Main Page | Class List | File List | Class Members | File Members

muxstuff.c

Go to the documentation of this file.
00001 #include "muxstuff.h"
00002 
00003 extern int debug;
00004 
00005 
00006 byte sync_8[1] = 
00007 { 
00008   0x7E,
00009 };
00010 
00011 byte sync_16[2] = 
00012 {
00013   0x4D,
00014   0xE1,
00015 };
00016 
00017 byte sync_2x16[4] = 
00018 {
00019   0x4D,
00020   0xE1,
00021   0x4D,
00022   0xE1,
00023 };
00024 
00025 byte sync_24[3] = 
00026 {
00027   0x82,
00028   0x4E,
00029   0xE7,
00030 };
00031 
00032 byte sync_32[4] = 
00033 {
00034   0x17,
00035   0x8A,
00036   0xCE,
00037   0x98,
00038 };
00039 
00040 
00041 static int twotothe(int n)
00042 {
00043   int r=1;
00044   while (n>0) {
00045     r *= 2;
00046     n--;
00047   }
00048   return (r);
00049 }
00050 
00051 int **make_mt_bytes(mux_table_entry *mt,
00052                     int mt_size,
00053                     int num_channels,
00054                     int info_bytes)
00055 /*
00056  * MAKE SURE that the multiplex table used only has MED's that reference
00057  * existing channels.  Ie if it refers to LCN3 but there is no LCN3
00058  * --> error.
00059  */
00060 {
00061   int **mt_bytes = (int **) malloc(mt_size * sizeof(int *));
00062   int i,j,k,n,repeating,towhere;
00063 
00064   if (mt_bytes != NULL) {
00065     for (i=0; i<mt_size; i++) {
00066       mt_bytes[i] = (int *) malloc(num_channels * sizeof(int));
00067       if (mt_bytes[i] != NULL) {
00068         /*
00069          * Figure out how many bytes get allocated to each channel 
00070          * per multiplex code.
00071          */
00072         for (j=0; j<num_channels; j++)
00073           mt_bytes[i][j]=0;
00074         
00075         repeating=!(mt[i].pattern->non_repeating_part_length);
00076         n=0;/* counter */
00077         for (k=0; k<info_bytes; k++) {
00078           if (!repeating) {
00079             towhere = mt[i].pattern->non_repeating_part[n++];
00080             if (towhere >= num_channels)
00081               error("make_mt_bytes","MUX table contains channels \
00082                      that are not used"); 
00083             if (n >= mt[i].pattern->non_repeating_part_length) {
00084               repeating = 1;
00085               n=0;
00086             }
00087           }
00088           else {
00089             towhere = mt[i].pattern->repeating_part[n++];
00090             if (towhere >= num_channels)
00091               error("make_mt_bytes","MUX table contains channels \
00092                      that are not used"); 
00093             if (n >= mt[i].pattern->repeating_part_length)
00094               n=0;
00095           }
00096           mt_bytes[i][towhere]++;
00097         }
00098       }
00099       else {
00100         error("make_mt_bytes", "malloc failed");
00101       }
00102     }
00103   }
00104   else {
00105     error("make_mt_bytes", "malloc failed");
00106   }
00107   return (mt_bytes);
00108 }
00109 
00110 
00111 float **make_mt_ratios(int **mt_bytes,
00112                        int mt_size,
00113                        int num_channels,
00114                        int info_bytes)
00115 {
00116   float **mt_ratios = (float **) malloc(mt_size * sizeof(float *));
00117   int i, j;
00118  
00119   int *junkblock;
00120  
00121   if (mt_ratios != NULL) {
00122     /*
00123      * Go through entire multiplex table.
00124      */
00125 
00126   /*
00127   junkblock = (int *) malloc(sizeof(int)*200);
00128   printf(" junkblock %x ...............................\n",junkblock);
00129   */
00130 
00131  for (i=0; i<mt_size; i++) {
00132       mt_ratios[i] = (float *) malloc(num_channels * sizeof(float));
00133       if (mt_ratios[i] != NULL) {
00134         if (info_bytes)
00135           for (j=0; j<num_channels; j++)
00136             mt_ratios[i][j] = (float) mt_bytes[i][j] / info_bytes;
00137       }
00138       else {
00139         error("make_mt_ratios", "malloc failed");
00140       }
00141     }
00142   }
00143   else {
00144     error("make_mt_ratios", "malloc failed");
00145   }
00146   return (mt_ratios);
00147 }
00148 
00149 
00150 mux_parameters *new_mux_parameters(char *name)
00151      /* 
00152       * A function to query the parameters shared between a multiplexer and 
00153       * the corresponding demultiplexer.
00154       */
00155 {
00156   mux_parameters *p;
00157   int x, y, n;
00158   char str[256];
00159 
00160   p = (mux_parameters *) malloc(sizeof(mux_parameters));
00161   if (p != NULL) {
00162 
00163     p->sync_flag_length = DEF_MUX_SYNC_FLAG;
00164     p->info_field_length = DEF_INFO_FIELD_LENGTH;
00165     p->sync_threshold = DEF_MUX_SYNC_THRESH;
00166 
00167     p->use_mpl = DEF_USE_MPL;
00168     p->header_code = DEF_HEADER_CODE;
00169     p->mpl_code = DEF_MPL_CODE;
00170 
00171     p->payload_min = DEF_PAYLOAD_MIN;
00172     p->payload_max = DEF_PAYLOAD_MAX;
00173 
00174     p->mux_table_size=0;
00175     p->mt_bytes=NULL;
00176     p->mt_ratios=NULL;
00177     
00178     for (x=0; x<MUX_TABLE_SIZE; x++) {
00179       p->mux_table[x].entry=NULL;
00180       p->mux_table[x].pattern=NULL;
00181     }
00182   }
00183   return (p);
00184 }
00185 
00186 
00187 
00188 static byte h223_headers[16] =
00189 /*
00190  * not including pm bit (bit 0)
00191  * Bit 0 set to 0.  
00192  *
00193  * [ CRC | MC | PM ]
00194  *
00195  *  0: 0000 0000
00196  *  1: 1010 0010
00197  *  2: 1110 0100
00198  *  3: 0100 0110
00199  *  4: 0110 1000
00200  *  5: 1100 1010
00201  *  6: 1000 1100
00202  *  7: 0010 1110
00203  *  8: 1101 0000
00204  *  9: 0111 0010
00205  * 10: 0011 0100
00206  * 11: 1001 0110
00207  * 12: 1011 1000
00208  * 13: 0001 1010
00209  * 14: 0101 1100
00210  * 15: 1111 1110
00211  */
00212 {
00213   0x00,   /*  0 */
00214   0xA2,   /*  1 */
00215   0xE4,   /*  2 */
00216   0x46,   /*  3 */
00217   0x68,   /*  4 */
00218   0xCA,   /*  5 */
00219   0x8C,   /*  6 */
00220   0x2E,   /*  7 */
00221   0xD0,   /*  8 */
00222   0x72,   /*  9 */
00223   0x34,   /* 10 */
00224   0x96,   /* 11 */
00225   0xB8,   /* 12 */
00226   0x1A,   /* 13 */
00227   0x5C,   /* 14 */
00228   0xFE,   /* 15 */
00229 };
00230 
00231 
00232 byte *construct_header(int mc, int pm, bch_type code, int level)
00233      /*
00234       * Constructs the header.  
00235       * NOTE: CRC is always 3 bits.  
00236       * MC is always 4 bits.
00237       * pm should be either 1 or 0, nothing else.
00238       *
00239       * compute crc field, add crc field to bits field
00240       * 
00241       * 
00242       * Bit fields look like this:
00243       *
00244       */
00245 {
00246   static byte h[8];
00247   unsigned long bits=0;
00248   unsigned int crcBits=0;
00249 
00250   if (debug) {
00251     printf("construct_header() MC = %d, %PM = %d\n", mc, pm);
00252   }
00253 
00254   if (level==1) { /* level 0 will also come here */
00255     crcBits = lookup_crc(mc); 
00256     bits = (mc << 4) | (crcBits << 1) | pm;
00257     h[0] = bits;
00258   }
00259   else
00260     error("construct_header","invalid level");
00261 
00262   return (h);
00263 }
00264 
00265 byte *construct_header_level2(int mc, int pm, int mpl)
00266 /*
00267  * constructs concatenated header with mc, pm and mpl protected
00268  * by golay code
00269  *
00270  * mc 4 bits
00271  * pm 1 bit
00272  * mpl 7 bits
00273  */
00274 {
00275   static byte ret[4];
00276   long bits,encoded;
00277   
00278   bits = (mc&0xF);
00279   bits = bits << 1;
00280   bits = bits | pm&0x1;
00281   bits = bits << 7;
00282   bits = bits | (mpl&0x7F);
00283 
00284   encoded = encode_golay(bits);
00285 
00286   /* now, encoded should contain codeword in 24 lsb bits of encoded */ 
00287   ret[0] = ((encoded >> 16)&0x000000FF);
00288   ret[1] = ((encoded >> 8)&0x000000FF);
00289   ret[2] = (encoded&0x000000FF);
00290   return ret;
00291 }
00292 
00293 
00294 int deconstruct_header(byte *header,int *mc,int *pm,bch_type code,int level)
00295      /*
00296       * Deconstructs the header, check crc for level 1.
00297       * returns 1 if crc checks valid, 0 if not  
00298       *
00299       */
00300 {
00301   unsigned long hbits=0;
00302   unsigned int recdCrcBits=0;
00303   int returnval;
00304 
00305   if (level == 1) { /* 0 will also come here */
00306     decode_bch(&hbits, header, code, 1);
00307     *pm = (hbits & 1);
00308     recdCrcBits = (hbits >> 1) & 0x07;
00309     *mc = (hbits >> 4) & 0x0F;
00310 
00311     if (recdCrcBits == lookup_crc(*mc))
00312       returnval = 1;
00313     else
00314       returnval = 0;
00315   }
00316   
00317   if (debug) {
00318     printf("deconstruct_header() MC = %d, PM = %d, CRC = %d\n",*mc,*pm,returnval);
00319   }
00320 
00321   return returnval;
00322 }
00323 
00324 void deconstruct_header_level2(byte *header,int *mc,int *pm,int *mpl)
00325 /* 
00326  * deconstructs the level 2 header, described above in construct_header
00327  * sets mc, pm and mpl to received value
00328  */
00329 {
00330   long codeword,decoded;
00331 
00332   /* form long out of byte array style header for golay decoding.  mask
00333      out MSB because only 23 bit code, not 24 bit code */
00334   codeword = ((header[0] & 0x7F)<<16) | header[1]<<8 | header[2];
00335 
00336   decoded = decode_golay(codeword);
00337   
00338   *mc = (decoded>>8) & 0xF; 
00339   *pm = (decoded>>7) & 0x1;
00340   *mpl = decoded & 0x7F;
00341   if (debug)
00342     printf("deconstruct_header() MC = %d, PM = %d, MPL = %d\n",*mc,*pm,*mpl);
00343 }
00344 
00345 byte *construct_mpl(int mpl, bch_type code)
00346 {
00347   static byte mplf[8];
00348   unsigned long bits=0;
00349 
00350   bits = mpl;
00351   
00352   if (debug) {
00353     printf("construct_mpl() MPL = %d\n", mpl);
00354   }
00355   
00356   encode_bch(bits, mplf, code);
00357   
00358   return (mplf);
00359 }
00360 
00361 int deconstruct_mpl(byte *mplf, int *mpl, bch_type code)
00362      /* 
00363       * returns status of detection (0 if errors detected, 1 if not) 
00364       * at this point, only will return 1 because using for correction
00365       */
00366 {
00367   unsigned long bits=0;
00368   int status;
00369 
00370   status = decode_bch(&bits, mplf, code, 1);
00371   *mpl = bits;
00372 
00373   if (debug) {
00374     printf("deconstruct_mpl() MPL = %d\n", *mpl);
00375   }
00376 
00377   return status;
00378 }
00379 
00380 void swapbits(bytes *b, int a1, int a2)
00381      /*
00382       * Swaps two bits.
00383       */
00384 {
00385   byte x = get_byte(b, (a1 / 8));
00386   byte y = get_byte(b, (a2 / 8));
00387   byte tmp = x;
00388   if (y & (1 << (a2 % 8))) {
00389     x |= (1 << (a1 % 8));
00390   }
00391   else {
00392     x &= ~(1 << (a1 % 8));
00393   }
00394   if (tmp & (1 << (a1 % 8))) {
00395     y |= (1 << (a2 % 8));
00396   }
00397   else {
00398     y &= ~(1 << (a2 % 8));
00399   }
00400   set_byte(b, (a1 / 8), x);
00401   set_byte(b, (a2 / 8), y);
00402 }
00403 
00404 
00405 void swapbytes(bytes *b, int a1, int a2)
00406      /*
00407       * Swaps bytes at a1 and a2 of (b).
00408       */
00409 {
00410   byte x1, x2;
00411   x1 = get_byte(b, a1);
00412   x2 = get_byte(b, a2);
00413   set_byte(b, a1, x2);
00414   set_byte(b, a2, x1);
00415 }
00416 
00417 
00418 void interleave_header(bytes *mux_pdu, int sync_bytes, 
00419                               int header_bytes, int mode)
00420 /*
00421  * Performs interleaving of the header throughout the area taken up by 
00422  * the header and the information field of the MUX-PDU.
00423  * 
00424  * Swaps bits or bytes around since that is the simplest way of doing it.
00425  */
00426 {
00427   int i, j;
00428   int field_length = num_bytes(mux_pdu) - sync_bytes;
00429 
00430   if (mode == BIT_INTERLEAVING) {
00431     for (i = header_bytes * 8 - 1; i > 0; i--) {
00432       j = field_length * 8 / i;
00433       swapbits(mux_pdu, i, j);
00434     }    
00435   }
00436   else if (mode == BYTE_INTERLEAVING) {
00437     for (i = header_bytes - 1; i > 0; i--) {
00438       j = field_length / i;
00439       swapbytes(mux_pdu, i, j);
00440     }
00441   }
00442 }
00443 
00444 
00445 int mux_byte_source(mux_table_entry *mte, int x)
00446 /*
00447  * Returns the channel that octet x of the information field of a packet
00448  * multiplexed with mux table entry *(mte) should come from or should 
00449  * return to.
00450  */
00451 {
00452   int source;
00453   
00454   if (x < mte->pattern->non_repeating_part_length) {
00455     source = mte->pattern->non_repeating_part[x];
00456   }
00457   else {
00458     x -= mte->pattern->non_repeating_part_length;
00459     x %= mte->pattern->repeating_part_length;
00460     source = mte->pattern->repeating_part[x];
00461   }
00462   return(source);
00463 }
00464 

Generated on Sun Jul 16 16:27:45 2006 by  doxygen 1.3.9.1