gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r34056 - in gnunet/src: include sensor sensordashboard


From: gnunet
Subject: [GNUnet-SVN] r34056 - in gnunet/src: include sensor sensordashboard
Date: Fri, 25 Jul 2014 20:02:46 +0200

Author: otarabai
Date: 2014-07-25 20:02:46 +0200 (Fri, 25 Jul 2014)
New Revision: 34056

Modified:
   gnunet/src/include/gnunet_protocols.h
   gnunet/src/include/gnunet_sensor_util_lib.h
   gnunet/src/sensor/gnunet-service-sensor-update.c
   gnunet/src/sensor/gnunet-service-sensor.c
   gnunet/src/sensor/sensor_util_lib.c
   gnunet/src/sensordashboard/gnunet-service-sensordashboard.c
Log:
sensor: towards update functionality


Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h       2014-07-25 13:24:15 UTC (rev 
34055)
+++ gnunet/src/include/gnunet_protocols.h       2014-07-25 18:02:46 UTC (rev 
34056)
@@ -2438,7 +2438,17 @@
  */
 #define GNUNET_MESSAGE_TYPE_SENSOR_BRIEF 806
 
+/**
+ * Request for full sensor information
+ */
+#define GNUNET_MESSAGE_TYPE_SENSOR_FULL_REQ 807
 
+/**
+ * Full sensor information
+ */
+#define GNUNET_MESSAGE_TYPE_SENSOR_FULL 808
+
+
 
/*******************************************************************************
  * PEERSTORE message types
  
******************************************************************************/

Modified: gnunet/src/include/gnunet_sensor_util_lib.h
===================================================================
--- gnunet/src/include/gnunet_sensor_util_lib.h 2014-07-25 13:24:15 UTC (rev 
34055)
+++ gnunet/src/include/gnunet_sensor_util_lib.h 2014-07-25 18:02:46 UTC (rev 
34056)
@@ -258,10 +258,56 @@
 
 };
 
+/**
+ * Used to communicate full information about a sensor.
+ */
+struct GNUNET_SENSOR_SensorFullMessage
+{
+
+  /**
+   * GNUNET general message header.
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Size of the config file carrying full sensor information.
+   * Allocated at position 0 after this struct.
+   */
+  uint16_t cfg_size;
+
+  /**
+   * Name of the file (usually script) associated with this sensor.
+   * At the moment we only support having one file since that's all our sensors
+   * need at the moment.
+   * The file name is allocated at position 1 after this struct.
+   */
+  uint16_t scriptname_size;
+
+  /**
+   * Size of the file (usually script) associated with this sensor.
+   * The file binary is allocated at position 2 after this struct.
+   */
+  uint16_t script_size;
+
+};
+
 GNUNET_NETWORK_STRUCT_END
 
 
 /**
+ * Given two version numbers as major and minor, compare them.
+ *
+ * @param v1_major First part of first version number
+ * @param v1_minor Second part of first version number
+ * @param v2_major First part of second version number
+ * @param v2_minor Second part of second version number
+ */
+int
+GNUNET_SENSOR_version_compare (uint16_t v1_major, uint16_t v1_minor,
+                               uint16_t v2_major, uint16_t v2_minor);
+
+
+/**
  * Reads sensor definitions from local data files
  *
  * @return a multihashmap of loaded sensors

Modified: gnunet/src/sensor/gnunet-service-sensor-update.c
===================================================================
--- gnunet/src/sensor/gnunet-service-sensor-update.c    2014-07-25 13:24:15 UTC 
(rev 34055)
+++ gnunet/src/sensor/gnunet-service-sensor-update.c    2014-07-25 18:02:46 UTC 
(rev 34056)
@@ -44,6 +44,29 @@
 
 
 /**
+ * Message queued to be sent to an update point stored in a DLL
+ */
+struct PendingMessage
+{
+
+  /**
+   * DLL
+   */
+  struct PendingMessage *prev;
+
+  /**
+   * DLL
+   */
+  struct PendingMessage *next;
+
+  /**
+   * Actual queued message
+   */
+  struct GNUNET_MessageHeader *msg;
+
+};
+
+/**
  * Sensors update point
  */
 struct UpdatePoint
