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

mux.h File Reference

#include "al_sending.h"
#include "al_receiving.h"
#include "channel.h"
#include "mux.h"
#include "med.h"
#include "bch.h"

Go to the source code of this file.

Classes

struct  mux_parameters
struct  mux

Defines

#define MUX_TABLE_SIZE   16
#define DEF_MUX_HEADER   1
#define DEF_MUX_SYNC_FLAG   32
#define DEF_MUX_SYNC_THRESH   28
#define DEF_MUX_LEVEL   1
#define DEF_PAYLOAD_MIN   1
#define DEF_PAYLOAD_MAX   128
#define DEF_HEADER_CODE   BCH15_5
#define DEF_USE_MPL   0
#define DEF_MPL_CODE   BCH15_11
#define DEF_INFO_FIELD_LENGTH   128
#define NO_INTERLEAVING   0
#define BIT_INTERLEAVING   1
#define BYTE_INTERLEAVING   2
#define DEF_HEADER_MC_LENGTH   4
#define DEF_HEADER_CRC_LENGTH   3
#define MAX_AL_SENDERS   10
#define MAX_AL_RECEIVERS   10

Functions

mux_parametersnew_mux_parameters (char *name)
muxnew_mux (char *name)
int bytes_ok (int mt_bytes[], int buffer_bytes[], int d, mux *m)
float ratio_difference (float a[], float b[], int d)
void print_int (int x)
void set_payload_size (mux *m)
void multiplex (mux *m, int num_channels)
void close_mux (mux *m)


Define Documentation

#define BIT_INTERLEAVING   1
 

Definition at line 36 of file mux.h.

#define BYTE_INTERLEAVING   2
 

Definition at line 37 of file mux.h.

#define DEF_HEADER_CODE   BCH15_5
 

Definition at line 28 of file mux.h.

#define DEF_HEADER_CRC_LENGTH   3
 

Definition at line 40 of file mux.h.

#define DEF_HEADER_MC_LENGTH   4
 

Definition at line 39 of file mux.h.

#define DEF_INFO_FIELD_LENGTH   128
 

Definition at line 32 of file mux.h.

#define DEF_MPL_CODE   BCH15_11
 

Definition at line 30 of file mux.h.

#define DEF_MUX_HEADER   1
 

Definition at line 18 of file mux.h.

#define DEF_MUX_LEVEL   1
 

Definition at line 22 of file mux.h.

#define DEF_MUX_SYNC_FLAG   32
 

Definition at line 19 of file mux.h.

#define DEF_MUX_SYNC_THRESH   28
 

Definition at line 20 of file mux.h.

#define DEF_PAYLOAD_MAX   128
 

Definition at line 26 of file mux.h.

#define DEF_PAYLOAD_MIN   1
 

Definition at line 25 of file mux.h.

#define DEF_USE_MPL   0
 

Definition at line 29 of file mux.h.

#define MAX_AL_RECEIVERS   10
 

Definition at line 43 of file mux.h.

#define MAX_AL_SENDERS   10
 

Definition at line 42 of file mux.h.

#define MUX_TABLE_SIZE   16
 

Definition at line 16 of file mux.h.

Referenced by demultiplex().

#define NO_INTERLEAVING   0
 

Definition at line 35 of file mux.h.


Function Documentation

int bytes_ok int  mt_bytes[],
int  buffer_bytes[],
int  d,
mux m
[static]
 

Referenced by multiplex().

void close_mux mux m  ) 
 

Definition at line 436 of file mux.c.

References mux::name, mux::packetsSent, mux::params, and mux_parameters::stat_file.

Referenced by cleanup().

00437 {
00438   FILE *outf;
00439   printf("%s: %d Packets Sent\n",m->name,m->packetsSent);
00440   if (*m->params->stat_file!=0) {
00441     outf = fopen(m->params->stat_file,"a");
00442     assert(outf!=NULL);
00443     fprintf(outf,"%s: %d packets sent\n",m->name,m->packetsSent);
00444     fclose(outf);
00445   }
00446 }

void multiplex mux m,
int  num_channels
 

Definition at line 114 of file mux.c.

References AL, al_buffer_level(), al_request(), al_requested_size(), byte, bytes_ok(), channel_write(), channel_write_indication(), close_combinations(), construct_header(), construct_header_level2(), debug, free_bytes(), get_al_pdu(), get_byte(), HEADER_BYTES, mux_parameters::header_code, INFO_BYTES, mux_parameters::level, make_mt_bytes(), make_mt_ratios(), MT, MT_BYTES, MT_RATIOS, MT_SIZE, mux_byte_source(), mux::name, new_combinations(), next_combination(), mux::output, mux::packetsSent, mux::params, print_time(), ratio_difference(), set_payload_size(), sync_16, sync_24, sync_2x16, sync_32, sync_8, SYNC_BITS, SYNC_BYTES, and mux_parameters::use_double_flag.

