dtncp.c

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <strings.h>
00043 #include <unistd.h>
00044 #include <errno.h>
00045 #include <sys/types.h>
00046 #include <sys/stat.h>
00047 #include <sys/time.h>
00048 #include <time.h>
00049 
00050 #include "dtn_api.h"
00051 
00052 char *progname;
00053 int verbose             = 1;
00054 
00055 char data_source[1024]; // filename or message, depending on type
00056 
00057 // specified options
00058 char * arg_dest         = NULL;
00059 char * arg_target       = NULL;
00060 
00061 void parse_options(int, char**);
00062 dtn_endpoint_id_t * parse_eid(dtn_handle_t handle, dtn_endpoint_id_t * eid, 
00063                           char * str);
00064 void print_usage();
00065 void print_eid(char * label, dtn_endpoint_id_t * eid);
00066 
00067 int
00068 main(int argc, char** argv)
00069 {
00070     int ret;
00071     dtn_handle_t handle;
00072     dtn_reg_info_t reginfo;
00073     dtn_reg_id_t regid = DTN_REGID_NONE;
00074     dtn_bundle_spec_t bundle_spec;
00075     dtn_bundle_spec_t reply_spec;
00076     dtn_bundle_payload_t send_payload;
00077     dtn_bundle_payload_t reply_payload;
00078     dtn_bundle_id_t bundle_id;
00079     char demux[4096];
00080     struct timeval start, end;
00081 
00082 /*     FILE * file; */
00083 /*     //struct stat finfo; */
00084 /*     char buffer[4096]; // max filesize to send is 4096 (temp) */
00085 /*     int bufsize = 0; */
00086 
00087     // force stdout to always be line buffered, even if output is
00088     // redirected to a pipe or file
00089     setvbuf(stdout, (char *)NULL, _IOLBF, 0);
00090     
00091     parse_options(argc, argv);
00092 
00093     // open the ipc handle
00094     if (verbose) fprintf(stdout, "Opening connection to local DTN daemon\n");
00095 
00096     int err = dtn_open(&handle);
00097     if (err != DTN_SUCCESS) {
00098         fprintf(stderr, "fatal error opening dtn handle: %s\n",
00099                 dtn_strerror(err));
00100         exit(1);
00101     }
00102 
00103 
00104     // ----------------------------------------------------
00105     // initialize bundle spec with src/dest/replyto
00106     // ----------------------------------------------------
00107 
00108     // initialize bundle spec
00109     memset(&bundle_spec, 0, sizeof(bundle_spec));
00110 
00111     // destination host is specified at run time, demux is hardcoded
00112     sprintf(demux, "%s/dtncp/recv?%s", arg_dest, arg_target);
00113     parse_eid(handle, &bundle_spec.dest, demux);
00114 
00115     // source is local eid with file path as demux string
00116     sprintf(demux, "/dtncp/send?%s", data_source);
00117     parse_eid(handle, &bundle_spec.source, demux);
00118 
00119     if (verbose)
00120     {
00121         print_eid("source_eid", &bundle_spec.source);
00122         print_eid("dest_eid", &bundle_spec.dest);
00123     }
00124 
00125     // set the expiration time (one hour)
00126     bundle_spec.expiration = 3600;
00127     
00128     // set the return receipt option
00129     bundle_spec.dopts |= DOPTS_DELIVERY_RCPT;
00130 
00131     // fill in a payload
00132     memset(&send_payload, 0, sizeof(send_payload));
00133 
00134     dtn_set_payload(&send_payload, DTN_PAYLOAD_FILE,
00135         data_source, strlen(data_source));
00136      
00137     // send file and wait for reply
00138 
00139     // create a new dtn registration to receive bundle status reports
00140     memset(&reginfo, 0, sizeof(reginfo));
00141     dtn_copy_eid(&reginfo.endpoint, &bundle_spec.source);
00142     reginfo.failure_action = DTN_REG_DEFER;
00143     reginfo.regid = regid;
00144     reginfo.expiration = 0;
00145     if ((ret = dtn_register(handle, &reginfo, &regid)) != 0) {
00146         fprintf(stderr, "error creating registration (id=%d): %d (%s)\n",
00147                 regid, ret, dtn_strerror(dtn_errno(handle)));
00148         exit(1);
00149     }
00150     
00151     if (verbose) printf("dtn_register succeeded, regid 0x%x\n", regid);
00152 
00153     gettimeofday(&start, NULL); // timer
00154 
00155     memset(&bundle_id, 0, sizeof(bundle_id));
00156                 
00157     if ((ret = dtn_send(handle, &bundle_spec, &send_payload,
00158                         &bundle_id)) != 0) {
00159         fprintf(stderr, "error sending file bundle: %d (%s)\n",
00160                 ret, dtn_strerror(dtn_errno(handle)));
00161         exit(1);
00162     }
00163 
00164     memset(&reply_spec, 0, sizeof(reply_spec));
00165     memset(&reply_payload, 0, sizeof(reply_payload));
00166             
00167     // now we block waiting for the echo reply
00168     if ((ret = dtn_recv(handle, &reply_spec,
00169                         DTN_PAYLOAD_MEM, &reply_payload, -1)) < 0)
00170     {
00171         fprintf(stderr, "error getting reply: %d (%s)\n",
00172                 ret, dtn_strerror(dtn_errno(handle)));
00173         exit(1);
00174     }
00175     gettimeofday(&end, NULL);
00176 
00177 
00178     printf("file sent successfully to [%s]: time=%.1f ms\n",
00179                    reply_spec.source.uri,
00180                    ((double)(end.tv_sec - start.tv_sec) * 1000.0 + 
00181                     (double)(end.tv_usec - start.tv_usec)/1000.0));
00182 
00183     dtn_close(handle);
00184     
00185     return 0;
00186 }
00187 
00188 void print_usage()
00189 {
00190     fprintf(stderr,
00191             "usage: %s [filename] [destination_eid] "
00192             "[remote-name]\n", progname);
00193     fprintf(stderr,
00194             "    Remote filename is optional; defaults to the "
00195             "local filename.\n");
00196     
00197     exit(1);
00198 }
00199 
00200 void parse_options(int argc, char**argv)
00201 {
00202     progname = argv[0];
00203 
00204     if (argc < 3)
00205     {
00206         print_usage();
00207         exit(1);
00208     }
00209 
00210     if (argv[1][0] == '/') sprintf(data_source, "%s", argv[1]);
00211     else sprintf(data_source, "%s/%s", getenv("PWD"), argv[1]);
00212 
00213     arg_dest = argv[2];
00214     if (argc > 3)
00215     {
00216         arg_target = argv[3];
00217     }
00218     else 
00219     {
00220         arg_target = strrchr(data_source, '/');
00221         if (arg_target == 0) arg_target = data_source;
00222     }
00223 }
00224 
00225 dtn_endpoint_id_t * parse_eid(dtn_handle_t handle, 
00226                           dtn_endpoint_id_t * eid, char * str)
00227 {
00228     
00229     // try the string as an actual dtn eid
00230     if (!dtn_parse_eid_string(eid, str)) 
00231     {
00232         return eid;
00233     }
00234     // build a local eid based on the configuration of our dtn
00235     // router plus the str as demux string
00236     else if (!dtn_build_local_eid(handle, eid, str))
00237     {
00238         return eid;
00239     }
00240     else
00241     {
00242         fprintf(stderr, "invalid endpoint id string '%s'\n", str);
00243         exit(1);
00244     }
00245 }
00246 
00247 void print_eid(char *  label, dtn_endpoint_id_t * eid)
00248 {
00249     printf("%s [%s]\n", label, eid->uri);
00250 }
00251     
00252 
00253 
00254 

Generated on Fri Dec 22 14:47:58 2006 for DTN Reference Implementation by  doxygen 1.5.1