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-analysis.c
23 * @brief sensor service analysis functionality
24 * @author Omar Tarabai
27 #include "gnunet_util_lib.h"
29 #include "gnunet_peerstore_service.h"
30 #include "gnunet_sensor_model_plugin.h"
32 #define LOG(kind,...) GNUNET_log_from (kind, "sensor-analysis",__VA_ARGS__)
35 * Carries information about the analysis model
36 * corresponding to one sensor
44 struct SensorModel *prev;
49 struct SensorModel *next;
52 * Pointer to sensor info structure
54 struct SensorInfo *sensor;
57 * Watcher of sensor values
59 struct GNUNET_PEERSTORE_WatchContext *wc;
62 * Closure for model plugin
71 static const struct GNUNET_CONFIGURATION_Handle *cfg;
76 static char *model_lib_name;
81 static struct GNUNET_SENSOR_ModelFunctions *model_api;
84 * Handle to peerstore service
86 static struct GNUNET_PEERSTORE_Handle *peerstore;
89 * Head of DLL of created models
91 static struct SensorModel *models_head;
94 * Tail of DLL of created models
96 static struct SensorModel *models_tail;
101 struct GNUNET_PeerIdentity peerid;
104 * Destroy a created model
107 destroy_sensor_model (struct SensorModel *sensor_model)
109 GNUNET_assert (NULL != sensor_model);
110 LOG (GNUNET_ERROR_TYPE_DEBUG,
111 "Destroying sensor model for `%s'.\n",
112 sensor_model->sensor->name);
113 if (NULL != sensor_model->wc)
115 GNUNET_PEERSTORE_watch_cancel(sensor_model->wc);
116 sensor_model->wc = NULL;
118 if (NULL != sensor_model->cls)
120 model_api->destroy_model (sensor_model->cls);
121 sensor_model->cls = NULL;
123 GNUNET_free(sensor_model);
128 * Stop the sensor analysis module
130 void SENSOR_analysis_stop()
132 struct SensorModel *sm;
134 LOG (GNUNET_ERROR_TYPE_DEBUG, "Stopping sensor analysis module.\n");
135 while (NULL != models_head)
138 GNUNET_CONTAINER_DLL_remove(models_head, models_tail, sm);
139 destroy_sensor_model(sm);
141 if (NULL != peerstore)
143 GNUNET_PEERSTORE_disconnect(peerstore);
146 if (NULL != model_api)
148 GNUNET_break (NULL == GNUNET_PLUGIN_unload (model_lib_name, model_api));
149 GNUNET_free (model_lib_name);
150 model_lib_name = NULL;
155 * Sensor value watch callback
158 sensor_watcher (void *cls,
159 struct GNUNET_PEERSTORE_Record *record,
162 struct SensorModel *sensor_model = cls;
166 LOG (GNUNET_ERROR_TYPE_DEBUG,
167 "Received a sensor value, will feed to sensor model.\n");
168 if (sizeof(double) != record->value_size)
170 LOG (GNUNET_ERROR_TYPE_ERROR,
171 _("Received an invalid sensor value."));
174 val = (double *)(record->value);
175 anomalous = model_api->feed_model (sensor_model->cls, *val);
176 if (GNUNET_YES == anomalous)
178 LOG (GNUNET_ERROR_TYPE_WARNING,
179 "Anomaly detected, value: %f.\n",
183 LOG (GNUNET_ERROR_TYPE_DEBUG, "Value non-anomalous.\n");
188 * Iterator for defined sensors
189 * Creates sensor model for numeric sensors
193 * @param value a 'struct SensorInfo *' with sensor information
194 * @return #GNUNET_YES to continue iterations
197 init_sensor_model (void *cls,
198 const struct GNUNET_HashCode *key,
201 struct SensorInfo *sensor = value;
202 struct SensorModel *sensor_model;
204 if (0 != strcmp("numeric", sensor->expected_datatype))
206 sensor_model = GNUNET_new(struct SensorModel);
207 sensor_model->sensor = sensor;
208 sensor_model->wc = GNUNET_PEERSTORE_watch(peerstore,
209 "sensor", &peerid, sensor->name,
210 &sensor_watcher, sensor_model);
211 sensor_model->cls = model_api->create_model(model_api->cls);
212 GNUNET_CONTAINER_DLL_insert(models_head, models_tail, sensor_model);
213 LOG (GNUNET_ERROR_TYPE_DEBUG,
214 "Created sensor model for `%s'.\n", sensor->name);
219 * Start the sensor analysis module
221 * @param c our service configuration
222 * @param sensors multihashmap of loaded sensors
223 * @return #GNUNET_OK if started successfully, #GNUNET_SYSERR otherwise
226 SENSOR_analysis_start(const struct GNUNET_CONFIGURATION_Handle *c,
227 struct GNUNET_CONTAINER_MultiHashMap *sensors)
231 GNUNET_assert(NULL != sensors);
234 GNUNET_CONFIGURATION_get_value_string (cfg, "sensor-analysis", "MODEL",
237 LOG (GNUNET_ERROR_TYPE_ERROR, _("Analysis model not defined in configuration.\n"));
238 return GNUNET_SYSERR;
240 GNUNET_asprintf (&model_lib_name, "libgnunet_plugin_sensor_model_%s", model_name);
241 model_api = GNUNET_PLUGIN_load(model_lib_name, (void *) cfg);
242 GNUNET_free(model_name);
243 if(NULL == model_api)
245 LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not load analysis model `%s'.\n"), model_lib_name);
246 return GNUNET_SYSERR;
248 peerstore = GNUNET_PEERSTORE_connect(cfg);
249 if (NULL == peerstore)
251 LOG (GNUNET_ERROR_TYPE_ERROR, _("Could not connect to peerstore service.\n"));
252 SENSOR_analysis_stop();
253 return GNUNET_SYSERR;
255 GNUNET_CRYPTO_get_peer_identity(cfg, &peerid);
256 GNUNET_CONTAINER_multihashmap_iterate(sensors, &init_sensor_model, NULL);
261 /* end of gnunet-service-sensor-analysis.c */