alc_rx.c

Go to the documentation of this file.
00001 
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <errno.h>
00037 #include <string.h>
00038 #include <time.h>
00039 #include <fcntl.h>
00040 #include <sys/stat.h>
00041 #include <sys/types.h>
00042 #include <math.h>
00043 #include <assert.h>
00044 
00045 #ifdef _MSC_VER
00046 #include <winsock2.h>
00047 #include <process.h>
00048 #include <io.h>
00049 #else
00050 #include <pthread.h>
00051 #include <sys/socket.h>
00052 #include <netdb.h>
00053 #include <sys/time.h>
00054 #endif
00055 
00056 #include "defines.h"
00057 #include "alc_rx.h"
00058 #include "alc_channel.h"
00059 #include "mad_rlc.h"
00060 #include "lct_hdr.h"
00061 #include "null_fec.h"
00062 #include "xor_fec.h"
00063 #include "rs_fec.h"
00064 #include "utils.h"
00065 #include "transport.h"
00066 #include "alc_list.h"
00067 
00080 int analyze_packet(char *data, int len, alc_channel_t *ch) {
00081 
00082         int retval = 0;
00083         int hdrlen = 0;                 /* length of whole FLUTE/ALC/LCT header */
00084         int het = 0;
00085         int hel = 0;
00086         int exthdrlen = 0;
00087         unsigned int word = 0;  
00088         short fec_enc_id = 0; 
00089         unsigned long long ull = 0;
00090         unsigned long long block_len = 0;
00091         unsigned long long pos = 0;
00092 
00093         /* LCT header upto CCI */
00094 
00095         def_lct_hdr_t *def_lct_hdr = NULL; 
00096 
00097         /* remaining LCT header fields*/
00098 
00099         unsigned long long tsi = 0; /* TSI */
00100         unsigned long long toi = 0; /* TOI */
00101 
00102         /* EXT_FDT */
00103 
00104         unsigned short flute_version = 0; /* V */
00105         int fdt_instance_id = 0; /* FDT Instance ID */
00106 
00107         /* EXT_CENC */
00108 
00109         unsigned char content_enc_algo = 0; /* CENC */
00110         unsigned short reserved = 0; /* Reserved */ 
00111 
00112         /* EXT_FTI */
00113 
00114         unsigned long long transfer_len = 0; /* L */
00115         unsigned char finite_field = 0; /* m */
00116         unsigned char nb_of_es_per_group = 0; /* G */
00117         unsigned short es_len = 0; /* E */
00118         unsigned short sb_len = 0;
00119         unsigned int max_sb_len = 0; /* B */
00120         unsigned short max_nb_of_es = 0; /* max_n */
00121         int fec_inst_id = 0; /* FEC Instance ID */
00122 
00123         /* FEC Payload ID */
00124 
00125         unsigned int sbn = 0;
00126         unsigned int esi = 0;
00127 
00128         trans_obj_t *trans_obj = NULL;
00129         trans_block_t *trans_block = NULL;
00130         trans_unit_t *trans_unit = NULL;
00131         trans_unit_t *tu = NULL;
00132         trans_unit_t *next_tu = NULL;
00133         wanted_obj_t *wanted_obj = NULL;
00134 
00135         char *buf = NULL;
00136 
00137         char filename[MAX_PATH_LENGTH];
00138         double rx_percent = 0;
00139         
00140         unsigned short j = 0;
00141         unsigned short nb_of_symbols = 0;
00142         
00143         if(len < (int)(sizeof(def_lct_hdr_t))) {
00144                 printf("analyze_packet: packet too short %d\n", len);
00145                 fflush(stdout);
00146                 return HDR_ERROR;
00147         }
00148 
00149         def_lct_hdr = (def_lct_hdr_t*)data;
00150 
00151         *(unsigned short*)def_lct_hdr = ntohs(*(unsigned short*)def_lct_hdr);
00152 
00153         hdrlen += (int)(sizeof(def_lct_hdr_t));
00154 
00155         if(def_lct_hdr->version != ALC_VERSION) {
00156                 printf("ALC version: %i not supported!\n", def_lct_hdr->version);
00157                 fflush(stdout); 
00158                 return HDR_ERROR;
00159         }
00160 
00161         if(def_lct_hdr->reserved != 0) {
00162                 printf("Reserved field not zero!\n");
00163                 fflush(stdout);
00164                 return HDR_ERROR;
00165         }
00166 
00167         if(def_lct_hdr->flag_t != 0) {
00168                 printf("Sender Current Time not supported!\n");
00169                 fflush(stdout);
00170                 return HDR_ERROR;
00171         }
00172 
00173         if(def_lct_hdr->flag_r != 0) {
00174                 printf("Expected Residual Time not supported!\n");
00175                 fflush(stdout);
00176                 return HDR_ERROR;
00177         }
00178 
00179         if(def_lct_hdr->flag_b == 1) {
00180                 /**** TODO ****/
00181         }
00182 
00183         if(def_lct_hdr->flag_c != 0) {
00184                 printf("Only 32 bits CCI-field supported!\n");
00185                 fflush(stdout);
00186                 return HDR_ERROR;
00187         }
00188         else {
00189                 if(def_lct_hdr->cci != 0) {
00190 
00191                         if(ch->s->cc_id == RLC) {
00192 
00193                                 retval = mad_rlc_analyze_cci(ch->s, (rlc_hdr_t*)(data + 4));
00194 
00195                                 if(retval < 0) {
00196                                         return HDR_ERROR;
00197                                 }
00198                         }
00199                 }
00200         }
00201 
00202         if(def_lct_hdr->flag_h == 1) {
00203 
00204                 if(def_lct_hdr->flag_s == 0) { /* TSI 16 bits */
00205                         word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00206                         hdrlen += 4;
00207 
00208                         tsi = (word & 0xFFFF0000) >> 16;
00209 
00210                         if(tsi != ch->s->tsi) {
00211 #ifdef _MSC_VER
00212                                 printf("Packet to wrong session: wrong TSI: %I64u\n", tsi);
00213 #else
00214                                 printf("Packet to wrong session: wrong TSI: %llu\n", tsi);
00215 #endif
00216                                 fflush(stdout);
00217                                 return HDR_ERROR;
00218                         }
00219                 }
00220                 else if(def_lct_hdr->flag_s == 1) { /* TSI 48 bits */
00221 
00222                         ull = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00223                         tsi = ull << 16;
00224                         hdrlen += 4;
00225 
00226                         word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00227                         hdrlen += 4;
00228 
00229                         tsi += (word & 0xFFFF0000) >> 16;
00230 
00231                         if(tsi != ch->s->tsi) {
00232 #ifdef _MSC_VER
00233                                 printf("Packet to wrong session: wrong TSI: %I64u\n", tsi);
00234 #else
00235                                 printf("Packet to wrong session: wrong TSI: %llu\n", tsi);
00236 #endif
00237                                 fflush(stdout);
00238                                 return HDR_ERROR;
00239                         }
00240                 }
00241 
00242                 if(def_lct_hdr->flag_a == 1) {
00243                         ch->s->state = SAFlagReceived;
00244                 }
00245 
00246                 if(def_lct_hdr->flag_o == 0) { /* TOI 16 bits */
00247                         toi = (word & 0x0000FFFF);
00248                 }
00249                 else if(def_lct_hdr->flag_o == 1) { /* TOI 48 bits */
00250 
00251                         ull = (word & 0x0000FFFF);
00252                         toi = ull << 32;
00253 
00254                         toi += ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00255                         hdrlen += 4;
00256                 }
00257                 else {
00258                         printf("Only 16, 32, 48 or 64 bits TOI-field supported!\n");
00259                         fflush(stdout);
00260                         return HDR_ERROR;
00261                 }
00262                 /*else if(def_lct_hdr->flag_o == 2) {                   
00263                 }
00264                 else if(def_lct_hdr->flag_o == 3) {
00265                 }*/
00266         }
00267         else {
00268                 if(def_lct_hdr->flag_s == 1) { /* TSI 32 bits */
00269                         tsi = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00270                         hdrlen += 4;
00271 
00272                         if(tsi != ch->s->tsi) {
00273 #ifdef _MSC_VER
00274                                 printf("Packet to wrong session: wrong TSI: %I64u\n", tsi);
00275 #else
00276                                 printf("Packet to wrong session: wrong TSI: %llu\n", tsi);
00277 #endif
00278                                 fflush(stdout);
00279                                 return HDR_ERROR;
00280                         }
00281                 }
00282                 else {
00283                         printf("Transport Session Identifier not present!\n");
00284                         fflush(stdout);
00285                         return HDR_ERROR;
00286                 }
00287 
00288                 if(def_lct_hdr->flag_a == 1) {
00289                         ch->s->state = SAFlagReceived;
00290                 }
00291 
00292                 if(def_lct_hdr->flag_o == 0) { /* TOI 0 bits */
00293 
00294                         if(def_lct_hdr->flag_a != 1) {
00295                                 printf("Transport Object Identifier not present!\n");
00296                                 fflush(stdout);
00297                                 return HDR_ERROR;
00298                         }
00299                         else {
00300                                 return EMPTY_PACKET;
00301                         }
00302                 }
00303                 else if(def_lct_hdr->flag_o == 1) { /* TOI 32 bits */
00304                         toi = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00305                         hdrlen += 4;
00306                 }
00307                 else if(def_lct_hdr->flag_o == 2) { /* TOI 64 bits */
00308 
00309                         ull = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00310                         toi = ull << 32;
00311                         hdrlen += 4;
00312 
00313                         toi += ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00314                         hdrlen += 4;
00315                 }
00316                 else {
00317                         printf("Only 16, 32, 48 or 64 bits TOI-field supported!\n");
00318                         fflush(stdout);
00319                         return HDR_ERROR;
00320                 }
00321                 /*else if(def_lct_hdr->flag_o == 3) {
00322                 }*/
00323         }
00324 
00325         if(!toi == FDT_TOI) {
00326                 wanted_obj = get_wanted_object(ch->s, toi);
00327 
00328                 if(wanted_obj == NULL) {
00329 
00330                         if(ch->s->rx_fdt_instance_list == NULL || ch->s->waiting_fdt_instance == TRUE) {
00331                                 return WAITING_FDT;
00332                         }
00333                         else {
00334                                 /*printf("Packet to not wanted toi: %i\n", toi);
00335                                 fflush(stdout);*/
00336                                 return HDR_ERROR;
00337                         }
00338                 }
00339 
00340                 es_len = wanted_obj->es_len;
00341                 max_sb_len = wanted_obj->max_sb_len;
00342                 max_nb_of_es = wanted_obj->max_nb_of_es;
00343                 fec_enc_id = wanted_obj->fec_enc_id;
00344                 transfer_len = wanted_obj->transfer_len;
00345                 content_enc_algo = wanted_obj->content_enc_algo;
00346 
00347                 if(fec_enc_id == RS_FEC_ENC_ID) {
00348                         finite_field = wanted_obj->finite_field;
00349                         nb_of_es_per_group = wanted_obj->nb_of_es_per_group;
00350                 }
00351                 else {
00352                         fec_inst_id = wanted_obj->fec_inst_id;
00353                 }
00354         }
00355 
00356         fec_enc_id = def_lct_hdr->codepoint;
00357 
00358         if(!(fec_enc_id == COM_NO_C_FEC_ENC_ID || fec_enc_id == RS_FEC_ENC_ID ||
00359                 fec_enc_id == SB_SYS_FEC_ENC_ID || fec_enc_id == SIMPLE_XOR_FEC_ENC_ID)) {
00360                         printf("FEC Encoding ID: %i is not supported!\n", fec_enc_id);
00361                         fflush(stdout);
00362                         return HDR_ERROR;
00363         }
00364 
00365         if(def_lct_hdr->hdr_len > (hdrlen >> 2)) {
00366 
00367                 /* LCT header extensions(EXT_FDT, EXT_CENC, EXT_FTI, EXT_AUTH, EXT_NOP)
00368                 go through all possible EH */
00369 
00370                 exthdrlen = def_lct_hdr->hdr_len - (hdrlen >> 2);
00371 
00372                 while(exthdrlen > 0) {
00373 
00374                         word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00375                         hdrlen += 4;
00376                         exthdrlen--;
00377 
00378                         het = (word & 0xFF000000) >> 24;
00379 
00380                         if(het < 128) {
00381                                 hel = (word & 0x00FF0000) >> 16;
00382                         }
00383 
00384                         switch(het) {
00385 
00386           case EXT_FDT:
00387 
00388                   flute_version = (word & 0x00F00000) >> 20;
00389                   fdt_instance_id = (word & 0x000FFFFF);
00390 
00391                   if(flute_version != FLUTE_VERSION) {
00392                           printf("FLUTE version: %i is not supported\n", flute_version);
00393                           return HDR_ERROR;
00394                   }
00395 
00396                   break;
00397 
00398           case EXT_CENC:
00399 
00400                   content_enc_algo = (word & 0x00FF0000) >> 16;
00401                   reserved = (word & 0x0000FFFF);
00402 
00403                   if(reserved != 0) {
00404                           printf("Bad CENC header extension!\n");
00405                           return HDR_ERROR;
00406                   }
00407 
00408 #ifdef USE_ZLIB
00409                   if((content_enc_algo != 0) && (content_enc_algo != ZLIB)) {
00410                           printf("Only NULL or ZLIB content encoding supported with FDT Instance!\n");
00411                           return HDR_ERROR;
00412                   }
00413 #else
00414                   if(content_enc_algo != 0) {
00415                           printf("Only NULL content encoding supported with FDT Instance!\n");
00416                           return HDR_ERROR;
00417                   }
00418 #endif
00419 
00420                   break;
00421 
00422           case EXT_FTI:
00423 
00424                   if(hel != 4) {
00425                           printf("Bad FTI header extension, length: %i\n", hel);
00426                           return HDR_ERROR;
00427                   }
00428 
00429                   transfer_len = ((word & 0x0000FFFF) << 16);
00430 
00431                   transfer_len += ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00432                   hdrlen += 4;
00433                   exthdrlen--;
00434 
00435                   word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00436                   hdrlen += 4;
00437                   exthdrlen--;
00438 
00439                   if(fec_enc_id == RS_FEC_ENC_ID) {
00440                           finite_field = (word & 0xFF000000) >> 24;
00441                           nb_of_es_per_group = (word & 0x00FF0000) >> 16;
00442 
00443                           /*if(finite_field < 2 || finite_field >16) {
00444                                   printf("Finite Field parameter: %i not supported!\n", finite_field);
00445                                   return HDR_ERROR;
00446                           }*/
00447                   }
00448                   else {
00449                           fec_inst_id = ((word & 0xFFFF0000) >> 16);
00450 
00451                           if((fec_enc_id == COM_NO_C_FEC_ENC_ID || fec_enc_id == SIMPLE_XOR_FEC_ENC_ID)
00452                                   && fec_inst_id != 0) {
00453                                           printf("Bad FTI header extension.\n");
00454                                           return HDR_ERROR;
00455                           }
00456                           else if(fec_enc_id == SB_SYS_FEC_ENC_ID && fec_inst_id != REED_SOL_FEC_INST_ID) {
00457                                   printf("FEC Encoding %i/%i is not supported!\n", fec_enc_id, fec_inst_id);
00458                                   return HDR_ERROR;
00459                           }
00460                   }
00461 
00462                   if(((fec_enc_id == COM_NO_C_FEC_ENC_ID) || (fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) 
00463                           ||(fec_enc_id == SB_LB_E_FEC_ENC_ID) || (fec_enc_id == COM_FEC_ENC_ID))){
00464 
00465                                   es_len = (word & 0x0000FFFF);
00466 
00467                                   max_sb_len = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00468                                   hdrlen += 4;
00469                                   exthdrlen--;
00470                   }
00471                   else if(((fec_enc_id == RS_FEC_ENC_ID) || (fec_enc_id == SB_SYS_FEC_ENC_ID))) {
00472 
00473                           es_len = (word & 0x0000FFFF);
00474 
00475                           word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00476 
00477                           max_sb_len = ((word & 0xFFFF0000) >> 16);
00478                           max_nb_of_es = (word & 0x0000FFFF);
00479                           hdrlen += 4;
00480                           exthdrlen--;
00481                   }
00482                   break;
00483 
00484           case EXT_AUTH:
00485                   /* ignore */
00486                   hdrlen += (hel-1) << 2;
00487                   exthdrlen -= (hel-1);
00488                   break;
00489 
00490           case EXT_NOP:
00491                   /* ignore */
00492                   hdrlen += (hel-1) << 2;
00493                   exthdrlen -= (hel-1);
00494                   break;
00495 
00496           case EXT_TIME:
00497                   /* ignore */
00498                   hdrlen += (hel-1) << 2;
00499                   exthdrlen -= (hel-1);
00500                   break;
00501 
00502           default:
00503 
00504                   printf("Unknown LCT Extension header, het: %i\n", het);
00505                   return HDR_ERROR;
00506                   break;
00507                         }
00508                 }
00509         }
00510 
00511         if((hdrlen >> 2) != def_lct_hdr->hdr_len) {
00512                 /* Wrong header length */
00513                 printf("analyze_packet: packet header length %d, should be %d\n", (hdrlen >> 2),
00514                         def_lct_hdr->hdr_len);
00515                 return HDR_ERROR;
00516         }
00517 
00518         /* Check if we have an empty packet without FEC Payload ID */
00519         if(hdrlen == len) {
00520                 return EMPTY_PACKET;            
00521         }
00522 
00523         if(toi == 0) {
00524                 if(is_received_instance(ch->s, fdt_instance_id)) {
00525                         return DUP_PACKET;
00526                 }
00527                 else {
00528                         ch->s->waiting_fdt_instance = TRUE;
00529                 }
00530         }
00531 
00532         if((fec_enc_id == COM_NO_C_FEC_ENC_ID) || (fec_enc_id ==  COM_FEC_ENC_ID)) {
00533 
00534                 if(len < hdrlen + 4) {
00535                         printf("analyze_packet: packet too short %d\n", len);
00536                         return HDR_ERROR;
00537                 }
00538 
00539                 word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00540                 sbn = (word >> 16);
00541                 esi = (word & 0xFFFF);
00542                 hdrlen += 4;
00543         }
00544         else if(fec_enc_id == RS_FEC_ENC_ID) {
00545                 word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00546 
00547                 sbn = (word >> finite_field);
00548                 esi = (word & ((1 << finite_field) - 1));
00549 
00550                 /* finite_field is not used furthermore, default value used in fec.c (#define GF_BITS  8 in fec.h) */
00551 
00552                 hdrlen += 4;
00553         }
00554         else if(((fec_enc_id == SB_LB_E_FEC_ENC_ID) || (fec_enc_id == SIMPLE_XOR_FEC_ENC_ID))) {
00555                 if (len < hdrlen + 8) {
00556                         printf("analyze_packet: packet too short %d\n", len);
00557                         return HDR_ERROR;
00558                 }
00559 
00560                 sbn = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00561                 hdrlen += 4;
00562                 esi = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00563                 hdrlen += 4;
00564 
00565         }
00566         else if(fec_enc_id == SB_SYS_FEC_ENC_ID) {
00567                 if (len < hdrlen + 8) {
00568                         printf("analyze_packet: packet too short %d\n", len);
00569                         return HDR_ERROR;
00570                 }
00571 
00572                 sbn = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00573 
00574                 hdrlen += 4;
00575                 word = ntohl(*(unsigned int*)((char*)def_lct_hdr + hdrlen));
00576                 sb_len = (word >> 16);
00577                 esi = (word & 0xFFFF);
00578                 hdrlen += 4;
00579         }
00580 
00581         /* TODO: check if instance_id is set --> EXT_FDT header exists in packet */
00582 
00583         if(len - hdrlen != 0) {
00584 
00585                 /* check if we have enough information */
00586 
00587                 if(((transfer_len == 0) || (fec_enc_id == -1) || ((fec_enc_id > 127) && (fec_inst_id == -1)) ||
00588                         (es_len == 0) || (max_sb_len == 0))) {
00589 #ifdef _MSC_VER
00590                                 printf("Not enough information to create Transport Object, TOI: %I64u\n", toi);
00591 #else
00592                                 printf("Not enough information to create Transport Object, TOI: %llu\n", toi);
00593 #endif
00594                                 fflush(stdout);
00595                                 return HDR_ERROR;
00596                 }
00597 
00598                 if(fec_enc_id == RS_FEC_ENC_ID) {
00599                         nb_of_symbols = nb_of_es_per_group;
00600                 }
00601                 else {
00602                         /* Let's check how many symbols are in the packet */
00603                         /* Encoding Symbol group length = len - hdrlen */
00604 
00605                         nb_of_symbols = (unsigned short)ceil((double)(len - hdrlen) / es_len);
00606                 }
00607 
00608                 /* Now we have to go through each symbol */
00609 
00610                 for(j = 0; j < nb_of_symbols; j++) {
00611 
00612 #ifdef USE_RETRIEVE_UNIT
00613                         /* Retrieve a transport unit from the session pool  */
00614                         trans_unit = retrieve_unit(ch->s, es_len);
00615 #else
00616                         /* Create transport unit */
00617                         trans_unit = create_units(1);
00618 #endif
00619 
00620                         if(trans_unit == NULL) {
00621                                 return MEM_ERROR;
00622                         }
00623 
00624                         trans_unit->esi = esi + j;
00625                         trans_unit->len = es_len;
00626 
00627 #ifndef USE_RETRIEVE_UNIT
00628                         /* Alloc memory for incoming TU data */
00629                         if(!(trans_unit->data = (char*)calloc(es_len, sizeof(char)))) {
00630                                 printf("Could not alloc memory for transport unit's data!\n");
00631                                 return MEM_ERROR;
00632                         }
00633 #endif
00634 
00635                         memcpy(trans_unit->data, (data + hdrlen + j*es_len), trans_unit->len);
00636 
00637                         /* Check if object already exist */
00638                         if(toi == FDT_TOI) {
00639                                 trans_obj = object_exist(fdt_instance_id, ch->s, 0);
00640                         }
00641                         else {
00642                                 trans_obj = object_exist(toi, ch->s, 1);
00643                         }
00644 
00645                         if(trans_obj == NULL) {
00646 
00647                                 trans_obj = create_object();
00648 
00649                                 if(trans_obj == NULL) {
00650                                         return MEM_ERROR;
00651                                 }
00652 
00653                                 if(toi == FDT_TOI) {
00654                                         trans_obj->toi = fdt_instance_id;
00655                                         trans_obj->content_enc_algo = content_enc_algo;
00656                                 }
00657                                 else {
00658                                         trans_obj->toi = toi;
00659 
00660 
00661                                         if(ch->s->rx_memory_mode == 1 || ch->s->rx_memory_mode == 2) {
00662 
00663                                                 memset(filename, 0, MAX_PATH_LENGTH);
00664 
00665                                                 if(content_enc_algo == 0) {
00666                                                         sprintf(filename, "%s/%s", ch->s->base_dir, "object_XXXXXX");
00667                                                         mktemp(filename);
00668                                                 }
00669 #ifdef USE_ZLIB
00670                                                 else if(content_enc_algo == GZIP) {
00671                                                         sprintf(filename, "%s/%s", ch->s->base_dir, "object_XXXXXX");
00672                                                         mktemp(filename);
00673                                                         strcat(filename, GZ_SUFFIX);
00674                                                 }
00675 #endif
00676                                                 else if(content_enc_algo == PAD) {
00677                                                         sprintf(filename, "%s/%s", ch->s->base_dir, "object_XXXXXX");
00678                                                         mktemp(filename);
00679                                                         strcat(filename, PAD_SUFFIX);
00680                                                 }
00681 
00682                                                 /* Alloc memory for tmp_filename */
00683                                                 if(!(trans_obj->tmp_filename = (char*)calloc(strlen(filename)+1, sizeof(char)))) {
00684                                                         printf("Could not alloc memory for tmp_filename!\n");
00685                                                         return MEM_ERROR;
00686                                                 }
00687 
00688                                                 memcpy(trans_obj->tmp_filename, filename, strlen(filename));
00689 
00690 #ifdef _MSC_VER
00691                                                 if((trans_obj->fd = open((const char*)trans_obj->tmp_filename,
00692                                                         _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC , _S_IWRITE)) < 0) {
00693 #else
00694                                                 if((trans_obj->fd = open64(trans_obj->tmp_filename,
00695                                                         O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU)) < 0) {
00696 #endif
00697                                                                 printf("Error: unable to open file %s\n", trans_obj->tmp_filename);
00698                                                                 fflush(stdout);
00699                                                                 return MEM_ERROR;
00700                                                 }
00701                                         }
00702 
00703 
00704                                         if(ch->s->rx_memory_mode == 2) {
00705 
00706                                                 /* when receiver is in large file mode a tmp file is used to store the data symbols */
00707 
00708                                                 memset(filename, 0, MAX_PATH_LENGTH);
00709                                                 sprintf(filename, "%s/%s", ch->s->base_dir, "st_XXXXXX");
00710                                                 mktemp(filename);
00711 
00712                                                 /* Alloc memory for tmp_st_filename */
00713                                                 if(!(trans_obj->tmp_st_filename = (char*)calloc(strlen(filename)+1, sizeof(char)))) {
00714                                                         printf("Could not alloc memory for tmp_st_filename!\n");
00715                                                         return MEM_ERROR;
00716                                                 }
00717 
00718                                                 memcpy(trans_obj->tmp_st_filename, filename, strlen(filename));
00719 
00720 #ifdef _MSC_VER
00721                                                 if((trans_obj->fd_st = open((const char*)trans_obj->tmp_st_filename,
00722                                                         _O_RDWR | _O_CREAT | _O_BINARY | _O_TRUNC , _S_IREAD | _S_IWRITE)) < 0) {
00723 #else
00724                                                 if((trans_obj->fd_st = open64(trans_obj->tmp_st_filename,
00725                                                         O_RDWR | O_CREAT | O_TRUNC , S_IRWXU)) < 0) {
00726 #endif
00727                                                                 printf("Error: unable to open file %s\n", trans_obj->tmp_st_filename);
00728                                                                 fflush(stdout);
00729                                                                 return MEM_ERROR;
00730                                                 }
00731                                         }  
00732                                 }
00733 
00734                                 trans_obj->len = transfer_len;
00735                                 trans_obj->fec_enc_id = (unsigned char)fec_enc_id;
00736                                 trans_obj->fec_inst_id = (unsigned short)fec_inst_id;
00737                                 trans_obj->es_len = es_len;
00738                                 trans_obj->max_sb_len = max_sb_len;
00739 
00740                                 /* Let's calculate the blocking structure for this object */
00741 
00742                                 trans_obj->bs = compute_blocking_structure(transfer_len, max_sb_len, es_len);
00743 
00744                                 if(!(trans_obj->block_list = (trans_block_t*)calloc(trans_obj->bs->N, sizeof(trans_block_t)))) {
00745                                         printf("Could not alloc memory for transport block list!\n");
00746                                         return MEM_ERROR;
00747                                 }
00748 
00749                                 if(toi == FDT_TOI) {
00750                                         insert_object(trans_obj, ch->s, 0);
00751                                 }
00752                                 else {
00753                                         insert_object(trans_obj, ch->s, 1);
00754                                 }
00755                         }
00756 
00757                         trans_block = trans_obj->block_list+sbn;
00758 
00759                         if(trans_block->nb_of_rx_units == 0) {
00760                                 trans_block->sbn = sbn;
00761 
00762                                 if(fec_enc_id == COM_NO_C_FEC_ENC_ID) { 
00763 
00764                                         if(sbn < trans_obj->bs->I) {
00765                                                 trans_block->k = trans_obj->bs->A_large;
00766                                         }
00767                                         else {
00768                                                 trans_block->k = trans_obj->bs->A_small;
00769                                         }
00770                                 }
00771                                 else if(fec_enc_id == SB_SYS_FEC_ENC_ID) {
00772 
00773                                         trans_block->k = sb_len;
00774                                         trans_block->max_k = max_sb_len;
00775                                         trans_block->max_n = max_nb_of_es;
00776                                 }
00777                                 else if(fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
00778 
00779                                         if(sbn < trans_obj->bs->I) {
00780                                                 trans_block->k = trans_obj->bs->A_large;
00781                                         }
00782                                         else {
00783                                                 trans_block->k = trans_obj->bs->A_small;
00784                                         }
00785 
00786                                         trans_block->max_k = max_sb_len;
00787                                 }
00788                                 else if(fec_enc_id == RS_FEC_ENC_ID) {
00789 
00790                                         if(sbn < trans_obj->bs->I) {
00791                                                 trans_block->k = trans_obj->bs->A_large;
00792                                         }
00793                                         else {
00794                                                 trans_block->k = trans_obj->bs->A_small;
00795                                         }
00796 
00797                                         trans_block->max_k = max_sb_len;
00798                                         trans_block->max_n = max_nb_of_es;
00799 
00800                                         /*trans_block->finite_field = finite_field;*/
00801                                 }
00802                         }
00803 
00804                         if(!block_ready_to_decode(trans_block)) {
00805 
00806                                 if(insert_unit(trans_unit, trans_block, trans_obj) != 1) {
00807 
00808                                         if(toi == FDT_TOI || ch->s->rx_memory_mode == 0) { 
00809 
00810                                                 if(block_ready_to_decode(trans_block)) {
00811                                                         trans_obj->nb_of_ready_blocks++;
00812                                                 }
00813                                         }
00814 
00815                                         /* if large file mode data symbol is stored in the tmp file */
00816                                         if(toi != FDT_TOI && ch->s->rx_memory_mode == 2) {
00817 
00818 #ifdef _MSC_VER
00819                                                 trans_unit->offset = _lseeki64(trans_obj->fd_st, 0, SEEK_END);
00820 #else
00821                                                 trans_unit->offset = lseek64(trans_obj->fd_st, 0, SEEK_END);
00822 #endif
00823                                                 if(trans_unit->offset == -1) {
00824 #ifdef _MSC_VER
00825                                                         printf("lseek error, toi: %I64u\n", toi);
00826 #else
00827                                                         printf("lseek error, toi: %llu\n", toi);
00828 #endif
00829                                                         fflush(stdout);
00830                                                         set_session_state(ch->s->s_id, SExiting);
00831                                                         return MEM_ERROR;
00832                                                 }
00833 
00834                                                 if(write(trans_obj->fd_st, trans_unit->data, (unsigned int)trans_unit->len) == -1) {
00835 #ifdef _MSC_VER
00836                                                         printf("write error, toi: %I64u, sbn: %i\n", toi, sbn);
00837 #else
00838                                                         printf("write error, toi: %llu, sbn: %i\n", toi, sbn);
00839 #endif
00840                                                         fflush(stdout);
00841                                                         set_session_state(ch->s->s_id, SExiting);
00842                                                         return MEM_ERROR;
00843                                                 }
00844 
00845 #ifndef USE_RETRIEVE_UNIT
00846                                                 free(trans_unit->data);
00847                                                 trans_unit->data = NULL;
00848 #endif
00849                                         }
00850 
00851                                         if(((toi == FDT_TOI && ch->s->verbosity == 4) || (toi != FDT_TOI && ch->s->verbosity > 1))) {
00852 
00853                                                 rx_percent = (double)((double)100 *
00854                                                         ((double)(long long)trans_obj->rx_bytes/(double)(long long)trans_obj->len));
00855 
00856                                                 if(((rx_percent >= (trans_obj->last_print_rx_percent + 1)) || (rx_percent == 100))) {
00857                                                         trans_obj->last_print_rx_percent = rx_percent;
00858                                                         printf("%.2f%% of object received (TOI=%llu LAYERS=%i)\n", rx_percent,
00859                                                                 toi, ch->s->nb_channel);
00860                                                         fflush(stdout);
00861                                                 }
00862                                         }
00863                                 }
00864                                 else {
00865 
00866 #ifdef USE_RETRIEVE_UNIT
00867                                         trans_unit->used = 0;
00868 #else
00869                                         free(trans_unit->data);
00870                                         free(trans_unit);
00871 #endif
00872                                         return DUP_PACKET;
00873                                 }
00874                         }
00875                         else {
00876 
00877 #ifdef USE_RETRIEVE_UNIT
00878                                 trans_unit->used = 0;
00879 #else
00880                                 free(trans_unit->data);
00881                                 free(trans_unit);
00882 #endif
00883                                 return DUP_PACKET;
00884                         }
00885 
00886                         if(toi != FDT_TOI) {
00887 
00888                                 if(ch->s->rx_memory_mode == 1 || ch->s->rx_memory_mode == 2) {  
00889 
00890                                         if(block_ready_to_decode(trans_block)) {
00891 
00892                                                 if(ch->s->rx_memory_mode == 2){
00893 
00894                                                         /* We have to restore the data symbols to trans_units from the symbol store tmp file */
00895 
00896                                                         next_tu = trans_block->unit_list;
00897 
00898                                                         while(next_tu != NULL) {
00899 
00900                                                                 tu = next_tu;
00901 
00902 #ifdef _MSC_VER
00903                                                                 if(_lseeki64(trans_obj->fd_st, tu->offset, SEEK_SET) == -1) {
00904 #else
00905                                                                 if(lseek64(trans_obj->fd_st, tu->offset, SEEK_SET) == -1) {
00906 #endif
00907 
00908 #ifdef _MSC_VER
00909                                                                         printf("lseek error, toi: %I64u\n", toi);
00910 #else
00911                                                                         printf("alc_rx.c line 1035 lseek error, toi: %llu\n", toi);
00912 #endif
00913                                                                         fflush(stdout);
00914                                                                         set_session_state(ch->s->s_id, SExiting);
00915                                                                         return MEM_ERROR;
00916                                                                 }
00917 
00918                                                                 /* let's copy the data symbols from the tmp file to the memory */
00919 
00920                                                                 /* Alloc memory for restoring data symbol */
00921 
00922                                                                 if(!(tu->data = (char*)calloc(tu->len, sizeof(char)))) {
00923                                                                         printf("Could not alloc memory for transport unit's data!\n");
00924                                                                         return MEM_ERROR;
00925                                                                 }
00926 
00927                                                                 if(read(trans_obj->fd_st, tu->data, tu->len) == -1) {
00928 #ifdef _MSC_VER
00929                                                                         printf("read error, toi: %I64u, sbn: %i\n", toi, sbn);
00930 #else
00931                                                                         printf("read error, toi: %llu, sbn: %i\n", toi, sbn);
00932 #endif
00933                                                                         fflush(stdout);
00934                                                                         set_session_state(ch->s->s_id, SExiting);
00935                                                                         return MEM_ERROR;
00936                                                                 }
00937 
00938                                                                 next_tu = tu->next;
00939                                                         }
00940                                                 }
00941 
00942                                                 /* decode the block and save data to the tmp file */
00943 
00944                                                 if(fec_enc_id == COM_NO_C_FEC_ENC_ID) {
00945                                                         buf = null_fec_decode_src_block(trans_block, &block_len, es_len);
00946                                                 }
00947                                                 else if(fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
00948                                                         buf = xor_fec_decode_src_block(trans_block, &block_len, es_len);
00949                                                 }
00950                                                 else if(fec_enc_id == RS_FEC_ENC_ID) {
00951                                                         buf = rs_fec_decode_src_block(trans_block, &block_len, es_len);
00952                                                 }
00953                                                 else if(fec_enc_id == SB_SYS_FEC_ENC_ID && fec_inst_id == REED_SOL_FEC_INST_ID) {               
00954                                                         buf = rs_fec_decode_src_block(trans_block, &block_len, es_len);
00955                                                 }
00956 
00957                                                 if(buf == NULL) {
00958                                                         return MEM_ERROR;
00959                                                 }
00960 
00961                                                 /* We have to check if there is padding in the last source symbol of the last source block */
00962 
00963                                                 if(trans_block->sbn == ((trans_obj->bs->N) - 1)) {
00964                                                         block_len = (trans_obj->len - (es_len * (trans_obj->bs->I * trans_obj->bs->A_large +
00965                                                                 (trans_obj->bs->N - trans_obj->bs->I -1) * trans_obj->bs->A_small)));
00966                                                 }
00967 
00968                                                 if(trans_block->sbn < trans_obj->bs->I) {
00969                                                         pos = ( (unsigned long long)trans_block->sbn * (unsigned long long)trans_obj->bs->A_large * (unsigned long long)es_len );
00970                                                 }
00971                                                 else {
00972                                                         pos = ( ( ( (unsigned long long)trans_obj->bs->I * (unsigned long long)trans_obj->bs->A_large ) +
00973                                                                 ( (unsigned long long)trans_block->sbn - (unsigned long long)trans_obj->bs->I )  *
00974                                                                 (unsigned long long)trans_obj->bs->A_small ) * (unsigned long long)es_len );
00975                                                 }
00976 
00977                                                 /* set correct position */
00978 
00979 #ifdef _MSC_VER
00980                                                 if(_lseeki64(trans_obj->fd, pos, SEEK_SET) == -1) {
00981 #else
00982                                                 if(lseek64(trans_obj->fd, pos, SEEK_SET) == -1) {
00983 #endif
00984 
00985 #ifdef _MSC_VER
00986                                                         printf("lseek error, toi: %I64u\n", toi);
00987 #else
00988                                                         printf("alc_rx.c line 1111 lseek error, toi: %llu\n", toi);
00989 #endif
00990                                                         fflush(stdout);
00991                                                         free(buf);
00992                                                         set_session_state(ch->s->s_id, SExiting);
00993                                                         return MEM_ERROR;
00994                                                 }
00995 
00996                                                 if(write(trans_obj->fd, buf, (unsigned int)block_len) == -1) {
00997 #ifdef _MSC_VER
00998                                                         printf("write error, toi: %I64u, sbn: %i\n", toi, sbn);
00999 #else
01000                                                         printf("write error, toi: %llu, sbn: %i\n", toi, sbn);
01001 #endif
01002                                                         fflush(stdout);
01003                                                         free(buf);
01004                                                         set_session_state(ch->s->s_id, SExiting);
01005                                                         return MEM_ERROR;
01006                                                 }
01007 
01008                                                 trans_obj->nb_of_ready_blocks++;
01009 
01010                                                 free(buf);
01011 
01012 #ifdef USE_RETRIEVE_UNIT
01013                                                 free_units2(trans_block);
01014 #else
01015                                                 free_units(trans_block);
01016 #endif
01017 
01018                                                 if(ch->s->verbosity > 2) {      
01019 #ifdef _MSC_VER
01020                                                         printf("%u/%u Source Blocks decoded (TOI=%I64u SBN=%u)\n", trans_obj->nb_of_ready_blocks, trans_obj->bs->N, toi, sbn);
01021                                                         fflush(stdout);
01022 #else
01023                                                         printf("%u/%u Source Blocks decoded (TOI=%llu SBN=%u)\n", trans_obj->nb_of_ready_blocks, trans_obj->bs->N, toi, sbn);
01024                                                         fflush(stdout);
01025 #endif
01026                                                 }
01027                                         }
01028                                 }
01029                         }
01030                 } /* End of "for(j = 0; j < nb_of_symbols; j++) {" */
01031         }
01032         else { /* We have an empty packet with FEC Payload ID */
01033                 return EMPTY_PACKET;    
01034         }
01035 
01036         return OK;
01037 }
01038 
01049 int recv_packet(alc_session_t *s) {
01050 
01051   char recvbuf[MAX_PACKET_LENGTH];
01052   int recvlen;
01053   int i;
01054   int retval;
01055   int recv_pkts = 0;
01056   alc_channel_t *ch;
01057   struct sockaddr_storage from;
01058   
01059   double loss_prob;
01060   
01061   alc_rcv_container_t *container;
01062   int my_list_not_empty = 0;
01063   
01064 #ifdef _MSC_VER
01065   int fromlen;
01066 #else
01067   socklen_t fromlen;
01068 #endif
01069   
01070   time_t systime;
01071   unsigned long long curr_time;
01072   
01073   memset(recvbuf, 0, MAX_PACKET_LENGTH);
01074   
01075   for(i = 0; i < s->nb_channel; i++) {
01076     ch = s->ch_list[i];
01077     
01078     if(ch->receiving_list != NULL) {
01079       if(!is_empty(ch->receiving_list)) {
01080         ++my_list_not_empty;
01081         break;
01082       }
01083     }
01084   }
01085   
01086   if(my_list_not_empty == 0) {
01087     
01088     if(s->stoptime != 0) {
01089       time(&systime);
01090       curr_time = systime + 2208988800U;
01091       
01092       if(curr_time >= s->stoptime) {
01093         s->state = SExiting;
01094         return -2;
01095       }
01096     }
01097     
01098 #ifdef _MSC_VER
01099     Sleep(500);
01100 #else
01101     usleep(500000);
01102 #endif
01103     
01104     if(s->state == SAFlagReceived) {
01105       s->state = STxStopped;
01106     }
01107     
01108     return 0;
01109   }
01110   
01111   for(i = 0; i < s->nb_channel; i++) {
01112     ch = s->ch_list[i];
01113     
01114     if(!is_empty(ch->receiving_list)) {
01115       assert(ch->rx_socket_thread_id != 0);
01116       
01117       container = (alc_rcv_container_t*)pop_front(ch->receiving_list);
01118       
01119       assert(container != NULL);
01120       
01121       recvlen = container->recvlen;
01122       from = container->from;
01123       fromlen = container->fromlen;
01124       memcpy(recvbuf, container->recvbuf, MAX_PACKET_LENGTH);
01125       
01126       if(recvlen < 0) {
01127         
01128         free(container);
01129         container = NULL;
01130         
01131         if(s->state == SExiting) {
01132           printf("recv_packet() SExiting\n");
01133           fflush(stdout);
01134           return -2;
01135         }
01136         else if(s->state == SClosed) {
01137           printf("recv_packet() SClosed\n");
01138           fflush(stdout);
01139           return 0;
01140         }
01141         else {
01142 #ifdef _MSC_VER
01143           printf("recvfrom failed: %d\n", WSAGetLastError());
01144           fflush(stdout);
01145 #else
01146           printf("recvfrom failed: %d\n", errno);
01147 #endif
01148           return -1;
01149         }
01150       }
01151       
01152       loss_prob = 0;
01153       
01154       if(ch->s->simul_losses) {
01155         if(ch->previous_lost == TRUE) {
01156           loss_prob = ch->s->loss_ratio2;
01157         }
01158         else {
01159           loss_prob = ch->s->loss_ratio1;
01160         }
01161       }
01162       
01163       if(!randomloss(loss_prob)) {
01164         
01165         retval = analyze_packet(recvbuf, recvlen, ch);
01166         
01167         if(ch->s->cc_id == RLC) {
01168           
01169           if(((ch->s->rlc->drop_highest_layer) && (ch->s->nb_channel != 1))) {
01170             
01171             ch->s->rlc->drop_highest_layer = FALSE;
01172             close_alc_channel(ch->s->ch_list[ch->s->nb_channel - 1], ch->s);
01173           }
01174         }
01175         
01176         if(retval == WAITING_FDT) {
01177           push_front(ch->receiving_list, (void*)container);
01178         }
01179         else {
01180           free(container);
01181           container = NULL;
01182           
01183           if(retval == HDR_ERROR) {
01184             continue;
01185           }
01186           else if(retval == DUP_PACKET) {
01187             continue;
01188           }
01189           else if(retval == MEM_ERROR) {
01190             return -1;
01191           }
01192           
01193           recv_pkts++;
01194           
01195           ch->previous_lost = FALSE;
01196         }
01197       }
01198       else {
01199         ch->previous_lost = TRUE;
01200       }
01201     }
01202   }    
01203   return recv_pkts;
01204 }
01205 
01206 void* rx_socket_thread(void *ch) {
01207 
01208   alc_channel_t *channel;
01209   alc_rcv_container_t *container;
01210   fd_set read_set;
01211   struct timeval time_out;
01212   char hostname[100];
01213   int retval;
01214   
01215   channel = (alc_channel_t *)ch;
01216   
01217   while(channel->s->state == SActive) {
01218 
01219     time_out.tv_sec = 1;
01220     time_out.tv_usec = 0;
01221 
01222     FD_ZERO(&read_set);
01223     FD_SET(channel->rx_sock, &read_set);
01224     
01225     retval = select((int)channel->rx_sock + 1, &read_set, 0, 0, &time_out);
01226   
01227     if(retval > 0) {
01228       if(!(container = (alc_rcv_container_t*)calloc(1, sizeof(alc_rcv_container_t)))) {
01229         printf("Could not alloc memory for container!\n");
01230         continue;
01231       }
01232       
01233       if(channel->s->addr_family == PF_INET) {
01234         container->fromlen = sizeof(struct sockaddr_in);
01235       }
01236       else if(channel->s->addr_family == PF_INET6) {
01237         container->fromlen = sizeof(struct sockaddr_in6);
01238       }
01239       
01240       container->recvlen = recvfrom(channel->rx_sock, container->recvbuf, MAX_PACKET_LENGTH, 
01241                                     0, (struct sockaddr*)&(container->from), &(container->fromlen));
01242       
01243 #ifdef _MSC_VER
01244       if(container->recvlen == -1) {
01245         /* Some times when you quit program very quick after starting in Windows, select returns
01246            1, but there is nothing to be stored to the queue. Continue is for avoiding error */
01247         continue;
01248       }
01249 #endif
01250       
01251       getnameinfo((struct sockaddr*)&(container->from), container->fromlen,
01252                   hostname, sizeof(hostname), NULL, 0, NI_NUMERICHOST);
01253       
01254       if(strcmp(channel->s->src_addr, "") != 0) {
01255         if(strcmp(hostname, channel->s->src_addr) != 0) {
01256           printf("Packet to wrong session: wrong source: %s\n", hostname);
01257           fflush(stdout);
01258           continue;
01259         }
01260       }
01261       
01262       push_back(channel->receiving_list, (void*)container);
01263       
01264       if(strcmp(channel->s->src_addr, "") == 0) {
01265         if(channel->s->verbosity > 0) {
01266           printf("Locked to source: %s\n", hostname);
01267           fflush(stdout);
01268         }
01269                 
01270         memcpy(channel->s->src_addr, hostname, strlen(hostname));
01271       }
01272     }
01273     else {
01274       continue;
01275     }
01276   }
01277   
01278 #ifdef _MSC_VER
01279   _endthread();
01280 #else
01281   pthread_exit(0);
01282 #endif
01283   
01284   return NULL;
01285 }
01286 
01287 void join_rx_socket_thread(alc_channel_t *ch) {
01288 
01289 #ifndef _MSC_VER
01290   int join_retval;
01291 #endif
01292 
01293   if(ch != NULL) {
01294 #ifdef _MSC_VER
01295     WaitForSingleObject(ch->handle_rx_socket_thread, INFINITE);
01296     CloseHandle(ch->handle_rx_socket_thread);
01297 #else
01298     join_retval = pthread_join(ch->rx_socket_thread_id, NULL);
01299     assert(join_retval == 0);
01300     pthread_detach(ch->rx_socket_thread_id);
01301 #endif
01302   }
01303 }
01304 
01305 void* rx_thread(void *s) {
01306   
01307   alc_session_t *session;
01308   int retval = 0;
01309   
01310   srand((unsigned)time(NULL));
01311   
01312   session = (alc_session_t *)s;
01313   
01314   while(session->state == SActive || session->state == SAFlagReceived) {
01315     
01316     if(session->nb_channel != 0) {
01317       retval = recv_packet(session);
01318     }
01319     else {
01320 #ifdef _MSC_VER
01321       Sleep(1);
01322 #else
01323       usleep(1000);
01324 #endif
01325     }
01326   }
01327   
01328 #ifdef _MSC_VER
01329   _endthread();
01330 #else
01331   pthread_exit(0);
01332 #endif
01333   
01334   return NULL;
01335 }
01336 
01337 char* alc_recv(int s_id, unsigned long long toi, unsigned long long *data_len, int *retval) {
01338 
01339         BOOL obj_completed = FALSE;
01340         alc_session_t *s;
01341         char *buf = NULL; /* Buffer where to construct the object from data units */
01342         trans_obj_t *to;
01343         int object_exists = 0;
01344 
01345         s = get_alc_session(s_id);
01346 
01347         while(!obj_completed) {
01348 
01349                 if(s->state == SExiting) {
01350                         /*printf("alc_recv() SExiting\n");
01351                         fflush(stdout);*/
01352                         *retval = -2;
01353                         return NULL;    
01354                 }
01355                 else if(s->state == SClosed) {
01356                         /*printf("alc_recv() SClosed\n");
01357                         fflush(stdout);*/
01358                         *retval = 0;
01359                         return NULL;    
01360                 }
01361 
01362                 to = s->obj_list;
01363 
01364                 if(!object_exists) {
01365 
01366                         while(to != NULL) {
01367                                 if(to->toi == toi) {
01368                                         object_exists = 1;
01369                                         break;
01370                                 }
01371                                 to = to->next;
01372                         }
01373 
01374                         if(to == NULL) {
01375                                 continue;
01376                         }
01377                 }
01378 
01379                 obj_completed = object_completed(to);
01380 
01381                 if(((s->state == STxStopped) && (!obj_completed))) {
01382                         /*printf("alc_recv() STxStopped, toi: %i\n", toi);
01383                         fflush(stdout);*/
01384                         *retval = -3;
01385                         return NULL;    
01386                 }
01387 
01388 #ifdef _MSC_VER
01389                 Sleep(1);
01390 #else
01391                 usleep(1000);
01392 #endif
01393         }
01394         printf("\n");
01395 
01396         remove_wanted_object(s_id, toi);
01397 
01398         /* Parse data from object to data buffer, return buffer and buffer length */
01399 
01400         to = object_exist(toi, s, 1);
01401 
01402         if(to->fec_enc_id == COM_NO_C_FEC_ENC_ID) {
01403                 buf = null_fec_decode_object(to, data_len, s);
01404         }
01405         else if(to->fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
01406                 buf = xor_fec_decode_object(to, data_len, s);
01407         }
01408         else if(to->fec_enc_id == RS_FEC_ENC_ID) {
01409                 buf = rs_fec_decode_object(to, data_len, s);
01410         }
01411         else if(to->fec_enc_id == SB_SYS_FEC_ENC_ID && to->fec_inst_id == REED_SOL_FEC_INST_ID) {
01412                 buf = rs_fec_decode_object(to, data_len, s);
01413         }
01414 
01415         if(buf == NULL) {
01416                 *retval = -1;
01417         }
01418 
01419         free_object(to, s, 1);
01420         return buf;
01421 }
01422 
01423 char* alc_recv2(int s_id, unsigned long long *toi, unsigned long long *data_len, int *retval) {
01424 
01425         BOOL obj_completed = FALSE;
01426         alc_session_t *s;
01427 
01428         unsigned long long tmp_toi = 0;
01429 
01430         char *buf = NULL; /* Buffer where to construct the object from data units */
01431         trans_obj_t *to;
01432 
01433         s = get_alc_session(s_id);
01434 
01435         while(1) {
01436 
01437                 to = s->obj_list;
01438 
01439                 if(s->state == SExiting) {
01440                         /*printf("alc_recv2() SExiting\n");
01441                         fflush(stdout);*/
01442                         *retval = -2;
01443                         return NULL;    
01444                 }
01445                 else if(s->state == SClosed) {
01446                         /*printf("alc_recv2() SClosed\n");
01447                         fflush(stdout);*/
01448                         *retval = 0;
01449                         return NULL;    
01450                 }
01451                 else if(((s->state == STxStopped) && (to == NULL))) {
01452                         /*printf("alc_recv2() STxStopped\n");
01453                         fflush(stdout);*/
01454                         *retval = -3;
01455                         return NULL;    
01456                 }
01457 
01458                 while(to != NULL) {
01459 
01460                         if(s->state == SExiting) {
01461                                 /*printf("alc_recv2() SExiting\n");
01462                                 fflush(stdout);*/
01463                                 *retval = -2;
01464                                 return NULL;    
01465                         }
01466                         else if(s->state == SClosed) {
01467                                 /*printf("alc_recv2() SClosed\n");
01468                                 fflush(stdout);*/
01469                                 *retval = 0;
01470                                 return NULL;    
01471                         }
01472 
01473                         obj_completed = object_completed(to);
01474 
01475                         if(obj_completed) {
01476                                 tmp_toi = to->toi;
01477                                 break;
01478                         }
01479 
01480                         if(((s->state == STxStopped) && (!obj_completed))) {
01481                                 /*printf("alc_recv2() STxStopped\n");
01482                                 fflush(stdout);*/
01483                                 *retval = -3;
01484                                 return NULL;    
01485                         }
01486 
01487                         to = to->next;
01488                 }
01489 
01490                 if(obj_completed) {
01491                         break;
01492                 }
01493 
01494 #ifdef _MSC_VER
01495                 Sleep(1);
01496 #else
01497                 usleep(1000);
01498 #endif
01499         }
01500 
01501         printf("\n");
01502 
01503         remove_wanted_object(s_id, tmp_toi);
01504 
01505         /* Parse data from object to data buffer, return buffer length */
01506 
01507         to = object_exist(tmp_toi, s, 1);
01508 
01509         if(to->fec_enc_id == COM_NO_C_FEC_ENC_ID) {
01510                 buf = null_fec_decode_object(to, data_len, s);
01511         }
01512         else if(to->fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
01513                 buf = xor_fec_decode_object(to, data_len, s);
01514         }
01515         else if(to->fec_enc_id == RS_FEC_ENC_ID) {
01516                 buf = rs_fec_decode_object(to, data_len, s);
01517         }
01518         else if(to->fec_enc_id == SB_SYS_FEC_ENC_ID && to->fec_inst_id == REED_SOL_FEC_INST_ID) {
01519                 buf = rs_fec_decode_object(to, data_len, s);
01520         }
01521 
01522         if(buf == NULL) {
01523                 *retval = -1;
01524         }
01525         else {
01526                 *toi = tmp_toi;
01527         }
01528 
01529         free_object(to, s, 1);
01530         return buf;
01531 }
01532 
01533 char* alc_recv3(int s_id, unsigned long long *toi, int *retval) {
01534 
01535         BOOL obj_completed = FALSE;
01536         alc_session_t *s;
01537 
01538         unsigned long long tmp_toi = 0;
01539 
01540         trans_obj_t *to;
01541         char *tmp_filename = NULL;
01542 
01543         s = get_alc_session(s_id);
01544 
01545         while(1) {
01546 
01547                 to = s->obj_list;
01548 
01549                 if(s->state == SExiting) {
01550                         /*printf("alc_recv3() SExiting\n");
01551                         fflush(stdout);*/
01552                         *retval = -2;
01553                         return NULL;    
01554                 }
01555                 else if(s->state == SClosed) {
01556                         /*printf("alc_recv3() SClosed\n");
01557                         fflush(stdout);*/
01558                         *retval = 0;
01559                         return NULL;    
01560                 }
01561                 else if(((s->state == STxStopped) && (to == NULL))) {
01562                         /*printf("alc_recv3() STxStopped, to == NULL\n");
01563                         fflush(stdout);*/
01564                         *retval = -3;
01565                         return NULL;    
01566                 }
01567 
01568                 while(to != NULL) {
01569 
01570                         obj_completed = FALSE;
01571 
01572                         if(s->state == SExiting) {
01573                                 /*printf("alc_recv3() SExiting\n");
01574                                 fflush(stdout);*/
01575                                 *retval = -2;
01576                                 return NULL;    
01577                         }
01578                         else if(s->state == SClosed) {
01579                                 /*printf("alc_recv3() SClosed\n");
01580                                 fflush(stdout);*/
01581                                 *retval = 0;
01582                                 return NULL;    
01583                         }
01584                         else if(s->state == STxStopped) {
01585                                 break;
01586                         }
01587 
01588                         obj_completed = object_completed(to);
01589 
01590                         if(obj_completed) {
01591                                 tmp_toi = to->toi;
01592                                 break;
01593                         }
01594 
01595                         to = to->next;
01596                 }
01597 
01598                 if(obj_completed) {
01599                         break;
01600                 }
01601                 else if(s->state == STxStopped) {
01602 
01603                         /* Check if there is completed object after A-flag is received */
01604 
01605                         to = s->obj_list;
01606 
01607                         while(to != NULL) {
01608 
01609                                 obj_completed = object_completed(to);
01610 
01611                                 if(obj_completed) {
01612                                         tmp_toi = to->toi;
01613                                         break;
01614                                 }
01615 
01616                                 to = to->next;
01617                         }
01618 
01619                         if(obj_completed) {
01620                                 break;
01621                         }
01622                         else {
01623                                 /*printf("alc_recv3() STxStopped, any object not completed\n");
01624                                 fflush(stdout);*/
01625                                 *retval = -3;
01626                                 return NULL;
01627                         }       
01628                 }
01629 
01630 #ifdef _MSC_VER
01631                 Sleep(1);
01632 #else
01633                 usleep(1000);
01634 #endif
01635         }
01636 
01637         remove_wanted_object(s_id, tmp_toi);
01638 
01639         if(!(tmp_filename = (char*)calloc((strlen(to->tmp_filename) + 1), sizeof(char)))) {
01640                 printf("Could not alloc memory for tmp_filename!\n");
01641                 *retval = -1;
01642                 return NULL;    
01643         }
01644 
01645         memcpy(tmp_filename, to->tmp_filename, strlen(to->tmp_filename));
01646 
01647         free_object(to, s, 1);
01648         *toi = tmp_toi;
01649 
01650         return tmp_filename;
01651 }
01652 
01653 char* fdt_recv(int s_id, unsigned long long *data_len, int *retval,
01654                            unsigned char *content_enc_algo, int* fdt_instance_id) {
01655 
01656    alc_session_t *s;                                                                                                                                          
01657    char *buf = NULL; /* Buffer where to construct the object from data units */                                                                                                                                     
01658    trans_obj_t *to;
01659    
01660    s = get_alc_session(s_id);
01661 
01662    while(1) {
01663            to = s->fdt_list;
01664 
01665            if(s->state == SExiting) {
01666                    /*printf("fdt_recv() SExiting\n");
01667                    fflush(stdout);*/
01668                    *retval = -2;
01669                    return NULL;
01670            }
01671            else if(s->state == SClosed) {
01672                    /*printf("fdt_recv() SClosed\n");
01673                    fflush(stdout);*/
01674                    *retval = 0;
01675                    return NULL;
01676            }
01677            else if(s->state == STxStopped) {
01678                    /*printf("fdt_recv() STxStopped\n");
01679                    fflush(stdout);*/
01680                    *retval = -3;
01681                    return NULL; 
01682            }
01683 
01684            if(to == NULL) {
01685 
01686 #ifdef _MSC_VER
01687                    Sleep(1);
01688 #else
01689                    usleep(1000);
01690 #endif
01691                    continue;    
01692            }
01693 
01694            do {
01695                    if(object_completed(to)) {
01696                            set_received_instance(s, (unsigned int)to->toi);
01697 
01698                            *content_enc_algo = to->content_enc_algo;
01699                            *fdt_instance_id = (int)to->toi;
01700 
01701                            if(to->fec_enc_id == COM_NO_C_FEC_ENC_ID) {
01702                                    buf = null_fec_decode_object(to, data_len, s);
01703                            }
01704                            else if(to->fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
01705                                    buf = xor_fec_decode_object(to, data_len, s);
01706                            }
01707                            else if(to->fec_enc_id == RS_FEC_ENC_ID) {
01708                                    buf = rs_fec_decode_object(to, data_len, s);
01709                            }
01710                            else if(to->fec_enc_id == SB_SYS_FEC_ENC_ID && to->fec_inst_id == REED_SOL_FEC_INST_ID) {
01711                                    buf = rs_fec_decode_object(to, data_len, s);
01712                            }
01713 
01714                            if(buf == NULL) {
01715                                    *retval = -1;
01716                            }
01717 
01718                            free_object(to, s, 0);
01719                            return buf;
01720                    }
01721                    to = to->next;
01722            } while(to != NULL);
01723 
01724 #ifdef _MSC_VER
01725            Sleep(1);
01726 #else
01727            usleep(1000);
01728 #endif
01729    }
01730 
01731    return buf;
01732 }
01733 
01734 trans_obj_t* object_exist(unsigned long long toi, alc_session_t *s, int type) {
01735 
01736   trans_obj_t *trans_obj = NULL;
01737 
01738   if(type == 0) {
01739           trans_obj = s->fdt_list;
01740   }
01741   else if(type == 1) {
01742           trans_obj = s->obj_list;
01743   }
01744 
01745   if(trans_obj != NULL) {
01746           for(;;) {
01747                   if(trans_obj->toi == toi) {
01748                           break;
01749                   }
01750                   if(trans_obj->next == NULL) {
01751                           trans_obj = NULL;
01752                           break;
01753                   }
01754                   trans_obj = trans_obj->next;
01755           }
01756   }
01757 
01758   return trans_obj;
01759 }
01760 
01761 BOOL object_completed(trans_obj_t *to) {
01762 
01763         BOOL ready = FALSE;
01764 
01765         if(to->nb_of_ready_blocks == to->bs->N) {
01766                 ready = TRUE;
01767         }
01768 
01769         return ready;
01770 }
01771 
01772 BOOL block_ready_to_decode(trans_block_t *tb) {
01773 
01774         BOOL ready = FALSE;
01775 
01776         if(tb->nb_of_rx_units >= tb->k) {
01777                 ready = TRUE;
01778         }
01779 
01780         return ready;
01781 }

Generated on Fri Mar 9 19:59:51 2007 for MAD-FCL by  doxygen 1.5.0