void to_bundles() { int bytes, ret; dtn_reg_info_t reg_report; /* for reports, if reqd */ dtn_reg_info_t reg_session; /* for session reg, if reqd */ // initialize bundle spec memset(&bundle_spec, 0, sizeof(bundle_spec)); parse_eid(handle, &bundle_spec.dest, arg_dest); parse_eid(handle, &bundle_spec.source, arg_source); if (arg_replyto == NULL) { dtn_copy_eid(&bundle_spec.replyto, &bundle_spec.source); } else { parse_eid(handle, &bundle_spec.replyto, arg_replyto); } if (verbose) { print_eid(info, "source_eid", &bundle_spec.source); print_eid(info, "replyto_eid", &bundle_spec.replyto); print_eid(info, "dest_eid", &bundle_spec.dest); } if (wait_for_report) { // if we're given a regid, bind to it, otherwise make a // registration for incoming reports if (regid != DTN_REGID_NONE) { if (dtn_bind(handle, regid) != DTN_SUCCESS) { fprintf(stderr, "%s: error in bind (id=0x%x): %d (%s)\n", progname, regid, ret, dtn_strerror(dtn_errno(handle))); exit(EXIT_FAILURE); } } else { memset(®_report, 0, sizeof(reg_report)); dtn_copy_eid(®_report.endpoint, &bundle_spec.replyto); reg_report.flags = DTN_REG_DEFER; reg_report.expiration = REG_EXPIRE; make_registration(®_report); } } if (session_flags) { // make a publisher registration memset(®_session, 0, sizeof(reg_session)); dtn_copy_eid(®_session.endpoint, &bundle_spec.dest); reg_session.flags = DTN_SESSION_PUBLISH; reg_session.expiration = 0; make_registration(®_session); } // set the dtn options bundle_spec.expiration = expiration; if (delivery_receipts) { // set the delivery receipt option bundle_spec.dopts |= DOPTS_DELIVERY_RCPT; } if (forwarding_receipts) { // set the forward receipt option bundle_spec.dopts |= DOPTS_FORWARD_RCPT; } if (custody) { // request custody transfer bundle_spec.dopts |= DOPTS_CUSTODY; } if (custody_receipts) { // request custody transfer bundle_spec.dopts |= DOPTS_CUSTODY_RCPT; } if (receive_receipts) { // request receive receipt bundle_spec.dopts |= DOPTS_RECEIVE_RCPT; } if (sequence_id) { bundle_spec.sequence_id.data.data_val = sequence_id; bundle_spec.sequence_id.data.data_len = strlen(sequence_id); } if (obsoletes_id) { bundle_spec.obsoletes_id.data.data_val = obsoletes_id; bundle_spec.obsoletes_id.data.data_len = strlen(obsoletes_id); } if ((bytes = fill_payload(&primary_payload)) < 0) { fprintf(stderr, "%s: error reading bundle data\n", progname); exit(EXIT_FAILURE); } memset(&bundle_id, 0, sizeof(bundle_id)); if ((ret = dtn_send(handle, regid, &bundle_spec, &primary_payload, &bundle_id)) != 0) { fprintf(stderr, "%s: error sending bundle: %d (%s)\n", progname, ret, dtn_strerror(dtn_errno(handle))); exit(EXIT_FAILURE); } if (verbose) fprintf(info, "Read %d bytes from stdin and wrote to bundles\n", bytes); if (wait_for_report) { memset(&reply_spec, 0, sizeof(reply_spec)); memset(&reply_payload, 0, sizeof(reply_payload)); // now we block waiting for any replies if ((ret = dtn_recv(handle, &reply_spec, DTN_PAYLOAD_MEM, &reply_payload, -1)) < 0) { fprintf(stderr, "%s: error getting reply: %d (%s)\n", progname, ret, dtn_strerror(dtn_errno(handle))); exit(EXIT_FAILURE); } if (gettimeofday(&end, NULL) < 0) { fprintf(stderr, "%s: gettimeofday(end) returned error %s\n", progname, strerror(errno)); exit(EXIT_FAILURE); } if (verbose) fprintf(info, "got %d byte report from [%s]: time=%.1f ms\n", reply_payload.buf.buf_len, reply_spec.source.uri, ((double)(end.tv_sec - start.tv_sec) * 1000.0 + (double)(end.tv_usec - start.tv_usec)/1000.0)); } }
int main(int argc, const char** argv) { int i; int ret; dtn_handle_t handle; dtn_endpoint_id_t source_eid; dtn_reg_info_t reginfo; dtn_reg_id_t regid; dtn_bundle_spec_t ping_spec; dtn_bundle_spec_t reply_spec; dtn_bundle_payload_t ping_payload; ping_payload_t payload_contents; ping_payload_t recv_contents; dtn_bundle_payload_t reply_payload; dtn_bundle_status_report_t* sr_data; dtn_bundle_id_t bundle_id; int debug = 1; char demux[64]; int dest_len = 0; struct timeval send_times[MAX_PINGS_IN_FLIGHT]; dtn_timestamp_t creation_times[MAX_PINGS_IN_FLIGHT]; struct timeval now, recv_start, recv_end; u_int32_t nonce; u_int32_t seqno = 0; int timeout; // force stdout to always be line buffered, even if output is // redirected to a pipe or file setvbuf(stdout, (char *)NULL, _IOLBF, 0); doOptions(argc, argv); memset(&ping_spec, 0, sizeof(ping_spec)); gettimeofday(&now, 0); srand(now.tv_sec); nonce = rand(); // open the ipc handle int err = dtn_open(&handle); if (err != DTN_SUCCESS) { fprintf(stderr, "fatal error opening dtn handle: %s\n", dtn_strerror(err)); exit(1); } // make sure they supplied a valid destination eid or // "localhost", in which case we just use the local daemon if (strcmp(dest_eid_str, "localhost") == 0) { dtn_build_local_eid(handle, &ping_spec.dest, "ping"); } else { if (dtn_parse_eid_string(&ping_spec.dest, dest_eid_str)) { fprintf(stderr, "invalid destination eid string '%s'\n", dest_eid_str); exit(1); } } dest_len = strlen(ping_spec.dest.uri); if ((dest_len < 4) || (strcmp(ping_spec.dest.uri + dest_len - 4, "ping") != 0)) { fprintf(stderr, "\nWARNING: ping destination does not end in \"ping\"\n\n"); } // if the user specified a source eid, register on it. // otherwise, build a local eid based on the configuration of // our dtn router plus the demux string snprintf(demux, sizeof(demux), "/ping.%d", getpid()); if (source_eid_str[0] != '\0') { if (dtn_parse_eid_string(&source_eid, source_eid_str)) { fprintf(stderr, "invalid source eid string '%s'\n", source_eid_str); exit(1); } } else { dtn_build_local_eid(handle, &source_eid, demux); } // set the source and replyto eids in the bundle spec if (debug) printf("source_eid [%s]\n", source_eid.uri); dtn_copy_eid(&ping_spec.source, &source_eid); dtn_copy_eid(&ping_spec.replyto, &source_eid); // now create a new registration based on the source memset(®info, 0, sizeof(reginfo)); dtn_copy_eid(®info.endpoint, &source_eid); reginfo.flags = DTN_REG_DEFER; reginfo.regid = DTN_REGID_NONE; reginfo.expiration = 0; if ((ret = dtn_register(handle, ®info, ®id)) != 0) { fprintf(stderr, "error creating registration: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); exit(1); } if (debug) printf("dtn_register succeeded, regid %d\n", regid); // set the expiration time and request deletion status reports ping_spec.expiration = expiration; ping_spec.dopts = DOPTS_DELETE_RCPT; printf("PING [%s] (expiration %u)...\n", ping_spec.dest.uri, expiration); if (interval == 0) { printf("WARNING: zero second interval will result in flooding pings!!\n"); } // loop, sending pings and polling for activity for (i = 0; count == 0 || i < count; ++i) { gettimeofday(&send_times[seqno], NULL); // fill in a short payload string, a nonce, and a sequence number // to verify the echo feature and make sure we're not getting // duplicate responses or ping responses from another app memcpy(&payload_contents.ping, PING_STR, 8); payload_contents.seqno = seqno; payload_contents.nonce = nonce; payload_contents.time = send_times[seqno].tv_sec; memset(&ping_payload, 0, sizeof(ping_payload)); dtn_set_payload(&ping_payload, DTN_PAYLOAD_MEM, (char*)&payload_contents, sizeof(payload_contents)); memset(&bundle_id, 0, sizeof(bundle_id)); if ((ret = dtn_send(handle, regid, &ping_spec, &ping_payload, &bundle_id)) != 0) { fprintf(stderr, "error sending bundle: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); exit(1); } creation_times[seqno] = bundle_id.creation_ts; memset(&reply_spec, 0, sizeof(reply_spec)); memset(&reply_payload, 0, sizeof(reply_payload)); // now loop waiting for replies / status reports until it's // time to send again, adding twice the expiration time if we // just sent the last ping timeout = interval * 1000; if (i == count - 1) timeout += expiration * 2000; do { gettimeofday(&recv_start, 0); if ((ret = dtn_recv(handle, &reply_spec, DTN_PAYLOAD_MEM, &reply_payload, timeout)) < 0) { if (dtn_errno(handle) == DTN_ETIMEOUT) { break; // time to send again } fprintf(stderr, "error getting ping reply: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); exit(1); } gettimeofday(&recv_end, 0); if (reply_payload.status_report != NULL) { sr_data = reply_payload.status_report; if (sr_data->flags != STATUS_DELETED) { fprintf(stderr, "(bad status report from %s: flags 0x%x)\n", reply_spec.source.uri, sr_data->flags); goto next; } // find the seqno corresponding to the original // transmission time in the status report int j = 0; for (j = 0; j < MAX_PINGS_IN_FLIGHT; ++j) { if (creation_times[j].secs == sr_data->bundle_id.creation_ts.secs && creation_times[j].seqno == sr_data->bundle_id.creation_ts.seqno) { printf("bundle deleted at [%s] (%s): seqno=%d, time=%ld ms\n", reply_spec.source.uri, dtn_status_report_reason_to_str(sr_data->reason), j, TIMEVAL_DIFF_MSEC(recv_end, send_times[j])); goto next; } } printf("bundle deleted at [%s] (%s): ERROR: can't find seqno\n", reply_spec.source.uri, dtn_status_report_reason_to_str(sr_data->reason)); } else { if (reply_payload.buf.buf_len != sizeof(ping_payload_t)) { printf("%d bytes from [%s]: ERROR: length != %zu\n", reply_payload.buf.buf_len, reply_spec.source.uri, sizeof(ping_payload_t)); goto next; } memcpy(&recv_contents, reply_payload.buf.buf_val, sizeof(recv_contents)); if (recv_contents.seqno > MAX_PINGS_IN_FLIGHT) { printf("%d bytes from [%s]: ERROR: invalid seqno %d\n", reply_payload.buf.buf_len, reply_spec.source.uri, recv_contents.seqno); goto next; } if (recv_contents.nonce != nonce) { printf("%d bytes from [%s]: ERROR: invalid nonce %u != %u\n", reply_payload.buf.buf_len, reply_spec.source.uri, recv_contents.nonce, nonce); goto next; } if (recv_contents.time != (u_int32_t)send_times[recv_contents.seqno].tv_sec) { printf("%d bytes from [%s]: ERROR: time mismatch -- " "seqno %u reply time %u != send time %lu\n", reply_payload.buf.buf_len, reply_spec.source.uri, recv_contents.seqno, recv_contents.time, (long unsigned int)send_times[recv_contents.seqno].tv_sec); goto next; } printf("%d bytes from [%s]: '%.*s' seqno=%d, time=%ld ms\n", reply_payload.buf.buf_len, reply_spec.source.uri, (u_int)strlen(PING_STR), reply_payload.buf.buf_val, recv_contents.seqno, TIMEVAL_DIFF_MSEC(recv_end, send_times[recv_contents.seqno])); fflush(stdout); } next: dtn_free_payload(&reply_payload); timeout -= TIMEVAL_DIFF_MSEC(recv_end, recv_start); // once we get status from all the pings we're supposed to // send, we're done reply_count++; if (count != 0 && reply_count == count) { break; } } while (timeout > 0); seqno++; seqno %= MAX_PINGS_IN_FLIGHT; } dtn_close(handle); return 0; }
int main(int argc, const char** argv) { int ret; dtn_handle_t handle; dtn_endpoint_id_t source_eid; dtn_endpoint_id_t replyto_eid; dtn_reg_info_t reginfo; dtn_reg_id_t regid; dtn_bundle_spec_t ping_spec; dtn_bundle_spec_t reply_spec; dtn_bundle_payload_t ping_payload; ping_payload_t payload_contents; ping_payload_t recv_contents; dtn_bundle_payload_t reply_payload; dtn_bundle_status_report_t* sr_data; dtn_bundle_id_t bundle_id; int debug = 1; char demux[64]; int dest_len = 0; struct timeval send_time, now; u_int32_t nonce; int done; time_t clock; struct tm* tm_buf; // force stdout to always be line buffered, even if output is // redirected to a pipe or file setvbuf(stdout, (char *)NULL, _IOLBF, 0); doOptions(argc, argv); memset(&ping_spec, 0, sizeof(ping_spec)); gettimeofday(&now, 0); srand(now.tv_sec); nonce = rand(); // open the ipc handle int err = 0; if (api_IP_set) err = dtn_open_with_IP(api_IP,api_port,&handle); else err = dtn_open(&handle); if (err != DTN_SUCCESS) { fprintf(stderr, "fatal error opening dtn handle: %s\n", dtn_strerror(err)); exit(1); } // make sure they supplied a valid destination eid or // "localhost", in which case we just use the local daemon if (strcmp(dest_eid_str, "localhost") == 0) { dtn_build_local_eid(handle, &ping_spec.dest, "ping"); } else { if (dtn_parse_eid_string(&ping_spec.dest, dest_eid_str)) { fprintf(stderr, "invalid destination eid string '%s'\n", dest_eid_str); exit(1); } } dest_len = strlen(ping_spec.dest.uri); if ((dest_len < 4) || (strcmp(ping_spec.dest.uri + dest_len - 4, "ping") != 0)) { fprintf(stderr, "\nWARNING: ping destination does not end in \"ping\"\n\n"); } // if the user specified a source eid, register on it. // otherwise, build a local eid based on the configuration of // our dtn router plus the demux string snprintf(demux, sizeof(demux), "/traceroute.%d", getpid()); if (source_eid_str[0] != '\0') { if (dtn_parse_eid_string(&source_eid, source_eid_str)) { fprintf(stderr, "invalid source eid string '%s'\n", source_eid_str); exit(1); } } else { dtn_build_local_eid(handle, &source_eid, demux); } if (debug) printf("source_eid [%s]\n", source_eid.uri); dtn_copy_eid(&ping_spec.source, &source_eid); // Make the replyto EID if ( replyto_eid_str[0]!=0 ) { if (dtn_parse_eid_string(&replyto_eid, replyto_eid_str)) { fprintf(stderr, "invalid replyto eid string '%s'\n", replyto_eid_str); exit(1); } dtn_copy_eid(&ping_spec.replyto, &replyto_eid); printf("using user-supplied replyto\n"); } else { dtn_copy_eid(&ping_spec.replyto, &source_eid); printf("using default replyto\n"); } // now create a new registration based on the source // if the replyto EID is unspecified or the same as the // source EID then we'll get status reports, otherwise // they'll go somewhere else. memset(®info, 0, sizeof(reginfo)); dtn_copy_eid(®info.endpoint, &source_eid); reginfo.flags = DTN_REG_DROP; reginfo.regid = DTN_REGID_NONE; reginfo.expiration = 0; if ((ret = dtn_register(handle, ®info, ®id)) != 0) { fprintf(stderr, "error creating registration: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); exit(1); } if (debug) printf("dtn_register succeeded, regid %d\n", regid); // set the expiration time and request a bunch of status reports ping_spec.expiration = expiration; ping_spec.dopts = DOPTS_DELETE_RCPT | DOPTS_RECEIVE_RCPT | DOPTS_FORWARD_RCPT | DOPTS_DELIVERY_RCPT; // loop, sending pings and polling for activity gettimeofday(&send_time, NULL); // fill in a short payload string, a nonce, and a sequence number // to verify the echo feature and make sure we're not getting // duplicate responses or ping responses from another app memcpy(&payload_contents.ping, PING_STR, 8); payload_contents.seqno = 0; payload_contents.nonce = nonce; payload_contents.time = send_time.tv_sec; memset(&ping_payload, 0, sizeof(ping_payload)); dtn_set_payload(&ping_payload, DTN_PAYLOAD_MEM, (char*)&payload_contents, sizeof(payload_contents)); memset(&bundle_id, 0, sizeof(bundle_id)); if ((ret = dtn_send(handle, regid, &ping_spec, &ping_payload, &bundle_id)) != 0) { fprintf(stderr, "error sending bundle: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); exit(1); } memset(&reply_spec, 0, sizeof(reply_spec)); memset(&reply_payload, 0, sizeof(reply_payload)); clock = time(&clock); tm_buf = gmtime(&clock); printf("%s: sent at %.*s UTC\n", ping_spec.source.uri, 24, asctime(tm_buf)); // now loop waiting for replies / status reports until we're done done = 0; while (1) { int timeout = done ? wait_after_done * 1000 : -1; if ((ret = dtn_recv(handle, &reply_spec, DTN_PAYLOAD_MEM, &reply_payload, timeout)) < 0) { if (done && dtn_errno(handle) == DTN_ETIMEOUT) { break; } fprintf(stderr, "error getting ping reply: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); exit(1); } gettimeofday(&now, 0); if (reply_payload.status_report != NULL) { sr_data = reply_payload.status_report; if (sr_data->flags & STATUS_RECEIVED) { clock = sr_data->receipt_ts.secs + DTNTIME_OFFSET; tm_buf = gmtime(&clock); printf("%s: received at %.*s UTC (%ld ms rtt)\n", reply_spec.source.uri, 24, asctime(tm_buf), TIMEVAL_DIFF_MSEC(now, send_time)); } if (sr_data->flags & STATUS_FORWARDED) { clock = sr_data->forwarding_ts.secs + DTNTIME_OFFSET; tm_buf = gmtime(&clock); printf("%s: forwarded at %.*s UTC (%ld ms rtt)\n", reply_spec.source.uri, 24, asctime(tm_buf), TIMEVAL_DIFF_MSEC(now, send_time)); } if (sr_data->flags & STATUS_DELIVERED) { clock = sr_data->delivery_ts.secs + DTNTIME_OFFSET; tm_buf = gmtime(&clock); printf("%s: delivered at %.*s UTC (%ld ms rtt)\n", reply_spec.source.uri, 24, asctime(tm_buf), TIMEVAL_DIFF_MSEC(now, send_time)); } if (sr_data->flags & STATUS_DELETED) { clock = sr_data->deletion_ts.secs + DTNTIME_OFFSET; tm_buf = gmtime(&clock); printf("%s: deleted at %.*s UTC (%s) (%ld ms rtt)\n", reply_spec.source.uri, 24, asctime(tm_buf), dtn_status_report_reason_to_str(sr_data->reason), TIMEVAL_DIFF_MSEC(now, send_time)); break; } } else { if (reply_payload.buf.buf_len != sizeof(ping_payload_t)) { printf("%d bytes from [%s]: ERROR: length != %zu\n", reply_payload.buf.buf_len, reply_spec.source.uri, sizeof(ping_payload_t)); break; } memcpy(&recv_contents, reply_payload.buf.buf_val, sizeof(recv_contents)); if (recv_contents.seqno != 0) { printf("%d bytes from [%s]: ERROR: invalid seqno %d\n", reply_payload.buf.buf_len, reply_spec.source.uri, recv_contents.seqno); break; } if (recv_contents.nonce != nonce) { printf("%d bytes from [%s]: ERROR: invalid nonce %u != %u\n", reply_payload.buf.buf_len, reply_spec.source.uri, recv_contents.nonce, nonce); break; } if ((int)recv_contents.time != (int)send_time.tv_sec) { printf("%d bytes from [%s]: ERROR: time mismatch %u != %lu\n", reply_payload.buf.buf_len, reply_spec.source.uri, recv_contents.time, (long unsigned int)send_time.tv_sec); } clock = reply_spec.creation_ts.secs + DTNTIME_OFFSET; tm_buf = gmtime(&clock); printf("%s: echo reply at %.*s UTC (%ld ms rtt)\n", reply_spec.source.uri, 24, asctime(tm_buf), TIMEVAL_DIFF_MSEC(now, send_time)); done = 1; } dtn_free_payload(&reply_payload); } dtn_close(handle); return 0; }
int main(int argc, char** argv) { int ret; dtn_handle_t handle; dtn_reg_info_t reginfo; dtn_reg_id_t regid = DTN_REGID_NONE; dtn_bundle_spec_t bundle_spec; dtn_bundle_spec_t reply_spec; dtn_bundle_payload_t send_payload; dtn_bundle_payload_t reply_payload; dtn_bundle_id_t bundle_id; char demux[4096]; struct timeval start, end; /* FILE * file; */ /* //struct stat finfo; */ /* char buffer[4096]; // max filesize to send is 4096 (temp) */ /* int bufsize = 0; */ // force stdout to always be line buffered, even if output is // redirected to a pipe or file setvbuf(stdout, (char *)NULL, _IOLBF, 0); parse_options(argc, argv); // open the ipc handle if (verbose) fprintf(stdout, "Opening connection to local DTN daemon\n"); int err = 0; if (api_IP_set) err = dtn_open_with_IP(api_IP,api_port,&handle); else err = dtn_open(&handle); if (err != DTN_SUCCESS) { fprintf(stderr, "fatal error opening dtn handle: %s\n", dtn_strerror(err)); exit(1); } // ---------------------------------------------------- // initialize bundle spec with src/dest/replyto // ---------------------------------------------------- // initialize bundle spec memset(&bundle_spec, 0, sizeof(bundle_spec)); // destination host is specified at run time, demux is hardcoded sprintf(demux, "%s/dtncp/recv?file=%s", arg_dest, arg_target); parse_eid(handle, &bundle_spec.dest, demux); // source is local eid with file path as demux string sprintf(demux, "/dtncp/send?source=%s", data_source); parse_eid(handle, &bundle_spec.source, demux); if (verbose) { print_eid("source_eid", &bundle_spec.source); print_eid("dest_eid", &bundle_spec.dest); } // set the expiration time (one hour) bundle_spec.expiration = expiration_time; if (delivery_receipts) { // set the delivery receipt option bundle_spec.dopts |= DOPTS_DELIVERY_RCPT; } // fill in a payload memset(&send_payload, 0, sizeof(send_payload)); dtn_set_payload(&send_payload, DTN_PAYLOAD_FILE, data_source, strlen(data_source)); // send file and wait for reply // create a new dtn registration to receive bundle status reports memset(®info, 0, sizeof(reginfo)); dtn_copy_eid(®info.endpoint, &bundle_spec.source); reginfo.flags = DTN_REG_DEFER; reginfo.regid = regid; reginfo.expiration = 0; if ((ret = dtn_register(handle, ®info, ®id)) != 0) { fprintf(stderr, "error creating registration (id=%d): %d (%s)\n", regid, ret, dtn_strerror(dtn_errno(handle))); exit(1); } if (verbose) printf("dtn_register succeeded, regid 0x%x\n", regid); gettimeofday(&start, NULL); // timer memset(&bundle_id, 0, sizeof(bundle_id)); if ((ret = dtn_send(handle, regid, &bundle_spec, &send_payload, &bundle_id)) != 0) { fprintf(stderr, "error sending file bundle: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); exit(1); } if (delivery_receipts) { memset(&reply_spec, 0, sizeof(reply_spec)); memset(&reply_payload, 0, sizeof(reply_payload)); // now we block waiting for the echo reply if ((ret = dtn_recv(handle, &reply_spec, DTN_PAYLOAD_MEM, &reply_payload, -1)) < 0) { fprintf(stderr, "error getting reply: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); exit(1); } gettimeofday(&end, NULL); printf("file sent successfully to [%s]: time=%.1f ms\n", reply_spec.source.uri, ((double)(end.tv_sec - start.tv_sec) * 1000.0 + (double)(end.tv_usec - start.tv_usec)/1000.0)); dtn_free_payload(&reply_payload); } else { printf("file sent to [%s]\n", bundle_spec.dest.uri); } dtn_close(handle); return 0; }
int reader_thread(void *p) { // loop reading from motes, writing to directory static int tcnt=0; DATAPACKET *dataPacket; // dtn api variables int ret; dtn_handle_t handle; dtn_reg_info_t reginfo; dtn_reg_id_t regid = DTN_REGID_NONE; dtn_bundle_spec_t bundle_spec; dtn_bundle_payload_t send_payload; dtn_bundle_id_t bundle_id; char demux[4096]; p = NULL; // open the ipc handle if (debug > 0) fprintf(stdout, "Opening connection to local DTN daemon\n"); int err = 0; if (api_IP_set) err = dtn_open_with_IP(api_IP,api_port,&handle); else err = dtn_open(&handle); if (err != DTN_SUCCESS) { fprintf(stderr, "fatal error opening dtn handle: %s\n", dtn_strerror(err)); exit(1); } // ---------------------------------------------------- // initialize bundle spec with src/dest/replyto // ---------------------------------------------------- // initialize bundle spec memset(&bundle_spec, 0, sizeof(bundle_spec)); // destination host is specified at run time, demux is hardcoded sprintf(demux, "%s/dtnmoteproxy/recv", arg_dest); parse_eid(handle, &bundle_spec.dest, demux); // source is local eid with file path as demux string sprintf(demux, "/dtnmoteproxy/send"); parse_eid(handle, &bundle_spec.source, demux); // reply to is the same as the source dtn_copy_eid(&bundle_spec.replyto, &bundle_spec.source); if (debug > 2) { print_eid("source_eid", &bundle_spec.source); print_eid("replyto_eid", &bundle_spec.replyto); print_eid("dest_eid", &bundle_spec.dest); } // set the return receipt option bundle_spec.dopts |= DOPTS_DELIVERY_RCPT; // send file and wait for reply // create a new dtn registration to receive bundle status reports memset(®info, 0, sizeof(reginfo)); dtn_copy_eid(®info.endpoint, &bundle_spec.replyto); reginfo.flags = DTN_REG_DEFER; reginfo.regid = regid; reginfo.expiration = 0; if ((ret = dtn_register(handle, ®info, ®id)) != 0) { fprintf(stderr, "error creating registration (id=%d): %d (%s)\n", regid, ret, dtn_strerror(dtn_errno(handle))); exit(1); } if (debug > 3) printf("dtn_register succeeded, regid 0x%x\n", regid); while (1) { static unsigned char motedata[BUFSIZ]; int length; int ret; if (debug > 1) fprintf(dout, "about to read from motes...\n"); while((ret=read_packet((char *) motedata, (int *) &length))) { if(ret==DEBUG_PKT) continue; if (debug > 0) { fprintf(dout, "\nreader loop... got [%d] bytes from motes\n", length); if (debug > 1) hexdump(motedata, length); } // the extra cast to void* is needed to circumvent gcc warnings // about unsafe casting dataPacket=(DATAPACKET *)((void*)motedata); // skip packets from base mote if(dataPacket->origin_mote_id == 0) continue; // set a default expiration time of one hour bundle_spec.expiration = 3600; // fill in a payload memset(&send_payload, 0, sizeof(send_payload)); dtn_set_payload(&send_payload, DTN_PAYLOAD_MEM, (char *) motedata, length); memset(&bundle_id, 0, sizeof(bundle_id)); if ((ret = dtn_send(handle, regid, &bundle_spec, &send_payload, &bundle_id)) != 0) { fprintf(stderr, "error sending bundle: %d (%s)\n", ret, dtn_strerror(dtn_errno(handle))); } else fprintf(stderr, "motedata bundle sent"); printf("Mote ID = %u\n",dataPacket->origin_mote_id); printf("Source Mote ID = %u\n",dataPacket->source_mote_id); printf("Hop Count = %u\n",dataPacket->hop_cnt); printf("Packet Type = %u\n",dataPacket->surge_pkt_type); printf("Parent Address = %u\n",dataPacket->surge_parent_addr); printf("Sequence Number = %u\n", (u_int)dataPacket->surge_seq_no); printf("Light = %u\n",dataPacket->light); printf("Temperature = %u\n\n",dataPacket->temp); tcnt=(tcnt+1)%10000; } if (debug > 0) fprintf(dout, "reader loop.... nothing to do? [shouldn't happen]\n"); } // if this was ever changed to gracefully shutdown, it would be good to call: dtn_close(handle); return (1); // NOTREACHED }