diff options
author | Omar Tarabai <tarabai@devegypt.com> | 2014-07-25 11:42:08 +0000 |
---|---|---|
committer | Omar Tarabai <tarabai@devegypt.com> | 2014-07-25 11:42:08 +0000 |
commit | ac2af3883bbceafd3258cad788587a70057010d9 (patch) | |
tree | eee0f1dec96321d13373c0090bfe17b708cca875 /src/sensordashboard | |
parent | 98638edc1f1013173895fde63443a667525c58be (diff) | |
download | gnunet-ac2af3883bbceafd3258cad788587a70057010d9.tar.gz gnunet-ac2af3883bbceafd3258cad788587a70057010d9.zip |
sensor: towards update functionality
Diffstat (limited to 'src/sensordashboard')
-rw-r--r-- | src/sensordashboard/gnunet-service-sensordashboard.c | 286 |
1 files changed, 254 insertions, 32 deletions
diff --git a/src/sensordashboard/gnunet-service-sensordashboard.c b/src/sensordashboard/gnunet-service-sensordashboard.c index 5cec7e636..b1fc67fa4 100644 --- a/src/sensordashboard/gnunet-service-sensordashboard.c +++ b/src/sensordashboard/gnunet-service-sensordashboard.c | |||
@@ -60,17 +60,78 @@ struct ClientPeerContext | |||
60 | struct GNUNET_CADET_Channel *ch; | 60 | struct GNUNET_CADET_Channel *ch; |
61 | 61 | ||
62 | /** | 62 | /** |
63 | * CADET transmit handle if we requested a transmission | ||
64 | */ | ||
65 | struct GNUNET_CADET_TransmitHandle *th; | ||
66 | |||
67 | /** | ||
68 | * Head of DLL of pending messages to be sent to client | ||
69 | */ | ||
70 | struct PendingMessage *pm_head; | ||
71 | |||
72 | /** | ||
73 | * Tail of DLL of pending messages to be sent to client | ||
74 | */ | ||
75 | struct PendingMessage *pm_tail; | ||
76 | |||
77 | /** | ||
63 | * Are we in the process of destroying this context? | 78 | * Are we in the process of destroying this context? |
64 | */ | 79 | */ |
65 | int destroying; | 80 | int destroying; |
66 | 81 | ||
67 | }; | 82 | }; |
68 | 83 | ||
84 | /** | ||
85 | * Message queued to be sent to a client stored in a DLL | ||
86 | */ | ||
87 | struct PendingMessage | ||
88 | { | ||
89 | |||
90 | /** | ||
91 | * DLL | ||
92 | */ | ||
93 | struct PendingMessage *prev; | ||
94 | |||
95 | /** | ||
96 | * DLL | ||
97 | */ | ||
98 | struct PendingMessage *next; | ||
99 | |||
100 | /** | ||
101 | * Actual queued message | ||
102 | */ | ||
103 | struct GNUNET_MessageHeader *msg; | ||
104 | |||
105 | }; | ||
69 | 106 | ||
70 | /** | 107 | /** |
71 | * Handle to CADET service | 108 | * Carries a single reading from a sensor |
72 | */ | 109 | */ |
73 | static struct GNUNET_CADET_Handle *cadet; | 110 | struct ClientSensorReading |
111 | { | ||
112 | |||
113 | /** | ||
114 | * Sensor this reading is related to | ||
115 | */ | ||
116 | struct GNUNET_SENSOR_SensorInfo *sensor; | ||
117 | |||
118 | /** | ||
119 | * Timestamp of taking the reading | ||
120 | */ | ||
121 | uint64_t timestamp; | ||
122 | |||
123 | /** | ||
124 | * Reading value | ||
125 | */ | ||
126 | void *value; | ||
127 | |||
128 | /** | ||
129 | * Size of @e value | ||
130 | */ | ||
131 | uint16_t value_size; | ||
132 | |||
133 | }; | ||
134 | |||
74 | 135 | ||
75 | /** | 136 | /** |
76 | * Global hashmap of defined sensors | 137 | * Global hashmap of defined sensors |
@@ -78,6 +139,11 @@ static struct GNUNET_CADET_Handle *cadet; | |||
78 | static struct GNUNET_CONTAINER_MultiHashMap *sensors; | 139 | static struct GNUNET_CONTAINER_MultiHashMap *sensors; |
79 | 140 | ||
80 | /** | 141 | /** |
142 | * Handle to CADET service | ||
143 | */ | ||
144 | static struct GNUNET_CADET_Handle *cadet; | ||
145 | |||
146 | /** | ||
81 | * Handle to the peerstore service connection | 147 | * Handle to the peerstore service connection |
82 | */ | 148 | */ |
83 | static struct GNUNET_PEERSTORE_Handle *peerstore; | 149 | static struct GNUNET_PEERSTORE_Handle *peerstore; |
@@ -99,6 +165,15 @@ static struct ClientPeerContext *cp_tail; | |||
99 | 165 | ||
100 | 166 | ||
101 | /** | 167 | /** |
168 | * Trigger sending next pending message to the given client peer if any. | ||
169 | * | ||
170 | * @param cp client peer context struct | ||
171 | */ | ||
172 | static void | ||
173 | trigger_send_next_msg (struct ClientPeerContext *cp); | ||
174 | |||
175 | |||
176 | /** | ||
102 | * Destroy a given client peer context | 177 | * Destroy a given client peer context |
103 | * | 178 | * |
104 | * @param cp client peer context | 179 | * @param cp client peer context |
@@ -106,7 +181,22 @@ static struct ClientPeerContext *cp_tail; | |||
106 | static void | 181 | static void |
107 | destroy_clientpeer (struct ClientPeerContext *cp) | 182 | destroy_clientpeer (struct ClientPeerContext *cp) |
108 | { | 183 | { |
184 | struct PendingMessage *pm; | ||
185 | |||
109 | cp->destroying = GNUNET_YES; | 186 | cp->destroying = GNUNET_YES; |
187 | if (NULL != cp->th) | ||
188 | { | ||
189 | GNUNET_CADET_notify_transmit_ready_cancel (cp->th); | ||
190 | cp->th = NULL; | ||
191 | } | ||
192 | pm = cp->pm_head; | ||
193 | while (NULL != pm) | ||
194 | { | ||
195 | GNUNET_CONTAINER_DLL_remove (cp->pm_head, cp->pm_tail, pm); | ||
196 | GNUNET_free (pm->msg); | ||
197 | GNUNET_free (pm); | ||
198 | pm = cp->pm_head; | ||
199 | } | ||
110 | if (NULL != cp->ch) | 200 | if (NULL != cp->ch) |
111 | { | 201 | { |
112 | GNUNET_CADET_channel_destroy (cp->ch); | 202 | GNUNET_CADET_channel_destroy (cp->ch); |
@@ -201,6 +291,9 @@ cadet_channel_created (void *cls, | |||
201 | { | 291 | { |
202 | struct ClientPeerContext *cp; | 292 | struct ClientPeerContext *cp; |
203 | 293 | ||
294 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
295 | "Received a channel connection from peer `%s'.\n", | ||
296 | GNUNET_i2s (initiator)); | ||
204 | cp = GNUNET_new (struct ClientPeerContext); | 297 | cp = GNUNET_new (struct ClientPeerContext); |
205 | cp->peerid = *initiator; | 298 | cp->peerid = *initiator; |
206 | cp->ch = channel; | 299 | cp->ch = channel; |
@@ -211,13 +304,168 @@ cadet_channel_created (void *cls, | |||
211 | 304 | ||
212 | 305 | ||
213 | /** | 306 | /** |
307 | * Function called to notify a client about the connection begin ready | ||
308 | * to queue more data. @a buf will be NULL and @a size zero if the | ||
309 | * connection was closed for writing in the meantime. | ||
310 | * | ||
311 | * Perform the actual sending of the message to client peer. | ||
312 | * | ||
313 | * @param cls closure, a `struct ClientPeerContext *` | ||
314 | * @param size number of bytes available in @a buf | ||
315 | * @param buf where the callee should write the message | ||
316 | * @return number of bytes written to @a buf | ||
317 | */ | ||
318 | static size_t | ||
319 | do_send_msg (void *cls, size_t size, void *buf) | ||
320 | { | ||
321 | struct ClientPeerContext *cp = cls; | ||
322 | struct PendingMessage *pm; | ||
323 | size_t msg_size; | ||
324 | |||
325 | cp->th = NULL; | ||
326 | pm = cp->pm_head; | ||
327 | msg_size = ntohs (pm->msg->size); | ||
328 | GNUNET_CONTAINER_DLL_remove (cp->pm_head, cp->pm_tail, pm); | ||
329 | if (NULL == buf || size < msg_size) | ||
330 | { | ||
331 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
332 | _("Error trying to send a message to peer `%s'.\n"), | ||
333 | GNUNET_i2s (&cp->peerid)); | ||
334 | return 0; | ||
335 | } | ||
336 | memcpy (buf, pm->msg, msg_size); | ||
337 | GNUNET_free (pm->msg); | ||
338 | GNUNET_free (pm); | ||
339 | trigger_send_next_msg (cp); | ||
340 | return msg_size; | ||
341 | } | ||
342 | |||
343 | |||
344 | /** | ||
345 | * Trigger sending next pending message to the given client peer if any. | ||
346 | * | ||
347 | * @param cp client peer context struct | ||
348 | */ | ||
349 | static void | ||
350 | trigger_send_next_msg (struct ClientPeerContext *cp) | ||
351 | { | ||
352 | struct PendingMessage *pm; | ||
353 | |||
354 | if (NULL == cp->pm_head) | ||
355 | return; | ||
356 | if (NULL != cp->th) | ||
357 | return; | ||
358 | pm = cp->pm_head; | ||
359 | cp->th = GNUNET_CADET_notify_transmit_ready (cp->ch, | ||
360 | GNUNET_YES, | ||
361 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
362 | ntohs (pm->msg->size), | ||
363 | &do_send_msg, | ||
364 | cp); | ||
365 | } | ||
366 | |||
367 | |||
368 | /** | ||
369 | * Add a new message to the queue to be sent to the given client peer. | ||
370 | * | ||
371 | * @param msg Message to be queued | ||
372 | * @param cp Client peer context | ||
373 | */ | ||
374 | static void | ||
375 | queue_msg (struct GNUNET_MessageHeader *msg, struct ClientPeerContext *cp) | ||
376 | { | ||
377 | struct PendingMessage *pm; | ||
378 | |||
379 | pm = GNUNET_new (struct PendingMessage); | ||
380 | pm->msg = msg; | ||
381 | GNUNET_CONTAINER_DLL_insert_tail (cp->pm_head, cp->pm_tail, pm); | ||
382 | trigger_send_next_msg (cp); | ||
383 | } | ||
384 | |||
385 | |||
386 | /** | ||
387 | * Iterate over defined sensors, creates and sends brief sensor information to | ||
388 | * given client peer over CADET. | ||
389 | * | ||
390 | * @param cls closure, the client peer | ||
391 | * @param key sensor key | ||
392 | * @param value sensor value | ||
393 | * @return #GNUNET_YES to continue iteration | ||
394 | */ | ||
395 | static int | ||
396 | send_sensor_brief (void *cls, | ||
397 | const struct GNUNET_HashCode *key, | ||
398 | void *value) | ||
399 | { | ||
400 | struct ClientPeerContext *cp = cls; | ||
401 | struct GNUNET_SENSOR_SensorInfo *sensor = value; | ||
402 | struct GNUNET_SENSOR_SensorBriefMessage *msg; | ||
403 | uint16_t sensorname_size; | ||
404 | uint16_t total_size; | ||
405 | |||
406 | /* Create message struct */ | ||
407 | sensorname_size = strlen (sensor->name) + 1; | ||
408 | total_size = sizeof (struct GNUNET_SENSOR_SensorBriefMessage) + | ||
409 | sensorname_size; | ||
410 | msg = GNUNET_malloc (total_size); | ||
411 | msg->header.size = htons (total_size); | ||
412 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_BRIEF); | ||
413 | msg->name_size = htons (sensorname_size); | ||
414 | msg->version_major = htons (sensor->version_major); | ||
415 | msg->version_minor = htons (sensor->version_minor); | ||
416 | memcpy (&msg[1], sensor->name, sensorname_size); | ||
417 | /* Queue the msg */ | ||
418 | queue_msg ((struct GNUNET_MessageHeader *)msg, cp); | ||
419 | return GNUNET_YES; | ||
420 | } | ||
421 | |||
422 | |||
423 | /** | ||
424 | * Called with any sensor list request received. | ||
425 | * | ||
426 | * Each time the function must call #GNUNET_CADET_receive_done on the channel | ||
427 | * in order to receive the next message. This doesn't need to be immediate: | ||
428 | * can be delayed if some processing is done on the message. | ||
429 | * | ||
430 | * @param cls Closure (set from #GNUNET_CADET_connect). | ||
431 | * @param channel Connection to the other end. | ||
432 | * @param channel_ctx Place to store local state associated with the channel. | ||
433 | * @param message The actual message. | ||
434 | * @return #GNUNET_OK to keep the channel open, | ||
435 | * #GNUNET_SYSERR to close it (signal serious error). | ||
436 | */ | ||
437 | static int | ||
438 | handle_sensor_list_req (void *cls, | ||
439 | struct GNUNET_CADET_Channel *channel, | ||
440 | void **channel_ctx, | ||
441 | const struct GNUNET_MessageHeader *message) | ||
442 | { | ||
443 | struct ClientPeerContext *cp = *channel_ctx; | ||
444 | struct GNUNET_MessageHeader *end_msg; | ||
445 | |||
446 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
447 | "Received a sensor list request from peer `%s'.\n", | ||
448 | GNUNET_i2s (&cp->peerid)); | ||
449 | GNUNET_CONTAINER_multihashmap_iterate (sensors, | ||
450 | &send_sensor_brief, | ||
451 | cp); | ||
452 | end_msg = GNUNET_new (struct GNUNET_MessageHeader); | ||
453 | end_msg->size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
454 | end_msg->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_END); | ||
455 | queue_msg (end_msg, cp); | ||
456 | GNUNET_CADET_receive_done (channel); | ||
457 | return GNUNET_OK; | ||
458 | } | ||
459 | |||
460 | |||
461 | /** | ||
214 | * Parses a sensor reading message struct | 462 | * Parses a sensor reading message struct |
215 | * | 463 | * |
216 | * @param msg message header received | 464 | * @param msg message header received |
217 | * @param sensors multihashmap of loaded sensors | 465 | * @param sensors multihashmap of loaded sensors |
218 | * @return sensor reading struct or NULL if error | 466 | * @return sensor reading struct or NULL if error |
219 | */ | 467 | */ |
220 | static struct GNUNET_SENSOR_Reading * | 468 | static struct ClientSensorReading * |
221 | parse_reading_message (const struct GNUNET_MessageHeader *msg, | 469 | parse_reading_message (const struct GNUNET_MessageHeader *msg, |
222 | struct GNUNET_CONTAINER_MultiHashMap *sensors) | 470 | struct GNUNET_CONTAINER_MultiHashMap *sensors) |
223 | { | 471 | { |
@@ -229,7 +477,7 @@ parse_reading_message (const struct GNUNET_MessageHeader *msg, | |||
229 | char *sensorname; | 477 | char *sensorname; |
230 | struct GNUNET_HashCode key; | 478 | struct GNUNET_HashCode key; |
231 | struct GNUNET_SENSOR_SensorInfo *sensor; | 479 | struct GNUNET_SENSOR_SensorInfo *sensor; |
232 | struct GNUNET_SENSOR_Reading *reading; | 480 | struct ClientSensorReading *reading; |
233 | 481 | ||
234 | msg_size = ntohs (msg->size); | 482 | msg_size = ntohs (msg->size); |
235 | if (msg_size < sizeof (struct GNUNET_SENSOR_ReadingMessage)) | 483 | if (msg_size < sizeof (struct GNUNET_SENSOR_ReadingMessage)) |
@@ -272,7 +520,7 @@ parse_reading_message (const struct GNUNET_MessageHeader *msg, | |||
272 | "Invalid value size for a numerical sensor.\n"); | 520 | "Invalid value size for a numerical sensor.\n"); |
273 | return NULL; | 521 | return NULL; |
274 | } | 522 | } |
275 | reading = GNUNET_new (struct GNUNET_SENSOR_Reading); | 523 | reading = GNUNET_new (struct ClientSensorReading); |
276 | reading->sensor = sensor; | 524 | reading->sensor = sensor; |
277 | reading->timestamp = GNUNET_be64toh (rm->timestamp); | 525 | reading->timestamp = GNUNET_be64toh (rm->timestamp); |
278 | reading->value_size = value_size; | 526 | reading->value_size = value_size; |
@@ -304,7 +552,7 @@ handle_sensor_reading (void *cls, | |||
304 | const struct GNUNET_MessageHeader *message) | 552 | const struct GNUNET_MessageHeader *message) |
305 | { | 553 | { |
306 | struct ClientPeerContext *cp = *channel_ctx; | 554 | struct ClientPeerContext *cp = *channel_ctx; |
307 | struct GNUNET_SENSOR_Reading *reading; | 555 | struct ClientSensorReading *reading; |
308 | 556 | ||
309 | reading = parse_reading_message (message, sensors); | 557 | reading = parse_reading_message (message, sensors); |
310 | if (NULL == reading) | 558 | if (NULL == reading) |
@@ -335,32 +583,6 @@ handle_sensor_reading (void *cls, | |||
335 | 583 | ||
336 | 584 | ||
337 | /** | 585 | /** |
338 | * Called with any sensor list request received. | ||
339 | * | ||
340 | * Each time the function must call #GNUNET_CADET_receive_done on the channel | ||
341 | * in order to receive the next message. This doesn't need to be immediate: | ||
342 | * can be delayed if some processing is done on the message. | ||
343 | * | ||
344 | * @param cls Closure (set from #GNUNET_CADET_connect). | ||
345 | * @param channel Connection to the other end. | ||
346 | * @param channel_ctx Place to store local state associated with the channel. | ||
347 | * @param message The actual message. | ||
348 | * @return #GNUNET_OK to keep the channel open, | ||
349 | * #GNUNET_SYSERR to close it (signal serious error). | ||
350 | */ | ||
351 | static int | ||
352 | handle_sensor_list_req (void *cls, | ||
353 | struct GNUNET_CADET_Channel *channel, | ||
354 | void **channel_ctx, | ||
355 | const struct GNUNET_MessageHeader *message) | ||
356 | { | ||
357 | //TODO | ||
358 | GNUNET_CADET_receive_done (channel); | ||
359 | return GNUNET_OK; | ||
360 | } | ||
361 | |||
362 | |||
363 | /** | ||
364 | * Process sensordashboard requests. | 586 | * Process sensordashboard requests. |
365 | * | 587 | * |
366 | * @param cls closure | 588 | * @param cls closure |