diff options
author | Omar Tarabai <tarabai@devegypt.com> | 2014-06-26 16:18:31 +0000 |
---|---|---|
committer | Omar Tarabai <tarabai@devegypt.com> | 2014-06-26 16:18:31 +0000 |
commit | e253b2d47cc6448b12ad006a3e7d95b58b90f256 (patch) | |
tree | ed4a80c205c8b28060873f3f7b7e571a5a148575 /src/sensor | |
parent | 2169f7aa618dd49ac96e29858f6d266e1468cbfc (diff) | |
download | gnunet-e253b2d47cc6448b12ad006a3e7d95b58b90f256.tar.gz gnunet-e253b2d47cc6448b12ad006a3e7d95b58b90f256.zip |
sensor analysis: gaussian model
Diffstat (limited to 'src/sensor')
-rw-r--r-- | src/sensor/gnunet-service-sensor-analysis.c | 47 | ||||
-rw-r--r-- | src/sensor/gnunet_sensor_model_plugin.h | 18 | ||||
-rw-r--r-- | src/sensor/plugin_sensor_model_gaussian.c | 108 | ||||
-rw-r--r-- | src/sensor/sensor.conf.in | 6 |
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 | ||
85 | static void | ||
86 | update_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 | */ | ||
100 | static int | ||
101 | sensor_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 | */ | ||
132 | static void | ||
133 | sensor_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 | */ | ||
60 | static void * | 146 | static void * |
61 | sensor_gaussian_model_create_model (void *cls) | 147 | sensor_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] |
9 | model = gaussian \ No newline at end of file | 9 | model = gaussian |
10 | |||
11 | [sensor-model-gaussian] | ||
12 | TRAINING_WINDOW = 1000 | ||
13 | CONFIDENCE_INTERVAL = 3 \ No newline at end of file | ||