dtncp.c

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <strings.h>
00022 #include <unistd.h>
00023 #include <errno.h>
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <sys/time.h>
00027 #include <time.h>
00028 
00029 #include "dtn_api.h"
00030 
00031 char *progname;
00032 int verbose             = 1;
00033 
00034 char data_source[1024]; // filename or message, depending on type
00035 
00036 // specified options
00037 char * arg_dest         = NULL;
00038 char * arg_target       = NULL;
00039 
00040 int    expiration_time  = 60 * 60; // default is 1 hour
00041 
00042 void parse_options(int, char**);
00043 dtn_endpoint_id_t * parse_eid(dtn_handle_t handle, dtn_endpoint_id_t * eid, 
00044                           char * str);
00045 void print_usage();
00046 void print_eid(char * label, dtn_endpoint_id_t * eid);
00047 
00048 int
00049 main(int argc, char** argv)
00050 {
00051     int ret;
00052     dtn_handle_t handle;
00053     dtn_reg_info_t reginfo;
00054     dtn_reg_id_t regid = DTN_REGID_NONE;
00055     dtn_bundle_spec_t bundle_spec;
00056     dtn_bundle_spec_t reply_spec;
00057     dtn_bundle_payload_t send_payload;
00058     dtn_bundle_payload_t reply_payload;
00059     dtn_bundle_id_t bundle_id;
00060     char demux[4096];
00061     struct timeval start, end;
00062 
00063 /*     FILE * file; */
00064 /*     //struct stat finfo; */
00065 /*     char buffer[4096]; // max filesize to send is 4096 (temp) */
00066 /*     int bufsize = 0; */
00067 
00068     // force stdout to always be line buffered, even if output is
00069     // redirected to a pipe or file
00070     setvbuf(stdout, (char *)NULL, _IOLBF, 0);
00071     
00072     parse_options(argc, argv);
00073 
00074     // open the ipc handle
00075     if (verbose) fprintf(stdout, "Opening connection to local DTN daemon\n");
00076 
00077     int err = dtn_open(&handle);
00078     if (err != DTN_SUCCESS) {
00079         fprintf(stderr, "fatal error opening dtn handle: %s\n",
00080                 dtn_strerror(err));
00081         exit(1);
00082     }
00083 
00084 
00085     // ----------------------------------------------------
00086     // initialize bundle spec with src/dest/replyto
00087     // ----------------------------------------------------
00088 
00089     // initialize bundle spec
00090     memset(&bundle_spec, 0, sizeof(bundle_spec));
00091 
00092     // destination host is specified at run time, demux is hardcoded
00093     sprintf(demux, "%s/dtncp/recv?%s", arg_dest, arg_target);
00094     parse_eid(handle, &bundle_spec.dest, demux);
00095 
00096     // source is local eid with file path as demux string
00097     sprintf(demux, "/dtncp/send?%s", data_source);
00098     parse_eid(handle, &bundle_spec.source, demux);
00099 
00100     if (verbose)
00101     {
00102         print_eid("source_eid", &bundle_spec.source);
00103         print_eid("dest_eid", &bundle_spec.dest);
00104     }
00105 
00106     // set the expiration time (one hour)
00107     bundle_spec.expiration = expiration_time;
00108     
00109     // set the return receipt option
00110     bundle_spec.dopts |= DOPTS_DELIVERY_RCPT;
00111 
00112     // fill in a payload
00113     memset(&send_payload, 0, sizeof(send_payload));
00114 
00115     dtn_set_payload(&send_payload, DTN_PAYLOAD_FILE,
00116         data_source, strlen(data_source));
00117      
00118     // send file and wait for reply
00119 
00120     // create a new dtn registration to receive bundle status reports
00121     memset(&reginfo, 0, sizeof(reginfo));
00122     dtn_copy_eid(&reginfo.endpoint, &bundle_spec.source);
00123     reginfo.failure_action = DTN_REG_DEFER;
00124     reginfo.regid = regid;
00125     reginfo.expiration = 0;
00126     if ((ret = dtn_register(handle, &reginfo, &regid)) != 0) {
00127         fprintf(stderr, "error creating registration (id=%d): %d (%s)\n",
00128                 regid, ret, dtn_strerror(dtn_errno(handle)));
00129         exit(1);
00130     }
00131     
00132     if (verbose) printf("dtn_register succeeded, regid 0x%x\n", regid);
00133 
00134     gettimeofday(&start, NULL); // timer
00135 
00136     memset(&bundle_id, 0, sizeof(bundle_id));
00137                 
00138     if ((ret = dtn_send(handle, &bundle_spec, &send_payload,
00139                         &bundle_id)) != 0) {
00140         fprintf(stderr, "error sending file bundle: %d (%s)\n",
00141                 ret, dtn_strerror(dtn_errno(handle)));
00142         exit(1);
00143     }
00144 
00145     memset(&reply_spec, 0, sizeof(reply_spec));
00146     memset(&reply_payload, 0, sizeof(reply_payload));
00147             
00148     // now we block waiting for the echo reply
00149     if ((ret = dtn_recv(handle, &reply_spec,
00150                         DTN_PAYLOAD_MEM, &reply_payload, -1)) < 0)
00151     {
00152         fprintf(stderr, "error getting reply: %d (%s)\n",
00153                 ret, dtn_strerror(dtn_errno(handle)));
00154         exit(1);
00155     }
00156     gettimeofday(&end, NULL);
00157 
00158 
00159     printf("file sent successfully to [%s]: time=%.1f ms\n",
00160                    reply_spec.source.uri,
00161                    ((double)(end.tv_sec - start.tv_sec) * 1000.0 + 
00162                     (double)(end.tv_usec - start.tv_usec)/1000.0));
00163 
00164     dtn_free_payload(&reply_payload);
00165     dtn_close(handle);
00166     
00167     return 0;
00168 }
00169 
00170 void print_usage()
00171 {
00172     fprintf(stderr,
00173             "usage: %s [--expiration sec] <filename> <destination_eid> <remote-name>\n", 
00174             progname);
00175     fprintf(stderr,
00176             "    Remote filename is optional; defaults to the "
00177             "local filename.\n\n"
00178             "Bundle expiration time is in seconds.\n");
00179     
00180     exit(1);
00181 }
00182 
00183 void parse_options(int argc, char**argv)
00184 {
00185     progname = argv[0];
00186 
00187     // expiration time in seconds
00188     if (argc < 2)
00189         goto bail;
00190 
00191     if (strcmp(argv[1], "--expiration") == 0)
00192     {
00193         argv++;
00194         argc--;
00195         
00196         if (argc < 2)
00197             goto bail;
00198         
00199         expiration_time = atoi(argv[1]);
00200         if (expiration_time == 0)
00201         {
00202             fprintf(stderr, 
00203                     "Expiration time must be > 0\n");
00204         exit(1);
00205     }
00206 
00207         argv++;
00208         argc--;
00209     }
00210 
00211     // parse the normal arguments
00212     if (argc < 3)
00213         goto bail;
00214 
00215     if (argv[1][0] == '/') sprintf(data_source, "%s", argv[1]);
00216     else sprintf(data_source, "%s/%s", getenv("PWD"), argv[1]);
00217 
00218     arg_dest = argv[2];
00219     if (argc > 3)
00220     {
00221         arg_target = argv[3];
00222     }
00223     else 
00224     {
00225         arg_target = strrchr(data_source, '/');
00226         if (arg_target == 0) arg_target = data_source;
00227     }
00228 
00229     return;
00230 
00231   bail:
00232         print_usage();
00233         exit(1);
00234 }
00235 
00236 dtn_endpoint_id_t * parse_eid(dtn_handle_t handle, 
00237                           dtn_endpoint_id_t * eid, char * str)
00238 {
00239     
00240     // try the string as an actual dtn eid
00241     if (!dtn_parse_eid_string(eid, str)) 
00242     {
00243         return eid;
00244     }
00245     // build a local eid based on the configuration of our dtn
00246     // router plus the str as demux string
00247     else if (!dtn_build_local_eid(handle, eid, str))
00248     {
00249         return eid;
00250     }
00251     else
00252     {
00253         fprintf(stderr, "invalid endpoint id string '%s'\n", str);
00254         exit(1);
00255     }
00256 }
00257 
00258 void print_eid(char *  label, dtn_endpoint_id_t * eid)
00259 {
00260     printf("%s [%s]\n", label, eid->uri);
00261 }
00262     
00263 
00264 
00265 

Generated on Thu Jun 7 16:56:49 2007 for DTN Reference Implementation by  doxygen 1.5.1