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