aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-08-11 18:39:39 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-08-11 18:39:39 +0000
commitd26fff163ec1d081db3293daf9dd566e74f3fde5 (patch)
treecc8f0de5a3fc57bebcdcb30f28bcd48ff405ee30 /src
parent321e66a9d999edaed3fff1a707d212f750fb40a1 (diff)
downloadgnunet-d26fff163ec1d081db3293daf9dd566e74f3fde5.tar.gz
gnunet-d26fff163ec1d081db3293daf9dd566e74f3fde5.zip
sensor: api changes
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_protocols.h6
-rw-r--r--src/include/gnunet_sensor_service.h45
-rw-r--r--src/sensor/gnunet-sensor.c14
-rw-r--r--src/sensor/gnunet-service-sensor.c10
-rw-r--r--src/sensor/sensor.conf.in2
-rw-r--r--src/sensor/sensor.h31
-rw-r--r--src/sensor/sensor_api.c632
7 files changed, 293 insertions, 447 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 246f7f836..176391580 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -2452,6 +2452,12 @@ extern "C"
2452 */ 2452 */
2453#define GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_REPORT 809 2453#define GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_REPORT 809
2454 2454
2455/**
2456 * Message sent from API to service to force a new sensor anomaly status
2457 * (For testing purposes only)
2458 */
2459#define GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_FORCE 810
2460
2455 2461
2456/******************************************************************************* 2462/*******************************************************************************
2457 * PEERSTORE message types 2463 * PEERSTORE message types
diff --git a/src/include/gnunet_sensor_service.h b/src/include/gnunet_sensor_service.h
index 4ef2885e6..a31b20e52 100644
--- a/src/include/gnunet_sensor_service.h
+++ b/src/include/gnunet_sensor_service.h
@@ -44,6 +44,11 @@ extern "C"
44struct GNUNET_SENSOR_Handle; 44struct GNUNET_SENSOR_Handle;
45 45
46/** 46/**
47 * Context for an iteration request.
48 */
49struct GNUNET_SENSOR_IterateContext;
50
51/**
47 * Structure containing brief info about sensor 52 * Structure containing brief info about sensor
48 */ 53 */
49struct SensorInfoShort 54struct SensorInfoShort
@@ -72,13 +77,13 @@ struct SensorInfoShort
72}; 77};
73 78
74/** 79/**
75 * Type of an iterator over sensor definitions. 80 * Sensor iterate request callback.
76 * 81 *
77 * @param cls closure 82 * @param cls closure
78 * @param hello hello message for the peer (can be NULL) 83 * @param sensor Brief sensor information
79 * @param error message 84 * @param error message
80 */ 85 */
81typedef void (*GNUNET_SENSOR_SensorIteratorCB) (void *cls, 86typedef void (*GNUNET_SENSOR_SensorIterateCB) (void *cls,
82 const struct SensorInfoShort * 87 const struct SensorInfoShort *
83 sensor, const char *err_msg); 88 sensor, const char *err_msg);
84 89
@@ -93,6 +98,15 @@ typedef void (*GNUNET_SENSOR_Continuation) (void *cls, const char *emsg);
93 98
94 99
95/** 100/**
101 * Disconnect from the sensor service
102 *
103 * @param h handle to disconnect
104 */
105void
106GNUNET_SENSOR_disconnect (struct GNUNET_SENSOR_Handle *h);
107
108
109/**
96 * Connect to the sensor service. 110 * Connect to the sensor service.
97 * 111 *
98 * @return NULL on error 112 * @return NULL on error
@@ -102,30 +116,33 @@ GNUNET_SENSOR_connect (const struct GNUNET_CONFIGURATION_Handle *cfg);
102 116
103 117
104/** 118/**
105 * Disconnect from the sensor service 119 * Cancel an iteration request.
120 * This should be called before the iterate callback is called with a NULL value.
106 * 121 *
107 * @param h handle to disconnect 122 * @param ic context of the iterator to cancel
108 */ 123 */
109void 124void
110GNUNET_SENSOR_disconnect (struct GNUNET_SENSOR_Handle *h); 125GNUNET_SENSOR_iterate_cancel (struct GNUNET_SENSOR_IterateContext
126 *ic);
111 127
112 128
113/** 129/**
114 * Client asking to iterate all available sensors 130 * Get one or all sensors loaded by the sensor service.
131 * The callback will be called with each sensor received and once with a NULL
132 * value to signal end of iteration.
115 * 133 *
116 * @param h Handle to SENSOR service 134 * @param h Handle to SENSOR service
117 * @param timeout how long to wait until timing out 135 * @param timeout how long to wait until timing out
118 * @param sensorname information on one sensor only, can be NULL to get all 136 * @param sensorname Name of the required sensor, NULL to get all
119 * @param sensorname_len length of the sensorname parameter 137 * @param callback the function to call for each sensor
120 * @param callback the method to call for each sensor
121 * @param callback_cls closure for callback 138 * @param callback_cls closure for callback
122 * @return iterator context 139 * @return iterator context
123 */ 140 */
124struct GNUNET_SENSOR_SensorIteratorContext * 141struct GNUNET_SENSOR_IterateContext *
125GNUNET_SENSOR_iterate_sensors (struct GNUNET_SENSOR_Handle *h, 142GNUNET_SENSOR_iterate (struct GNUNET_SENSOR_Handle *h,
126 struct GNUNET_TIME_Relative timeout, 143 struct GNUNET_TIME_Relative timeout,
127 const char *sensorname, size_t sensorname_len, 144 const char *sensor_name,
128 GNUNET_SENSOR_SensorIteratorCB callback, 145 GNUNET_SENSOR_SensorIterateCB callback,
129 void *callback_cls); 146 void *callback_cls);
130 147
131#if 0 /* keep Emacsens' auto-indent happy */ 148#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/sensor/gnunet-sensor.c b/src/sensor/gnunet-sensor.c
index ffd61f8b4..ec7b5cb9e 100644
--- a/src/sensor/gnunet-sensor.c
+++ b/src/sensor/gnunet-sensor.c
@@ -79,7 +79,10 @@ print_sensor_info (void *cls, const struct SensorInfoShort *sensor,
79 return; 79 return;
80 } 80 }
81 if (NULL == sensor) /* no more sensors from service */ 81 if (NULL == sensor) /* no more sensors from service */
82 {
83 GNUNET_SCHEDULER_shutdown ();
82 return; 84 return;
85 }
83 printf ("Name: %s\nVersion: %d.%d\n", sensor->name, sensor->version_major, 86 printf ("Name: %s\nVersion: %d.%d\n", sensor->name, sensor->version_major,
84 sensor->version_minor); 87 sensor->version_minor);
85 if (NULL != sensor->description) 88 if (NULL != sensor->description)
@@ -107,17 +110,14 @@ run (void *cls, char *const *args, const char *cfgfile,
107 GNUNET_assert (NULL != sensor_handle); 110 GNUNET_assert (NULL != sensor_handle);
108 if (GNUNET_YES == get_all) 111 if (GNUNET_YES == get_all)
109 { 112 {
110 GNUNET_SENSOR_iterate_sensors (sensor_handle, GNUNET_TIME_UNIT_FOREVER_REL, 113 GNUNET_SENSOR_iterate (sensor_handle, GNUNET_TIME_UNIT_FOREVER_REL, NULL,
111 NULL, 0, &print_sensor_info, NULL); 114 &print_sensor_info, NULL);
112 } 115 }
113 else if (NULL != get_sensor) 116 else if (NULL != get_sensor)
114 { 117 {
115 GNUNET_SENSOR_iterate_sensors (sensor_handle, GNUNET_TIME_UNIT_FOREVER_REL, 118 GNUNET_SENSOR_iterate (sensor_handle, GNUNET_TIME_UNIT_FOREVER_REL,
116 get_sensor, strlen (get_sensor), 119 get_sensor, &print_sensor_info, NULL);
117 &print_sensor_info, NULL);
118 } 120 }
119
120 GNUNET_SCHEDULER_shutdown ();
121 ret = 0; 121 ret = 0;
122} 122}
123 123
diff --git a/src/sensor/gnunet-service-sensor.c b/src/sensor/gnunet-service-sensor.c
index b404d4806..ce6fa04fc 100644
--- a/src/sensor/gnunet-service-sensor.c
+++ b/src/sensor/gnunet-service-sensor.c
@@ -286,7 +286,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
286 286
287 cfg = c; 287 cfg = c;
288 if (GNUNET_OK != 288 if (GNUNET_OK !=
289 GNUNET_CONFIGURATION_get_value_filename (cfg, "SENSOR", "SENSOR_DIR", 289 GNUNET_CONFIGURATION_get_value_filename (cfg, "sensor", "SENSOR_DIR",
290 &sensor_dir)) 290 &sensor_dir))
291 { 291 {
292 sensor_dir = GNUNET_SENSOR_get_default_sensor_dir (); 292 sensor_dir = GNUNET_SENSOR_get_default_sensor_dir ();
@@ -296,22 +296,22 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
296 start_reporting = GNUNET_YES; 296 start_reporting = GNUNET_YES;
297 start_update = GNUNET_YES; 297 start_update = GNUNET_YES;
298 if (GNUNET_NO == 298 if (GNUNET_NO ==
299 GNUNET_CONFIGURATION_get_value_yesno (cfg, "SENSOR", "START_MONITORING")) 299 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_MONITORING"))
300 { 300 {
301 start_monitoring = GNUNET_NO; 301 start_monitoring = GNUNET_NO;
302 } 302 }
303 if (GNUNET_NO == 303 if (GNUNET_NO ==
304 GNUNET_CONFIGURATION_get_value_yesno (cfg, "SENSOR", "START_REPORTING")) 304 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_REPORTING"))
305 { 305 {
306 start_reporting = GNUNET_NO; 306 start_reporting = GNUNET_NO;
307 } 307 }
308 if (GNUNET_NO == 308 if (GNUNET_NO ==
309 GNUNET_CONFIGURATION_get_value_yesno (cfg, "SENSOR", "START_ANALYSIS")) 309 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_ANALYSIS"))
310 { 310 {
311 start_analysis = GNUNET_NO; 311 start_analysis = GNUNET_NO;
312 } 312 }
313 if (GNUNET_NO == 313 if (GNUNET_NO ==
314 GNUNET_CONFIGURATION_get_value_yesno (cfg, "SENSOR", "START_UPDATE")) 314 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_UPDATE"))
315 { 315 {
316 start_update = GNUNET_NO; 316 start_update = GNUNET_NO;
317 } 317 }
diff --git a/src/sensor/sensor.conf.in b/src/sensor/sensor.conf.in
index 12b5b4d35..a2bfe8a8e 100644
--- a/src/sensor/sensor.conf.in
+++ b/src/sensor/sensor.conf.in
@@ -9,7 +9,7 @@ UNIX_MATCH_GID = YES
9START_MONITORING = YES 9START_MONITORING = YES
10START_REPORTING = YES 10START_REPORTING = YES
11START_ANALYSIS = YES 11START_ANALYSIS = YES
12STARTING_UPDATE = YES 12START_UPDATE = YES
13 13
14# Path to directory containing sensor definitions. 14# Path to directory containing sensor definitions.
15# If not set, will load from default location. 15# If not set, will load from default location.
diff --git a/src/sensor/sensor.h b/src/sensor/sensor.h
index 0b8daaa2c..521f931ce 100644
--- a/src/sensor/sensor.h
+++ b/src/sensor/sensor.h
@@ -40,9 +40,9 @@ GNUNET_NETWORK_STRUCT_BEGIN
40 struct GNUNET_MessageHeader header; 40 struct GNUNET_MessageHeader header;
41 41
42 /** 42 /**
43 * Length of sensor name (name follows the struct) 43 * Length of sensor name. Allocated at position 0 after this struct.
44 */ 44 */
45 size_t name_len; 45 uint16_t name_len;
46 46
47 /** 47 /**
48 * First part of version number 48 * First part of version number
@@ -55,9 +55,32 @@ GNUNET_NETWORK_STRUCT_BEGIN
55 uint16_t version_minor; 55 uint16_t version_minor;
56 56
57 /** 57 /**
58 * Length of sensor description (description itself follows) 58 * Length of sensor description. Allocated at position 1 after this struct.
59 */ 59 */
60 size_t description_len; 60 uint16_t description_len;
61};
62
63/**
64 * A message sent to the sensor service to force an anomaly status on a sensor.
65 */
66struct ForceAnomalyMessage
67{
68
69 /**
70 * Message header
71 */
72 struct GNUNET_MessageHeader header;
73
74 /**
75 * Hash of the sensor name
76 */
77 struct GNUNET_HashCode sensor_name_hash;
78
79 /**
80 * New status
81 */
82 uint16_t anomalous;
83
61}; 84};
62 85
63GNUNET_NETWORK_STRUCT_END 86GNUNET_NETWORK_STRUCT_END
diff --git a/src/sensor/sensor_api.c b/src/sensor/sensor_api.c
index a143df087..b7ee55fb6 100644
--- a/src/sensor/sensor_api.c
+++ b/src/sensor/sensor_api.c
@@ -20,7 +20,7 @@
20 20
21/** 21/**
22 * @file sensor/sensor_api.c 22 * @file sensor/sensor_api.c
23 * @brief API for sensor 23 * @brief API for sensor service
24 * @author Omar Tarabai 24 * @author Omar Tarabai
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
@@ -29,10 +29,6 @@
29 29
30#define LOG(kind,...) GNUNET_log_from (kind, "sensor-api",__VA_ARGS__) 30#define LOG(kind,...) GNUNET_log_from (kind, "sensor-api",__VA_ARGS__)
31 31
32/******************************************************************************/
33/************************ DATA STRUCTURES ****************************/
34/******************************************************************************/
35
36/** 32/**
37 * Handle to the sensor service. 33 * Handle to the sensor service.
38 */ 34 */
@@ -50,95 +46,37 @@ struct GNUNET_SENSOR_Handle
50 struct GNUNET_CLIENT_Connection *client; 46 struct GNUNET_CLIENT_Connection *client;
51 47
52 /** 48 /**
53 * Head of transmission queue.
54 */
55 struct GNUNET_SENSOR_RequestContext *rc_head;
56
57 /**
58 * Tail of transmission queue.
59 */
60 struct GNUNET_SENSOR_RequestContext *rc_tail;
61
62 /**
63 * Handle for the current transmission request, or NULL if none is pending.
64 */
65 struct GNUNET_CLIENT_TransmitHandle *th;
66
67 /**
68 * Head of iterator DLL. 49 * Head of iterator DLL.
69 */ 50 */
70 struct GNUNET_SENSOR_SensorIteratorContext *ic_head; 51 struct GNUNET_SENSOR_IterateContext *ic_head;
71 52
72 /** 53 /**
73 * Tail of iterator DLL. 54 * Tail of iterator DLL.
74 */ 55 */
75 struct GNUNET_SENSOR_SensorIteratorContext *ic_tail; 56 struct GNUNET_SENSOR_IterateContext *ic_tail;
76
77 /**
78 * ID for a reconnect task.
79 */
80 GNUNET_SCHEDULER_TaskIdentifier r_task;
81 57
82 /** 58 /**
83 * Are we now receiving? 59 * Message queue used to send data to service
84 */ 60 */
85 int in_receive; 61 struct GNUNET_MQ_Handle *mq;
86
87};
88
89/**
90 * Entry in the transmission queue to SENSOR service.
91 *
92 */
93struct GNUNET_SENSOR_RequestContext
94{
95 /**
96 * This is a linked list.
97 */
98 struct GNUNET_SENSOR_RequestContext *next;
99
100 /**
101 * This is a linked list.
102 */
103 struct GNUNET_SENSOR_RequestContext *prev;
104
105 /**
106 * Handle to the SENSOR service.
107 */
108 struct GNUNET_SENSOR_Handle *h;
109
110 /**
111 * Function to call after request has been transmitted, or NULL.
112 */
113 GNUNET_SENSOR_Continuation cont;
114
115 /**
116 * Closure for 'cont'.
117 */
118 void *cont_cls;
119
120 /**
121 * Number of bytes of the request message (follows after this struct).
122 */
123 size_t size;
124 62
125}; 63};
126 64
127/** 65/**
128 * Context for an iteration request. 66 * Context for an iteration request.
129 */ 67 */
130struct GNUNET_SENSOR_SensorIteratorContext 68struct GNUNET_SENSOR_IterateContext
131{ 69{
132 70
133 /** 71 /**
134 * Kept in a DLL. 72 * Kept in a DLL.
135 */ 73 */
136 struct GNUNET_SENSOR_SensorIteratorContext *next; 74 struct GNUNET_SENSOR_IterateContext *next;
137 75
138 /** 76 /**
139 * Kept in a DLL. 77 * Kept in a DLL.
140 */ 78 */
141 struct GNUNET_SENSOR_SensorIteratorContext *prev; 79 struct GNUNET_SENSOR_IterateContext *prev;
142 80
143 /** 81 /**
144 * Handle to the SENSOR service. 82 * Handle to the SENSOR service.
@@ -148,7 +86,7 @@ struct GNUNET_SENSOR_SensorIteratorContext
148 /** 86 /**
149 * Function to call with the results. 87 * Function to call with the results.
150 */ 88 */
151 GNUNET_SENSOR_SensorIteratorCB callback; 89 GNUNET_SENSOR_SensorIterateCB callback;
152 90
153 /** 91 /**
154 * Closure for 'callback'. 92 * Closure for 'callback'.
@@ -156,174 +94,193 @@ struct GNUNET_SENSOR_SensorIteratorContext
156 void *callback_cls; 94 void *callback_cls;
157 95
158 /** 96 /**
159 * Our entry in the transmission queue. 97 * Envelope containing iterate request.
160 */ 98 */
161 struct GNUNET_SENSOR_RequestContext *rc; 99 struct GNUNET_MQ_Envelope *ev;
162 100
163 /** 101 /**
164 * Task responsible for timeout. 102 * Is the request already sent? If yes, cannot be canceled.
165 */ 103 */
166 GNUNET_SCHEDULER_TaskIdentifier timeout_task; 104 int request_sent;
167 105
168 /** 106 /**
169 * Timeout for the operation. 107 * Are we expecting records from service?
170 */ 108 */
171 struct GNUNET_TIME_Absolute timeout; 109 int receiving;
172 110
173 /** 111 /**
174 * Set to GNUNET_YES if we are currently receiving replies from the 112 * Task responsible for timeout.
175 * service.
176 */ 113 */
177 int request_transmitted; 114 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
178 115
179}; 116};
180 117
181/******************************************************************************/
182/*********************** DECLARATIONS *************************/
183/******************************************************************************/
184
185/**
186 * Close the existing connection to SENSOR and reconnect.
187 *
188 * @param h handle to the service
189 */
190static void
191reconnect (struct GNUNET_SENSOR_Handle *h);
192
193 118
194/** 119/**
195 * Check if we have a request pending in the transmission queue and are 120 * Notifier of an error encountered by MQ.
196 * able to transmit it right now. If so, schedule transmission.
197 * 121 *
198 * @param h handle to the service 122 * @param cls Closure, service handle
123 * @param error MQ error type
199 */ 124 */
200static void 125static void
201trigger_transmit (struct GNUNET_SENSOR_Handle *h); 126mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
202
203/******************************************************************************/
204/******************* CONNECTION FUNCTIONS *********************/
205/******************************************************************************/
206
207/**
208 * Connect to the sensor service.
209 *
210 * @return NULL on error
211 */
212struct GNUNET_SENSOR_Handle *
213GNUNET_SENSOR_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
214{ 127{
215 struct GNUNET_CLIENT_Connection *client; 128 struct GNUNET_SENSOR_Handle *h = cls;
216 struct GNUNET_SENSOR_Handle *h;
217 129
218 client = GNUNET_CLIENT_connect ("sensor", cfg); 130 LOG (GNUNET_ERROR_TYPE_ERROR,
219 if (NULL == client) 131 _("Received an error notification from MQ of type: %d\n"), error);
220 return NULL; 132 GNUNET_SENSOR_disconnect (h); //TODO: try to reconnect
221 h = GNUNET_new (struct GNUNET_SENSOR_Handle);
222 h->client = client;
223 h->cfg = cfg;
224 return h;
225} 133}
226 134
227 135
228/** 136/**
229 * Disconnect from the sensor service 137 * Handler to a message of type: #GNUNET_MESSAGE_TYPE_SENSOR_END
230 * 138 *
231 * @param h handle to disconnect 139 * @param cls Closure, service handle
140 * @param msg Message received
232 */ 141 */
233void 142static void
234GNUNET_SENSOR_disconnect (struct GNUNET_SENSOR_Handle *h) 143handle_end (void *cls, const struct GNUNET_MessageHeader *msg)
235{ 144{
236 if (NULL != h->client) 145 struct GNUNET_SENSOR_Handle *h = cls;
146 struct GNUNET_SENSOR_IterateContext *ic;
147 GNUNET_SENSOR_SensorIterateCB cb;
148 void *cb_cls;
149
150 if (NULL == h->ic_head)
237 { 151 {
238 GNUNET_CLIENT_disconnect (h->client); 152 GNUNET_break_op (0);
239 h->client = NULL; 153 //TODO: reconnect
154 return;
240 } 155 }
241 GNUNET_free (h); 156 ic = h->ic_head;
157 cb = ic->callback;
158 cb_cls = ic->callback_cls;
159 ic->receiving = GNUNET_NO;
160 GNUNET_SENSOR_iterate_cancel (ic);
161 if (NULL != cb)
162 cb (cb_cls, NULL, NULL);
242} 163}
243 164
244 165
245/** 166/**
246 * Task scheduled to re-try connecting to the sensor service. 167 * Handler to a message of type: #GNUNET_MESSAGE_TYPE_SENSOR_INFO
247 * 168 *
248 * @param cls the 'struct GNUNET_SENSOR_Handle' 169 * @param cls Closure, service handle
249 * @param tc scheduler context 170 * @param msg Message received
250 */ 171 */
251static void 172static void
252reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 173handle_sensor_info (void *cls, const struct GNUNET_MessageHeader *msg)
253{ 174{
254 struct GNUNET_SENSOR_Handle *h = cls; 175 struct GNUNET_SENSOR_Handle *h = cls;
176 struct GNUNET_SENSOR_IterateContext *ic;
177 uint16_t msg_size;
178 struct SensorInfoMessage *sensor_msg;
179 uint16_t sensor_name_len;
180 uint16_t sensor_desc_len;
181 struct SensorInfoShort *sensor;
182 void *dummy;
255 183
256 h->r_task = GNUNET_SCHEDULER_NO_TASK; 184 if (NULL == h->ic_head)
257 reconnect (h); 185 {
186 GNUNET_break_op (0);
187 //TODO: reconnect
188 return;
189 }
190 ic = h->ic_head;
191 if (NULL == ic->callback) /* no need to parse message */
192 return;
193 msg_size = ntohs (msg->size);
194 if (msg_size < sizeof (struct SensorInfoMessage))
195 {
196 GNUNET_break_op (0);
197 //TODO: reconnect
198 return;
199 }
200 sensor_msg = (struct SensorInfoMessage *) msg;
201 sensor_name_len = ntohs (sensor_msg->name_len);
202 sensor_desc_len = ntohs (sensor_msg->description_len);
203 if (msg_size !=
204 sizeof (struct SensorInfoMessage) + sensor_name_len + sensor_desc_len)
205 {
206 GNUNET_break_op (0);
207 //TODO: reconnect
208 return;
209 }
210 sensor = GNUNET_new (struct SensorInfoShort);
211 sensor->version_major = ntohs (sensor_msg->version_major);
212 sensor->version_minor = ntohs (sensor_msg->version_minor);
213 dummy = &sensor_msg[1];
214 sensor->name = GNUNET_strndup (dummy, sensor_name_len);
215 dummy += sensor_name_len;
216 sensor->description = GNUNET_strndup (dummy, sensor_desc_len);
217 ic->callback (ic->callback_cls, sensor, NULL);
218 GNUNET_free (sensor->name);
219 GNUNET_free (sensor->description);
220 GNUNET_free (sensor);
258} 221}
259 222
260 223
261/** 224/**
262 * Close the existing connection to SENSOR and reconnect. 225 * Disconnect from the sensor service
263 * 226 *
264 * @param h handle to the service 227 * @param h handle to disconnect
265 */ 228 */
266static void 229void
267reconnect (struct GNUNET_SENSOR_Handle *h) 230GNUNET_SENSOR_disconnect (struct GNUNET_SENSOR_Handle *h)
268{ 231{
269 if (GNUNET_SCHEDULER_NO_TASK != h->r_task) 232 struct GNUNET_SENSOR_IterateContext *ic;
233
234 ic = h->ic_head;
235 while (NULL != ic)
270 { 236 {
271 GNUNET_SCHEDULER_cancel (h->r_task); 237 if (NULL != ic->callback)
272 h->r_task = GNUNET_SCHEDULER_NO_TASK; 238 ic->callback (ic->callback_cls, NULL,
239 _("Iterate request canceled due to disconnection.\n"));
240 GNUNET_SENSOR_iterate_cancel (ic);
241 ic = h->ic_head;
273 } 242 }
274 if (NULL != h->th) 243 if (NULL != h->mq)
275 { 244 {
276 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); 245 GNUNET_MQ_destroy (h->mq);
277 h->th = NULL; 246 h->mq = NULL;
278 } 247 }
279 if (NULL != h->client) 248 if (NULL != h->client)
280 { 249 {
281 GNUNET_CLIENT_disconnect (h->client); 250 GNUNET_CLIENT_disconnect (h->client);
282 h->client = NULL; 251 h->client = NULL;
283 } 252 }
284 h->in_receive = GNUNET_NO; 253 GNUNET_free (h);
285 h->client = GNUNET_CLIENT_connect ("sensor", h->cfg);
286 if (NULL == h->client)
287 {
288 h->r_task =
289 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect_task,
290 h);
291 return;
292 }
293 trigger_transmit (h);
294} 254}
295 255
296/******************************************************************************/
297/****************** SENSOR DATA FUNCTIONS *********************/
298/******************************************************************************/
299 256
300/** 257/**
301 * Cancel an iteration over sensor information. 258 * Connect to the sensor service.
302 * 259 *
303 * @param ic context of the iterator to cancel 260 * @return NULL on error
304 */ 261 */
305void 262struct GNUNET_SENSOR_Handle *
306GNUNET_SENSOR_iterate_sensor_cancel (struct GNUNET_SENSOR_SensorIteratorContext 263GNUNET_SENSOR_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
307 *ic)
308{ 264{
265 struct GNUNET_CLIENT_Connection *client;
309 struct GNUNET_SENSOR_Handle *h; 266 struct GNUNET_SENSOR_Handle *h;
310 267
311 h = ic->h; 268 static const struct GNUNET_MQ_MessageHandler mq_handlers[] = {
312 if (GNUNET_SCHEDULER_NO_TASK != ic->timeout_task) 269 {&handle_sensor_info, GNUNET_MESSAGE_TYPE_SENSOR_INFO, 0},
313 { 270 {&handle_end, GNUNET_MESSAGE_TYPE_SENSOR_END, 0},
314 GNUNET_SCHEDULER_cancel (ic->timeout_task); 271 GNUNET_MQ_HANDLERS_END
315 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK; 272 };
316 } 273
317 ic->callback = NULL; 274 client = GNUNET_CLIENT_connect ("sensor", cfg);
318 if (GNUNET_YES == ic->request_transmitted) 275 if (NULL == client)
319 return; /* need to finish processing */ 276 return NULL;
320 GNUNET_CONTAINER_DLL_remove (h->ic_head, h->ic_tail, ic); 277 h = GNUNET_new (struct GNUNET_SENSOR_Handle);
321 if (NULL != ic->rc) 278 h->client = client;
322 { 279 h->cfg = cfg;
323 GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, ic->rc); 280 h->mq =
324 GNUNET_free (ic->rc); 281 GNUNET_MQ_queue_for_connection_client (h->client, mq_handlers,
325 } 282 &mq_error_handler, h);
326 GNUNET_free (ic); 283 return h;
327} 284}
328 285
329 286
@@ -337,14 +294,14 @@ static void
337signal_sensor_iteration_timeout (void *cls, 294signal_sensor_iteration_timeout (void *cls,
338 const struct GNUNET_SCHEDULER_TaskContext *tc) 295 const struct GNUNET_SCHEDULER_TaskContext *tc)
339{ 296{
340 struct GNUNET_SENSOR_SensorIteratorContext *ic = cls; 297 struct GNUNET_SENSOR_IterateContext *ic = cls;
341 GNUNET_SENSOR_SensorIteratorCB cb; 298 GNUNET_SENSOR_SensorIterateCB cb;
342 void *cb_cls; 299 void *cb_cls;
343 300
344 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK; 301 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
345 cb = ic->callback; 302 cb = ic->callback;
346 cb_cls = ic->callback_cls; 303 cb_cls = ic->callback_cls;
347 GNUNET_SENSOR_iterate_sensor_cancel (ic); 304 GNUNET_SENSOR_iterate_cancel (ic);
348 if (NULL != cb) 305 if (NULL != cb)
349 cb (cb_cls, NULL, 306 cb (cb_cls, NULL,
350 _("Timeout transmitting iteration request to `SENSOR' service.")); 307 _("Timeout transmitting iteration request to `SENSOR' service."));
@@ -352,289 +309,132 @@ signal_sensor_iteration_timeout (void *cls,
352 309
353 310
354/** 311/**
355 * Type of a function to call when we receive a message from the 312 * Callback from MQ when the request has already been sent to the service.
356 * service. Call the iterator with the result and (if applicable) 313 * Now it can not be canelled.
357 * continue to receive more messages or trigger processing the next
358 * event (if applicable).
359 * 314 *
360 * @param cls closure 315 * @param cls closure
361 * @param msg message received, NULL on timeout or fatal error
362 */ 316 */
363static void 317static void
364sensor_handler (void *cls, const struct GNUNET_MessageHeader *msg) 318iterate_request_sent (void *cls)
365{ 319{
366 struct GNUNET_SENSOR_Handle *h = cls; 320 struct GNUNET_SENSOR_IterateContext *ic = cls;
367 struct GNUNET_SENSOR_SensorIteratorContext *ic = h->ic_head;
368 GNUNET_SENSOR_SensorIteratorCB cb;
369 void *cb_cls;
370 uint16_t ms;
371 const struct SensorInfoMessage *im;
372 struct SensorInfoShort *sensor;
373 size_t name_len;
374 size_t desc_len;
375 char *str_ptr;
376 321
377 h->in_receive = GNUNET_NO; 322 ic->request_sent = GNUNET_YES;
378 if (NULL == msg) 323 ic->ev = NULL;
379 { 324 ic->receiving = GNUNET_YES;
380 /* sensor service died, signal error */
381 if (NULL != ic)
382 {
383 cb = ic->callback;
384 cb_cls = ic->callback_cls;
385 GNUNET_SENSOR_iterate_sensor_cancel (ic);
386 }
387 else
388 {
389 cb = NULL;
390 }
391 reconnect (h);
392 if (NULL != cb)
393 cb (cb_cls, NULL, _("Failed to receive response from `SENSOR' service."));
394 return;
395 }
396 if (NULL == ic)
397 {
398 /* didn't expect a response, reconnect */
399 reconnect (h);
400 return;
401 }
402 ic->request_transmitted = GNUNET_NO;
403 cb = ic->callback;
404 cb_cls = ic->callback_cls;
405 if (GNUNET_MESSAGE_TYPE_SENSOR_END == ntohs (msg->type))
406 {
407 /* normal end of list of sensors, signal end, process next pending request */
408 LOG (GNUNET_ERROR_TYPE_DEBUG,
409 "Received end of list of sensors from `%s' service\n", "SENSOR");
410 GNUNET_SENSOR_iterate_sensor_cancel (ic);
411 trigger_transmit (h);
412 if ((GNUNET_NO == h->in_receive) && (NULL != h->ic_head))
413 {
414 h->in_receive = GNUNET_YES;
415 GNUNET_CLIENT_receive (h->client, &sensor_handler, h,
416 GNUNET_TIME_absolute_get_remaining (h->
417 ic_head->timeout));
418 }
419 if (NULL != cb)
420 cb (cb_cls, NULL, NULL);
421 return;
422 }
423 ms = ntohs (msg->size);
424 im = (const struct SensorInfoMessage *) msg;
425 name_len = ntohs (im->name_len);
426 desc_len = ntohs (im->description_len);
427 if ((ms != sizeof (struct SensorInfoMessage) + name_len + desc_len) ||
428 (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_SENSOR_INFO))
429 {
430 /* malformed message */
431 GNUNET_break (0);
432 GNUNET_SENSOR_iterate_sensor_cancel (ic);
433 reconnect (h);
434 if (NULL != cb)
435 cb (cb_cls, NULL, _("Received invalid message from `SENSOR' service."));
436 return;
437 }
438 sensor = GNUNET_new (struct SensorInfoShort);
439 str_ptr = (char *) &im[1];
440 sensor->name = GNUNET_strndup (str_ptr, name_len);
441 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received sensor name (%d): %.*s\n", name_len,
442 name_len, str_ptr);
443 str_ptr += name_len;
444 if (desc_len > 0)
445 {
446 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received sensor description (%d): %.*s\n",
447 desc_len, desc_len, str_ptr);
448 sensor->description = GNUNET_strndup (str_ptr, desc_len);
449 }
450 sensor->version_major = ntohs (im->version_major);
451 sensor->version_minor = ntohs (im->version_minor);
452 h->in_receive = GNUNET_YES;
453 GNUNET_CLIENT_receive (h->client, &sensor_handler, h,
454 GNUNET_TIME_absolute_get_remaining (ic->timeout));
455 if (NULL != cb)
456 cb (cb_cls, sensor, NULL);
457} 325}
458 326
459 327
460/** 328/**
461 * We've transmitted the iteration request. Now get ready to process 329 * Cancel an iteration request.
462 * the results (or handle transmission error). 330 * This should be called before the iterate callback is called with a NULL value.
463 * 331 *
464 * @param cls the 'struct GNUNET_SENSOR_SensorIteratorContext' 332 * @param ic context of the iterator to cancel
465 * @param emsg error message, NULL if transmission worked
466 */
467static void
468sensor_iterator_start_receive (void *cls, const char *emsg)
469{
470 struct GNUNET_SENSOR_SensorIteratorContext *ic = cls;
471 struct GNUNET_SENSOR_Handle *h = ic->h;
472 GNUNET_SENSOR_SensorIteratorCB cb;
473 void *cb_cls;
474
475 ic->rc = NULL;
476 if (NULL != emsg)
477 {
478 cb = ic->callback;
479 cb_cls = ic->callback_cls;
480 GNUNET_SENSOR_iterate_sensor_cancel (ic);
481 reconnect (h);
482 if (NULL != cb)
483 cb (cb_cls, NULL, emsg);
484 return;
485 }
486 LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for response from `%s' service.\n",
487 "SENSOR");
488 ic->request_transmitted = GNUNET_YES;
489 if (GNUNET_NO == h->in_receive)
490 {
491 h->in_receive = GNUNET_YES;
492 GNUNET_CLIENT_receive (h->client, &sensor_handler, h,
493 GNUNET_TIME_absolute_get_remaining (ic->timeout));
494 }
495}
496
497
498/**
499 * Transmit the request at the head of the transmission queue
500 * and trigger continuation (if any).
501 *
502 * @param cls the 'struct GNUNET_SENSOR_Handle' (with the queue)
503 * @param size size of the buffer (0 on error)
504 * @param buf where to copy the message
505 * @return number of bytes copied to buf
506 */ 333 */
507static size_t 334void
508do_transmit (void *cls, size_t size, void *buf) 335GNUNET_SENSOR_iterate_cancel (struct GNUNET_SENSOR_IterateContext *ic)
509{ 336{
510 struct GNUNET_SENSOR_Handle *h = cls; 337 struct GNUNET_SENSOR_Handle *h;
511 struct GNUNET_SENSOR_RequestContext *rc = h->rc_head;
512 size_t ret;
513 338
514 h->th = NULL; 339 h = ic->h;
515 if (NULL == rc) 340 if (GNUNET_NO == ic->request_sent)
516 return 0; /* request was cancelled in the meantime */
517 if (NULL == buf)
518 { 341 {
519 /* sensor service died */ 342 GNUNET_MQ_send_cancel (ic->ev);
520 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 343 ic->ev = NULL;
521 "Failed to transmit message to `%s' service.\n", "SENSOR"); 344 ic->request_sent = GNUNET_YES;
522 GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, rc);
523 reconnect (h);
524 if (NULL != rc->cont)
525 rc->cont (rc->cont_cls, _("failed to transmit request (service down?)"));
526 GNUNET_free (rc);
527 return 0;
528 } 345 }
529 ret = rc->size; 346 if (GNUNET_YES == ic->receiving)
530 if (size < ret)
531 { 347 {
532 /* change in head of queue (i.e. cancel + add), try again */ 348 /* don't remove since we are still expecting records */
533 trigger_transmit (h); 349 ic->callback = NULL;
534 return 0; 350 ic->callback_cls = NULL;
351 return;
535 } 352 }
536 LOG (GNUNET_ERROR_TYPE_DEBUG, 353 if (GNUNET_SCHEDULER_NO_TASK != ic->timeout_task)
537 "Transmitting request of size %u to `%s' service.\n", ret, "SENSOR");
538 memcpy (buf, &rc[1], ret);
539 GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, rc);
540 trigger_transmit (h);
541 if (NULL != rc->cont)
542 rc->cont (rc->cont_cls, NULL);
543 GNUNET_free (rc);
544 return ret;
545}
546
547
548/**
549 * Check if we have a request pending in the transmission queue and are
550 * able to transmit it right now. If so, schedule transmission.
551 *
552 * @param h handle to the service
553 */
554static void
555trigger_transmit (struct GNUNET_SENSOR_Handle *h)
556{
557 struct GNUNET_SENSOR_RequestContext *rc;
558
559 if (NULL == (rc = h->rc_head))
560 return; /* no requests queued */
561 if (NULL != h->th)
562 return; /* request already pending */
563 if (NULL == h->client)
564 { 354 {
565 /* disconnected, try to reconnect */ 355 GNUNET_SCHEDULER_cancel (ic->timeout_task);
566 reconnect (h); 356 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
567 return;
568 } 357 }
569 h->th = 358 GNUNET_CONTAINER_DLL_remove (h->ic_head, h->ic_tail, ic);
570 GNUNET_CLIENT_notify_transmit_ready (h->client, rc->size, 359 GNUNET_free (ic);
571 GNUNET_TIME_UNIT_FOREVER_REL,
572 GNUNET_YES, &do_transmit, h);
573} 360}
574 361
575 362
576/** 363/**
577 * Client asking to iterate all available sensors 364 * Get one or all sensors loaded by the sensor service.
365 * The callback will be called with each sensor received and once with a NULL
366 * value to signal end of iteration.
578 * 367 *
579 * @param h Handle to SENSOR service 368 * @param h Handle to SENSOR service
580 * @param timeout how long to wait until timing out 369 * @param timeout how long to wait until timing out
581 * @param sensorname information on one sensor only, can be NULL to get all 370 * @param sensorname Name of the required sensor, NULL to get all
582 * @param sensorname_len length of the sensorname parameter 371 * @param callback the function to call for each sensor
583 * @param callback the method to call for each sensor
584 * @param callback_cls closure for callback 372 * @param callback_cls closure for callback
585 * @return iterator context 373 * @return iterator context
586 */ 374 */
587struct GNUNET_SENSOR_SensorIteratorContext * 375struct GNUNET_SENSOR_IterateContext *
588GNUNET_SENSOR_iterate_sensors (struct GNUNET_SENSOR_Handle *h, 376GNUNET_SENSOR_iterate (struct GNUNET_SENSOR_Handle *h,
589 struct GNUNET_TIME_Relative timeout, 377 struct GNUNET_TIME_Relative timeout,
590 const char *sensorname, size_t sensorname_len, 378 const char *sensor_name,
591 GNUNET_SENSOR_SensorIteratorCB callback, 379 GNUNET_SENSOR_SensorIterateCB callback,
592 void *callback_cls) 380 void *callback_cls)
593{ 381{
594 struct GNUNET_SENSOR_SensorIteratorContext *ic; 382 struct GNUNET_SENSOR_IterateContext *ic;
595 struct GNUNET_SENSOR_RequestContext *rc; 383 struct GNUNET_MessageHeader *msg;
596 struct GNUNET_MessageHeader *mh; 384 struct GNUNET_MQ_Envelope *ev;
597 385 size_t sensor_name_len;
598 ic = GNUNET_new (struct GNUNET_SENSOR_SensorIteratorContext);
599 386
600 if (NULL == sensorname) 387 if (NULL == sensor_name)
601 { 388 {
602 LOG (GNUNET_ERROR_TYPE_INFO, 389 ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SENSOR_GETALL);
603 "Requesting list of sensors from SENSOR service\n");
604 rc = GNUNET_malloc (sizeof (struct GNUNET_SENSOR_RequestContext) +
605 sizeof (struct GNUNET_MessageHeader));
606 rc->size = sizeof (struct GNUNET_MessageHeader);
607 mh = (struct GNUNET_MessageHeader *) &rc[1];
608 mh->size = htons (sizeof (struct GNUNET_MessageHeader));
609 mh->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_GETALL);
610 } 390 }
611 else 391 else
612 { 392 {
613 LOG (GNUNET_ERROR_TYPE_INFO, 393 sensor_name_len = strlen (sensor_name) + 1;
614 "Requesting information on sensor `%s' from SENSOR service\n", 394 ev = GNUNET_MQ_msg_extra (msg, sensor_name_len,
615 sensorname); 395 GNUNET_MESSAGE_TYPE_SENSOR_GET);
616 rc = GNUNET_malloc (sizeof (struct GNUNET_SENSOR_RequestContext) + 396 memcpy (&msg[1], sensor_name, sensor_name_len);
617 sizeof (struct GNUNET_MessageHeader) + sensorname_len);
618 rc->size = sizeof (struct GNUNET_MessageHeader) + sensorname_len;
619 mh = (struct GNUNET_MessageHeader *) &rc[1];
620 mh->size = htons (rc->size);
621 mh->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_GET);
622 memcpy (&mh[1], sensorname, sensorname_len);
623 } 397 }
398 GNUNET_MQ_send (h->mq, ev);
399 ic = GNUNET_new (struct GNUNET_SENSOR_IterateContext);
400
624 ic->h = h; 401 ic->h = h;
625 ic->rc = rc; 402 ic->ev = ev;
403 ic->request_sent = GNUNET_NO;
404 ic->receiving = GNUNET_NO;
626 ic->callback = callback; 405 ic->callback = callback;
627 ic->callback_cls = callback_cls; 406 ic->callback_cls = callback_cls;
628 ic->timeout = GNUNET_TIME_relative_to_absolute (timeout);
629 ic->timeout_task = 407 ic->timeout_task =
630 GNUNET_SCHEDULER_add_delayed (timeout, &signal_sensor_iteration_timeout, 408 GNUNET_SCHEDULER_add_delayed (timeout, &signal_sensor_iteration_timeout,
631 ic); 409 ic);
632 rc->cont = &sensor_iterator_start_receive; 410 GNUNET_MQ_notify_sent (ev, &iterate_request_sent, ic);
633 rc->cont_cls = ic;
634 GNUNET_CONTAINER_DLL_insert_tail (h->rc_head, h->rc_tail, rc);
635 GNUNET_CONTAINER_DLL_insert_tail (h->ic_head, h->ic_tail, ic); 411 GNUNET_CONTAINER_DLL_insert_tail (h->ic_head, h->ic_tail, ic);
636 trigger_transmit (h);
637 return ic; 412 return ic;
638} 413}
639 414
415
416/**
417 * Force an anomaly status change on a given sensor. If the sensor reporting
418 * module is running, this will trigger the usual reporting logic, therefore,
419 * please only use this in a test environment.
420 *
421 * Also, if the sensor analysis module is running, it might conflict and cause
422 * undefined behaviour if it detects a real anomaly.
423 *
424 * @param h Service handle
425 * @param sensor_name Sensor name to set the anomaly status
426 * @param anomalous The desired status: #GNUNET_YES / #GNUNET_NO
427 */
428void
429GNUNET_SENSOR_force_anomaly (struct GNUNET_SENSOR_Handle *h,
430 char *sensor_name, int anomalous)
431{
432 struct ForceAnomalyMessage *msg;
433 struct GNUNET_MQ_Envelope *ev;
434
435 ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_REPORT);
436 GNUNET_MQ_send (h->mq, ev);
437}
438
439
640/* end of sensor_api.c */ 440/* end of sensor_api.c */