~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
cvs/emstar/devel/mm/stream/medsensor_dbconnect.c


  1 #include <sys/socket.h>
  2 #include <sys/types.h>
  3 #include <sys/time.h>
  4 #include <asm/types.h>
  5 #include <arpa/inet.h>
  6 #include <linux/if_packet.h>
  7 #include <linux/if_ether.h>   /* The L2 protocols */
  8 #include <linux/if_arp.h>
  9 
 10 #include <libdev/packet_dev.h>
 11 #include <link/link.h>
 12 #include <medsensor.h>
 13 #include <string.h>
 14 
 15 // for db
 16 #include <stdio.h>
 17 #include <stdlib.h>
 18 #include "libpq-fe.h" // for libpq
 19 
 20 // for options
 21 #include <getopt.h>
 22 
 23 // for my e-mail hack
 24 #include <sys/time.h>
 25 #include <time.h>
 26 
 27 // local #defines
 28 #define TEMP_BUFFER_SIZE         1024
 29 #define DEFAULT_PROXY_LOCATION   "Office, John"
 30 
 31 typedef struct {
 32   // for the database connection
 33   char conninfo[TEMP_BUFFER_SIZE];
 34   PGconn     *conn;
 35   PGresult   *res;
 36   char *database_name; // database name
 37   char *proxy_location; // location of the proxy
 38 } database_state_t;
 39 
 40 typedef struct {
 41   pd_client_context_t* pdc_ref;  // to connect to packet device
 42   status_context_t *status_ref; // status device context
 43   database_state_t dbinfo; // information about the connection to the backend
 44   char *iface_name; // pointer to the interface name
 45 } medsensor_db_ctx_t;
 46 
 47 
 48 static int medsensor_db_print(status_context_t *info, buf_t *buf);
 49 static int medsensor_pktdev_recv(void *data, ssize_t len, pd_client_context_t *pd_client);
 50 static char *get_mac_addr(char *iface_name, char *macaddr /* output addr */);
 51 static char *get_ip(char *interface, char *ip_addr /* output addr */);
 52 
 53 static void
 54 exit_nicely(PGconn *conn)
 55 {
 56   PQfinish(conn);
 57   exit(1);
 58 }
 59 
 60 // status device callbacks
 61 static 
 62 int medsensor_db_print(status_context_t *info, buf_t *buf)
 63 {
 64   bufprintf(buf, "medsensor_dbconnect: alive\n");
 65   return STATUS_MSG_COMPLETE;
 66 }
 67 
 68 /* TO RECEIVE data from the named packet device client */
 69 static 
 70 int medsensor_pktdev_recv(void *data, ssize_t len, pd_client_context_t *pd_client)
 71 {
 72   medsensor_db_ctx_t *medsensor_db_state = (medsensor_db_ctx_t *) pdc_data(pd_client);
 73   medsensor_temp_pkt_t *med_pkt = (medsensor_temp_pkt_t *) data;
 74   database_state_t *dbinfo = &(medsensor_db_state->dbinfo);
 75 
 76   PGconn     *conn = dbinfo->conn;
 77   PGresult   *res;
 78 
 79   char command[1024]; // more hardcoded stuff
 80   char mac_addr[100]; // mac address
 81   char ip_addr[100]; // mac address
 82   char timebuf[100]; // for storing the time
 83 
 84 /*   // for timestamping */
 85 /*   static struct timeval curr_time, last_time, diff_time; */
 86 
 87 /*   // check the time */
 88 /*  curr_time = med_pkt->rcv_time; */
 89 /*   if(timerisset(&last_time)) { */
 90 /*     timersub(&curr_time, &last_time, &diff_time); */
 91 /*     elog(LOG_NOTICE, "seconds elapsed: %lu\n", diff_time.tv_sec); */
 92 /*   } else { */
 93 /*     last_time = curr_time; */
 94 /*   } */
 95 
 96 /*   // copy the data over into my local buffer */
 97 /*   // hardcoded hack */
 98   strftime(timebuf, 100, "%F %T", localtime(&(med_pkt->rcv_time.tv_sec)));
 99   sprintf(timebuf, "%s.%ld", timebuf, med_pkt->rcv_time.tv_usec);
100   char *proxy_time = &timebuf[0];
101 
102 /*   if(diff_time.tv_sec >= (30 * 60)) { */
103 /*     FILE *remindfile; */
104 /*     if((remindfile = fopen("remindfile", "w")) == NULL) { */
105 /*       sprintf(temp_buf, "Could not open %s", "/root/remindfile"); */
106 /*       perror(temp_buf); */
107 /*       goto out; */
108 /*     } */
109     
110     
111 /*     fprintf(remindfile, "Time: %s\n", timebuf); */
112 /*     fprintf(remindfile, "Sensor Type: Temp, "); */
113 /*     fprintf(remindfile, "Sensor Value: %d, ", med_pkt->dataValue); */
114 /*     fprintf(remindfile, "Sample Number: %d\n", med_pkt->sampleNumber); */
115 /*     fprintf(remindfile, "Mote ID Number: %d\n", med_pkt->moteSrcId); */
116 /*     fprintf(remindfile, "\nWhat were you doing during this sample?\n"); */
117 /*     fclose(remindfile); */
118 
119 /*     // execute my script */
120 /*     if(system("devel/mm/stream/testtabs/mail-remind.pl remindfile dcurtis@csail.mit.edu") < 0) { */
121 /*       perror("mail-remind.pl failed"); */
122 /*       goto out; */
123 /*     } */
124 /*   } */
125 
126   /* 
127   sensor_type text,    -- a constant enum identifying sensor type
128   sensor_value integer,  -- value returned by this sensor
129   sample_number integer, -- lets us know if samples were dropped
130   mote_id     integer,   -- id of the mote
131   proxy_id    macaddr,   -- MAC address of the device
132   proxy_time  timestamp with time zone, 
133   proxy_location text -- readable name of current location of proxy
134   */
135   // another hack, only send the data if the database and the sensor id's match
136 
137   elog(LOG_NOTICE, "moteSrcId: %d, Database Name: %s\n", med_pkt->moteSrcId, dbinfo->database_name);
138 
139   if((dbinfo->database_name != NULL) && 
140      ((med_pkt->moteSrcId < 100 &&
141       strcmp(dbinfo->database_name, "med_db0") == 0) ||
142      (med_pkt->moteSrcId >= 100 && med_pkt->moteSrcId < 200 &&
143       strcmp(dbinfo->database_name, "med_db1") == 0) ||
144      (med_pkt->moteSrcId >= 200 && med_pkt->moteSrcId < 300 &&
145       strcmp(dbinfo->database_name, "med_db2") == 0))) {
146 
147     sprintf(command, "INSERT INTO rawtest0 (sensor_type, sensor_value,sample_number, mote_id, proxy_id, proxy_time, proxy_location, ip_addr) VALUES ('%s',%d,%d,%d,'%s','%s','%s', '%s');",
148             "Temp",
149             med_pkt->dataValue, 
150             med_pkt->sampleNumber, 
151             med_pkt->moteSrcId, 
152             get_mac_addr(medsensor_db_state->iface_name, mac_addr),
153             proxy_time, 
154             dbinfo->proxy_location,
155             get_ip(medsensor_db_state->iface_name, ip_addr)
156             );
157     elog(LOG_NOTICE, "Executing [%s]\n", command); 
158     
159     if(dbinfo->database_name != NULL) {
160       res = PQexec(conn, command);
161       if (PQresultStatus(res) != PGRES_COMMAND_OK) {
162         fprintf(stderr, "INSERT failed: %s", PQerrorMessage(conn));
163         PQclear(res);
164         exit_nicely(conn);
165       }
166       PQclear(res);
167     }
168   }
169 
170   // out:  
171   /* free buffer and packet */
172   free(data);
173   return EVENT_RENEW;
174 }
175   
176 /* 
177  * Shutdown handler 
178  */
179 static
180 void medsensor_db_shutdown(void *data)
181 {
182   elog(LOG_NOTICE, " MedSensor DB Connect Client is shutting down\n");
183   exit(0);
184 }
185 
186 void usage(const char *s)
187 {
188   fprintf(stderr, 
189           "Usage: %s --interface <device it is using> --database <name of database> --location <device location>\n"
190           "\n",
191           s);
192   exit(1);
193 }
194 
195 int
196 main(int argc, char *argv[]) 
197 {
198 
199   // for the options
200   int c;
201   char *iface_name = NULL;
202   char *database_name = NULL;
203   char *location = NULL;
204 
205 /*   int digit_optind = 0; */
206 
207   medsensor_db_ctx_t medsensor_db_state = {};
208   PGconn *conn;
209 
210   /* emrun will trigger this callback to run on shutdown */
211   emrun_opts_t emrun_opts = {
212     shutdown: medsensor_db_shutdown,
213     data: &medsensor_db_state // don't know why this is here;
214   };
215 
216   // process options
217   while(1) {
218     /*     int this_option_optind = optind ? optind : 1; */
219     int option_index = 0;
220     static struct option long_options[] = {
221       {"database", 1, 0, 0},
222       {"interface", 1, 0, 0},
223       {"location", 1, 0, 0},
224     };
225 
226     c = getopt_long(argc, argv, "d:i:l:", long_options, &option_index);
227     if (c == -1) {
228       break;
229     }
230     
231     switch (c) {
232     case 'd':
233       database_name = optarg;
234       elog(LOG_NOTICE, "database = %s", optarg);
235       break;
236     case 'i':
237       iface_name = optarg;
238       elog(LOG_NOTICE, "interface = %s", optarg);
239       break;
240     case 'l':
241       location = optarg;
242       elog(LOG_NOTICE, "location = %s", optarg);
243       break;
244     default:
245       elog(LOG_CRIT, "unrecognized option 0%o ??\n", c);
246       exit(1);
247     }
248   }
249 
250   if (optind < argc) {
251     elog(LOG_NOTICE, "unrecognized options: ");      
252     while(optind < argc) {
253       elog(LOG_NOTICE, "%s", argv[optind++]);
254     }
255     usage(argv[0]);
256   }
257   
258   if(iface_name == NULL) {
259     usage(argv[0]);
260   }
261 
262   if(location == NULL) {
263     location = DEFAULT_PROXY_LOCATION;    
264     elog(LOG_NOTICE, "location = %s", location);
265   }
266 
267   // fill in the db_state data structure
268   medsensor_db_state.iface_name = iface_name;
269   medsensor_db_state.dbinfo.proxy_location = location;
270   medsensor_db_state.dbinfo.database_name = database_name;
271 
272   if(database_name != NULL) {
273     sprintf(medsensor_db_state.dbinfo.conninfo, "host=18.31.0.20 dbname=%s user=med_user0 password=pcn13579", database_name);
274     medsensor_db_state.dbinfo.conn = PQconnectdb(medsensor_db_state.dbinfo.conninfo);
275     conn = medsensor_db_state.dbinfo.conn; // for convenience
276     // open the link to the database
277     elog(LOG_NOTICE, "Opening database connection, %s", medsensor_db_state.dbinfo.conninfo);
278     
279     /* Check to see that the backend connection was successfully made */
280     if (PQstatus(conn) != CONNECTION_OK) {
281       fprintf(stderr, "Connection to database '%s' failed.\n", PQdb(conn));
282       fprintf(stderr, "%s", PQerrorMessage(conn));
283       exit_nicely(conn);
284     }
285   }
286   
287   // setup the interface to the packet device
288   {
289     pd_client_opts_t pdc_opts = {
290       devname: MEDSENSOR_PACKET_DEV, // device name of the packet device?
291       receive: medsensor_pktdev_recv,
292       data: &medsensor_db_state
293     };
294     
295     elog(LOG_NOTICE, "opening pktdev from client");
296     
297     /* Open the link */
298     if (pd_client_open(&pdc_opts, &(medsensor_db_state.pdc_ref)) < 0) {
299       elog(LOG_CRIT, "Unable to open pktdev %s: %m", pdc_opts.devname);
300       exit(1);
301     }
302   }
303   
304   // setup status device
305   {
306     status_dev_opts_t status_opts = {
307       device: {
308         devname: MEDSENSOR_DB_STATUS_DEV,
309         device_info: &medsensor_db_state
310       },
311       printable: medsensor_db_print
312     };
313     
314     if(g_status_dev(&status_opts, &(medsensor_db_state.status_ref)) < 0) {
315       elog(LOG_CRIT, "Unable to create status device: %m");
316       exit(1);
317     }
318   }
319   
320   emrun_init(&emrun_opts);
321   g_main();
322   elog(LOG_ALERT, "event system terminated abnormally");
323   return 1;
324   
325 }
326 
327 static char *
328 get_mac_addr(char *iface_name, char *mac_addr /* output addr */) 
329 {
330   int s; // socket 
331   struct ifreq buffer;
332   char tempbuf[TEMP_BUFFER_SIZE]; // temporary storage
333   
334   s = socket(PF_INET, SOCK_DGRAM, 0);
335   if(s < 0) {
336     elog(LOG_CRIT, "Could not open socket!");
337     exit(1);
338   }
339   
340   memset(&buffer, 0, sizeof(buffer));
341   snprintf(buffer.ifr_name, sizeof(buffer.ifr_name), "%s", iface_name);
342   if (ioctl(s, SIOCGIFHWADDR, &buffer) != 0) {
343     elog(LOG_CRIT, "ioctl(SIOCGIFHWADDR)");
344     sprintf(tempbuf, "%s\n", buffer.ifr_name);
345     perror(tempbuf);
346     close(s);
347     exit(1);
348   }
349   
350   mac_addr[0] = 0;
351   close(s);
352   for(s = 0; s < 6; s++) { // length of mac address
353     sprintf(tempbuf, "%.2X:", (unsigned char)buffer.ifr_hwaddr.sa_data[s]);
354     strcat(mac_addr, tempbuf);
355   }
356   mac_addr[strlen(mac_addr) - 1] = 0; // get rid of last :
357 
358   return mac_addr;
359 }
360 
361 
362 static 
363 char* get_ip(char* interface, char* buf) {
364 
365   int s;
366   struct ifreq ifr;
367 
368   /* ----------------------------------------------- */
369   /* Check buffer sanity                             */
370   /* ----------------------------------------------- */
371   if ( !buf ) return 0;
372   buf[0] = 0;
373 
374   /* ----------------------------------------------- */
375   /* Open a socket to get access to ioctl functions  */
376   /* ----------------------------------------------- */
377   s = socket(AF_INET,SOCK_DGRAM,0);
378   if(s < 0) {
379     elog(LOG_CRIT, "Could not open socket!");
380     exit(1);
381   }
382 
383   /* ----------------------------------------------- */
384   /* Grab the eth0 interface info                    */
385   /* ----------------------------------------------- */
386   bzero((void*)(&ifr.ifr_name),sizeof(ifr.ifr_name));
387   strncpy(ifr.ifr_name,interface,sizeof(ifr.ifr_name));
388   if ( ioctl(s,SIOCGIFADDR,&ifr) != 0 ) {
389     close(s);
390     return 0;
391   }
392   close(s);
393 
394   strcpy(buf,inet_ntoa((*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr));
395 
396   return buf;
397 }
398 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.