gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r33061 - in gnunet/src: . sensor


From: gnunet
Subject: [GNUnet-SVN] r33061 - in gnunet/src: . sensor
Date: Mon, 14 Apr 2014 14:08:48 +0200

Author: otarabai
Date: 2014-04-14 14:08:48 +0200 (Mon, 14 Apr 2014)
New Revision: 33061

Added:
   gnunet/src/sensor/
   gnunet/src/sensor/Makefile.am
   gnunet/src/sensor/gnunet-sensor.c
   gnunet/src/sensor/gnunet-service-sensor.c
   gnunet/src/sensor/sensor.conf.in
   gnunet/src/sensor/sensor.h
   gnunet/src/sensor/sensor_api.c
   gnunet/src/sensor/test_sensor_api.c
Log:
SENSOR component inital commit


Added: gnunet/src/sensor/Makefile.am
===================================================================
--- gnunet/src/sensor/Makefile.am                               (rev 0)
+++ gnunet/src/sensor/Makefile.am       2014-04-14 12:08:48 UTC (rev 33061)
@@ -0,0 +1,69 @@
+SUBDIRS = .
+
+INCLUDES = \
+  -I$(top_srcdir)/src/include \
+  -I$(top_srcdir)
+
+AM_CPPFLAGS = \
+  $(GNUNET_CPPFLAGS)
+
+# Set this variable if you are using GNUNET libraries for all programs and
+# libraries. You don't then need to target-specific _LDFLAGS with 
GNUNET_LDFLAGS
+# AM_LDFLAGS = \
+#   $(GNUNET_LDFLAGS) \
+#   $(WINFLAGS) \
+#   -export-dynamic
+
+lib_LTLIBRARIES = libgnunetsensor.la
+
+pkgcfgdir= $(prefix)/share/gnunet/config.d/
+
+libexecdir= $(prefix)/lib/gnunet/libexec/
+
+libgnunetsensor_la_SOURCES = \
+  sensor_api.c 
+libgnunetsensor_la_LIBADD = \
+  -lgnunetutil
+libgnunetsensor_la_LDFLAGS = \
+  $(GNUNET_LDFLAGS)  $(WINFLAGS) \
+  -version-info 0:0:0
+
+
+bin_PROGRAMS = gnunet-sensor
+
+libexec_PROGRAMS = gnunet-service-sensor
+
+check_PROGRAMS = \
+ test_sensor_api 
+
+TESTS = $(check_PROGRAMS)
+
+gnunet_service_sensor_SOURCES = \
+  gnunet-service-sensor.c
+gnunet_service_sensor_LDADD = \
+  -lgnunetutil -lgnunetcore -lgnunetdht\
+  $(INTLLIBS) 
+gnunet_service_sensor_LDFLAGS = \
+  $(GNUNET_LDFLAGS)  $(WINFLAGS) -export-dynamic 
+
+gnunet_sensor_SOURCES = \
+  gnunet-sensor.c
+gnunet_sensor_LDADD = \
+  -lgnunetutil \
+  libgnunetsensor.la \
+  $(INTLLIBS) 
+gnunet_sensor_LDFLAGS = \
+ $(GNUNET_LDFLAGS) $(WINFLAGS) -export-dynamic 
+
+
+
+test_sensor_api_SOURCES = \
+ test_sensor_api.c
+test_sensor_api_LDADD = \
+  $(top_builddir)/src/sensor/libgnunetsensor.la \
+  -lgnunetutil
+test_sensor_api_LDFLAGS = \
+ $(GNUNET_LDFLAGS)  $(WINFLAGS) -export-dynamic
+ 
+ pkgcfg_DATA = sensor.conf 
+ 

Added: gnunet/src/sensor/gnunet-sensor.c
===================================================================
--- gnunet/src/sensor/gnunet-sensor.c                           (rev 0)
+++ gnunet/src/sensor/gnunet-sensor.c   2014-04-14 12:08:48 UTC (rev 33061)
@@ -0,0 +1,149 @@
+/*
+     This file is part of GNUnet.
+     (C)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file sensor/gnunet-sensor.c
+ * @brief sensor tool
+ * @author Omar Tarabai
+ */
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_util_lib.h>
+#include "gnunet_sensor_service.h"
+
+static int ret;
+
+/*
+ * option '-a'
+ */
+static int get_all;
+
+/*
+ * Handle to sensor service
+ */
+struct GNUNET_SENSOR_Handle *sensor_handle;
+
+/**
+ * Run on shutdown
+ *
+ * @param cls unused
+ * @param tc scheduler context
+ */
+static void
+shutdown_task (void *cls,
+         const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  if(NULL != sensor_handle)
+  {
+    GNUNET_SENSOR_disconnect(sensor_handle);
+    sensor_handle = NULL;
+  }
+}
+
+/**
+ * Callback for getting sensor info from service
+ *
+ * @param cls not used
+ * @param sensor brief information about sensor (NULL means end of 
transmission)
+ * @param err_msg contains error string if any
+ */
+void print_sensor_info(void *cls,
+    const struct SensorInfoShort *sensor,
+    const char *err_msg)
+{
+  if(NULL != err_msg)
+  {
+    printf("Error: %s\n", err_msg);
+    GNUNET_SCHEDULER_shutdown();
+    return;
+  }
+  if(NULL == sensor) /* no more sensors from service */
+  {
+    GNUNET_SCHEDULER_shutdown();
+    return;
+  }
+  printf("Name: %s\nVersion: %d.%d\n",
+      sensor->name,
+      sensor->version_major,
+      sensor->version_minor);
+  if(NULL != sensor->description)
+    printf("Description: %s\n", sensor->description);
+  printf("\n");
+}
+
+/**
+ * Main function that will be run by the scheduler.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be 
NULL!)
+ * @param cfg configuration
+ */
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+
+  sensor_handle = NULL;
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+                                  &shutdown_task,
+                                  NULL);
+  if(GNUNET_YES == get_all)
+  {
+    sensor_handle = GNUNET_SENSOR_connect(cfg);
+    GNUNET_assert(NULL != sensor_handle);
+    GNUNET_SENSOR_iterate_sensors(sensor_handle,
+        GNUNET_TIME_UNIT_FOREVER_REL,
+        NULL,
+        0,
+        &print_sensor_info,
+        NULL);
+  }
+
+  ret = 0;
+}
+
+/**
+ * The main function to sensor.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc, char *const *argv)
+{
+  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
+      {'a', "all", NULL,
+          gettext_noop("Retrieve names of all defined sensors"),
+      0, &GNUNET_GETOPT_set_one, &get_all},
+    GNUNET_GETOPT_OPTION_END
+  };
+  return (GNUNET_OK ==
+          GNUNET_PROGRAM_run (argc,
+                              argv,
+                              "gnunet-sensor [options [value]]",
+                              gettext_noop
+                              ("sensor"),
+                              options, &run, NULL)) ? ret : 1;
+}
+
+/* end of gnunet-sensor.c */