Referenced by main_loop().

00118 {
00119   int requested_sizes[MAX_AL_SENDERS];
00120   int al_bytes[MAX_AL_SENDERS];
00121   float al_ratios[MAX_AL_SENDERS];
00122   float best_diff;
00123   float diff;
00124   int best_mc;
00125   int num_arqs;
00126   combinations *arq_combs;
00127   int *arq_attempt;
00128   int total_bytes;
00129   int i, j, k, l, n, count;
00130   int MC=-1;
00131   int repeating;
00132   int fromwhere;
00133   int ok;
00134   byte larry;
00135   byte *header;
00136   byte *mplf;
00137   bytes *al_pdus[MAX_AL_SENDERS];
00138   int al_pdu_counters[MAX_AL_SENDERS];
00139   int als_requesting_arqs[MAX_AL_SENDERS];
00140 
00141 #define SYNC_BYTES ((m->params->sync_flag_length)/8)
00142 #define SYNC_BITS (m->params->sync_flag_length)
00143 
00144 #define HEADER_BYTES ((code_length(m->params->header_code)+1)/8)
00145 #define MPL_BYTES ((code_length(m->params->mpl_code)+1)/8)
00146 #define INFO_BYTES (m->params->info_field_length)
00147 #define PACKET_BYTES (SYNC_BYTES + HEADER_BYTES + INFO_BYTES)
00148 #define AL (m->al_senders)
00149 #define MT_SIZE (m->params->mux_table_size)
00150 #define MT (m->params->mux_table)
00151 #define MT_RATIOS (m->params->mt_ratios)
00152 #define MT_BYTES (m->params->mt_bytes)
00153 
00154   /*
00155    * If it is time to make a packet, do so.  
00156    */
00157   
00158   if (channel_write_indication(m->output)) {
00159     
00160     /*
00161      * pick payload size randomly.
00162      */
00163     set_payload_size(m);
00164     
00165     MT_BYTES = make_mt_bytes(MT, MT_SIZE, num_channels, INFO_BYTES);
00166     MT_RATIOS = make_mt_ratios(MT_BYTES, MT_SIZE, num_channels, INFO_BYTES);
00167     
00168     if (debug) {
00169       printf("%s MUX [%s]: Payload field length = %d bytes\n", 
00170              print_time(), m->name, INFO_BYTES);
00171       printf("%s MUX [%s]: Buffer levels  : ", print_time(), m->name);
00172       for (i=0; i<num_channels; i++) {
00173         printf("%3d ", al_buffer_level(AL[i]));
00174       }
00175       printf("\n");
00176     }
00177     
00178     /*
00179      * Requested arq sizes 
00180      */
00181     if (debug >= 2) {
00182       printf("MUX [%s]: Requested sizes: ", m->name); 
00183     }
00184     num_arqs = 0;
00185     for (i=0; i<num_channels; i++) {
00186       if (al_request(AL[i]) == -1) {
00187         requested_sizes[i] = al_requested_size(AL[i]);
00188         als_requesting_arqs[num_arqs++] = i;
00189       }
00190       else {
00191         requested_sizes[i] = 0;
00192       }
00193       if (debug >= 2) {
00194         printf("%4d ", requested_sizes[i]);
00195       }
00196     }
00197     if (debug >= 2) {
00198       printf("\n");
00199     }
00200     
00201     if (debug >= 2) {
00202       printf("MUX : als requesting arq's: ");
00203       for (i=0; i<num_arqs; i++) 
00204         printf("%4d ", als_requesting_arqs[i]);
00205       printf("\n");
00206     }
00207     /*
00208      * Try to pick a multiplex code.  First try handling all or some of the ARQ's.
00209      */
00210     best_mc = -1;
00211     best_diff = -1;
00212     for (i = num_arqs; ((i >= 0) && (best_mc==-1)); i--) {
00213       if (debug >= 2) {
00214         printf("MUX : Trying to satisfy %d ARQ's.\n", i);
00215       }
00216       arq_combs = new_combinations(als_requesting_arqs, num_arqs, i);
00217       arq_attempt = next_combination(arq_combs);
00218       do {
00219         /*
00220          * Set up bytes per channel and ratios to check for this combination.
00221          */
00222         if (debug >= 3) {
00223           printf("MUX : ARQ combination: ");
00224           for (l=0; l<i; l++) 
00225             printf("%4d", arq_attempt[l]);
00226           printf("\n");
00227         }
00228         total_bytes = 0;
00229         for (j=0; j<num_channels; j++) {
00230           al_ratios[j] = 0.0;
00231           al_bytes[j] = 0;
00232         }
00233         for (j=0; j<i; j++) {
00234           al_bytes[arq_attempt[j]] = requested_sizes[arq_attempt[j]];
00235           al_ratios[arq_attempt[j]] = (float) al_bytes[arq_attempt[j]];
00236           total_bytes += al_bytes[arq_attempt[j]];
00237         }
00238         for (j=0; j<num_channels; j++) {
00239           if (al_bytes[j] == 0) {
00240             al_bytes[j] = al_buffer_level(AL[j]);
00241             al_ratios[j] = (int) al_bytes[j];
00242             total_bytes += al_bytes[j];
00243           }
00244         }
00245         if (total_bytes) {
00246           for (j=0; j<num_channels; j++) {
00247             al_ratios[j] = (float) al_ratios[j] / total_bytes;
00248           }
00249         }
00250         if (debug >= 2) {
00251           printf("MUX : AL Bytes per channel: ");
00252           for (l=0; l<num_channels; l++) 
00253             printf("%6d ", al_bytes[l]);
00254           printf("\n");
00255           printf("MUX : Byte ratios         : ");
00256           for (l=0; l<num_channels; l++)
00257             printf("%6.3f ", al_ratios[l]);
00258           printf("\n");   
00259         }
00260         /*
00261          * For each entry in the multiplex table, see if it handles the ARQ's we want.
00262          */
00263         for (j=0; j<MT_SIZE; j++) {
00264           if (debug >= 3) {
00265             printf("MUX : MC %2d ratios        : ", j);
00266             for (l=0; l<num_channels; l++) 
00267               printf("%6.3f ", MT_RATIOS[j][l]);
00268           }
00269           ok = 1;
00270           /* 
00271            * Make sure all ARQ's are handled (exactly for now) 
00272            */
00273           for (k=0; ((k<i) && (ok)); k++) {
00274             if (MT_BYTES[j][arq_attempt[k]] != requested_sizes[arq_attempt[k]])
00275               ok = 0;
00276           }
00277           /*
00278            * Check that bytes are ok.
00279            */
00280           if (ok) {
00281             if (!bytes_ok(MT_BYTES[j], al_bytes, num_channels,m))
00282               ok = 0;
00283           }
00284           /*
00285            * See if it's the best.
00286            */
00287           if (ok) {
00288             diff = ratio_difference(MT_RATIOS[j], al_ratios, num_channels);
00289             if (debug >= 3) {
00290               printf(" diff = %6.3f\n", diff);
00291             }
00292             if ((best_mc == -1) || (diff < best_diff)) {
00293               best_mc = j;
00294               best_diff = diff;
00295             }
00296           }
00297           else { 
00298             if (debug >= 3) {
00299               printf("\n");
00300             }
00301           }
00302         }
00303       } while ((arq_attempt = next_combination(arq_combs)) != NULL);
00304       close_combinations(arq_combs);
00305     }
00306     
00307     /*
00308      * If that didn't work, I don't know what will.
00309      */
00310     MC = best_mc;
00311     
00312     if (MC == -1) {
00313       if (debug) {
00314         printf("%s MUX [%s]: Doing nothing.\n", print_time(), m->name);
00315       }
00316       return;
00317     }
00318     else {
00319       if (debug) {
00320         printf("%s MUX [%s]: Making packet with MC %d, ", print_time(), m->name, MC);
00321         
00322         for (i=0; i<num_channels; i++)
00323           printf(" %3d", MT_BYTES[MC][i]);
00324         printf("\n");
00325       }
00326     }
00327     /************************************************************/
00328     /* Now form a packet based on the multiplex code chosen.    */
00329     /************************************************************/
00330     
00331     /* 
00332      * Get AL-PDU's.  Set counters to 0.
00333      */
00334     for (i=0; i<num_channels; i++) {
00335       if (MT_BYTES[MC][i] != 0) {
00336         al_pdus[i] = get_al_pdu(AL[i], MT_BYTES[MC][i]);
00337       }
00338       else {
00339         al_pdus[i] = NULL;
00340       }
00341       al_pdu_counters[i] = 0;
00342     }
00343     
00344     /*
00345      * Start sending packet 
00346      */
00347     n = 0;          /* Mux-pdu position counter */
00348     /*
00349      * Send SYNC field.
00350      */
00351     if (debug) {
00352       printf("%s MUX [%s]: Sending %d SYNC_BYTES.\n", print_time(),
00353              m->name, SYNC_BYTES);
00354     }
00355     for (count = 0; count < SYNC_BYTES; count++)  {
00356       if (m->params->use_double_flag) {
00357         larry = sync_2x16[count];
00358       }
00359       else if (SYNC_BITS == 32) {
00360         larry = sync_32[count];
00361       }
00362       else if (SYNC_BITS == 24) {
00363         larry = sync_24[count];
00364       }
00365       else if (SYNC_BITS == 16) {
00366         larry = sync_16[count];
00367       }
00368       else if (SYNC_BITS == 8) {
00369         larry = sync_8[count];
00370       }
00371       
00372       channel_write(m->output, larry);
00373       n++;
00374     }
00375 
00376     if (m->params->level == 2) {
00377       /* send HEADER and MPL concatenated, protected by 23,12 Golay code */
00378       header = construct_header_level2(MC,0,INFO_BYTES);
00379       for (count = 0; count < HEADER_BYTES; count++) {
00380         channel_write(m->output, header[count]);
00381       }
00382       if (debug) {
00383         printf("%s MUX [%s]: Sending %d HEADER_BYTES.\n", print_time(), 
00384                m->name,HEADER_BYTES);
00385       }
00386     } 
00387     else { /* level is 1 or 0 */
00388       /*
00389        * send HEADER field with BCH code
00390        */
00391       header = construct_header(MC, 0, m->params->header_code, m->params->level);
00392                               /* PM bit hard-coded to zero.  :-( */
00393       if (debug) {
00394         printf("%s MUX [%s]: Sending %d HEADER_BYTES.\n", print_time(),
00395                m->name, HEADER_BYTES);
00396       }
00397       for (count = 0; count < HEADER_BYTES; count++) {
00398         channel_write(m->output, header[count]);
00399         n++;
00400       }
00401     } 
00402     
00403     /*
00404      * Send INFO BYTES.
00405      */
00406     if (debug) {
00407         printf("%s MUX [%s]: Sending %d INFO_BYTES.\n", print_time(),
00408                m->name, INFO_BYTES);
00409     }
00410 
00411     for (count = 0; count < INFO_BYTES; count++) {
00412       fromwhere = mux_byte_source(&MT[MC], count);
00413       larry = get_byte(al_pdus[fromwhere], al_pdu_counters[fromwhere]++);
00414 
00415       channel_write(m->output, larry);
00416       n++;
00417     }
00418 
00419     /*
00420      * Don't need these anymore.
00421      */
00422     for (i=0; i<num_channels; i++) {
00423       if (al_pdus[i] != NULL) {
00424         free_bytes(al_pdus[i]);
00425       }
00426     }
00427     m->packetsSent++;
00428   }
00429   else {
00430     if (debug) {
00431       printf("%s MUX [%s] Not time to write yet.\n", print_time(), m->name);
00432     }
00433   }
00434 }

mux* new_mux char *  name  ) 
 

Definition at line 23 of file mux.c.

References mux::name, mux::num_al_senders, mux::packetsSent, and mux::wait_time.

Referenced by start_config().

00024 {
00025   mux *bob;
00026   
00027   bob = malloc(sizeof(mux));
00028   if (bob != NULL) {
00029      bob->num_al_senders = 0;
00030      strcpy(bob->name, name);
00031      bob->wait_time=0;
00032   }
00033 
00034   bob->packetsSent = 0;
00035   return(bob);
00036 }

mux_parameters* new_mux_parameters char *  name  ) 
 

Definition at line 150 of file muxstuff.c.

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 }

void print_int int  x  )  [static]
 

float ratio_difference float  a[],
float  b[],
int  d
 

Definition at line 67 of file mux.c.

References a.

Referenced by multiplex().

00072                                 :
00073       * 
00074       * diff = compute_difference(mt_ratios, al_ratios, num_channels);
00075       */
00076 {
00077   float sum = 0.0;
00078   int i;
00079   for (i=0; i<d; i++) {
00080     sum += fabs(b[i] - a[i]);
00081   }
00082   return (sum);
00083 }

void set_payload_size mux m  )  [static]
 

Referenced by multiplex().


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