dtnmoteproxy.c

Go to the documentation of this file.
00001 /*
00002  *    Copyright 1996-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 /*
00019  * moteproxy: a DTN <-> mote proxying app, intended for use with GSK
00020  *   for MICA-2, use 57600 baud rate
00021  */
00022 
00023 /* Modified to recognize Mote-PC protocol -- Mark Thomas (23/06/04) 
00024  * Now uses serialsource.c to communicate with serial port 
00025  * Files: crc16.c, misc.c, mote_io.c and mote_io.h are not used anymore */
00026 
00027 
00028 #include <sys/types.h>
00029 #include <signal.h>
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <unistd.h>
00033 #include <getopt.h>
00034 #include <fcntl.h>
00035 #include <string.h>
00036 #include "serialsource.h"
00037 
00038 #include <strings.h>
00039 #include <errno.h>
00040 #include <sys/stat.h>
00041 #include <sys/time.h>
00042 #include <time.h>
00043 
00044 #include <oasys/compat/inttypes.h>
00045 
00046 #include "dtn_api.h"
00047  
00048 #define dout    stderr
00049 
00050 #include <ctype.h>
00051 
00052 char *progname;
00053 
00054 static char *msgs[] = {
00055   "unknown_packet_type",
00056   "ack_timeout" ,
00057   "sync"        ,
00058   "too_long"    ,
00059   "too_short"   ,
00060   "bad_sync"    ,
00061   "bad_crc"     ,
00062   "closed"      ,
00063   "no_memory"   ,
00064   "unix_error"
00065 };
00066 
00067 typedef struct data_packet
00068 {
00069     // MultiHop Header 
00070     u_int16_t source_mote_id;
00071     u_int16_t origin_mote_id;
00072     u_int16_t seq_no;
00073     u_int8_t hop_cnt;
00074 
00075     // Surge Sensor Header 
00076     u_int8_t surge_pkt_type;
00077     u_int16_t surge_reading;
00078     u_int16_t surge_parent_addr;
00079     u_int32_t surge_seq_no;
00080     u_int8_t light;
00081     u_int8_t temp;
00082     u_int8_t magx;
00083     u_int8_t magy;
00084     u_int8_t accelx;
00085     u_int8_t accely;
00086 
00087 }DATAPACKET;
00088 
00089 #define DATAPACKET_SIZE 22
00090 #define SURGE_PKT       0x11
00091 #define DEBUG_PKT       0x03
00092 
00093 void parse_options(int, char**);
00094 dtn_endpoint_id_t * parse_eid(dtn_handle_t handle, dtn_endpoint_id_t * eid, 
00095                           char * str);
00096 void print_usage();
00097 void print_eid(char * label, dtn_endpoint_id_t * eid);
00098 void init_motes();
00099 void stderr_msg(serial_source_msg problem);
00100 void usage(char *str1, char *str2);
00101 void readCommandLineArgs(int argc, char **argv);
00102 void hexdump();
00103 void read_packet_file(char* filename);
00104 
00105 // specified options
00106 char arg_dest[128];
00107 char arg_target[128];
00108 
00109 char devicename[128] = "/dev/ttyS0";
00110 char baud[128] = "57600";
00111 char directory[128]="send";
00112 u_int32_t debug = 0;             // higher values cause more info to print
00113 serial_source src;
00114 
00115 int g_argc;
00116 char **g_argv;
00117 
00118 int
00119 main(int argc, char **argv)
00120 {
00121     /* save in case of crash */
00122     g_argc = argc;
00123     g_argv = argv;
00124 
00125     readCommandLineArgs(argc, argv);
00126     init_motes();
00127 
00128     // NOTREACHED 
00129     return (EXIT_FAILURE);      // should never get here 
00130 }
00131 
00132 void stderr_msg(serial_source_msg problem)
00133 {
00134   fprintf(stderr, "Note: %s\n", msgs[problem]);
00135 }
00136 
00137 int read_packet(char *buf, int *n)
00138 {
00139     const char *buff;
00140     int i;
00141     
00142     if (debug > 0) fprintf(stdout, "Reading packet:\n");
00143     
00144     if(!(buff = read_serial_packet(src, n)))
00145         return 0;
00146 
00147     if (debug > 0) fprintf(stdout, " ==> : ");
00148     for (i = 0; i < buff[4]; i++)
00149         printf(" %02x", buff[i]);
00150     putchar('\n');
00151 
00152    
00153     // strip TOS header & copy to buf 
00154     memset(buf,0,BUFSIZ);
00155     memcpy(buf,buff,buff[4]+5);
00156     *n=buff[4] + 5;
00157     if(buff[2]==SURGE_PKT || buff[2]==DEBUG_PKT) return buff[2];
00158     return -1;
00159 }
00160 
00161 int
00162 reader_thread(void *p)
00163 {
00164 
00165     // loop reading from motes, writing to directory
00166 
00167     static int tcnt=0;
00168     DATAPACKET *dataPacket;
00169 
00170     // dtn api variables
00171     int ret;
00172     dtn_handle_t handle;
00173     dtn_reg_info_t reginfo;
00174     dtn_reg_id_t regid = DTN_REGID_NONE;
00175     dtn_bundle_spec_t bundle_spec;
00176     dtn_bundle_payload_t send_payload;
00177     dtn_bundle_id_t bundle_id;
00178     char demux[4096];
00179 
00180     p = NULL;
00181 
00182     // open the ipc handle
00183     if (debug > 0) fprintf(stdout, "Opening connection to local DTN daemon\n");
00184 
00185     int err = dtn_open(&handle);
00186     if (err != DTN_SUCCESS) {
00187         fprintf(stderr, "fatal error opening dtn handle: %s\n",
00188                 dtn_strerror(err));
00189         exit(1);
00190     }
00191 
00192     // ----------------------------------------------------
00193     // initialize bundle spec with src/dest/replyto
00194     // ----------------------------------------------------
00195 
00196     // initialize bundle spec
00197     memset(&bundle_spec, 0, sizeof(bundle_spec));
00198 
00199     // destination host is specified at run time, demux is hardcoded
00200     sprintf(demux, "%s/dtnmoteproxy/recv", arg_dest);
00201     parse_eid(handle, &bundle_spec.dest, demux);
00202 
00203     // source is local eid with file path as demux string
00204     sprintf(demux, "/dtnmoteproxy/send");
00205     parse_eid(handle, &bundle_spec.source, demux);
00206 
00207     // reply to is the same as the source
00208     dtn_copy_eid(&bundle_spec.replyto, &bundle_spec.source);
00209 
00210 
00211     if (debug > 2)
00212     {
00213         print_eid("source_eid", &bundle_spec.source);
00214         print_eid("replyto_eid", &bundle_spec.replyto);
00215         print_eid("dest_eid", &bundle_spec.dest);
00216     }
00217 
00218     // set the return receipt option
00219     bundle_spec.dopts |= DOPTS_DELIVERY_RCPT;
00220 
00221     // send file and wait for reply
00222 
00223     // create a new dtn registration to receive bundle status reports
00224     memset(&reginfo, 0, sizeof(reginfo));
00225     dtn_copy_eid(&reginfo.endpoint, &bundle_spec.replyto);
00226     reginfo.failure_action = DTN_REG_DEFER;
00227     reginfo.regid = regid;
00228     reginfo.expiration = 0;
00229     if ((ret = dtn_register(handle, &reginfo, &regid)) != 0) {
00230         fprintf(stderr, "error creating registration (id=%d): %d (%s)\n",
00231                 regid, ret, dtn_strerror(dtn_errno(handle)));
00232         exit(1);
00233     }
00234     
00235     if (debug > 3) printf("dtn_register succeeded, regid 0x%x\n", regid);
00236 
00237     while (1) {
00238         static unsigned char motedata[BUFSIZ];
00239         int length;
00240         int ret;
00241 
00242         if (debug > 1) fprintf(dout, "about to read from motes...\n");
00243 
00244         while((ret=read_packet((char *) motedata, (int *) &length))){
00245             if(ret==DEBUG_PKT)
00246                 continue;
00247             if (debug > 0) {
00248                 fprintf(dout, "\nreader loop... got [%d] bytes from motes\n", 
00249                         length);
00250                 if (debug > 1) hexdump(motedata, length);
00251             }
00252             
00253             dataPacket=(DATAPACKET *)(motedata);
00254             
00255             // skip packets from base mote 
00256             if(dataPacket->origin_mote_id == 0) continue;
00257 
00258             // set a default expiration time of one hour
00259             bundle_spec.expiration = 3600;
00260             
00261             // fill in a payload
00262             memset(&send_payload, 0, sizeof(send_payload));
00263 
00264             dtn_set_payload(&send_payload, DTN_PAYLOAD_MEM,
00265                             (char *) motedata, length);
00266  
00267             memset(&bundle_id, 0, sizeof(bundle_id));
00268                         
00269             if ((ret = dtn_send(handle, &bundle_spec, &send_payload,
00270                                 &bundle_id)) != 0)
00271             {
00272                 fprintf(stderr, "error sending bundle: %d (%s)\n",
00273                         ret, dtn_strerror(dtn_errno(handle)));
00274             }   
00275             else fprintf(stderr, "motedata bundle sent");
00276 
00277             printf("Mote ID = %u\n",dataPacket->origin_mote_id);
00278             printf("Source Mote ID = %u\n",dataPacket->source_mote_id);
00279             printf("Hop Count = %u\n",dataPacket->hop_cnt);
00280             printf("Packet Type = %u\n",dataPacket->surge_pkt_type);
00281             printf("Parent Address = %u\n",dataPacket->surge_parent_addr);
00282             printf("Sequence Number = %u\n", (u_int)dataPacket->surge_seq_no);
00283             printf("Light = %u\n",dataPacket->light);
00284             printf("Temperature = %u\n\n",dataPacket->temp);        
00285 
00286             tcnt=(tcnt+1)%10000;
00287           
00288         }
00289         if (debug > 0)
00290             fprintf(dout, "reader loop.... nothing to do? [shouldn't happen]\n");
00291     }
00292 
00293     // if this was ever changed to gracefully shutdown, it would be good to call:
00294     dtn_close(handle);
00295     
00296     return (1);
00297     // NOTREACHED 
00298 }
00299 
00300 
00301 void
00302 readCommandLineArgs(int argc, char **argv)
00303 {
00304     int c;
00305 
00306     while ((c = getopt(argc, argv, "hr:d:b:D:t:")) != EOF) {
00307         switch (c) {
00308         case 'h':
00309             usage("moteproxy", "");
00310             exit(0);
00311             break;
00312         case 'r':
00313             read_packet_file(optarg);
00314             exit(0);
00315         case 'd':
00316             debug = atoi(optarg);
00317             break;
00318         case 'b':
00319             strcpy(baud, optarg);
00320             break;
00321         case 't':
00322             strcpy(devicename, optarg);
00323             break;
00324         case 'D':
00325             strcpy(arg_dest,optarg);
00326             break;              
00327         default:
00328             fprintf(stderr, "mfproxy: unknown option: '%c'\n", (char) c);
00329             usage("moteproxy", "");
00330             exit(EXIT_FAILURE);
00331         }
00332     }
00333 }
00334 
00335 void
00336 usage(char *str1, char *str2)
00337 {
00338     (void)str2;
00339     
00340     fprintf(stderr, "usage: %s\n", str1);
00341     fprintf(stderr, "  [-b baudrate]     - baud rate\n");
00342     fprintf(stderr, "  [-t devicename]      - name of mote network dev tty\n");
00343     fprintf(stderr, "  [-d debugValue]\n");
00344     fprintf(stderr, "  [-D directory]\n");
00345     fprintf(stderr, "  [-h]              - print this message.\n");
00346     fprintf(stderr, "\n");
00347 }
00348 
00349 
00350 // initialize the motes
00351 void
00352 init_motes()
00353 {
00354     src = open_serial_source(devicename, atoi(baud), 0, stderr_msg);
00355 
00356     if(reader_thread(NULL) == 1) {
00357         fprintf(stderr, "couldn't start reader on mote network\n");
00358         exit(EXIT_FAILURE);
00359     }
00360     return;
00361 }
00362 
00363 void read_packet_file(char* filename)
00364 {
00365     int fd = open(filename, O_RDONLY);
00366     static unsigned char buf[BUFSIZ];
00367     int n = read(fd, buf, BUFSIZ);
00368     hexdump(buf, n);
00369 }
00370 
00371 void
00372 hexdump(unsigned char *buf, int n)
00373 {
00374     int i;
00375     unsigned char *p = buf;
00376 
00377     fprintf(dout,"Packet contains %d:\n",n);
00378     for (i = 0; i < n; i++) {
00379         fprintf(dout,"%02x ", *p++);
00380         if ((i & 0x7) == 0x7)
00381             fprintf(dout,"\n");
00382     }
00383     printf("\n\n");
00384     fflush(stdout);
00385 }
00386 
00387 dtn_endpoint_id_t * parse_eid(dtn_handle_t handle, 
00388                           dtn_endpoint_id_t * eid, char * str)
00389 {
00390     
00391     // try the string as an actual dtn eid
00392     if (!dtn_parse_eid_string(eid, str)) 
00393     {
00394         return eid;
00395     }
00396     // build a local eid based on the configuration of our dtn
00397     // router plus the str as demux string
00398     else if (!dtn_build_local_eid(handle, eid, str))
00399     {
00400         return eid;
00401     }
00402     else
00403     {
00404         fprintf(stderr, "invalid eid string '%s'\n", str);
00405         exit(1);
00406     }
00407 }
00408 
00409 void print_eid(char* label, dtn_endpoint_id_t* eid)
00410 {
00411     printf("%s [%s]\n", label, eid->uri);
00412 }
00413     

Generated on Sat Sep 8 08:36:16 2007 for DTN Reference Implementation by  doxygen 1.5.3