mad_rlc.c

Go to the documentation of this file.
00001 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include <string.h>
00042 
00043 #ifdef _MSC_VER
00044 #include <winsock2.h>
00045 #include <ws2tcpip.h>
00046 #else
00047 #include <sys/socket.h>
00048 #include <netinet/in.h>
00049 #include <arpa/inet.h>
00050 #endif
00051 
00052 #include "mad_rlc.h"
00053 #include "alc_channel.h"
00054 
00064 int mad_rlc_process_rx_sp(alc_session_t *s) {
00065 
00066   static char addrs[MAX_CHANNELS_IN_SESSION][INET6_ADDRSTRLEN]; /* multicast addresses */
00067   static char ports[MAX_CHANNELS_IN_SESSION][MAX_PORT_LENGTH];  /* local port numbers  */
00068 
00069   struct sockaddr_in ipv4;
00070   struct sockaddr_in6 ipv6;
00071 
00072 #ifdef _MSC_VER
00073   int addr_size;
00074 #endif
00075 
00076   int retcode;
00077   
00078   int retval = 0;
00079   
00080   if(s->rlc->rx_nblost_since_sp <= s->rlc->loss_accepted
00081      && s->rlc->rx_nblate_since_sp <= s->rlc->late_accepted) {
00082     
00083     if(s->addr_family == PF_INET) {
00084       if(s->addr_type == 1) {
00085         ipv4.sin_addr.s_addr = htonl(ntohl(inet_addr(s->ch_list[s->nb_channel - 1]->addr)));
00086       }
00087       else {
00088         ipv4.sin_addr.s_addr = htonl(ntohl(inet_addr(s->ch_list[s->nb_channel - 1]->addr)) + 1);
00089       }
00090       
00091       memset(addrs[s->nb_channel], 0, INET6_ADDRSTRLEN);
00092       sprintf(addrs[s->nb_channel], "%s", inet_ntoa(ipv4.sin_addr));
00093       
00094       memset(ports[s->nb_channel], 0, MAX_PORT_LENGTH);
00095       sprintf(ports[s->nb_channel], "%i", (atoi(s->ch_list[s->nb_channel - 1]->port) + 1));
00096     }
00097     else if(s->addr_family == PF_INET6) {
00098       
00099 #ifdef _MSC_VER
00100         addr_size = sizeof(struct sockaddr_in6);
00101         WSAStringToAddress((char*)s->ch_list[s->nb_channel - 1]->addr, AF_INET6, NULL, (struct sockaddr*)&ipv6, &addr_size);
00102 #else 
00103         inet_pton(AF_INET6, s->ch_list[s->nb_channel - 1]->addr, &ipv6.sin6_addr);
00104 #endif
00105 
00106       if(s->addr_type == 0) {
00107         if(increase_ipv6_address(&ipv6.sin6_addr) == -1) {
00108           printf("Increasing IPv6 address %s is not possible\n", s->ch_list[s->nb_channel - 1]->addr);
00109           return -1;
00110         }
00111       }
00112       
00113       memset(addrs[s->nb_channel], 0, INET6_ADDRSTRLEN);
00114 
00115 #ifdef _MSC_VER
00116           addr_size = sizeof(addrs[s->nb_channel]);
00117       WSAAddressToString((struct sockaddr*)&ipv6, sizeof(struct sockaddr_in6),
00118                         NULL, addrs[s->nb_channel], &addr_size);
00119 #else
00120           inet_ntop(AF_INET6, &ipv6.sin6_addr, addrs[s->nb_channel], sizeof(addrs[s->nb_channel]));
00121 #endif
00122       
00123       memset(ports[s->nb_channel], 0, MAX_PORT_LENGTH);
00124       sprintf(ports[s->nb_channel], "%i", (atoi(s->ch_list[s->nb_channel - 1]->port) + 1));
00125     }
00126     
00127     retcode = add_alc_channel(s->s_id, ports[s->nb_channel], addrs[s->nb_channel],
00128                               s->ch_list[s->nb_channel - 1]->intface,
00129                               s->ch_list[s->nb_channel - 1]->intface_name);
00130     
00131     if(!(retcode < 0)) {
00132       s->rlc->rx_nblost_since_sp = 0;
00133       s->rlc->rx_nblate_since_sp = 0;
00134       retval = 1;
00135     }
00136   }
00137   
00138   return retval;
00139 }
00140 
00148 void mad_rlc_free_lists(alc_session_t *s) {
00149         int i;
00150         late_list_t *current_late;
00151         lost_list_t *current_lost;
00152 
00153         for(i = 0; i < MAX_CHANNELS_IN_SESSION; i++) {  
00154                 current_late = s->rlc->rx_missing[i].next;
00155                 while(current_late != NULL) {
00156                         s->rlc->rx_missing[i].next = current_late->next;
00157                         free(current_late);
00158                         current_late = s->rlc->rx_missing[i].next;
00159                 }
00160                 s->rlc->rx_missing[i].next = NULL; /* redundant, isn't it? */
00161         }
00162 
00163         current_lost = s->rlc->rx_lost.next;
00164         while(current_lost != NULL) {
00165                 s->rlc->rx_lost.next = current_lost->next;
00166                 free(current_lost);
00167                 current_lost = s->rlc->rx_lost.next;
00168         }
00169         s->rlc->rx_lost.next = NULL; /* redundant, isn't it? */
00170         s->rlc->rx_nblost = 0;
00171         s->rlc->rx_nblate = 0;
00172         s->rlc->rx_nblost_since_sp = 0;
00173         s->rlc->rx_nblate_since_sp = 0;
00174 }
00175 
00187 int mad_rlc_add_late(alc_session_t *s, int layer, int nseq) {
00188         late_list_t     *new_missing;
00189         double currenttime;
00190 
00191         if(layer > s->nb_channel) {
00192                 return -1;
00193         }
00194 
00195         if(!( new_missing = (late_list_t *)malloc(sizeof(late_list_t))) ) {
00196                 printf("Could not alloc memory for late_list_t structure!\n");
00197                 return -1;
00198         }
00199 
00200         currenttime = sec();
00201 
00202         new_missing->seq_num = nseq;
00203         new_missing->losttime = currenttime + (double)((double)s->rlc->pkt_timeout / (double)1000);
00204         new_missing->next = s->rlc->rx_missing[layer].next;
00205 
00206         s->rlc->rx_missing[layer].next = new_missing;
00207         s->rlc->rx_nblate++;
00208         s->rlc->rx_nblate_since_sp++;
00209         
00210         /* update stats: assume a late pkt is lost (corrected later if req.) */
00211         s->lost_packets++;
00212                 
00213         return 0;
00214 }
00215 
00227 int mad_rlc_remove_late(alc_session_t *s, int layer, int nseq) {
00228         late_list_t *prev;
00229         late_list_t *current;
00230 
00231         if(layer > s->nb_channel) {
00232                 return -1;
00233         }
00234 
00235         prev = &(s->rlc->rx_missing[layer]);
00236         current = prev->next;
00237         
00238         while(current != NULL && current->seq_num != nseq ) {
00239                 prev = current;
00240                 current = current->next;
00241         }
00242 
00243         if(current == NULL) {
00244                 return -1;
00245         }
00246         else {
00247                 prev->next = current->next;
00248                 free(current);
00249                 s->rlc->rx_nblate--;
00250                 s->rlc->rx_nblate_since_sp--;
00251         }
00252 
00253         /* correct stats... */
00254         s->lost_packets++;
00255 
00256         return 0;
00257 }
00258 
00259 
00269 int mad_rlc_add_lost(alc_session_t *s) {
00270         
00271         lost_list_t     *new_lost;
00272         double currenttime;
00273 
00274         currenttime = sec();
00275 
00276         s->rlc->rx_nblost++;
00277         s->rlc->rx_nblost_since_sp++;
00278         
00279         if(s->rlc->rx_nblost >= s->rlc->loss_limit) {
00280                 /* too many losses... drop a layer! */
00281                 
00282                 s->rlc->drop_highest_layer = TRUE;
00283 
00284                 /* initial state for future potential use of this layer*/
00285                 s->rlc->rx_first_pkt[s->ch_list[s->nb_channel - 1]->ch_id] = 1;
00286 
00287                 /* Clean up late and lost lists... */
00288                 mad_rlc_free_lists(s);
00289 
00290                 /* entering the deaf period... */
00291                 s->rlc->rx_deaf_wait = currenttime + (double)s->rlc->deaf_period / (double)1000;
00292 
00293                 return -1000;
00294         }
00295 
00296         if(!(new_lost = (lost_list_t *)malloc(sizeof(lost_list_t)))) {
00297                 printf("Could not alloc memory for lost_list_t structure!\n");
00298                 return -1;
00299         }
00300 
00301         new_lost->pkt_remaining = s->rlc->loss_timeout;
00302         new_lost->next = s->rlc->rx_lost.next;
00303         s->rlc->rx_lost.next = new_lost;
00304         
00305         return 0;
00306 }
00307 
00317 int mad_rlc_update_late_list(alc_session_t *s) {
00318         int layer;
00319         late_list_t *prev;
00320         late_list_t *current;
00321         double currenttime;
00322 
00323         for(layer = 0; layer < s->nb_channel; layer++) {
00324                 currenttime = sec();
00325 
00326                 prev = &(s->rlc->rx_missing[layer]);
00327                 current = prev->next;
00328                 
00329                 while(current != NULL) {
00330                         if(current->losttime <= currenttime) {
00331                                 /* this one is lost! */
00332                                 prev->next = current->next;
00333                                 free(current);
00334                                 s->rlc->rx_nblate--;
00335                                 s->rlc->rx_nblate_since_sp--;
00336                                 
00337                                 if(mad_rlc_add_lost(s) == -1000) {
00338                                         return -1; /* roca 0 */
00339                                 }
00340                         }
00341                         else {
00342                                 prev = current;
00343                                 current = prev->next;
00344                         }
00345                 }
00346         }
00347 
00348         return 0;
00349 }
00350 
00360 int mad_rlc_update_loss_list(alc_session_t *s) {
00361         lost_list_t *prev;
00362         lost_list_t *current;
00363 
00364         prev = &(s->rlc->rx_lost);
00365         current = prev->next;
00366 
00367         while(current != NULL) {        
00368                 if(--(current->pkt_remaining) == 0) { /* this loss is too old : removing */             
00369                         prev->next = current->next;
00370                         free(current);
00371                         s->rlc->rx_nblost--;
00372                 }
00373                 else {
00374                         prev = current;
00375                 }
00376 
00377                 current = prev->next;
00378         }
00379 
00380         return 0;
00381 }
00382 
00394 int mad_rlc_check_sequence(alc_session_t *s, int layer, int seqid) {
00395         unsigned short Delta1;
00396         unsigned short Delta2;
00397 
00398         int i;
00399         int late_limit;
00400         
00401         if(s->rlc->rx_wait_for[layer] == seqid) {
00402                 /* This is the packet we're waiting for, let's go on! */
00403                 s->rlc->rx_wait_for[layer]++;
00404                 return 0;
00405         }
00406 
00407         /* This is not the one we're waiting for... */
00408         if(s->rlc->rx_wait_for[layer] < seqid) {
00409 
00410                 Delta1 = seqid - s->rlc->rx_wait_for[layer];
00411                 Delta2 = 65535 - Delta1;
00412                 
00413                 if(Delta1 < Delta2) {
00414                         
00415                         late_limit = RLC_MAX_LATES;
00416                         
00417                         for(i = s->rlc->rx_wait_for[layer]; i < seqid; i++) {
00418                                 mad_rlc_add_late(s, layer, i);
00419                                 late_limit--;
00420                                 if(late_limit <= 0 ) {
00421                                         printf("RLC Warning*** Max number of LATE packets reached\n");
00422                                         fflush(stdout);
00423                                         break;
00424                                 }
00425                         }
00426                         /* EOFIX */
00427                         s->rlc->rx_wait_for[layer] = seqid + 1;
00428                 }
00429                 else {
00430                         /* Late arrival packet (uint16 overflow) */
00431                         /* eg. we're waiting seq 4 and we get seq 65532 */
00432                         mad_rlc_remove_late(s, layer, seqid);
00433                 }
00434         }
00435         else { /* rx_wait_for > rlc_seqid */
00436                 
00437                 Delta1 = s->rlc->rx_wait_for[layer] - seqid;
00438                 Delta2 = 65535 - Delta1;
00439                 if (Delta1 < Delta2) { /* Late arrival packet */
00440                 /* ie: we're waiting seq 501 and we get seq 498 */
00441                         mad_rlc_remove_late(s, layer, seqid);
00442                 }
00443                 else {
00444                 /* Some packet(s) are missing (uint16 overflow) */
00445                 /* ie: waiting seq 65531 and get seq 3 */
00446                         /* FIX 14/12/01 */
00447                         late_limit = RLC_MAX_LATES;
00448                         for(i = s->rlc->rx_wait_for[layer]; i != (seqid-1); i++) {
00449                                 mad_rlc_add_late(s, layer, i);
00450                                 late_limit--;
00451                                 if(late_limit <= 0 ) {
00452                                         printf("RLC Warning*** Max number of LATE packets reached\n");
00453                                         fflush(stdout);
00454                                         break;
00455                                 }
00456                         }
00457                         /* EOFIX */
00458                         s->rlc->rx_wait_for[layer] = seqid + 1;
00459                 }
00460         }
00461 
00462         return 0;
00463 }
00464 
00465 int init_mad_rlc(alc_session_t *s) {
00466         int i;
00467 
00468         if(!(s->rlc = (mad_rlc_t*)calloc(1, sizeof(mad_rlc_t)))) {
00469                 printf("Could not alloc memory for mad rlc congestion control!\n");
00470                 return -1;
00471         }
00472 
00473         if(s->mode == SENDER) {
00474                 s->rlc->sp_cycle  =     RLC_SP_CYCLE;
00475         }
00476         else if(s->mode == RECEIVER) {
00477                 s->rlc->drop_highest_layer = FALSE;
00478                 s->rlc->pkt_timeout = RLC_PKT_TIMEOUT;
00479                 s->rlc->deaf_period = RLC_DEAF_PERIOD;
00480                 s->rlc->loss_accepted = RLC_LOSS_ACCEPTED;
00481                 s->rlc->late_accepted = RLC_LATE_ACCEPTED;
00482                 s->rlc->loss_limit  = RLC_LOSS_LIMIT;
00483                 s->rlc->loss_timeout = RLC_LOSS_TIMEOUT;
00484                 s->rlc->rx_deaf_wait = 0;
00485 
00486                 for(i = 0 ; i < MAX_CHANNELS_IN_SESSION; i++) {
00487                         s->rlc->rx_first_pkt[i] = 1;
00488                         s->rlc->rx_first_sp[i] = 0;
00489                 }
00490         }
00491         
00492         return 0;       
00493 }
00494 
00495 void close_mad_rlc(alc_session_t *s) {
00496         if(s->mode == RECEIVER) {
00497                 mad_rlc_free_lists(s);
00498         }
00499 
00500         free(s->rlc);
00501 }
00502 
00503 double mad_rlc_next_sp(alc_session_t *s, int layer) {
00504         
00505         double spacing;
00506         double currenttime;
00507 
00508         currenttime = sec();
00509 
00510         spacing = (double)((double)s->rlc->sp_cycle / (double)1000) * (double)(min((1 << layer), 128 + layer));
00511 
00512         return (currenttime + (double)spacing);
00513 }
00514 
00515 void mad_rlc_reset_tx_sp(alc_session_t *s) {
00516         
00517         int i;
00518 
00519         for(i = 0 ; i < MAX_CHANNELS_IN_SESSION; i++) {
00520                 s->rlc->tx_next_sp[i] = mad_rlc_next_sp(s, i);
00521         }
00522 }
00523 
00524 int mad_rlc_fill_header(alc_session_t *s, rlc_hdr_t *rlc_hdr, int layer) {
00525         
00526         unsigned short hdr_seqid;
00527         double currenttime;
00528 
00529         currenttime = sec();
00530 
00531         if(layer > MAX_CHANNELS_IN_SESSION || layer > s->nb_channel) {
00532                 printf("BAD layer!\n");
00533                 fflush(stdout);
00534                 return -1;
00535         }       
00536 
00537         hdr_seqid = s->rlc->tx_layers_seq[layer];
00538         s->rlc->tx_layers_seq[layer]++;
00539                 
00540         rlc_hdr->reserved = 0x55;       /* unused: rlc_reserved = 1010101 */
00541         rlc_hdr->layer = layer;
00542         rlc_hdr->seqid = htons(hdr_seqid);
00543 
00544         if(s->rlc->tx_next_sp[layer] <= currenttime) {
00545 
00546                 if((layer + 1) == s->nb_channel) {
00547                         rlc_hdr->sp = 0;        
00548                 }
00549                 else {
00550                         /* OK this is a new SP for this layer */
00551                         rlc_hdr->sp = 1;
00552 
00553                         /* calculate when next SP will occur */
00554                         s->rlc->tx_next_sp[layer] = mad_rlc_next_sp(s, layer);
00555 
00556                         if(layer + 1 < MAX_CHANNELS_IN_SESSION &&
00557                                 s->ch_list[layer + 1]->start_sending == FALSE) {
00558 
00559                                 s->ch_list[layer + 1]->start_sending = TRUE;
00560                                 s->nb_sending_channel++;
00561                         }
00562                 }
00563         }
00564         else {  /* not a SP... */
00565                 rlc_hdr->sp = 0;
00566         }
00567 
00568         return 0;
00569 }
00570 
00571 int mad_rlc_analyze_cci(alc_session_t *s, rlc_hdr_t *rlc_hdr) {
00572         
00573         unsigned char hdr_layer;        
00574         unsigned short hdr_seqid;
00575         unsigned char hdr_sp;
00576         double currenttime;
00577 
00578         hdr_seqid = ntohs(rlc_hdr->seqid);
00579         hdr_layer = rlc_hdr->layer;
00580         hdr_sp = rlc_hdr->sp;
00581 
00582         if(rlc_hdr->reserved != 0x55) {
00583                 return -1;
00584         }
00585         if(rlc_hdr->layer >= s->nb_channel) {
00586                 return -1;
00587         }
00588 
00589         mad_rlc_update_loss_list(s);
00590         mad_rlc_update_late_list(s);
00591 
00592         currenttime = sec();
00593 
00594         if(s->rlc->rx_deaf_wait != 0) {
00595                 
00596                 if(s->rlc->rx_deaf_wait > currenttime) {
00597 
00598                         s->rlc->rx_wait_for[rlc_hdr->layer] = hdr_seqid + 1;
00599                         return 0;
00600                 }
00601         }
00602 
00603         if(s->rlc->rx_first_pkt[hdr_layer]) {
00604                 /* First packet on this layer... */
00605                 s->rlc->rx_wait_for[hdr_layer] = hdr_seqid + 1;
00606                 s->rlc->rx_first_pkt[hdr_layer] = 0;
00607                 /* continue as this pkt may contain an SP */
00608         } else {
00609                 /* check if some pkts have been lost or not */
00610                 mad_rlc_check_sequence(s, hdr_layer, hdr_seqid);
00611         }
00612 
00613         if(hdr_sp) {
00614                 if(hdr_layer == s->nb_channel - 1) {
00615                         /* This is a Synchronisation Point */
00616                         if(s->rlc->rx_first_sp[hdr_layer] == 1) {
00617                                 /* skip 1st SP, especially after deaf-period */
00618                                 s->rlc->rx_first_sp[hdr_layer] = 0;
00619                         } else {
00620                                 mad_rlc_process_rx_sp(s);
00621                         }
00622                 }
00623         }
00624 
00625         return 0;
00626 }

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