Added: gnunet/src/sensor/gnunet-service-sensor.c
===================================================================
--- gnunet/src/sensor/gnunet-service-sensor.c                           (rev 0)
+++ gnunet/src/sensor/gnunet-service-sensor.c   2014-04-14 12:08:48 UTC (rev 
33061)
@@ -0,0 +1,577 @@
+/*
+     This file is part of GNUnet.
+     (C) 
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file sensor/gnunet-service-sensor.c
+ * @brief sensor service implementation
+ * @author Christian Grothoff
+ */
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_util_lib.h>
+#include "sensor.h"
+
+/**
+ * Structure containing sensor definition
+ */
+struct SensorInfo
+{
+
+  /*
+   * Sensor name
+   */
+  char *name;
+
+  /*
+   * Path to definition file
+   */
+  char *def_file;
+
+  /*
+   * First part of version number
+   */
+  uint16_t version_major;
+
+  /*
+   * Second part of version number
+   */
+  uint16_t version_minor;
+
+  /*
+   * Sensor description
+   */
+  char *description;
+
+  /*
+   * Category under which the sensor falls (e.g. tcp, datastore)
+   */
+  char *category;
+
+  /*
+   * When does the sensor become active
+   */
+  struct GNUNET_TIME_Absolute *start_time;
+
+  /*
+   * When does the sensor expire
+   */
+  struct GNUNET_TIME_Absolute *end_time;
+
+  /*
+   * Time interval to collect sensor information (e.g. every 1 min)
+   */
+  struct GNUNET_TIME_Relative *interval;
+
+  /*
+   * Lifetime of an information sample after which it is deleted from storage
+   */
+  struct GNUNET_TIME_Relative *lifetime;
+
+  /*
+   * A set of required peer capabilities for the sensor to collect meaningful 
information (e.g. ipv6)
+   */
+  char *capabilities;
+
+  /*
+   * Either "gnunet-statistics" or external "process"
+   */
+  char *source;
+
+  /*
+   * Name of the GNUnet service that is the source for the gnunet-statistics 
entry
+   */
+  char *gnunet_stat_service;
+
+  /*
+   * Name of the gnunet-statistics entry
+   */
+  char *gnunet_stat_name;
+
+  /*
+   * Name of the external process to be executed
+   */
+  char *ext_process;
+
+  /*
+   * Arguments to be passed to the external process
+   */
+  char *ext_args;
+
+  /*
+   * The output datatype to be expected
+   */
+  char *expected_datatype;
+
+  /*
+   * Peer-identity of peer running collection point
+   */
+  struct GNUNET_PeerIdentity *collection_point;
+
+  /*
+   * Time interval to send sensor information to collection point (e.g. every 
30 mins)
+   */
+  struct GNUNET_TIME_Relative *collection_interval;
+
+  /*
+   * Flag specifying if value is to be communicated to the p2p network
+   */
+  int p2p_report;
+
+  /*
+   * Time interval to communicate value to the p2p network
+   */
+  struct GNUNET_TIME_Relative *p2p_interval;
+
+};
+
+/**
+ * Our configuration.
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * Hashmap of loaded sensor definitions
+ */
+struct GNUNET_CONTAINER_MultiHashMap *sensors;
+
+/**
+ * Task run during shutdown.
+ *
+ * @param cls unused
+ * @param tc unused
+ */
+static void
+shutdown_task (void *cls,
+              const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+}
+
+
+/**
+ * A client disconnected.  Remove all of its data structure entries.
+ *
+ * @param cls closure, NULL
+ * @param client identification of the client
+ */
+static void
+handle_client_disconnect (void *cls,
+                         struct GNUNET_SERVER_Client
+                         * client)
+{
+}
+
+/**
+ * Parses a version number string into major and minor
+ *
+ * @param version full version string
+ * @param major pointer to parsed major value
+ * @param minor pointer to parsed minor value
+ * @return #GNUNET_OK if parsing went ok, #GNUNET_SYSERROR in case of error
+ */
+static int
+version_parse(char *version, uint16_t *major, uint16_t *minor)
+{
+  int majorval = 0;
+  int minorval = 0;
+
+  for(; isdigit(*version); version++)
+  {
+    majorval *= 10;
+    majorval += *version - '0';
+  }
+  if(*version != '.')
+    return GNUNET_SYSERR;
+  version++;
+  for(; isdigit(*version); version++)
+  {
+    minorval *= 10;
+    minorval += *version - '0';
+  }
+  if(*version != 0)
+    return GNUNET_SYSERR;
+  *major = majorval;
+  *minor = minorval;
+
+  return GNUNET_OK;
+}
+
+/**
+ * Load sensor definition from configuration
+ *
+ * @param cfg configuration handle
+ * @param sectionname configuration section containing definition
+ */
+static struct SensorInfo *
+load_sensor_from_cfg(struct GNUNET_CONFIGURATION_Handle *cfg, char 
*sectionname)
+{
+  struct SensorInfo *sensor;
+  char *versionstr;
+
+  sensor = GNUNET_new(struct SensorInfo);
+  //name
+  sensor->name = GNUNET_strdup(sectionname);
+  //version
+  if(GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, sectionname, 
"VERSION", &versionstr) ||
+      NULL == versionstr)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Error reading sensor version\n"));
+    GNUNET_free(sensor);
+    return NULL;
+  }
+  if(GNUNET_OK != version_parse(versionstr, &(sensor->version_major), 
&(sensor->version_minor)))
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Invalid sensor version number, 
format should be major.minor\n"));
+    GNUNET_free(sensor);
+    return NULL;
+  }
+  //description
+  GNUNET_CONFIGURATION_get_value_string(cfg, sectionname, "DESCRIPTION", 
&sensor->description);
+  //category
+  if(GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, sectionname, 
"CATEGORY", &sensor->category) ||
+        NULL == sensor->category)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Error reading sensor category\n"));
+    GNUNET_free(sensor);
+    return NULL;
+  }
+
+  return sensor;
+}
+
+/**
+ * Load sensor definition from file
+ *
+ * @param filename full path to file containing sensor definition
+ */
+static struct SensorInfo *
+load_sensor_from_file(const char *filename)
+{
+  struct GNUNET_CONFIGURATION_Handle *sensorcfg;
+  char *filebasename;
+  struct SensorInfo *sensor;
+
+  //test file
+  if(GNUNET_YES != GNUNET_DISK_file_test(filename))
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Failed to access sensor file: 
%s\n"), filename);
+    return NULL;
+  }
+  //load file as configuration
+  sensorcfg = GNUNET_CONFIGURATION_create();
+  if(GNUNET_SYSERR == GNUNET_CONFIGURATION_parse(sensorcfg, filename))
+  {
+    GNUNET_CONFIGURATION_destroy(sensorcfg);
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Failed to load sensor definition: 
%s\n"), filename);
+    return NULL;
+  }
+  //configuration section should be the same as filename
+  filebasename = GNUNET_STRINGS_get_short_name(filename);
+  sensor = load_sensor_from_cfg(sensorcfg, filebasename);
+  sensor->def_file = GNUNET_strdup(filename);
+
+  GNUNET_CONFIGURATION_destroy(sensorcfg);
+
+  return sensor;
+}
+
+/**
+ * Compares version numbers of two sensors
+ *
+ * @param s1 first sensor
+ * @param s2 second sensor
+ * @return 1: s1 > s2, 0: s1 == s2, -1: s1 < s2
+ */
+static int
+sensor_version_compare(struct SensorInfo *s1, struct SensorInfo *s2)
+{
+  if(s1->version_major == s2->version_major)
+    return (s1->version_minor < s2->version_minor) ? -1 : (s1->version_minor > 
s2->version_minor);
+  else
+    return (s1->version_major < s2->version_major) ? -1 : (s1->version_major > 
s2->version_major);
+}
+
+/**
+ * Adds a new sensor to given hashmap.
+ * If the same name exist, compares versions and update if old.
+ *
+ * @param sensor Sensor structure to add
+ * @param map Hashmap to add to
+ * @return #GNUNET_YES if added, #GNUNET_NO if not added which is not 
necessarily an error
+ */
+static int
+add_sensor_to_hashmap(struct SensorInfo *sensor, struct 
GNUNET_CONTAINER_MultiHashMap *map)
+{
+  struct GNUNET_HashCode key;
+  struct SensorInfo *existing;
+
+  GNUNET_CRYPTO_hash(sensor->name, sizeof(sensor->name), &key);
+  existing = GNUNET_CONTAINER_multihashmap_get(map, &key);
+  if(NULL != existing) //sensor with same name already exists
+  {
+    if(sensor_version_compare(existing, sensor) >= 0) //same or newer version 
already exist
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Sensor `%s' already exists with 
same or newer version\n"), sensor->name);
+      return GNUNET_NO;
+    }
+    else
+    {
+      GNUNET_CONTAINER_multihashmap_remove(map, &key, existing); //remove the 
old version
+      GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Upgrading sensor `%s' to a newer 
version\n"), sensor->name);
+    }
+  }
+  if(GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put(map, &key, sensor, 
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Error adding new sensor `%s' to 
global hashmap, this should not happen\n"), sensor->name);
+    return GNUNET_NO;
+  }
+
+  return GNUNET_YES;
+}
+
+/**
+ * Iterating over files in sensors directory
+ *
+ * @param cls closure
+ * @param filename complete filename (absolute path)
+ * @return #GNUNET_OK to continue to iterate,
+ *  #GNUNET_NO to stop iteration with no error,
+ *  #GNUNET_SYSERR to abort iteration with error!
+ */
+static int
+reload_sensors_dir_cb(void *cls, const char *filename)
+{
+  struct SensorInfo *sensor;
+
+  sensor = load_sensor_from_file(filename);
+  if(NULL == sensor)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Error loading sensor from file: 
%s\n"), filename);
+    return GNUNET_OK;
+  }
+  if(GNUNET_YES == add_sensor_to_hashmap(sensor, sensors))
+    GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Sensor `%s' added to global 
hashmap\n"), sensor->name);
+  else
+    GNUNET_log(GNUNET_ERROR_TYPE_INFO, ("Could not add sensor `%s' to global 
hashmap\n"), sensor->name);
+
+  return GNUNET_OK;
+}
+
+/*
+ * Get path to the directory containing the sensor definition files
+ *
+ * @return sensor files directory
+ */
+static char *
+get_sensor_dir()
+{
+  char* datadir;
+  char* sensordir;
+
+  datadir = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_SELF_PREFIX);
+  //should eval to '$prefix/share/gnunet-mi/sensors/'
+  //TODO: is there a better way?
+  GNUNET_asprintf(&sensordir, "%sshare%sgnunet-mi%ssensors%s",
+      datadir, DIR_SEPARATOR_STR, DIR_SEPARATOR_STR, DIR_SEPARATOR_STR);
+
+  return sensordir;
+}
+
+/**
+ * Reads sensor definitions from data files
+ *
+ */
+static void
+reload_sensors()
+{
+  char* sensordir;
+  int filesfound;
+
+  sensordir = get_sensor_dir();
+  GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Reloading sensor definitions from 
directory `%s'\n"), sensordir);
+  GNUNET_assert(GNUNET_YES == GNUNET_DISK_directory_test(sensordir, 
GNUNET_YES));
+
+  //read all files in sensors directory
+  filesfound = GNUNET_DISK_directory_scan(sensordir, &reload_sensors_dir_cb, 
NULL);
+  GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Loaded %d/%d sensors from directory 
`%s'\n"),
+      GNUNET_CONTAINER_multihashmap_size(sensors), filesfound, sensordir);
+}
+
+/**
+ * Creates a structure with basic sensor info to be sent to a client
+ *
+ * @parm sensor sensor information
+ * @return message ready to be sent to client
+ */
+static struct SensorInfoMessage *
+create_sensor_info_msg(struct SensorInfo *sensor)
+{
+  struct SensorInfoMessage *msg;
+  uint16_t len;
+  size_t name_len;
+  size_t desc_len;
+
+  name_len = strlen(sensor->name);
+  if(NULL == sensor->description)
+    desc_len = 0;
+  else
+    desc_len = strlen(sensor->description);
+  len = 0;
+  len += sizeof(struct SensorInfoMessage);
+  len += name_len;
+  len += desc_len;
+  msg = GNUNET_malloc(len);
+  msg->header.size = htons(len);
+  msg->header.type = htons(GNUNET_MESSAGE_TYPE_SENSOR_INFO);
+  msg->name_len = htons(name_len);
+  msg->description_len = htons(desc_len);
+  msg->version_major = htons(sensor->version_major);
+  msg->version_minor = htons(sensor->version_minor);
+  memcpy(&msg[1], sensor->name, name_len);
+  memcpy((&msg[1]) + name_len, sensor->description, desc_len);
+
+  return msg;
+}
+
+/**
+ * Handle GET SENSOR message.
+ *
+ * @param cls closure
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+handle_get_sensor (void *cls, struct GNUNET_SERVER_Client *client,
+            const struct GNUNET_MessageHeader *message)
+{
+  struct GNUNET_SERVER_TransmitContext *tc;
+  char *sensorname;
+  size_t sensorname_len;
+  struct GNUNET_HashCode key;
+  struct SensorInfo *sensorinfo;
+  struct SensorInfoMessage *msg;
+
+  sensorname = (char *)&message[1];
+  sensorname_len = message->size - sizeof(struct GNUNET_MessageHeader);
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "`%s' message received for sensor 
`%.*s\n",
+              "GET SENSOR", sensorname_len, sensorname);
+  tc = GNUNET_SERVER_transmit_context_create (client);
+  GNUNET_CRYPTO_hash(sensorname, sensorname_len, &key);
+  sensorinfo = (struct SensorInfo *)GNUNET_CONTAINER_multihashmap_get(sensors, 
&key);
+  msg = create_sensor_info_msg(sensorinfo);
+  GNUNET_SERVER_transmit_context_append_message(tc, (struct 
GNUNET_MessageHeader *)msg);
+  GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
+
+  GNUNET_free(msg);
+}
+
+/**
+ * Iterator for sensors and adds them to transmit context
+ *
+ * @param cls a 'struct GNUNET_SERVER_TransmitContext *'
+ * @param key hash of sensor name, key to hashmap
+ * @param value a 'struct SensorInfo *'
+ */
+int add_sensor_to_tc(void *cls,
+    const struct GNUNET_HashCode *key, void *value)
+{
+  struct GNUNET_SERVER_TransmitContext *tc = cls;
+  struct SensorInfo *sensorinfo = value;
+  struct SensorInfoMessage *msg;
+
+  msg = create_sensor_info_msg(sensorinfo);
+  GNUNET_SERVER_transmit_context_append_message(tc, (struct 
GNUNET_MessageHeader *)msg);
+
+  GNUNET_free(msg);
+
+  return GNUNET_YES;
+}
+
+/**
+ * Handle GET ALL SENSORS message.
+ *
+ * @param cls closure
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+handle_get_all_sensors (void *cls, struct GNUNET_SERVER_Client *client,
+            const struct GNUNET_MessageHeader *message)
+{
+  struct GNUNET_SERVER_TransmitContext *tc;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "`%s' message received.\n",
+                "GET ALL SENSOR");
+  tc = GNUNET_SERVER_transmit_context_create (client);
+  GNUNET_CONTAINER_multihashmap_iterate(sensors, &add_sensor_to_tc, tc);
+  GNUNET_SERVER_transmit_context_append_data(tc, NULL, 0, 
GNUNET_MESSAGE_TYPE_SENSOR_END);
+  GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
+}
+
+/**
+ * Process statistics requests.
+ *
+ * @param cls closure
+ * @param server the initialized server
+ * @param c configuration to use
+ */
+static void
+run (void *cls,
+     struct GNUNET_SERVER_Handle *server,
+     const struct GNUNET_CONFIGURATION_Handle *c)
+{
+  static const struct GNUNET_SERVER_MessageHandler handlers[] = {
+    {&handle_get_sensor, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GET,
+     sizeof (struct GNUNET_MessageHeader)},
+    {&handle_get_all_sensors, NULL, GNUNET_MESSAGE_TYPE_SENSOR_GETALL,
+     0},
+    {NULL, NULL, 0, 0}
+  };
+
+  cfg = c;
+  sensors = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO);
+  reload_sensors();
+  GNUNET_SERVER_add_handlers (server, handlers);
+  GNUNET_SERVER_disconnect_notify (server, 
+                                  &handle_client_disconnect,
+                                  NULL);
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+                               &shutdown_task,
+                               NULL);
+}
+
+
+/**
+ * The main function for the sensor service.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc, char *const *argv)
+{
+  return (GNUNET_OK ==
+          GNUNET_SERVICE_run (argc,
+                              argv,
+                              "sensor",
+                             GNUNET_SERVICE_OPTION_NONE,
+                             &run, NULL)) ? 0 : 1;
+}
+
+/* end of gnunet-service-sensor.c */