@@ -70,16 +93,31 @@
   struct GNUNET_CADET_Channel *ch;
 
   /**
-   * CADET transmit handle for a sensor list request.
+   * CADET transmit handle for a message to be sent to update point.
    */
-  struct GNUNET_CADET_TransmitHandle *sensor_list_req_th;
+  struct GNUNET_CADET_TransmitHandle *th;
 
   /**
+   * Head of DLL of pending requests to be sent to update point.
+   */
+  struct PendingMessage *pm_head;
+
+  /**
+   * Tail of DLL of pending requests to be sent to update point.
+   */
+  struct PendingMessage *pm_tail;
+
+  /**
    * Are we waiting for a sensor list?
    */
   int expecting_sensor_list;
 
   /**
+   * How many sensor updates did we request and are waiting for.
+   */
+  int expected_sensor_updates;
+
+  /**
    * Did a failure occur while dealing with this update point before?
    */
   int failed;
@@ -93,6 +131,11 @@
 static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 /**
+ * Hashmap of known sensors
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *sensors;
+
+/**
  * Head of update points DLL.
  */
 static struct UpdatePoint *up_head;
@@ -115,7 +158,7 @@
 /**
  * Are we in the process of checking and updating sensors?
  */
-static int updating; //TODO: when done, set to #GNUNET_NO and destroy channel
+static int updating;
 
 
 /**
@@ -128,7 +171,14 @@
 check_for_updates (void *cls,
                    const struct GNUNET_SCHEDULER_TaskContext *tc);
 
+/**
+ * Trigger sending next pending message to the default update point if any.
+ *
+ */
+static void
+trigger_send_next_msg ();
 
+
 /**
  * Cleanup update point context. This does not destroy the struct itself.
  *
@@ -137,11 +187,23 @@
 static void
 cleanup_updatepoint (struct UpdatePoint *up)
 {
-  if (NULL != up->sensor_list_req_th)
+  struct PendingMessage *pm;
+
+  up->expecting_sensor_list = GNUNET_NO;
+  up->expected_sensor_updates = 0;
+  if (NULL != up->th)
   {
-    GNUNET_CADET_notify_transmit_ready_cancel (up->sensor_list_req_th);
-    up->sensor_list_req_th = NULL;
+    GNUNET_CADET_notify_transmit_ready_cancel (up->th);
+    up->th = NULL;
   }
+  pm = up->pm_head;
+  while (NULL != pm)
+  {
+    GNUNET_CONTAINER_DLL_remove (up->pm_head, up->pm_tail, pm);
+    GNUNET_free (pm->msg);
+    GNUNET_free (pm);
+    pm = up->pm_head;
+  }
   if (NULL != up->ch)
   {
     GNUNET_CADET_channel_destroy (up->ch);
@@ -217,7 +279,7 @@
  * to queue more data.  @a buf will be NULL and @a size zero if the
  * connection was closed for writing in the meantime.
  *
- * Writes the sensor list request to be sent to the update point.
+ * Perform the actual sending of the message to update point.
  *
  * @param cls closure (unused)
  * @param size number of bytes available in @a buf
@@ -225,30 +287,75 @@
  * @return number of bytes written to @a buf
  */
 static size_t
-do_send_sensor_list_req (void *cls, size_t size, void *buf)
+do_send_msg (void *cls, size_t size, void *buf)
 {
-  struct GNUNET_MessageHeader *msg;
+  struct PendingMessage *pm;
   size_t msg_size;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Sending sensor list request now.\n");
-  up_default->sensor_list_req_th = NULL;
-  if (NULL == buf)
+  up_default->th = NULL;
+  pm = up_default->pm_head;
+  msg_size = ntohs (pm->msg->size);
+  GNUNET_CONTAINER_DLL_remove (up_default->pm_head, up_default->pm_tail, pm);
+  if (NULL == buf || size < msg_size)
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("Error trying to send a message to update point `%s'.\n"),
+                GNUNET_i2s (&up_default->peer_id));
     fail ();
     return 0;
   }
