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;
47 * Resets the service by stopping components, reloading sensors and starting
48 * components. This is needed when we receive new sensor updates.
55 * Stops components and destroys sensors
60 SENSOR_update_stop ();
61 SENSOR_analysis_stop ();
62 SENSOR_reporting_stop ();
63 SENSOR_monitoring_stop ();
64 GNUNET_SENSOR_destroy_sensors (sensors);
69 * Task run during shutdown.
75 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
78 if (NULL != sensor_dir)
80 GNUNET_free (sensor_dir);
83 GNUNET_SCHEDULER_shutdown ();
88 * Creates a structure with basic sensor info to be sent to a client.
90 * @param sensor sensor information
91 * @return message ready to be sent to client
93 static struct SensorInfoMessage *
94 create_sensor_info_msg (struct GNUNET_SENSOR_SensorInfo *sensor)
96 struct SensorInfoMessage *msg;
102 name_len = strlen (sensor->name);
103 if (NULL == sensor->description)
106 desc_len = strlen (sensor->description) + 1;
108 len += sizeof (struct SensorInfoMessage);
111 msg = GNUNET_malloc (len);
112 msg->header.size = htons (len);
113 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_INFO);
114 msg->name_len = htons (name_len);
115 msg->description_len = htons (desc_len);
116 msg->version_major = htons (sensor->version_major);
117 msg->version_minor = htons (sensor->version_minor);
118 str_ptr = (char *) &msg[1];
119 memcpy (str_ptr, sensor->name, name_len);
120 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending sensor name (%d): %.*s\n",
121 name_len, name_len, str_ptr);
123 memcpy (str_ptr, sensor->description, desc_len);
124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
125 "Sending sensor description (%d): %.*s\n", desc_len, desc_len,
132 * Handle GET SENSOR message.
135 * @param client identification of the client
136 * @param message the actual message
139 handle_get_sensor (void *cls, struct GNUNET_SERVER_Client *client,
140 const struct GNUNET_MessageHeader *message)
142 struct GNUNET_SERVER_TransmitContext *tc;
144 size_t sensorname_len;
145 struct GNUNET_HashCode key;
146 struct GNUNET_SENSOR_SensorInfo *sensorinfo;
147 struct SensorInfoMessage *msg;
149 sensorname = (char *) &message[1];
150 sensorname_len = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
151 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
152 "`%s' message received for sensor (%d) `%.*s'\n", "GET SENSOR",
153 sensorname_len, sensorname_len, sensorname);
154 tc = GNUNET_SERVER_transmit_context_create (client);
155 GNUNET_CRYPTO_hash (sensorname, sensorname_len, &key);
156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
157 "Created key hash for requested sensor\n");
159 (struct GNUNET_SENSOR_SensorInfo *)
160 GNUNET_CONTAINER_multihashmap_get (sensors, &key);
161 if (NULL != sensorinfo)
163 msg = create_sensor_info_msg (sensorinfo);
164 GNUNET_SERVER_transmit_context_append_message (tc,
165 (struct GNUNET_MessageHeader
170 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
171 "Requested sensor `%.*s' was not found\n", sensorname_len,
173 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
174 GNUNET_MESSAGE_TYPE_SENSOR_END);
175 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
180 * Iterator for sensors and adds them to transmit context
182 * @param cls a `struct GNUNET_SERVER_TransmitContext *`
183 * @param key hash of sensor name, key to hashmap
184 * @param value a `struct GNUNET_SENSOR_SensorInfo *`
187 add_sensor_to_tc (void *cls, const struct GNUNET_HashCode *key, void *value)
189 struct GNUNET_SERVER_TransmitContext *tc = cls;
190 struct GNUNET_SENSOR_SensorInfo *sensorinfo = value;
191 struct SensorInfoMessage *msg;
193 msg = create_sensor_info_msg (sensorinfo);
194 GNUNET_SERVER_transmit_context_append_message (tc,
195 (struct GNUNET_MessageHeader *)
204 * Handle GET ALL SENSORS message.
207 * @param client identification of the client
208 * @param message the actual message
211 handle_get_all_sensors (void *cls, struct GNUNET_SERVER_Client *client,
212 const struct GNUNET_MessageHeader *message)
214 struct GNUNET_SERVER_TransmitContext *tc;
216 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "`%s' message received.\n",
218 tc = GNUNET_SERVER_transmit_context_create (client);
219 GNUNET_CONTAINER_multihashmap_iterate (sensors, &add_sensor_to_tc, tc);
220 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
221 GNUNET_MESSAGE_TYPE_SENSOR_END);
222 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
227 * Loads sensors and starts different service components
232 sensors = GNUNET_SENSOR_load_all_sensors (sensor_dir);
233 SENSOR_monitoring_start (cfg, sensors);
234 SENSOR_reporting_start (cfg, sensors);
235 SENSOR_analysis_start (cfg, sensors);
236 SENSOR_update_start (cfg, sensors, &reset);
241 * Process statistics requests.
244 * @param server the initialized server
245 * @param c configuration to use
248 run (void *cls, struct GNUNET_SERVER_Handle *server,
249 const struct GNUNET_CONFIGURATION_Handle *c)
251 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
252 {&handle_get_sensor, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GET,
254 {&handle_get_all_sensors, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GETALL,
255 sizeof (struct GNUNET_MessageHeader)},
261 GNUNET_CONFIGURATION_get_value_filename (cfg, "SENSOR", "SENSOR_DIR",
264 sensor_dir = GNUNET_SENSOR_get_default_sensor_dir ();
266 GNUNET_SERVER_add_handlers (server, handlers);
267 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
274 * Resets the service by stopping components, reloading sensors and starting
275 * components. This is needed when we receive new sensor updates.
286 * The main function for the sensor service.
288 * @param argc number of arguments from the command line
289 * @param argv command line arguments
290 * @return 0 ok, 1 on error
293 main (int argc, char *const *argv)
296 GNUNET_SERVICE_run (argc, argv, "sensor", GNUNET_SERVICE_OPTION_NONE,
297 &run, NULL)) ? 0 : 1;
300 /* end of gnunet-service-sensor.c */