aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_sensor_service.h44
-rw-r--r--src/include/gnunet_sensor_util_lib.h91
-rw-r--r--src/sensor/Makefile.am6
-rw-r--r--src/sensor/gnunet-service-sensor-reporting.c62
-rw-r--r--src/sensor/gnunet-service-sensor.c59
-rw-r--r--src/sensor/sensor_util_lib.c152
-rw-r--r--src/sensordashboard/gnunet-service-sensordashboard.c35
7 files changed, 319 insertions, 130 deletions
diff --git a/src/include/gnunet_sensor_service.h b/src/include/gnunet_sensor_service.h
index f81248b28..eb4fbdc67 100644
--- a/src/include/gnunet_sensor_service.h
+++ b/src/include/gnunet_sensor_service.h
@@ -71,50 +71,6 @@ struct SensorInfoShort
71 71
72}; 72};
73 73
74GNUNET_NETWORK_STRUCT_BEGIN
75
76/**
77 * Used to communicate sensor readings to
78 * collection points (SENSORDASHBAORD service)
79 */
80struct GNUNET_SENSOR_Reading
81{
82
83 /**
84 * GNUNET general message header
85 */
86 struct GNUNET_MessageHeader *header;
87
88 /**
89 * Size of the sensor name value, allocated
90 * at position 0 after this struct
91 */
92 size_t sensorname_size;
93
94 /**
95 * First part of sensor version number
96 */
97 uint16_t sensorversion_major;
98
99 /**
100 * Second part of sensor version number
101 */
102 uint16_t sensorversion_minor;
103
104 /**
105 * Timestamp of recorded reading
106 */
107 uint64_t timestamp;
108
109 /**
110 * Size of reading value, allocation
111 * at poistion 1 after this struct
112 */
113 size_t value_size;
114
115};
116GNUNET_NETWORK_STRUCT_END
117
118/** 74/**
119 * Type of an iterator over sensor definitions. 75 * Type of an iterator over sensor definitions.
120 * 76 *
diff --git a/src/include/gnunet_sensor_util_lib.h b/src/include/gnunet_sensor_util_lib.h
index 15fb61b4c..56e0bc868 100644
--- a/src/include/gnunet_sensor_util_lib.h
+++ b/src/include/gnunet_sensor_util_lib.h
@@ -188,6 +188,78 @@ struct SensorInfo
188}; 188};
189 189
190/** 190/**
191 * Carries a single reading from a sensor
192 */
193struct GNUNET_SENSOR_Reading
194{
195
196 /**
197 * Sensor this reading is related to
198 */
199 struct SensorInfo *sensor;
200
201 /**
202 * Timestamp of taking the reading
203 */
204 uint64_t timestamp;
205
206 /**
207 * Reading value
208 */
209 void *value;
210
211 /**
212 * Size of @value
213 */
214 uint16_t value_size;
215
216};
217
218GNUNET_NETWORK_STRUCT_BEGIN
219
220/**
221 * Used to communicate sensor readings to
222 * collection points (SENSORDASHBAORD service)
223 */
224struct GNUNET_SENSOR_ReadingMessage
225{
226
227 /**
228 * GNUNET general message header
229 */
230 struct GNUNET_MessageHeader header;
231
232 /**
233 * Size of the sensor name value, allocated
234 * at position 0 after this struct
235 */
236 uint16_t sensorname_size;
237
238 /**
239 * First part of sensor version number
240 */
241 uint16_t sensorversion_major;
242
243 /**
244 * Second part of sensor version number
245 */
246 uint16_t sensorversion_minor;
247
248 /**
249 * Timestamp of recorded reading
250 */
251 uint64_t timestamp;
252
253 /**
254 * Size of reading value, allocation
255 * at poistion 1 after this struct
256 */
257 uint16_t value_size;
258
259};
260GNUNET_NETWORK_STRUCT_END
261
262/**
191 * Reads sensor definitions from local data files 263 * Reads sensor definitions from local data files
192 * 264 *
193 * @return a multihashmap of loaded sensors 265 * @return a multihashmap of loaded sensors
@@ -203,6 +275,25 @@ GNUNET_SENSOR_load_all_sensors ();
203char * 275char *
204GNUNET_SENSOR_get_sensor_dir (); 276GNUNET_SENSOR_get_sensor_dir ();
205 277
278/**
279 * Parses a sensor reading message struct
280 *
281 * @param msg message header received
282 * @param sensors multihashmap of loaded sensors
283 * @return sensor reading struct or NULL if error
284 */
285struct GNUNET_SENSOR_Reading *
286GNUNET_SENSOR_parse_reading_message (const struct GNUNET_MessageHeader *msg,
287 struct GNUNET_CONTAINER_MultiHashMap *sensors);
288
289/**
290 * Destroys a group of sensors in a hashmap and the hashmap itself
291 *
292 * @param sensors hashmap containing the sensors
293 */
294void
295GNUNET_SENSOR_destroy_sensors (struct GNUNET_CONTAINER_MultiHashMap *sensors);
296
206#if 0 /* keep Emacsens' auto-indent happy */ 297#if 0 /* keep Emacsens' auto-indent happy */
207{ 298{
208#endif 299#endif
diff --git a/src/sensor/Makefile.am b/src/sensor/Makefile.am
index a9b703cbd..1ddff32be 100644
--- a/src/sensor/Makefile.am
+++ b/src/sensor/Makefile.am
@@ -56,11 +56,13 @@ libgnunetsensor_la_LDFLAGS = \
56libgnunetsensorutil_la_SOURCES = \ 56libgnunetsensorutil_la_SOURCES = \
57 sensor_util_lib.c 57 sensor_util_lib.c
58libgnunetsensorutil_la_LIBADD = \ 58libgnunetsensorutil_la_LIBADD = \
59 $(top_builddir)/src/util/libgnunetutil.la 59 $(top_builddir)/src/util/libgnunetutil.la \
60 $(top_builddir)/src/statistics/libgnunetstatistics.la
60libgnunetsensorutil_la_LDFLAGS = \ 61libgnunetsensorutil_la_LDFLAGS = \
61 $(GN_LIB_LDFLAGS) 62 $(GN_LIB_LDFLAGS)
62libgnunetsensorutil_la_DEPENDENCIES = \ 63libgnunetsensorutil_la_DEPENDENCIES = \
63 $(top_builddir)/src/util/libgnunetutil.la 64 $(top_builddir)/src/util/libgnunetutil.la \
65 $(top_builddir)/src/statistics/libgnunetstatistics.la
64 66
65plugin_LTLIBRARIES = \ 67plugin_LTLIBRARIES = \
66 libgnunet_plugin_sensor_model_gaussian.la 68 libgnunet_plugin_sensor_model_gaussian.la
diff --git a/src/sensor/gnunet-service-sensor-reporting.c b/src/sensor/gnunet-service-sensor-reporting.c
index 7b32c7f6c..94f53e4ec 100644
--- a/src/sensor/gnunet-service-sensor-reporting.c
+++ b/src/sensor/gnunet-service-sensor-reporting.c
@@ -23,6 +23,7 @@
23 * @brief sensor service reporting functionality 23 * @brief sensor service reporting functionality
24 * @author Omar Tarabai 24 * @author Omar Tarabai
25 */ 25 */
26#include <inttypes.h>
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
28#include "sensor.h" 29#include "sensor.h"
@@ -33,6 +34,11 @@
33#define LOG(kind,...) GNUNET_log_from (kind, "sensor-reporting",__VA_ARGS__) 34#define LOG(kind,...) GNUNET_log_from (kind, "sensor-reporting",__VA_ARGS__)
34 35
35/** 36/**
37 * Retry interval (seconds) in case channel to collection point is busy
38 */
39#define COLLECTION_RETRY 1
40
41/**
36 * Context of reporting operations 42 * Context of reporting operations
37 */ 43 */
38struct ReportingContext 44struct ReportingContext
@@ -129,6 +135,11 @@ struct CadetChannelContext
129 */ 135 */
130 struct GNUNET_CADET_TransmitHandle *th; 136 struct GNUNET_CADET_TransmitHandle *th;
131 137
138 /**
139 * Are we currently destroying the channel and its context?
140 */
141 int destroying;
142
132}; 143};
133 144
134/** 145/**
@@ -202,6 +213,7 @@ destroy_reporting_context (struct ReportingContext *rc)
202static void 213static void
203destroy_cadet_channel_context (struct CadetChannelContext *cc) 214destroy_cadet_channel_context (struct CadetChannelContext *cc)
204{ 215{
216 cc->destroying = GNUNET_YES;
205 if (NULL != cc->th) 217 if (NULL != cc->th)
206 { 218 {
207 GNUNET_CADET_notify_transmit_ready_cancel (cc->th); 219 GNUNET_CADET_notify_transmit_ready_cancel (cc->th);
@@ -280,6 +292,7 @@ get_cadet_channel (struct GNUNET_PeerIdentity pid)
280 GNUNET_CADET_OPTION_DEFAULT); 292 GNUNET_CADET_OPTION_DEFAULT);
281 cc->pid = pid; 293 cc->pid = pid;
282 cc->sending = GNUNET_NO; 294 cc->sending = GNUNET_NO;
295 cc->destroying = GNUNET_NO;
283 GNUNET_CONTAINER_DLL_insert (cc_head, cc_tail, cc); 296 GNUNET_CONTAINER_DLL_insert (cc_head, cc_tail, cc);
284 return cc; 297 return cc;
285} 298}
@@ -293,25 +306,25 @@ get_cadet_channel (struct GNUNET_PeerIdentity pid)
293 */ 306 */
294static size_t 307static size_t
295construct_reading_message (struct ReportingContext *rc, 308construct_reading_message (struct ReportingContext *rc,
296 struct GNUNET_SENSOR_Reading **msg) 309 struct GNUNET_SENSOR_ReadingMessage **msg)
297{ 310{
298 struct GNUNET_SENSOR_Reading *ret; 311 struct GNUNET_SENSOR_ReadingMessage *ret;
299 size_t sensorname_size; 312 uint16_t sensorname_size;
300 size_t total_size; 313 uint16_t total_size;
301 void *dummy; 314 void *dummy;
302 315
303 sensorname_size = strlen (rc->sensor->name) + 1; 316 sensorname_size = strlen (rc->sensor->name) + 1;
304 total_size = sizeof(struct GNUNET_SENSOR_Reading) + 317 total_size = sizeof(struct GNUNET_SENSOR_ReadingMessage) +
305 sensorname_size + 318 sensorname_size +
306 rc->last_value_size; 319 rc->last_value_size;
307 ret = GNUNET_malloc (total_size); 320 ret = GNUNET_malloc (total_size);
308 ret->header->size = htons (total_size); 321 ret->header.size = htons (total_size);
309 ret->header->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_READING); 322 ret->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_READING);
310 ret->sensorname_size = GNUNET_htobe64 (sensorname_size); 323 ret->sensorname_size = htons (sensorname_size);
311 ret->sensorversion_major = htons (rc->sensor->version_major); 324 ret->sensorversion_major = htons (rc->sensor->version_major);
312 ret->sensorversion_minor = htons (rc->sensor->version_minor); 325 ret->sensorversion_minor = htons (rc->sensor->version_minor);
313 ret->timestamp = GNUNET_htobe64 (rc->timestamp); 326 ret->timestamp = GNUNET_htobe64 (rc->timestamp);
314 ret->value_size = GNUNET_htobe64 (rc->last_value_size); 327 ret->value_size = htons (rc->last_value_size);
315 dummy = &ret[1]; 328 dummy = &ret[1];
316 memcpy (dummy, rc->sensor->name, sensorname_size); 329 memcpy (dummy, rc->sensor->name, sensorname_size);
317 dummy += sensorname_size; 330 dummy += sensorname_size;
@@ -336,12 +349,19 @@ do_report_collection_point (void *cls, size_t size, void *buf)
336 struct CadetChannelContext *cc = cls; 349 struct CadetChannelContext *cc = cls;
337 size_t written = 0; 350 size_t written = 0;
338 351
339 LOG (GNUNET_ERROR_TYPE_DEBUG, "Copying to CADET transmit buffer.\n"); 352 cc->th = NULL;
340 cc->sending = GNUNET_NO; 353 cc->sending = GNUNET_NO;
341 if (NULL == buf || size != cc->pending_msg_size) 354 LOG (GNUNET_ERROR_TYPE_DEBUG, "Copying to CADET transmit buffer.\n");
355 if (NULL == buf)
342 { 356 {
343 LOG (GNUNET_ERROR_TYPE_WARNING, 357 LOG (GNUNET_ERROR_TYPE_WARNING,
344 "CADET failed to transmit message to collection point, discarding."); 358 "CADET failed to transmit message (NULL buf), discarding.\n");
359 }
360 else if (size < cc->pending_msg_size)
361 {
362 LOG (GNUNET_ERROR_TYPE_WARNING,
363 "CADET failed to transmit message (small size, expected: %u, got: %u)"
364 ", discarding.\n", cc->pending_msg_size, size);
345 } 365 }
346 else 366 else
347 { 367 {
@@ -349,6 +369,7 @@ do_report_collection_point (void *cls, size_t size, void *buf)
349 written = cc->pending_msg_size; 369 written = cc->pending_msg_size;
350 } 370 }
351 GNUNET_free (cc->pending_msg); 371 GNUNET_free (cc->pending_msg);
372 cc->pending_msg = NULL;
352 cc->pending_msg_size = 0; 373 cc->pending_msg_size = 0;
353 return written; 374 return written;
354} 375}
@@ -365,7 +386,7 @@ static void report_collection_point
365 struct ReportingContext *rc = cls; 386 struct ReportingContext *rc = cls;
366 struct SensorInfo *sensor = rc->sensor; 387 struct SensorInfo *sensor = rc->sensor;
367 struct CadetChannelContext *cc; 388 struct CadetChannelContext *cc;
368 struct GNUNET_SENSOR_Reading *msg; 389 struct GNUNET_SENSOR_ReadingMessage *msg;
369 size_t msg_size; 390 size_t msg_size;
370 391
371 rc->cp_task = GNUNET_SCHEDULER_NO_TASK; 392 rc->cp_task = GNUNET_SCHEDULER_NO_TASK;
@@ -385,9 +406,11 @@ static void report_collection_point
385 { 406 {
386 LOG (GNUNET_ERROR_TYPE_DEBUG, 407 LOG (GNUNET_ERROR_TYPE_DEBUG,
387 "Cadet channel to collection point busy, " 408 "Cadet channel to collection point busy, "
388 "trying again for sensor `%s' on next interval.\n", rc->sensor->name); 409 "trying again for sensor `%s' after %d seconds.\n", rc->sensor->name,
389 rc->cp_task = GNUNET_SCHEDULER_add_delayed (sensor->collection_interval, 410 COLLECTION_RETRY);
390 &report_collection_point, rc); 411 rc->cp_task = GNUNET_SCHEDULER_add_delayed (
412 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, COLLECTION_RETRY),
413 &report_collection_point, rc);
391 return; 414 return;
392 } 415 }
393 msg_size = construct_reading_message (rc, &msg); 416 msg_size = construct_reading_message (rc, &msg);
@@ -414,8 +437,6 @@ sensor_watch_cb (void *cls,
414{ 437{
415 struct ReportingContext *rc = cls; 438 struct ReportingContext *rc = cls;
416 439
417 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a sensor `%s' watch value, "
418 "updating notification last_value.\n", rc->sensor->name);
419 if (NULL != emsg) 440 if (NULL != emsg)
420 return GNUNET_YES; 441 return GNUNET_YES;
421 if (NULL != rc->last_value) 442 if (NULL != rc->last_value)
@@ -427,6 +448,9 @@ sensor_watch_cb (void *cls,
427 memcpy (rc->last_value, record->value, record->value_size); 448 memcpy (rc->last_value, record->value, record->value_size);
428 rc->last_value_size = record->value_size; 449 rc->last_value_size = record->value_size;
429 rc->timestamp = GNUNET_TIME_absolute_get().abs_value_us; 450 rc->timestamp = GNUNET_TIME_absolute_get().abs_value_us;
451 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a sensor `%s' watch value at "
452 "timestamp %" PRIu64 ", updating notification last_value.\n",
453 rc->sensor->name, rc->timestamp);
430 return GNUNET_YES; 454 return GNUNET_YES;
431} 455}
432 456
@@ -502,6 +526,8 @@ static void cadet_channel_destroyed (void *cls,
502{ 526{
503 struct CadetChannelContext *cc = channel_ctx; 527 struct CadetChannelContext *cc = channel_ctx;
504 528
529 if (GNUNET_YES == cc->destroying)
530 return;
505 LOG (GNUNET_ERROR_TYPE_DEBUG, 531 LOG (GNUNET_ERROR_TYPE_DEBUG,
506 "Received a `channel destroyed' notification from CADET, " 532 "Received a `channel destroyed' notification from CADET, "
507 "cleaning up.\n"); 533 "cleaning up.\n");
diff --git a/src/sensor/gnunet-service-sensor.c b/src/sensor/gnunet-service-sensor.c
index b41d8906c..20466cec3 100644
--- a/src/sensor/gnunet-service-sensor.c
+++ b/src/sensor/gnunet-service-sensor.c
@@ -61,61 +61,6 @@ char *subsystem = "sensor";
61struct GNUNET_PeerIdentity peerid; 61struct GNUNET_PeerIdentity peerid;
62 62
63/** 63/**
64 * Remove sensor execution from scheduler
65 *
66 * @param cls unused
67 * @param key hash of sensor name, key to hashmap
68 * @param value a 'struct SensorInfo *'
69 * @return #GNUNET_YES if we should continue to
70 * iterate,
71 * #GNUNET_NO if not.
72 */
73static int destroy_sensor(void *cls,
74 const struct GNUNET_HashCode *key, void *value)
75{
76 struct SensorInfo *sensorinfo = value;
77
78 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Destroying sensor `%s'\n", sensorinfo->name);
79 if(GNUNET_SCHEDULER_NO_TASK != sensorinfo->execution_task)
80 {
81 GNUNET_SCHEDULER_cancel(sensorinfo->execution_task);
82 sensorinfo->execution_task = GNUNET_SCHEDULER_NO_TASK;
83 }
84 if(NULL != sensorinfo->gnunet_stat_get_handle)
85 {
86 GNUNET_STATISTICS_get_cancel(sensorinfo->gnunet_stat_get_handle);
87 sensorinfo->gnunet_stat_get_handle = NULL;
88 }
89 if(NULL != sensorinfo->ext_cmd)
90 {
91 GNUNET_OS_command_stop(sensorinfo->ext_cmd);
92 sensorinfo->ext_cmd = NULL;
93 }
94 if(NULL != sensorinfo->cfg)
95 GNUNET_CONFIGURATION_destroy(sensorinfo->cfg);
96 if(NULL != sensorinfo->name)
97 GNUNET_free(sensorinfo->name);
98 if(NULL != sensorinfo->def_file)
99 GNUNET_free(sensorinfo->def_file);
100 if(NULL != sensorinfo->description)
101 GNUNET_free(sensorinfo->description);
102 if(NULL != sensorinfo->category)
103 GNUNET_free(sensorinfo->category);
104 if(NULL != sensorinfo->capabilities)
105 GNUNET_free(sensorinfo->capabilities);
106 if(NULL != sensorinfo->gnunet_stat_service)
107 GNUNET_free(sensorinfo->gnunet_stat_service);
108 if(NULL != sensorinfo->gnunet_stat_name)
109 GNUNET_free(sensorinfo->gnunet_stat_name);
110 if(NULL != sensorinfo->ext_process)
111 GNUNET_free(sensorinfo->ext_process);
112 if(NULL != sensorinfo->ext_args)
113 GNUNET_free(sensorinfo->ext_args);
114 GNUNET_free(sensorinfo);
115 return GNUNET_YES;
116}
117
118/**
119 * Disable a sensor 64 * Disable a sensor
120 * Sensor will not run again unless 65 * Sensor will not run again unless
121 * explicitly enabled or reloaded 66 * explicitly enabled or reloaded
@@ -146,8 +91,7 @@ shutdown_task (void *cls,
146{ 91{
147 SENSOR_reporting_stop(); 92 SENSOR_reporting_stop();
148 SENSOR_analysis_stop(); 93 SENSOR_analysis_stop();
149 GNUNET_CONTAINER_multihashmap_iterate(sensors, &destroy_sensor, NULL); 94 GNUNET_SENSOR_destroy_sensors (sensors);
150 GNUNET_CONTAINER_multihashmap_destroy(sensors);
151 if(NULL != statistics) 95 if(NULL != statistics)
152 { 96 {
153 GNUNET_STATISTICS_destroy(statistics, GNUNET_YES); 97 GNUNET_STATISTICS_destroy(statistics, GNUNET_YES);
@@ -464,6 +408,7 @@ void sensor_process_callback (void *cls, const char *line)
464 GNUNET_PEERSTORE_STOREOPTION_MULTIPLE, 408 GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
465 NULL, 409 NULL,
466 NULL); 410 NULL);
411 GNUNET_free (value);
467 } 412 }
468} 413}
469 414
diff --git a/src/sensor/sensor_util_lib.c b/src/sensor/sensor_util_lib.c
index 90befe6af..9e36f7ebe 100644
--- a/src/sensor/sensor_util_lib.c
+++ b/src/sensor/sensor_util_lib.c
@@ -27,6 +27,7 @@
27#include "platform.h" 27#include "platform.h"
28#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
29#include "gnunet_sensor_util_lib.h" 29#include "gnunet_sensor_util_lib.h"
30#include "gnunet_statistics_service.h"
30 31
31#define LOG(kind,...) GNUNET_log_from (kind, "sensor-util",__VA_ARGS__) 32#define LOG(kind,...) GNUNET_log_from (kind, "sensor-util",__VA_ARGS__)
32 33
@@ -215,6 +216,7 @@ load_sensor_from_cfg(struct GNUNET_CONFIGURATION_Handle *cfg, const char *sectio
215 return NULL; 216 return NULL;
216 } 217 }
217 //reporting mechanism 218 //reporting mechanism
219 sensor->collection_point = NULL;
218 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, sectionname, "COLLECTION_POINT", &dummy)) 220 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, sectionname, "COLLECTION_POINT", &dummy))
219 { 221 {
220 if(GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, sectionname, "COLLECTION_INTERVAL", &time_sec)) 222 if(GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, sectionname, "COLLECTION_INTERVAL", &time_sec))
@@ -230,6 +232,7 @@ load_sensor_from_cfg(struct GNUNET_CONFIGURATION_Handle *cfg, const char *sectio
230 sensor->collection_point->public_key = public_key; 232 sensor->collection_point->public_key = public_key;
231 } 233 }
232 } 234 }
235 GNUNET_free (dummy);
233 } 236 }
234 sensor->p2p_report = GNUNET_NO; 237 sensor->p2p_report = GNUNET_NO;
235 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg, sectionname, "P2P_REPORT")) 238 if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg, sectionname, "P2P_REPORT"))
@@ -322,7 +325,7 @@ add_sensor_to_hashmap(struct SensorInfo *sensor, struct GNUNET_CONTAINER_MultiHa
322 struct GNUNET_HashCode key; 325 struct GNUNET_HashCode key;
323 struct SensorInfo *existing; 326 struct SensorInfo *existing;
324 327
325 GNUNET_CRYPTO_hash(sensor->name, strlen(sensor->name), &key); 328 GNUNET_CRYPTO_hash(sensor->name, strlen(sensor->name) + 1, &key);
326 existing = GNUNET_CONTAINER_multihashmap_get(map, &key); 329 existing = GNUNET_CONTAINER_multihashmap_get(map, &key);
327 if(NULL != existing) //sensor with same name already exists 330 if(NULL != existing) //sensor with same name already exists
328 { 331 {
@@ -369,10 +372,7 @@ reload_sensors_dir_cb(void *cls, const char *filename)
369 _("Error loading sensor from file: %s\n"), filename); 372 _("Error loading sensor from file: %s\n"), filename);
370 return GNUNET_OK; 373 return GNUNET_OK;
371 } 374 }
372 if(GNUNET_YES == add_sensor_to_hashmap(sensor, sensors)) 375 if(GNUNET_YES != add_sensor_to_hashmap(sensor, sensors))
373 LOG (GNUNET_ERROR_TYPE_DEBUG,
374 "Sensor `%s' added to global hashmap\n", sensor->name);
375 else
376 LOG (GNUNET_ERROR_TYPE_WARNING, 376 LOG (GNUNET_ERROR_TYPE_WARNING,
377 "Could not add sensor `%s' to global hashmap\n", sensor->name); 377 "Could not add sensor `%s' to global hashmap\n", sensor->name);
378 378
@@ -422,3 +422,145 @@ GNUNET_SENSOR_load_all_sensors ()
422 GNUNET_free(sensordir); 422 GNUNET_free(sensordir);
423 return sensors; 423 return sensors;
424} 424}
425
426/**
427 * Parses a sensor reading message struct
428 *
429 * @param msg message header received
430 * @param sensors multihashmap of loaded sensors
431 * @return sensor reading struct or NULL if error
432 */
433struct GNUNET_SENSOR_Reading *
434GNUNET_SENSOR_parse_reading_message (const struct GNUNET_MessageHeader *msg,
435 struct GNUNET_CONTAINER_MultiHashMap *sensors)
436{
437 uint16_t msg_size;
438 struct GNUNET_SENSOR_ReadingMessage *rm;
439 uint16_t sensorname_size;
440 uint16_t value_size;
441 void *dummy;
442 char *sensorname;
443 struct GNUNET_HashCode key;
444 struct SensorInfo *sensor;
445 struct GNUNET_SENSOR_Reading *reading;
446
447 msg_size = ntohs (msg->size);
448 if (msg_size < sizeof (struct GNUNET_SENSOR_ReadingMessage))
449 {
450 LOG (GNUNET_ERROR_TYPE_WARNING, "Invalid reading message size.\n");
451 return NULL;
452 }
453 rm = (struct GNUNET_SENSOR_ReadingMessage *)msg;
454 sensorname_size = ntohs (rm->sensorname_size);
455 value_size = ntohs (rm->value_size);
456 if ((sizeof (struct GNUNET_SENSOR_ReadingMessage)
457 + sensorname_size + value_size) != msg_size)
458 {
459 LOG (GNUNET_ERROR_TYPE_WARNING, "Invalid reading message size.\n");
460 return NULL;
461 }
462 dummy = &rm[1];
463 sensorname = GNUNET_malloc (sensorname_size);
464 memcpy (sensorname, dummy, sensorname_size);
465 GNUNET_CRYPTO_hash(sensorname, sensorname_size, &key);
466 GNUNET_free (sensorname);
467 sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &key);
468 if (NULL == sensor)
469 {
470 LOG (GNUNET_ERROR_TYPE_WARNING,
471 "Unknown sensor name in reading message.\n");
472 return NULL;
473 }
474 if ((sensor->version_minor != ntohs (rm->sensorversion_minor)) ||
475 (sensor->version_major != ntohs (rm->sensorversion_major)))
476 {
477 LOG (GNUNET_ERROR_TYPE_WARNING,
478 "Sensor version mismatch in reading message.\n");
479 return NULL;
480 }
481 if (0 == strcmp (sensor->expected_datatype, "numeric") &&
482 sizeof (double) != value_size)
483 {
484 LOG (GNUNET_ERROR_TYPE_WARNING,
485 "Invalid value size for a numerical sensor.\n");
486 return NULL;
487 }
488 reading = GNUNET_new (struct GNUNET_SENSOR_Reading);
489 reading->sensor = sensor;
490 reading->timestamp = GNUNET_be64toh (rm->timestamp);
491 reading->value_size = value_size;
492 reading->value = GNUNET_malloc (value_size);
493 dummy += sensorname_size;
494 memcpy (reading->value, dummy, value_size);
495 return reading;
496}
497
498/**
499 * Remove sensor execution from scheduler
500 *
501 * @param cls unused
502 * @param key hash of sensor name, key to hashmap
503 * @param value a 'struct SensorInfo *'
504 * @return #GNUNET_YES if we should continue to
505 * iterate,
506 * #GNUNET_NO if not.
507 */
508static int destroy_sensor(void *cls,
509 const struct GNUNET_HashCode *key, void *value)
510{
511 struct SensorInfo *sensorinfo = value;
512
513 if(GNUNET_SCHEDULER_NO_TASK != sensorinfo->execution_task)
514 {
515 GNUNET_SCHEDULER_cancel(sensorinfo->execution_task);
516 sensorinfo->execution_task = GNUNET_SCHEDULER_NO_TASK;
517 }
518 if(NULL != sensorinfo->gnunet_stat_get_handle)
519 {
520 GNUNET_STATISTICS_get_cancel(sensorinfo->gnunet_stat_get_handle);
521 sensorinfo->gnunet_stat_get_handle = NULL;
522 }
523 if(NULL != sensorinfo->ext_cmd)
524 {
525 GNUNET_OS_command_stop(sensorinfo->ext_cmd);
526 sensorinfo->ext_cmd = NULL;
527 }
528 if(NULL != sensorinfo->cfg)
529 GNUNET_CONFIGURATION_destroy(sensorinfo->cfg);
530 if(NULL != sensorinfo->name)
531 GNUNET_free(sensorinfo->name);
532 if(NULL != sensorinfo->def_file)
533 GNUNET_free(sensorinfo->def_file);
534 if(NULL != sensorinfo->description)
535 GNUNET_free(sensorinfo->description);
536 if(NULL != sensorinfo->category)
537 GNUNET_free(sensorinfo->category);
538 if(NULL != sensorinfo->capabilities)
539 GNUNET_free(sensorinfo->capabilities);
540 if(NULL != sensorinfo->gnunet_stat_service)
541 GNUNET_free(sensorinfo->gnunet_stat_service);
542 if(NULL != sensorinfo->gnunet_stat_name)
543 GNUNET_free(sensorinfo->gnunet_stat_name);
544 if(NULL != sensorinfo->ext_process)
545 GNUNET_free(sensorinfo->ext_process);
546 if(NULL != sensorinfo->ext_args)
547 GNUNET_free(sensorinfo->ext_args);
548 if (NULL != sensorinfo->collection_point)
549 GNUNET_free (sensorinfo->collection_point);
550 GNUNET_free(sensorinfo);
551 return GNUNET_YES;
552}
553
554/**
555 * Destroys a group of sensors in a hashmap and the hashmap itself
556 *
557 * @param sensors hashmap containing the sensors
558 */
559void
560GNUNET_SENSOR_destroy_sensors (struct GNUNET_CONTAINER_MultiHashMap *sensors)
561{
562 LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying sensor list.\n");
563 GNUNET_CONTAINER_multihashmap_iterate(sensors, &destroy_sensor, NULL);
564 GNUNET_CONTAINER_multihashmap_destroy(sensors);
565}
566
diff --git a/src/sensordashboard/gnunet-service-sensordashboard.c b/src/sensordashboard/gnunet-service-sensordashboard.c
index 91c7e98f5..841268762 100644
--- a/src/sensordashboard/gnunet-service-sensordashboard.c
+++ b/src/sensordashboard/gnunet-service-sensordashboard.c
@@ -23,6 +23,7 @@
23 * @brief Service collecting sensor readings from peers 23 * @brief Service collecting sensor readings from peers
24 * @author Omar Tarabai 24 * @author Omar Tarabai
25 */ 25 */
26#include <inttypes.h>
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
28#include "gnunet_applications.h" 29#include "gnunet_applications.h"
@@ -51,6 +52,7 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
51 GNUNET_CADET_disconnect(cadet); 52 GNUNET_CADET_disconnect(cadet);
52 cadet = NULL; 53 cadet = NULL;
53 } 54 }
55 GNUNET_SENSOR_destroy_sensors (sensors);
54 GNUNET_SCHEDULER_shutdown(); 56 GNUNET_SCHEDULER_shutdown();
55} 57}
56 58
@@ -69,7 +71,9 @@ static void cadet_channel_destroyed (void *cls,
69 const struct GNUNET_CADET_Channel *channel, 71 const struct GNUNET_CADET_Channel *channel,
70 void *channel_ctx) 72 void *channel_ctx)
71{ 73{
74 struct GNUNET_PeerIdentity *peer = channel_ctx;
72 75
76 GNUNET_free (peer);
73} 77}
74 78
75/** 79/**
@@ -95,10 +99,11 @@ static void *cadet_channel_created (void *cls,
95 const struct GNUNET_PeerIdentity *initiator, 99 const struct GNUNET_PeerIdentity *initiator,
96 uint32_t port, enum GNUNET_CADET_ChannelOption options) 100 uint32_t port, enum GNUNET_CADET_ChannelOption options)
97{ 101{
98 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 102 struct GNUNET_PeerIdentity *peer;
99 "CADET channel opened by remote peer `%s'.\n", 103
100 GNUNET_i2s(initiator)); 104 peer = GNUNET_new (struct GNUNET_PeerIdentity);
101 return NULL; /* FIXME */ 105 memcpy (peer, initiator, sizeof (struct GNUNET_PeerIdentity));
106 return peer;
102} 107}
103 108
104/** 109/**
@@ -118,7 +123,29 @@ static void *cadet_channel_created (void *cls,
118int sensor_reading_receiver (void *cls, struct GNUNET_CADET_Channel *channel, 123int sensor_reading_receiver (void *cls, struct GNUNET_CADET_Channel *channel,
119 void **channel_ctx, const struct GNUNET_MessageHeader *message) 124 void **channel_ctx, const struct GNUNET_MessageHeader *message)
120{ 125{
126 struct GNUNET_PeerIdentity *peer = *channel_ctx;
127 struct GNUNET_SENSOR_Reading *reading;
121 128
129 reading = GNUNET_SENSOR_parse_reading_message (message, sensors);
130 if (NULL == reading)
131 {
132 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
133 "Received an invalid sensor reading from peer `%s'\n",
134 GNUNET_i2s (peer));
135 return GNUNET_SYSERR;
136 }
137 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
138 "Received a sensor reading from peer `%s':\n"
139 "# Sensor name: `%s'\n"
140 "# Timestamp: %" PRIu64 "\n"
141 "# Value size: %" PRIu64 ".\n",
142 GNUNET_i2s (peer),
143 reading->sensor->name,
144 reading->timestamp,
145 reading->value_size);
146 GNUNET_free (reading->value);
147 GNUNET_free (reading);
148 return GNUNET_OK;
122} 149}
123 150
124/** 151/**