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 * Creates a structure with basic sensor info to be sent to a client.
114 * @param sensor sensor information
115 * @return message ready to be sent to client
117 static struct SensorInfoMessage *
118 create_sensor_info_msg (struct GNUNET_SENSOR_SensorInfo *sensor)
120 struct SensorInfoMessage *msg;
126 name_len = strlen (sensor->name);
127 if (NULL == sensor->description)
130 desc_len = strlen (sensor->description) + 1;
132 len += sizeof (struct SensorInfoMessage);
135 msg = GNUNET_malloc (len);
136 msg->header.size = htons (len);
137 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_INFO);
138 msg->name_len = htons (name_len);
139 msg->description_len = htons (desc_len);
140 msg->version_major = htons (sensor->version_major);
141 msg->version_minor = htons (sensor->version_minor);
142 str_ptr = (char *) &msg[1];
143 memcpy (str_ptr, sensor->name, name_len);
144 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending sensor name (%d): %.*s\n",
145 name_len, name_len, str_ptr);
147 memcpy (str_ptr, sensor->description, desc_len);
148 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
149 "Sending sensor description (%d): %.*s\n", desc_len, desc_len,
156 * Handle GET SENSOR message.
159 * @param client identification of the client
160 * @param message the actual message
163 handle_get_sensor (void *cls, struct GNUNET_SERVER_Client *client,
164 const struct GNUNET_MessageHeader *message)
166 struct GNUNET_SERVER_TransmitContext *tc;
168 size_t sensorname_len;
169 struct GNUNET_HashCode key;
170 struct GNUNET_SENSOR_SensorInfo *sensorinfo;
171 struct SensorInfoMessage *msg;
173 sensorname = (char *) &message[1];
174 sensorname_len = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
175 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
176 "`%s' message received for sensor (%d) `%.*s'\n", "GET SENSOR",
177 sensorname_len, sensorname_len, sensorname);
178 tc = GNUNET_SERVER_transmit_context_create (client);
179 GNUNET_CRYPTO_hash (sensorname, sensorname_len, &key);
180 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
181 "Created key hash for requested sensor\n");
183 (struct GNUNET_SENSOR_SensorInfo *)
184 GNUNET_CONTAINER_multihashmap_get (sensors, &key);
185 if (NULL != sensorinfo)
187 msg = create_sensor_info_msg (sensorinfo);
188 GNUNET_SERVER_transmit_context_append_message (tc,
189 (struct GNUNET_MessageHeader
194 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
195 "Requested sensor `%.*s' was not found\n", sensorname_len,
197 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
198 GNUNET_MESSAGE_TYPE_SENSOR_END);
199 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
204 * Iterator for sensors and adds them to transmit context
206 * @param cls a `struct GNUNET_SERVER_TransmitContext *`
207 * @param key hash of sensor name, key to hashmap
208 * @param value a `struct GNUNET_SENSOR_SensorInfo *`
211 add_sensor_to_tc (void *cls, const struct GNUNET_HashCode *key, void *value)
213 struct GNUNET_SERVER_TransmitContext *tc = cls;
214 struct GNUNET_SENSOR_SensorInfo *sensorinfo = value;
215 struct SensorInfoMessage *msg;
217 msg = create_sensor_info_msg (sensorinfo);
218 GNUNET_SERVER_transmit_context_append_message (tc,
219 (struct GNUNET_MessageHeader *)
228 * Handle GET ALL SENSORS message.
231 * @param client identification of the client
232 * @param message the actual message
235 handle_get_all_sensors (void *cls, struct GNUNET_SERVER_Client *client,
236 const struct GNUNET_MessageHeader *message)
238 struct GNUNET_SERVER_TransmitContext *tc;
240 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "`%s' message received.\n",
242 tc = GNUNET_SERVER_transmit_context_create (client);
243 GNUNET_CONTAINER_multihashmap_iterate (sensors, &add_sensor_to_tc, tc);
244 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
245 GNUNET_MESSAGE_TYPE_SENSOR_END);
246 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
251 * Loads sensors and starts different service components
256 sensors = GNUNET_SENSOR_load_all_sensors (sensor_dir);
257 if (GNUNET_YES == start_monitoring)
258 SENSOR_monitoring_start (cfg, sensors);
259 if (GNUNET_YES == start_reporting)
260 SENSOR_reporting_start (cfg, sensors);
261 if (GNUNET_YES == start_analysis)
262 SENSOR_analysis_start (cfg, sensors);
263 if (GNUNET_YES == start_update)
264 SENSOR_update_start (cfg, sensors, &reset);
269 * Process statistics requests.
272 * @param server the initialized server
273 * @param c configuration to use
276 run (void *cls, struct GNUNET_SERVER_Handle *server,
277 const struct GNUNET_CONFIGURATION_Handle *c)
279 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
280 {&handle_get_sensor, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GET,
282 {&handle_get_all_sensors, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GETALL,
283 sizeof (struct GNUNET_MessageHeader)},
289 GNUNET_CONFIGURATION_get_value_filename (cfg, "SENSOR", "SENSOR_DIR",
292 sensor_dir = GNUNET_SENSOR_get_default_sensor_dir ();
294 start_monitoring = GNUNET_YES;
295 start_analysis = GNUNET_YES;
296 start_reporting = GNUNET_YES;
297 start_update = GNUNET_YES;
299 GNUNET_CONFIGURATION_get_value_yesno (cfg, "SENSOR", "START_MONITORING"))
301 start_monitoring = GNUNET_NO;
304 GNUNET_CONFIGURATION_get_value_yesno (cfg, "SENSOR", "START_REPORTING"))
306 start_reporting = GNUNET_NO;
309 GNUNET_CONFIGURATION_get_value_yesno (cfg, "SENSOR", "START_ANALYSIS"))
311 start_analysis = GNUNET_NO;
314 GNUNET_CONFIGURATION_get_value_yesno (cfg, "SENSOR", "START_UPDATE"))
316 start_update = GNUNET_NO;
318 GNUNET_SERVER_add_handlers (server, handlers);
319 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
326 * Resets the service by stopping components, reloading sensors and starting
327 * components. This is needed when we receive new sensor updates.
338 * The main function for the sensor service.
340 * @param argc number of arguments from the command line
341 * @param argv command line arguments
342 * @return 0 ok, 1 on error
345 main (int argc, char *const *argv)
348 GNUNET_SERVICE_run (argc, argv, "sensor", GNUNET_SERVICE_OPTION_NONE,
349 &run, NULL)) ? 0 : 1;
352 /* end of gnunet-service-sensor.c */