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

Linux Cross Reference
cvs/emstar/link/examples/ping/dsr_ping.c


  1 /* ex: set tabstop=2 expandtab shiftwidth=2 softtabstop=2: */
  2 /*
  3  *
  4  * Copyright (c) 2003 The Regents of the University of California.  All 
  5  * rights reserved.
  6  *
  7  * Redistribution and use in source and binary forms, with or without
  8  * modification, are permitted provided that the following conditions
  9  * are met:
 10  *
 11  * - Redistributions of source code must retain the above copyright
 12  *   notice, this list of conditions and the following disclaimer.
 13  *
 14  * - Neither the name of the University nor the names of its
 15  *   contributors may be used to endorse or promote products derived
 16  *   from this software without specific prior written permission.
 17  *
 18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
 19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 21  * PARTICULAR  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 26  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 29  *
 30  */
 31  
 32 
 33 /*
 34  * ping.c: This a "ping" client, which broadcasts a 'ping' packet, and
 35  * then waits for replies from the network.  This program, and the
 36  * corresponding 'pingd' server, serve as a useful example for various
 37  * tasks:
 38  *
 39  *   - How to create an application-layer protocol format
 40  *   - How to send packets to the network
 41  *   - How to wait for and react to packets that come from the network
 42  *   - How to filter incoming packets
 43  *
 44  * $Id: dsr_ping.c,v 1.1 2007-08-13 02:16:22 allenm Exp $
 45  */
 46 
 47 char ping_c_cvsid[] = "$Id: dsr_ping.c,v 1.1 2007-08-13 02:16:22 allenm Exp $";
 48 
 49 #include <stdio.h>
 50 #include <stdlib.h>
 51 #include <sys/time.h>
 52 #include <arpa/inet.h>
 53 
 54 #include "emrun/emrun.h"
 55 #include "link/link.h"
 56 #include "ping.h"
 57 
 58 #ifndef SECOND
 59 #define SECOND  1000 
 60 #endif
 61 #define DEFAULT_STARTUP_DELAY   (20 * SECOND)
 62 
 63 
 64 /*******************************************************************/
 65 
 66 
 67 #define MAX_PINGS 1000
 68 
 69 
 70 
 71 typedef struct _wake_status {
 72   int64_t cmd_sent_timestamp;
 73   int64_t path_est_timestamp;
 74   int valid;
 75   int ping_rcvd;
 76   int sleep_state;
 77 } wake_status_t;
 78 
 79 
 80 typedef struct ping_state {
 81   int random_id;                /* our randomly selected ID, to
 82                                  * differentiate our packets from any
 83                                  * other ping processes that might be
 84                                  * happening at the same time. */
 85   int last_seqno;               /* last seqno we used */
 86   int last_seqno_rcv;           /* last seqno received (used to detect 
 87                                  * duplicates when using hbh and acks are 
 88                                  * lost) */
 89   if_id_t last_replier;         /* src address of last reply */
 90   int total_sent;               /* total pings sent */
 91   struct timeval time_sent;     /* time we sent the most recent ping */
 92   struct timeval rtt[MAX_PINGS];/* rtts of responses we've received */
 93   int num_replies;              /* number of responses we've received */
 94   int request_receipts;         /* command line arg to request receipts */
 95   lu_context_t *link;           /* link we're using to ping on */
 96   if_id_t dest;                 /* node id destination of our ping */
 97   uint32_t period;
 98   uint32_t max_pings;
 99   int logging;
100 
101   status_context_t *dsrping_status_ev;
102   status_client_context_t *wakestat_ref;
103   wake_status_t wakestatus;
104 } ping_state_t;
105 
106 
107 
108 
109 
110 int64_t get_time();
111 void record_command(char *type, uint16_t seq, ping_state_t *p);
112 void dsrping_init_status(ping_state_t *p);
113 int dsrping_status_binary(status_context_t *info, buf_t *buf);
114 int dsrping_status_printable(status_context_t *info, buf_t *buf);
115 //int dsrping_status_write(status_context_t *info, char *command, 
116 //    size_t buf_size);
117 //void mote_wakestat_open(ping_state_t *p);
118 //int handle_wakestat_input(void *new_buffer, size_t size, void *data);
119 
120 
121 #define DSRPING_STATUS_DEV_NAME   ("/dev/dsr/pingstatus")
122 //#define MOTE_WAKE_DEV_NAME        ("/dev/herd/wakestat")
123 
124 
125 /*
126 int handle_wakestat_input(void *new_buffer, size_t size, void *data)
127 {
128   free(new_buffer);
129   return EVENT_RENEW;
130 }
131 */
132 /*
133 void mote_wakestat_open(ping_state_t *p)
134 { 
135   status_client_opts_t opts = {
136     devname: sim_path(MOTE_WAKE_DEV_NAME),
137     private_data: p,
138     handler: handle_wakestat_input,
139     read_as_ascii: 0,
140     silent: 1,
141   };
142 
143   if (g_status_client_open(opts.devname, opts.handler, p, 
144         &p->wakestat_ref) < 0) {
145     elog(LOG_ERR, "Can't open status device %s: %m",
146         opts.devname);
147     exit(1);
148   }
149 }
150 */
151 
152 void dsrping_init_status(ping_state_t *p)
153 {
154   status_dev_opts_t s1_opts = {
155     device: {
156       device_info: p
157     },
158     printable: dsrping_status_printable,
159     binary: dsrping_status_binary,
160     //    write: dsrping_status_write,
161   };
162 
163   s1_opts.device.devname = sim_path(DSRPING_STATUS_DEV_NAME);
164 
165   if (g_status_dev(&s1_opts, &p->dsrping_status_ev) < 0) {
166     elog(LOG_CRIT, "Can't create status dev %s: %m",
167         s1_opts.device.devname);
168     exit(1);
169   }
170 
171 }
172 
173 
174 int dsrping_status_binary(status_context_t *info, buf_t *buf)
175 {
176   return STATUS_MSG_COMPLETE;
177 }
178 
179 
180 int dsrping_status_printable(status_context_t *info, buf_t *buf)
181 {
182   ping_state_t *p = (ping_state_t *)sd_data(info);
183   wake_status_t *ws = &p->wakestatus;
184   
185   bufprintf(buf, "Valid = %d\n", ws->valid);
186   bufprintf(buf, "Start time = %lld\n", ws->cmd_sent_timestamp);
187   bufprintf(buf, "End time = %lld\n", ws->path_est_timestamp);
188   bufprintf(buf, "Reply rcvd = %d\n", ws->ping_rcvd);
189 
190   return STATUS_MSG_COMPLETE;
191 }
192 
193 /*
194 int dsrping_status_write(status_context_t *info, char *command, 
195     size_t buf_size)
196 {
197   ping_state_t *p = (ping_state_t *)sd_data(info);
198   wake_status_t *ws = &p->wakestatus;
199 
200 
201   if (strncasecmp(command, "wakeup", strlen("wakeup")) == 0) {
202     buf_t *cmd = buf_new();
203 
204     // reset wake status
205     memset(ws, 0, sizeof(wake_status_t));
206     // set valid to 1
207     ws->valid = 1;
208 
209     // create command
210     bufprintf(cmd, "go");
211 
212     // send command
213     if (status_client_write(sim_path(MOTE_WAKE_DEV_NAME), 
214           cmd, STATUS_M_ASCII) < 0) {
215       elog(LOG_ERR, "Can't send command to status device: %m");
216       exit(1);
217     }
218 
219     buf_free(cmd);
220     // timestamp start time
221     ws->cmd_sent_timestamp = get_time();
222     g_status_dev_notify(p->dsrping_status_ev);
223   } else {
224     elog(LOG_ERR, "Got unrecognized command %s", command);
225   }
226 
227   return STATUS_WRITE_DONE;
228 }
229 */
230 
231 
232 /*******************************************************************/
233 
234 /*
235  * Callback activated when we are asked to shut down by emrun.
236  * Compute and print summary statistics of all replies received
237  */  
238 void ping_shutdown(void *data)
239 {
240   ping_state_t *p = (ping_state_t *) data;
241   struct timeval min, max, sum;
242   int i;
243 
244   if (!p->num_replies) {
245     elog_g(LOG_NOTICE, "%d pings sent, no replies received", p->total_sent);
246     goto done;
247   }
248 
249   min = max = sum = p->rtt[0];
250 
251   /* This loop finds the min and max RTTs, sums all the RTTs for
252    * average, and counts how many replies we received. */
253   for (i = 1; i < p->num_replies; i++) {
254 
255     /* misc_tv_* are convenience functions for doing computations on a
256      * struct timeval found in libmisc */
257     if (misc_tv_offset_neg(&p->rtt[i], &min) < 0)
258       min = p->rtt[i];
259     if (misc_tv_offset_neg(&p->rtt[i], &max) > 0)
260       max = p->rtt[i];
261 
262     misc_tv_add(&sum, &p->rtt[i]);
263   }
264 
265   /* compute average from the sum */
266   elog_g(LOG_NOTICE, "%d pings sent, %d replies received, "
267          "min/avg/max rtt %.1f/%.1f/%.1f ms",
268          p->total_sent, p->num_replies,
269          misc_tv_msec_f(&min),
270 
271          ((float) sum.tv_sec + (sum.tv_usec / MILLION_F)) * 1000.0 /
272          p->num_replies,
273 
274          misc_tv_msec_f(&max));
275 
276   /* Now shut down */
277  done:
278   exit(0);
279 }
280 
281 
282 /*
283  * Construct a ping packet, and send it out over the wire, using the
284  * link context stored as part of our "ping" state.
285  */
286 void ping_send(ping_state_t *p)
287 {
288   /* Allocate a small buffer for the packet */
289   char buf[200];
290   link_pkt_t *pkt = (link_pkt_t *) buf;
291   ping_pkt_t *ping_pkt = (ping_pkt_t *) pkt->data;
292   int this_seq = p->last_seqno + 1;
293  
294   /* initialize the outer header (the link_pkt header) */
295   memset(buf, 0, sizeof(buf));
296   pkt->src.id = my_node_id;
297   pkt->dst.id = p->dest;
298   pkt->type = PKT_TYPE_PING;
299 
300   /* and our application-layer (ping) protocol data */
301   ping_pkt->cmd = PING_REQUEST;
302   ping_pkt->random_id = p->random_id;
303   ping_pkt->seqno = this_seq;
304   ping_pkt->node_id = my_node_id;
305 
306   /* request a receipt.. */
307   /* if you request a receipt, you will receive back a MAC_CTRL message that tells 
308    * what happened to your packet. */
309   if (p->request_receipts)
310     link_receipt_request(pkt, NULL);
311 
312   if (p->link==NULL) {
313     elog(LOG_ERR, "Can't send pkt on a NULL link!");
314     exit(1);
315   }
316 
317   /* now launch the packet! */
318   if (lu_send(p->link, pkt, sizeof(ping_pkt_t)) < 0) {
319     if (errno != EAGAIN)
320       elog(LOG_ERR, "can't send on %s: %m", lu_name(p->link, NULL));
321   }
322   else {
323     elog(LOG_NOTICE, "send ping seqno %d to dest %s", ping_pkt->seqno,
324          print_if_id(pkt->dst.id));
325     elog(LOG_DEBUG(5), "command: %d, random id: %d, data len: %d", 
326          ping_pkt->cmd, ping_pkt->random_id, sizeof(ping_pkt_t));
327 
328     record_command("CMD_PING_REQ_SENT", ping_pkt->seqno, p);
329     
330     /* remember what time it is, so we can calculate RTT */
331     gettimeofday(&p->time_sent, NULL);
332     p->last_seqno = this_seq;
333     p->total_sent++;
334   }
335 }
336 
337 
338 /* Called every time our periodic ping timer expies.  */
339 int ping_periodic_timer(void *data, int interval, g_event_t *ev)
340 {
341   ping_state_t *p = (ping_state_t *) data;
342 
343   ping_send(p);
344 
345   return EVENT_RENEW;
346 }
347 
348 
349 
350 int startup_timer(void *data, int interval, g_event_t *ev) 
351 {
352   ping_state_t *p = (ping_state_t *)data;
353   /* Send an initial ping */
354   ping_send(p);
355 
356   /* And set a timer to send one every 'period' miliseconds */
357   g_timer_add(p->period, ping_periodic_timer, p, NULL, NULL);
358 
359   return TIMER_DONE;
360 }
361 
362 
363 /*
364  * This callback is called whenever a packet arrives on the link we
365  * opened.  "pkt" is a pointer to a link_pkt_t header followed by
366  * data_len bytes of data.  (data_len is the length of the data
367  * following the header; it doesn't include the size of the link_pkt_t
368  * header itself.)  "link" is a pointer to the link that the packet
369  * was received on, and can be used for sending a reply packet (we
370  * don't send reply packets from the receiver callback here, but see
371  * pingd for an example where we do.)
372  */
373 int ping_receiver(lu_context_t *link, link_pkt_t *link_pkt, ssize_t data_len)
374 {
375   /* flag if duplicate */
376   int duplicate=0;
377 
378   /* Get a pointer to the data portion of the packet */
379   ping_pkt_t *ping_pkt = (ping_pkt_t *) link_pkt->data;
380 
381   /* We stored a pointer to the 'ping_state' struct as the "data"
382    * field of link_opts in main().  Now, we retrieve that pointer. */
383   ping_state_t *p = (ping_state_t *) lu_data(link);
384 
385   /*
386    * Make sure the packet has the right packet type.  Since we
387    * specified the desired packet type when we registered to receive
388    * packets, this test should never fail.
389    */
390   if (link_pkt->type != PKT_TYPE_PING) {
391       if ((link_pkt->type != PKT_TYPE_MAC_CTRL) 
392           || (link_pkt->ext_type != MAC_CTRL_RECEIPT)) { 
393         elog(LOG_DEBUG(0), "got a packet not meant for us - filter failed!");
394         goto done;
395       }
396   }
397 
398   if ((link_pkt->type == PKT_TYPE_MAC_CTRL) &&
399       (link_pkt->ext_type == MAC_CTRL_RECEIPT)) {
400        
401       if (link_pkt->retval != 0) {
402           elog(LOG_ERR, "Ping to destination %d failed: %d",
403               link_pkt->dst.id, link_pkt->retval);
404 
405       }
406       goto done;
407   }
408     
409 
410 
411   /*
412    * Make sure the data portion of the packet is exactly the right
413    * size (i.e., the size of our "ping" application-layer protocol
414    * frame.
415    */
416   if (data_len != sizeof(ping_pkt_t)) {
417     elog(LOG_ERR, "got a short ping packet (%d bytes)!", data_len);
418     goto done;
419   }
420 
421   /* We now know that the data pointed to by ping_pkt is valid */
422 
423   /*
424    * Ignore everything but ping replies (i.e. ignore requests that
425    * other ping clients might be sending.)
426    */
427   if (ping_pkt->cmd != PING_REPLY) {
428     elog(LOG_DEBUG(2), "got non-reply packet - dropping");
429     goto done;
430   }
431 
432   /*
433    * Ignore replies not meant for us (based on the random ID), or that
434    * are arriving late for the previous request
435    */
436   if (ping_pkt->random_id != p->random_id ||
437       ping_pkt->seqno != p->last_seqno) {
438     elog(LOG_DEBUG(2), "dropping old or not-for-us reply packet");
439     goto done;
440   }
441 
442   /* Flag (some) duplicates that arrive due to the lost of an ack, when using
443    * a hop by hop reliable mechanism like hbh.  Will usually work using
444    * unicast pings, will sometimes work with broadcasts.
445    *
446    * NOTE: when using multihop routing *and* if the links in the path 
447    * are not very reliable, it would be possible that a later ping reply
448    * could get to us before a previous one (out of order delivery).
449    * The chances of out of order delivery increase with smaller ping 
450    * intervals and with a low reliability network.  If this is the case,
451    * you may want to maintain not just the last packet recieved but a 
452    * list (buffer) of the last X packet received, such that you can fill
453    * the holes when you have out of order delivery.  The current simple
454    * implementation detects duplicates but it does not deal with out of 
455    * order delivery.
456    */
457   if (ping_pkt->seqno < p->last_seqno_rcv ||
458       (ping_pkt->seqno == p->last_seqno_rcv &&
459        link_pkt->src.id == p->last_replier)) {
460     duplicate = 1;
461   } else { /* update state */
462     p->last_seqno_rcv = ping_pkt->seqno;  
463     p->last_replier = link_pkt->src.id;
464   }
465   
466   /*
467    * compute the roundtrip time, by subtracting the time the reply
468    * arrived from the time the original ping was sent.
469    */
470   misc_tv_sub(&link_pkt->rcv_time, &p->time_sent);
471   {
472     int offset = p->num_replies % MAX_PINGS;
473     p->rtt[offset] = link_pkt->rcv_time;
474   }
475   p->num_replies++;
476 
477   record_command("CMD_PING_REPLY_RCVD", ping_pkt->seqno, p);
478 
479  // if wakestatus is valid and we haven't received a ping yet
480   if (p->wakestatus.valid==1 && p->wakestatus.ping_rcvd==0) {
481     // set ping_rcvd to one and timestamp the event
482     p->wakestatus.ping_rcvd = 1;
483     p->wakestatus.path_est_timestamp = get_time();
484     // now notify status dev
485     g_status_dev_notify(p->dsrping_status_ev);
486   }
487 
488   elog(LOG_NOTICE, "got reply %d from node %d, iface %s, rtt %.2f ms, %d hops away %s",
489        p->num_replies,
490        ping_pkt->node_id,
491        print_if_id(link_pkt->src.id),
492        misc_tv_msec_f(&link_pkt->rcv_time),
493        PING_MAX_HOPS - link_pkt->max_hops,
494        duplicate ? "(DUP!)" : "");
495  
496   if ((p->max_pings > 0) && (p->num_replies >= p->max_pings)) {
497     elog(LOG_ALERT, "max pings exceeded; shutting down");
498     ping_shutdown(p);
499   }
500 
501  done:
502   /* note, packet must be freed! */
503   free(link_pkt);
504   return EVENT_RENEW;
505 }
506 
507 
508 void usage(char *name)
509 {
510   misc_print_usage
511     (name, "-U <device> [-f] [-i <interval>] [-p <pot value>] [-d <destination>]",
512      "  --uses <device>: Specify device to use\n"
513      "  --flood: send pings as fast as possible\n"
514      "  --interval: send pings as specified interval (ms)\n"
515      "  --pot <value>: TX potentiomenter value\n"
516      "  --dest <value>: node id destination of the pings\n"
517      "  --request_receipts: turn on receipt requests\n"
518      );
519   exit(1);
520 }
521 
522 
523 int main(int argc, char *argv[])
524 {
525   ping_state_t ping_state;
526   uint period = 1000;
527   uint startup_delay = DEFAULT_STARTUP_DELAY;
528   int pot = 0;
529   char *uses = NULL;
530  
531   emrun_opts_t emrun_opts = {
532     shutdown: ping_shutdown,
533     data: (void *) &ping_state
534   };
535 
536   /* Generic initialization common to most software */
537   misc_init(&argc, argv, CVSTAG);
538   
539   /* clean up our state variable */
540   memset(&ping_state, 0, sizeof(ping_state));
541   
542   /* get the --uses arg */
543   uses = link_parse_uses(&argc, argv, NULL);
544   if (uses == NULL) {
545     elog(LOG_CRIT, "Please specify a link to use!");
546     usage(argv[0]);
547   }
548 
549   /* ping flood option */
550   if (misc_parse_out_switch(&argc, argv, "flood", 'f'))
551     period = 10;
552 
553   /* ping interval option */
554   misc_parse_option_as_uint(&argc, argv, "interval", 'i', &period);  
555   ping_state.period = period;
556 
557   misc_parse_option_as_uint(&argc, argv, "delay", 'l', &startup_delay);
558   
559   /* ping pot option */
560   misc_parse_option_as_int(&argc, argv, "pot", 'p', &pot);
561 
562   if (misc_parse_out_switch(&argc, argv, "enable-log", 0)) {
563     ping_state.logging=1;
564   } else {
565     ping_state.logging=0;
566   }
567 
568   /* request receipt option */
569   ping_state.request_receipts = 1;
570   //ping_state.request_receipts = misc_parse_out_switch(&argc, argv, "request_receipts", 0);
571   
572   /* set default destination to broadcast */
573   ping_state.dest = LINK_BROADCAST;
574   
575   /* ping destination option */
576   char *dest_str = misc_parse_out_option(&argc, argv, "dest", 'd');
577   if (dest_str && parse_if_id(dest_str, &(ping_state.dest)) < 0) {
578     elog(LOG_CRIT, "invalid destination address: '%s'.. use 0xXX, DD, or dotted-quad",
579          dest_str);
580     exit(1);
581   }
582 
583   if (ping_state.dest==0) {
584     // 0 means don't send anything, so we just exit
585     elog(LOG_NOTICE, "Got destination 0, exiting");
586     exit(1);
587   }
588     
589   /* add'l args? */
590   if (misc_args_remain(&argc, argv)) {
591     elog(LOG_CRIT, "Additional unparsed arguments!");
592     usage(argv[0]);
593   }
594 
595   /* 
596    * Pick our random ID (a 14 bit number, from the definition of the
597    * ping packet in ping.h
598    */
599   ping_state.random_id = random_range(1, (1 << 13));
600 
601   /*
602    * Open the link-layer device.  The options struct tells it we want
603    * the ping_receiver function to be called every time a packet of
604    * type PKT_TYPE_PING arrives.
605    *
606    * If the link-opening succeeds, the link struct is returned to us
607    * using the 2nd argument (i.e., written to ping_state.link)
608    */
609   {
610     lu_opts_t lu_opts = {
611       opts: {
612         name: uses,
613         data: &ping_state,
614         // filter removed to allow for DST_UNREACHABLE replies too!
615 //      pkt_type: PKT_TYPE_PING  /* only give us ping-type packets */
616       },
617       receive: ping_receiver     /* call this func when packets arrive */
618     };
619     
620     if (lu_open(&lu_opts, &ping_state.link) < 0) {
621       elog(LOG_CRIT, "can't open %s: %m", link_name(&lu_opts.opts, NULL));
622       exit(1);
623     }
624 
625     /* Try to set the potentiometer of the radio to 'pot' */
626     // ONLY if the pot has in fact been set...no more 70ies
627     if (pot > 0) {
628       if (lu_ioctl(ping_state.link, LINK_SET_POT, &pot) < 0)
629         elog(LOG_CRIT, "warning: can't set potentiometer: %m");
630     }
631     
632     elog_g(LOG_NOTICE, "running, using %s", lu_name(ping_state.link, NULL));
633   }
634 
635   g_timer_add(startup_delay, startup_timer, &ping_state, NULL, NULL);
636 
637 #if 0
638   /* Send an initial ping */
639   ping_send(&ping_state);
640 
641   /* And set a timer to send one every 'period' miliseconds */
642   g_timer_add(period, ping_periodic_timer, &ping_state, NULL, NULL);
643 #endif
644 
645   /*
646    * Start the event loop running - it should never exit (the shutdown
647    * handler is called when the program is supposed to stop)
648    */
649 
650 
651   // init status dev
652   //  mote_wakestat_open(&ping_state);
653   dsrping_init_status(&ping_state);
654 
655   emrun_init(&emrun_opts); /* this should be the last initialization */
656   g_main();
657   elog_g(LOG_CRIT, "event loop terminated abnormally!");
658   return 0;
659 }
660 
661 
662 int64_t get_time()
663 {
664     int64_t time_now=0;
665     struct timeval now={0};
666 
667     gettimeofday(&now, NULL);
668     time_now = misc_timeval_to_int64(&now);
669 
670     return time_now;
671 }
672 
673 
674 void record_command(char *type, uint16_t seq, ping_state_t *p)
675 {
676 #if 0
677     FILE *logfile = NULL;
678     int64_t time_now=0;
679     struct timeval now={0};
680 
681     if (p->logging == 0) {
682       // logging is OFF, return
683       return;
684     }
685 
686     logfile = fopen("/scratch/latlog", "a");
687     if (logfile==NULL) {
688         elog(LOG_ERR, "Couldn't open latlog: %m");
689         exit(1);
690     }
691 
692     gettimeofday(&now, NULL);
693     time_now = misc_timeval_to_int64(&now);
694     fprintf(logfile, "%lld:%d:%s:%d:%s\n",
695             time_now,
696             my_node_id,
697             "P",
698             seq,
699             type);
700     fflush(logfile);
701     fclose(logfile);
702 #endif
703 }
704 
705 

~ [ 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.