flute.c

Go to the documentation of this file.
00001 
00033 #include <stdlib.h>
00034 #include <assert.h>
00035 #include <sys/stat.h>
00036 #include <errno.h>
00037 #include <fcntl.h>
00038 #include <ctype.h>
00039 #include <time.h>
00040 #include <string.h>
00041 #include <stdio.h>
00042 
00043 #ifdef _MSC_VER
00044 #include <winsock2.h>
00045 #include <ws2tcpip.h>
00046 #include <process.h>
00047 #include <io.h>
00048 #include <direct.h>
00049 #else
00050 #include <sys/socket.h>
00051 #include <netinet/in.h>
00052 #include <arpa/inet.h>
00053 #include <netdb.h>
00054 #endif
00055 
00056 #include "../alclib/alc_session.h"
00057 #include "../alclib/alc_tx.h"
00058 #include "../alclib/alc_rx.h"
00059 
00060 #include "flute.h"
00061 #include "fdt_gen.h"
00062 #include "receiver.h"
00063 #include "sender.h"
00064 #include "uri.h"
00065 #include "padding_encoding.h"
00066 #include "mad_zlib.h"
00067 #include "mad_md5.h"
00068 #include "display.h"
00069 
00070 #ifdef USE_FILE_REPAIR
00071 #include "http_file_repair.h"
00072 #include "flute_file_repair.h"
00073 #include "apd.h"
00074 #endif
00075 
00085 int name_incomplete_objects(flute_receiver_t *receiver) {
00086 
00087         trans_obj_t *to = NULL;
00088         file_t *file = NULL;
00089         file_t *next_file = NULL;
00090         uri_t *uri = NULL;
00091         char *filepath = NULL;
00092         char *tmp = NULL;
00093         char* session_basedir = NULL;
00094         char *ptr;
00095         int point; 
00096         int ch = '/';
00097         int i;
00098         char fullpath[MAX_PATH_LENGTH];
00099         char filename[MAX_PATH_LENGTH];
00100         int retval;
00101         char *pad_tmp_filename = NULL;
00102         char *tmp_filename = NULL;
00103 
00104         session_basedir = get_session_basedir(receiver->s_id);
00105         to = get_session_obj_list(receiver->s_id);
00106 
00107         while(to != NULL) {
00108                 next_file = receiver->fdt->file_list;
00109                 while(next_file != NULL) {
00110                         file = next_file;
00111 
00112                         if(file->toi == to->toi) {
00113                                 break;
00114                         }
00115 
00116                         next_file = file->next;
00117                 }
00118 
00119                 if(file->encoding != NULL && strcmp(file->encoding, "gzip") == 0) {
00120                         printf("Cannot rename content encoded incomplete object.\n");
00121                         to = to->next;
00122                         continue;
00123                 }
00124 
00125                 uri = parse_uri(file->location, strlen(file->location));
00126                 filepath = get_uri_host_and_path(uri);
00127 
00128                 if(!(tmp = (char*)calloc((strlen(filepath) + 1), sizeof(char)))) {
00129                         printf("Could not alloc memory for tmp-filepath!\n");
00130                         fflush(stdout);
00131 
00132                         free(filepath);
00133                         free_uri(uri);
00134                         return -1;
00135                 }
00136 
00137                 memcpy(tmp, filepath, strlen(filepath));
00138                 ptr = strchr(tmp, ch);
00139 
00140                 memset(fullpath, 0, MAX_PATH_LENGTH);
00141                 memcpy(fullpath, session_basedir, strlen(session_basedir));
00142 
00143                 i = 0;
00144 
00145                 if(ptr != NULL) {
00146                         while(ptr != NULL) {
00147                                 i++;
00148                                 point = (int)(ptr - tmp);
00149 
00150                                 memset(filename, 0, MAX_PATH_LENGTH);           
00151 #ifdef _MSC_VER
00152                                 memcpy((fullpath + strlen(fullpath)), "\\", 1);
00153 #else
00154                                 memcpy((fullpath + strlen(fullpath)), "/", 1);
00155 #endif
00156                                 memcpy((fullpath + strlen(fullpath)), tmp, point);
00157 
00158                                 memcpy(filename, (tmp + point + 1), (strlen(tmp) - (point + 1)));               
00159 #ifdef _MSC_VER
00160                                 if(mkdir(fullpath) < 0) {                                       
00161 #else           
00162                                 if(mkdir(fullpath, S_IRWXU) < 0) {
00163 #endif
00164                                         if(errno != EEXIST) {
00165                                                 printf("mkdir failed: cannot create directory %s (errno=%i)\n", fullpath, errno);
00166                                                 fflush(stdout);
00167 
00168                                                 free(tmp);
00169                                                 free(filepath);
00170                                                 free_uri(uri);
00171                                                 return -1;
00172                                         }
00173                                 }
00174 
00175                                 strcpy(tmp, filename);
00176                                 ptr = strchr(tmp, ch);
00177                         }
00178 #ifdef _MSC_VER
00179                         memcpy((fullpath + strlen(fullpath)), "\\", 1);
00180 #else
00181                         memcpy((fullpath + strlen(fullpath)), "/", 1);
00182 #endif
00183                         memcpy((fullpath + strlen(fullpath)), filename, strlen(filename));
00184                 }
00185                 else{
00186 #ifdef _MSC_VER
00187                         memcpy((fullpath + strlen(fullpath)), "\\", 1);
00188 #else
00189                         memcpy((fullpath + strlen(fullpath)), "/", 1);
00190 #endif
00191                         memcpy((fullpath + strlen(fullpath)), filepath, strlen(filepath));
00192                 }
00193 
00194                 if(!(tmp_filename = (char*)calloc((strlen(to->tmp_filename) + 1), sizeof(char)))) {
00195                         printf("Could not alloc memory for tmp_filename!\n");
00196 
00197                         free(tmp);
00198                         free(filepath);
00199                         free_uri(uri);
00200                         return -1;    
00201                 }
00202 
00203                 if(file->encoding == NULL) {
00204                         memcpy(tmp_filename, to->tmp_filename, strlen(to->tmp_filename));
00205                         free_object(to, get_alc_session(receiver->s_id), 1);
00206                 }
00207                 else if(strcmp(file->encoding, "pad") == 0) {
00208 
00209                         if(!(pad_tmp_filename = (char*)calloc((strlen(to->tmp_filename) + 1), sizeof(char)))) {
00210                                 printf("Could not alloc memory for pad_tmp_filename!\n");
00211 
00212                                 free(tmp);
00213                                 free(filepath);
00214                                 free_uri(uri);
00215                                 return -1;    
00216                         }
00217 
00218                         memcpy(pad_tmp_filename, to->tmp_filename, strlen(to->tmp_filename));
00219 
00220                         ptr = strstr(to->tmp_filename, PAD_SUFFIX);
00221                         memcpy(tmp_filename, to->tmp_filename, (ptr - to->tmp_filename));
00222 
00223                         free_object(to, get_alc_session(receiver->s_id), 1);
00224 
00225                         retval = padding_decoder(pad_tmp_filename, (int)file->content_len);
00226 
00227                         if(retval == -1) {
00228                                 free(tmp_filename);
00229                                 free(pad_tmp_filename); 
00230                                 free(tmp);
00231                                 free(filepath);
00232                                 free_uri(uri);
00233                                 return -1;             
00234                         }
00235 
00236                         free(pad_tmp_filename);
00237                 }       
00238 
00239                 if(rename(tmp_filename, fullpath) < 0) {
00240 
00241                         if(errno == EEXIST) {
00242                                 retval = remove(fullpath);
00243 
00244                                 if(retval == -1) {    
00245                                         printf("errno: %i\n", errno);
00246                                         fflush(stdout);
00247                                 }
00248 
00249                                 if(rename(tmp_filename, fullpath) < 0) {
00250                                         printf("rename() error1: %s\n", tmp_filename);
00251                                         fflush(stdout);
00252                                 }
00253                         }
00254                         else {
00255                                 printf("rename() error2: %s\n", tmp_filename);
00256                                 fflush(stdout);
00257                         }
00258                 }
00259 
00260                 free(tmp);
00261                 free(filepath);
00262                 free_uri(uri);
00263                 free(tmp_filename);
00264 
00265                 to = get_alc_session(receiver->s_id)->obj_list;
00266         }
00267 
00268         return 0;
00269 }
00270 
00280 void add_missing_block(flute_receiver_report_t *report, unsigned long long first, 
00281                        unsigned long long last) {
00282     missing_block_t *block = malloc(sizeof(missing_block_t));
00283     block->first = first;
00284     block->last = last;
00285     block->next = report->mb_list;
00286 
00287     report->mb_list = block;
00288 }
00289 
00299 void copy_file_name(char **file_name, flute_receiver_t *r, unsigned long long toi) {
00300     file_t *file;
00301 
00302     file = find_file_with_toi(r->fdt, toi);
00303 
00304     *file_name = malloc(strlen(file->location)+1);
00305     strcpy(*file_name, file->location);
00306 }
00307 
00317 void copy_md5(char **md5, flute_receiver_t *r, unsigned long long toi) {
00318     file_t *file;
00319 
00320     file = find_file_with_toi(r->fdt, toi);
00321 
00322     *md5 = malloc(strlen(file->md5)+1);
00323     strcpy(*md5, file->md5);
00324 }
00325 
00335 void build_report(arguments_t *a, flute_receiver_t *r, flute_receiver_report_t **report) {
00336     trans_obj_t *obj_list;
00337     flute_receiver_report_t *report_row;
00338         unsigned long long position ;
00339     unsigned long long to_data_left;
00340     trans_block_t *tb;
00341     unsigned int i;
00342 
00343     if(report == NULL) {
00344         return;
00345     }
00346 
00347     assert(a != NULL);
00348     assert(r != NULL);
00349 
00350     *report = NULL;
00351     obj_list = get_session_obj_list(r->s_id);
00352     while(obj_list != NULL) {
00353         if(!object_completed(obj_list)) {
00354             // Not completed file found
00355             position = 0;
00356             to_data_left = obj_list->len;
00357             tb = obj_list->block_list;
00358 
00359             report_row = malloc(sizeof(flute_receiver_report_t));
00360             copy_file_name(&(report_row->file_name), r, obj_list->toi);
00361             copy_md5(&(report_row->md5), r, obj_list->toi);
00362             report_row->mb_list = NULL;
00363             report_row->next = *report;
00364             *report = report_row;
00365 
00366             if(a->alc_a.verbosity >= 4) {
00367                 printf("%s received incomplete\n", report_row->file_name);
00368             }
00369 
00370             for(i = 0; i < obj_list->bs->N; ++i) {
00371 
00372                 // This is the len of a generic undecoded block
00373                 unsigned long long block_len = obj_list->es_len*tb->k;
00374 
00375                 // This is the len of the next undecoded block
00376                 unsigned long long len = to_data_left < block_len ? to_data_left : block_len;
00377 
00378                 if(!block_ready_to_decode(tb)) {
00379                     // missed bytes from position to position+len;
00380                     add_missing_block(report_row, position, position+len);
00381                     if(a->alc_a.verbosity >= 4) {
00382 #ifdef _MSC_VER
00383                         printf("Missing bytes from %I64x to %I64x\n", position, position+len);
00384 #else
00385                         printf("Missing bytes from %llu to %llu\n", position, position+len);
00386 #endif
00387                     }
00388                 }
00389 
00390                 assert(0 <= position);
00391                 assert(position < obj_list->len+1);
00392                 assert(len <= (obj_list->len-position));
00393 
00394                 position += len;
00395                 to_data_left -= len;
00396 
00397                 assert(to_data_left >= 0);
00398 
00399                 tb = obj_list->block_list+(i+1);
00400             }
00401         }
00402 
00403         obj_list = obj_list->next;
00404     }
00405 }
00406 
00407 
00417 #ifdef USE_FILE_REPAIR
00418 unsigned int random_number(int max) {
00419         return (unsigned int)(rand()%max);
00420 }
00421 #endif
00422 
00423 int flute_sender(arguments_t *a, int *s_id, unsigned long long *session_size) {
00424 
00425         unsigned short i;
00426         int j, n;
00427         int retval = 0;
00428         int retcode = 0;
00429 
00430         struct sockaddr_in ipv4;
00431         struct sockaddr_in6 ipv6;
00432 
00433         char addrs[MAX_CHANNELS_IN_SESSION][INET6_ADDRSTRLEN];  /* Mcast addresses on which to send */
00434         char ports[MAX_CHANNELS_IN_SESSION][MAX_PORT_LENGTH];      /* Local port numbers  */
00435 
00436         char tmp[5];
00437 
00438         time_t systime;
00439 
00440         unsigned long long curr_time;
00441 
00442 #ifdef USE_FILE_REPAIR
00443         char flute_fdt_file[MAX_PATH_LENGTH];
00444         char fullpath[MAX_PATH_LENGTH];
00445         FILE *fp;
00446 #endif
00447 
00448         char *sdp_buf = NULL;
00449         FILE *sdp_fp;
00450         struct stat sdp_file_stats;
00451         int nbytes;
00452 
00453 #ifdef _MSC_VER
00454         HANDLE handle_sender_file_table_output_thread;
00455         unsigned int sender_file_table_output_thread_id;
00456         int addr_size;
00457 #else
00458         pthread_t sender_file_table_output_thread_id;
00459         int join_retval;
00460 #endif
00461 
00462         flute_sender_t sender;
00463 
00464         *session_size = 0;
00465 
00466         if(strcmp(a->sdp_file, "") != 0) {
00467 
00468                 if(stat(a->sdp_file, &sdp_file_stats) == -1) {
00469                         printf("Error: %s is not valid file name\n", a->sdp_file);
00470                         fflush(stdout);
00471                         memset(a->sdp_file, 0, MAX_PATH_LENGTH);
00472                         return -1;
00473                 }
00474 
00475                 /* Allocate memory for buf */
00476                 if(!(sdp_buf = (char*)calloc((sdp_file_stats.st_size + 1), sizeof(char)))) {
00477                         printf("Could not alloc memory for sdp buffer!\n");
00478                         fflush(stdout);
00479                         return -1;
00480                 }
00481 
00482                 if((sdp_fp = fopen(a->sdp_file, "rb")) == NULL) {
00483                         printf("Error: unable to open sdp_file %s\n", a->sdp_file);
00484                         fflush(stdout);
00485                         free(sdp_buf);
00486                         return -1;
00487                 }
00488 
00489                 nbytes = fread(sdp_buf, 1, sdp_file_stats.st_size, sdp_fp); 
00490 
00491                 if(parse_sdp_file(a, addrs, ports, sdp_buf) == -1) {
00492                         free(sdp_buf);
00493                         return -1;
00494                 }
00495 
00496                 free(sdp_buf);
00497         }
00498         else {
00499                 if(a->alc_a.addr_family == PF_INET) {
00500 
00501                         for(j = 0; j < a->alc_a.nb_channel; j++) {
00502                                 memset(addrs[j], 0, INET6_ADDRSTRLEN);
00503                                 ipv4.sin_addr.s_addr = htonl(ntohl(inet_addr(a->alc_a.addr)) + j);
00504                                 sprintf(addrs[j], "%s", inet_ntoa(ipv4.sin_addr));
00505 
00506                                 memset(ports[j], 0, MAX_PORT_LENGTH);
00507                                 sprintf(ports[j], "%i", (atoi(a->alc_a.port) + j));
00508                         }
00509                 }
00510                 else if(a->alc_a.addr_family == PF_INET6) {
00511 
00512 #ifdef _MSC_VER
00513                         addr_size = sizeof(struct sockaddr_in6);
00514                         WSAStringToAddress((char*)a->alc_a.addr, AF_INET6, NULL, (struct sockaddr*)&ipv6, &addr_size);
00515 #else 
00516                         inet_pton(AF_INET6, a->alc_a.addr, &ipv6.sin6_addr);
00517 #endif
00518 
00519                         for(j = 0; j < a->alc_a.nb_channel; j++) {
00520 
00521                                 memset(addrs[j], 0, INET6_ADDRSTRLEN);
00522 
00523 #ifdef _MSC_VER
00524                                 addr_size = sizeof(addrs[j]);
00525                                 WSAAddressToString((struct sockaddr*)&ipv6, sizeof(struct sockaddr_in6),
00526                                         NULL, addrs[j], &addr_size);
00527 #else
00528                                 inet_ntop(AF_INET6, &ipv6.sin6_addr, addrs[j], sizeof(addrs[j]));
00529 #endif
00530 
00531                                 memset(ports[j], 0, MAX_PORT_LENGTH);
00532                                 sprintf(ports[j], "%i", (atoi(a->alc_a.port) + j));
00533 
00534                                 if(j < (a->alc_a.nb_channel - 1)) {
00535                                         if(increase_ipv6_address(&ipv6.sin6_addr) == -1) {
00536                                                 printf("Increasing IPv6 address %s is not possible\n", addrs[j]);
00537                                                 return -1;
00538                                         }
00539                                 }
00540                         }
00541                 }
00542         }
00543 
00544         if(a->alc_a.stop_time != 0) {
00545                 time(&systime);
00546                 curr_time = systime + 2208988800U;
00547 
00548                 if(a->alc_a.stop_time <= curr_time) {
00549                         printf("Session end time reached\n");
00550                         fflush(stdout);
00551                         return -3;
00552                 }
00553         }
00554 
00555         *s_id = open_alc_session(&a->alc_a);
00556 
00557         if(*s_id < 0) {
00558                 printf("Error opening ALC session\n");
00559                 fflush(stdout);
00560                 return -1;
00561         }
00562 
00563         for(i = 0; (int)i < a->alc_a.nb_channel; i++) {
00564 
00565                 if(a->alc_a.addr_type == 1) {
00566                         retval = add_alc_channel(*s_id, ports[i], addrs[0], a->alc_a.intface, a->alc_a.intface_name);
00567                 }
00568                 else {
00569                         retval = add_alc_channel(*s_id, ports[i], addrs[i], a->alc_a.intface, a->alc_a.intface_name);
00570                 }
00571 
00572                 if(retval == -1) {    
00573                         close_alc_session(*s_id);
00574                         return -1;
00575                 }       
00576         }
00577 
00578         /* Generate fdt file first */
00579         if(strcmp(a->fdt_file, "") == 0) {
00580 
00581                 memset(a->fdt_file, 0, MAX_PATH_LENGTH);
00582                 strcpy(a->fdt_file, "fdt_tsi");
00583 
00584                 memset(tmp, 0, 5);
00585 
00586 #ifdef _MSC_VER
00587                 sprintf(tmp, "%I64u", a->alc_a.tsi);
00588 #else
00589                 sprintf(tmp, "%llu", a->alc_a.tsi);
00590 #endif
00591 
00592                 strcat(a->fdt_file, tmp);
00593                 strcat(a->fdt_file, ".xml");
00594 
00595                 retcode = generate_fdt(a->file_path, a->alc_a.base_dir, s_id, a->fdt_file, a->complete_fdt,
00596                         a->alc_a.verbosity);
00597 
00598                 if(retcode < 0) {
00599                         close_alc_session(*s_id);
00600                         return -1;
00601                 }
00602         }
00603 
00604 #ifdef USE_FILE_REPAIR
00605         if(strcmp(a->repair, "") != 0) {
00606 
00607                 if((fp = fopen(a->repair, "wb")) == NULL) {
00608                         close_alc_session(*s_id);
00609                         return -1;
00610                 }
00611 
00612                 memset(fullpath, 0, MAX_PATH_LENGTH);
00613                 memset(flute_fdt_file, 0, MAX_PATH_LENGTH);
00614 
00615                 if(getcwd(fullpath, MAX_PATH_LENGTH) != NULL) {
00616 
00617                   if(strcmp(a->alc_a.base_dir, "") == 0) {
00618                     fprintf(fp, "BaseDir=%s\n", fullpath);
00619                   }
00620                   else {
00621                     fprintf(fp, "BaseDir=%s\n", a->alc_a.base_dir);
00622                   }
00623                   
00624                   if(((a->alc_a.fec_enc_id == SB_SYS_FEC_ENC_ID) && (a->alc_a.fec_inst_id == REED_SOL_FEC_INST_ID))) {
00625                     fprintf(fp, "FECRatio=%i\n", a->alc_a.fec_ratio);
00626                   }
00627                   
00628 
00629                   if(strcmp(a->file_path, "") != 0) {
00630                     
00631                     memcpy(flute_fdt_file, fullpath, strlen(fullpath));
00632 #ifdef _MSC_VER
00633                     strcat(flute_fdt_file, "\\");
00634 #else
00635                     strcat(flute_fdt_file, "/");
00636 #endif
00637                     strcat(flute_fdt_file, a->fdt_file);
00638                   }
00639                   else {
00640                     strcat(flute_fdt_file, a->fdt_file);
00641                   }
00642                   fprintf(fp, "FDTFile=%s\n", flute_fdt_file);
00643                 }
00644                 
00645                 fclose(fp);
00646         }
00647 #endif
00648 
00649         sender.fdt = NULL;
00650         sender.s_id = *s_id;
00651 
00652         /* Create Display thread */
00653 
00654         if(a->file_table_output == TRUE) {
00655 
00656 #ifdef _MSC_VER
00657                 handle_sender_file_table_output_thread =
00658                         (HANDLE)_beginthreadex(NULL, 0, (void*)sender_file_table_output_thread,
00659                         (void*)&sender, 0, &sender_file_table_output_thread_id);
00660 
00661                 if(handle_sender_file_table_output_thread == NULL) {
00662                         perror("flute_sender(): _beginthread");
00663                         close_alc_session(*s_id);
00664                         return -1;
00665                 }
00666 #else
00667                 if(pthread_create(&sender_file_table_output_thread_id, NULL, sender_file_table_output_thread,
00668                         (void*)&sender) != 0) {
00669                                 perror("flute_sender(): pthread_create");
00670                                 close_alc_session(*s_id);
00671                                 return -1;
00672                 }
00673 #endif
00674         }
00675 
00676         /***** FDT based send *****/
00677 
00678         retval = sender_in_fdt_based_mode(a, &sender);
00679 
00680         /* If A flag packets must not be included into the session size, use this */
00681         *session_size = get_session_sent_bytes(*s_id);
00682 
00683         if(a->send_session_close_packets == 1) {
00684 
00685                 if(retval != -1) {
00686 
00687                         if(a->alc_a.verbosity > 0) {
00688                                 printf("Sending session close packets\n");
00689                                 fflush(stdout);
00690                         }
00691 
00692                         /* Let's send three session close packets for the base channel */
00693 
00694                         for(n = 0; n < 3; n++) {
00695                                 retcode = send_session_close_packet(*s_id);
00696                                 if(retcode == -1) {
00697                                         break;
00698                                 }
00699                         }
00700                 }
00701         }
00702 
00703         set_session_state(*s_id, SExiting);
00704 
00705         if(((a->alc_a.cc_id == RLC) || ((a->alc_a.cc_id == Null) && (a->alc_a.nb_channel != 1)))) {
00706 #ifdef _MSC_VER
00707                 WaitForSingleObject(get_alc_session(*s_id)->handle_tx_thread, INFINITE);
00708                 CloseHandle(get_alc_session(*s_id)->handle_tx_thread);
00709 #else
00710                 join_retval = pthread_join(get_alc_session(*s_id)->tx_thread_id, NULL);
00711                 assert(join_retval == 0);
00712                 pthread_detach(get_alc_session(*s_id)->tx_thread_id);
00713 #endif
00714         }
00715 
00716         if(a->file_table_output == TRUE) {
00717 #ifdef _MSC_VER
00718                 WaitForSingleObject(handle_sender_file_table_output_thread, INFINITE);
00719                 CloseHandle(handle_sender_file_table_output_thread);
00720 #else
00721                 join_retval = pthread_join(sender_file_table_output_thread_id, NULL);
00722                 assert(join_retval == 0);
00723                 pthread_detach(sender_file_table_output_thread_id);
00724 #endif
00725         }
00726 
00727         /* If A flag packets have to be included into the session size, use this */
00730         if(sender.fdt != NULL) {
00731                 FreeFDT(sender.fdt);
00732         }
00733 
00734         close_alc_session(*s_id);
00735 
00736         return retval;
00737 }
00738 
00739 int flute_receiver(arguments_t *a, int *s_id) {
00740     return flute_receiver_report(a, s_id, NULL);
00741 }
00742 
00743 int flute_receiver_report(arguments_t *a, int *s_id, flute_receiver_report_t **report) {
00744 
00745         unsigned short i;
00746         int j;
00747         int retval = 0;
00748 
00749         char wildcard_token[MAX_PATH_LENGTH];
00750         char *file_uri = NULL;
00751         int file_nb = 0;
00752 
00753         struct sockaddr_in ipv4;
00754         struct sockaddr_in6 ipv6;
00755 
00756         char addrs[MAX_CHANNELS_IN_SESSION][INET6_ADDRSTRLEN];  /* Mcast addresses */
00757         char ports[MAX_CHANNELS_IN_SESSION][MAX_PORT_LENGTH];         /* Local port numbers  */
00758 
00759         time_t systime;
00760         BOOL is_printed = FALSE;
00761 
00762         unsigned long long curr_time;
00763 
00764 #ifdef _MSC_VER
00765         HANDLE handle_fdt_thread;
00766         unsigned int fdt_thread_id;
00767         HANDLE handle_receiver_file_table_output_thread;
00768         unsigned int receiver_file_table_output_thread_id;
00769         int addr_size;
00770 #else
00771         pthread_t fdt_thread_id;
00772         pthread_t receiver_file_table_output_thread_id;
00773         int join_retval;
00774 #endif
00775 
00776         char *sdp_buf = NULL;
00777         FILE *sdp_fp;
00778         struct stat sdp_file_stats;
00779         int nbytes;
00780 
00781         flute_receiver_t receiver;
00782 
00783 #ifdef USE_FILE_REPAIR
00784         int n;
00785         char *file_repair_sdp_buf = NULL;
00786         serviceURI_t *tmp_serviceURI;
00787         int waitTime;
00788         apd_t *apd;
00789         unsigned int nb_of_http_servers;
00790         unsigned int http_server_index;
00791         int repairing_needed = 0;
00792 
00793         file_t *file = NULL;
00794         char *apd_buf = NULL;
00795         FILE *apd_fp;
00796         struct stat apd_file_stats;      
00797         int apd_nbytes;
00798 
00799         CURL *curl = NULL;
00800         CURLcode code;
00801         long responseCode;
00802         chunk_t chunk;
00803         char errorBuffer[CURL_ERROR_SIZE];
00804 #endif
00805 
00806 #ifdef _MSC_VER
00807         if(mkdir(a->alc_a.base_dir) < 0) {                                      
00808 #else           
00809         if(mkdir(a->alc_a.base_dir, S_IRWXU) < 0) {
00810 #endif
00811                 if(errno != EEXIST) {
00812                         printf("mkdir failed: cannot create directory %s (errno=%i)\n", a->alc_a.base_dir, errno);
00813                         fflush(stdout);
00814                         return -1;
00815                 }
00816         }
00817 
00818         if(strcmp(a->sdp_file, "") != 0) {
00819 
00820                 if(stat(a->sdp_file, &sdp_file_stats) == -1) {
00821                         printf("Error: %s is not valid file name\n", a->sdp_file);
00822                         fflush(stdout);
00823                         return -1;
00824                 }
00825 
00826                 /* Allocate memory for buf */
00827                 if(!(sdp_buf = (char*)calloc((sdp_file_stats.st_size + 1), sizeof(char)))) {
00828                         printf("Could not alloc memory for sdp buffer!\n");
00829                         fflush(stdout);
00830                         return -1;
00831                 }
00832 
00833                 if((sdp_fp = fopen(a->sdp_file, "rb")) == NULL) {
00834                         printf("Error: unable to open sdp_file %s\n", a->sdp_file);
00835                         fflush(stdout);
00836                         free(sdp_buf);
00837                         return -1;
00838                 }
00839 
00840                 nbytes = fread(sdp_buf, 1, sdp_file_stats.st_size, sdp_fp); 
00841 
00842                 if(parse_sdp_file(a, addrs, ports, sdp_buf) == -1) {
00843                         free(sdp_buf);
00844                         return -1;
00845                 }
00846 
00847                 free(sdp_buf);
00848 
00849                 if(a->alc_a.nb_channel == 0) {
00850                         printf("Error: No acceptable channels found in SDP.");
00851                         fflush(stdout);
00852                         return -1;
00853                 }    
00854         }
00855         else {
00856                 if(((a->alc_a.cc_id == Null) && (a->alc_a.nb_channel != 1))) {
00857 
00858                         if(a->alc_a.addr_family == PF_INET) {
00859                                 for(j = 0; j < a->alc_a.nb_channel; j++) {
00860                                         memset(addrs[j], 0, INET6_ADDRSTRLEN);
00861                                         ipv4.sin_addr.s_addr = htonl(ntohl(inet_addr(a->alc_a.addr)) + j);
00862                                         sprintf(addrs[j], "%s", inet_ntoa(ipv4.sin_addr));
00863 
00864                                         memset(ports[j], 0, MAX_PORT_LENGTH);
00865                                         sprintf(ports[j], "%i", (atoi(a->alc_a.port) + j));
00866                                 }
00867                         }
00868                         else if(a->alc_a.addr_family == PF_INET6) {
00869 
00870 #ifdef _MSC_VER
00871                                 addr_size = sizeof(struct sockaddr_in6);
00872                                 WSAStringToAddress((char*)a->alc_a.addr, AF_INET6, NULL, (struct sockaddr*)&ipv6, &addr_size);
00873 #else 
00874                                 inet_pton(AF_INET6, a->alc_a.addr, &ipv6.sin6_addr);
00875 #endif
00876 
00877                                 for(j = 0; j < a->alc_a.nb_channel; j++) {
00878                                         memset(addrs[j], 0, INET6_ADDRSTRLEN);
00879 
00880 #ifdef _MSC_VER
00881                                         addr_size = sizeof(addrs[j]);
00882                                         WSAAddressToString((struct sockaddr*)&ipv6, sizeof(struct sockaddr_in6),
00883                                                 NULL, addrs[j], &addr_size);
00884 #else
00885                                         inet_ntop(AF_INET6, &ipv6.sin6_addr, addrs[j], sizeof(addrs[j]));
00886 #endif
00887 
00888                                         memset(ports[j], 0, MAX_PORT_LENGTH);
00889                                         sprintf(ports[j], "%i", (atoi(a->alc_a.port) + j));
00890 
00891                                         if(j < (a->alc_a.nb_channel - 1)) {
00892                                                 if(increase_ipv6_address(&ipv6.sin6_addr) == -1) {
00893                                                         printf("Increasing IPv6 address %s is not possible\n", addrs[j]);
00894                                                         return -1;
00895                                                 }
00896                                         }
00897                                 }
00898                         }
00899                 }
00900                 else {
00901                         memset(addrs[0], 0, INET6_ADDRSTRLEN);
00902                         memset(ports[0], 0, MAX_PORT_LENGTH);
00903 
00904                         memcpy(addrs[0], a->alc_a.addr, strlen(a->alc_a.addr));
00905                         memcpy(ports[0], a->alc_a.port, strlen(a->alc_a.port));
00906                 }
00907         }
00908 
00909         if(a->alc_a.stop_time != 0) {
00910                 time(&systime);
00911                 curr_time = systime + 2208988800U;
00912 
00913                 if(a->alc_a.stop_time <= curr_time) {
00914                         printf("Session end time reached\n");
00915                         fflush(stdout);
00916                         return -1;
00917                 }
00918         }
00919 
00920         *s_id = open_alc_session(&a->alc_a);
00921 
00922         if(*s_id < 0) {
00923                 printf("Error opening ALC session\n");
00924                 fflush(stdout);
00925                 return -1;
00926         }
00927 
00928         if(a->alc_a.start_time != 0) {
00929                 while(1) {
00930 
00931                         time(&systime);
00932                         curr_time = systime + 2208988800U;
00933 
00934                         if((a->alc_a.start_time - 3) > curr_time) {
00935 
00936                                 if(!is_printed) {
00937                                         printf("Waiting for session start time...\n");
00938                                         fflush(stdout);
00939                                         is_printed = TRUE;
00940                                 }
00941 #ifdef _MSC_VER
00942                                 Sleep(1000);
00943 #else
00944                                 sleep(1);
00945 #endif
00946                         }
00947                         else {
00948                                 break;
00949                         }
00950 
00951                         if(get_session_state(*s_id) == SExiting) {
00952                                 close_alc_session(*s_id);
00953                                 return -5;
00954                         }
00955                 }
00956         }
00957 
00958         if(a->alc_a.cc_id == Null) {
00959 
00960                 for(i = 0; (int)i < a->alc_a.nb_channel; i++) {
00961 
00962                         if(a->alc_a.addr_type == 1) {
00963                                 retval = add_alc_channel(*s_id, ports[i], addrs[0], a->alc_a.intface, a->alc_a.intface_name);
00964                         }
00965                         else {
00966                                 retval = add_alc_channel(*s_id, ports[i], addrs[i], a->alc_a.intface, a->alc_a.intface_name);
00967                         }
00968 
00969                         if(retval == -1) {
00970                                 close_alc_session(*s_id);
00971                                 return -1;
00972                         }
00973                 }
00974         }
00975         else if(a->alc_a.cc_id == RLC) {
00976 
00977                 retval = add_alc_channel(*s_id, ports[0], addrs[0], a->alc_a.intface, a->alc_a.intface_name);
00978 
00979                 if(retval == -1) {
00980                         close_alc_session(*s_id);
00981                         return -1;      
00982                 }
00983         }
00984 
00985         if(a->rx_object) {
00986                 retval = receiver_in_object_mode(s_id, a);
00987                 receiver.fdt = NULL;
00988         }
00989         else {
00990 
00991                 for(i = 0; i < 10; i++) {
00992                         receiver.file_uri_table[i] = NULL;
00993                 }
00994 
00995                 receiver.wildcard_token = NULL;
00996 
00997                 file_uri = strtok(a->file_path, ",");
00998 
00999                 while(file_uri != NULL) {
01000 
01001                         if(strchr(file_uri, '*') != NULL) {
01002 
01003                                 memset(wildcard_token, 0, MAX_PATH_LENGTH);
01004 
01005                                 if((file_uri[0] == '*') && (strlen(file_uri) == 1) ) {
01006                                         printf("Only *something*, something* and *something are valid values in wild card mode!\n");
01007                                         fflush(stdout);
01008                                         close_alc_session(*s_id);
01009                                         return -1;
01010                                 }
01011                                 else if((file_uri[0] == '*') && (file_uri[(strlen(file_uri) - 1)] == '*') ) {
01012                                         memcpy(wildcard_token, (file_uri + 1), (strlen(file_uri) - 2));
01013                                 }
01014                                 else if(file_uri[0] == '*') {
01015                                         memcpy(wildcard_token, (file_uri + 1), (strlen(file_uri) - 1));
01016                                 }
01017                                 else if(file_uri[(strlen(file_uri) - 1)] == '*') {
01018                                         memcpy(wildcard_token, file_uri, (strlen(file_uri) - 2));
01019                                 }
01020                                 else {
01021                                         printf("Only *something*, something* and *something are valid values in wild card mode!\n");
01022                                         fflush(stdout);
01023                                         close_alc_session(*s_id);
01024                                         return -1;
01025                                 }
01026 
01027                                 receiver.wildcard_token = wildcard_token;
01028                         }
01029                         else {
01030                                 receiver.file_uri_table[file_nb] = file_uri;
01031                         }
01032 
01033                         file_nb++;
01034                         file_uri = strtok(NULL, ",");
01035                 }
01036 
01037                 receiver.fdt = NULL;
01038                 receiver.s_id = *s_id;
01039                 receiver.rx_automatic = a->rx_automatic;
01040                 receiver.accept_expired_fdt_inst = a->alc_a.accept_expired_fdt_inst;
01041                 receiver.verbosity = a->alc_a.verbosity;
01042 
01043                 /* Create FDT receiving thread */
01044 
01045 #ifdef _MSC_VER
01046                 handle_fdt_thread =
01047                         (HANDLE)_beginthreadex(NULL, 0,
01048                         (void*)fdt_thread, (void*)&receiver, 0, &fdt_thread_id);
01049                 if(handle_fdt_thread==NULL) {
01050                         printf("Error: flute_receiver, _beginthread\n");
01051                         fflush(stdout);
01052                         close_alc_session(*s_id);
01053                         return -1;
01054                 }
01055 #else
01056                 if((pthread_create(&fdt_thread_id, NULL, fdt_thread, (void*)&receiver)) != 0) {
01057                         printf("Error: flute_receiver, pthread_create\n");
01058                         fflush(stdout);
01059                         close_alc_session(*s_id);
01060                         return -1;        
01061                 }
01062 #endif
01063 
01064                 /* Create Display thread */
01065 
01066                 if(((a->rx_automatic) && (a->file_table_output))) {
01067 
01068 #ifdef _MSC_VER
01069                         handle_receiver_file_table_output_thread =
01070                                 (HANDLE)_beginthreadex(NULL, 0, (void*)receiver_file_table_output_thread,
01071                                 (void*)&receiver, 0, &receiver_file_table_output_thread_id);
01072 
01073                         if(handle_receiver_file_table_output_thread == NULL) {
01074                                 perror("flute_receiver(): _beginthread");
01075                                 close_alc_session(*s_id);
01076                                 return -1;
01077                         }
01078 #else
01079                         if(pthread_create(&receiver_file_table_output_thread_id, NULL, receiver_file_table_output_thread,
01080                                 (void*)&receiver) != 0) {
01081                                         perror("flute_receiver(): pthread_create");
01082                                         close_alc_session(*s_id);
01083                                         return -1;
01084                         }
01085 #endif
01086                 }
01087 
01088                 if(((a->rx_automatic) || (strcmp(a->file_path, "") != 0))) {
01089                         retval = receiver_in_fdt_based_mode(a, &receiver);
01090                 }
01091                 else {
01092                         retval = receiver_in_ui_mode(a, &receiver);
01093                 }
01094         }
01095 
01096         build_report(a, &receiver, report);
01097 
01098         if(retval == -3) {
01099                 if(a->alc_a.verbosity > 0) {
01100                         printf("Sender closed the session\n");
01101                         fflush(stdout);
01102                 }
01103         }
01104 
01105         set_session_state(*s_id, SExiting);
01106 
01107 #ifdef _MSC_VER
01108         if(get_alc_session(*s_id)->handle_rx_thread != NULL) {
01109                 WaitForSingleObject(get_alc_session(*s_id)->handle_rx_thread, INFINITE);
01110                 CloseHandle(get_alc_session(*s_id)->handle_rx_thread);
01111                 get_alc_session(*s_id)->handle_rx_thread = NULL;
01112         }
01113 
01114         if(!a->rx_object) {
01115                 WaitForSingleObject(handle_fdt_thread, INFINITE);
01116                 CloseHandle(handle_fdt_thread);
01117         }
01118 
01119         if(((a->rx_automatic) && (a->file_table_output))) {
01120                 WaitForSingleObject(handle_receiver_file_table_output_thread, INFINITE);
01121                 CloseHandle(handle_receiver_file_table_output_thread); 
01122         }
01123 #else
01124         if(get_alc_session(*s_id)->rx_thread_id != 0) {
01125                 join_retval = pthread_join(get_alc_session(*s_id)->rx_thread_id, NULL);
01126                 assert(join_retval == 0);
01127                 pthread_detach(get_alc_session(*s_id)->rx_thread_id);
01128                 get_alc_session(*s_id)->rx_thread_id = 0;
01129         }
01130 
01131         if(!a->rx_object) {
01132                 join_retval = pthread_join(fdt_thread_id, NULL);
01133                 assert(join_retval == 0);
01134                 pthread_detach(fdt_thread_id);
01135         }
01136 
01137         if(((a->rx_automatic) && (a->file_table_output))) {
01138                 join_retval = pthread_join(receiver_file_table_output_thread_id, NULL);
01139                 assert(join_retval == 0);
01140                 pthread_detach(receiver_file_table_output_thread_id);
01141         }
01142 #endif
01143 
01144         remove_alc_channels(*s_id);
01145 
01146 #ifdef USE_FILE_REPAIR
01147 
01148         if(receiver.fdt != NULL) {
01149                 file = receiver.fdt->file_list;
01150         }
01151 
01152         if(file != NULL) {      
01153                 if(a->rx_automatic) {
01154 
01155                         /* If we found one file entry from the fdt that is not downloaded completely we */
01156                         /* should do file repairing */
01157 
01158                         while(1) {
01159 
01160                                 if(file->status != 2) {
01161                                         repairing_needed = 1;
01162                                         break;
01163                                 }
01164 
01165                                 if(file->next == NULL) {
01166                                         break;
01167                                 }
01168                                 else {
01169                                         file = file->next;
01170                                 }
01171                         }
01172                 }
01173                 else if(receiver.wildcard_token != NULL) {
01174 
01175                         /* If we found file entries from the fdt that match to the wildcard token and */
01176                         /* is not downloaded completely we should do file repairing. */
01177 
01178                         while(1) {
01179 
01180                                 if(strstr(file->location, receiver.wildcard_token) != NULL) {
01181                                         if(file->status == 1) {
01182                                                 repairing_needed = 1;
01183                                         }
01184                                 }
01185 
01186                                 if(file->next == NULL) {
01187                                         break;
01188                                 }
01189                                 else {
01190                                         file = file->next;
01191                                 }
01192                         }
01193                 }
01194                 else {
01195 
01196                         /* If we found wanted files defined in file_uri_table which are not downloaded */
01197                         /* completely repairing is needed */
01198 
01199                         for(i = 0; i < FILE_URI_TABLE_SIZE; i++) {  
01200                                 if(receiver.file_uri_table[i] == NULL) {
01201                                         continue;
01202                                 }
01203                                 else {
01204                                         repairing_needed = 1;
01205                                         break;
01206                                 }
01207                         }
01208                 }
01209         }
01210 
01211         if((strcmp(a->repair, "") != 0) && repairing_needed) {
01212 
01213                 curl = curl_easy_init();
01214 
01215                 if(curl == NULL) {
01216                         printf("Failed to create CURL connection\n");
01217                         close_alc_session(*s_id);
01218 
01219                         if(receiver.fdt != NULL) {
01220                                 FreeFDT(receiver.fdt);
01221                         }
01222 
01223                         return -1; 
01224                 }
01225 
01226                 code = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
01227 
01228                 if(code != CURLE_OK) {
01229                         printf("Failed to set error buffer [%d]\n", code);
01230                 close_alc_session(*s_id);
01231                         
01232                         if(receiver.fdt != NULL) {
01233                                 FreeFDT(receiver.fdt);
01234                         }
01235 
01236                         curl_easy_cleanup(curl);
01237                         return -1; 
01238                 }
01239                 
01240                 code = curl_easy_setopt(curl, CURLOPT_USERAGENT, "mbms-rel6-FLUTE-repair/0.1");
01241 
01242                 if(code != CURLE_OK) {
01243                         printf("Failed to set user agent [%s]\n", errorBuffer);
01244                 close_alc_session(*s_id);
01245 
01246                         if(receiver.fdt != NULL) {
01247                                 FreeFDT(receiver.fdt);
01248                         }
01249 
01250                         curl_easy_cleanup(curl);
01251                         return -1; 
01252                 }
01253 
01254                 /* Let's do file repairing */
01255 
01256                 retval = 0;
01257 
01258                 if(a->alc_a.verbosity > 0) {
01259                         printf("Starting file repair procedure...\n");
01260                 }
01261 
01262                 /* Let's get the config from "apd.xml" */
01263 
01264                 if(stat(a->repair, &apd_file_stats) == -1) {
01265                         printf("Error: %s is not valid file name\n", a->repair);
01266                         fflush(stdout);
01267                         close_alc_session(*s_id);
01268 
01269                         if(receiver.fdt != NULL) {
01270                                 FreeFDT(receiver.fdt);
01271                         }
01272 
01273                         curl_easy_cleanup(curl);
01274                         return -1;
01275                 }
01276 
01277                 /* Allocate memory for buf */
01278                 if(!(apd_buf = (char*)calloc((apd_file_stats.st_size + 1), sizeof(char)))) {
01279                         printf("Could not alloc memory for buffer!\n");
01280                         fflush(stdout);
01281                         close_alc_session(*s_id);
01282 
01283                         if(receiver.fdt != NULL) {
01284                                 FreeFDT(receiver.fdt);
01285                         }
01286 
01287                         curl_easy_cleanup(curl);
01288                         return -1;
01289                 }
01290 
01291                 if((apd_fp = fopen(a->repair, "rb")) == NULL) {
01292                         printf("Error: unable to open file %s\n", a->repair);
01293                         fflush(stdout);
01294                         free(apd_buf);
01295                         close_alc_session(*s_id);
01296 
01297                         if(receiver.fdt != NULL) {
01298                                 FreeFDT(receiver.fdt);
01299                         }
01300 
01301                         curl_easy_cleanup(curl);
01302                         return -1;
01303                 }
01304 
01305                 apd_nbytes = fread(apd_buf, 1, apd_file_stats.st_size, apd_fp);
01306 
01307                 if(apd_nbytes <= 0) {
01308                         free(apd_buf);
01309                         fclose(apd_fp);
01310                         close_alc_session(*s_id);
01311         
01312                         if(receiver.fdt != NULL) {
01313                                 FreeFDT(receiver.fdt);
01314                         }
01315 
01316                         curl_easy_cleanup(curl);
01317                         return -1;
01318                 }
01319 
01320                 fclose(apd_fp);
01321 
01322                 apd = decode_apd_config(apd_buf);
01323                 free(apd_buf);
01324 
01325                 if(apd->bmFileRepair->sessionDescriptionURI != NULL) {
01326 
01327                         /* Let's get SDP description for the multicast repair session */
01328 
01329                         code = curl_easy_setopt(curl, CURLOPT_URL, apd->bmFileRepair->sessionDescriptionURI);
01330 
01331                         if(code != CURLE_OK) {
01332                                 printf("Failed to set URL [%s]\n", errorBuffer);
01333                                 close_alc_session(*s_id);
01334 
01335                                 if(receiver.fdt != NULL) {
01336                                         FreeFDT(receiver.fdt);
01337                                 }
01338 
01339                                 curl_easy_cleanup(curl);
01340                                 FreeAPD(apd);
01341                                 return -1;
01342                         }
01343 
01344                         code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_to_buffer);
01345 
01346                         if(code != CURLE_OK) {
01347                                 printf("Failed to set writer [%s]\n", errorBuffer);
01348                         close_alc_session(*s_id);
01349 
01350                                 if(receiver.fdt != NULL) {
01351                                         FreeFDT(receiver.fdt);
01352                                 }
01353         
01354                                 curl_easy_cleanup(curl);
01355                                 FreeAPD(apd);
01356                                 return -1;
01357                         }
01358 
01359                         chunk.data = NULL;
01360                         chunk.size = 0;
01361 
01362                         code = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk);
01363 
01364                         if(code != CURLE_OK) {
01365                                 printf("Failed to set write data [%s]\n", errorBuffer);
01366                         close_alc_session(*s_id);
01367 
01368                                 if(receiver.fdt != NULL) {
01369                                         FreeFDT(receiver.fdt);
01370                                 }
01371 
01372                                 curl_easy_cleanup(curl);
01373                                 FreeAPD(apd);
01374                                 return -1;
01375                         }
01376 
01377                         code = curl_easy_perform(curl);
01378 
01379                         if(code != CURLE_OK) {
01380                                 printf("Failed to get '%s' [%s]\n", apd->bmFileRepair->sessionDescriptionURI, errorBuffer);
01381                                 close_alc_session(*s_id);
01382 
01383                                 if(receiver.fdt != NULL) {
01384                                         FreeFDT(receiver.fdt);
01385                                 }
01386 
01387                                 curl_easy_cleanup(curl);
01388                                 FreeAPD(apd);
01389                                 return -1;
01390                         }
01391                         
01392                         code = curl_easy_getinfo(curl , CURLINFO_HTTP_CODE , &responseCode);
01393 
01394                         if(code != CURLE_OK) {
01395                                 printf("Failed to get http response code [%s]\n", errorBuffer);
01396                                 close_alc_session(*s_id);
01397 
01398                                 if(receiver.fdt != NULL) {
01399                                         FreeFDT(receiver.fdt);
01400                                 }
01401                         
01402                                 curl_easy_cleanup(curl);
01403                                 FreeAPD(apd);
01404                                 return -1;
01405                         }
01406 
01407                         if(responseCode == 200 && chunk.size != 0) {
01408                                 if(a->alc_a.verbosity > 0) {
01409                                         printf("Starting FLUTE file repair...\n");
01410                                 }
01411 
01412                                 retval = flute_file_repair(&receiver, a, chunk.data);
01413 
01414                                 if(retval == -3) {
01415                                         if(a->alc_a.verbosity > 0) {
01416                                                 printf("Sender closed the session\n");
01417                                                 fflush(stdout);
01418                                         }
01419                                 }
01420 
01421                                 free(chunk.data);
01422                         }
01423                 }
01424                 else {
01425 
01426                         /* if NULL then we should do ptp repair */
01427 
01428                         while(1) {
01429                                 http_server_index = 0;
01430                                 nb_of_http_servers = 0;
01431 
01432                                 /* Let's get the amount of available serviceURIs */
01433 
01434                                 tmp_serviceURI = apd->postFileRepair->serviceURI_List;
01435 
01436                                 if(tmp_serviceURI == NULL) {
01437                                         if(a->alc_a.verbosity > 0) {
01438                                                 printf("Number of HTTP servers available: %i\n", nb_of_http_servers);
01439                                                 printf("HTTP file repair procedure failed.\n");
01440                                         }
01441                                         break;
01442                                 }
01443                                 else {
01444                                         while(1) {
01445                                                 nb_of_http_servers++;
01446                                                 if(tmp_serviceURI->next == NULL) {                              
01447                                                         break;
01448                                                 }   
01449                                                 else {
01450                                                         tmp_serviceURI = tmp_serviceURI->next;
01451                                                 }
01452                                         }
01453 
01454                                         /* Let's choose randomly one of the servers */
01455 
01456                                         http_server_index = 1 + random_number(nb_of_http_servers);
01457 
01458                                         if(a->alc_a.verbosity > 0) {
01459                                                 printf("Number of HTTP servers available: %i\n", nb_of_http_servers);
01460                                         }
01461 
01462                                         tmp_serviceURI = apd->postFileRepair->serviceURI_List;
01463 
01464                                         for(n = 1;; n++) {
01465                                                 if(n == (int)http_server_index) {
01466                                                         printf("Using: %s\n", tmp_serviceURI->URI);
01467                                                         break;
01468                                                 }
01469                                                 else {
01470                                                         tmp_serviceURI = tmp_serviceURI->next;
01471                                                 }
01472                                         }
01473 
01474                                         /* Let's wait offsetTime + randomTime */
01475 
01476                                         waitTime = apd->postFileRepair->offsetTime;
01477 
01478                                         waitTime += random_number(apd->postFileRepair->randomTimePeriod + 1);
01479 
01480                                         if(a->alc_a.verbosity > 0) {
01481                                                 printf("waitTime: %i\n", waitTime);               
01482                                         }
01483 
01484         #ifdef _MSC_VER
01485                                         Sleep(1000*waitTime);
01486         #else
01487                                         sleep(waitTime);
01488         #endif
01489 
01490                                         if(a->alc_a.verbosity > 0) {
01491                                                 printf("Starting HTTP file repair...\n");
01492                                         }
01493 
01494                                         file_repair_sdp_buf = http_file_repair(&receiver, a->open_file, &retval, curl, tmp_serviceURI->URI);
01495 
01496                                         /* if file_repair_sdp_buf != NULL we should do multicast file repair */
01497 
01498                                         if(file_repair_sdp_buf != NULL) {
01499                                                 break;
01500                                         }
01501 
01502                                         /* If retval == 0 HTTP repair has succeeded, if not we should try another server */
01503 
01504                                         if(retval == 0) {
01505                                                 break;
01506                                         }
01507                                         else {
01508                                                 /*Let's remove the used http server from the list so that it is not used anymore */
01509 
01510                                                 if(tmp_serviceURI->prev != NULL) {
01511                                                         tmp_serviceURI->prev->next = tmp_serviceURI->next;
01512                                                 }
01513                                                 else {
01514                                                         apd->postFileRepair->serviceURI_List = tmp_serviceURI->next;                                                            
01515                                                 }
01516                                                 if(tmp_serviceURI->next != NULL) {
01517                                                         tmp_serviceURI->next->prev = tmp_serviceURI->prev;
01518                                                 }
01519                                                 free(tmp_serviceURI);
01520                                         }
01521                                 }
01522                         }
01523 
01524                         /* if file_repair_sdp_buf != NULL we should do multicast file repair */
01525 
01526                         if(file_repair_sdp_buf != NULL) {
01527 
01528                                 if(a->alc_a.verbosity > 0) {
01529                                         printf("Starting FLUTE file repair after 302 Redirect response...\n");
01530                                 }
01531 
01532                                 retval = flute_file_repair(&receiver, a, file_repair_sdp_buf);
01533 
01534                                 if(retval == -3) {
01535                                         if(a->alc_a.verbosity > 0) {
01536                                                 printf("Sender closed the session\n");
01537                                                 fflush(stdout);
01538                                         }
01539                                 }
01540                         }  
01541                 }
01542 
01543                 FreeAPD(apd);
01544                 curl_easy_cleanup(curl);
01545         }
01546 #endif /* USE_FILE_REPAIR */
01547 
01548         if(a->name_incomplete_objects) {
01549                 /* name incomplete objects, so that all received data is used */
01550                 retval = name_incomplete_objects(&receiver);
01551         }
01552 
01553         if(a->alc_a.cc_id == RLC) {
01554                 if(a->alc_a.verbosity > 0) {
01555                         printf("%i packets were lost in the session\n", get_alc_session(*s_id)->lost_packets);
01556                         fflush(stdout);
01557                 }
01558         }
01559 
01560         if(receiver.fdt != NULL) {
01561                 FreeFDT(receiver.fdt);
01562         }
01563 
01564         close_alc_session(*s_id);
01565 
01566         return retval;
01567 }
01568 
01569 void free_receiver_report(flute_receiver_report_t *report) {
01570     flute_receiver_report_t *iterReport = report;
01571 
01572     while (iterReport != NULL) {
01573         missing_block_t *iterMB = iterReport->mb_list;
01574         while(iterMB != NULL) {
01575             missing_block_t *temp = iterMB->next;
01576             free (iterMB);
01577             iterMB = temp;
01578         }
01579 
01580         free (report->file_name);
01581         free (report->md5);
01582         iterReport = iterReport->next;
01583     }
01584 }
01585 
01586 unsigned long long flute_session_size(arguments_t *a, int *s_id) {
01587 
01588         BOOL old_flag = a->alc_a.calculate_session_size;
01589         int old_flag2 = a->alc_a.verbosity;
01590         int old_flag3 = a->alc_a.nb_tx;
01591         int old_flag4 = a->alc_a.cc_id;
01592         int myRet;
01593         unsigned long long session_size;
01594 
01595         a->alc_a.calculate_session_size = TRUE;
01596         a->alc_a.verbosity = 0;
01597         a->alc_a.cc_id = Null;
01598 
01599         if(a->cont) {
01600                 printf("Session size can't be calculated due to continuous Tx mode.\n");
01601                 a->alc_a.calculate_session_size = old_flag;
01602                 a->alc_a.verbosity = old_flag2;
01603                 a->alc_a.nb_tx = old_flag3;
01604                 a->alc_a.cc_id = old_flag4;
01605                 return 0;
01606         }
01607 
01608         myRet = flute_sender(a, s_id, &session_size);
01609 
01610         if(myRet < 0) {
01611                 printf("Session size can't be calculated because myRet < 0.\n");
01612                 printf("Error: myRet: %d\n", myRet);
01613 
01614                 a->alc_a.calculate_session_size = old_flag;
01615                 a->alc_a.verbosity = old_flag2;
01616                 a->alc_a.nb_tx = old_flag3;
01617                 a->alc_a.cc_id = old_flag4;
01618                 return 0;
01619         }
01620 
01621         a->alc_a.calculate_session_size = old_flag;
01622         a->alc_a.verbosity = old_flag2;
01623         a->alc_a.nb_tx = old_flag3;
01624         a->alc_a.cc_id = old_flag4;
01625 
01626         return session_size;
01627 }
01628 
01629 void set_flute_session_state(int s_id, enum alc_session_states state) {
01630 
01631         set_session_state(s_id, state);
01632 }
01633 
01634 void set_all_flute_sessions_state(enum alc_session_states state) {
01635 
01636         set_all_sessions_state(state); 
01637 }
01638 
01639 void set_flute_session_base_rate(int s_id, int base_tx_rate) {
01640         update_session_tx_rate(s_id, base_tx_rate); 
01641 }
01642 
01643 int start_up_flute(void) {
01644 
01645 #ifdef _MSC_VER
01646         WSADATA wsd;
01647         int wsreturn;
01648 #endif
01649 
01650 #ifdef _MSC_VER
01651 
01652         wsreturn = WSAStartup(MAKEWORD(2, 2), &wsd);
01653 
01654         if(wsreturn != 0) {
01655                 printf("WSAStartup() failed\n");
01656                 return wsreturn;
01657         }
01658 
01659 #endif
01660 
01661         initialize_fdt_parser();
01662         initialize_session_handler();
01663 
01664         return 0;
01665 }
01666 
01667 void shut_down_flute(arguments_t *anArguments) {
01668 
01669 #ifdef _MSC_VER
01670         WSACleanup();
01671 #endif
01672 
01673         release_session_handler();
01674         release_fdt_parser();
01675 
01676         if(anArguments == NULL) {
01677                 return;
01678         }
01679 
01680         if(anArguments->log_fd != -1) {
01681                 close(anArguments->log_fd);
01682         }
01683 
01684         if(strcmp(anArguments->sdp_file, "") != 0) {
01685                 sf_free(anArguments->src_filt);
01686                 free(anArguments->src_filt);
01687                 sdp_message_free(anArguments->sdp);
01688         }
01689 }
01690 
01691 void shut_down_flute2(void) {
01692 
01693 #ifdef _MSC_VER
01694         WSACleanup();
01695 #endif
01696 
01697         release_session_handler();
01698         release_fdt_parser();
01699 }

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