dtnmoteproxy.c

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

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