-  msg = GNUNET_new (struct GNUNET_MessageHeader);
-  msg_size = sizeof (struct GNUNET_MessageHeader);
-  msg->size = htons (msg_size);
-  msg->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_LIST_REQ);
-  memcpy (buf, msg, msg_size);
-  up_default->expecting_sensor_list = GNUNET_YES;
+  memcpy (buf, pm->msg, msg_size);
+  GNUNET_free (pm->msg);
+  GNUNET_free (pm);
+  trigger_send_next_msg ();
   return msg_size;
 }
 
 
 /**
+ * Trigger sending next pending message to the default update point if any.
+ *
+ */
+static void
+trigger_send_next_msg ()
+{
+  struct PendingMessage *pm;
+
+  if (NULL == up_default->pm_head)
+    return;
+  if (NULL != up_default->th)
+    return;
+  pm = up_default->pm_head;
+  up_default->th =
+      GNUNET_CADET_notify_transmit_ready (up_default->ch,
+                                          GNUNET_YES,
+                                          GNUNET_TIME_UNIT_FOREVER_REL,
+                                          ntohs (pm->msg->size),
+                                          &do_send_msg,
+                                          NULL);
+}
+
+
+/**
+ * Add a message to the queue to be sent to the current default update point.
+ *
+ * @param msg Message to be queued
+ */
+static void
+queue_msg (struct GNUNET_MessageHeader *msg)
+{
+  struct PendingMessage *pm;
+
+  pm = GNUNET_new (struct PendingMessage);
+  pm->msg = msg;
+  GNUNET_CONTAINER_DLL_insert_tail (up_default->pm_head,
+                                    up_default->pm_tail,
+                                    pm);
+  trigger_send_next_msg ();
+}
+
+
+/**
  * Contact update points to check for new updates
  *
  * @param cls unused
@@ -258,6 +365,9 @@
 check_for_updates (void *cls,
                    const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
+  struct GNUNET_MessageHeader *msg;
+  size_t msg_size;
+
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
     return;
   if (GNUNET_YES == updating)
@@ -290,12 +400,12 @@
     return;
   }
   /* Start by requesting list of sensors available from update point */
-  up_default->sensor_list_req_th =
-      GNUNET_CADET_notify_transmit_ready (up_default->ch,
-                                          GNUNET_YES,
-                                          GNUNET_TIME_UNIT_FOREVER_REL,
-                                          sizeof (struct GNUNET_MessageHeader),
-                                          &do_send_sensor_list_req, NULL);
+  up_default->expecting_sensor_list = GNUNET_YES;
+  msg = GNUNET_new (struct GNUNET_MessageHeader);
+  msg_size = sizeof (struct GNUNET_MessageHeader);
+  msg->size = htons (msg_size);
+  msg->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_LIST_REQ);
+  queue_msg (msg);
   GNUNET_SCHEDULER_add_delayed (SENSOR_UPDATE_CHECK_INTERVAL,
                                 &check_for_updates, NULL);
 }
@@ -353,8 +463,9 @@
     up = GNUNET_new (struct UpdatePoint);
     up->peer_id.public_key = public_key;
     up->ch = NULL;
-    up->sensor_list_req_th = NULL;
+    up->th = NULL;
     up->expecting_sensor_list = GNUNET_NO;
