N-sim
Emulation and simulation of
Wireless Sensor Networks



   Home


   Project Page


   Download


   CVS



   Installation


   Configuration


   Plug-ins




 Hosted by
SourceForge.net Logo

/home/brennan/n-sim/Vaike/linux/system-addons/networking/sensor_mesh_daemon.c

Go to the documentation of this file.
00001 
00014 /*
00015  * Copyright 2007. Los Alamos National Security, LLC. This material
00016  * was produced under U.S. Government contract DE-AC52-06NA25396 for
00017  * Los Alamos National Laboratory (LANL), which is operated by Los
00018  * Alamos National Security, LLC, for the Department of Energy. The
00019  * U.S. Government has rights to use, reproduce, and distribute this
00020  * software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY,
00021  * LLC, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
00022  * LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified to
00023  * produce derivative works, such modified software should be clearly
00024  * marked, so as not to confuse it with the version available from LANL.
00025  *
00026  * Additionally, this program is free software; you can redistribute
00027  * it and/or modify it under the terms of the GNU General Public
00028  * License as published by the Free Software Foundation; version 2 of
00029  * the License. Accordingly, this program is distributed in the hope
00030  * it will be useful, but WITHOUT ANY WARRANTY; without even the
00031  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00032  * PURPOSE. See the GNU General Public License for more details.
00033  */
00034 
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <unistd.h>
00038 #include <string.h>
00039 #include <sys/types.h>
00040 #include <sys/socket.h>
00041 #include <sys/ioctl.h>
00042 #include <sys/stat.h>
00043 #include <fcntl.h>
00044 #include <netinet/in.h>
00045 #include <arpa/inet.h>
00046 #include <net/if.h>
00047 #include <syslog.h>
00048 #include <signal.h>
00049 #include <pthread.h>
00050 #include <errno.h>
00051 
00052 #include "sensor_self.h"
00053 #include "mesh_metrics.h"
00054 #include "mesh_discovery.h"
00055 #include "mesh_neighbor.h"
00056 #include "mesh_net.h"
00057 #include "mesh_ipc.h"
00058 #include "mesh_on_demand.h"
00059 
00060 #ifdef DEBUG
00061 # include "sigsegv.h"
00062 #endif
00063 
00064 
00065 #define MESH_APPLICATION        "sensormeshd"
00066 #define MESH_VERSION            "0.3"
00067 
00068 #define error(...) do { \
00069   fprintf(stderr, "%s (%s:%d) ", MESH_APPLICATION, __FUNCTION__, __LINE__); \
00070   fprintf(stderr, __VA_ARGS__); \
00071   fprintf(stderr, ".\n"); \
00072 } while (0)
00073 
00074 
00075 void *run_echo(void *arg)
00076 {
00077   self_t *self = (self_t*)arg;
00078   if (self == NULL)
00079     return NULL;
00080   echo_statistics(self);
00081   return NULL;  
00082 }
00083 
00084 
00085 void *run_statistics(void *arg)
00086 {
00087   self_t *self = (self_t*)arg;
00088   if (self == NULL)
00089     return NULL;
00090   gather_statistics(self);
00091   return NULL;  
00092 }
00093 
00094 
00095 void *run_controller(void *arg)
00096 {
00097   self_t *self = (self_t*)arg;
00098   if (self == NULL)
00099     return NULL;
00100   mesh_ioserv(self);
00101   return NULL;
00102 }
00103 
00104 
00105 void *discover_neighbors(void *arg)
00106 {
00107   self_t *self = (self_t*)arg;
00108   if (self == NULL)
00109     return NULL;
00110   neighbor_discovery(self);
00111   return NULL;
00112 }
00113 
00114 
00115 void *semi_reliability(void *arg)
00116 {
00117   self_t *self = (self_t*)arg;
00118   if (self == NULL)
00119     return NULL;
00120   reliable_net(self);
00121   return NULL;
00122 }
00123 
00124 
00125 void *start_on_demand(void *arg)
00126 {
00127   self_t *self = (self_t*)arg;
00128   if (self == NULL)
00129     return NULL;
00130   on_demand(self);
00131   return NULL;
00132 }
00133 
00134 
00135 void *on_demand_timeouts(void *arg)
00136 {
00137   self_t *self = (self_t*)arg;
00138   if (self == NULL)
00139     return NULL;
00140   packet_usage(self);
00141   return NULL;
00142 }
00143 
00144 
00145 
00146 
00147 static void daemonize(char *device)
00148 {
00149   int fd;
00150   struct sigaction sa;
00151         
00152   if (setreuid(0, 0) < 0) {
00153     fprintf(stderr, "Root access required\n");
00154     exit(-1);
00155   }
00156 
00157   if (fork()) 
00158     exit(0); 
00159         
00160   fd = open("/dev/null", O_RDWR);
00161   dup2(fd, 0); dup2(fd, 1); dup2(fd, 2);
00162   close(fd);
00163         
00164   setsid();
00165   chdir("/");
00166 
00167   openlog(MESH_APPLICATION, LOG_CONS | LOG_PID | LOG_NDELAY | LOG_PERROR,
00168           LOG_DAEMON);
00169   syslog(LOG_INFO, "%s v%s started on %s.",
00170          MESH_APPLICATION, MESH_VERSION, device);
00171 
00172   memset(&sa, 0, sizeof(sa));
00173   sa.sa_handler = SIG_IGN;
00174   sigaction(SIGCHLD, &sa, NULL);
00175 }
00176 
00177 
00178 int main(int argc, char *argv[])
00179 {
00180   pthread_t stats, echo, control;
00181   int fd, i, rc;
00182   char *address = NULL;
00183   struct ifreq ifr;
00184   self_t myself;
00185   protocol_t *cur;
00186 
00187 #ifdef DEBUG
00188   setup_sigsegv();
00189 #endif
00190   init_self(&myself);
00191 
00192   if (argc < 2 || argc > 5) {
00193   usage:
00194     fprintf(stderr, "Usage: %s [-g] [-a address] [-p lat:lon:alt] interface\n",
00195             argv[0]);
00196     exit(-1);
00197   }
00198   for (i = 1; i < argc; i++) {
00199     // TODO: accept arg for battery state
00200     if (strncmp("-g", argv[i], 2) == 0)
00201       myself.isa_gateway = 1;
00202     if (strncmp("-a", argv[i], 2) == 0)
00203       address = argv[++i];
00204     if (strncmp("-p", argv[i], 2) == 0) {
00205       if (sscanf(argv[++i], "%lf:%lf:%lf",
00206                  &myself.latitude, &myself.longitude, &myself.altitude) < 3)
00207         goto usage;
00208       // TODO: interface with gpsd
00209     }
00210     else if (strcmp("", argv[i]) != 0)
00211       myself.interface = argv[i];
00212   }
00213   if (myself.interface == NULL) {
00214     error("no network interface given");
00215     exit(-1);
00216   }
00217 
00218   fd = socket(PF_INET, SOCK_DGRAM, 0);
00219   strcpy(ifr.ifr_name, myself.interface);
00220 
00221   if (address != NULL)
00222     strncpy(myself.ip_addr, address, NET_ADDR_LEN);
00223   else {
00224     ifr.ifr_addr.sa_family = AF_INET;
00225     if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
00226       error("network interface \"%s\" not found (%s)",
00227               myself.interface, strerror(errno));
00228       exit(-1);
00229     }
00230     strcpy(myself.ip_addr,
00231            inet_ntoa(((struct sockaddr_in*)(&ifr.ifr_addr))->sin_addr));
00232 
00233     if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0) {
00234       error("error retrieving broadcast address (%s)",
00235               strerror(errno));
00236       exit(-1);
00237     }
00238     strcpy(myself.broadcast,
00239            inet_ntoa(((struct sockaddr_in*)(&ifr.ifr_addr))->sin_addr));
00240 
00241     if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0) {
00242       error("error retrieving netmask (%s)",
00243               strerror(errno));
00244       exit(-1);
00245     }
00246     strcpy(myself.netmask,
00247            inet_ntoa(((struct sockaddr_in*)(&ifr.ifr_addr))->sin_addr));
00248   }
00249   close(fd);
00250 
00251   daemonize(myself.interface);
00252 
00253 #ifdef DEBUG
00254   syslog(LOG_INFO, "configuration for %s: addr=%s, bcast=%s, netmask=%s",
00255          myself.interface, myself.ip_addr, myself.broadcast, myself.netmask);
00256 #endif
00257   /*
00258   if ((rc = pthread_create(&echo, NULL, run_echo, &myself)) < 0) {
00259     syslog(LOG_ERR, "echo statistics: %m");
00260     exit(-1);
00261   }
00262   if ((rc = pthread_create(&stats, NULL, run_statistics, &myself)) < 0) {
00263     syslog(LOG_ERR, "gather statistics: %m");
00264     exit(-1);
00265   }
00266   */
00267   if ((rc = pthread_create(&control, NULL, run_controller, &myself)) < 0) {
00268     syslog(LOG_ERR, "control server: %m");
00269     exit(-1);
00270   }
00271 
00272   cur = myself.protocols;
00273   while (cur != NULL) {
00274     pthread_join(cur->discover_thread, NULL);
00275     cur = cur->next;
00276   }
00277   pthread_join(stats, NULL);
00278   pthread_join(echo, NULL);
00279   pthread_join(control, NULL);
00280   return 0;
00281 }


© 2007, Los Alamos National Security, LLC.