00001 #include "standard.h"
00002 #include <stdio.h>
00003 #include <math.h>
00004 #include "mux.h"
00005 #include "al.h"
00006 #include "al_sending.h"
00007 #include "comb.h"
00008 #include "muxstuff.h"
00009
00010
00011 #define MIN(a, b) ({int _a=(a),_b=(b);(_a<_b)?_a:_b;})
00012
00013
00014 extern int debug;
00015
00016 extern byte sync_8[1];
00017 extern byte sync_16[2];
00018 extern byte sync_2x16[2];
00019 extern byte sync_24[3];
00020 extern byte sync_32[4];
00021
00022
00023 mux *new_mux(char *name)
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 }
00037
00038
00039 static int bytes_ok(int mt_bytes[], int buffer_bytes[], int d, mux *m)
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 {
00052 int ok = 1;
00053 int i;
00054 int tot_bytes = 0;
00055
00056 for (i=0; i<d; i++) {
00057 tot_bytes += mt_bytes[i];
00058 if (buffer_bytes[i] < mt_bytes[i])
00059 ok = 0;
00060 }
00061 if (tot_bytes < m->params->info_field_length)
00062 ok = 0;
00063 return (ok);
00064 }
00065
00066
00067 float ratio_difference(float a[], float b[], int d)
00068
00069
00070
00071
00072
00073
00074
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 }
00084
00085
00086 static void print_int(int x)
00087 {
00088 int i;
00089 for (i=31; i>=0; i--) {
00090 if (x & (1 << i))
00091 putchar('1');
00092 else
00093 putchar('0');
00094 }
00095 putchar('\n');
00096 }
00097
00098
00099 static void set_payload_size(mux *m)
00100 {
00101 int x;
00102 double d;
00103
00104 x = random();
00105
00106 d = (double) x / 0x7FFFFFFF;
00107
00108 m->params->info_field_length =
00109 (int) (d * (m->params->payload_max - m->params->payload_min) +
00110 m->params->payload_min + 0.5);
00111 }
00112
00113
00114 void multiplex(mux *m, int num_channels)
00115
00116
00117
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
00156
00157
00158 if (channel_write_indication(m->output)) {
00159
00160
00161
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
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
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
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
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
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
00279
00280 if (ok) {
00281 if (!bytes_ok(MT_BYTES[j], al_bytes, num_channels,m))
00282 ok = 0;
00283 }
00284
00285
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
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
00329
00330
00331
00332
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
00346
00347 n = 0;
00348
00349
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
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 {
00388
00389
00390
00391 header = construct_header(MC, 0, m->params->header_code, m->params->level);
00392
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
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
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 }
00435
00436 void close_mux(mux *m)
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 }
00447