+    up->expected_sensor_updates = 0;
     up->failed = GNUNET_NO;
     GNUNET_CONTAINER_DLL_insert (up_head, up_tail, up);
     LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -366,6 +477,38 @@
 
 
 /**
+ * Checks if the given sensor name and version (retrieved from an update point)
+ * is new for us and we would like to install it. This is the case if we don't
+ * have this sensor or we have an old version of it.
+ *
+ * @param sensorname Sensor name
+ * @param sensorversion_major First part of version number
+ * @param sensorversion_minor Second part of version number
+ * @return #GNUNET_YES if we don't have this sensor
+ *         #GNUNET_NO if we have it
+ */
+static int
+update_required (char *sensorname,
+                 uint16_t sensorversion_major,
+                 uint16_t sensorversion_minor)
+{
+  struct GNUNET_HashCode key;
+  struct GNUNET_SENSOR_SensorInfo *local_sensor;
+
+  GNUNET_CRYPTO_hash (sensorname, strlen (sensorname) + 1, &key);
+  local_sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &key);
+  if (NULL == local_sensor)
+    return GNUNET_YES;
+  if (GNUNET_SENSOR_version_compare (local_sensor->version_major,
+                                     local_sensor->version_minor,
+                                     sensorversion_major,
+                                     sensorversion_minor) < 0)
+    return GNUNET_YES;
+  return GNUNET_NO;
+}
+
+
+/**
  * Handler of a sensor list message received from an update point.
  *
  * @param cls Closure (unused).
@@ -382,24 +525,49 @@
                      const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_SENSOR_SensorBriefMessage *sbm;
+  struct GNUNET_MessageHeader *pull_req;
+  uint16_t version_major;
+  uint16_t version_minor;
+  uint16_t msg_size;
 
   GNUNET_assert (*channel_ctx == up_default);
-  GNUNET_assert (GNUNET_YES == up_default->expecting_sensor_list);
+  if (GNUNET_YES != up_default->expecting_sensor_list)
+  {
+    GNUNET_break_op (0);
+    fail ();
+    return GNUNET_OK;
+  }
   if (GNUNET_MESSAGE_TYPE_SENSOR_END == ntohs (message->type))
   {
     up_default->expecting_sensor_list = GNUNET_NO;
-    //TODO: cleanup
-    updating = GNUNET_NO; //FIXME: should not be here, only for testing
+    if (0 == up_default->expected_sensor_updates)
+    {
+      updating = GNUNET_NO;
+      cleanup_updatepoint (up_default);
+      return GNUNET_OK;
+    }
   }
   else
   {
     sbm = (struct GNUNET_SENSOR_SensorBriefMessage *)message;
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Sensor brief: %.*s %d.%d\n",
-         ntohs (sbm->name_size),
-         &sbm[1],
-         ntohs (sbm->version_major),
-         ntohs (sbm->version_minor));
+    version_major = ntohs (sbm->version_major);
+    version_minor = ntohs (sbm->version_minor);
+    if (GNUNET_YES == update_required ((char *)&sbm[1],
+                                       version_major,
+                                       version_minor))
+    {
+      LOG (GNUNET_ERROR_TYPE_INFO,
+           "Requesting sensor %s %d.%d from update point.\n",
+           &sbm[1], version_major, version_minor);
+      /* We duplicate the same msg received but change the type and send it
+       * back to update point to ask for full sensor information. */
+      msg_size = ntohs (message->size);
+      pull_req = GNUNET_malloc (msg_size);
+      memcpy (pull_req, message, msg_size);
+      pull_req->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_FULL_REQ);
+      queue_msg (pull_req);
+      up_default->expected_sensor_updates ++;
+    }
   }
   GNUNET_CADET_receive_done (channel);
   return GNUNET_OK;
