pud: enable dynamic polling of the position file
authorFerry Huberts <ferry.huberts@pelagic.nl>
Thu, 29 Nov 2012 20:44:47 +0000 (21:44 +0100)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Thu, 29 Nov 2012 20:57:00 +0000 (21:57 +0100)
Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
lib/pud/olsrd.conf.sample
lib/pud/src/configuration.c
lib/pud/src/configuration.h
lib/pud/src/pud.c
lib/pud/src/pudOlsrdPlugin.h
lib/pud/src/receiver.c
lib/pud/src/receiver.h

index 99b6deb..9f33b44 100644 (file)
@@ -89,6 +89,17 @@ LoadPlugin "<olsrd plugin library path>/olsrd_pud.so.1.1.0"
     #
     #PlParam "positionFile"                     ""
 
+    # Specifies the period in milliseconds on which to read the positionFile
+    # (if it changed) and activate its new setting for the position.
+    # This setting is only relevant if positionFile has been configured.
+    # A setting of zero disables dynamic updates, the positionFile is then only
+    # read during olsrd startup.
+    #
+    # Default: 0
+    #
+    #PlParam "positionFilePeriod" "0"
+
+
     #
     # TX Parameters
     #
index 020965e..08c3e99 100644 (file)
@@ -548,11 +548,6 @@ int setPositionFile(const char *value, void *data __attribute__ ((unused)),
 
        assert(value != NULL);
 
-       if (!startPositionFile()) {
-               stopPositionFile();
-               return true;
-       }
-
        valueLength = strlen(value);
        if (valueLength > PATH_MAX) {
                pudError(false, "Value of parameter %s is too long, maximum length is"
@@ -567,6 +562,58 @@ int setPositionFile(const char *value, void *data __attribute__ ((unused)),
 }
 
 /*
+ * positionFilePeriod
+ */
+
+/** The positionFilePeriod value (milliseconds) */
+unsigned long long positionFilePeriod = PUD_POSFILEPERIOD_DEFAULT;
+
+/**
+ @return
+ The positionFilePeriod (in milliseconds)
+ */
+unsigned long long getPositionFilePeriod(void) {
+       return positionFilePeriod;
+}
+
+/**
+ Set the positionFilePeriod
+
+ @param value
+ The positionFilePeriod (a number in string representation)
+ @param data
+ Unused
+ @param addon
+ Unused
+
+ @return
+ - true when an error is detected
+ - false otherwise
+ */
+int setPositionFilePeriod(const char *value, void *data __attribute__ ((unused)),
+               set_plugin_parameter_addon addon __attribute__ ((unused))) {
+       static const char * valueName = PUD_POSFILEPERIOD_NAME;
+       unsigned long long positionFilePeriodNew;
+
+       assert(value != NULL);
+
+       if (!readULL(valueName, value, &positionFilePeriodNew)) {
+               return true;
+       }
+
+       if ((positionFilePeriodNew != 0)
+                       && ((positionFilePeriodNew < PUD_POSFILEPERIOD_MIN) || (positionFilePeriodNew > PUD_POSFILEPERIOD_MAX))) {
+               pudError(false, "Configured %s (%llu) is outside of"
+                               " valid range %llu-%llu", valueName, positionFilePeriodNew, PUD_POSFILEPERIOD_MIN, PUD_POSFILEPERIOD_MAX);
+               return true;
+       }
+
+       positionFilePeriod = positionFilePeriodNew;
+
+       return false;
+}
+
+/*
  * txNonOlsrIf
  */
 
index 4152037..402306e 100644 (file)
@@ -83,6 +83,21 @@ setRxMcPort(const char *value, void *data, set_plugin_parameter_addon addon);
 char * getPositionFile(void);
 int setPositionFile(const char *value, void *data, set_plugin_parameter_addon addon);
 
+/** The name of the positionFilePeriod plugin parameter */
+#define PUD_POSFILEPERIOD_NAME    "positionFilePeriod"
+
+/** The default value of the positionFilePeriod plugin parameter */
+#define PUD_POSFILEPERIOD_DEFAULT ((unsigned long long)0)
+
+/** The minimal value of the positionFilePeriod plugin parameter */
+#define PUD_POSFILEPERIOD_MIN     ((unsigned long long)1000)
+
+/** The maximal value of the positionFilePeriod plugin parameter */
+#define PUD_POSFILEPERIOD_MAX     ((unsigned long long)320000000)
+
+unsigned long long getPositionFilePeriod(void);
+int setPositionFilePeriod(const char *value, void *data, set_plugin_parameter_addon addon);
+
 /*
  * TX Parameters
  */
index b2cf42c..13bac7e 100644 (file)
@@ -7,6 +7,7 @@
 #include "gpsConversion.h"
 #include "receiver.h"
 #include "state.h"
+#include "posFile.h"
 #include "compiler.h"
 
 /* OLSRD includes */
@@ -303,6 +304,20 @@ static void packetReceivedForOlsr(int skfd, void *data __attribute__ ((unused)),
 }
 
 /**
+ * Timer callback that reads the pud position file
+ */
+static void pud_read_position_file(void *context __attribute__ ((unused))) {
+       updatePositionFromFile();
+       return;
+}
+
+/** The timer cookie, used to trace back the originator in debug */
+static struct olsr_cookie_info *pud_position_file_timer_cookie = NULL;
+
+/** The timer */
+static struct timer_entry * pud_position_file_timer = NULL;
+
+/**
  Initialise the plugin: check the configuration, initialise the NMEA parser,
  create network interface sockets, hookup the plugin to OLSR and setup data
  that can be setup in advance.
@@ -312,6 +327,8 @@ static void packetReceivedForOlsr(int skfd, void *data __attribute__ ((unused)),
  - true otherwise
  */
 bool initPud(void) {
+       unsigned long long positionFilePeriod;
+
        if (!checkConfig()) {
                pudError(false, "Invalid configuration");
                goto error;
@@ -324,6 +341,10 @@ bool initPud(void) {
                goto error;
        }
 
+       if (!startPositionFile()) {
+               goto error;
+       }
+
        if (!startReceiver()) {
                pudError(false, "Could not start receiver");
                goto error;
@@ -353,6 +374,25 @@ bool initPud(void) {
        /* switch to syslog logging, load was succesful */
        pudErrorUseSysLog = !olsr_cnf->no_fork;
 
+       positionFilePeriod = getPositionFilePeriod();
+       if (getPositionFile() && positionFilePeriod) {
+               if (pud_position_file_timer_cookie == NULL) {
+                       pud_position_file_timer_cookie = olsr_alloc_cookie("pud position file", OLSR_COOKIE_TYPE_TIMER);
+                       if (pud_position_file_timer_cookie == NULL) {
+                               pudError(false, "Could not allocate pud position file cookie");
+                               return false;
+                       }
+               }
+               if (pud_position_file_timer == NULL) {
+                       pud_position_file_timer = olsr_start_timer(positionFilePeriod, 0, OLSR_TIMER_PERIODIC, &pud_read_position_file,
+                                       NULL, pud_position_file_timer_cookie);
+                       if (pud_position_file_timer == NULL) {
+                               pudError(false, "Could not start pud position file timer");
+                               return false;
+                       }
+               }
+       }
+
        return true;
 
        error: closePud();
@@ -364,6 +404,15 @@ bool initPud(void) {
  the NMEA parser.
  */
 void closePud(void) {
+       if (pud_position_file_timer != NULL) {
+               olsr_stop_timer(pud_position_file_timer);
+               pud_position_file_timer = NULL;
+       }
+       if (pud_position_file_timer_cookie != NULL) {
+               olsr_free_cookie(pud_position_file_timer_cookie);
+               pud_position_file_timer_cookie = NULL;
+       }
+       stopPositionFile();
        closeNetworkInterfaces();
        stopReceiver();
        destroyDeDupList(&deDupList);
index e5acbfd..e746e17 100644 (file)
@@ -34,6 +34,7 @@ static const struct olsrd_plugin_parameters plugin_parameters[] = {
        {       .name = PUD_RX_MC_ADDR_NAME, .set_plugin_parameter = &setRxMcAddr, .data = NULL},
        {       .name = PUD_RX_MC_PORT_NAME, .set_plugin_parameter = &setRxMcPort, .data = NULL},
        {       .name = PUD_POSFILE_NAME, .set_plugin_parameter = &setPositionFile, .data = NULL},
+       {       .name = PUD_POSFILEPERIOD_NAME, .set_plugin_parameter = &setPositionFilePeriod, .data = NULL},
 
        /* TX */
        {       .name = PUD_TX_NON_OLSR_IF_NAME, .set_plugin_parameter = &addTxNonOlsrInterface, .data = NULL},
index 86295af..eb29bff 100644 (file)
@@ -763,6 +763,16 @@ static void nmea_errors(const char *str, int str_size __attribute__((unused))) {
 }
 
 /**
+ * Helper function to read the position file into the transmit position
+ */
+void updatePositionFromFile(void) {
+  char * positionFile = getPositionFile();
+  if (positionFile) {
+    readPositionFile(positionFile, &transmitGpsInformation.txPosition.nmeaInfo);
+  }
+}
+
+/**
  Start the receiver
 
  @return
@@ -771,7 +781,6 @@ static void nmea_errors(const char *str, int str_size __attribute__((unused))) {
  */
 bool startReceiver(void) {
        MovementState externalState;
-       char * positionFile = getPositionFile();
 
        if (!nmea_parser_init(&nmeaParser)) {
                pudError(false, "Could not initialise NMEA parser");
@@ -781,11 +790,9 @@ bool startReceiver(void) {
        /* hook up the NMEA library error callback */
        nmea_context_set_error_func(&nmea_errors);
 
-       if (positionFile) {
-               readPositionFile(positionFile, &transmitGpsInformation.txPosition.nmeaInfo);
-       } else {
-               nmea_zero_INFO(&transmitGpsInformation.txPosition.nmeaInfo);
-       }
+       nmea_zero_INFO(&transmitGpsInformation.txPosition.nmeaInfo);
+       updatePositionFromFile();
+
        transmitGpsInformation.txGateway = olsr_cnf->main_addr;
        transmitGpsInformation.positionUpdated = false;
        transmitGpsInformation.nodeId = getNodeId();
index 1ee2f42..5770f47 100644 (file)
@@ -22,6 +22,7 @@ typedef struct _TransmitGpsInformation {
 bool startReceiver(void);
 void stopReceiver(void);
 
+void updatePositionFromFile(void);
 bool receiverUpdateGpsInformation(unsigned char * rxBuffer, size_t rxCount);
 
 #endif /* _PUD_RECEIVER_H_ */