aboutsummaryrefslogtreecommitdiff
path: root/src/sensor/gnunet-service-sensor-update.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sensor/gnunet-service-sensor-update.c')
-rw-r--r--src/sensor/gnunet-service-sensor-update.c333
1 files changed, 333 insertions, 0 deletions
diff --git a/src/sensor/gnunet-service-sensor-update.c b/src/sensor/gnunet-service-sensor-update.c
new file mode 100644
index 000000000..e8c294923
--- /dev/null
+++ b/src/sensor/gnunet-service-sensor-update.c
@@ -0,0 +1,333 @@
1/*
2 This file is part of GNUnet.
3 (C)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file sensor/gnunet-service-sensor-update.c
23 * @brief sensor service update functionality
24 * @author Omar Tarabai
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "sensor.h"
29#include "gnunet_cadet_service.h"
30#include "gnunet_sensor_model_plugin.h"
31#include "gnunet_applications.h"
32
33#define LOG(kind,...) GNUNET_log_from (kind, "sensor-update",__VA_ARGS__)
34
35/**
36 * Interval at which to contact update points for new sensor updates.
37 */
38//#define SENSOR_UPDATE_CHECK_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1)
39
40/**
41 * When connecting to update points fail, retry after...
42 */
43//#define SENSOR_UPDATE_RETRY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
44
45
46/**
47 * Sensors update point
48 */
49struct UpdatePoint
50{
51
52 /**
53 * DLL
54 */
55 struct UpdatePoint *prev;
56
57 /**
58 * DLL
59 */
60 struct UpdatePoint *next;
61
62 /**
63 * Identity of peer running update point
64 */
65 struct GNUNET_PeerIdentity peer_id;
66
67 /**
68 * CADET channel to update point
69 */
70 struct GNUNET_CADET_Channel *ch;
71
72 /**
73 * CADET transmit handle for a sensor list request.
74 */
75 struct GNUNET_CADET_TransmitHandle *sensor_list_req_th;
76
77};
78
79
80/**
81 * Our configuration.
82 */
83static const struct GNUNET_CONFIGURATION_Handle *cfg;
84
85/**
86 * Head of update points DLL.
87 */
88static struct UpdatePoint *up_head;
89
90/**
91 * Tail of update points DLL.
92 */
93static struct UpdatePoint *up_tail;
94
95/**
96 * The current default update point to use.
97 */
98static struct UpdatePoint *up_default;
99
100/**
101 * Handle to CADET service
102 */
103static struct GNUNET_CADET_Handle *cadet;
104
105
106/**
107 * Cleanup update point context. This does not destroy the struct itself.
108 *
109 * @param up UpdatePoint struct
110 */
111static void
112cleanup_updatepoint (struct UpdatePoint *up)
113{
114 if (NULL != up->sensor_list_req_th)
115 {
116 GNUNET_CADET_notify_transmit_ready_cancel (up->sensor_list_req_th);
117 up->sensor_list_req_th = NULL;
118 }
119 if (NULL != up->ch)
120 {
121 GNUNET_CADET_channel_destroy (up->ch);
122 up->ch = NULL;
123 }
124}
125
126
127/**
128 * Stop the sensor update module.
129 */
130void
131SENSOR_update_stop ()
132{
133 struct UpdatePoint *up;
134
135 up = up_head;
136 while (NULL != up)
137 {
138 GNUNET_CONTAINER_DLL_remove (up_head, up_tail, up);
139 cleanup_updatepoint (up);
140 GNUNET_free (up);
141 up = up_head;
142 }
143 if (NULL != cadet)
144 {
145 GNUNET_CADET_disconnect (cadet);
146 cadet = NULL;
147 }
148 LOG (GNUNET_ERROR_TYPE_DEBUG,
149 "Sensor update module stopped.\n");
150}
151
152
153/**
154 * A failure occured in connecting/retrieval/verification with current default
155 * update point. This method will try to find another update point, do cleanup
156 * and reschedule update check.
157 */
158static void
159fail ()
160{
161 cleanup_updatepoint (up_default);
162 //TODO:
163}
164
165
166/**
167 * Function called to notify a client about the connection begin ready
168 * to queue more data. @a buf will be NULL and @a size zero if the
169 * connection was closed for writing in the meantime.
170 *
171 * Writes the sensor list request to be sent to the update point.
172 *
173 * @param cls closure (unused)
174 * @param size number of bytes available in @a buf
175 * @param buf where the callee should write the message
176 * @return number of bytes written to @a buf
177 */
178static size_t
179do_send_sensor_list_req (void *cls, size_t size, void *buf)
180{
181 up_default->sensor_list_req_th = NULL;
182 //TODO
183
184 return 0; //FIXME
185}
186
187
188/**
189 * Contact update points to check for new updates
190 *
191 * @param cls unused
192 * @param tc GNUnet scheduler task context
193 */
194static void
195check_for_updates (void *cls,
196 const struct GNUNET_SCHEDULER_TaskContext *tc)
197{
198 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
199 return;
200 LOG (GNUNET_ERROR_TYPE_DEBUG,
201 "Checking for sensor updates.\n");
202 GNUNET_assert (NULL != up_default);
203 up_default->ch =
204 GNUNET_CADET_channel_create (cadet,
205 up_default,
206 &up_default->peer_id,
207 GNUNET_APPLICATION_TYPE_SENSORUPDATE,
208 GNUNET_CADET_OPTION_DEFAULT);
209 if (NULL == up_default->ch)
210 {
211 LOG (GNUNET_ERROR_TYPE_ERROR,
212 _("Failed to connect to update point `%s'.\n"),
213 GNUNET_i2s (&up_default->peer_id));
214 fail ();
215 return;
216 }
217 /* Start by requesting list of sensors available from update point */
218 up_default->sensor_list_req_th =
219 GNUNET_CADET_notify_transmit_ready (up_default->ch,
220 GNUNET_YES,
221 GNUNET_TIME_UNIT_FOREVER_REL,
222 sizeof (struct GNUNET_MessageHeader),
223 &do_send_sensor_list_req, NULL);
224 //TODO
225}
226
227
228/**
229 * Function that reads and validates (correctness not connectivity) of available
230 * sensor update points.
231 *
232 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
233 */
234static int
235load_update_points ()
236{
237 char *points_list;
238 int points_list_len;
239 int i;
240 int start;
241 int len;
242 struct GNUNET_CRYPTO_EddsaPublicKey public_key;
243 struct UpdatePoint *up;
244
245 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg,
246 "sensor",
247 "UPDATE_POINTS",
248 &points_list))
249 {
250 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
251 "sensor",
252 "UPDATE_POINTS");
253 return GNUNET_SYSERR;
254 }
255 points_list_len = strlen (points_list) + 1;
256 for (i = 0; i < points_list_len; i ++)
257 {
258 if (' ' == points_list[i])
259 continue;
260 start = i;
261 len = 0;
262 while (' ' != points_list[i] && '\0' != points_list[i])
263 {
264 len ++;
265 i ++;
266 }
267 if (GNUNET_OK !=
268 GNUNET_CRYPTO_eddsa_public_key_from_string (points_list + start,
269 len,
270 &public_key))
271 {
272 LOG (GNUNET_ERROR_TYPE_ERROR,
273 "Invalid EDDSA public key `%.*s' for update point.\n",
274 len, points_list + len);
275 continue;
276 }
277 up = GNUNET_new (struct UpdatePoint);
278 up->peer_id.public_key = public_key;
279 up->ch = NULL;
280 up->sensor_list_req_th = NULL;
281 GNUNET_CONTAINER_DLL_insert (up_head, up_tail, up);
282 LOG (GNUNET_ERROR_TYPE_DEBUG,
283 "Loaded update point `%s'.\n",
284 GNUNET_i2s_full (&up->peer_id));
285 }
286 return (NULL == up_head) ? GNUNET_SYSERR : GNUNET_OK;
287}
288
289
290/**
291 * Start the sensor update module
292 *
293 * @param c our service configuration
294 * @param sensors multihashmap of loaded sensors
295 * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise
296 */
297int
298SENSOR_update_start (const struct GNUNET_CONFIGURATION_Handle *c,
299 struct GNUNET_CONTAINER_MultiHashMap *sensors)
300{
301 static struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
302 {NULL, 0, 0}
303 };
304
305 GNUNET_assert(NULL != sensors);
306 cfg = c;
307 cadet = GNUNET_CADET_connect(cfg,
308 NULL,
309 NULL,
310 NULL,
311 cadet_handlers,
312 NULL);
313 if (NULL == cadet)
314 {
315 LOG (GNUNET_ERROR_TYPE_ERROR,
316 _("Failed to connect to CADET service.\n"));
317 SENSOR_update_stop ();
318 return GNUNET_SYSERR;
319 }
320 if (GNUNET_OK != load_update_points ())
321 {
322 LOG (GNUNET_ERROR_TYPE_ERROR,
323 "Failed to load update points.\n");
324 return GNUNET_SYSERR;
325 }
326 up_default = up_head;
327 GNUNET_SCHEDULER_add_now (&check_for_updates, NULL);
328 LOG (GNUNET_ERROR_TYPE_DEBUG,
329 "Sensor update module started.\n");
330 return GNUNET_OK;
331}
332
333/* end of gnunet-service-sensor-update.c */