2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors)
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 sensordashboard/gnunet-service-sensordashboard.c
23 * @brief Service collecting sensor readings from peers
24 * @author Omar Tarabai
28 #include "gnunet_util_lib.h"
29 #include "gnunet_applications.h"
30 #include "sensordashboard.h"
31 #include "gnunet_cadet_service.h"
32 #include "gnunet_sensor_util_lib.h"
33 #include "gnunet_peerstore_service.h"
36 * Handle to CADET service
38 static struct GNUNET_CADET_Handle *cadet;
41 * Global hashmap of defined sensors
43 static struct GNUNET_CONTAINER_MultiHashMap *sensors;
46 * Handle to the peerstore service connection
48 static struct GNUNET_PEERSTORE_Handle *peerstore;
51 * Name of this subsystem to be used for peerstore operations
53 static char *subsystem = "sensordashboard";
56 * Task run during shutdown.
62 cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
66 GNUNET_CADET_disconnect(cadet);
69 if (NULL != peerstore)
71 GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_YES);
74 GNUNET_SENSOR_destroy_sensors (sensors);
75 GNUNET_SCHEDULER_shutdown();
79 * Function called whenever a channel is destroyed. Should clean up
80 * any associated state.
82 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
84 * @param cls closure (set from #GNUNET_CADET_connect)
85 * @param channel connection to the other end (henceforth invalid)
86 * @param channel_ctx place where local state associated
87 * with the channel is stored
89 static void cadet_channel_destroyed (void *cls,
90 const struct GNUNET_CADET_Channel *channel,
93 struct GNUNET_PeerIdentity *peer = channel_ctx;
99 * Method called whenever another peer has added us to a channel
100 * the other peer initiated.
101 * Only called (once) upon reception of data with a message type which was
102 * subscribed to in #GNUNET_CADET_connect.
104 * A call to #GNUNET_CADET_channel_destroy causes the channel to be ignored. In
105 * this case the handler MUST return NULL.
108 * @param channel new handle to the channel
109 * @param initiator peer that started the channel
110 * @param port Port this channel is for.
111 * @param options CadetOption flag field, with all active option bits set to 1.
113 * @return initial channel context for the channel
114 * (can be NULL -- that's not an error)
116 static void *cadet_channel_created (void *cls,
117 struct GNUNET_CADET_Channel *channel,
118 const struct GNUNET_PeerIdentity *initiator,
119 uint32_t port, enum GNUNET_CADET_ChannelOption options)
121 struct GNUNET_PeerIdentity *peer;
123 peer = GNUNET_new (struct GNUNET_PeerIdentity);
124 memcpy (peer, initiator, sizeof (struct GNUNET_PeerIdentity));
129 * Called with any sensor reading messages received from CADET.
131 * Each time the function must call #GNUNET_CADET_receive_done on the channel
132 * in order to receive the next message. This doesn't need to be immediate:
133 * can be delayed if some processing is done on the message.
135 * @param cls Closure (set from #GNUNET_CADET_connect).
136 * @param channel Connection to the other end.
137 * @param channel_ctx Place to store local state associated with the channel.
138 * @param message The actual message.
139 * @return #GNUNET_OK to keep the channel open,
140 * #GNUNET_SYSERR to close it (signal serious error).
142 int sensor_reading_receiver (void *cls, struct GNUNET_CADET_Channel *channel,
143 void **channel_ctx, const struct GNUNET_MessageHeader *message)
145 struct GNUNET_PeerIdentity *peer = *channel_ctx;
146 struct GNUNET_SENSOR_Reading *reading;
148 reading = GNUNET_SENSOR_parse_reading_message (message, sensors);
151 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
152 "Received an invalid sensor reading from peer `%s'\n",
154 return GNUNET_SYSERR;
156 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
157 "Received a sensor reading from peer `%s':\n"
158 "# Sensor name: `%s'\n"
159 "# Timestamp: %" PRIu64 "\n"
160 "# Value size: %" PRIu64 ".\n",
162 reading->sensor->name,
164 reading->value_size);
165 GNUNET_PEERSTORE_store (peerstore, subsystem, peer, reading->sensor->name,
166 reading->value, reading->value_size, GNUNET_TIME_UNIT_FOREVER_ABS,
167 GNUNET_PEERSTORE_STOREOPTION_MULTIPLE, NULL, NULL);
168 GNUNET_free (reading->value);
169 GNUNET_free (reading);
174 * Process sensordashboard requests.
177 * @param server the initialized server
178 * @param cfg configuration to use
181 run (void *cls, struct GNUNET_SERVER_Handle *server,
182 const struct GNUNET_CONFIGURATION_Handle *cfg)
184 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
187 static struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
188 {&sensor_reading_receiver, GNUNET_MESSAGE_TYPE_SENSOR_READING, 0},
191 static uint32_t cadet_ports[] = {
192 GNUNET_APPLICATION_TYPE_SENSORDASHBOARD,
193 GNUNET_APPLICATION_TYPE_END
195 sensors = GNUNET_SENSOR_load_all_sensors ();
196 GNUNET_assert (NULL != sensors);
197 cadet = GNUNET_CADET_connect(cfg,
199 &cadet_channel_created,
200 &cadet_channel_destroyed,
205 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
206 _("Failed to connect to `%s' service.\n"), "CADET");
207 GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
210 peerstore = GNUNET_PEERSTORE_connect (cfg);
211 if (NULL == peerstore)
213 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
214 _("Failed to connect to `%s' service.\n"), "PEERSTORE");
215 GNUNET_SCHEDULER_add_now (&cleanup_task, NULL);
218 GNUNET_SERVER_add_handlers (server, handlers);
219 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task,
225 * The main function for the sensordashboard service.
227 * @param argc number of arguments from the command line
228 * @param argv command line arguments
229 * @return 0 ok, 1 on error
232 main (int argc, char *const *argv)
235 GNUNET_SERVICE_run (argc, argv, "sensordashboard",
236 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
239 /* end of gnunet-service-sensordashboard.c */