00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <stdio.h>
00043 #include <unistd.h>
00044 #include <errno.h>
00045 #include <strings.h>
00046 #include <string.h>
00047 #include <stdlib.h>
00048 #include <sys/time.h>
00049 #include <sys/file.h>
00050 #include <time.h>
00051 #include <assert.h>
00052
00053 #include "dtn_api.h"
00054 #include "dtn_types.h"
00055
00056 #define MAX_MEM_PAYLOAD 50000 // max payload (in bytes) if bundles are stored into memory
00057 #define ILLEGAL_PAYLOAD 0 // illegal number of bytes for the bundle payload
00058 #define DEFAULT_PAYLOAD 50000 // default value (in bytes) for bundle payload
00059
00060
00061
00062
00063
00064 char *progname;
00065
00066
00067 dtn_bundle_payload_location_t
00068 payload_type = DTN_PAYLOAD_FILE;
00069 int verbose = 0;
00070 char op_mode ;
00071 int debug = 0;
00072 int csv_out = 0;
00073
00074
00075
00076
00077
00078
00079
00080 int expiration = 3600;
00081 int delivery_receipts = 1;
00082 int forwarding_receipts = 0;
00083 int custody = 0;
00084 int custody_receipts = 0;
00085 int receive_receipts = 0;
00086
00087 int wait_for_report = 1;
00088
00089
00090 char * arg_replyto = NULL;
00091 char * arg_source = NULL;
00092 char * arg_dest = NULL;
00093
00094 dtn_reg_id_t regid = DTN_REGID_NONE;
00095 long bundle_payload = DEFAULT_PAYLOAD;
00096 char * p_arg ;
00097
00098
00099 int transmission_time = 0;
00100
00101
00102 long data_qty = 0;
00103 char * n_arg ;
00104 char * p_arg ;
00105 int n_copies = 1;
00106 int sleepVal = 0;
00107 int use_file = 1;
00108 char data_unit ;
00109
00110
00111 int fd ;
00112 int data_written = 0;
00113 int data_read = 0;
00114 char * file_name_src = "/var/lib/dtn/dtnperf/dtnbuffer.snd";
00115
00116
00117
00118
00119 void parse_options(int, char**);
00120 dtn_endpoint_id_t* parse_eid(dtn_handle_t handle, dtn_endpoint_id_t * eid, char * str);
00121 void print_usage(char* progname);
00122 void print_eid(char * label, dtn_endpoint_id_t * eid);
00123 void pattern(char *outBuf, int inBytes);
00124 struct timeval set(double sec);
00125 struct timeval add(double sec);
00126 void show_report (u_int buf_len, char* eid, struct timeval start, struct timeval end, int data);
00127 void csv_time_report(int b_sent, int payload, struct timeval start, struct timeval end);
00128 void csv_data_report(int b_id, int payload, struct timeval start, struct timeval end);
00129 long bundles_needed (long data, long pl);
00130 void check_options();
00131 void show_options();
00132 void add_time(struct timeval *tot_time, struct timeval part_time);
00133 long mega2byte(long n);
00134 long kilo2byte(long n);
00135 char findDataUnit(const char *inarg);
00136
00137
00138
00139
00140 int main(int argc, char** argv)
00141 {
00142
00143
00144
00145 int ret;
00146 struct timeval start, end,
00147 p_start, p_end, now;
00148
00149 int i, j;
00150 const char* time_report_hdr = "BUNDLE_SENT,PAYLOAD,TIME,DATA_SENT,GOODPUT";
00151 const char* data_report_hdr = "BUNDLE_ID,PAYLOAD,TIME,GOODPUT";
00152 int n_bundles = 0;
00153
00154
00155 dtn_handle_t handle;
00156 dtn_reg_info_t reginfo;
00157 dtn_bundle_spec_t bundle_spec;
00158 dtn_bundle_spec_t reply_spec;
00159 dtn_bundle_id_t bundle_id;
00160 dtn_bundle_payload_t send_payload;
00161 dtn_bundle_payload_t reply_payload;
00162 char demux[64];
00163
00164
00165 char* buffer = NULL;
00166 int bufferLen;
00167 int bundles_sent;
00168
00169
00170
00171
00172
00173
00174 printf("\nDTNperf - CLIENT - v 1.6.0");
00175 printf("\nwritten by piero.cornice@gmail.com");
00176 printf("\nDEIS - University of Bologna, Italy");
00177 printf("\n");
00178
00179
00180 parse_options(argc, argv);
00181 if (debug) printf("[debug] parsed command-line options\n");
00182
00183
00184 if (debug) printf("[debug] checking command-line options...");
00185 check_options();
00186 if (debug) printf(" done\n");
00187
00188
00189 if (verbose) {
00190 show_options();
00191 }
00192
00193
00194 if (debug) fprintf(stdout, "Opening connection to local DTN daemon...");
00195 int err = dtn_open(&handle);
00196 if (err != DTN_SUCCESS) {
00197 fprintf(stderr, "fatal error opening dtn handle: %s\n", dtn_strerror(err));
00198 exit(1);
00199 }
00200 if (debug) printf(" done\n");
00201
00202
00203
00204
00205
00206
00207
00208 if (debug) printf("[debug] memset for bundle_spec...");
00209 memset(&bundle_spec, 0, sizeof(bundle_spec));
00210 if (debug) printf(" done\n");
00211
00212
00213 sprintf(demux, "/dtnperf:/src");
00214 dtn_build_local_eid(handle, &bundle_spec.source, demux);
00215 if (verbose) printf("\nSource : %s\n", bundle_spec.source.uri);
00216
00217
00218 sprintf(demux, "/dtnperf:/dest");
00219 strcat(arg_dest, demux);
00220 parse_eid(handle, &bundle_spec.dest, arg_dest);
00221 if (verbose) printf("Destination: %s\n", bundle_spec.dest.uri);
00222
00223
00224 if (arg_replyto == NULL) {
00225 if (debug) printf("[debug] setting replyto = source...");
00226 dtn_copy_eid(&bundle_spec.replyto, &bundle_spec.source);
00227 if (debug) printf(" done\n");
00228 }
00229 else {
00230 sprintf(demux, "/dtnperf:/src");
00231 strcat(arg_replyto, demux);
00232 parse_eid(handle, &bundle_spec.dest, arg_replyto);
00233 }
00234 if (verbose) printf("Reply-to : %s\n\n", bundle_spec.replyto.uri);
00235
00236
00237
00238
00239 if (debug) printf("[debug] setting the DTN options: ");
00240
00241
00242 bundle_spec.expiration = expiration;
00243
00244
00245 if (delivery_receipts) {
00246 bundle_spec.dopts |= DOPTS_DELIVERY_RCPT;
00247 if (debug) printf("DELIVERY_RCPT ");
00248 }
00249
00250
00251 if (forwarding_receipts) {
00252 bundle_spec.dopts |= DOPTS_FORWARD_RCPT;
00253 if (debug) printf("FORWARD_RCPT ");
00254 }
00255
00256
00257 if (custody) {
00258 bundle_spec.dopts |= DOPTS_CUSTODY;
00259 if (debug) printf("CUSTODY ");
00260 }
00261
00262
00263 if (custody_receipts) {
00264 bundle_spec.dopts |= DOPTS_CUSTODY_RCPT;
00265 if (debug) printf("CUSTODY_RCPT ");
00266 }
00267
00268
00269 if (receive_receipts) {
00270 bundle_spec.dopts |= DOPTS_RECEIVE_RCPT;
00271 if (debug) printf("RECEIVE_RCPT ");
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281 if (debug) printf("option(s) set\n");
00282
00283
00284
00285
00286 if (debug) printf("[debug] memset for reginfo...");
00287 memset(®info, 0, sizeof(reginfo));
00288 if (debug) printf(" done\n");
00289
00290 if (debug) printf("[debug] copying bundle_spec.replyto to reginfo.endpoint...");
00291 dtn_copy_eid(®info.endpoint, &bundle_spec.replyto);
00292 if (debug) printf(" done\n");
00293
00294 if (debug) printf("[debug] setting up reginfo...");
00295 reginfo.failure_action = DTN_REG_DEFER;
00296 reginfo.regid = regid;
00297 reginfo.expiration = 30;
00298 if (debug) printf(" done\n");
00299
00300 if (debug) printf("[debug] registering to local daemon...");
00301 if ((ret = dtn_register(handle, ®info, ®id)) != 0) {
00302 fprintf(stderr, "error creating registration: %d (%s)\n",
00303 ret, dtn_strerror(dtn_errno(handle)));
00304 exit(1);
00305 }
00306 if (debug) printf(" done: regid 0x%x\n", regid);
00307
00308
00309 if (bundle_payload > MAX_MEM_PAYLOAD)
00310 use_file = 1;
00311 else
00312 use_file = 0;
00313
00314
00315
00316
00317
00318 if (op_mode == 't') {
00319
00320
00321
00322 if (verbose) printf("Working in Time_Mode\n");
00323 if (verbose) printf("requested %d second(s) of transmission\n", transmission_time);
00324
00325 if (debug) printf("[debug] bundle_payload %s %d bytes\n",
00326 use_file ? ">=" : "<",
00327 MAX_MEM_PAYLOAD);
00328 if (verbose) printf(" transmitting data %s\n", use_file ? "using a file" : "using memory");
00329
00330
00331 if (debug) printf("[debug] reset data_qty and bundles_sent...");
00332 data_qty = 0;
00333 bundles_sent = 0;
00334 if (debug) printf(" done\n");
00335
00336
00337 if (debug) printf("[debug] malloc for the buffer...");
00338 buffer = malloc(bundle_payload);
00339 if (debug) printf(" done\n");
00340
00341
00342 if (debug) printf("[debug] initialize the buffer with a pattern...");
00343 pattern(buffer, bundle_payload);
00344 if (debug) printf(" done\n");
00345 bufferLen = strlen(buffer);
00346 if (debug) printf("[debug] bufferLen = %d\n", bufferLen);
00347
00348 if (use_file) {
00349
00350 if (debug) printf("[debug] creating file %s...", file_name_src);
00351 fd = open(file_name_src, O_CREAT|O_TRUNC|O_WRONLY|O_APPEND, 0666);
00352 if (fd < 0) {
00353 fprintf(stderr, "ERROR: couldn't create file %s [fd = %d].\n \
00354 Maybe you don't have permissions\n",
00355 file_name_src, fd);
00356 exit(2);
00357 }
00358 if (debug) printf(" done\n");
00359
00360
00361 if (debug) printf("[debug] filling the file (%s) with the pattern...", file_name_src);
00362 data_written += write(fd, buffer, bufferLen);
00363 if (debug) printf(" done. Written %d bytes\n", data_written);
00364
00365
00366 if (debug) printf("[debug] closing file (%s)...", file_name_src);
00367 close(fd);
00368 if (debug) printf(" done\n");
00369 }
00370
00371
00372 if (debug) printf("[debug] memset for payload...");
00373 memset(&send_payload, 0, sizeof(send_payload));
00374 if (debug) printf(" done\n");
00375
00376
00377 if (debug) printf("[debug] filling payload...");
00378 if (use_file)
00379 dtn_set_payload(&send_payload, DTN_PAYLOAD_FILE, file_name_src, strlen(file_name_src));
00380 else
00381 dtn_set_payload(&send_payload, DTN_PAYLOAD_MEM, buffer, bufferLen);
00382 if (debug) printf(" done\n");
00383
00384
00385 if (debug) printf("[debug] initializing timer...");
00386 gettimeofday(&start, NULL);
00387 if (debug) printf(" start.tv_sec = %d sec\n", (u_int)start.tv_sec);
00388
00389
00390 if (debug) printf("[debug] calculating end-time...");
00391 end = set (0);
00392 end.tv_sec = start.tv_sec + transmission_time;
00393 if (debug) printf(" end.tv_sec = %d sec\n", (u_int)end.tv_sec);
00394
00395
00396 if (debug) printf("[debug] entering loop...\n");
00397 for (now.tv_sec = start.tv_sec; now.tv_sec <= end.tv_sec; gettimeofday(&now, NULL)) {
00398
00399 if (debug) printf("\t[debug] now.tv_sec = %u sec of %u\n", (u_int)now.tv_sec, (u_int)end.tv_sec);
00400
00401
00402 if (debug) printf("\t[debug] sending the bundle...");
00403 memset(&bundle_id, 0, sizeof(bundle_id));
00404 if ((ret = dtn_send(handle, &bundle_spec, &send_payload, &bundle_id)) != 0) {
00405 fprintf(stderr, "error sending bundle: %d (%s)\n",
00406 ret, dtn_strerror(dtn_errno(handle)));
00407 exit(1);
00408 }
00409 if (debug) printf(" bundle sent\n");
00410
00411
00412 bundles_sent++;
00413 if (debug) printf("\t[debug] now bundles_sent is %d\n", bundles_sent);
00414
00415
00416 data_qty += bundle_payload;
00417 if (debug) printf("\t[debug] now data_qty is %lu\n", data_qty);
00418
00419
00420 if (wait_for_report)
00421 {
00422 if (debug) printf("\t[debug] memset for reply_spec...");
00423 memset(&reply_spec, 0, sizeof(reply_spec));
00424 if (debug) printf(" done\n");
00425 if (debug) printf("\t[debug] memset for reply_payload...");
00426 memset(&reply_payload, 0, sizeof(reply_payload));
00427 if (debug) printf(" done\n");
00428 }
00429
00430
00431 if (debug) printf("\t[debug] waiting for the reply...");
00432 if ((ret = dtn_recv(handle, &reply_spec, DTN_PAYLOAD_MEM, &reply_payload, -1)) < 0)
00433 {
00434 fprintf(stderr, "error getting reply: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle)));
00435 exit(1);
00436 }
00437 if (debug) printf(" reply received\n");
00438
00439
00440 if (debug) printf("\t[debug] getting partial end-time...");
00441 gettimeofday(&p_end, NULL);
00442 if (debug) printf(" end.tv_sec = %u sec\n", (u_int)p_end.tv_sec);
00443
00444 if (debug) printf("----- END OF THIS LOOP -----\n\n");
00445 }
00446 if (debug) printf("[debug] out from loop\n");
00447
00448
00449 if (debug) printf("[debug] deallocating buffer memory...");
00450 free((void*)buffer);
00451 if (debug) printf(" done\n");
00452
00453
00454 if (debug) printf("[debug] getting total end-time...");
00455 gettimeofday(&end, NULL);
00456 if (debug) printf(" end.tv_sec = %u sec\n", (u_int)end.tv_sec);
00457
00458
00459 if (csv_out == 0) {
00460 printf("%d bundles sent, each with a %ld bytes payload\n", bundles_sent, bundle_payload);
00461 show_report(reply_payload.buf.buf_len,
00462 reply_spec.source.uri,
00463 start,
00464 end,
00465 data_qty);
00466 }
00467 if (csv_out == 1) {
00468 printf("%s\n", time_report_hdr);
00469 csv_time_report(bundles_sent, bundle_payload, start, end);
00470 }
00471
00472 }
00473
00474 else if (op_mode == 'd') {
00475
00476
00477
00478 if (verbose) printf("Working in Data_Mode\n");
00479
00480
00481 if (debug) printf("[debug] initializing buffer...");
00482 if (!use_file) {
00483 buffer = malloc( (data_qty < bundle_payload) ? data_qty : bundle_payload );
00484 memset(buffer, 0, (data_qty < bundle_payload) ? data_qty : bundle_payload );
00485 pattern(buffer, (data_qty < bundle_payload) ? data_qty : bundle_payload );
00486 }
00487 if (use_file) {
00488 buffer = malloc(data_qty);
00489 memset(buffer, 0, data_qty);
00490 pattern(buffer, data_qty);
00491 }
00492 bufferLen = strlen(buffer);
00493 if (debug) printf(" done. bufferLen = %d (should equal %s)\n",
00494 bufferLen, use_file ? "data_qty" : "bundle_payload");
00495
00496 if (use_file) {
00497
00498 if (debug) printf("[debug] creating file %s...", file_name_src);
00499 fd = open(file_name_src, O_CREAT|O_TRUNC|O_WRONLY|O_APPEND, 0666);
00500 if (fd < 0) {
00501 fprintf(stderr, "ERROR: couldn't create file [fd = %d]. Maybe you don't have permissions\n", fd);
00502 exit(2);
00503 }
00504 if (debug) printf(" done\n");
00505
00506
00507 if (debug) printf("[debug] filling the file (%s) with the pattern...", file_name_src);
00508 data_written += write(fd, buffer, bufferLen);
00509 if (debug) printf(" done. Written %d bytes\n", data_written);
00510
00511
00512 if (debug) printf("[debug] closing file (%s)...", file_name_src);
00513 close(fd);
00514 if (debug) printf(" done\n");
00515 }
00516
00517
00518 if (debug) printf("[debug] filling the bundle payload...");
00519 memset(&send_payload, 0, sizeof(send_payload));
00520 if (use_file) {
00521 dtn_set_payload(&send_payload, DTN_PAYLOAD_FILE, file_name_src, strlen(file_name_src));
00522 } else {
00523 dtn_set_payload(&send_payload, DTN_PAYLOAD_MEM, buffer, bufferLen);
00524 }
00525 if (debug) printf(" done\n");
00526
00527
00528 if (csv_out == 1)
00529 printf("%s\n", data_report_hdr);
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 if (debug) printf("[debug] calculating how many bundles are needed...");
00540 n_bundles = bundles_needed(data_qty, bundle_payload);
00541 if (debug) printf(" n_bundles = %d\n", n_bundles);
00542
00543
00544 if (debug) printf("[debug] initializing TOTAL start timer...");
00545 gettimeofday(&start, NULL);
00546 if (debug) printf(" start.tv_sec = %u sec\n", (u_int)start.tv_sec);
00547
00548 if (debug) printf("[debug] entering n_copies loop...\n");
00549
00550 for (i=0; i<n_copies; i++) {
00551
00552 if (debug) printf("\t[debug] entering n_bundles loop...\n");
00553 for (j=0; j<n_bundles; j++) {
00554
00555
00556 if (debug) printf("\t\t[debug] initializing PARTIAL start timer...");
00557 gettimeofday(&p_start, NULL);
00558 if (debug) printf(" p_start.tv_sec = %u sec\n", (u_int)p_start.tv_sec);
00559
00560
00561 if (debug) printf("\t\t[debug] sending copy %d...", i+1);
00562 memset(&bundle_id, 0, sizeof(bundle_id));
00563 if ((ret = dtn_send(handle, &bundle_spec, &send_payload, &bundle_id)) != 0) {
00564 fprintf(stderr, "error sending bundle: %d (%s)\n",
00565 ret, dtn_strerror(dtn_errno(handle)));
00566 exit(1);
00567 }
00568 if (debug) printf(" bundle sent\n");
00569
00570
00571 if (wait_for_report)
00572 {
00573 if (debug) printf("\t\t[debug] setting memory for reply...");
00574 memset(&reply_spec, 0, sizeof(reply_spec));
00575 memset(&reply_payload, 0, sizeof(reply_payload));
00576 if (debug) printf(" done\n");
00577 }
00578
00579
00580 if (debug) printf("\t\t[debug] waiting for the reply...");
00581 if ((ret = dtn_recv(handle, &reply_spec, DTN_PAYLOAD_MEM, &reply_payload, -1)) < 0)
00582 {
00583 fprintf(stderr, "error getting reply: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle)));
00584 exit(1);
00585 }
00586 if (debug) printf(" reply received\n");
00587
00588
00589 if (debug) printf("\t\t[debug] stopping PARTIAL timer...");
00590 gettimeofday(&p_end, NULL);
00591 if (debug) printf(" p_end.tv_sec = %u sec\n", (u_int)p_end.tv_sec);
00592
00593
00594 if (verbose) {
00595 printf("[%d/%d] ", j+1, n_bundles);
00596 show_report(reply_payload.buf.buf_len,
00597 bundle_spec.source.uri,
00598 p_start,
00599 p_end,
00600 ((bundle_payload <= data_qty)?bundle_payload:data_qty));
00601 }
00602 }
00603 if (debug) printf("\t[debug] ...out from n_bundles loop\n");
00604
00605
00606 if (debug) printf("\t[debug] calculating TOTAL end time...");
00607 gettimeofday(&end, NULL);
00608 if (debug) printf(" end.tv_sec = %u sec\n", (u_int)end.tv_sec);
00609
00610
00611 if (csv_out == 0) {
00612 show_report(reply_payload.buf.buf_len,
00613 reply_spec.source.uri,
00614 start,
00615 end,
00616 data_qty);
00617 }
00618 if (csv_out == 1) {
00619 csv_data_report(i+1, data_qty, start, end);
00620 }
00621
00622 if (n_copies > 0)
00623 sleep(sleepVal);
00624
00625 }
00626 if (debug) printf("[debug] ...out from n_copies loop\n");
00627
00628
00629
00630 if (debug) printf("[debug] deallocating buffer memory...");
00631 free(buffer);
00632 if (debug) printf(" done\n");
00633
00634 }
00635
00636 else {
00637 fprintf(stderr, "ERROR: invalid operative mode! Specify -t or -n\n");
00638 exit(3);
00639 }
00640
00641
00642 if (debug) printf("[debug] closing DTN handle...");
00643 if (dtn_close(handle) != DTN_SUCCESS)
00644 {
00645 fprintf(stderr, "fatal error closing dtn handle: %s\n",
00646 strerror(errno));
00647 exit(1);
00648 }
00649 if (debug) printf(" done\n");
00650
00651
00652 printf("\n");
00653
00654 return 0;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 void print_usage(char* progname)
00667 {
00668 fprintf(stderr, "\nSYNTAX: %s "
00669 "-d <dest_eid> "
00670 "[-t <sec> | -n <num>] [options]\n\n", progname);
00671 fprintf(stderr, "where:\n");
00672 fprintf(stderr, " -d <eid> destination eid (required)\n");
00673 fprintf(stderr, " -t <sec> Time-Mode: seconds of transmission\n");
00674 fprintf(stderr, " -n <num> Data-Mode: number of MBytes to send\n");
00675 fprintf(stderr, "Options common to both Time and Data Mode:\n");
00676 fprintf(stderr, " -p <size> size in KBytes of bundle payload\n");
00677 fprintf(stderr, " -r <eid> reply-to eid (if none specified, source tuple is used)\n");
00678 fprintf(stderr, "Data-Mode options:\n");
00679 fprintf(stderr, " -m use memory instead of file\n");
00680 fprintf(stderr, " -B <num> number of consecutive transmissions (default 1)\n");
00681 fprintf(stderr, " -S <sec> sleeping seconds between consecutive transmissions (default 1)\n");
00682 fprintf(stderr, "Other options:\n");
00683 fprintf(stderr, " -c CSV output (useful with redirection of the output to a file)\n");
00684 fprintf(stderr, " -h help: show this message\n");
00685 fprintf(stderr, " -v verbose\n");
00686 fprintf(stderr, " -D debug messages (many)\n");
00687 fprintf(stderr, " -F enables forwarding receipts\n");
00688 fprintf(stderr, " -R enables receive receipts\n");
00689 fprintf(stderr, "\n");
00690 exit(1);
00691 }
00692
00693
00694
00695
00696
00697 void parse_options(int argc, char**argv)
00698 {
00699 char c, done = 0;
00700
00701 while (!done)
00702 {
00703 c = getopt(argc, argv, "hvDcmr:d:i:t:p:n:S:B:FRf:");
00704 switch (c)
00705 {
00706 case 'v':
00707 verbose = 1;
00708 break;
00709 case 'h':
00710 print_usage(argv[0]);
00711 exit(0);
00712 return;
00713 case 'c':
00714 csv_out = 1;
00715 break;
00716 case 'r':
00717 arg_replyto = optarg;
00718 break;
00719 case 'd':
00720 arg_dest = optarg;
00721 break;
00722 case 'i':
00723 regid = atoi(optarg);
00724 break;
00725 case 'D':
00726 debug = 1;
00727 break;
00728 case 't':
00729 op_mode = 't';
00730 transmission_time = atoi(optarg);
00731 break;
00732 case 'n':
00733 op_mode = 'd';
00734 n_arg = optarg;
00735 data_unit = findDataUnit(n_arg);
00736 switch (data_unit) {
00737 case 'B':
00738 data_qty = atol(n_arg);
00739 break;
00740 case 'K':
00741 data_qty = kilo2byte(atol(n_arg));
00742 break;
00743 case 'M':
00744 data_qty = mega2byte(atol(n_arg));
00745 break;
00746 default:
00747 printf("\nWARNING: (-n option) invalid data unit, assuming 'M' (MBytes)\n\n");
00748 data_qty = mega2byte(atol(n_arg));
00749 break;
00750 }
00751 break;
00752 case 'p':
00753 p_arg = optarg;
00754 data_unit = findDataUnit(p_arg);
00755 switch (data_unit) {
00756 case 'B':
00757 bundle_payload = atol(p_arg);
00758 break;
00759 case 'K':
00760 bundle_payload = kilo2byte(atol(p_arg));
00761 break;
00762 case 'M':
00763 bundle_payload = mega2byte(atol(p_arg));
00764 break;
00765 default:
00766 printf("\nWARNING: (-p option) invalid data unit, assuming 'K' (KBytes)\n\n");
00767 bundle_payload = kilo2byte(atol(p_arg));
00768 break;
00769 }
00770 break;
00771 case 'B':
00772 n_copies = atoi(optarg);
00773 break;
00774 case 'S':
00775 sleepVal = atoi(optarg);
00776 break;
00777
00778 case 'f':
00779 use_file = 1;
00780 file_name_src = strdup(optarg);
00781 break;
00782
00783 case 'm':
00784 use_file = 0;
00785 payload_type = DTN_PAYLOAD_MEM;
00786 break;
00787
00788 case 'F':
00789 forwarding_receipts = 1;
00790 break;
00791
00792 case 'R':
00793 receive_receipts = 1;
00794 break;
00795
00796 case -1:
00797 done = 1;
00798 break;
00799 default:
00800
00801 print_usage(argv[0]);
00802 exit(1);
00803 }
00804 }
00805
00806 #define CHECK_SET(_arg, _what) \
00807 if (_arg == 0) { \
00808 fprintf(stderr, "\nSYNTAX ERROR: %s must be specified\n", _what); \
00809 print_usage(argv[0]); \
00810 exit(1); \
00811 }
00812
00813 CHECK_SET(arg_dest, "destination tuple");
00814 CHECK_SET(op_mode, "-t or -n");
00815 }
00816
00817
00818
00819
00820 void check_options() {
00821
00822 if (n_copies <= 0) {
00823 fprintf(stderr, "\nSYNTAX ERROR: (-B option) consecutive retransmissions should be a positive number\n\n");
00824 exit(2);
00825 }
00826 if (sleepVal < 0) {
00827 fprintf(stderr, "\nSYNTAX ERROR: (-S option) sleeping seconds should be a positive number\n\n");
00828 exit(2);
00829 }
00830 if ((op_mode == 't') && (transmission_time <= 0)) {
00831 fprintf(stderr, "\nSYNTAX ERROR: (-t option) you should specify a positive time\n\n");
00832 exit(2);
00833 }
00834 if ((op_mode == 'd') && (data_qty <= 0)) {
00835 fprintf(stderr, "\nSYNTAX ERROR: (-n option) you should send a positive number of MBytes (%ld)\n\n", data_qty);
00836 exit(2);
00837 }
00838
00839 if ((use_file) && (op_mode == 't')) {
00840 if (bundle_payload <= ILLEGAL_PAYLOAD) {
00841 bundle_payload = DEFAULT_PAYLOAD;
00842 fprintf(stderr, "\nWARNING (a): bundle payload set to %ld bytes\n", bundle_payload);
00843 fprintf(stderr, "(use_file && op_mode=='t' + payload <= %d)\n\n", ILLEGAL_PAYLOAD);
00844 }
00845 }
00846 if ((use_file) && (op_mode == 'd')) {
00847 if ((bundle_payload <= ILLEGAL_PAYLOAD) || (bundle_payload > data_qty)) {
00848 bundle_payload = data_qty;
00849 fprintf(stderr, "\nWARNING (b): bundle payload set to %ld bytes\n", bundle_payload);
00850 fprintf(stderr, "(use_file && op_mode=='d' + payload <= %d or > %ld)\n\n", ILLEGAL_PAYLOAD, data_qty);
00851 }
00852 }
00853 if ((!use_file) && (bundle_payload <= ILLEGAL_PAYLOAD) && (op_mode == 'd')) {
00854 if (data_qty <= MAX_MEM_PAYLOAD) {
00855 bundle_payload = data_qty;
00856 fprintf(stderr, "\nWARNING (c1): bundle payload set to %ld bytes\n", bundle_payload);
00857 fprintf(stderr, "(!use_file + payload <= %d + data_qty <= %d + op_mode=='d')\n\n",
00858 ILLEGAL_PAYLOAD, MAX_MEM_PAYLOAD);
00859 }
00860 if (data_qty > MAX_MEM_PAYLOAD) {
00861 bundle_payload = MAX_MEM_PAYLOAD;
00862 fprintf(stderr, "(!use_file + payload <= %d + data_qty > %d + op_mode=='d')\n",
00863 ILLEGAL_PAYLOAD, MAX_MEM_PAYLOAD);
00864 fprintf(stderr, "\nWARNING (c2): bundle payload set to %ld bytes\n\n", bundle_payload);
00865 }
00866 }
00867 if ((!use_file) && (op_mode == 't')) {
00868 if (bundle_payload <= ILLEGAL_PAYLOAD) {
00869 bundle_payload = DEFAULT_PAYLOAD;
00870 fprintf(stderr, "\nWARNING (d1): bundle payload set to %ld bytes\n\n", bundle_payload);
00871 fprintf(stderr, "(!use_file + payload <= %d + op_mode=='t')\n\n", ILLEGAL_PAYLOAD);
00872 }
00873 if (bundle_payload > MAX_MEM_PAYLOAD) {
00874 fprintf(stderr, "\nWARNING (d2): bundle payload was set to %ld bytes, now set to %ld bytes\n",
00875 bundle_payload, (long)DEFAULT_PAYLOAD);
00876 bundle_payload = DEFAULT_PAYLOAD;
00877 fprintf(stderr, "(!use_file + payload > %d)\n\n", MAX_MEM_PAYLOAD);
00878 }
00879 }
00880 if ((csv_out == 1) && ((verbose == 1) || (debug == 1))) {
00881 fprintf(stderr, "\nSYNTAX ERROR: (-c option) you cannot use -v or -D together with CSV output\n\n");
00882 exit(2);
00883 }
00884 if ((op_mode == 't') && (n_copies != 1)) {
00885 fprintf(stderr, "\nSYNTAX ERROR: you cannot use -B option in Time-Mode\n\n");
00886 exit(2);
00887 }
00888 if ((op_mode == 't') && (sleepVal != 0)) {
00889 fprintf(stderr, "\nSYNTAX ERROR: you cannot use -S option in Time-Mode\n\n");
00890 exit(2);
00891 }
00892 }
00893
00894
00895
00896
00897
00898 void show_options() {
00899 printf("\nRequested");
00900 if (op_mode == 't')
00901 printf(" %d second(s) of transmission\n", transmission_time);
00902 if (op_mode == 'd') {
00903 printf(" %ld byte(s) to be transmitted %d time(s) every %d second(s)\n",
00904 data_qty, n_copies, sleepVal);
00905 }
00906 printf(" payload of each bundle = %ld byte(s)", bundle_payload);
00907 printf("\n\n");
00908 }
00909
00910
00911
00912
00913
00914 dtn_endpoint_id_t* parse_eid(dtn_handle_t handle, dtn_endpoint_id_t* eid, char * str)
00915 {
00916
00917 if (!dtn_parse_eid_string(eid, str))
00918 {
00919
00920 return eid;
00921 }
00922
00923
00924 else if (!dtn_build_local_eid(handle, eid, str))
00925 {
00926 if (verbose) fprintf(stdout, "%s (local)\n", str);
00927 return eid;
00928 }
00929 else
00930 {
00931 fprintf(stderr, "invalid eid string '%s'\n", str);
00932 exit(1);
00933 }
00934 }
00935
00936
00937
00938
00939
00940 void print_eid(char * label, dtn_endpoint_id_t * eid)
00941 {
00942 printf("%s [%s]\n", label, eid->uri);
00943 }
00944
00945
00946
00947
00948
00949
00950
00951 void pattern(char *outBuf, int inBytes) {
00952 assert (outBuf != NULL);
00953 while (inBytes-- > 0) {
00954 outBuf[inBytes] = (inBytes % 10) + '0';
00955 }
00956 }
00957
00958
00959
00960
00961
00962 struct timeval set( double sec ) {
00963 struct timeval mTime;
00964
00965 mTime.tv_sec = (long) sec;
00966 mTime.tv_usec = (long) ((sec - mTime.tv_sec) * 1000000);
00967
00968 return mTime;
00969 }
00970
00971
00972
00973
00974
00975 struct timeval add( double sec ) {
00976 struct timeval mTime;
00977
00978 mTime.tv_sec = (long) sec;
00979 mTime.tv_usec = (long) ((sec - ((long) sec )) * 1000000);
00980
00981
00982 if ( mTime.tv_usec >= 1000000 ) {
00983 mTime.tv_usec -= 1000000;
00984 mTime.tv_sec++;
00985 }
00986
00987 assert( mTime.tv_usec >= 0 && mTime.tv_usec < 1000000 );
00988
00989 return mTime;
00990 }
00991
00992
00993
00994
00995
00996 void show_report (u_int buf_len, char* eid, struct timeval start, struct timeval end, int data) {
00997 double g_put;
00998
00999 printf("got %d byte report from [%s]: time=%.1f ms - %d bytes sent",
01000 buf_len,
01001 eid,
01002 ((double)(end.tv_sec - start.tv_sec) * 1000.0 +
01003 (double)(end.tv_usec - start.tv_usec)/1000.0),
01004 data);
01005
01006
01007 g_put = (data*8) / ((double)(end.tv_sec - start.tv_sec) * 1000.0 +
01008 (double)(end.tv_usec - start.tv_usec)/1000.0);
01009 printf(" (goodput = %.2f Kbit/s)\n", g_put);
01010
01011 if (debug) {
01012
01013 printf("[debug] started at %u sec - ended at %u sec\n", (u_int)start.tv_sec, (u_int)end.tv_sec);
01014 }
01015 }
01016
01017
01018
01019
01020
01021 void csv_time_report(int b_sent, int payload, struct timeval start, struct timeval end) {
01022
01023 double g_put, data;
01024
01025 data = b_sent * payload;
01026
01027 g_put = (data*8) / ((double)(end.tv_sec - start.tv_sec) * 1000.0 +
01028 (double)(end.tv_usec - start.tv_usec)/1000.0);
01029
01030 printf("%d,%d,%.1f,%d,%.2f\n", b_sent,
01031 payload,
01032 ((double)(end.tv_sec - start.tv_sec) * 1000.0 +
01033 (double)(end.tv_usec - start.tv_usec)/1000.0),
01034 (b_sent * payload),
01035 g_put);
01036 }
01037
01038
01039
01040
01041
01042 void csv_data_report(int b_id, int payload, struct timeval start, struct timeval end) {
01043
01044 double g_put;
01045
01046 g_put = (payload*8) / ((double)(end.tv_sec - start.tv_sec) * 1000.0 +
01047 (double)(end.tv_usec - start.tv_usec)/1000.0);
01048
01049 printf("%d,%d,%.1f,%.2f\n", b_id,
01050 payload,
01051 ((double)(end.tv_sec - start.tv_sec) * 1000.0 +
01052 (double)(end.tv_usec - start.tv_usec)/1000.0),
01053 g_put);
01054 }
01055
01056
01057
01058
01059
01060 long bundles_needed (long data, long pl) {
01061 long res = 0;
01062 ldiv_t r;
01063
01064 r = ldiv(data, pl);
01065 res = r.quot;
01066 if (r.rem > 0)
01067 res += 1;
01068
01069 return res;
01070 }
01071
01072
01073
01074
01075
01076 void add_time(struct timeval *tot_time, struct timeval part_time) {
01077 tot_time->tv_sec += part_time.tv_sec;
01078 tot_time->tv_usec += part_time.tv_sec;
01079
01080 if (tot_time->tv_usec >= 1000000) {
01081 tot_time->tv_sec++;
01082 tot_time->tv_usec -= 1000000;
01083 }
01084
01085 }
01086
01087
01088
01089
01090
01091
01092 long mega2byte(long n) {
01093 return (n * 1048576);
01094 }
01095
01096
01097
01098
01099
01100
01101 long kilo2byte(long n) {
01102 return (n * 1024);
01103 }
01104
01105
01106
01107
01108
01109
01110
01111 char findDataUnit(const char *inarg) {
01112
01113 const char unitArray[] = {'B', 'K', 'M'};
01114 char * unit = malloc(sizeof(char));
01115
01116 if ((unit = strpbrk(inarg, unitArray)) == NULL) {
01117 unit = "Z";
01118 }
01119 return unit[0];
01120 }