gnunet-service-sensor.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. This file is part of GNUnet.
  3. (C)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file sensor/gnunet-service-sensor.c
  19. * @brief sensor service implementation
  20. * @author Omar Tarabai
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #include "sensor.h"
  25. /**
  26. * Our configuration.
  27. */
  28. static const struct GNUNET_CONFIGURATION_Handle *cfg;
  29. /**
  30. * Path to sensor definitions directory
  31. */
  32. static char *sensor_dir;
  33. /**
  34. * Hashmap of loaded sensor definitions
  35. */
  36. static struct GNUNET_CONTAINER_MultiHashMap *sensors;
  37. /**
  38. * Start the monitoring module ?
  39. */
  40. static int start_monitoring;
  41. /**
  42. * Start the analysis module ?
  43. */
  44. static int start_analysis;
  45. /**
  46. * Start the reporting module ?
  47. */
  48. static int start_reporting;
  49. /**
  50. * Start the update module ?
  51. */
  52. static int start_update;
  53. /**
  54. * Resets the service by stopping components, reloading sensors and starting
  55. * components. This is needed when we receive new sensor updates.
  56. */
  57. static void
  58. reset ();
  59. /**
  60. * Stops components and destroys sensors
  61. */
  62. static void
  63. stop ()
  64. {
  65. if (GNUNET_YES == start_update)
  66. SENSOR_update_stop ();
  67. if (GNUNET_YES == start_analysis)
  68. SENSOR_analysis_stop ();
  69. if (GNUNET_YES == start_reporting)
  70. SENSOR_reporting_stop ();
  71. if (GNUNET_YES == start_monitoring)
  72. SENSOR_monitoring_stop ();
  73. GNUNET_SENSOR_destroy_sensors (sensors);
  74. }
  75. /**
  76. * Task run during shutdown.
  77. *
  78. * @param cls unused
  79. * @param tc unused
  80. */
  81. static void
  82. shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  83. {
  84. stop ();
  85. if (NULL != sensor_dir)
  86. {
  87. GNUNET_free (sensor_dir);
  88. sensor_dir = NULL;
  89. }
  90. GNUNET_SCHEDULER_shutdown ();
  91. }
  92. /**
  93. * Handle a force anomaly request from client.
  94. *
  95. * @param cls closure
  96. * @param client identification of the client
  97. * @param message the actual message
  98. */
  99. static void
  100. handle_anomaly_force (void *cls, struct GNUNET_SERVER_Client *client,
  101. const struct GNUNET_MessageHeader *message)
  102. {
  103. struct ForceAnomalyMessage *anomaly_msg;
  104. struct GNUNET_SENSOR_SensorInfo *sensor;
  105. anomaly_msg = (struct ForceAnomalyMessage *) message;
  106. sensor =
  107. GNUNET_CONTAINER_multihashmap_get (sensors,
  108. &anomaly_msg->sensor_name_hash);
  109. if (NULL == sensor)
  110. {
  111. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  112. "Force anomaly message received for a sensor we don't have.\n");
  113. GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
  114. return;
  115. }
  116. SENSOR_reporting_anomaly_update (sensor, ntohs (anomaly_msg->anomalous));
  117. GNUNET_SERVER_receive_done (client, GNUNET_YES);
  118. }
  119. /**
  120. * Creates a structure with basic sensor info to be sent to a client.
  121. *
  122. * @param sensor sensor information
  123. * @return message ready to be sent to client
  124. */
  125. static struct SensorInfoMessage *
  126. create_sensor_info_msg (struct GNUNET_SENSOR_SensorInfo *sensor)
  127. {
  128. struct SensorInfoMessage *msg;
  129. uint16_t len;
  130. size_t name_len;
  131. size_t desc_len;
  132. char *str_ptr;
  133. name_len = strlen (sensor->name);
  134. if (NULL == sensor->description)
  135. desc_len = 0;
  136. else
  137. desc_len = strlen (sensor->description) + 1;
  138. len = 0;
  139. len += sizeof (struct SensorInfoMessage);
  140. len += name_len;
  141. len += desc_len;
  142. msg = GNUNET_malloc (len);
  143. msg->header.size = htons (len);
  144. msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_INFO);
  145. msg->name_len = htons (name_len);
  146. msg->description_len = htons (desc_len);
  147. msg->version_major = htons (sensor->version_major);
  148. msg->version_minor = htons (sensor->version_minor);
  149. str_ptr = (char *) &msg[1];
  150. memcpy (str_ptr, sensor->name, name_len);
  151. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending sensor name (%d): %.*s\n",
  152. name_len, name_len, str_ptr);
  153. str_ptr += name_len;
  154. memcpy (str_ptr, sensor->description, desc_len);
  155. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  156. "Sending sensor description (%d): %.*s\n", desc_len, desc_len,
  157. str_ptr);
  158. return msg;
  159. }
  160. /**
  161. * Handle GET SENSOR message.
  162. *
  163. * @param cls closure
  164. * @param client identification of the client
  165. * @param message the actual message
  166. */
  167. static void
  168. handle_get_sensor (void *cls, struct GNUNET_SERVER_Client *client,
  169. const struct GNUNET_MessageHeader *message)
  170. {
  171. struct GNUNET_SERVER_TransmitContext *tc;
  172. char *sensorname;
  173. size_t sensorname_len;
  174. struct GNUNET_HashCode key;
  175. struct GNUNET_SENSOR_SensorInfo *sensorinfo;
  176. struct SensorInfoMessage *msg;
  177. sensorname = (char *) &message[1];
  178. sensorname_len = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
  179. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  180. "`%s' message received for sensor (%d) `%.*s'\n", "GET SENSOR",
  181. sensorname_len, sensorname_len, sensorname);
  182. tc = GNUNET_SERVER_transmit_context_create (client);
  183. GNUNET_CRYPTO_hash (sensorname, sensorname_len, &key);
  184. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  185. "Created key hash for requested sensor\n");
  186. sensorinfo =
  187. (struct GNUNET_SENSOR_SensorInfo *)
  188. GNUNET_CONTAINER_multihashmap_get (sensors, &key);
  189. if (NULL != sensorinfo)
  190. {
  191. msg = create_sensor_info_msg (sensorinfo);
  192. GNUNET_SERVER_transmit_context_append_message (tc,
  193. (struct GNUNET_MessageHeader
  194. *) msg);
  195. GNUNET_free (msg);
  196. }
  197. else
  198. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  199. "Requested sensor `%.*s' was not found\n", sensorname_len,
  200. sensorname);
  201. GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
  202. GNUNET_MESSAGE_TYPE_SENSOR_END);
  203. GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
  204. }
  205. /**
  206. * Iterator for sensors and adds them to transmit context
  207. *
  208. * @param cls a `struct GNUNET_SERVER_TransmitContext *`
  209. * @param key hash of sensor name, key to hashmap
  210. * @param value a `struct GNUNET_SENSOR_SensorInfo *`
  211. */
  212. static int
  213. add_sensor_to_tc (void *cls, const struct GNUNET_HashCode *key, void *value)
  214. {
  215. struct GNUNET_SERVER_TransmitContext *tc = cls;
  216. struct GNUNET_SENSOR_SensorInfo *sensorinfo = value;
  217. struct SensorInfoMessage *msg;
  218. msg = create_sensor_info_msg (sensorinfo);
  219. GNUNET_SERVER_transmit_context_append_message (tc,
  220. (struct GNUNET_MessageHeader *)
  221. msg);
  222. GNUNET_free (msg);
  223. return GNUNET_YES;
  224. }
  225. /**
  226. * Handle GET ALL SENSORS message.
  227. *
  228. * @param cls closure
  229. * @param client identification of the client
  230. * @param message the actual message
  231. */
  232. static void
  233. handle_get_all_sensors (void *cls, struct GNUNET_SERVER_Client *client,
  234. const struct GNUNET_MessageHeader *message)
  235. {
  236. struct GNUNET_SERVER_TransmitContext *tc;
  237. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "`%s' message received.\n",
  238. "GET ALL SENSOR");
  239. tc = GNUNET_SERVER_transmit_context_create (client);
  240. GNUNET_CONTAINER_multihashmap_iterate (sensors, &add_sensor_to_tc, tc);
  241. GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
  242. GNUNET_MESSAGE_TYPE_SENSOR_END);
  243. GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
  244. }
  245. /**
  246. * Loads sensors and starts different service components
  247. */
  248. static void
  249. start ()
  250. {
  251. sensors = GNUNET_SENSOR_load_all_sensors (sensor_dir);
  252. if (GNUNET_YES == start_monitoring)
  253. SENSOR_monitoring_start (cfg, sensors);
  254. if (GNUNET_YES == start_reporting)
  255. SENSOR_reporting_start (cfg, sensors);
  256. if (GNUNET_YES == start_analysis)
  257. SENSOR_analysis_start (cfg, sensors);
  258. if (GNUNET_YES == start_update)
  259. SENSOR_update_start (cfg, sensors, &reset);
  260. }
  261. /**
  262. * Process statistics requests.
  263. *
  264. * @param cls closure
  265. * @param server the initialized server
  266. * @param c configuration to use
  267. */
  268. static void
  269. run (void *cls, struct GNUNET_SERVER_Handle *server,
  270. const struct GNUNET_CONFIGURATION_Handle *c)
  271. {
  272. static const struct GNUNET_SERVER_MessageHandler handlers[] = {
  273. {&handle_get_sensor, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GET,
  274. 0},
  275. {&handle_get_all_sensors, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GETALL,
  276. sizeof (struct GNUNET_MessageHeader)},
  277. {
  278. &handle_anomaly_force, NULL, GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_FORCE,
  279. sizeof (struct ForceAnomalyMessage)},
  280. {NULL, NULL, 0, 0}
  281. };
  282. cfg = c;
  283. if (GNUNET_OK !=
  284. GNUNET_CONFIGURATION_get_value_filename (cfg, "sensor", "SENSOR_DIR",
  285. &sensor_dir))
  286. {
  287. sensor_dir = GNUNET_SENSOR_get_default_sensor_dir ();
  288. }
  289. start_monitoring = GNUNET_YES;
  290. start_analysis = GNUNET_YES;
  291. start_reporting = GNUNET_YES;
  292. start_update = GNUNET_YES;
  293. if (GNUNET_NO ==
  294. GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_MONITORING"))
  295. {
  296. start_monitoring = GNUNET_NO;
  297. }
  298. if (GNUNET_NO ==
  299. GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_REPORTING"))
  300. {
  301. start_reporting = GNUNET_NO;
  302. }
  303. if (GNUNET_NO ==
  304. GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_ANALYSIS"))
  305. {
  306. start_analysis = GNUNET_NO;
  307. }
  308. if (GNUNET_NO ==
  309. GNUNET_CONFIGURATION_get_value_yesno (cfg, "sensor", "START_UPDATE"))
  310. {
  311. start_update = GNUNET_NO;
  312. }
  313. GNUNET_SERVER_add_handlers (server, handlers);
  314. GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
  315. NULL);
  316. start ();
  317. }
  318. /**
  319. * Resets the service by stopping components, reloading sensors and starting
  320. * components. This is needed when we receive new sensor updates.
  321. */
  322. static void
  323. reset ()
  324. {
  325. stop ();
  326. start ();
  327. }
  328. /**
  329. * The main function for the sensor service.
  330. *
  331. * @param argc number of arguments from the command line
  332. * @param argv command line arguments
  333. * @return 0 ok, 1 on error
  334. */
  335. int
  336. main (int argc, char *const *argv)
  337. {
  338. return (GNUNET_OK ==
  339. GNUNET_SERVICE_run (argc, argv, "sensor", GNUNET_SERVICE_OPTION_NONE,
  340. &run, NULL)) ? 0 : 1;
  341. }
  342. /* end of gnunet-service-sensor.c */