Added: gnunet/src/sensor/sensor.conf.in
===================================================================
--- gnunet/src/sensor/sensor.conf.in                            (rev 0)
+++ gnunet/src/sensor/sensor.conf.in    2014-04-14 12:08:48 UTC (rev 33061)
@@ -0,0 +1,7 @@
+[sensor]
+BINARY = gnunet-service-sensor
+UNIXPATH = /tmp/gnunet-service-sensor.sock
+HOME = $SERVICEHOME
+# PORT = 2106
address@hidden@ PORT = 2087
+

Added: gnunet/src/sensor/sensor.h
===================================================================
--- gnunet/src/sensor/sensor.h                          (rev 0)
+++ gnunet/src/sensor/sensor.h  2014-04-14 12:08:48 UTC (rev 33061)
@@ -0,0 +1,63 @@
+/*
+      This file is part of GNUnet
+      (C) 2012-2013 Christian Grothoff (and other contributing authors)
+
+      GNUnet is free software; you can redistribute it and/or modify
+      it under the terms of the GNU General Public License as published
+      by the Free Software Foundation; either version 3, or (at your
+      option) any later version.
+
+      GNUnet is distributed in the hope that it will be useful, but
+      WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      General Public License for more details.
+
+      You should have received a copy of the GNU General Public License
+      along with GNUnet; see the file COPYING.  If not, write to the
+      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+      Boston, MA 02111-1307, USA.
+ */
+/**
+ * @file sensor/sensor.h
+ * @brief example IPC messages between SENSOR API and GNS service
+ * @author Omar Tarabai
+ */
+
+#include "gnunet_sensor_service.h"
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Carries a summary of a sensor
+ *
+ */
+struct SensorInfoMessage
+{
+  /**
+   * Message header
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Length of sensor name (name follows the struct)
+   */
+  size_t name_len;
+
+  /**
+   * First part of version number
+   */
+  uint16_t version_major;
+
+  /**
+   * Second part of version number
+   */
+  uint16_t version_minor;
+
+  /**
+   * Length of sensor description (description itself follows)
+   */
+  size_t description_len;
+};
+
+GNUNET_NETWORK_STRUCT_END

