main.c

Go to the documentation of this file.
00001 
00033 #include <stdlib.h>
00034 #include <sys/stat.h>
00035 #include <signal.h>
00036 #include <stdio.h>
00037 #include <time.h>
00038 
00039 #ifdef _MSC_VER
00040 #include <windows.h>
00041 #include <io.h>
00042 #include <crtdbg.h>
00043 #include <process.h>
00044 #else
00045 #include <unistd.h>
00046 #include <pthread.h>
00047 #include <assert.h>
00048 #include <string.h>
00049 #endif
00050 
00051 #include "../flutelib/flute.h"
00052 
00057 #define _DEBUG_MEMORY 0
00058 
00064 typedef struct thread_params {
00065   arguments_t a;
00066   int s_id;
00067   unsigned long long session_size;
00068 } thread_params_t;
00069 
00070 
00078 void signal_handler(int sig){
00079 
00080   printf("Exiting...\n");
00081   fflush(stdout);
00082 
00083   set_all_flute_sessions_state(SExiting);
00084 }
00085 
00091 void usage(void) {
00092   printf("\nFLUTE Version %s, %s\n\n", MAD_FCL_RELEASE_VERSION, MAD_FCL_RELEASE_DATE);
00093   printf("  Copyright (c) 2003-2007 TUT - Tampere University of Technology\n");
00094   printf("  main authors/contacts: jani.peltotalo@tut.fi and sami.peltotalo@tut.fi\n");
00095   printf("  web site: http://www.atm.tut.fi/mad/\n\n");
00096   printf("  This is free software, and you are welcome to redistribute it\n");
00097   printf("  under certain conditions; See the GNU General Public License\n");
00098   printf("  as published by the Free Software Foundation, version 2 or later,\n");
00099   printf("  for more details.\n\n");
00100   printf("  * mad_rlc.c & mad_rlc.h -- Portions of code derived from MCL library by\n");
00101   printf("  * Vincent Roca et al. (http://www.inrialpes.fr/planete/people/roca/mcl/)\n");
00102   printf("  *\n");
00103   printf("  * Copyright (c) 1999-2004 INRIA - Universite Paris 6 - All rights reserved\n");
00104   printf("  * (main author: Julien Laboure - julien.laboure@inrialpes.fr\n");
00105   printf("  *               Vincent Roca - vincent.roca@inrialpes.fr)\n\n");
00106   printf("  * fec.c & fec.h -- forward error correction based on Vandermonde matrices\n");
00107   printf("  * 980624\n");
00108   printf("  * (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it)\n");
00109   printf("  *\n");
00110   printf("  * Portions derived from code by Phil Karn (karn@ka9q.ampr.org),\n");
00111   printf("  * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and\n");
00112   printf("  * Hari Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995\n");
00113   printf("  *\n");
00114   printf("  * Redistribution and use in source and binary forms, with or without\n");
00115   printf("  * modification, are permitted provided that the following conditions\n");
00116   printf("  * are met:\n");
00117   printf("  *\n");
00118   printf("  * 1. Redistributions of source code must retain the above copyright\n");
00119   printf("  *    notice, this list of conditions and the following disclaimer.\n");
00120   printf("  * 2. Redistributions in binary form must reproduce the above\n");
00121   printf("  *    copyright notice, this list of conditions and the following\n");
00122   printf("  *    disclaimer in the documentation and/or other materials\n");
00123   printf("  *    provided with the distribution.\n");
00124   printf("  *\n");
00125   printf("  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND\n");
00126   printf("  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n");
00127   printf("  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n");
00128   printf("  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS\n");
00129   printf("  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n");
00130   printf("  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n");
00131   printf("  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n");
00132   printf("  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n");
00133   printf("  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\n");
00134   printf("  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n");
00135   printf("  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\n");
00136   printf("  * OF SUCH DAMAGE.\n\n");
00137   printf("Sender usage: flute [-a:str] [-B:str] [-c:int] [-C] [-d:str] [-D:ull] [-e:int]\n"); 
00138   printf("                    [-f:str] [-F:str,str,...] [-G] [-h] [-H] [-i:str] [-k:int] [-l:int]\n");
00139   printf("                    [-L:int] [-m:str] [-n:int] [-p:int] [-P:float,float]\n");
00140   printf("                    [-q:int] [-r:int]");
00141 #ifdef USE_FILE_REPAIR
00142   printf(" [-R:str] [-S] [-t:ull] [-T:int] [-U]\n");
00143   printf("                    [-v:int] [-V:str] [-w:int] [-W] [-x:int] [-X:int] [-z:int]\n");
00144   printf("                    [-Z]\n\n");
00145 #else
00146   printf(" [-S] [-t:ull] [-T:int] [-U] [-v:int]\n");
00147   printf("                    [-V:str] [-w:int] [-W] [-x:int] [-X:int] [-z:int] [-Z]\n\n");
00148 #endif
00149   printf("Receiver usage: flute [-a:str] [-A] [-b:int] [-B:str] [-c:int] [-d:str] [-E]\n"); 
00150   printf("                      [-F:str,str,...] [-h] [-i:str]"); 
00151 #ifdef _MSC_VER
00152   printf(" [-I:int]");
00153 #else
00154   printf(" [-I:str]");
00155 #endif
00156   printf(" [-m:str]"); 
00157 #ifdef SSM
00158   printf(" [-M]\n");
00159 #endif
00160   printf("                      [-N] [-o:ull]");
00161 #ifdef _MSC_VER
00162   printf(" [-O]");
00163 #endif
00164   printf(" [-p:int] [-P:float,float]");
00165 #ifdef USE_FILE_REPAIR
00166   printf(" [-R:str]\n");
00167   printf("                      [-s:str] [-t:ull] [-U] [-v:int] [-V:str] [-w:int] [-W]\n\n");
00168 #else
00169   printf(" [-s:str]\n");
00170   printf("                      [-t:ull] [-U] [-v:int] [-V:str] [-w:int] [-W]\n\n");
00171 #endif
00172   printf("Common options:\n\n");
00173   printf("   -a:str           Address family [IPv4 or IPv6], default: IPv4\n");
00174   printf("   -d:str           SDP file (start/join FLUTE session based on SDP file),\n");
00175   printf("                    default: no\n");
00176   printf("   -h               Print this help\n");
00177   printf("   -i:str           Local interface to bind to, default: INADDR_ANY\n");
00178   printf("   -m:str           IPv4 or IPv6 address for base channel,\n");
00179   printf("                    default: %s or %s\n", DEF_MCAST_IPv4_ADDR, DEF_MCAST_IPv6_ADDR);
00180   printf("   -p:int           Port number for base channel, default: %s\n", DEF_MCAST_PORT);
00181   printf("   -P[:float,float] Simulate packet losses, default packet loss\n");
00182   printf("                    percentages: %.1f,%.1f\n", (float)P_LOSS_WHEN_OK, (float)P_LOSS_WHEN_LOSS);
00183   printf("   -S               Act as sender, send data; otherwise receive data\n");
00184   printf("   -t:ull           TSI for the session, default: %i\n", DEF_TSI);
00185   printf("   -U               Address type is unicast, default: multicast\n");
00186   printf("   -v:int           Log verbosity level [0 = No output, 1 = File level,\n");
00187   printf("                    2 = 1 + percent, 3 = 2 + blocks, 4 = 3 + FDT], default: 1\n");
00188   printf("   -V:str           Print logs to 'str' file, default: print to stdout\n");  
00189   printf("   -w:int           Congestion control scheme [0 = Null, 1 = RLC],\n");
00190   printf("                    default: %i; the number of channels, defined by -c option,\n", DEF_CC);
00191   printf("                    are used with both schemes and bitrate of each channel is\n");
00192   printf("                    set according to RLC rules\n");
00193   printf("   -W               File table output mode. In receiver this work only with\n");
00194   printf("                    -A option\n\n");
00195   printf("Sender options:\n\n");
00196   printf("   -B:str           Base directory for files or directories to be sent,\n");
00197   printf("                    default: working directory\n");
00198   printf("   -c:int           Number of used channels, default: %i\n", DEF_NB_CHANNEL);
00199   printf("   -C               Continuous transmission, default: not used\n");
00200   printf("   -D:ull           Duration of the session in seconds, default: %i\n", DEF_SESSION_DURATION);
00201   printf("   -e:int           FEC-OTI for file objects\n");
00202   printf("                    [0 = FEC-OTI in FDT, 1 = FEC-OTI in EXT_FTI], default: 0\n");
00203   printf("   -f:str           FDT file (send based on FDT), default: %s\n", DEF_FDT);
00204   printf("   -F:str,str,...   Files or directories to be sent. Given base directory is\n");
00205   printf("                    same for all entries.\n");
00206   printf("   -G               Calculate session size, but do not send anything\n");
00207   printf("   -H               Use Half-word (when used, TSI field can be 16, 32 or 48\n");
00208   printf("                    bits long and TOI field can be 16, 32, 48 or 64 bits\n");
00209   printf("                    long), default: not used\n");
00210   printf("   -k:int           Send a Complete FDT in the beginning of the session\n");
00211   printf("                    [0 = No, 1 = Yes, 2 = Yes, only Complete FDT], default: 0\n");
00212   printf("   -l:int           Encoding symbol length in bytes, default: %i\n", DEF_SYMB_LENGTH);
00213   printf("   -L:int           Maximum source block length in multiple of encoding\n");
00214   printf("                    symbols, default: %i\n", DEF_MAX_SB_LEN);
00215   printf("   -n:int           Number of transmissions, default: %i\n", DEF_TX_NB);
00216   printf("   -q:int           Send session close packets [0 = No, 1 = Yes], default: 1\n");
00217   printf("   -r:int           Transmission rate at base channel in kbits/s, default: %i\n", DEF_TX_RATE);
00218 #ifdef USE_FILE_REPAIR
00219   printf("   -R[:str]         Save configuration to a file, default: %s\n", DEF_FLUTE_CONF_FILE);
00220 #endif
00221   printf("   -T:int           Time To Live or Hop Limit for the session, default: %i\n", DEF_TTL);
00222   printf("   -x:int           FEC Encoding [0 = Null, 1 = Simple XOR, 2 = Reed-Solomon\n");
00223   printf("                    (old I-D) 3 = Reed-Solomon (new I-D), default: %i\n", DEF_FEC);
00224   printf("   -X:int           FEC ratio percent, default: %i\n", DEF_FEC_RATIO);
00225 #ifdef USE_ZLIB
00226   printf("   -z:int           Encode content [0 = no, 1 = ZLIB FDT,\n");
00227   printf("                    2 = ZLIB FDT and GZIP files,\n");
00228   printf("                    3 = PAD files], default: 0\n");
00229 #else
00230   printf("   -z:int           Encode content [0 = no, 3 = PAD files],\n");
00231   printf("                    default: 0\n");
00232 #endif
00233   printf("   -Z               Optimize transmission rate (use more CPU)\n\n");
00234   printf("Receiver options:\n\n");
00235   printf("   -A               Receive files automatically\n");
00236   printf("   -b:int           Receiver's memory consumption [0 = high, 1 = medium,\n");
00237   printf("                    2 = low], default: 1\n");
00238   printf("   -B:str           Base directory for downloaded files,\n");
00239   printf("                    default: %s\n", DEF_BASE_DIR);
00240   printf("   -c:int           Maximum number of channels, default: %i\n", DEF_NB_CHANNEL);
00241   printf("   -E               Accept expired FDT Instances\n");   
00242   printf("   -F:str,str,...   Files to be received\n");
00243 #ifdef _MSC_VER
00244   printf("   -I:int           Local interface index for IPv6 multicast join, use for\n");
00245   printf("                    example 'ipv6 if' command to see interface indexes;\n");
00246   printf("                    otherwise OS default\n");
00247 #else
00248   printf("   -I:str           Local interface name for IPv6 multicast join, use for\n");
00249   printf("                    example 'ifconfig' command to see interface names;\n");
00250   printf("                    otherwise OS default\n");
00251 #endif
00252 #ifdef SSM
00253   printf("   -M               Use Source-Specific Multicast, default: no\n");
00254 #endif
00255   printf("   -N               Name incomplete objects after the session has ended\n");
00256   printf("   -o:ull           TOI for the object to be received\n");
00257 #ifdef _MSC_VER
00258   printf("   -O               Open received file(s) automatically, default: no\n");
00259 #endif
00260 #ifdef USE_FILE_REPAIR
00261   printf("   -R[:str]         Use HTTP file repair with given config file, default:\n");
00262   printf("                    %s\n", DEF_APD_CONF_FILE);
00263 #endif
00264   printf("   -s:str           Source IPv4 or IPv6 address of this session. If not set,\n");
00265   printf("                    receiver locks to the first IP address found from the\n");
00266   printf("                    FLUTE packets.\n"); 
00267   printf("\nExample use cases:\n\n");
00268   printf("1. Send a file or directory n times\n\n\tflute -S -m:224.1.1.1 -p:4000 -t:2 -r:100 -F:files/flute-draft.txt\n");
00269   printf("\t      -n:2\n\n");
00270   printf("2. Send a file or directory in a loop\n\n\tflute -S -m:224.1.1.1 -p:4000 -t:2 -r:100 -F:files/flute-draft.txt\n");
00271   printf("\t      -C\n\n");
00272   printf("3. Send files defined in an FDT file\n\n\tflute -S -m:224.1.1.1 -p:4000 -t:2 -r:100 -f:fdt2.xml\n\n");
00273   printf("4. Send files defined in an FDT file in a loop\n\n\tflute -S -m:224.1.1.1 -p:4000 -t:2 -r:100 -f:fdt2.xml -C\n\n");
00274   printf("5. Send using unicast\n\n\tflute -S -U -m:1.2.3.4 -p:4000 -t:2 -r:100 -f:fdt2.xml -C\n\n");
00275   printf("6. Receive one object\n\n\tflute -m:224.1.1.1 -p:4000 -t:2 -s:2.2.2.2 -o:1\n\n");
00276   printf("7. Receive file(s) defined by file name(s)\n\n\tflute -m:224.1.1.1 -p:4000 -t:2 -s:2.2.2.2\n");
00277   printf("\t      -F:files/flute-man.txt,flute-draft.txt\n\n");
00278   printf("8. Receive file(s) defined by wild card option\n\n\tflute -m:224.1.1.1 -p:4000 -t:2 -s:2.2.2.2 -F:*.jpg\n\n");
00279   printf("9. Receive file(s) with User Interface\n\n\tflute -m:224.1.1.1 -p:4000 -t:2 -s:2.2.2.2\n\n");
00280   printf("10. Receive file(s) automatically from session\n\n\tflute -A -m:224.1.1.1 -p:4000 -t:2 -s:2.2.2.2\n\n");
00281   printf("11. Receive using unicast\n\n\tflute -A -U -p:4000 -t:2 -s:2.2.2.2\n\n");
00282   
00283   exit(1);
00284 }
00285 
00293 void* start_flute_process(void *t_par) {
00294 
00295   thread_params_t *t_p;
00296   int retval = 0;
00297 
00298   t_p = (thread_params_t*)t_par;
00299 
00300   if(t_p->a.alc_a.mode == SENDER) {
00301         retval = flute_sender(&t_p->a, &t_p->s_id, &t_p->session_size);
00302 
00303         if(t_p->a.alc_a.verbosity > 0) {
00304 #ifdef _MSC_VER
00305           printf("Total bytes sent: %I64u\n", t_p->session_size);
00306 #else   
00307           printf("Total bytes sent: %llu\n", t_p->session_size);
00308 #endif  
00309         }
00310   }
00311   else if(t_p->a.alc_a.mode == RECEIVER) {
00312         retval = flute_receiver(&t_p->a, &t_p->s_id);
00313   }
00314 
00315 #ifdef _MSC_VER
00316         _endthread();
00317 #else   
00318         pthread_exit(0);
00319 #endif
00320 
00321   return NULL;
00322 }
00323 
00334 int main(int argc, char **argv) {
00335 
00336   int retval = 0;
00337 
00338   thread_params_t par1;
00339   thread_params_t par2;
00340 
00341   /* Handles for two session */
00342 #ifdef _MSC_VER
00343   HANDLE handle_thread1;
00344   unsigned int thread_id1;
00345   HANDLE handle_thread2;
00346   unsigned int thread_id2;
00347   int addr_size;
00348 #else
00349   pthread_t thread_id1;
00350   int join_retval1;
00351   pthread_t thread_id2;
00352   int join_retval2;
00353 #endif
00354 
00355   char tmp_port[MAX_PORT_LENGTH];
00356   char tmp_addr[INET6_ADDRSTRLEN];
00357   struct sockaddr_in ipv4;
00358   struct sockaddr_in6 ipv6;
00359   int j;
00360 
00361 #if defined(_MSC_VER) && _DEBUG_MEMORY > 0
00362   _CrtSetDbgFlag(
00363         _CRTDBG_ALLOC_MEM_DF |
00364         _CRTDBG_CHECK_ALWAYS_DF |
00365         _CRTDBG_CHECK_CRT_DF |
00366         _CRTDBG_DELAY_FREE_MEM_DF |
00367         _CRTDBG_LEAK_CHECK_DF);
00368 #endif
00369   
00370   if(start_up_flute() != 0) {
00371     return -1;
00372   }
00373 
00374   /* Set signal handler */
00375   
00376   signal(SIGINT, signal_handler);
00377 #ifdef _MSC_VER
00378   signal(SIGBREAK, signal_handler);
00379 #endif
00380   
00381   srand((unsigned)time(NULL));
00382 
00383 
00384   /* Command line argumants are parsed twise, own argument
00385      structure for both session */
00386 
00387   retval = parse_args(argc, argv, &par1.a);
00388 
00389   if(retval == -1) {
00390     usage();
00391   }
00392 
00393   retval = parse_args(argc, argv, &par2.a);
00394 
00395   if(retval == -1) {
00396     usage();
00397   }
00398 
00399   /* Essential parameters are changed */
00400 
00401   par2.a.alc_a.tsi = par1.a.alc_a.tsi + 1;
00402   
00403   memset(tmp_port, 0, MAX_PORT_LENGTH);
00404   sprintf(tmp_port, "%i", (atoi(par1.a.alc_a.port) + 1000));
00405   par2.a.alc_a.port = tmp_port;
00406 
00407   if(par1.a.alc_a.addr_family == PF_INET) {
00408         memset(tmp_addr, 0, INET6_ADDRSTRLEN);
00409         ipv4.sin_addr.s_addr = htonl(ntohl(inet_addr(par1.a.alc_a.addr)) + 10);
00410         sprintf(tmp_addr, "%s", inet_ntoa(ipv4.sin_addr));
00411   }
00412   else if(par1.a.alc_a.addr_family == PF_INET6) {
00413 #ifdef _MSC_VER
00414     addr_size = sizeof(struct sockaddr_in6);
00415         WSAStringToAddress((char*)par1.a.alc_a.addr, AF_INET6, NULL, (struct sockaddr*)&ipv6, &addr_size);
00416 #else 
00417         inet_pton(AF_INET6, par1.a.alc_a.addr, &ipv6.sin6_addr);
00418 #endif
00419         
00420         for(j = 0; j < 10; j++) {
00421                 if(increase_ipv6_address(&ipv6.sin6_addr) == -1) {
00422                         printf("Increasing IPv6 address is not possible\n");
00423                         return -1;
00424                 }
00425         }
00426 
00427         memset(tmp_addr, 0, INET6_ADDRSTRLEN);
00428 
00429 #ifdef _MSC_VER
00430         addr_size = sizeof(tmp_addr);
00431         WSAAddressToString((struct sockaddr*)&ipv6, sizeof(struct sockaddr_in6),
00432                                         NULL, tmp_addr, &addr_size);
00433 #else
00434         inet_ntop(AF_INET6, &ipv6.sin6_addr, tmp_addr, sizeof(tmp_addr));
00435 #endif
00436   }
00437 
00438   par2.a.alc_a.addr = tmp_addr;
00439   
00440   par1.s_id = -1;
00441   par2.s_id = -1;
00442 
00443 #ifdef _MSC_VER
00444     handle_thread1 =
00445       (HANDLE)_beginthreadex(NULL, 0, (void*)start_flute_process,
00446                          (void*)&par1, 0, &thread_id1);
00447     
00448     if(handle_thread1 == NULL) {
00449       perror("main.c: _beginthread 1");
00450       return -1;
00451     }
00452 #else
00453     if(pthread_create(&thread_id1, NULL, start_flute_process, (void*)&par1) != 0) {
00454       perror("main.c: pthread_create 1");
00455       return -1;
00456     }
00457 #endif
00458 
00459 #ifdef _MSC_VER
00460     handle_thread2 =
00461       (HANDLE)_beginthreadex(NULL, 0, (void*)start_flute_process,
00462                              (void*)&par2, 0, &thread_id2);
00463     
00464     if(handle_thread2 == NULL) {
00465       perror("main.c: _beginthread 2");
00466       return -1;
00467     }
00468 #else
00469     if(pthread_create(&thread_id2, NULL, start_flute_process, (void*)&par2) != 0) {
00470       perror("main.c: pthread_create 2");
00471       return -1;
00472     }
00473 #endif
00474 
00475 #ifdef _MSC_VER
00476     WaitForSingleObject(handle_thread1, INFINITE);
00477     CloseHandle(handle_thread1);
00478 #else
00479     join_retval1 = pthread_join(thread_id1, NULL);
00480     assert(join_retval1 == 0);
00481     pthread_detach(thread_id1);
00482 #endif
00483 
00484 #ifdef _MSC_VER
00485     WaitForSingleObject(handle_thread2, INFINITE);
00486     CloseHandle(handle_thread2);
00487 #else
00488     join_retval2 = pthread_join(thread_id2, NULL);
00489     assert(join_retval2 == 0);
00490     pthread_detach(thread_id2);
00491 #endif
00492 
00493   free_args(&par1.a);
00494   free_args(&par2.a);
00495   shut_down_flute2();
00496   
00497   return retval;
00498 }

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