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