parse_args.c

Go to the documentation of this file.
00001 
00033 #include <stdlib.h>
00034 #include <fcntl.h>
00035 #include <errno.h>
00036 #include <assert.h>
00037 #include <time.h>
00038 #include <string.h>
00039 #include <stdio.h>
00040 
00041 #ifdef _MSC_VER
00042 #include <io.h>
00043 #else
00044 #include <unistd.h>
00045 #endif
00046 
00047 #include "parse_args.h"
00048 
00049 int parse_args(int argc, char **argv, arguments_t *a) {
00050 
00051   int i;
00052   time_t systime;
00053   unsigned long long curr_time;
00054  
00055 #ifndef _MSC_VER
00056   char *ep;
00057 #endif
00058 
00059   unsigned int tmp_max_sb_len;
00060   unsigned int tmp_es_len;
00061   char *tmp_addr;
00062   unsigned char fec_enc;
00063   char *tmp_base_dir;
00064   char *tmp_repair;
00065   BOOL repair;
00066   unsigned long long tmp_tsi;
00067   unsigned long long duration;
00068   char *loss_ratio2;
00069   div_t div_max_k;
00070   div_t div_max_n;
00071  
00072   time(&systime);
00073   curr_time = systime + 2208988800U;
00074   
00075   tmp_tsi = DEF_TSI;                                     /* transport session identifier */
00076   tmp_max_sb_len = 0;
00077   tmp_es_len = 0;
00078   tmp_addr = NULL;
00079   fec_enc = DEF_FEC;
00080   tmp_base_dir = NULL;
00081   tmp_repair = NULL;
00082   repair = FALSE;
00083   loss_ratio2 = NULL;
00084   duration = 0;
00085 
00086   a->toi = 0;                                                   /* transport object identifier */
00087   a->cont = FALSE;                                       /* continuous transmission */
00088   a->rx_automatic = FALSE;                               /* download files defined in IDT automatically */
00089   a->rx_object = FALSE;
00090   a->file_table_output = FALSE;
00091   a->log_fd = -1;
00092   a->complete_fdt = 0;
00093   a->send_session_close_packets = 1;
00094   a->name_incomplete_objects = FALSE;
00095 
00096 #ifdef _MSC_VER
00097   a->open_file = FALSE;                                  /* open received file automatically */
00098 #endif
00099 
00100   memset(a->sdp_file, 0, MAX_PATH_LENGTH);
00101   memset(a->file_path, 0, MAX_PATH_LENGTH);  /* file(s) or directory to send */
00102   memset(a->fdt_file, 0, MAX_PATH_LENGTH);
00103   strcpy(a->fdt_file, DEF_FDT);                          /* fdt file (fdt based send) */
00104  
00105   a->alc_a.cc_id = DEF_CC;                              /* congestion control */
00106   a->alc_a.mode = RECEIVER;                             /* sender or receiver? */                       
00107   a->alc_a.port = DEF_MCAST_PORT;                                /* local port number for base channel */
00108   a->alc_a.nb_channel = DEF_NB_CHANNEL;                  /* number of channels */
00109   a->alc_a.intface = NULL;                                       /* interface */
00110   a->alc_a.intface_name = NULL;                          /* interface name/index for IPv6 multicast join */
00111   a->alc_a.addr_family = DEF_ADDR_FAMILY;
00112   a->alc_a.addr_type = 0;
00113   a->alc_a.es_len = DEF_SYMB_LENGTH;                             /* encoding symbol length */
00114   a->alc_a.max_sb_len = DEF_MAX_SB_LEN;                  /* source block length */
00115   a->alc_a.tx_rate = DEF_TX_RATE;                                /* transmission rate in kbit/s */
00116   a->alc_a.ttl = DEF_TTL;                                        /* time to live  */
00117   a->alc_a.nb_tx = DEF_TX_NB;                                    /* nb of time to send the file/directory */
00118   a->alc_a.simul_losses = FALSE;                                 /* simulate packet losses */
00119   a->alc_a.loss_ratio1 = P_LOSS_WHEN_OK;
00120   a->alc_a.loss_ratio2 = P_LOSS_WHEN_LOSS;
00121   a->alc_a.fec_ratio = DEF_FEC_RATIO;                            /* FEC ratio percent */        
00122   a->alc_a.fec_enc_id = DEF_FEC_ENC_ID;                  /* FEC Encoding */
00123   a->alc_a.fec_inst_id = DEF_FEC_INST_ID; 
00124   a->alc_a.rx_memory_mode = 1;
00125   a->alc_a.verbosity = 1;  
00126   a->alc_a.use_fec_oti_ext_hdr = 0;                              /* include fec oti extension header to flute header */
00127   a->alc_a.encode_content = 0;                           /* encode content */
00128   a->alc_a.src_addr = NULL;
00129   a->alc_a.optimize_tx_rate = FALSE;
00130   a->alc_a.calculate_session_size = FALSE;
00131   a->alc_a.half_word = FALSE;
00132   a->alc_a.accept_expired_fdt_inst = FALSE;
00133 
00134 #ifdef SSM
00135   a->alc_a.use_ssm = FALSE;                                      /* use source specific multicast */
00136 #endif
00137   
00138   if(strstr(argv[0], "repair_sender")) {
00139     a->alc_a.mode = SENDER;
00140     repair = TRUE;
00141   }
00142   else {
00143     a->alc_a.mode = RECEIVER;
00144   }
00145 
00146   for(i = 1; i < argc ; i++) {
00147     if(argv[i][0] == '-') {
00148       
00149       switch(argv[i][1])
00150         {
00151         case 'A':  /* automatic download */
00152           if(strlen(argv[i]) > 2) {
00153             return -1;
00154           }
00155           a->rx_automatic = TRUE;
00156           break;
00157         case 'a':  /* address family */
00158           if(strlen(argv[i]) > 3) {
00159             if(!(strcmp(&argv[i][3], "IPv4"))) {
00160               a->alc_a.addr_family = PF_INET;
00161             }
00162             else if(!(strcmp(&argv[i][3], "IPv6"))) {
00163               a->alc_a.es_len = MAX_SYMB_LENGTH_IPv6_FEC_ID_0_3_130;
00164               a->alc_a.addr_family = PF_INET6;
00165             }
00166           }
00167           else {
00168             return -1;
00169           }
00170           break;
00171         case 'B':  /* base directory for downloaded files */
00172           if(strlen(argv[i]) > 3) {
00173             tmp_base_dir = &argv[i][3];
00174           }
00175           else {
00176             return -1;
00177           }
00178           break;
00179         case 'b':  /* rx_memory_mode */
00180           if(strlen(argv[i]) > 3) {
00181             a->alc_a.rx_memory_mode = (unsigned char)atoi(&argv[i][3]);
00182 
00183             if(a->alc_a.rx_memory_mode > 2) {
00184               printf("Possible values for option -b are: 0, 1, or 2\n");
00185               fflush(stdout);
00186               return -1;
00187             }
00188           }
00189           else {                         
00190             return -1;
00191           }
00192           break;
00193         case 'C':  /* Continuous transmission */
00194           if(strlen(argv[i]) > 2) {
00195             return -1;
00196           }
00197           a->cont = TRUE;
00198           break;
00199         case 'c':  /* number of channels */
00200           if(strlen(argv[i]) > 3) {
00201             a->alc_a.nb_channel = (unsigned char)atoi(&argv[i][3]);
00202             
00203             if(a->alc_a.nb_channel > MAX_CHANNELS_IN_SESSION) {
00204               printf("Channel number set to maximum value: %i\n", MAX_CHANNELS_IN_SESSION);
00205               a->alc_a.nb_channel = MAX_CHANNELS_IN_SESSION;
00206             }
00207             else if(a->alc_a.nb_channel == 0) {
00208               printf("Channel number set to 1\n");
00209               a->alc_a.nb_channel = 1;
00210             }
00211           }
00212           else {
00213             return -1;
00214           }
00215           break;
00216         case 'D':  /* session duration time */
00217           if(strlen(argv[i]) > 3) {
00218 #ifdef _MSC_VER                   
00219             duration = _atoi64(&argv[i][3]);
00220             
00221             if(duration > (unsigned long long)0xFFFFFFFFFFFFFFFF) {
00222               printf("Duration: %I64u too big (max=%I64u)\n", duration, (unsigned long long)0xFFFFFFFFFFFFFFFF);
00223               fflush(stdout);
00224               return -1;
00225             }
00226 #else
00227             duration = strtoull(&argv[i][3], &ep, 10);
00228             
00229             if(&argv[i][3] == '\0' || *ep != '\0') {
00230               printf("Duration not a number\n");
00231               fflush(stdout);
00232               return -1;
00233             }
00234             
00235             if(errno == ERANGE && duration == 0xFFFFFFFFFFFFFFFFULL) {
00236               printf("Duration too big for unsigned long long (64 bits)\n");
00237               fflush(stdout);
00238               return -1;
00239             }
00240 #endif  
00241           }
00242           else {
00243             return -1;
00244           }
00245           break;
00246         case 'd':  /* sdp file */
00247           if(strlen(argv[i]) <= 3) {
00248                 return -1;
00249           }
00250           else if(strlen(argv[i]) >= MAX_PATH_LENGTH) {
00251             printf("\nFile path for SDP file too long\n");
00252                 return -1;
00253           }
00254           else {
00255             memset(a->sdp_file, 0, MAX_PATH_LENGTH);
00256             strcpy(a->sdp_file, &argv[i][3]);
00257           }
00258           break;
00259         case 'E':  /* Accept Expired FDT Instances */
00260           if(strlen(argv[i]) > 2) {
00261             return -1;
00262           }
00263           a->alc_a.accept_expired_fdt_inst = TRUE;
00264           break;
00265         case 'e':  /* Use fec oti extension header */
00266           if(strlen(argv[i]) > 3) {
00267             a->alc_a.use_fec_oti_ext_hdr = (unsigned char)atoi(&argv[i][3]);
00268             
00269             if(a->alc_a.use_fec_oti_ext_hdr > 1) {
00270               printf("Possible values for option -e are: 0, or 1\n");
00271               fflush(stdout);
00272               return -1;
00273             }
00274           }
00275           else {                         
00276             return -1;
00277           }
00278           break;
00279         case 'F':  /* files or directories to send/receive */
00280           if(strlen(argv[i]) <= 3) {
00281                 return -1;
00282           }
00283           else if(strlen(argv[i]) >= MAX_PATH_LENGTH) {
00284             printf("\nFile path for files or directories too long\n");
00285                 return -1;
00286           }
00287           else {
00288             memset(a->file_path, 0, MAX_PATH_LENGTH);
00289             strcpy(a->file_path, &argv[i][3]);
00290           }
00291           memset(a->fdt_file, 0, MAX_PATH_LENGTH);
00292           break;
00293         case 'f':  /* fdt based send */
00294           if(strlen(argv[i]) <= 3) {
00295                 return -1;
00296           }
00297           else if(strlen(argv[i]) >= MAX_PATH_LENGTH) {
00298             printf("\nFile path for FDT file too long\n");
00299                 return -1;
00300           }
00301           else {
00302             memset(a->fdt_file, 0, MAX_PATH_LENGTH);
00303             strcpy(a->fdt_file, &argv[i][3]);
00304           }
00305           memset(a->file_path, 0, MAX_PATH_LENGTH);
00306           break;
00307         case 'G':  /* Calculate session size but do not send anything */
00308                 if(strlen(argv[i]) > 2) {                       
00309                         return -1;                      
00310                 }       
00311                 a->alc_a.calculate_session_size = TRUE;          
00312                 break;
00313         case 'H':  /* use half-word */
00314           if(strlen(argv[i]) > 2) {
00315             return -1;
00316           }
00317           a->alc_a.half_word = TRUE;
00318           break;
00319         case 'h':  /* help/usage */
00320           return -1;
00321           break;
00322         case 'I':  /* local interface name/index for IPv6 multicast join */
00323           if(strlen(argv[i]) > 3) {
00324             a->alc_a.intface_name = &argv[i][3];
00325           }
00326           else {
00327             return -1;
00328           }
00329           break;
00330         case 'i':  /* local interface to use */
00331           if(strlen(argv[i]) > 3) {
00332             a->alc_a.intface = &argv[i][3];
00333           }
00334           else {
00335             return -1;
00336           }
00337           break;
00338     case 'K':  /* 'repair_sender.conf' */
00339           if(strlen(argv[i]) <= 3) {
00340                 return -1;
00341           }
00342           else if(strlen(argv[i]) >= MAX_PATH_LENGTH) {
00343                 printf("\nFile path for repair sender configuration file too long\n");
00344                 return -1;
00345           }
00346           else {
00347                 tmp_repair = &argv[i][3];
00348           }
00349           break;
00350         case 'k':  /* Complete FDT */
00351           if(strlen(argv[i]) > 3) {
00352             a->complete_fdt = (unsigned short)atoi(&argv[i][3]);
00353           }
00354           else {
00355             return -1;
00356           }
00357           break;
00358         case 'L':  /* sbl length */
00359           if(strlen(argv[i]) > 3) {
00360             tmp_max_sb_len = (unsigned int)atoi(&argv[i][3]);
00361           }
00362           else {
00363             return -1;
00364           }
00365           break;
00366         case 'l':  /*  encoding symbol length */
00367           if(strlen(argv[i]) > 3) {
00368             tmp_es_len = (unsigned short)atoi(&argv[i][3]);                                             
00369           }
00370           else {
00371             return -1;
00372           }
00373           break;
00374 #ifdef SSM
00375         case 'M':  /* use source specific multicast */
00376           if(strlen(argv[i]) > 2) {
00377             return -1;
00378           }
00379           a->alc_a.use_ssm = TRUE;
00380           break;
00381         case 'm':  /* Multicast group for base channel */
00382           if(strlen(argv[i]) > 3) {
00383             tmp_addr = &argv[i][3];
00384           }
00385           else {
00386             return -1;
00387           }
00388           break;
00389 #endif
00390         case 'N':
00391           if(strlen(argv[i]) > 2) {
00392             return -1;
00393           }
00394           a->name_incomplete_objects = TRUE;
00395           break;
00396         case 'n':  /* tx loops */
00397           if(strlen(argv[i]) > 3) {
00398             a->alc_a.nb_tx = (unsigned short)atoi(&argv[i][3]);
00399           }
00400           else {
00401             return -1;
00402           }
00403           break;
00404 #ifdef _MSC_VER
00405         case 'O':  /* automatic opening */
00406           if(strlen(argv[i]) > 2) {
00407             return -1;
00408           }
00409           a->open_file = TRUE;
00410           break;
00411 #endif
00412         case 'o':  /* toi */
00413           if(strlen(argv[i]) > 3) {
00414 #ifdef _MSC_VER                   
00415             a->toi = _atoi64(&argv[i][3]);
00416             
00417             if(a->toi > (unsigned long long)0xFFFFFFFFFFFFFFFF) {
00418               printf("TOI: %I64u too big (max=%I64u)\n", a->toi, (unsigned long long)0xFFFFFFFFFFFFFFFF);
00419               fflush(stdout);
00420               return -1;
00421             }
00422 #else       
00423             a->toi = strtoull(&argv[i][3], &ep, 10);
00424             
00425             if(&argv[i][3] == '\0' || *ep != '\0') {
00426               printf("TOI not a number\n");
00427               fflush(stdout);
00428               return -1;
00429             }
00430             
00431             if(errno == ERANGE && a->toi == 0xFFFFFFFFFFFFFFFFULL) {
00432               printf("TOI too big for unsigned long long (64 bits)\n");
00433               fflush(stdout);
00434               return -1;
00435             }
00436 #endif
00437             a->rx_object = 1;
00438           }
00439           else {
00440             return -1;
00441           }
00442           break;
00443         case 'P':  /* simulate packet losses */
00444           if(strlen(argv[i]) >= 2) {
00445             a->alc_a.simul_losses = TRUE;
00446           }
00447           if(strlen(argv[i]) > 3) {
00448             a->alc_a.loss_ratio1 = atof(strtok(&argv[i][3], ","));
00449             loss_ratio2 = strtok(NULL, "\0");
00450             if(loss_ratio2 == NULL) {
00451               return -1;
00452             }
00453             a->alc_a.loss_ratio2 = atof(loss_ratio2);
00454           }
00455           if(strlen(argv[i]) == 3) {
00456             return -1;
00457           }
00458           break;
00459         case 'p':  /* Port number for base channel*/
00460           if(strlen(argv[i]) > 3) {
00461             a->alc_a.port = &argv[i][3];
00462 
00463             assert(atoi(a->alc_a.port) > 0);
00464             assert(atoi(a->alc_a.port) <= 0xFFFF);
00465           }
00466           else {
00467             return -1;
00468           }
00469           break;
00470         case 'q':  /* Send session close packets */
00471           if(strlen(argv[i]) > 3) {
00472             a->send_session_close_packets = atoi(&argv[i][3]);
00473           }
00474           else {
00475             return -1;
00476           }
00477           break;
00478 
00479 #ifdef USE_FILE_REPAIR
00480         case 'R':  /* 'apd.xml' or 'flute.conf' */
00481           if(strlen(argv[i]) == 3) {
00482                 return -1;
00483           }
00484           else if(strlen(argv[i]) >= MAX_PATH_LENGTH) {
00485                 printf("\nFile path for repair configuration file too long\n");
00486                 return -1;
00487           }
00488           else if(strlen(argv[i]) == 2) {
00489             repair = TRUE;
00490           }
00491           else {
00492                 repair = TRUE;
00493                 tmp_repair = &argv[i][3];
00494           }
00495           break;
00496 #endif
00497         case 'r':  /* Transmission rate in kbits/s */
00498           if(strlen(argv[i]) > 3) {      
00499             a->alc_a.tx_rate = (unsigned int)atoi(&argv[i][3]);
00500           }
00501           else {
00502             return -1;
00503           }
00504           break;
00505           
00506         case 'S':  /* sender */
00507           if(strlen(argv[i]) > 2) {
00508             return -1;
00509           }
00510           a->alc_a.mode = SENDER;
00511           a->toi = FDT_TOI;
00512           break;
00513         case 's':  /* first alc session identifier */
00514           if(strlen(argv[i]) > 3) {
00515             a->alc_a.src_addr = &argv[i][3];
00516           }
00517           else {
00518             return -1;
00519           }
00520           break;
00521         case 'T':  /* ttl */
00522           if(strlen(argv[i]) > 3) {
00523             a->alc_a.ttl = (unsigned char)atoi(&argv[i][3]);
00524           }
00525           else {
00526             return -1;
00527           }
00528           break;
00529         case 't':  /* second alc session identifier */
00530           if(strlen(argv[i]) > 3) {
00531 #ifdef _MSC_VER                   
00532             tmp_tsi = _atoi64(&argv[i][3]);
00533 #else       
00534             tmp_tsi = strtoull(&argv[i][3], &ep, 10);
00535             
00536             if(&argv[i][3] == '\0' || *ep != '\0') {                   
00537               printf("TSI not a number\n");
00538               fflush(stdout);
00539               return -1;
00540             }
00541             
00542             if(errno == ERANGE && tmp_tsi == 0xFFFFFFFFFFFFFFFFULL) {   
00543               printf("TSI too big for unsigned long long (64 bits)\n");
00544               fflush(stdout);
00545               return -1;
00546             }
00547 #endif 
00548 #ifdef _MSC_VER
00549             if(tmp_tsi > (unsigned long long)0xFFFFFFFFFFFF) {
00550               printf("TSI: %I64u too big (max=%I64u)\n", tmp_tsi, (unsigned long long)0xFFFFFFFFFFFF);
00551 #else
00552               if(tmp_tsi > 0xFFFFFFFFFFFFULL) {
00553                 printf("TSI: %llu too big (max=%llu)\n", tmp_tsi, 0xFFFFFFFFFFFFULL);
00554 #endif
00555                 fflush(stdout);
00556                 return -1;
00557               }
00558             }
00559             else {
00560               return -1;
00561             }
00562             break;
00563           case 'U':  /* unicast address */                    
00564             if(strlen(argv[i]) > 2) {
00565               return -1;
00566             }
00567             a->alc_a.addr_type = 1;
00568             break;
00569           case 'V': /* redirect stderr and stdout into given file */
00570             if (strlen(argv[i]) > 3) {
00571 #ifdef _MSC_VER
00572               a->log_fd = _open(&argv[i][3], _O_RDWR | _O_CREAT | _O_TRUNC, 0666);
00573 #else 
00574               a->log_fd = open(&argv[i][3], O_RDWR | O_CREAT | O_TRUNC, 0666);
00575 #endif
00576               
00577               if(a->log_fd < 0) {
00578                 
00579                 printf("Log file: %s cannot be opened\n", &argv[i][3]);
00580                 fflush(stdout);
00581                 return -1;
00582               }
00583               
00584 #ifdef _MSC_VER
00585               _dup2(a->log_fd, _fileno(stdout));
00586               _dup2(a->log_fd, _fileno(stderr));
00587 #else
00588               dup2(a->log_fd, fileno(stdout));
00589               dup2(a->log_fd, fileno(stderr));
00590 #endif
00591             }
00592             break;
00593           case 'v':  /* verbosity level */
00594             if(strlen(argv[i]) > 3) {
00595               a->alc_a.verbosity = atoi(&argv[i][3]);
00596               
00597               if(a->alc_a.verbosity > 4) {
00598                 printf("Possible values for option -v are: 0, 1, 2, 3, or 4\n");
00599                 fflush(stdout);
00600                 return -1;
00601               }
00602             }
00603             else {
00604               return -1;
00605             }
00606             break;
00607           case 'W':  /* File table output */
00608             if(strlen(argv[i]) > 2) {
00609               return -1;
00610             }
00611             a->file_table_output = TRUE;
00612             break;
00613           case 'w':  /* congestion control */
00614             if(strlen(argv[i]) > 3) {
00615               a->alc_a.cc_id = (unsigned char)atoi(&argv[i][3]);
00616               
00617               if(a->alc_a.cc_id > 1) {
00618                 printf("Possible values for option -w are: 0, or 1\n");
00619                 fflush(stdout);
00620                 return -1;
00621               }
00622             }
00623             else {
00624               return -1;
00625             }
00626             break;
00627           case 'X':  /* FEC ratio percent */
00628             if(strlen(argv[i]) > 3) {
00629               a->alc_a.fec_ratio = (unsigned short)atoi(&argv[i][3]);
00630             }
00631             else {
00632               return -1;
00633             }
00634             break;
00635           case 'x':  /* fec encoding */
00636             if(strlen(argv[i]) > 3) {
00637               fec_enc = (unsigned char)atoi(&argv[i][3]);
00638 
00639               if(fec_enc > 3) {
00640             printf("Possible values for option -x are: 0, 1, 2 or 3\n");
00641                         fflush(stdout);
00642             return -1;
00643               }
00644             }
00645             else {
00646               return -1;
00647             }
00648             break;
00649           case 'Z':  /* optimize transmission rate (use more CPU) */
00650             if(strlen(argv[i]) > 2) {
00651               return -1;
00652             }
00653             a->alc_a.optimize_tx_rate = TRUE;
00654             break;
00655           case 'z':  /* encode content */
00656             if(strlen(argv[i]) > 3) {
00657               a->alc_a.encode_content = (unsigned char)atoi(&argv[i][3]);
00658               
00659               if(a->alc_a.encode_content > 3) {
00660                 printf("Possible values for option -z are: 0, 1, 2 or 3\n");
00661                 fflush(stdout);
00662                 return -1;
00663               }
00664             }
00665             else {
00666               return -1;
00667             }
00668             break;
00669           default:
00670             return -1;
00671             break;
00672           }
00673         }
00674       else {
00675         return -1;
00676       }
00677     }
00678     
00679     if(tmp_addr == NULL) {
00680       if(a->alc_a.addr_family == PF_INET) {
00681         tmp_addr = DEF_MCAST_IPv4_ADDR;
00682       }
00683       else if(a->alc_a.addr_family == PF_INET6) {
00684         tmp_addr = DEF_MCAST_IPv6_ADDR;
00685       }
00686     }
00687     a->alc_a.addr = tmp_addr;
00688     
00689     if(fec_enc == 1) {
00690       a->alc_a.fec_enc_id = SIMPLE_XOR_FEC_ENC_ID;
00691       
00692       if(a->alc_a.addr_family == PF_INET) {
00693                 a->alc_a.es_len = MAX_SYMB_LENGTH_IPv4_FEC_ID_2_128_129;
00694       }
00695       else if(a->alc_a.addr_family == PF_INET6) {
00696                 a->alc_a.es_len = MAX_SYMB_LENGTH_IPv6_FEC_ID_2_128_129;
00697       }
00698     }
00699     else if(fec_enc == 2) {
00700       a->alc_a.fec_enc_id = SB_SYS_FEC_ENC_ID;
00701       a->alc_a.fec_inst_id = REED_SOL_FEC_INST_ID;
00702       
00703       if(a->alc_a.addr_family == PF_INET) {
00704                 a->alc_a.es_len = MAX_SYMB_LENGTH_IPv4_FEC_ID_2_128_129;
00705       }
00706       else if(a->alc_a.addr_family == PF_INET6) {
00707                 a->alc_a.es_len = MAX_SYMB_LENGTH_IPv6_FEC_ID_2_128_129;
00708       }
00709     }
00710     else if(fec_enc == 3) {
00711       a->alc_a.fec_enc_id = RS_FEC_ENC_ID;
00712     }
00713     
00714     if(a->alc_a.mode == RECEIVER) {
00715       a->alc_a.tsi = tmp_tsi;
00716       
00717       memset(a->alc_a.base_dir, 0, MAX_PATH_LENGTH);
00718       
00719       if(tmp_base_dir == NULL) {
00720             strcpy(a->alc_a.base_dir, DEF_BASE_DIR);
00721       }
00722       else {
00723             strcpy(a->alc_a.base_dir, tmp_base_dir);
00724       }
00725       
00726       a->alc_a.start_time = curr_time;
00727 
00728           if(duration == 0) {
00729                   a->alc_a.stop_time = curr_time + DEF_RECEIVER_TIMEOUT;
00730           }
00731           else {
00732                   a->alc_a.stop_time = curr_time + duration;
00733           }
00734       
00735 #ifdef USE_FILE_REPAIR
00736       if(repair) {
00737             memset(a->repair, 0, MAX_PATH_LENGTH);
00738         
00739             if(tmp_repair == NULL) {
00740               strcpy(a->repair, DEF_APD_CONF_FILE);
00741             }
00742             else {
00743              strcpy(a->repair, tmp_repair);
00744             }
00745       }
00746       else {
00747             memset(a->repair, 0, MAX_PATH_LENGTH);
00748       }
00749 #endif
00750       
00751     }
00752     else {
00753       if(((a->alc_a.half_word == FALSE) && (tmp_tsi > 0xFFFFFFFF))) {
00754             printf("TSI too big for unsigned long (32 bits)\n");
00755             fflush(stdout);
00756             return -1;
00757       }
00758       else {
00759             a->alc_a.tsi = tmp_tsi;
00760       }
00761       
00762       memset(a->alc_a.base_dir, 0, MAX_PATH_LENGTH);
00763       
00764       if(tmp_base_dir != NULL) {
00765             strcpy(a->alc_a.base_dir, tmp_base_dir);
00766       }
00767       
00768       a->alc_a.start_time = curr_time;
00769 
00770           if(duration == 0) {
00771         a->alc_a.stop_time = curr_time + DEF_SESSION_DURATION;
00772           }
00773           else {
00774         a->alc_a.stop_time = curr_time + duration;
00775           }
00776 
00777 #ifdef USE_FILE_REPAIR
00778       if(repair) {
00779             memset(a->repair, 0, MAX_PATH_LENGTH);
00780         
00781             if(tmp_repair == NULL) {
00782               strcpy(a->repair, DEF_FLUTE_CONF_FILE);
00783             }
00784             else {
00785              strcpy(a->repair, tmp_repair);
00786             }
00787       }
00788       else {
00789             memset(a->repair, 0, MAX_PATH_LENGTH);
00790       }
00791 #else
00792       if(repair) {
00793             memset(a->repair, 0, MAX_PATH_LENGTH);
00794         
00795             if(tmp_repair == NULL) {
00796               strcpy(a->repair, DEF_REPAIR_SENDER_CONF_FILE);
00797             }
00798             else {
00799               strcpy(a->repair, tmp_repair);
00800             }
00801       }
00802       else {
00803             memset(a->repair, 0, MAX_PATH_LENGTH);
00804       }
00805 #endif
00806     }
00807     
00808     if(tmp_max_sb_len != 0) {
00809       if(a->alc_a.fec_enc_id == COM_NO_C_FEC_ENC_ID) {
00810         
00811         if(tmp_max_sb_len > MAX_SB_LEN_NULL_FEC) {
00812           printf("Maximum source block length set to maximum value: %i\n", MAX_SB_LEN_NULL_FEC);
00813           fflush(stdout);
00814           tmp_max_sb_len = MAX_SB_LEN_NULL_FEC;
00815         }
00816         a->alc_a.max_sb_len = tmp_max_sb_len;
00817       }
00818       
00819       else if(a->alc_a.fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
00820         if(tmp_max_sb_len > MAX_SB_LEN_SIMPLE_XOR_FEC) {
00821           printf("Maximum source block length set to maximum value: %i\n", MAX_SB_LEN_SIMPLE_XOR_FEC);
00822           fflush(stdout);
00823           tmp_max_sb_len = MAX_SB_LEN_SIMPLE_XOR_FEC;
00824         }
00825         a->alc_a.max_sb_len = tmp_max_sb_len;
00826       }
00827       
00828       else if(((a->alc_a.fec_enc_id == RS_FEC_ENC_ID) || ((a->alc_a.fec_enc_id == SB_SYS_FEC_ENC_ID)
00829                && (a->alc_a.fec_inst_id == REED_SOL_FEC_INST_ID)))) {
00830         
00831         div_max_n = div((tmp_max_sb_len * (100 + a->alc_a.fec_ratio)), 100);
00832         
00833         if(div_max_n.quot > MAX_N_REED_SOLOMON) {
00834           
00835           div_max_k = div((MAX_N_REED_SOLOMON * 100), (100 + a->alc_a.fec_ratio));
00836           
00837           printf("Maximum source block length set to maximum value: %i\n", div_max_k.quot);
00838           fflush(stdout);
00839           tmp_max_sb_len = div_max_k.quot;
00840         }
00841         a->alc_a.max_sb_len = tmp_max_sb_len;
00842       }
00843     }
00844     
00845     if(tmp_es_len != 0) {
00846       if(a->alc_a.addr_family == PF_INET) {
00847         if(((a->alc_a.fec_enc_id == COM_NO_C_FEC_ENC_ID)
00848             || (a->alc_a.fec_enc_id == RS_FEC_ENC_ID)
00849             || (a->alc_a.fec_enc_id == COM_FEC_ENC_ID))) {
00850           if(tmp_es_len > MAX_SYMB_LENGTH_IPv4_FEC_ID_0_3_130) {
00851             printf("Encoding symbol length set to maximum value: %i\n",
00852                    MAX_SYMB_LENGTH_IPv4_FEC_ID_0_3_130);
00853             fflush(stdout);
00854             tmp_es_len = MAX_SYMB_LENGTH_IPv4_FEC_ID_0_3_130;
00855           }
00856         }
00857         else if(((a->alc_a.fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) ||
00858                  (a->alc_a.fec_enc_id == SB_LB_E_FEC_ENC_ID) ||
00859                  (a->alc_a.fec_enc_id == SB_SYS_FEC_ENC_ID))) {
00860           if(tmp_es_len > MAX_SYMB_LENGTH_IPv4_FEC_ID_2_128_129) {
00861             printf("Encoding symbol length set to maximum value: %i\n",
00862                    MAX_SYMB_LENGTH_IPv4_FEC_ID_2_128_129);
00863             fflush(stdout);
00864             tmp_es_len = MAX_SYMB_LENGTH_IPv4_FEC_ID_2_128_129;
00865           }     
00866         }
00867       }
00868       else if(a->alc_a.addr_family == PF_INET6) {       
00869         if(((a->alc_a.fec_enc_id == COM_NO_C_FEC_ENC_ID)
00870             || (a->alc_a.fec_enc_id == RS_FEC_ENC_ID)
00871             || (a->alc_a.fec_enc_id == COM_FEC_ENC_ID))) {
00872           if(tmp_es_len > MAX_SYMB_LENGTH_IPv6_FEC_ID_0_3_130) {
00873             printf("Encoding symbol length set to maximum value: %i\n",
00874                    MAX_SYMB_LENGTH_IPv6_FEC_ID_0_3_130);
00875             fflush(stdout);
00876             tmp_es_len = MAX_SYMB_LENGTH_IPv6_FEC_ID_0_3_130;
00877           }
00878         }
00879         else if(((a->alc_a.fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) ||
00880                  (a->alc_a.fec_enc_id == SB_LB_E_FEC_ENC_ID) ||
00881                  (a->alc_a.fec_enc_id == SB_SYS_FEC_ENC_ID))) {
00882           if(tmp_es_len > MAX_SYMB_LENGTH_IPv6_FEC_ID_2_128_129) {
00883             printf("Encoding symbol length set to maximum value: %i\n",
00884                    MAX_SYMB_LENGTH_IPv6_FEC_ID_2_128_129);
00885             fflush(stdout);
00886             tmp_es_len = MAX_SYMB_LENGTH_IPv6_FEC_ID_2_128_129;
00887           }     
00888         }
00889       }
00890       
00891       a->alc_a.es_len = tmp_es_len;
00892     }
00893 
00894     if(((((a->rx_automatic == TRUE) || (a->alc_a.mode == SENDER)))
00895         && (a->file_table_output == TRUE))) {
00896       a->alc_a.verbosity = -1;
00897     }
00898     
00899     return 0;
00900   }
00901 
00902 int parse_sdp_file(arguments_t *a, char addrs[MAX_CHANNELS_IN_SESSION][INET6_ADDRSTRLEN],
00903                    char ports[MAX_CHANNELS_IN_SESSION][MAX_PORT_LENGTH], char *sdp_buf) {
00904   int i;
00905   int m_lines = 0;
00906   int j = 0;
00907   int number_of_port;
00908   int number_of_address;
00909   int nb_of_accepted_ch = 0;
00910   int nb_of_defined_ch = 0;
00911   
00912   struct sockaddr_in ipv4;
00913   struct sockaddr_in6 ipv6;
00914   
00915   int position = 0;
00916   
00917 #ifdef _MSC_VER
00918   int addr_size;
00919 #else
00920   char *ep;
00921 #endif
00922   
00923   int m_line_att_pos;
00924   char *att_name;
00925   char *att_value;
00926   BOOL supported_fec = FALSE;
00927   BOOL fec_inst_exists = FALSE;
00928 
00929   char *addr_type = NULL;
00930   char *source_filter = NULL;
00931   char *tsi = NULL;
00932   char *flute_ch = NULL;
00933   int flute_ch_number;
00934   char *start_time = NULL;
00935   char *stop_time = NULL;
00936   fec_dec_t *fec_dec;
00937   fec_dec_t *current_fec_dec;
00938   
00939   sdp_message_init(&a->sdp);
00940 
00941   if(sdp_message_parse(a->sdp, sdp_buf) != 0) {
00942     printf("Error: sdp_parse()\n");
00943     fflush(stdout);
00944     return -1;
00945   }
00946   
00947   if((source_filter = sdp_attr_get(a->sdp, "source-filter")) == NULL) {
00948     printf("Error: Invalid SDP, source-filter not present.\n");
00949     fflush(stdout);
00950         return -1;
00951   }
00952   else {
00953           a->src_filt = sf_char2struct(source_filter);
00954           a->alc_a.src_addr = a->src_filt->src_addr;
00955   }
00956 
00957   if((tsi = sdp_attr_get(a->sdp, "flute-tsi")) == NULL) {
00958     printf("Error: Invalid SDP, TSI not present.\n");
00959     fflush(stdout);
00960         return -1;
00961   }
00962   else {
00963         a->alc_a.tsi = (unsigned int)atoi(tsi);
00964   }
00965 
00966   /* Default channel number is one and it is overwrited if there is
00967      'a:flute-ch' in the SDP file. */
00968   
00969   flute_ch_number = 1;
00970   flute_ch = sdp_attr_get(a->sdp, "flute-ch");
00971   
00972   if(flute_ch != NULL) {
00973     flute_ch_number = (unsigned int)atoi(flute_ch);
00974   }
00975 
00976   if((addr_type = sdp_message_c_addrtype_get(a->sdp, 0, 0)) == NULL) {
00977     printf("Error: Invalid SDP, no valid 'c' field.\n");
00978     fflush(stdout);
00979         return -1;
00980   }
00981   else {
00982         if(strcmp(addr_type, "IP4") == 0) {
00983                 a->alc_a.addr_family = PF_INET;
00984         }
00985         else if(strcmp(addr_type, "IP6") == 0) {
00986                 a->alc_a.addr_family = PF_INET6;
00987         }
00988         else {
00989                 printf("Error: Invalid SDP, address type invalid.\n");
00990                 fflush(stdout);
00991                 return -1;
00992         }
00993   }
00994   
00995   /* fetch session starttime */
00996   
00997   start_time = sdp_message_t_start_time_get (a->sdp, 0);
00998   
00999   if(start_time != NULL) {
01000 #ifdef _MSC_VER                   
01001     a->alc_a.start_time = _atoi64(start_time);
01002     
01003     if(a->alc_a.start_time > (unsigned long long)0xFFFFFFFFFFFFFFFF) {
01004       printf("Error: Invalid SDP, start time too big.\n");
01005       fflush(stdout);   
01006       return -1;
01007     }
01008 #else                           
01009     a->alc_a.start_time = strtoull(start_time, &ep, 10);
01010     
01011     if(errno == ERANGE && a->alc_a.start_time == 0xFFFFFFFFFFFFFFFFULL) {
01012       printf("Error: Invalid SDP, start time too big.\n");
01013       fflush(stdout); 
01014       return -1;
01015     }
01016 #endif  
01017   }
01018   
01019   /* fetch session stoptime */
01020   
01021   stop_time = sdp_message_t_stop_time_get (a->sdp, 0);
01022   
01023   if(stop_time != NULL) {
01024 #ifdef _MSC_VER                   
01025     a->alc_a.stop_time = _atoi64(stop_time);
01026     
01027     if(a->alc_a.stop_time > (unsigned long long)0xFFFFFFFFFFFFFFFF) {
01028       printf("Error: Invalid SDP, stop time too big.\n");
01029       fflush(stdout);   
01030       return -1;
01031     }
01032 #else                           
01033     a->alc_a.stop_time = strtoull(stop_time, &ep, 10);
01034     
01035     if(errno == ERANGE && a->alc_a.stop_time == 0xFFFFFFFFFFFFFFFFULL) {
01036       printf("Error: Invalid SDP, stop time too big.\n");
01037       fflush(stdout); 
01038       return -1;
01039     }
01040 #endif
01041         if(a->alc_a.stop_time == 0) {
01042                 a->cont = TRUE;
01043         }
01044   }
01045   
01046   /* Session level FEC declaration */
01047   fec_dec = sdp_fec_dec_get(a->sdp);
01048   
01049   /* Search how many m-lines is defined in SDP */
01050 
01051   while(1) {
01052           if(sdp_message_endof_media(a->sdp, position) == 0) {
01053                   /* check that 'proto' field is FLUTE/UDP */
01054                   if(strcmp(sdp_message_m_proto_get(a->sdp, position), "FLUTE/UDP") == 0) {
01055                           /* check that payload number exists */
01056                           if(sdp_message_m_payload_get(a->sdp, position, 0) != NULL) {
01057                                   m_lines++;
01058                           }
01059                   }
01060                   position++;
01061           }
01062           else {
01063                   break;
01064           }
01065   }
01066   
01067   if(m_lines == 0) {
01068     printf("Error: Invalid SDP, no valid 'm' field.\n");
01069     fflush(stdout);
01070     fec_dec_free(fec_dec);
01071     return -1;
01072   }
01073   
01074   for(i = 0; i < m_lines; i++) {
01075     
01076     m_line_att_pos = 0;
01077     
01078     while((att_name = sdp_message_a_att_field_get(a->sdp, i, m_line_att_pos)) != NULL) {
01079       
01080       if(strcmp(att_name, "FEC") == 0) {
01081         fec_inst_exists = TRUE;
01082         att_value = sdp_message_a_att_value_get(a->sdp, i, m_line_att_pos);
01083         
01084         if(fec_dec == NULL) {
01085           printf("Error: Invalid SDP, FEC-declaration does not exists.\n");
01086           fflush(stdout);
01087           return -1;
01088         }
01089         
01090         current_fec_dec = fec_dec;
01091         
01092         while(current_fec_dec != NULL) {
01093           
01094           if(current_fec_dec->index == (unsigned int)atoi(att_value)) {
01095             
01096             if(current_fec_dec->fec_enc_id == COM_NO_C_FEC_ENC_ID) {
01097               a->alc_a.fec_enc_id = COM_NO_C_FEC_ENC_ID;
01098               a->alc_a.fec_inst_id = 0;
01099               supported_fec = TRUE;
01100             }
01101             else if(current_fec_dec->fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
01102               a->alc_a.fec_enc_id = SIMPLE_XOR_FEC_ENC_ID;
01103               a->alc_a.fec_inst_id = 0;
01104               supported_fec = TRUE;
01105             }
01106             else if(current_fec_dec->fec_enc_id  == RS_FEC_ENC_ID) {
01107               a->alc_a.fec_enc_id = RS_FEC_ENC_ID;
01108               a->alc_a.fec_inst_id = 0;
01109               supported_fec = TRUE;
01110         }
01111             else if(current_fec_dec->fec_enc_id  == SB_SYS_FEC_ENC_ID &&
01112                     current_fec_dec->fec_inst_id == REED_SOL_FEC_INST_ID) {
01113               a->alc_a.fec_enc_id = SB_SYS_FEC_ENC_ID;
01114               a->alc_a.fec_inst_id = REED_SOL_FEC_INST_ID;
01115               supported_fec = TRUE;
01116             }
01117           }
01118           current_fec_dec = current_fec_dec->next;
01119         }
01120       }
01121       else if(strcmp(att_name, "FEC-declaration") == 0) {
01122         fec_inst_exists = TRUE;
01123         att_value = sdp_message_a_att_value_get(a->sdp, i, m_line_att_pos);
01124         
01125         current_fec_dec = fec_dec_char2struct(att_value);
01126         
01127         if(current_fec_dec->fec_enc_id == COM_NO_C_FEC_ENC_ID) {
01128           a->alc_a.fec_enc_id = COM_NO_C_FEC_ENC_ID;
01129           a->alc_a.fec_inst_id = 0;
01130           supported_fec = TRUE;
01131         }
01132         else if(current_fec_dec->fec_enc_id == SIMPLE_XOR_FEC_ENC_ID) {
01133           a->alc_a.fec_enc_id = SIMPLE_XOR_FEC_ENC_ID;
01134           a->alc_a.fec_inst_id = 0;
01135           supported_fec = TRUE;
01136         }
01137         else if(current_fec_dec->fec_enc_id  == RS_FEC_ENC_ID) {
01138           a->alc_a.fec_enc_id = RS_FEC_ENC_ID;
01139           a->alc_a.fec_inst_id = 0;
01140           supported_fec = TRUE;
01141         }
01142         else if(current_fec_dec->fec_enc_id == SB_SYS_FEC_ENC_ID &&
01143                 current_fec_dec->fec_inst_id == REED_SOL_FEC_INST_ID) {
01144           a->alc_a.fec_enc_id = SB_SYS_FEC_ENC_ID;
01145           a->alc_a.fec_inst_id = REED_SOL_FEC_INST_ID;
01146           supported_fec = TRUE;
01147         }
01148         
01149         fec_dec_free(current_fec_dec);
01150       }
01151       m_line_att_pos++;
01152     }
01153   
01154     if(fec_inst_exists == FALSE) {
01155       supported_fec = TRUE;
01156       a->alc_a.fec_enc_id = COM_NO_C_FEC_ENC_ID;
01157       a->alc_a.fec_inst_id = 0;
01158     }
01159   
01160     /* how many ports in m-line */
01161     
01162     if(sdp_message_m_number_of_port_get(a->sdp, i) == NULL) {
01163       number_of_port = 1;
01164     }
01165     else {
01166       number_of_port = atoi(sdp_message_m_number_of_port_get(a->sdp, i));
01167     }
01168     
01169     /* how many addresses in c-line */
01170     
01171     if(sdp_message_c_addr_multicast_int_get(a->sdp, i, 0) == NULL) {
01172       number_of_address = 1;
01173     }
01174     else {
01175       number_of_address = atoi(sdp_message_c_addr_multicast_int_get(a->sdp, i, 0));
01176     }
01177     
01178     if(((number_of_port != 1) && (number_of_address != 1))) {
01179       printf("Error: Invalid SDP, confusing number of ports and addresses.\n");
01180       fflush(stdout);
01181       fec_dec_free(fec_dec);   
01182       return -1;
01183     }
01184     
01185     if(number_of_address == 1) {
01186 
01187       for(j = 0; j < number_of_port; j++) {     
01188         if(supported_fec == TRUE) {
01189           memset(ports[nb_of_accepted_ch], 0, MAX_PORT_LENGTH);
01190           memset(addrs[nb_of_accepted_ch], 0, INET6_ADDRSTRLEN); 
01191           sprintf(ports[nb_of_accepted_ch], "%i", (atoi(sdp_message_m_port_get(a->sdp, i)) + j));
01192           strcpy(addrs[nb_of_accepted_ch], sdp_message_c_addr_get(a->sdp, i, 0));
01193 
01194           nb_of_accepted_ch++;
01195         }
01196         nb_of_defined_ch++;
01197       }
01198     }
01199     else if(number_of_port == 1) {
01200 
01201       for(j = 0; j < number_of_address; j++) {
01202         if(supported_fec == TRUE) {
01203           if(a->alc_a.addr_family == PF_INET) {
01204             memset(addrs[nb_of_accepted_ch], 0, INET6_ADDRSTRLEN);
01205             ipv4.sin_addr.s_addr = htonl(ntohl(inet_addr(a->alc_a.addr)) + j);
01206             sprintf(addrs[j], "%s", inet_ntoa(ipv4.sin_addr));
01207             
01208             memset(ports[nb_of_accepted_ch], 0, MAX_PORT_LENGTH);
01209             sprintf(ports[nb_of_accepted_ch], "%i",  atoi(sdp_message_m_port_get(a->sdp, i)));
01210           }
01211           else if(a->alc_a.addr_family == PF_INET6) {
01212 #ifdef _MSC_VER
01213             addr_size = sizeof(struct sockaddr_in6);
01214             WSAStringToAddress((char*)a->alc_a.addr, AF_INET6, NULL, (struct sockaddr*)&ipv6, &addr_size);
01215 #else 
01216             inet_pton(AF_INET6, a->alc_a.addr, &ipv6.sin6_addr);
01217 #endif
01218             
01219             memset(addrs[nb_of_accepted_ch], 0, INET6_ADDRSTRLEN);
01220 
01221 #ifdef _MSC_VER
01222             addr_size = sizeof(addrs[nb_of_accepted_ch]);
01223                 WSAAddressToString((struct sockaddr*)&ipv6, sizeof(struct sockaddr_in6),
01224                         NULL, addrs[nb_of_accepted_ch], &addr_size);
01225 #else
01226             inet_ntop(AF_INET6, &ipv6.sin6_addr, addrs[nb_of_accepted_ch], sizeof(addrs[nb_of_accepted_ch]));
01227 #endif
01228             
01229             memset(ports[nb_of_accepted_ch], 0, MAX_PORT_LENGTH);
01230             sprintf(ports[nb_of_accepted_ch], "%i",  atoi(sdp_message_m_port_get(a->sdp, i)));
01231             
01232             if(j < (a->alc_a.nb_channel - 1)) {
01233               if(increase_ipv6_address(&ipv6.sin6_addr) == -1) {
01234                 printf("Increasing IPv6 address %s is not possible\n", addrs[j]);
01235                 fec_dec_free(fec_dec);
01236                 return -1;
01237               }
01238             }
01239           }
01240           nb_of_accepted_ch++;
01241         }
01242         nb_of_defined_ch++;
01243       }
01244     }
01245   }
01246     
01247   if(flute_ch_number != nb_of_defined_ch) {
01248     printf("Error: Invalid SDP, channel number not correct.\n");
01249     fflush(stdout);
01250     fec_dec_free(fec_dec);
01251     return -1;
01252   }
01253   
01254   a->alc_a.nb_channel = nb_of_accepted_ch;
01255   
01256   fec_dec_free(fec_dec);
01257   
01258   return 0;
01259 }
01260 
01261 void free_args(arguments_t *a) {
01262 
01263   if(a == NULL) {
01264     return;
01265   }
01266 
01267   if(a->log_fd != -1) {
01268     close(a->log_fd);
01269   }
01270 
01271   if(strcmp(a->sdp_file, "") != 0) {
01272     sf_free(a->src_filt);
01273     free(a->src_filt);
01274     sdp_message_free(a->sdp);
01275   }
01276 }
01277 
01278  

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