@@ -407,6 +575,58 @@
 
 
 /**
+ * Handler of a sensor list message received from an update point.
+ *
+ * @param cls Closure (unused).
+ * @param channel Connection to the other end.
+ * @param channel_ctx Place to store local state associated with the channel.
+ * @param message The actual message.
+ * @return #GNUNET_OK to keep the channel open,
+ *         #GNUNET_SYSERR to close it (signal serious error).
+ */
+static int
+handle_sensor_full (void *cls,
+                     struct GNUNET_CADET_Channel *channel,
+                     void **channel_ctx,
+                     const struct GNUNET_MessageHeader *message)
+{
+  struct GNUNET_SENSOR_SensorFullMessage *sfm;
+  uint16_t msg_size;
+
+  /* error check */
+  GNUNET_assert (*channel_ctx == up_default);
+  msg_size = ntohs (message->size);
+  if (up_default->expected_sensor_updates <= 0 ||
+      msg_size < sizeof (struct GNUNET_SENSOR_SensorFullMessage))
+  {
+    GNUNET_break_op (0);
+    fail ();
+    return GNUNET_OK;
+  }
+  /* parse received msg */
+  sfm = (struct GNUNET_SENSOR_SensorFullMessage *)message;
+  LOG (GNUNET_ERROR_TYPE_INFO,
+       "Received full sensor info:\n"
+       "File size: %d\n"
+       "Script name size: %d\n"
+       "Script size: %d.\n",
+       ntohs (sfm->cfg_size),
+       ntohs (sfm->scriptname_size),
+       ntohs (sfm->script_size));
+  //TODO: do the actual update
+  up_default->expected_sensor_updates --;
+  if (0 == up_default->expected_sensor_updates)
+  {
+    updating = GNUNET_NO;
+    cleanup_updatepoint (up_default);
+  }
+  else
+    GNUNET_CADET_receive_done (channel);
+  return GNUNET_OK;
+}
+
+
+/**
  * Function called whenever a channel is destroyed.  Should clean up
  * any associated state.
  *
@@ -424,8 +644,6 @@
 {
   struct UpdatePoint *up = channel_ctx;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "CADET Channel destroyed callback triggered.\n");
   up->ch = NULL;
   if (GNUNET_YES == updating)
   {
@@ -445,16 +663,18 @@
  */
 int
 SENSOR_update_start (const struct GNUNET_CONFIGURATION_Handle *c,
-                     struct GNUNET_CONTAINER_MultiHashMap *sensors)
+                     struct GNUNET_CONTAINER_MultiHashMap *s)
 {
   static struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
       {&handle_sensor_brief, GNUNET_MESSAGE_TYPE_SENSOR_BRIEF, 0},
       {&handle_sensor_brief, GNUNET_MESSAGE_TYPE_SENSOR_END, 0},
+      {&handle_sensor_full, GNUNET_MESSAGE_TYPE_SENSOR_FULL, 0},
       {NULL, 0, 0}
   };
 
-  GNUNET_assert(NULL != sensors);
+  GNUNET_assert(NULL != s);
   cfg = c;
