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 #include <stdio.h>
00040 #include <unistd.h>
00041 #include <errno.h>
00042 #include <strings.h>
00043 #include <stdlib.h>
00044 #include <sys/time.h>
00045 #include <time.h>
00046
00047 #include "dtn_api.h"
00048
00049 char *progname;
00050
00051
00052 dtn_bundle_payload_location_t
00053 payload_type = 0;
00054 int copies = 1;
00055 int verbose = 0;
00056 int sleep_time = 0;
00057
00058
00059 int expiration = 3600;
00060 int delivery_receipts = 0;
00061 int forwarding_receipts = 0;
00062 int custody = 0;
00063 int custody_receipts = 0;
00064 int receive_receipts = 0;
00065 int overwrite = 0;
00066 int wait_for_report = 0;
00067
00068 char * data_source = NULL;
00069 char date_buf[256];
00070
00071
00072 char * arg_replyto = NULL;
00073 char * arg_source = NULL;
00074 char * arg_dest = NULL;
00075
00076 dtn_reg_id_t regid = DTN_REGID_NONE;
00077
00078
00079 void parse_options(int, char**);
00080 dtn_endpoint_id_t * parse_eid(dtn_handle_t handle,
00081 dtn_endpoint_id_t * eid,
00082 char * str);
00083 void print_usage();
00084 void print_eid(char * label, dtn_endpoint_id_t * eid);
00085 void fill_payload(dtn_bundle_payload_t* payload);
00086
00087 int
00088 main(int argc, char** argv)
00089 {
00090 int i;
00091 int ret;
00092 dtn_handle_t handle;
00093 dtn_reg_info_t reginfo;
00094 dtn_bundle_spec_t bundle_spec;
00095 dtn_bundle_spec_t reply_spec;
00096 dtn_bundle_id_t bundle_id;
00097 dtn_bundle_payload_t send_payload;
00098 dtn_bundle_payload_t reply_payload;
00099 struct timeval start, end;
00100
00101
00102
00103 setvbuf(stdout, (char *)NULL, _IOLBF, 0);
00104
00105 parse_options(argc, argv);
00106
00107
00108 if (verbose) fprintf(stdout, "Opening connection to local DTN daemon\n");
00109
00110 int err = dtn_open(&handle);
00111 if (err != DTN_SUCCESS) {
00112 fprintf(stderr, "fatal error opening dtn handle: %s\n",
00113 dtn_strerror(err));
00114 exit(1);
00115 }
00116
00117
00118 memset(&bundle_spec, 0, sizeof(bundle_spec));
00119
00120
00121 if (verbose) fprintf(stdout, "Destination: %s\n", arg_dest);
00122 parse_eid(handle, &bundle_spec.dest, arg_dest);
00123
00124 if (verbose) fprintf(stdout, "Source: %s\n", arg_source);
00125 parse_eid(handle, &bundle_spec.source, arg_source);
00126 if (arg_replyto == NULL)
00127 {
00128 if (verbose) fprintf(stdout, "Reply To: same as source\n");
00129 dtn_copy_eid(&bundle_spec.replyto, &bundle_spec.source);
00130 }
00131 else
00132 {
00133 if (verbose) fprintf(stdout, "Reply To: %s\n", arg_replyto);
00134 parse_eid(handle, &bundle_spec.replyto, arg_replyto);
00135 }
00136
00137 if (verbose)
00138 {
00139 print_eid("source_eid", &bundle_spec.source);
00140 print_eid("replyto_eid", &bundle_spec.replyto);
00141 print_eid("dest_eid", &bundle_spec.dest);
00142 }
00143
00144 if (wait_for_report)
00145 {
00146
00147 memset(®info, 0, sizeof(reginfo));
00148 dtn_copy_eid(®info.endpoint, &bundle_spec.replyto);
00149 reginfo.failure_action = DTN_REG_DROP;
00150 reginfo.regid = regid;
00151 reginfo.expiration = 60 * 60;
00152 if ((ret = dtn_register(handle, ®info, ®id)) != 0) {
00153 fprintf(stderr, "error creating registration (id=%d): %d (%s)\n",
00154 regid, ret, dtn_strerror(dtn_errno(handle)));
00155 exit(1);
00156 }
00157
00158 if (verbose) printf("dtn_register succeeded, regid 0x%x\n", regid);
00159 }
00160
00161
00162 bundle_spec.expiration = expiration;
00163
00164 if (delivery_receipts)
00165 {
00166
00167 bundle_spec.dopts |= DOPTS_DELIVERY_RCPT;
00168 }
00169
00170 if (forwarding_receipts)
00171 {
00172
00173 bundle_spec.dopts |= DOPTS_FORWARD_RCPT;
00174 }
00175
00176 if (custody)
00177 {
00178
00179 bundle_spec.dopts |= DOPTS_CUSTODY;
00180 }
00181
00182 if (custody_receipts)
00183 {
00184
00185 bundle_spec.dopts |= DOPTS_CUSTODY_RCPT;
00186 }
00187
00188 if (receive_receipts)
00189 {
00190
00191 bundle_spec.dopts |= DOPTS_RECEIVE_RCPT;
00192 }
00193
00194
00195 for (i = 0; i < copies; ++i) {
00196 gettimeofday(&start, NULL);
00197
00198 fill_payload(&send_payload);
00199
00200 memset(&bundle_id, 0, sizeof(bundle_id));
00201
00202 if ((ret = dtn_send(handle, &bundle_spec, &send_payload,
00203 &bundle_id)) != 0)
00204 {
00205 fprintf(stderr, "error sending bundle: %d (%s)\n",
00206 ret, dtn_strerror(dtn_errno(handle)));
00207 exit(1);
00208 }
00209
00210 if (verbose) fprintf(stdout, "bundle sent successfully: id %s,%u.%u\n",
00211 bundle_id.source.uri,
00212 bundle_id.creation_secs,
00213 bundle_id.creation_subsecs);
00214
00215 if (wait_for_report)
00216 {
00217 memset(&reply_spec, 0, sizeof(reply_spec));
00218 memset(&reply_payload, 0, sizeof(reply_payload));
00219
00220
00221 if ((ret = dtn_recv(handle, &reply_spec,
00222 DTN_PAYLOAD_MEM, &reply_payload, -1)) < 0)
00223 {
00224 fprintf(stderr, "error getting reply: %d (%s)\n",
00225 ret, dtn_strerror(dtn_errno(handle)));
00226 exit(1);
00227 }
00228 gettimeofday(&end, NULL);
00229
00230 printf("got %d byte report from [%s]: time=%.1f ms\n",
00231 reply_payload.dtn_bundle_payload_t_u.buf.buf_len,
00232 reply_spec.source.uri,
00233 ((double)(end.tv_sec - start.tv_sec) * 1000.0 +
00234 (double)(end.tv_usec - start.tv_usec)/1000.0));
00235 }
00236
00237 if (sleep_time != 0) {
00238 usleep(sleep_time * 1000);
00239 }
00240 }
00241
00242 dtn_close(handle);
00243
00244 return 0;
00245 }
00246
00247 void print_usage()
00248 {
00249 fprintf(stderr, "usage: %s [opts] "
00250 "-s <source_eid> -d <dest_eid> -t <type> -p <payload>\n",
00251 progname);
00252 fprintf(stderr, "options:\n");
00253 fprintf(stderr, " -v verbose\n");
00254 fprintf(stderr, " -h help\n");
00255 fprintf(stderr, " -s <eid|demux_string> source eid)\n");
00256 fprintf(stderr, " -d <eid|demux_string> destination eid)\n");
00257 fprintf(stderr, " -r <eid|demux_string> reply to eid)\n");
00258 fprintf(stderr, " -t <f|m|d> payload type: file, message, or date\n");
00259 fprintf(stderr, " -p <filename|string> payload data\n");
00260 fprintf(stderr, " -e <time> expiration time in seconds (default: one hour)\n");
00261 fprintf(stderr, " -i <regid> registration id for reply to\n");
00262 fprintf(stderr, " -n <int> copies of the bundle to send\n");
00263 fprintf(stderr, " -z <time> msecs to sleep between transmissions\n");
00264 fprintf(stderr, " -c request custody transfer\n");
00265 fprintf(stderr, " -C request custody transfer receipts\n");
00266 fprintf(stderr, " -D request for end-to-end delivery receipt\n");
00267 fprintf(stderr, " -R request for bundle reception receipts\n");
00268 fprintf(stderr, " -F request for bundle forwarding receipts\n");
00269 fprintf(stderr, " -w wait for bundle status reports\n");
00270
00271 exit(1);
00272 }
00273
00274 void parse_options(int argc, char**argv)
00275 {
00276 char c, done = 0;
00277 char arg_type = 0;
00278
00279 progname = argv[0];
00280
00281 while (!done)
00282 {
00283 c = getopt(argc, argv, "vhHr:s:d:e:n:woDFRcCt:p:i:z:");
00284 switch (c)
00285 {
00286 case 'v':
00287 verbose = 1;
00288 break;
00289 case 'h':
00290 case 'H':
00291 print_usage();
00292 exit(0);
00293 return;
00294 case 'r':
00295 arg_replyto = optarg;
00296 break;
00297 case 's':
00298 arg_source = optarg;
00299 break;
00300 case 'd':
00301 arg_dest = optarg;
00302 break;
00303 case 'e':
00304 expiration = atoi(optarg);
00305 break;
00306 case 'n':
00307 copies = atoi(optarg);
00308 break;
00309 case 'w':
00310 wait_for_report = 1;
00311 break;
00312 case 'D':
00313 delivery_receipts = 1;
00314 break;
00315 case 'F':
00316 forwarding_receipts = 1;
00317 break;
00318 case 'R':
00319 receive_receipts = 1;
00320 break;
00321 case 'c':
00322 custody = 1;
00323 break;
00324 case 'C':
00325 custody_receipts = 1;
00326 break;
00327 case 't':
00328 arg_type = optarg[0];
00329 break;
00330 case 'p':
00331 data_source = strdup(optarg);
00332 break;
00333 case 'i':
00334 regid = atoi(optarg);
00335 break;
00336 case 'z':
00337 sleep_time = atoi(optarg);
00338 break;
00339 case -1:
00340 done = 1;
00341 break;
00342 default:
00343
00344
00345 print_usage();
00346 exit(1);
00347 }
00348 }
00349
00350 #define CHECK_SET(_arg, _what) \
00351 if (_arg == 0) { \
00352 fprintf(stderr, "dtnsend: %s must be specified\n", _what); \
00353 print_usage(); \
00354 exit(1); \
00355 }
00356
00357 CHECK_SET(arg_source, "source eid");
00358 CHECK_SET(arg_dest, "destination eid");
00359 CHECK_SET(arg_type, "payload type");
00360 if (arg_type != 'd') {
00361 CHECK_SET(data_source, "payload data");
00362 }
00363
00364 switch (arg_type)
00365 {
00366 case 'f': payload_type = DTN_PAYLOAD_FILE; break;
00367 case 'm': payload_type = DTN_PAYLOAD_MEM; break;
00368 case 'd':
00369 payload_type = DTN_PAYLOAD_MEM;
00370 data_source = date_buf;
00371 break;
00372 default:
00373 fprintf(stderr, "dtnsend: type argument '%d' invalid\n", arg_type);
00374 print_usage();
00375 exit(1);
00376 }
00377 }
00378
00379 dtn_endpoint_id_t * parse_eid(dtn_handle_t handle,
00380 dtn_endpoint_id_t* eid, char * str)
00381 {
00382
00383 if (!dtn_parse_eid_string(eid, str))
00384 {
00385 if (verbose) fprintf(stdout, "%s (literal)\n", str);
00386 return eid;
00387 }
00388
00389
00390 else if (!dtn_build_local_eid(handle, eid, str))
00391 {
00392 if (verbose) fprintf(stdout, "%s (local)\n", str);
00393 return eid;
00394 }
00395 else
00396 {
00397 fprintf(stderr, "invalid eid string '%s'\n", str);
00398 exit(1);
00399 }
00400 }
00401
00402 void print_eid(char * label, dtn_endpoint_id_t * eid)
00403 {
00404 printf("%s [%s]\n", label, eid->uri);
00405 }
00406
00407 void fill_payload(dtn_bundle_payload_t* payload) {
00408
00409 if (data_source == date_buf) {
00410 time_t current = time(NULL);
00411 strcpy(date_buf, ctime(¤t));
00412 }
00413
00414 memset(payload, 0, sizeof(*payload));
00415 dtn_set_payload(payload, payload_type, data_source, strlen(data_source));
00416 }