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");
135 SENSOR_reporting_anomaly_update (sensor, ntohs (anomaly_msg->anomalous));
140 * Creates a structure with basic sensor info to be sent to a client.
142 * @param sensor sensor information
143 * @return message ready to be sent to client
145 static struct SensorInfoMessage *
146 create_sensor_info_msg (struct GNUNET_SENSOR_SensorInfo *sensor)
148 struct SensorInfoMessage *msg;
154 name_len = strlen (sensor->name);
155 if (NULL == sensor->description)
158 desc_len = strlen (sensor->description) + 1;
160 len += sizeof (struct SensorInfoMessage);
163 msg = GNUNET_malloc (len);
164 msg->header.size = htons (len);
165 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_INFO);
166 msg->name_len = htons (name_len);
167 msg->description_len = htons (desc_len);
168 msg->version_major = htons (sensor->version_major);
169 msg->version_minor = htons (sensor->version_minor);
170 str_ptr = (char *) &msg[1];
171 memcpy (str_ptr, sensor->name, name_len);
172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending sensor name (%d): %.*s\n",
173 name_len, name_len, str_ptr);
175 memcpy (str_ptr, sensor->description, desc_len);
176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
177 "Sending sensor description (%d): %.*s\n", desc_len, desc_len,
184 * Handle GET SENSOR message.
187 * @param client identification of the client
188 * @param message the actual message
191 handle_get_sensor (void *cls, struct GNUNET_SERVER_Client *client,
192 const struct GNUNET_MessageHeader *message)
194 struct GNUNET_SERVER_TransmitContext *tc;
196 size_t sensorname_len;
197 struct GNUNET_HashCode key;
198 struct GNUNET_SENSOR_SensorInfo *sensorinfo;
199 struct SensorInfoMessage *msg;
201 sensorname = (char *) &message[1];
202 sensorname_len = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
203 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
204 "`%s' message received for sensor (%d) `%.*s'\n", "GET SENSOR",
205 sensorname_len, sensorname_len, sensorname);
206 tc = GNUNET_SERVER_transmit_context_create (client);
207 GNUNET_CRYPTO_hash (sensorname, sensorname_len, &key);
208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
209 "Created key hash for requested sensor\n");
211 (struct GNUNET_SENSOR_SensorInfo *)
212 GNUNET_CONTAINER_multihashmap_get (sensors, &key);
213 if (NULL != sensorinfo)
215 msg = create_sensor_info_msg (sensorinfo);
216 GNUNET_SERVER_transmit_context_append_message (tc,
217 (struct GNUNET_MessageHeader
222 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
223 "Requested sensor `%.*s' was not found\n", sensorname_len,
225 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
226 GNUNET_MESSAGE_TYPE_SENSOR_END);
227 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
232 * Iterator for sensors and adds them to transmit context
234 * @param cls a `struct GNUNET_SERVER_TransmitContext *`
235 * @param key hash of sensor name, key to hashmap
236 * @param value a `struct GNUNET_SENSOR_SensorInfo *`
239 add_sensor_to_tc (void *cls, const struct GNUNET_HashCode *key, void *value)
241 struct GNUNET_SERVER_TransmitContext *tc = cls;
242 struct GNUNET_SENSOR_SensorInfo *sensorinfo = value;
243 struct SensorInfoMessage *msg;
245 msg = create_sensor_info_msg (sensorinfo);
246 GNUNET_SERVER_transmit_context_append_message (tc,
247 (struct GNUNET_MessageHeader *)
256 * Handle GET ALL SENSORS message.
259 * @param client identification of the client
260 * @param message the actual message
263 handle_get_all_sensors (void *cls, struct GNUNET_SERVER_Client *client,
264 const struct GNUNET_MessageHeader *message)
266 struct GNUNET_SERVER_TransmitContext *tc;
268 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "`%s' message received.\n",
270 tc = GNUNET_SERVER_transmit_context_create (client);
271 GNUNET_CONTAINER_multihashmap_iterate (sensors, &add_sensor_to_tc, tc);
272 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
273 GNUNET_MESSAGE_TYPE_SENSOR_END);
274 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
279 * Loads sensors and starts different service components
284 sensors = GNUNET_SENSOR_load_all_sensors (sensor_dir);
285 if (GNUNET_YES == start_monitoring)
286 SENSOR_monitoring_start (cfg, sensors);
287 if (GNUNET_YES == start_reporting)
288 SENSOR_reporting_start (cfg, sensors);
289 if (GNUNET_YES == start_analysis)
290 SENSOR_analysis_start (cfg, sensors);
291 if (GNUNET_YES == start_update)
292 SENSOR_update_start (cfg, sensors, &reset);
297 * Process statistics requests.
300 * @param server the initialized server
301 * @param c configuration to use
304 run (void *cls, struct GNUNET_SERVER_Handle *server,
305 const struct GNUNET_CONFIGURATION_Handle *c)
307 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
308 {&handle_get_sensor, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GET,
310 {&handle_get_all_sensors, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GETALL,
311 sizeof (struct GNUNET_MessageHeader)},
313 &handle_anomaly_force, NULL, GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_FORCE,
314 sizeof (struct ForceAnomalyMessage)},
320 GNUNET_CONFIGURATION_get_value_filename (cfg, "sensor", "SENSOR_DIR",
323 sensor_dir = GNUNET_SENSOR_get_default_sensor_dir ();
325 start_monitoring = GNUNET_YES;
326 start_analysis = GNUNET_YES;
327 start_reporting = GNUNET_YES;
328 start_update = GNUNET_YES;
330 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_MONITORING"))
332 start_monitoring = GNUNET_NO;
335 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_REPORTING"))
337 start_reporting = GNUNET_NO;
340 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_ANALYSIS"))
342 start_analysis = GNUNET_NO;
345 GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_UPDATE"))
347 start_update = GNUNET_NO;
349 GNUNET_SERVER_add_handlers (server, handlers);
350 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
357 * Resets the service by stopping components, reloading sensors and starting
358 * components. This is needed when we receive new sensor updates.
369 * The main function for the sensor service.
371 * @param argc number of arguments from the command line
372 * @param argv command line arguments
373 * @return 0 ok, 1 on error
376 main (int argc, char *const *argv)
379 GNUNET_SERVICE_run (argc, argv, "sensor", GNUNET_SERVICE_OPTION_NONE,
380 &run, NULL)) ? 0 : 1;
383 /* end of gnunet-service-sensor.c */