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

demux.c

Go to the documentation of this file.
00001 #include "standard.h"
00002 #include "mux.h"
00003 #include "demux.h"
00004 #include "crc3.h"
00005 #include "muxstuff.h"
00006 
00007 extern int debug;
00008 extern byte sync_8[1];
00009 extern byte sync_16[2];
00010 extern byte sync_2x16[4];
00011 extern byte sync_24[3];
00012 extern byte sync_32[4];
00013 
00014 
00015 /* 
00016  * The DEMUX will do something positive.  
00017  * 
00018  */
00019 
00020 demux *new_demux(char *name)
00021 {
00022   int i;
00023   demux *bob;
00024 
00025   bob = malloc(sizeof(demux));
00026   if (bob != NULL) {
00027     bob->num_al_receivers = 0;
00028     strcpy(bob->name, name);
00029 
00030     for (i=0; i<8; i++) {
00031       bob->header_reg[i]=0;
00032       bob->sync_reg[i]=0;
00033       bob->mpl_reg[i]=0;
00034     }
00035     bob->THRESH=0;
00036     bob->MC=-1;
00037     bob->PM=-1;
00038     bob->MPL=-1;
00039     bob->in_sync=0;
00040     bob->sync_delay=0;
00041     bob->goodPackets=0;
00042     bob->badPackets=0;
00043     bob->mpl_counter=0;
00044   }
00045   return (bob);
00046 }
00047 
00048 void close_demux(demux *d)
00049 {
00050   FILE *outf;
00051   printf("%s: %d Good CRC Packets (y1), %d Failed CRC Packets , %d bad MPLs\n",
00052           d->name, d->goodPackets, d->badPackets, d->bad_mpls);
00053   if (*d->params->stat_file!=0) {
00054     outf = fopen(d->params->stat_file,"a");
00055     assert(outf!=NULL);
00056     fprintf(outf,"%s: %d Good Packets, %d Bad Packets, %d bad MPLs\n",d->name,
00057           d->goodPackets, d->badPackets, d->bad_mpls);
00058     fclose(outf);
00059   }
00060   free (d);
00061 }
00062 
00063 
00064 static int correlation(byte a, byte b)
00065      /*
00066       * returns the number of bits the same in a and b.
00067       */
00068 {
00069   int r=0;
00070   int i;
00071 
00072   for (i=0; i<8; i++) {
00073     if ((a & (1 << i)) == (b & (1 << i)))
00074       r++;
00075   }
00076   return r;
00077 }
00078 
00079 
00080 byte shift_in(demux *d, byte b)
00081 {
00082   byte tmpA, tmpB;
00083   int i;
00084   byte *sync_std=NULL;
00085   int sync_bytes=((d->params->sync_flag_length)/8);
00086   int header_bytes=((code_length(d->params->header_code)+1)/8);
00087   int mpl_bytes=((code_length(d->params->mpl_code)+1)/8);
00088 
00089   /* 
00090    * Shift in new byte b.  Return byte shifted out. 
00091    *
00092    * it will calculate the threshold each time.  if mpl is
00093    * used, it doesn't need to, this can be improved
00094    */
00095 
00096   tmpB = b;
00097 
00098   if (d->params->use_mpl) {
00099     for (i=mpl_bytes-1; i>=0; i--) {
00100       tmpA = d->mpl_reg[i];
00101       d->mpl_reg[i] = tmpB;
00102       tmpB = tmpA;
00103     }
00104   }
00105   for (i=header_bytes-1; i>=0; i--) {
00106     tmpA = d->header_reg[i];
00107     d->header_reg[i] = tmpB;
00108     tmpB = tmpA;
00109   }
00110   for (i=sync_bytes-1; i>=0; i--) {
00111     tmpA = d->sync_reg[i];
00112     d->sync_reg[i] = tmpB;
00113     tmpB = tmpA;
00114   }
00115   /*
00116    * Get new values for THRESH, MC, PM, MPL
00117    */
00118 
00119   d->THRESH=0;
00120 
00121   switch(sync_bytes){
00122     case 1: sync_std = sync_8;  break;
00123     case 2: sync_std = sync_16; break;
00124     case 3: sync_std = sync_24; break;
00125     case 4: sync_std = sync_32; break;
00126   }
00127 
00128   /* if level 2 double flag mode.. */
00129   if (d->params->use_double_flag)
00130     sync_std = sync_2x16;
00131 
00132   for (i=0; i<sync_bytes; i++) {
00133     d->THRESH += correlation(d->sync_reg[i], sync_std[i]);
00134   }
00135 
00136   return tmpB;
00137 }
00138 
00139 
00140 
00141 void demultiplex(demux *d)
00142      /*
00143       * This is kind of the opposite of multiplex().
00144       */
00145 {
00146   int i, j, mplok;
00147   int towhere;
00148   byte b;
00149   int sync_bytes=((d->params->sync_flag_length)/8);
00150   int header_bytes=((code_length(d->params->header_code)+1)/8);
00151   int mpl_bytes=((code_length(d->params->mpl_code)+1)/8);
00152 
00153   int delay_bytes = sync_bytes + header_bytes;
00154 
00155   int check = 0;
00156 
00157   if (d->params->use_mpl) {
00158     delay_bytes += mpl_bytes;
00159   }
00160 
00161 #define MT (d->params->mux_table)
00162 #define AL (d->al_receivers)
00163 
00164   if (!channel_read_indication(d->input)) {
00165     if (debug)
00166       printf("%s DEMUX [%s] Nothing to read yet.\n", print_time(), d->name);
00167   }
00168 
00169   while (channel_read_indication(d->input)) {
00170 
00171     if (debug)
00172       printf("%s DEMUX [%s] reading data.\n", print_time(), d->name);
00173     /*
00174      * get new byte.
00175      */
00176     b = channel_read(d->input);
00177 
00178     d->mpl_counter--;
00179 
00180     /*
00181      * shift in new byte, get out old byte.  
00182      */
00183     b = shift_in(d, b);
00184    
00185     /*
00186      * process incoming data 
00187      */
00188 
00189     if (d->sync_delay) {
00190       d->sync_delay --;
00191       if (debug) {
00192         printf("%s DEMUX [%s] Delay... delay remaining = %d\n",
00193                  print_time(), d->name, d->sync_delay);
00194       }
00195     }
00196     else {
00197       if (d->in_sync) {
00198           towhere = mux_byte_source(&MT[d->MC], d->byte_count);
00199          
00200           if (debug) {
00201             printf("%s DEMUX [%s] Sending byte %d to LCN%d\n", print_time(), 
00202                     d->name, d->byte_count, towhere);
00203           }
00204           
00205           send_to_al(AL[towhere], b);
00206 
00207           d->byte_count++;
00208       }
00209     }
00210      
00211     /* 
00212      * if we've found a sync flag (and mpl counter < 0), do some stuff.  
00213      */
00214     if ((d->THRESH >= d->params->sync_threshold) && (d->mpl_counter < 0)) {
00215       /* found a syncflag.  */
00216       if (debug) {
00217         printf("%s DEMUX [%s] Got SYNC.  correlation=%d\n", print_time(), d->name, d->THRESH);
00218       }
00219       
00220       /*
00221        * send closing flag message to AL's
00222        */
00223       
00224       for (i=0;i<d->num_al_receivers;i++)
00225         send_closing_flag(AL[i]);
00226 
00227       /* 
00228        * found sync flag.  set MC, PM, and MPL.  :-)
00229        */
00230       
00231       if (d->params->level==2) {
00232         deconstruct_header_level2(d->header_reg, &d->MC, &d->PM, &d->MPL);
00233           if (debug)
00234             printf("%s DEMUX [%s] MC = %d, MPL = %d\n", print_time(), d->name, 
00235                     d->MC, d->MPL);
00236           d->goodPackets++;
00237           check = 1;
00238       }
00239       else {
00240         check = deconstruct_header(d->header_reg, &d->MC, &d->PM, 
00241                                    d->params->header_code, d->params->level);
00242 
00243         if (check) {
00244           if (debug)
00245             printf("%s DEMUX [%s] MC = %d, PM = %d\n", print_time(), d->name, 
00246                     d->MC, d->PM);
00247           d->goodPackets++;
00248         }
00249         else {
00250           if (debug) printf("%s DEMUX [%s] Bad Hdr Recd\n", print_time(), d->name);
00251           d->badPackets++;
00252         }
00253       }
00254 
00255       /* reset received bytes */
00256       d->byte_count=0;
00257       
00258       d->in_sync=1;
00259       
00260       /*
00261        * Do some testing of MC
00262        */
00263       if (d->MC < 0 || d->MC >= MUX_TABLE_SIZE || !check) {
00264         if (debug)
00265           printf("%s DEMUX [%s] Receiving invalid MC.\n",print_time(), d->name);
00266         d->in_sync=0;
00267         d->MC=-1;
00268       }
00269       if (d->params->mux_table[d->MC].pattern == NULL) {
00270         if (debug)
00271           printf("%s DEMUX [%s] Receiving invalid MC.\n",print_time(), d->name);
00272         d->in_sync=0;
00273         d->MC=-1;
00274       }
00275 
00276       if (d->params->use_mpl && d->params->level!=2) {
00277         mplok = deconstruct_mpl(d->mpl_reg, &d->MPL, d->params->mpl_code);
00278         if (debug)  {
00279           if (mplok) {
00280             printf("%s DEMUX [%s] Receiving MPL %d\n", print_time(), 
00281                     d->name,d->MPL);
00282           }
00283           else {
00284             printf("%s DEMUX [%s] Receiving bad MPL, ignoring\n", print_time(), 
00285                     d->name);
00286             d->bad_mpls++;
00287           }
00288         }
00289         if (mplok) {
00290           d->mpl_counter = d->MPL;
00291         }
00292       }
00293 
00294       /*
00295        * set sync_delay.  sync_delay is the number of bytes in flag+header, 
00296        * which need to be read out of the buffer before you start reading data.
00297        */
00298       d->sync_delay = delay_bytes;
00299     }
00300   }
00301 }

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