+  sensors = s;
   cadet = GNUNET_CADET_connect(cfg,
                                NULL,
                                NULL,

Modified: gnunet/src/sensor/gnunet-service-sensor.c
===================================================================
--- gnunet/src/sensor/gnunet-service-sensor.c   2014-07-25 13:24:15 UTC (rev 
34055)
+++ gnunet/src/sensor/gnunet-service-sensor.c   2014-07-25 18:02:46 UTC (rev 
34056)
@@ -212,9 +212,10 @@
  * @param key hash of sensor name, key to hashmap
  * @param value a `struct GNUNET_SENSOR_SensorInfo *`
  */
-int add_sensor_to_tc (void *cls,
-                      const struct GNUNET_HashCode *key,
-                      void *value)
+static int
+add_sensor_to_tc (void *cls,
+                  const struct GNUNET_HashCode *key,
+                  void *value)
 {
   struct GNUNET_SERVER_TransmitContext *tc = cls;
   struct GNUNET_SENSOR_SensorInfo *sensorinfo = value;
@@ -291,11 +292,12 @@
  * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if 
not
  * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
  */
-int sensor_statistics_iterator (void *cls,
-    const char *ss,
-    const char *name,
-    uint64_t value,
-    int is_persistent)
+static int
+sensor_statistics_iterator (void *cls,
+                            const char *ss,
+                            const char *name,
+                            uint64_t value,
+                            int is_persistent)
 {
   struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls;
   double dvalue = (double)value;
@@ -323,7 +325,8 @@
  * @param success #GNUNET_OK if statistics were
  *        successfully obtained, #GNUNET_SYSERR if not.
  */
-void end_sensor_run_stat (void *cls, int success)
+static void
+end_sensor_run_stat (void *cls, int success)
 {
   struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls;
 
@@ -376,7 +379,8 @@
  * @param cls `struct GNUNET_SENSOR_SensorInfo *`
  * @param line line of output from a command, NULL for the end
  */
-void sensor_process_callback (void *cls, const char *line)
+static void
+sensor_process_callback (void *cls, const char *line)
 {
   struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls;
   void *value;
@@ -445,9 +449,9 @@
  * @param cls 'struct SensorInfo'
  * @param tc unsed
  */
-void
+static void
 sensor_run (void *cls,
-    const struct GNUNET_SCHEDULER_TaskContext * tc)
+            const struct GNUNET_SCHEDULER_TaskContext * tc)
 {
   struct GNUNET_SENSOR_SensorInfo *sensorinfo = cls;
   int check_result;
@@ -493,11 +497,12 @@
       //search in sensor directory
       sensors_dir = GNUNET_SENSOR_get_sensor_dir ();
       GNUNET_free(process_path);
-      GNUNET_asprintf(&process_path, "%s%s-files%s%s",
-          sensors_dir,
-          sensorinfo->name,
-          DIR_SEPARATOR_STR,
-          sensorinfo->ext_process);
+      GNUNET_asprintf(&process_path,
+                      "%s%s-files%s%s",
+                      sensors_dir,
+                      sensorinfo->name,
+                      DIR_SEPARATOR_STR,
+                      sensorinfo->ext_process);
       GNUNET_free(sensors_dir);
       check_result =
         GNUNET_OS_check_helper_binary(process_path, GNUNET_NO, NULL);
@@ -541,8 +546,8 @@
  *         iterate,
  *         #GNUNET_NO if not.
  */
-int schedule_sensor(void *cls,
-    const struct GNUNET_HashCode *key, void *value)
+static int
+schedule_sensor (void *cls, const struct GNUNET_HashCode *key, void *value)
 {
   struct GNUNET_SENSOR_SensorInfo *sensorinfo = value;
 

Modified: gnunet/src/sensor/sensor_util_lib.c
===================================================================
--- gnunet/src/sensor/sensor_util_lib.c 2014-07-25 13:24:15 UTC (rev 34055)
+++ gnunet/src/sensor/sensor_util_lib.c 2014-07-25 18:02:46 UTC (rev 34056)
@@ -295,23 +295,26 @@
   return sensor;
 }
 
+
 /**
- * Compares version numbers of two sensors
+ * Given two version numbers as major and minor, compare them.
  *
- * @param s1 first sensor
- * @param s2 second sensor
- * @return 1: s1 > s2, 0: s1 == s2, -1: s1 < s2
+ * @param v1_major First part of first version number
+ * @param v1_minor Second part of first version number
+ * @param v2_major First part of second version number
+ * @param v2_minor Second part of second version number
  */
-static int
-sensor_version_compare (struct GNUNET_SENSOR_SensorInfo *s1,
-                        struct GNUNET_SENSOR_SensorInfo *s2)
+int
+GNUNET_SENSOR_version_compare (uint16_t v1_major, uint16_t v1_minor,
+                               uint16_t v2_major, uint16_t v2_minor)
 {
-  if (s1->version_major == s2->version_major)
-    return (s1->version_minor < s2->version_minor) ? -1 : (s1->version_minor > 
s2->version_minor);
+  if (v1_major == v2_major)
+    return (v1_minor < v2_minor) ? -1 : (v1_minor > v2_minor);
   else
-    return (s1->version_major < s2->version_major) ? -1 : (s1->version_major > 
s2->version_major);
+    return (v1_major < v2_major) ? -1 : (v1_major > v2_major);
 }
 
+
 /**
  * Adds a new sensor to given hashmap.
  * If the same name exist, compares versions and update if old.
@@ -332,7 +335,10 @@
   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
+    if(GNUNET_SENSOR_version_compare (existing->version_major,
+                                      existing->version_minor,
+                                      sensor->version_major,
+                                      sensor->version_minor) >= 0)
     {
       LOG (GNUNET_ERROR_TYPE_INFO,
            _("Sensor `%s' already exists with same or newer version\n"),
@@ -389,9 +395,10 @@
 }
 
 /*
- * Get path to the directory containing the sensor definition files
+ * Get path to the directory containing the sensor definition files with a
+ * trailing directory separator.
  *
- * @return sensor files directory
+ * @return sensor files directory full path
  */
 char *
 GNUNET_SENSOR_get_sensor_dir ()
@@ -400,8 +407,10 @@
   char* sensordir;
 
   datadir = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_DATADIR);
-  GNUNET_asprintf(&sensordir, "%ssensors%s",
-      datadir, DIR_SEPARATOR_STR);
+  GNUNET_asprintf (&sensordir,
+                   "%ssensors%s",
+                   datadir,
+                   DIR_SEPARATOR_STR);
   GNUNET_free(datadir);
 
   return sensordir;

Modified: gnunet/src/sensordashboard/gnunet-service-sensordashboard.c
===================================================================
--- gnunet/src/sensordashboard/gnunet-service-sensordashboard.c 2014-07-25 
13:24:15 UTC (rev 34055)
+++ gnunet/src/sensordashboard/gnunet-service-sensordashboard.c 2014-07-25 
18:02:46 UTC (rev 34056)
@@ -558,7 +558,7 @@
   if (NULL == reading)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Received an invalid sensor reading from peer `%s'\n",
+                "Received an invalid sensor reading from peer `%s'.\n",
                 GNUNET_i2s (&cp->peerid));
     return GNUNET_SYSERR;
   }
@@ -583,6 +583,142 @@
 
 
 /**
+ * Create a message with full information about sensor
+ *
+ * @param sensorname Name of sensor requested
+ * @return Message ready to be sent to client or NULL on error
+ */
+static struct GNUNET_SENSOR_SensorFullMessage *
+create_full_sensor_msg (char *sensorname)
+{
+  struct GNUNET_HashCode key;
+  struct GNUNET_SENSOR_SensorInfo *sensor;
+  struct GNUNET_SENSOR_SensorFullMessage *msg;
+  char *sensor_dir;
+  char *sensor_path;
+  char *sensorscript_path;
+  uint64_t sensorfile_size;
+  uint64_t sensorscriptname_size;
+  uint64_t sensorscript_size;
+  uint64_t total_size;
+  void *dummy;
+
+  GNUNET_CRYPTO_hash (sensorname, strlen (sensorname) + 1, &key);
+  sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &key);
+  if (NULL == sensor)
+    return NULL;
+  sensor_dir = GNUNET_SENSOR_get_sensor_dir ();
+  GNUNET_asprintf (&sensor_path, "%s%s",
+                   sensor_dir, sensorname);
+  if (GNUNET_OK != GNUNET_DISK_file_size (sensor_path,
+                                          &sensorfile_size,
+                                          GNUNET_NO,
+                                          GNUNET_YES))
+  {
+    GNUNET_free (sensor_dir);
+    GNUNET_free (sensor_path);
+    return NULL;
+  }
+  sensorscript_size = 0;
+  sensorscriptname_size = 0;
+  /* Test if there is an associated script */
+  if (NULL != sensor->ext_process)
+  {
+    GNUNET_asprintf (&sensorscript_path, "%s%s-files%s%s",
+                     sensor_dir,
+                     sensor->name,
+                     DIR_SEPARATOR_STR,
+                     sensor->ext_process);
+    if (GNUNET_OK == GNUNET_DISK_file_size (sensorscript_path,
+                                            &sensorscript_size,
+                                            GNUNET_NO,
+                                            GNUNET_YES))
+      sensorscriptname_size = strlen (sensor->ext_process) + 1;
+  }
+  /* Construct the msg */
+  total_size = sizeof (struct GNUNET_SENSOR_SensorFullMessage) +
+               sensorfile_size + sensorscriptname_size + sensorscript_size;
+  msg = GNUNET_malloc (total_size);
+  msg->header.size = htons (total_size);
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_FULL);
+  msg->cfg_size = htons (sensorfile_size);
+  msg->scriptname_size = htons (sensorscriptname_size);
+  msg->script_size = htons (sensorscript_size);
+  dummy = &msg[1];
+  GNUNET_DISK_fn_read (sensor_path, dummy, sensorfile_size);
+  dummy += sensorfile_size;
+  if (sensorscriptname_size > 0)
+  {
+    memcpy (dummy, sensor->ext_process, sensorscriptname_size);
+    dummy += sensorscriptname_size;
+    GNUNET_DISK_fn_read (sensorscript_path, dummy, sensorscript_size);
+  }
+  GNUNET_free (sensor_dir);
+  GNUNET_free (sensor_path);
+  GNUNET_free (sensorscript_path);
+  return msg;
+}
+
+
+/**
+ * Called with any request for full sensor information.
+ *
+ * Each time the function must call #GNUNET_CADET_receive_done on the channel
+ * in order to receive the next message. This doesn't need to be immediate:
+ * can be delayed if some processing is done on the message.
+ *
+ * @param cls Closure (set from #GNUNET_CADET_connect).
+ * @param channel Connection to the other end.
+ * @param channel_ctx Place to store local state associated with the channel.
+ * @param message The actual message.
+ * @return #GNUNET_OK to keep the channel open,
+ *         #GNUNET_SYSERR to close it (signal serious error).
+ */
+static int
+handle_sensor_full_req (void *cls,
+                        struct GNUNET_CADET_Channel *channel,
+                        void **channel_ctx,
+                        const struct GNUNET_MessageHeader *message)
+{
+  struct ClientPeerContext *cp = *channel_ctx;
+  struct GNUNET_SENSOR_SensorBriefMessage *sbm = NULL;
+  struct GNUNET_SENSOR_SensorFullMessage *sfm;
+  uint16_t msg_size;
+  uint16_t sensorname_size;
+
+  msg_size = ntohs (message->size);
+  /* parse & error check */
+  if (msg_size > sizeof (struct GNUNET_SENSOR_SensorBriefMessage))
+  {
+    sbm = (struct GNUNET_SENSOR_SensorBriefMessage *)message;
+    sensorname_size = ntohs (sbm->name_size);
+    if (msg_size != sizeof (struct GNUNET_SENSOR_SensorBriefMessage) +
+                    sensorname_size)
+      sbm = NULL;
+  }
+  if (NULL == sbm)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Received an invalid full sensor request from peer `%s'.\n",
+                GNUNET_i2s (&cp->peerid));
+    return GNUNET_SYSERR;
+  }
+  /* Create and send msg with full sensor info */
+  sfm = create_full_sensor_msg ((char *)&sbm[1]);
+  if (NULL == sfm)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error creating full sensor info msg for sensor `%s'.\n",
+                (char *)&sbm[1]);
+    return GNUNET_SYSERR;
+  }
+  queue_msg ((struct GNUNET_MessageHeader *)sfm, cp);
+  GNUNET_CADET_receive_done (channel);
+  return GNUNET_OK;
+}
+
+
+/**
  * Process sensordashboard requests.
  *
  * @param cls closure
@@ -602,6 +738,9 @@
       {&handle_sensor_list_req,
        GNUNET_MESSAGE_TYPE_SENSOR_LIST_REQ,
        sizeof (struct GNUNET_MessageHeader)},
+      {&handle_sensor_full_req,
+      GNUNET_MESSAGE_TYPE_SENSOR_FULL_REQ,
+      sizeof (struct GNUNET_MessageHeader)},
       {NULL, 0, 0}
   };
   static uint32_t cadet_ports[] = {




reply via email to

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