aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-07-25 18:02:46 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-07-25 18:02:46 +0000
commit29f73bb496a579a5a7600b3e3b2ab88b859bee65 (patch)
tree8752fcdd559c54c31b84cd0ba7dddd09cad37a5e
parent30752e6cb73b6c71ad5aab392c40ac482257e410 (diff)
downloadgnunet-29f73bb496a579a5a7600b3e3b2ab88b859bee65.tar.gz
gnunet-29f73bb496a579a5a7600b3e3b2ab88b859bee65.zip
sensor: towards update functionality
-rw-r--r--src/include/gnunet_protocols.h10
-rw-r--r--src/include/gnunet_sensor_util_lib.h46
-rw-r--r--src/sensor/gnunet-service-sensor-update.c298
-rw-r--r--src/sensor/gnunet-service-sensor.c43
-rw-r--r--src/sensor/sensor_util_lib.c39
-rw-r--r--src/sensordashboard/gnunet-service-sensordashboard.c141
6 files changed, 503 insertions, 74 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index a95c0107a..4063b2efd 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2438,6 +2438,16 @@ extern "C"
2438 */ 2438 */
2439#define GNUNET_MESSAGE_TYPE_SENSOR_BRIEF 806 2439#define GNUNET_MESSAGE_TYPE_SENSOR_BRIEF 806
2440 2440
2441/**
2442 * Request for full sensor information
2443 */
2444#define GNUNET_MESSAGE_TYPE_SENSOR_FULL_REQ 807
2445
2446/**
2447 * Full sensor information
2448 */
2449#define GNUNET_MESSAGE_TYPE_SENSOR_FULL 808
2450
2441 2451
2442/******************************************************************************* 2452/*******************************************************************************
2443 * PEERSTORE message types 2453 * PEERSTORE message types
diff --git a/src/include/gnunet_sensor_util_lib.h b/src/include/gnunet_sensor_util_lib.h
index 1e5108d29..a9651bc1b 100644
--- a/src/include/gnunet_sensor_util_lib.h
+++ b/src/include/gnunet_sensor_util_lib.h
@@ -258,10 +258,56 @@ struct GNUNET_SENSOR_SensorBriefMessage
258 258
259}; 259};
260 260
261/**
262 * Used to communicate full information about a sensor.
263 */
264struct GNUNET_SENSOR_SensorFullMessage
265{
266
267 /**
268 * GNUNET general message header.
269 */
270 struct GNUNET_MessageHeader header;
271
272 /**
273 * Size of the config file carrying full sensor information.
274 * Allocated at position 0 after this struct.
275 */
276 uint16_t cfg_size;
277
278 /**
279 * Name of the file (usually script) associated with this sensor.
280 * At the moment we only support having one file since that's all our sensors
281 * need at the moment.
282 * The file name is allocated at position 1 after this struct.
283 */
284 uint16_t scriptname_size;
285
286 /**
287 * Size of the file (usually script) associated with this sensor.
288 * The file binary is allocated at position 2 after this struct.
289 */
290 uint16_t script_size;
291
292};
293
261GNUNET_NETWORK_STRUCT_END 294GNUNET_NETWORK_STRUCT_END
262 295
263 296
264/** 297/**
298 * Given two version numbers as major and minor, compare them.
299 *
300 * @param v1_major First part of first version number
301 * @param v1_minor Second part of first version number
302 * @param v2_major First part of second version number
303 * @param v2_minor Second part of second version number
304 */
305int
306GNUNET_SENSOR_version_compare (uint16_t v1_major, uint16_t v1_minor,
307 uint16_t v2_major, uint16_t v2_minor);
308
309
310/**
265 * Reads sensor definitions from local data files 311 * Reads sensor definitions from local data files
266 * 312 *
267 * @return a multihashmap of loaded sensors 313 * @return a multihashmap of loaded sensors
diff --git a/src/sensor/gnunet-service-sensor-update.c b/src/sensor/gnunet-service-sensor-update.c
index b5d31626d..4cbe26b5b 100644
--- a/src/sensor/gnunet-service-sensor-update.c
+++ b/src/sensor/gnunet-service-sensor-update.c
@@ -44,6 +44,29 @@
44 44
45 45
46/** 46/**
47 * Message queued to be sent to an update point stored in a DLL
48 */
49struct PendingMessage
50{
51
52 /**
53 * DLL
54 */
55 struct PendingMessage *prev;
56
57 /**
58 * DLL
59 */
60 struct PendingMessage *next;
61
62 /**
63 * Actual queued message
64 */
65 struct GNUNET_MessageHeader *msg;
66
67};
68
69/**
47 * Sensors update point 70 * Sensors update point
48 */ 71 */
49struct UpdatePoint 72struct UpdatePoint
@@ -70,9 +93,19 @@ struct UpdatePoint
70 struct GNUNET_CADET_Channel *ch; 93 struct GNUNET_CADET_Channel *ch;
71 94
72 /** 95 /**
73 * CADET transmit handle for a sensor list request. 96 * CADET transmit handle for a message to be sent to update point.
97 */
98 struct GNUNET_CADET_TransmitHandle *th;
99
100 /**
101 * Head of DLL of pending requests to be sent to update point.
102 */
103 struct PendingMessage *pm_head;
104
105 /**
106 * Tail of DLL of pending requests to be sent to update point.
74 */ 107 */
75 struct GNUNET_CADET_TransmitHandle *sensor_list_req_th; 108 struct PendingMessage *pm_tail;
76 109
77 /** 110 /**
78 * Are we waiting for a sensor list? 111 * Are we waiting for a sensor list?
@@ -80,6 +113,11 @@ struct UpdatePoint
80 int expecting_sensor_list; 113 int expecting_sensor_list;
81 114
82 /** 115 /**
116 * How many sensor updates did we request and are waiting for.
117 */
118 int expected_sensor_updates;
119
120 /**
83 * Did a failure occur while dealing with this update point before? 121 * Did a failure occur while dealing with this update point before?
84 */ 122 */
85 int failed; 123 int failed;
@@ -93,6 +131,11 @@ struct UpdatePoint
93static const struct GNUNET_CONFIGURATION_Handle *cfg; 131static const struct GNUNET_CONFIGURATION_Handle *cfg;
94 132
95/** 133/**
134 * Hashmap of known sensors
135 */
136static struct GNUNET_CONTAINER_MultiHashMap *sensors;
137
138/**
96 * Head of update points DLL. 139 * Head of update points DLL.
97 */ 140 */
98static struct UpdatePoint *up_head; 141static struct UpdatePoint *up_head;
@@ -115,7 +158,7 @@ static struct GNUNET_CADET_Handle *cadet;
115/** 158/**
116 * Are we in the process of checking and updating sensors? 159 * Are we in the process of checking and updating sensors?
117 */ 160 */
118static int updating; //TODO: when done, set to #GNUNET_NO and destroy channel 161static int updating;
119 162
120 163
121/** 164/**
@@ -128,6 +171,13 @@ static void
128check_for_updates (void *cls, 171check_for_updates (void *cls,
129 const struct GNUNET_SCHEDULER_TaskContext *tc); 172 const struct GNUNET_SCHEDULER_TaskContext *tc);
130 173
174/**
175 * Trigger sending next pending message to the default update point if any.
176 *
177 */
178static void
179trigger_send_next_msg ();
180
131 181
132/** 182/**
133 * Cleanup update point context. This does not destroy the struct itself. 183 * Cleanup update point context. This does not destroy the struct itself.
@@ -137,10 +187,22 @@ check_for_updates (void *cls,
137static void 187static void
138cleanup_updatepoint (struct UpdatePoint *up) 188cleanup_updatepoint (struct UpdatePoint *up)
139{ 189{
140 if (NULL != up->sensor_list_req_th) 190 struct PendingMessage *pm;
191
192 up->expecting_sensor_list = GNUNET_NO;
193 up->expected_sensor_updates = 0;
194 if (NULL != up->th)
195 {
196 GNUNET_CADET_notify_transmit_ready_cancel (up->th);
197 up->th = NULL;
198 }
199 pm = up->pm_head;
200 while (NULL != pm)
141 { 201 {
142 GNUNET_CADET_notify_transmit_ready_cancel (up->sensor_list_req_th); 202 GNUNET_CONTAINER_DLL_remove (up->pm_head, up->pm_tail, pm);
143 up->sensor_list_req_th = NULL; 203 GNUNET_free (pm->msg);
204 GNUNET_free (pm);
205 pm = up->pm_head;
144 } 206 }
145 if (NULL != up->ch) 207 if (NULL != up->ch)
146 { 208 {
@@ -217,7 +279,7 @@ fail ()
217 * to queue more data. @a buf will be NULL and @a size zero if the 279 * to queue more data. @a buf will be NULL and @a size zero if the
218 * connection was closed for writing in the meantime. 280 * connection was closed for writing in the meantime.
219 * 281 *
220 * Writes the sensor list request to be sent to the update point. 282 * Perform the actual sending of the message to update point.
221 * 283 *
222 * @param cls closure (unused) 284 * @param cls closure (unused)
223 * @param size number of bytes available in @a buf 285 * @param size number of bytes available in @a buf
@@ -225,30 +287,75 @@ fail ()
225 * @return number of bytes written to @a buf 287 * @return number of bytes written to @a buf
226 */ 288 */
227static size_t 289static size_t
228do_send_sensor_list_req (void *cls, size_t size, void *buf) 290do_send_msg (void *cls, size_t size, void *buf)
229{ 291{
230 struct GNUNET_MessageHeader *msg; 292 struct PendingMessage *pm;
231 size_t msg_size; 293 size_t msg_size;
232 294
233 LOG (GNUNET_ERROR_TYPE_DEBUG, 295 up_default->th = NULL;
234 "Sending sensor list request now.\n"); 296 pm = up_default->pm_head;
235 up_default->sensor_list_req_th = NULL; 297 msg_size = ntohs (pm->msg->size);
236 if (NULL == buf) 298 GNUNET_CONTAINER_DLL_remove (up_default->pm_head, up_default->pm_tail, pm);
299 if (NULL == buf || size < msg_size)
237 { 300 {
301 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
302 _("Error trying to send a message to update point `%s'.\n"),
303 GNUNET_i2s (&up_default->peer_id));
238 fail (); 304 fail ();
239 return 0; 305 return 0;
240 } 306 }
241 msg = GNUNET_new (struct GNUNET_MessageHeader); 307 memcpy (buf, pm->msg, msg_size);
242 msg_size = sizeof (struct GNUNET_MessageHeader); 308 GNUNET_free (pm->msg);
243 msg->size = htons (msg_size); 309 GNUNET_free (pm);
244 msg->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_LIST_REQ); 310 trigger_send_next_msg ();
245 memcpy (buf, msg, msg_size);
246 up_default->expecting_sensor_list = GNUNET_YES;
247 return msg_size; 311 return msg_size;
248} 312}
249 313
250 314
251/** 315/**
316 * Trigger sending next pending message to the default update point if any.
317 *
318 */
319static void
320trigger_send_next_msg ()
321{
322 struct PendingMessage *pm;
323
324 if (NULL == up_default->pm_head)
325 return;
326 if (NULL != up_default->th)
327 return;
328 pm = up_default->pm_head;
329 up_default->th =
330 GNUNET_CADET_notify_transmit_ready (up_default->ch,
331 GNUNET_YES,
332 GNUNET_TIME_UNIT_FOREVER_REL,
333 ntohs (pm->msg->size),
334 &do_send_msg,
335 NULL);
336}
337
338
339/**
340 * Add a message to the queue to be sent to the current default update point.
341 *
342 * @param msg Message to be queued
343 */
344static void
345queue_msg (struct GNUNET_MessageHeader *msg)
346{
347 struct PendingMessage *pm;
348
349 pm = GNUNET_new (struct PendingMessage);
350 pm->msg = msg;
351 GNUNET_CONTAINER_DLL_insert_tail (up_default->pm_head,
352 up_default->pm_tail,
353 pm);
354 trigger_send_next_msg ();
355}
356
357
358/**
252 * Contact update points to check for new updates 359 * Contact update points to check for new updates
253 * 360 *
254 * @param cls unused 361 * @param cls unused
@@ -258,6 +365,9 @@ static void
258check_for_updates (void *cls, 365check_for_updates (void *cls,
259 const struct GNUNET_SCHEDULER_TaskContext *tc) 366 const struct GNUNET_SCHEDULER_TaskContext *tc)
260{ 367{
368 struct GNUNET_MessageHeader *msg;
369 size_t msg_size;
370
261 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 371 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
262 return; 372 return;
263 if (GNUNET_YES == updating) 373 if (GNUNET_YES == updating)
@@ -290,12 +400,12 @@ check_for_updates (void *cls,
290 return; 400 return;
291 } 401 }
292 /* Start by requesting list of sensors available from update point */ 402 /* Start by requesting list of sensors available from update point */
293 up_default->sensor_list_req_th = 403 up_default->expecting_sensor_list = GNUNET_YES;
294 GNUNET_CADET_notify_transmit_ready (up_default->ch, 404 msg = GNUNET_new (struct GNUNET_MessageHeader);
295 GNUNET_YES, 405 msg_size = sizeof (struct GNUNET_MessageHeader);
296 GNUNET_TIME_UNIT_FOREVER_REL, 406 msg->size = htons (msg_size);
297 sizeof (struct GNUNET_MessageHeader), 407 msg->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_LIST_REQ);
298 &do_send_sensor_list_req, NULL); 408 queue_msg (msg);
299 GNUNET_SCHEDULER_add_delayed (SENSOR_UPDATE_CHECK_INTERVAL, 409 GNUNET_SCHEDULER_add_delayed (SENSOR_UPDATE_CHECK_INTERVAL,
300 &check_for_updates, NULL); 410 &check_for_updates, NULL);
301} 411}
@@ -353,8 +463,9 @@ load_update_points ()
353 up = GNUNET_new (struct UpdatePoint); 463 up = GNUNET_new (struct UpdatePoint);
354 up->peer_id.public_key = public_key; 464 up->peer_id.public_key = public_key;
355 up->ch = NULL; 465 up->ch = NULL;
356 up->sensor_list_req_th = NULL; 466 up->th = NULL;
357 up->expecting_sensor_list = GNUNET_NO; 467 up->expecting_sensor_list = GNUNET_NO;
468 up->expected_sensor_updates = 0;
358 up->failed = GNUNET_NO; 469 up->failed = GNUNET_NO;
359 GNUNET_CONTAINER_DLL_insert (up_head, up_tail, up); 470 GNUNET_CONTAINER_DLL_insert (up_head, up_tail, up);
360 LOG (GNUNET_ERROR_TYPE_DEBUG, 471 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -366,6 +477,38 @@ load_update_points ()
366 477
367 478
368/** 479/**
480 * Checks if the given sensor name and version (retrieved from an update point)
481 * is new for us and we would like to install it. This is the case if we don't
482 * have this sensor or we have an old version of it.
483 *
484 * @param sensorname Sensor name
485 * @param sensorversion_major First part of version number
486 * @param sensorversion_minor Second part of version number
487 * @return #GNUNET_YES if we don't have this sensor
488 * #GNUNET_NO if we have it
489 */
490static int
491update_required (char *sensorname,
492 uint16_t sensorversion_major,
493 uint16_t sensorversion_minor)
494{
495 struct GNUNET_HashCode key;
496 struct GNUNET_SENSOR_SensorInfo *local_sensor;
497
498 GNUNET_CRYPTO_hash (sensorname, strlen (sensorname) + 1, &key);
499 local_sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &key);
500 if (NULL == local_sensor)
501 return GNUNET_YES;
502 if (GNUNET_SENSOR_version_compare (local_sensor->version_major,
503 local_sensor->version_minor,
504 sensorversion_major,
505 sensorversion_minor) < 0)
506 return GNUNET_YES;
507 return GNUNET_NO;
508}
509
510
511/**
369 * Handler of a sensor list message received from an update point. 512 * Handler of a sensor list message received from an update point.
370 * 513 *
371 * @param cls Closure (unused). 514 * @param cls Closure (unused).
@@ -382,24 +525,49 @@ handle_sensor_brief (void *cls,
382 const struct GNUNET_MessageHeader *message) 525 const struct GNUNET_MessageHeader *message)
383{ 526{
384 struct GNUNET_SENSOR_SensorBriefMessage *sbm; 527 struct GNUNET_SENSOR_SensorBriefMessage *sbm;
528 struct GNUNET_MessageHeader *pull_req;
529 uint16_t version_major;
530 uint16_t version_minor;
531 uint16_t msg_size;
385 532
386 GNUNET_assert (*channel_ctx == up_default); 533 GNUNET_assert (*channel_ctx == up_default);
387 GNUNET_assert (GNUNET_YES == up_default->expecting_sensor_list); 534 if (GNUNET_YES != up_default->expecting_sensor_list)
535 {
536 GNUNET_break_op (0);
537 fail ();
538 return GNUNET_OK;
539 }
388 if (GNUNET_MESSAGE_TYPE_SENSOR_END == ntohs (message->type)) 540 if (GNUNET_MESSAGE_TYPE_SENSOR_END == ntohs (message->type))
389 { 541 {
390 up_default->expecting_sensor_list = GNUNET_NO; 542 up_default->expecting_sensor_list = GNUNET_NO;
391 //TODO: cleanup 543 if (0 == up_default->expected_sensor_updates)
392 updating = GNUNET_NO; //FIXME: should not be here, only for testing 544 {
545 updating = GNUNET_NO;
546 cleanup_updatepoint (up_default);
547 return GNUNET_OK;
548 }
393 } 549 }
394 else 550 else
395 { 551 {
396 sbm = (struct GNUNET_SENSOR_SensorBriefMessage *)message; 552 sbm = (struct GNUNET_SENSOR_SensorBriefMessage *)message;
397 LOG (GNUNET_ERROR_TYPE_DEBUG, 553 version_major = ntohs (sbm->version_major);
398 "Sensor brief: %.*s %d.%d\n", 554 version_minor = ntohs (sbm->version_minor);
399 ntohs (sbm->name_size), 555 if (GNUNET_YES == update_required ((char *)&sbm[1],
400 &sbm[1], 556 version_major,
401 ntohs (sbm->version_major), 557 version_minor))
402 ntohs (sbm->version_minor)); 558 {
559 LOG (GNUNET_ERROR_TYPE_INFO,
560 "Requesting sensor %s %d.%d from update point.\n",
561 &sbm[1], version_major, version_minor);
562 /* We duplicate the same msg received but change the type and send it
563 * back to update point to ask for full sensor information. */
564 msg_size = ntohs (message->size);
565 pull_req = GNUNET_malloc (msg_size);
566 memcpy (pull_req, message, msg_size);
567 pull_req->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_FULL_REQ);
568 queue_msg (pull_req);
569 up_default->expected_sensor_updates ++;
570 }
403 } 571 }
404 GNUNET_CADET_receive_done (channel); 572 GNUNET_CADET_receive_done (channel);
405 return GNUNET_OK; 573 return GNUNET_OK;
@@ -407,6 +575,58 @@ handle_sensor_brief (void *cls,
407 575
408 576
409/** 577/**
578 * Handler of a sensor list message received from an update point.
579 *
580 * @param cls Closure (unused).
581 * @param channel Connection to the other end.
582 * @param channel_ctx Place to store local state associated with the channel.
583 * @param message The actual message.
584 * @return #GNUNET_OK to keep the channel open,
585 * #GNUNET_SYSERR to close it (signal serious error).
586 */
587static int
588handle_sensor_full (void *cls,
589 struct GNUNET_CADET_Channel *channel,
590 void **channel_ctx,
591 const struct GNUNET_MessageHeader *message)
592{
593 struct GNUNET_SENSOR_SensorFullMessage *sfm;
594 uint16_t msg_size;
595
596 /* error check */
597 GNUNET_assert (*channel_ctx == up_default);
598 msg_size = ntohs (message->size);
599 if (up_default->expected_sensor_updates <= 0 ||
600 msg_size < sizeof (struct GNUNET_SENSOR_SensorFullMessage))
601 {
602 GNUNET_break_op (0);
603 fail ();
604 return GNUNET_OK;
605 }
606 /* parse received msg */
607 sfm = (struct GNUNET_SENSOR_SensorFullMessage *)message;
608 LOG (GNUNET_ERROR_TYPE_INFO,
609 "Received full sensor info:\n"
610 "File size: %d\n"
611 "Script name size: %d\n"
612 "Script size: %d.\n",
613 ntohs (sfm->cfg_size),
614 ntohs (sfm->scriptname_size),
615 ntohs (sfm->script_size));
616 //TODO: do the actual update
617 up_default->expected_sensor_updates --;
618 if (0 == up_default->expected_sensor_updates)
619 {
620 updating = GNUNET_NO;
621 cleanup_updatepoint (up_default);
622 }
623 else
624 GNUNET_CADET_receive_done (channel);
625 return GNUNET_OK;
626}
627
628
629/**
410 * Function called whenever a channel is destroyed. Should clean up 630 * Function called whenever a channel is destroyed. Should clean up
411 * any associated state. 631 * any associated state.
412 * 632 *
@@ -424,8 +644,6 @@ cadet_channel_destroyed (void *cls,
424{ 644{
425 struct UpdatePoint *up = channel_ctx; 645 struct UpdatePoint *up = channel_ctx;
426 646
427 LOG (GNUNET_ERROR_TYPE_DEBUG,
428 "CADET Channel destroyed callback triggered.\n");
429 up->ch = NULL; 647 up->ch = NULL;
430 if (GNUNET_YES == updating) 648 if (GNUNET_YES == updating)
431 { 649 {
@@ -445,16 +663,18 @@ cadet_channel_destroyed (void *cls,
445 */ 663 */
446int 664int
447SENSOR_update_start (const struct GNUNET_CONFIGURATION_Handle *c, 665SENSOR_update_start (const struct GNUNET_CONFIGURATION_Handle *c,
448 struct GNUNET_CONTAINER_MultiHashMap *sensors) 666 struct GNUNET_CONTAINER_MultiHashMap *s)
449{ 667{
450 static struct GNUNET_CADET_MessageHandler cadet_handlers[] = { 668 static struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
451 {&handle_sensor_brief, GNUNET_MESSAGE_TYPE_SENSOR_BRIEF, 0}, 669 {&handle_sensor_brief, GNUNET_MESSAGE_TYPE_SENSOR_BRIEF, 0},
452 {&handle_sensor_brief, GNUNET_MESSAGE_TYPE_SENSOR_END, 0}, 670 {&handle_sensor_brief, GNUNET_MESSAGE_TYPE_SENSOR_END, 0},
671 {&handle_sensor_full, GNUNET_MESSAGE_TYPE_SENSOR_FULL, 0},
453 {NULL, 0, 0} 672 {NULL, 0, 0}
454 }; 673 };
455 674
456 GNUNET_assert(NULL != sensors); 675 GNUNET_assert(NULL != s);
457 cfg = c; 676 cfg = c;
677 sensors = s;
458 cadet = GNUNET_CADET_connect(cfg, 678 cadet = GNUNET_CADET_connect(cfg,
459 NULL, 679 NULL,
460 NULL, 680 NULL,
diff --git a/src/sensor/gnunet-service-sensor.c b/src/sensor/gnunet-service-sensor.c
index 1092e4a2f..e476db50c 100644
--- a/src/sensor/gnunet-service-sensor.c
+++ b/src/sensor/gnunet-service-sensor.c
@@ -212,9 +212,10 @@ handle_get_sensor (void *cls,
212 * @param key hash of sensor name, key to hashmap 212 * @param key hash of sensor name, key to hashmap
213 * @param value a `struct GNUNET_SENSOR_SensorInfo *` 213 * @param value a `struct GNUNET_SENSOR_SensorInfo *`
214 */ 214 */
215int add_sensor_to_tc (void *cls, 215static int
216 const struct GNUNET_HashCode *key, 216add_sensor_to_tc (void *cls,
217 void *value) 217 const struct GNUNET_HashCode *key,
218 void *value)
218{ 219{
219 struct GNUNET_SERVER_TransmitContext *tc = cls; 220 struct GNUNET_SERVER_TransmitContext *tc = cls;
220 struct GNUNET_SENSOR_SensorInfo *sensorinfo = value; 221 struct GNUNET_SENSOR_SensorInfo *sensorinfo = value;
@@ -291,11 +292,12 @@ should_run_sensor(struct GNUNET_SENSOR_SensorInfo *sensorinfo)
291 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not 292 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
292 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration 293 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
293 */ 294 */
294int sensor_statistics_iterator (void *cls, 295static int
295 const char *ss, 296sensor_statistics_iterator (void *cls,
296 const char *name, 297 const char *ss,
297 uint64_t value, 298 const char *name,
298 int is_persistent) 299 uint64_t value,
300 int is_persistent)
299{ 301{
300 struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls; 302 struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls;
301 double dvalue = (double)value; 303 double dvalue = (double)value;
@@ -323,7 +325,8 @@ int sensor_statistics_iterator (void *cls,
323 * @param success #GNUNET_OK if statistics were 325 * @param success #GNUNET_OK if statistics were
324 * successfully obtained, #GNUNET_SYSERR if not. 326 * successfully obtained, #GNUNET_SYSERR if not.
325 */ 327 */
326void end_sensor_run_stat (void *cls, int success) 328static void
329end_sensor_run_stat (void *cls, int success)
327{ 330{
328 struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls; 331 struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls;
329 332
@@ -376,7 +379,8 @@ parse_sensor_value (const char *value,
376 * @param cls `struct GNUNET_SENSOR_SensorInfo *` 379 * @param cls `struct GNUNET_SENSOR_SensorInfo *`
377 * @param line line of output from a command, NULL for the end 380 * @param line line of output from a command, NULL for the end
378 */ 381 */
379void sensor_process_callback (void *cls, const char *line) 382static void
383sensor_process_callback (void *cls, const char *line)
380{ 384{
381 struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls; 385 struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls;
382 void *value; 386 void *value;
@@ -445,9 +449,9 @@ is_path(char *filename)
445 * @param cls 'struct SensorInfo' 449 * @param cls 'struct SensorInfo'
446 * @param tc unsed 450 * @param tc unsed
447 */ 451 */
448void 452static void
449sensor_run (void *cls, 453sensor_run (void *cls,
450 const struct GNUNET_SCHEDULER_TaskContext * tc) 454 const struct GNUNET_SCHEDULER_TaskContext * tc)
451{ 455{
452 struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls; 456 struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls;
453 int check_result; 457 int check_result;
@@ -493,11 +497,12 @@ sensor_run (void *cls,
493 //search in sensor directory 497 //search in sensor directory
494 sensors_dir = GNUNET_SENSOR_get_sensor_dir (); 498 sensors_dir = GNUNET_SENSOR_get_sensor_dir ();
495 GNUNET_free(process_path); 499 GNUNET_free(process_path);
496 GNUNET_asprintf(&process_path, "%s%s-files%s%s", 500 GNUNET_asprintf(&process_path,
497 sensors_dir, 501 "%s%s-files%s%s",
498 sensorinfo->name, 502 sensors_dir,
499 DIR_SEPARATOR_STR, 503 sensorinfo->name,
500 sensorinfo->ext_process); 504 DIR_SEPARATOR_STR,
505 sensorinfo->ext_process);
501 GNUNET_free(sensors_dir); 506 GNUNET_free(sensors_dir);
502 check_result = 507 check_result =
503 GNUNET_OS_check_helper_binary(process_path, GNUNET_NO, NULL); 508 GNUNET_OS_check_helper_binary(process_path, GNUNET_NO, NULL);
@@ -541,8 +546,8 @@ sensor_run (void *cls,
541 * iterate, 546 * iterate,
542 * #GNUNET_NO if not. 547 * #GNUNET_NO if not.
543 */ 548 */
544int schedule_sensor(void *cls, 549static int
545 const struct GNUNET_HashCode *key, void *value) 550schedule_sensor (void *cls, const struct GNUNET_HashCode *key, void *value)
546{ 551{
547 struct GNUNET_SENSOR_SensorInfo *sensorinfo = value; 552 struct GNUNET_SENSOR_SensorInfo *sensorinfo = value;
548 553
diff --git a/src/sensor/sensor_util_lib.c b/src/sensor/sensor_util_lib.c
index b77ba48fc..0302c2046 100644
--- a/src/sensor/sensor_util_lib.c
+++ b/src/sensor/sensor_util_lib.c
@@ -295,23 +295,26 @@ load_sensor_from_file(const char *filename)
295 return sensor; 295 return sensor;
296} 296}
297 297
298
298/** 299/**
299 * Compares version numbers of two sensors 300 * Given two version numbers as major and minor, compare them.
300 * 301 *
301 * @param s1 first sensor 302 * @param v1_major First part of first version number
302 * @param s2 second sensor 303 * @param v1_minor Second part of first version number
303 * @return 1: s1 > s2, 0: s1 == s2, -1: s1 < s2 304 * @param v2_major First part of second version number
305 * @param v2_minor Second part of second version number
304 */ 306 */
305static int 307int
306sensor_version_compare (struct GNUNET_SENSOR_SensorInfo *s1, 308GNUNET_SENSOR_version_compare (uint16_t v1_major, uint16_t v1_minor,
307 struct GNUNET_SENSOR_SensorInfo *s2) 309 uint16_t v2_major, uint16_t v2_minor)
308{ 310{
309 if (s1->version_major == s2->version_major) 311 if (v1_major == v2_major)
310 return (s1->version_minor < s2->version_minor) ? -1 : (s1->version_minor > s2->version_minor); 312 return (v1_minor < v2_minor) ? -1 : (v1_minor > v2_minor);
311 else 313 else
312 return (s1->version_major < s2->version_major) ? -1 : (s1->version_major > s2->version_major); 314 return (v1_major < v2_major) ? -1 : (v1_major > v2_major);
313} 315}
314 316
317
315/** 318/**
316 * Adds a new sensor to given hashmap. 319 * Adds a new sensor to given hashmap.
317 * If the same name exist, compares versions and update if old. 320 * If the same name exist, compares versions and update if old.
@@ -332,7 +335,10 @@ add_sensor_to_hashmap (struct GNUNET_SENSOR_SensorInfo *sensor,
332 existing = GNUNET_CONTAINER_multihashmap_get(map, &key); 335 existing = GNUNET_CONTAINER_multihashmap_get(map, &key);
333 if(NULL != existing) //sensor with same name already exists 336 if(NULL != existing) //sensor with same name already exists
334 { 337 {
335 if(sensor_version_compare(existing, sensor) >= 0) //same or newer version already exist 338 if(GNUNET_SENSOR_version_compare (existing->version_major,
339 existing->version_minor,
340 sensor->version_major,
341 sensor->version_minor) >= 0)
336 { 342 {
337 LOG (GNUNET_ERROR_TYPE_INFO, 343 LOG (GNUNET_ERROR_TYPE_INFO,
338 _("Sensor `%s' already exists with same or newer version\n"), 344 _("Sensor `%s' already exists with same or newer version\n"),
@@ -389,9 +395,10 @@ reload_sensors_dir_cb(void *cls, const char *filename)
389} 395}
390 396
391/* 397/*
392 * Get path to the directory containing the sensor definition files 398 * Get path to the directory containing the sensor definition files with a
399 * trailing directory separator.
393 * 400 *
394 * @return sensor files directory 401 * @return sensor files directory full path
395 */ 402 */
396char * 403char *
397GNUNET_SENSOR_get_sensor_dir () 404GNUNET_SENSOR_get_sensor_dir ()
@@ -400,8 +407,10 @@ GNUNET_SENSOR_get_sensor_dir ()
400 char* sensordir; 407 char* sensordir;
401 408
402 datadir = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_DATADIR); 409 datadir = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_DATADIR);
403 GNUNET_asprintf(&sensordir, "%ssensors%s", 410 GNUNET_asprintf (&sensordir,
404 datadir, DIR_SEPARATOR_STR); 411 "%ssensors%s",
412 datadir,
413 DIR_SEPARATOR_STR);
405 GNUNET_free(datadir); 414 GNUNET_free(datadir);
406 415
407 return sensordir; 416 return sensordir;
diff --git a/src/sensordashboard/gnunet-service-sensordashboard.c b/src/sensordashboard/gnunet-service-sensordashboard.c
index b1fc67fa4..a1f4318b8 100644
--- a/src/sensordashboard/gnunet-service-sensordashboard.c
+++ b/src/sensordashboard/gnunet-service-sensordashboard.c
@@ -558,7 +558,7 @@ handle_sensor_reading (void *cls,
558 if (NULL == reading) 558 if (NULL == reading)
559 { 559 {
560 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 560 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
561 "Received an invalid sensor reading from peer `%s'\n", 561 "Received an invalid sensor reading from peer `%s'.\n",
562 GNUNET_i2s (&cp->peerid)); 562 GNUNET_i2s (&cp->peerid));
563 return GNUNET_SYSERR; 563 return GNUNET_SYSERR;
564 } 564 }
@@ -583,6 +583,142 @@ handle_sensor_reading (void *cls,
583 583
584 584
585/** 585/**
586 * Create a message with full information about sensor
587 *
588 * @param sensorname Name of sensor requested
589 * @return Message ready to be sent to client or NULL on error
590 */
591static struct GNUNET_SENSOR_SensorFullMessage *
592create_full_sensor_msg (char *sensorname)
593{
594 struct GNUNET_HashCode key;
595 struct GNUNET_SENSOR_SensorInfo *sensor;
596 struct GNUNET_SENSOR_SensorFullMessage *msg;
597 char *sensor_dir;
598 char *sensor_path;
599 char *sensorscript_path;
600 uint64_t sensorfile_size;
601 uint64_t sensorscriptname_size;
602 uint64_t sensorscript_size;
603 uint64_t total_size;
604 void *dummy;
605
606 GNUNET_CRYPTO_hash (sensorname, strlen (sensorname) + 1, &key);
607 sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &key);
608 if (NULL == sensor)
609 return NULL;
610 sensor_dir = GNUNET_SENSOR_get_sensor_dir ();
611 GNUNET_asprintf (&sensor_path, "%s%s",
612 sensor_dir, sensorname);
613 if (GNUNET_OK != GNUNET_DISK_file_size (sensor_path,
614 &sensorfile_size,
615 GNUNET_NO,
616 GNUNET_YES))
617 {
618 GNUNET_free (sensor_dir);
619 GNUNET_free (sensor_path);
620 return NULL;
621 }
622 sensorscript_size = 0;
623 sensorscriptname_size = 0;
624 /* Test if there is an associated script */
625 if (NULL != sensor->ext_process)
626 {
627 GNUNET_asprintf (&sensorscript_path, "%s%s-files%s%s",
628 sensor_dir,
629 sensor->name,
630 DIR_SEPARATOR_STR,
631 sensor->ext_process);
632 if (GNUNET_OK == GNUNET_DISK_file_size (sensorscript_path,
633 &sensorscript_size,
634 GNUNET_NO,
635 GNUNET_YES))
636 sensorscriptname_size = strlen (sensor->ext_process) + 1;
637 }
638 /* Construct the msg */
639 total_size = sizeof (struct GNUNET_SENSOR_SensorFullMessage) +
640 sensorfile_size + sensorscriptname_size + sensorscript_size;
641 msg = GNUNET_malloc (total_size);
642 msg->header.size = htons (total_size);
643 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_FULL);
644 msg->cfg_size = htons (sensorfile_size);
645 msg->scriptname_size = htons (sensorscriptname_size);
646 msg->script_size = htons (sensorscript_size);
647 dummy = &msg[1];
648 GNUNET_DISK_fn_read (sensor_path, dummy, sensorfile_size);
649 dummy += sensorfile_size;
650 if (sensorscriptname_size > 0)
651 {
652 memcpy (dummy, sensor->ext_process, sensorscriptname_size);
653 dummy += sensorscriptname_size;
654 GNUNET_DISK_fn_read (sensorscript_path, dummy, sensorscript_size);
655 }
656 GNUNET_free (sensor_dir);
657 GNUNET_free (sensor_path);
658 GNUNET_free (sensorscript_path);
659 return msg;
660}
661
662
663/**
664 * Called with any request for full sensor information.
665 *
666 * Each time the function must call #GNUNET_CADET_receive_done on the channel
667 * in order to receive the next message. This doesn't need to be immediate:
668 * can be delayed if some processing is done on the message.
669 *
670 * @param cls Closure (set from #GNUNET_CADET_connect).
671 * @param channel Connection to the other end.
672 * @param channel_ctx Place to store local state associated with the channel.
673 * @param message The actual message.
674 * @return #GNUNET_OK to keep the channel open,
675 * #GNUNET_SYSERR to close it (signal serious error).
676 */
677static int
678handle_sensor_full_req (void *cls,
679 struct GNUNET_CADET_Channel *channel,
680 void **channel_ctx,
681 const struct GNUNET_MessageHeader *message)
682{
683 struct ClientPeerContext *cp = *channel_ctx;
684 struct GNUNET_SENSOR_SensorBriefMessage *sbm = NULL;
685 struct GNUNET_SENSOR_SensorFullMessage *sfm;
686 uint16_t msg_size;
687 uint16_t sensorname_size;
688
689 msg_size = ntohs (message->size);
690 /* parse & error check */
691 if (msg_size > sizeof (struct GNUNET_SENSOR_SensorBriefMessage))
692 {
693 sbm = (struct GNUNET_SENSOR_SensorBriefMessage *)message;
694 sensorname_size = ntohs (sbm->name_size);
695 if (msg_size != sizeof (struct GNUNET_SENSOR_SensorBriefMessage) +
696 sensorname_size)
697 sbm = NULL;
698 }
699 if (NULL == sbm)
700 {
701 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
702 "Received an invalid full sensor request from peer `%s'.\n",
703 GNUNET_i2s (&cp->peerid));
704 return GNUNET_SYSERR;
705 }
706 /* Create and send msg with full sensor info */
707 sfm = create_full_sensor_msg ((char *)&sbm[1]);
708 if (NULL == sfm)
709 {
710 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
711 "Error creating full sensor info msg for sensor `%s'.\n",
712 (char *)&sbm[1]);
713 return GNUNET_SYSERR;
714 }
715 queue_msg ((struct GNUNET_MessageHeader *)sfm, cp);
716 GNUNET_CADET_receive_done (channel);
717 return GNUNET_OK;
718}
719
720
721/**
586 * Process sensordashboard requests. 722 * Process sensordashboard requests.
587 * 723 *
588 * @param cls closure 724 * @param cls closure
@@ -602,6 +738,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
602 {&handle_sensor_list_req, 738 {&handle_sensor_list_req,
603 GNUNET_MESSAGE_TYPE_SENSOR_LIST_REQ, 739 GNUNET_MESSAGE_TYPE_SENSOR_LIST_REQ,
604 sizeof (struct GNUNET_MessageHeader)}, 740 sizeof (struct GNUNET_MessageHeader)},
741 {&handle_sensor_full_req,
742 GNUNET_MESSAGE_TYPE_SENSOR_FULL_REQ,
743 sizeof (struct GNUNET_MessageHeader)},
605 {NULL, 0, 0} 744 {NULL, 0, 0}
606 }; 745 };
607 static uint32_t cadet_ports[] = { 746 static uint32_t cadet_ports[] = {