aboutsummaryrefslogtreecommitdiff
path: root/src/sensordashboard
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-07-25 11:42:08 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-07-25 11:42:08 +0000
commitac2af3883bbceafd3258cad788587a70057010d9 (patch)
treeeee0f1dec96321d13373c0090bfe17b708cca875 /src/sensordashboard
parent98638edc1f1013173895fde63443a667525c58be (diff)
downloadgnunet-ac2af3883bbceafd3258cad788587a70057010d9.tar.gz
gnunet-ac2af3883bbceafd3258cad788587a70057010d9.zip
sensor: towards update functionality
Diffstat (limited to 'src/sensordashboard')
-rw-r--r--src/sensordashboard/gnunet-service-sensordashboard.c286
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 */
87struct 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 */
73static struct GNUNET_CADET_Handle *cadet; 110struct 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;
78static struct GNUNET_CONTAINER_MultiHashMap *sensors; 139static struct GNUNET_CONTAINER_MultiHashMap *sensors;
79 140
80/** 141/**
142 * Handle to CADET service
143 */
144static struct GNUNET_CADET_Handle *cadet;
145
146/**
81 * Handle to the peerstore service connection 147 * Handle to the peerstore service connection
82 */ 148 */
83static struct GNUNET_PEERSTORE_Handle *peerstore; 149static 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 */
172static void
173trigger_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;
106static void 181static void
107destroy_clientpeer (struct ClientPeerContext *cp) 182destroy_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 */
318static size_t
319do_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 */
349static void
350trigger_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 */
374static void
375queue_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 */
395static int
396send_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 */
437static int
438handle_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 */
220static struct GNUNET_SENSOR_Reading * 468static struct ClientSensorReading *
221parse_reading_message (const struct GNUNET_MessageHeader *msg, 469parse_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 */
351static int
352handle_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