aboutsummaryrefslogtreecommitdiff
path: root/src/sensor
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-06-26 16:18:31 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-06-26 16:18:31 +0000
commite253b2d47cc6448b12ad006a3e7d95b58b90f256 (patch)
treeed4a80c205c8b28060873f3f7b7e571a5a148575 /src/sensor
parent2169f7aa618dd49ac96e29858f6d266e1468cbfc (diff)
downloadgnunet-e253b2d47cc6448b12ad006a3e7d95b58b90f256.tar.gz
gnunet-e253b2d47cc6448b12ad006a3e7d95b58b90f256.zip
sensor analysis: gaussian model
Diffstat (limited to 'src/sensor')
-rw-r--r--src/sensor/gnunet-service-sensor-analysis.c47
-rw-r--r--src/sensor/gnunet_sensor_model_plugin.h18
-rw-r--r--src/sensor/plugin_sensor_model_gaussian.c108
-rw-r--r--src/sensor/sensor.conf.in6
4 files changed, 170 insertions, 9 deletions
diff --git a/src/sensor/gnunet-service-sensor-analysis.c b/src/sensor/gnunet-service-sensor-analysis.c
index 531f7857d..0dcae61b6 100644
--- a/src/sensor/gnunet-service-sensor-analysis.c
+++ b/src/sensor/gnunet-service-sensor-analysis.c
@@ -27,6 +27,7 @@
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "sensor.h" 28#include "sensor.h"
29#include "gnunet_peerstore_service.h" 29#include "gnunet_peerstore_service.h"
30#include "gnunet_sensor_model_plugin.h"
30 31
31#define LOG(kind,...) GNUNET_log_from (kind, "sensor-analysis",__VA_ARGS__) 32#define LOG(kind,...) GNUNET_log_from (kind, "sensor-analysis",__VA_ARGS__)
32 33
@@ -57,6 +58,11 @@ struct SensorModel
57 */ 58 */
58 struct GNUNET_PEERSTORE_WatchContext *wc; 59 struct GNUNET_PEERSTORE_WatchContext *wc;
59 60
61 /*
62 * Closure for model plugin
63 */
64 void *cls;
65
60}; 66};
61 67
62/** 68/**
@@ -109,6 +115,12 @@ destroy_sensor_model (struct SensorModel *sensor_model)
109 GNUNET_PEERSTORE_watch_cancel(sensor_model->wc); 115 GNUNET_PEERSTORE_watch_cancel(sensor_model->wc);
110 sensor_model->wc = NULL; 116 sensor_model->wc = NULL;
111 } 117 }
118 if (NULL != sensor_model->cls)
119 {
120 model_api->destroy_model (sensor_model->cls);
121 sensor_model->cls = NULL;
122 }
123 GNUNET_free(sensor_model);
112 sensor_model = NULL; 124 sensor_model = NULL;
113} 125}
114 126
@@ -120,23 +132,23 @@ void SENSOR_analysis_stop()
120 struct SensorModel *sm; 132 struct SensorModel *sm;
121 133
122 LOG (GNUNET_ERROR_TYPE_DEBUG, "Stopping sensor analysis module.\n"); 134 LOG (GNUNET_ERROR_TYPE_DEBUG, "Stopping sensor analysis module.\n");
123 if (NULL != model_api)
124 {
125 GNUNET_break (NULL == GNUNET_PLUGIN_unload (model_lib_name, model_api));
126 GNUNET_free (model_lib_name);
127 model_lib_name = NULL;
128 }
129 while (NULL != models_head) 135 while (NULL != models_head)
130 { 136 {
131 sm = models_head; 137 sm = models_head;
132 destroy_sensor_model(sm);
133 GNUNET_CONTAINER_DLL_remove(models_head, models_tail, sm); 138 GNUNET_CONTAINER_DLL_remove(models_head, models_tail, sm);
139 destroy_sensor_model(sm);
134 } 140 }
135 if (NULL != peerstore) 141 if (NULL != peerstore)
136 { 142 {
137 GNUNET_PEERSTORE_disconnect(peerstore); 143 GNUNET_PEERSTORE_disconnect(peerstore);
138 peerstore = NULL; 144 peerstore = NULL;
139 } 145 }
146 if (NULL != model_api)
147 {
148 GNUNET_break (NULL == GNUNET_PLUGIN_unload (model_lib_name, model_api));
149 GNUNET_free (model_lib_name);
150 model_lib_name = NULL;
151 }
140} 152}
141 153
142/* 154/*
@@ -147,8 +159,28 @@ sensor_watcher (void *cls,
147 struct GNUNET_PEERSTORE_Record *record, 159 struct GNUNET_PEERSTORE_Record *record,
148 char *emsg) 160 char *emsg)
149{ 161{
162 struct SensorModel *sensor_model = cls;
163 double *val;
164 int anomalous;
165
150 LOG (GNUNET_ERROR_TYPE_DEBUG, 166 LOG (GNUNET_ERROR_TYPE_DEBUG,
151 "Received a sensor value, will feed to sensor model.\n"); 167 "Received a sensor value, will feed to sensor model.\n");
168 if (sizeof(double) != record->value_size)
169 {
170 LOG (GNUNET_ERROR_TYPE_ERROR,
171 _("Received an invalid sensor value."));
172 return GNUNET_YES;
173 }
174 val = (double *)(record->value);
175 anomalous = model_api->feed_model (sensor_model->cls, *val);
176 if (GNUNET_YES == anomalous)
177 {
178 LOG (GNUNET_ERROR_TYPE_WARNING,
179 "Anomaly detected, value: %f.\n",
180 *val);
181 }
182 else
183 LOG (GNUNET_ERROR_TYPE_DEBUG, "Value non-anomalous.\n");
152 return GNUNET_YES; 184 return GNUNET_YES;
153} 185}
154 186
@@ -176,6 +208,7 @@ init_sensor_model (void *cls,
176 sensor_model->wc = GNUNET_PEERSTORE_watch(peerstore, 208 sensor_model->wc = GNUNET_PEERSTORE_watch(peerstore,
177 "sensor", &peerid, sensor->name, 209 "sensor", &peerid, sensor->name,
178 &sensor_watcher, sensor_model); 210 &sensor_watcher, sensor_model);
211 sensor_model->cls = model_api->create_model(model_api->cls);
179 GNUNET_CONTAINER_DLL_insert(models_head, models_tail, sensor_model); 212 GNUNET_CONTAINER_DLL_insert(models_head, models_tail, sensor_model);
180 LOG (GNUNET_ERROR_TYPE_DEBUG, 213 LOG (GNUNET_ERROR_TYPE_DEBUG,
181 "Created sensor model for `%s'.\n", sensor->name); 214 "Created sensor model for `%s'.\n", sensor->name);
diff --git a/src/sensor/gnunet_sensor_model_plugin.h b/src/sensor/gnunet_sensor_model_plugin.h
index b2973a60d..ddb39a928 100644
--- a/src/sensor/gnunet_sensor_model_plugin.h
+++ b/src/sensor/gnunet_sensor_model_plugin.h
@@ -57,6 +57,24 @@ struct GNUNET_SENSOR_ModelFunctions
57 void * 57 void *
58 (*create_model) (void *cls); 58 (*create_model) (void *cls);
59 59
60 /*
61 * Destroy a model instance
62 *
63 * @param cls closure (model state)
64 */
65 void
66 (*destroy_model) (void *cls);
67
68 /*
69 * Feed a new value to a model
70 *
71 * @param cls closure (model state)
72 * @param val value to be fed to the model
73 * @return #GNUNET_YES in case of a detected outlier, #GNUNET_NO otherwise
74 */
75 int
76 (*feed_model) (void *cls, double val);
77
60}; 78};
61 79
62 80
diff --git a/src/sensor/plugin_sensor_model_gaussian.c b/src/sensor/plugin_sensor_model_gaussian.c
index bf2090217..052b1a94a 100644
--- a/src/sensor/plugin_sensor_model_gaussian.c
+++ b/src/sensor/plugin_sensor_model_gaussian.c
@@ -42,6 +42,16 @@ struct Plugin
42 */ 42 */
43 const struct GNUNET_CONFIGURATION_Handle *cfg; 43 const struct GNUNET_CONFIGURATION_Handle *cfg;
44 44
45 /*
46 * Number of initial readings to be used for training only
47 */
48 int training_window;
49
50 /*
51 * Number of standard deviations considered within "normal"
52 */
53 int confidence_interval;
54
45}; 55};
46 56
47/* 57/*
@@ -55,8 +65,84 @@ struct Model
55 */ 65 */
56 struct Plugin *plugin; 66 struct Plugin *plugin;
57 67
68 /*
69 * Number of readings so far
70 */
71 int n;
72
73 /*
74 * Sum of readings
75 */
76 long double sum;
77
78 /*
79 * Sum square of readings
80 */
81 long double sumsq;
82
58}; 83};
59 84
85static void
86update_sums (struct Model *model, double val)
87{
88 model->sum += val;
89 model->sumsq += val * val;
90 model->n ++;
91}
92
93/*
94 * Feed a new value to a model
95 *
96 * @param cls closure (model state)
97 * @param val value to be fed to the model
98 * @return #GNUNET_YES in case of a detected outlier, #GNUNET_NO otherwise
99 */
100static int
101sensor_gaussian_model_feed (void *cls, double val)
102{
103 struct Model *model = cls;
104 struct Plugin *plugin = model->plugin;
105 long double mean;
106 long double stddev;
107 long double allowed_variance;
108
109 if (model->n < plugin->training_window)
110 {
111 update_sums(model, val);
112 return GNUNET_NO;
113 }
114 mean = model->sum / model->n;
115 stddev = sqrt(
116 (model->sumsq - 2 * mean * model->sum + model->n * mean * mean)
117 /
118 (model->n - 1)
119 );
120 allowed_variance = (plugin->confidence_interval * stddev);
121 if ((val < (mean - allowed_variance)) ||
122 (val > (mean + allowed_variance)))
123 return GNUNET_YES;
124 return GNUNET_NO;
125}
126
127/*
128 * Destroy a model instance
129 *
130 * @param cls closure (model state)
131 */
132static void
133sensor_gaussian_model_destroy_model (void *cls)
134{
135 struct Model *model = cls;
136
137 GNUNET_free(model);
138}
139
140/*
141 * Create a model instance
142 *
143 * @param cls closure (plugin state)
144 * @return model state to be used for later calls
145 */
60static void * 146static void *
61sensor_gaussian_model_create_model (void *cls) 147sensor_gaussian_model_create_model (void *cls)
62{ 148{
@@ -80,14 +166,34 @@ libgnunet_plugin_sensor_model_gaussian_init (void *cls)
80 static struct Plugin plugin; 166 static struct Plugin plugin;
81 const struct GNUNET_CONFIGURATION_Handle *cfg = cls; 167 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
82 struct GNUNET_SENSOR_ModelFunctions *api; 168 struct GNUNET_SENSOR_ModelFunctions *api;
169 unsigned long long num;
83 170
84 if (NULL != plugin.cfg) 171 if (NULL != plugin.cfg)
85 return NULL; /* can only initialize once! */ 172 return NULL; /* can only initialize once! */
86 memset (&plugin, 0, sizeof (struct Plugin)); 173 memset (&plugin, 0, sizeof (struct Plugin));
87 plugin.cfg = cfg; 174 plugin.cfg = cfg;
175 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg,
176 "sensor-model-gaussian", "TRAINING_WINDOW", &num))
177 {
178 LOG (GNUNET_ERROR_TYPE_ERROR,
179 _("Missing `TRAINING_WINDOW' value in configuration.\n"));
180 return NULL;
181 }
182 plugin.training_window = (int) num;
183 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg,
184 "sensor-model-gaussian", "CONFIDENCE_INTERVAL", &num))
185 {
186 LOG (GNUNET_ERROR_TYPE_ERROR,
187 _("Missing `CONFIDENCE_INTERVAL' value in configuration.\n"));
188 return NULL;
189 }
190 plugin.confidence_interval = (int) num;
88 api = GNUNET_new (struct GNUNET_SENSOR_ModelFunctions); 191 api = GNUNET_new (struct GNUNET_SENSOR_ModelFunctions);
89 api->cls = &plugin; 192 api->cls = &plugin;
90 LOG(GNUNET_ERROR_TYPE_DEBUG, "Guassian model plugin is running\n"); 193 api->create_model = &sensor_gaussian_model_create_model;
194 api->destroy_model = &sensor_gaussian_model_destroy_model;
195 api->feed_model = &sensor_gaussian_model_feed;
196 LOG(GNUNET_ERROR_TYPE_DEBUG, "Gaussian model plugin is running.\n");
91 return api; 197 return api;
92} 198}
93 199
diff --git a/src/sensor/sensor.conf.in b/src/sensor/sensor.conf.in
index 5c023d130..92b49100a 100644
--- a/src/sensor/sensor.conf.in
+++ b/src/sensor/sensor.conf.in
@@ -6,4 +6,8 @@ HOME = $SERVICEHOME
6@UNIXONLY@ PORT = 2087 6@UNIXONLY@ PORT = 2087
7 7
8[sensor-analysis] 8[sensor-analysis]
9model = gaussian \ No newline at end of file 9model = gaussian
10
11[sensor-model-gaussian]
12TRAINING_WINDOW = 1000
13CONFIDENCE_INTERVAL = 3 \ No newline at end of file