Added: gnunet/src/sensor/sensor_api.c
===================================================================
--- gnunet/src/sensor/sensor_api.c                              (rev 0)
+++ gnunet/src/sensor/sensor_api.c      2014-04-14 12:08:48 UTC (rev 33061)
@@ -0,0 +1,627 @@
+/*
+     This file is part of GNUnet.
+     (C) 
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file sensor/sensor_api.c
+ * @brief API for sensor
+ * @author Omar Tarabai
+ */
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_util_lib.h>
+#include "sensor.h"
+
+#define LOG(kind,...) GNUNET_log_from (kind, "sensor-api",__VA_ARGS__)
+
+/******************************************************************************/
+/************************      DATA STRUCTURES     
****************************/
+/******************************************************************************/
+
+/**
+ * Handle to the sensor service.
+ */
+struct GNUNET_SENSOR_Handle
+{
+
+  /**
+   * Our configuration.
+   */
+    const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Connection to the service.
+   */
+  struct GNUNET_CLIENT_Connection *client;
+
+  /**
+   * Head of transmission queue.
+   */
+  struct GNUNET_SENSOR_RequestContext *rc_head;
+
+  /**
+   * Tail of transmission queue.
+   */
+  struct GNUNET_SENSOR_RequestContext *rc_tail;
+
+  /**
+   * Handle for the current transmission request, or NULL if none is pending.
+   */
+  struct GNUNET_CLIENT_TransmitHandle *th;
+
+  /**
+   * Head of iterator DLL.
+   */
+  struct GNUNET_SENSOR_SensorIteratorContext *ic_head;
+
+  /**
+   * Tail of iterator DLL.
+   */
+  struct GNUNET_SENSOR_SensorIteratorContext *ic_tail;
+
+  /**
+   * ID for a reconnect task.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier r_task;
+
+  /**
+   * Are we now receiving?
+   */
+  int in_receive;
+
+};
+
+/**
+ * Entry in the transmission queue to SENSOR service.
+ *
+ */
+struct GNUNET_SENSOR_RequestContext
+{
+  /**
+   * This is a linked list.
+   */
+  struct GNUNET_SENSOR_RequestContext *next;
+
+  /**
+   * This is a linked list.
+   */
+  struct GNUNET_SENSOR_RequestContext *prev;
+
+  /**
+   * Handle to the SENSOR service.
+   */
+  struct GNUNET_SENSOR_Handle *h;
+
+  /**
+   * Function to call after request has been transmitted, or NULL.
+   */
+  GNUNET_SENSOR_Continuation cont;
+
+  /**
+   * Closure for 'cont'.
+   */
+  void *cont_cls;
+
+  /**
+   * Number of bytes of the request message (follows after this struct).
+   */
+  size_t size;
+
+};
+
+/**
+ * Context for an iteration request.
+ */
+struct GNUNET_SENSOR_SensorIteratorContext
+{
+
+  /**
+   * Kept in a DLL.
+   */
+  struct GNUNET_SENSOR_SensorIteratorContext *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct GNUNET_SENSOR_SensorIteratorContext *prev;
+
+  /**
+   * Handle to the SENSOR service.
+   */
+  struct GNUNET_SENSOR_Handle *h;
+
+  /**
+   * Function to call with the results.
+   */
+  GNUNET_SENSOR_SensorIteratorCB callback;
+
+  /**
+   * Closure for 'callback'.
+   */
+  void *callback_cls;
+
+  /**
+   * Our entry in the transmission queue.
+   */
+  struct GNUNET_SENSOR_RequestContext *rc;
+
+  /**
+   * Task responsible for timeout.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+  /**
+   * Timeout for the operation.
+   */
+  struct GNUNET_TIME_Absolute timeout;
+
+  /**
+   * Set to GNUNET_YES if we are currently receiving replies from the
+   * service.
+   */
+  int request_transmitted;
+
+};
+
+/******************************************************************************/
+/***********************         DECLARATIONS         
*************************/
+/******************************************************************************/
+
+/**
+ * Close the existing connection to SENSOR and reconnect.
+ *
+ * @param h handle to the service
+ */
+static void
+reconnect (struct GNUNET_SENSOR_Handle *h);
+
+/**
+ * Check if we have a request pending in the transmission queue and are
+ * able to transmit it right now.  If so, schedule transmission.
+ *
+ * @param h handle to the service
+ */
+static void
+trigger_transmit (struct GNUNET_SENSOR_Handle *h);
+
+/******************************************************************************/
+/*******************         CONNECTION FUNCTIONS         
*********************/
+/******************************************************************************/
+
+/**
+ * Connect to the sensor service.
+ *
+ * @return NULL on error
+ */
+struct GNUNET_SENSOR_Handle *
+GNUNET_SENSOR_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  struct GNUNET_CLIENT_Connection *client;
+  struct GNUNET_SENSOR_Handle *h;
+
+  client = GNUNET_CLIENT_connect ("sensor", cfg);
+  if(NULL == client)
+    return NULL;
+  h = GNUNET_new (struct GNUNET_SENSOR_Handle);
+  h->client = client;
+  h->cfg = cfg;
+  return h;
+}
+
+/**
+ * Disconnect from the sensor service
+ *
+ * @param h handle to disconnect
+ */
+void
+GNUNET_SENSOR_disconnect(struct GNUNET_SENSOR_Handle *h)
+{
+  if (NULL != h->client)
+  {
+    GNUNET_CLIENT_disconnect (h->client);
+    h->client = NULL;
+  }
+  GNUNET_free (h);
+}
+
+/**
+ * Task scheduled to re-try connecting to the sensor service.
+ *
+ * @param cls the 'struct GNUNET_SENSOR_Handle'
+ * @param tc scheduler context
+ */
+static void
+reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_SENSOR_Handle *h = cls;
+
+  h->r_task = GNUNET_SCHEDULER_NO_TASK;
+  reconnect (h);
+}
+
+/**
+ * Close the existing connection to SENSOR and reconnect.
+ *
+ * @param h handle to the service
+ */
+static void
+reconnect (struct GNUNET_SENSOR_Handle *h)
+{
+  if (GNUNET_SCHEDULER_NO_TASK != h->r_task)
+  {
+    GNUNET_SCHEDULER_cancel (h->r_task);
+    h->r_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+  if (NULL != h->th)
+  {
+    GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
+    h->th = NULL;
+  }
+  if (NULL != h->client)
+  {
+    GNUNET_CLIENT_disconnect (h->client);
+    h->client = NULL;
+  }
+  h->in_receive = GNUNET_NO;
+  h->client = GNUNET_CLIENT_connect ("sensor", h->cfg);
+  if (NULL == h->client)
+  {
+    h->r_task =
+        GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 
&reconnect_task,
+                                      h);
+    return;
+  }
+  trigger_transmit (h);
+}
+
+/******************************************************************************/
+/******************         SENSOR DATA FUNCTIONS         
*********************/
+/******************************************************************************/
+
+/**
+ * Cancel an iteration over sensor information.
+ *
+ * @param ic context of the iterator to cancel
+ */
+void
+GNUNET_SENSOR_iterate_sensor_cancel (struct 
GNUNET_SENSOR_SensorIteratorContext *ic)
+{
+  struct GNUNET_SENSOR_Handle *h;
+
+  h = ic->h;
+  if (GNUNET_SCHEDULER_NO_TASK != ic->timeout_task)
+  {
+    GNUNET_SCHEDULER_cancel (ic->timeout_task);
+    ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+  ic->callback = NULL;
+  if (GNUNET_YES == ic->request_transmitted)
+    return;                     /* need to finish processing */
+  GNUNET_CONTAINER_DLL_remove (h->ic_head,
+             h->ic_tail,
+             ic);
+  if (NULL != ic->rc)
+  {
+    GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, ic->rc);
+    GNUNET_free (ic->rc);
+  }
+  GNUNET_free (ic);
+}
+
+/**
+ * Iteration request has timed out.
+ *
+ * @param cls the 'struct GNUNET_SENSOR_SensorIteratorContext*'
+ * @param tc scheduler context
+ */
+static void
+signal_sensor_iteration_timeout (void *cls, const struct 
GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_SENSOR_SensorIteratorContext *ic = cls;
+  GNUNET_SENSOR_SensorIteratorCB cb;
+  void *cb_cls;
+
+  ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  cb = ic->callback;
+  cb_cls = ic->callback_cls;
+  GNUNET_SENSOR_iterate_sensor_cancel (ic);
+  if (NULL != cb)
+    cb (cb_cls, NULL,
+  _("Timeout transmitting iteration request to `SENSOR' service."));
+}
+
+/**
+ * Type of a function to call when we receive a message from the
+ * service.  Call the iterator with the result and (if applicable)
+ * continue to receive more messages or trigger processing the next
+ * event (if applicable).
+ *
+ * @param cls closure
+ * @param msg message received, NULL on timeout or fatal error
+ */
+static void
+sensor_handler(void *cls, const struct GNUNET_MessageHeader *msg)
+{
+  struct GNUNET_SENSOR_Handle *h = cls;
+  struct GNUNET_SENSOR_SensorIteratorContext *ic = h->ic_head;
+  GNUNET_SENSOR_SensorIteratorCB cb;
+  void *cb_cls;
+  uint16_t ms;
+  const struct SensorInfoMessage *im;
+  struct SensorInfoShort *sensor;
+  size_t name_len;
+  size_t desc_len;
+
+
+  h->in_receive = GNUNET_NO;
+  if (NULL == msg)
+  {
+    /* sensor service died, signal error */
+    if (NULL != ic)
+    {
+      cb = ic->callback;
+      cb_cls = ic->callback_cls;
+      GNUNET_SENSOR_iterate_sensor_cancel(ic);
+    }
+    else
+    {
+      cb = NULL;
+    }
+    reconnect (h);
+    if (NULL != cb)
+      cb (cb_cls, NULL,
+    _("Failed to receive response from `SENSOR' service."));
+    return;
+  }
+  if (NULL == ic)
+  {
+    /* didn't expect a response, reconnect */
+    reconnect (h);
+    return;
+  }
+  ic->request_transmitted = GNUNET_NO;
+  cb = ic->callback;
+  cb_cls = ic->callback_cls;
+  if (GNUNET_MESSAGE_TYPE_SENSOR_END == ntohs (msg->type))
+  {
+    /* normal end of list of sensors, signal end, process next pending request 
*/
+    LOG (GNUNET_ERROR_TYPE_INFO,
+         "Received end of list of sensors from `%s' service\n", "SENSOR");
+    GNUNET_SENSOR_iterate_sensor_cancel(ic);
+    trigger_transmit (h);
+    if ( (GNUNET_NO == h->in_receive) &&
+   (NULL != h->ic_head) )
+    {
+      h->in_receive = GNUNET_YES;
+      GNUNET_CLIENT_receive (h->client, &sensor_handler, h,
+           GNUNET_TIME_absolute_get_remaining (h->ic_head->timeout));
+    }
+    if (NULL != cb)
+      cb (cb_cls, NULL, NULL);
+    return;
+  }
+  ms = ntohs (msg->size);
+  im = (const struct SensorInfoMessage *) msg;
+  name_len = ntohs(im->name_len);
+  desc_len = ntohs(im->description_len);
+  if ((ms != sizeof (struct SensorInfoMessage) + name_len + desc_len) ||
+      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_SENSOR_INFO))
+  {
+    /* malformed message */
+    GNUNET_break (0);
+    GNUNET_SENSOR_iterate_sensor_cancel(ic);
+    reconnect (h);
+    if (NULL != cb)
+      cb (cb_cls, NULL,
+    _("Received invalid message from `SENSOR' service."));
+    return;
+  }
+  sensor = GNUNET_new(struct SensorInfoShort);
+  sensor->name = GNUNET_strndup((char *)&im[1], name_len);
+  if(desc_len > 0)
+    sensor->description = GNUNET_strndup((char *)((&im[1]) + name_len), 
desc_len);
+  sensor->version_major = ntohs(im->version_major);
+  sensor->version_minor = ntohs(im->version_minor);
+  h->in_receive = GNUNET_YES;
+  GNUNET_CLIENT_receive (h->client, &sensor_handler, h,
+                         GNUNET_TIME_absolute_get_remaining (ic->timeout));
+  if (NULL != cb)
+    cb (cb_cls, sensor, NULL);
+}
+
+/**
+ * We've transmitted the iteration request.  Now get ready to process
+ * the results (or handle transmission error).
+ *
+ * @param cls the 'struct GNUNET_SENSOR_SensorIteratorContext'
+ * @param emsg error message, NULL if transmission worked
+ */
+static void
+sensor_iterator_start_receive (void *cls, const char *emsg)
+{
+  struct GNUNET_SENSOR_SensorIteratorContext *ic = cls;
+  struct GNUNET_SENSOR_Handle *h = ic->h;
+  GNUNET_SENSOR_SensorIteratorCB cb;
+  void *cb_cls;
+
+  ic->rc = NULL;
+  if (NULL != emsg)
+  {
+    cb = ic->callback;
+    cb_cls = ic->callback_cls;
+    GNUNET_SENSOR_iterate_sensor_cancel (ic);
+    reconnect (h);
+    if (NULL != cb)
+      cb (cb_cls, NULL, emsg);
+    return;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Waiting for response from `%s' service.\n",
+       "SENSOR");
+  ic->request_transmitted = GNUNET_YES;
+  if (GNUNET_NO == h->in_receive)
+  {
+    h->in_receive = GNUNET_YES;
+    GNUNET_CLIENT_receive (h->client, &sensor_handler, h,
+         GNUNET_TIME_absolute_get_remaining (ic->timeout));
+  }
+}
+
+/**
+ * Transmit the request at the head of the transmission queue
+ * and trigger continuation (if any).
+ *
+ * @param cls the 'struct GNUNET_SENSOR_Handle' (with the queue)
+ * @param size size of the buffer (0 on error)
+ * @param buf where to copy the message
+ * @return number of bytes copied to buf
+ */
+static size_t
+do_transmit (void *cls, size_t size, void *buf)
+{
+  struct GNUNET_SENSOR_Handle *h = cls;
+  struct GNUNET_SENSOR_RequestContext *rc = h->rc_head;
+  size_t ret;
+
+  h->th = NULL;
+  if (NULL == rc)
+    return 0; /* request was cancelled in the meantime */
+  if (NULL == buf)
+  {
+    /* sensor service died */
+    LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+         "Failed to transmit message to `%s' service.\n", "SENSOR");
+    GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, rc);
+    reconnect (h);
+    if (NULL != rc->cont)
+      rc->cont (rc->cont_cls, _("failed to transmit request (service down?)"));
+    GNUNET_free (rc);
+    return 0;
+  }
+  ret = rc->size;
+  if (size < ret)
+  {
+    /* change in head of queue (i.e. cancel + add), try again */
+    trigger_transmit (h);
+    return 0;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Transmitting request of size %u to `%s' service.\n", ret, "SENSOR");
+  memcpy (buf, &rc[1], ret);
+  GNUNET_CONTAINER_DLL_remove (h->rc_head, h->rc_tail, rc);
+  trigger_transmit (h);
+  if (NULL != rc->cont)
+    rc->cont (rc->cont_cls, NULL);
+  GNUNET_free (rc);
+  return ret;
+}
+
+/**
+ * Check if we have a request pending in the transmission queue and are
+ * able to transmit it right now.  If so, schedule transmission.
+ *
+ * @param h handle to the service
+ */
+static void
+trigger_transmit (struct GNUNET_SENSOR_Handle *h)
+{
+  struct GNUNET_SENSOR_RequestContext *rc;
+
+  if (NULL == (rc = h->rc_head))
+    return; /* no requests queued */
+  if (NULL != h->th)
+    return; /* request already pending */
+  if (NULL == h->client)
+  {
+    /* disconnected, try to reconnect */
+    reconnect (h);
+    return;
+  }
+  h->th =
+    GNUNET_CLIENT_notify_transmit_ready (h->client, rc->size,
+           GNUNET_TIME_UNIT_FOREVER_REL,
+           GNUNET_YES,
+           &do_transmit, h);
+}
+
+/**
+ * Client asking to iterate all available sensors
+ *
+ * @param h Handle to SENSOR service
+ * @param timeout how long to wait until timing out
+ * @param sensorname information on one sensor only, can be NULL to get all
+ * @param sensorname_len length of the sensorname parameter
+ * @param callback the method to call for each sensor
+ * @param callback_cls closure for callback
+ * @return iterator context
+ */
+struct GNUNET_SENSOR_SensorIteratorContext *
+GNUNET_SENSOR_iterate_sensors (struct GNUNET_SENSOR_Handle *h,
+    struct GNUNET_TIME_Relative timeout,
+    const char* sensorname, size_t sensorname_len,
+    GNUNET_SENSOR_SensorIteratorCB callback, void *callback_cls)
+{
+  struct GNUNET_SENSOR_SensorIteratorContext *ic;
+  struct GNUNET_SENSOR_RequestContext *rc;
+  struct GNUNET_MessageHeader *mh;
+
+  ic = GNUNET_new (struct GNUNET_SENSOR_SensorIteratorContext);
+  if (NULL == sensorname)
+  {
+    LOG (GNUNET_ERROR_TYPE_INFO,
+         "Requesting list of sensors from SENSOR service\n");
+    rc =
+        GNUNET_malloc (sizeof (struct GNUNET_SENSOR_RequestContext) +
+                       sizeof (struct GNUNET_MessageHeader));
+    rc->size = sizeof (struct GNUNET_MessageHeader);
+    mh = (struct GNUNET_MessageHeader *) &rc[1];
+    mh->size = htons(sizeof (struct GNUNET_MessageHeader));
+    mh->type = htons(GNUNET_MESSAGE_TYPE_SENSOR_GETALL);
+  }
+  else
+  {
+    LOG (GNUNET_ERROR_TYPE_INFO,
+         "Requesting information on sensor `%s' from SENSOR service\n",
+         sensorname);
+    rc =
+        GNUNET_malloc (sizeof (struct GNUNET_SENSOR_RequestContext) +
+                       sizeof (struct GNUNET_MessageHeader) +
+                       sensorname_len);
+    rc->size = sizeof (struct GNUNET_MessageHeader) + sensorname_len;
+    mh = (struct GNUNET_MessageHeader *) &rc[1];
+    mh->size = htons(rc->size);
+    mh->type = htons(GNUNET_MESSAGE_TYPE_SENSOR_GET);
+    memcpy(&mh[1], sensorname, sensorname_len);
+  }
+  ic->h = h;
+  ic->rc = rc;
+  ic->callback = callback;
+  ic->callback_cls = callback_cls;
+  ic->timeout = GNUNET_TIME_relative_to_absolute (timeout);
+  ic->timeout_task =
+      GNUNET_SCHEDULER_add_delayed (timeout, &signal_sensor_iteration_timeout, 
ic);
+  rc->cont = &sensor_iterator_start_receive;
+  rc->cont_cls = ic;
+  GNUNET_CONTAINER_DLL_insert_tail (h->rc_head, h->rc_tail, rc);
+  GNUNET_CONTAINER_DLL_insert_tail (h->ic_head,
+            h->ic_tail,
+            ic);
+  trigger_transmit (h);
+  return ic;
+}
+
+/* end of sensor_api.c */

