2 This file is part of GNUnet.
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.
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.
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.
22 * @file sensor/gnunet-service-sensor.c
23 * @brief sensor service implementation
24 * @author Omar Tarabai
27 #include "gnunet_util_lib.h"
33 static const struct GNUNET_CONFIGURATION_Handle *cfg;
36 * Path to sensor definitions directory
38 static char *sensor_dir;
41 * Hashmap of loaded sensor definitions
43 static struct GNUNET_CONTAINER_MultiHashMap *sensors;
46 * Start the monitoring module ?
48 static int start_monitoring;
51 * Start the analysis module ?
53 static int start_analysis;
56 * Start the reporting module ?
58 static int start_reporting;
61 * Start the update module ?
63 static int start_update;
67 * Resets the service by stopping components, reloading sensors and starting
68 * components. This is needed when we receive new sensor updates.
75 * Stops components and destroys sensors
80 if (GNUNET_YES == start_update)
81 SENSOR_update_stop ();
82 if (GNUNET_YES == start_analysis)
83 SENSOR_analysis_stop ();
84 if (GNUNET_YES == start_reporting)
85 SENSOR_reporting_stop ();
86 if (GNUNET_YES == start_monitoring)
87 SENSOR_monitoring_stop ();
88 GNUNET_SENSOR_destroy_sensors (sensors);
93 * Task run during shutdown.
99 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
102 if (NULL != sensor_dir)
104 GNUNET_free (sensor_dir);
107 GNUNET_SCHEDULER_shutdown ();
112 * Handle a force anomaly request from client.
115 * @param client identification of the client
116 * @param message the actual message
119 handle_anomaly_force (void *cls, struct GNUNET_SERVER_Client *client,
120 const struct GNUNET_MessageHeader *message)
122 struct ForceAnomalyMessage *anomaly_msg;
123 struct GNUNET_SENSOR_SensorInfo *sensor;
125 anomaly_msg = (struct ForceAnomalyMessage *) message;
127 GNUNET_CONTAINER_multihashmap_get (sensors,
128 &anomaly_msg->sensor_name_hash);
131 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
132 "Force anomaly message received for a sensor we don't have.\n");
133 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
136 SENSOR_reporting_anomaly_update (sensor, ntohs (anomaly_msg->anomalous));
137 GNUNET_SERVER_receive_done (client, GNUNET_YES);
142 * Creates a structure with basic sensor info to be sent to a client.
144 * @param sensor sensor information
145 * @return message ready to be sent to client
147 static struct SensorInfoMessage *
148 create_sensor_info_msg (struct GNUNET_SENSOR_SensorInfo *sensor)
150 struct SensorInfoMessage *msg;
156 name_len = strlen (sensor->name);
157 if (NULL == sensor->description)
160 desc_len = strlen (sensor->description) + 1;
162 len += sizeof (struct SensorInfoMessage);
165 msg = GNUNET_malloc (len);
166 msg->header.size = htons (len);
167 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_INFO);
168 msg->name_len = htons (name_len);
169 msg->description_len = htons (desc_len);
170 msg->version_major = htons (sensor->version_major);
171 msg->version_minor = htons (sensor->version_minor);
172 str_ptr = (char *) &msg[1];
173 memcpy (str_ptr, sensor->name, name_len);
174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending sensor name (%d): %.*s\n",
175 name_len, name_len, str_ptr);
177 memcpy (str_ptr, sensor->description, desc_len);
178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
179 "Sending sensor description (%d): %.*s\n", desc_len, desc_len,
186 * Handle GET SENSOR message.
189 * @param client identification of the client
190 * @param message the actual message
193 handle_get_sensor (void *cls, struct GNUNET_SERVER_Client *client,
194 const struct GNUNET_MessageHeader *message)
196 struct GNUNET_SERVER_TransmitContext *tc;
198 size_t sensorname_len;
199 struct GNUNET_HashCode key;
200 struct GNUNET_SENSOR_SensorInfo *sensorinfo;
201 struct SensorInfoMessage *msg;
203 sensorname = (char *) &message[1];
204 sensorname_len = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
205 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
206 "`%s' message received for sensor (%d) `%.*s'\n", "GET SENSOR",
207 sensorname_len, sensorname_len, sensorname);
208 tc = GNUNET_SERVER_transmit_context_create (client);
209 GNUNET_CRYPTO_hash (sensorname, sensorname_len, &key);
210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
211 "Created key hash for requested sensor\n");
213 (struct GNUNET_SENSOR_SensorInfo *)
214 GNUNET_CONTAINER_multihashmap_get (sensors, &key);
215 if (NULL != sensorinfo)
217 msg = create_sensor_info_msg (sensorinfo);
218 GNUNET_SERVER_transmit_context_append_message (tc,
219 (struct GNUNET_MessageHeader
224 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
225 "Requested sensor `%.*s' was not found\n", sensorname_len,
227 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
228 GNUNET_MESSAGE_TYPE_SENSOR_END);
229 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
234 * Iterator for sensors and adds them to transmit context
236 * @param cls a `struct GNUNET_SERVER_TransmitContext *`
237 * @param key hash of sensor name, key to hashmap
238 * @param value a `struct GNUNET_SENSOR_SensorInfo *`
241 add_sensor_to_tc (void *cls, const struct GNUNET_HashCode *key, void *value)
243 struct GNUNET_SERVER_TransmitContext *tc = cls;
244 struct GNUNET_SENSOR_SensorInfo *sensorinfo = value;
245 struct SensorInfoMessage *msg;
247 msg = create_sensor_info_msg (sensorinfo);
248 GNUNET_SERVER_transmit_context_append_message (tc,
249 (struct GNUNET_MessageHeader *)
258 * Handle GET ALL SENSORS message.
261 * @param client identification of the client
262 * @param message the actual message
265 handle_get_all_sensors (void *cls, struct GNUNET_SERVER_Client *client,
266 const struct GNUNET_MessageHeader *message)
268 struct GNUNET_SERVER_TransmitContext *tc;
270 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "`%s' message received.\n",
272 tc = GNUNET_SERVER_transmit_context_create (client);
273 GNUNET_CONTAINER_multihashmap_iterate (sensors, &add_sensor_to_tc, tc);
274 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
275 GNUNET_MESSAGE_TYPE_SENSOR_END);
276 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
281 * Loads sensors and starts different service components
286 sensors = GNUNET_SENSOR_load_all_sensors (sensor_dir);
287 if (GNUNET_YES == start_monitoring)
288 SENSOR_monitoring_start (cfg, sensors);
289 if (GNUNET_YES == start_reporting)
290 SENSOR_reporting_start (cfg, sensors);
291 if (GNUNET_YES == start_analysis)
292 SENSOR_analysis_start (cfg, sensors);
293 if (GNUNET_YES == start_update)
294 SENSOR_update_start (cfg, sensors, &reset);
299 * Process statistics requests.
302 * @param server the initialized server
303 * @param c configuration to use
306 run (void *cls, struct GNUNET_SERVER_Handle *server,
307 const struct GNUNET_CONFIGURATION_Handle *c)
309 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
310 {&handle_get_sensor, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GET,
312 {&handle_get_all_sensors, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GETALL,
313 sizeof (struct GNUNET_MessageHeader)},
315 &handle_anomaly_force, NULL, GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_FORCE,
316 sizeof (struct ForceAnomalyMessage)},
322 GNUNET_CONFIGURATION_get_value_filename (cfg, "sensor", "SENSOR_DIR",
325 sensor_dir = GNUNET_SENSOR_get_default_sensor_dir ();
327 start_monitoring = GNUNET_YES;
328 start_analysis = GNUNET_YES;
329 start_reporting = GNUNET_YES;
330 start_update = GNUNET_YES;
332 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_MONITORING"))
334 start_monitoring = GNUNET_NO;
337 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_REPORTING"))
339 start_reporting = GNUNET_NO;
342 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_ANALYSIS"))
344 start_analysis = GNUNET_NO;
347 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_UPDATE"))
349 start_update = GNUNET_NO;
351 GNUNET_SERVER_add_handlers (server, handlers);
352 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
359 * Resets the service by stopping components, reloading sensors and starting
360 * components. This is needed when we receive new sensor updates.
371 * The main function for the sensor service.
373 * @param argc number of arguments from the command line
374 * @param argv command line arguments
375 * @return 0 ok, 1 on error
378 main (int argc, char *const *argv)
381 GNUNET_SERVICE_run (argc, argv, "sensor", GNUNET_SERVICE_OPTION_NONE,
382 &run, NULL)) ? 0 : 1;
385 /* end of gnunet-service-sensor.c */