Added: gnunet/src/sensor/test_sensor_api.c
===================================================================
--- gnunet/src/sensor/test_sensor_api.c                         (rev 0)
+++ gnunet/src/sensor/test_sensor_api.c 2014-04-14 12:08:48 UTC (rev 33061)
@@ -0,0 +1,84 @@
+/*
+     This file is part of GNUnet.
+     (C)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file sensor/test_sensor_api.c
+ * @brief testcase for sensor_api.c
+ */
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_util_lib.h>
+#include "gnunet_sensor_service.h"
+
+
+static int ok = 1;
+
+
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  ok = 0;
+}
+
+
+static int
+check ()
+{
+  char *const argv[] = { "test-sensor-api", NULL };
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_OPTION_END
+  };
+  struct GNUNET_OS_Process *proc;
+  char *path = GNUNET_OS_get_libexec_binary_path ( "gnunet-service-sensor");
+  if (NULL == path)
+  {
+               fprintf (stderr, "Service executable not found `%s'\n", 
"gnunet-service-sensor");
+               return -1;
+  }
+
+  proc = GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL,
+      NULL, NULL, path, "gnunet-service-sensor", NULL);
+
+  GNUNET_free (path);
+  GNUNET_assert (NULL != proc);
+  GNUNET_PROGRAM_run (1, argv, "test-sensor-api", "nohelp",
+                      options, &run, &ok);
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
+    {
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+      ok = 1;
+    }
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_destroy (proc);
+  return ok;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  GNUNET_log_setup ("test_statistics_api", 
+                   "WARNING",
+                   NULL);
+  return check ();
+}
+
+/* end of test_sensor_api.c */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]