pud: fix intSetupNodeIdBinaryDoubleLongLong for short values
[olsrd.git] / lib / pud / src / configuration.c
1 #include "configuration.h"
2
3 /* Plugin includes */
4 #include "pud.h"
5 #include "networkInterfaces.h"
6 #include "netTools.h"
7 #include "posFile.h"
8 #include "configTools.h"
9
10 /* OLSR includes */
11 #include <olsr_protocol.h>
12 #include <olsr.h>
13
14 /* System includes */
15 #include <unistd.h>
16 #include <nmea/parse.h>
17 #include <OlsrdPudWireFormat/nodeIdConversion.h>
18 #include <limits.h>
19
20 /* forward declarations */
21 static bool setupNodeIdBinaryAndValidate(NodeIdType nodeIdTypeNumber);
22
23 /*
24  * Note:
25  * Setters must return true when an error is detected, false otherwise
26  */
27
28 /*
29  * nodeIdType
30  */
31
32 /** The nodeIdType */
33 static NodeIdType nodeIdType = PUD_NODE_ID_TYPE_DEFAULT;
34
35 /**
36  @return
37  The node ID type
38  */
39 NodeIdType getNodeIdTypeNumber(void) {
40         return nodeIdType;
41 }
42
43 static int setNodeIdType(const char *value, const char * valueName) {
44         unsigned long long nodeIdTypeNew;
45
46         if (!readULL(valueName, value, &nodeIdTypeNew, 10)) {
47                 return true;
48         }
49
50         if (!isValidNodeIdType(nodeIdTypeNew)) {
51                 pudError(false, "Value in parameter %s (%llu) is reserved", valueName,
52                                 nodeIdTypeNew);
53                 return true;
54         }
55
56         nodeIdType = nodeIdTypeNew;
57
58         return false;
59 }
60
61 /*
62  * nodeId
63  */
64
65 /** The nodeId buffer */
66 static unsigned char nodeId[PUD_TX_NODEID_BUFFERSIZE];
67
68 /** The length of the string in the nodeId buffer */
69 static size_t nodeIdLength = 0;
70
71 /** True when the nodeId is set */
72 static bool nodeIdSet = false;
73
74 /** The nodeId as a binary representation, with status */
75 static nodeIdBinaryType nodeIdBinary;
76
77 /**
78  Get the nodeId and its length
79
80  @param length
81  a pointer to the variable in which to store the nodeId length (allowed to be
82  NULL, in which case the length is not stored)
83
84  @return
85  The node ID
86  */
87 unsigned char * getNodeId(size_t *length) {
88         if (!nodeIdSet) {
89                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
90         }
91
92         if (length != NULL) {
93                 *length = nodeIdLength;
94         }
95
96         return &nodeId[0];
97 }
98
99 /**
100  Get the nodeIdBinary
101
102  @return
103  The node ID in binary representation
104  */
105 nodeIdBinaryType * getNodeIdBinary(void) {
106         if (!nodeIdBinary.set) {
107                 setNodeId("", NULL, (set_plugin_parameter_addon) {.pc = NULL});
108         }
109
110         return &nodeIdBinary;
111 }
112
113 int setNodeId(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
114         size_t valueLength;
115         char * number;
116         char * identification;
117
118         assert (value != NULL);
119
120   nodeId[0] = '\0';
121   nodeIdLength = 0;
122   nodeIdSet = false;
123   nodeIdBinary.set = false;
124
125         valueLength = strlen(value);
126   number = olsr_malloc(valueLength + 1, "setNodeId");
127   strcpy(number, value);
128
129   /* split "number,identification" */
130   identification = strchr(number, ',');
131   if (identification) {
132     *identification = '\0';
133     identification++;
134   }
135
136   /* parse number into nodeIdType (if present) */
137   valueLength = strlen(number);
138   if (valueLength && setNodeIdType(number, PUD_NODE_ID_NAME)) {
139     free(number);
140     return true;
141   }
142
143   /* copy identification into nodeId (if present) */
144   if (identification) {
145     valueLength = strlen(identification);
146     if (valueLength > (PUD_TX_NODEID_BUFFERSIZE - 1)) {
147       pudError(false, "Value in parameter %s is too long, maximum length is"
148         " %u, current length is %lu", PUD_NODE_ID_NAME, (PUD_TX_NODEID_BUFFERSIZE - 1),
149           (unsigned long) valueLength);
150       free(number);
151       return true;
152     }
153
154     if (valueLength) {
155       strcpy((char *) &nodeId[0], identification);
156       nodeIdLength = valueLength;
157       nodeIdSet = true;
158     }
159   }
160
161   free(number);
162
163   /* fill in automatic values */
164   if (!nodeIdSet) {
165     if (nodeIdType == PUD_NODEIDTYPE_DNS) {
166       memset(nodeId, 0, sizeof(nodeId));
167       errno = 0;
168       if (gethostname((char *)&nodeId[0], sizeof(nodeId) - 1) < 0) {
169         pudError(true, "Could not get the host name");
170         return true;
171       }
172
173       nodeIdLength = strlen((char *)nodeId);
174       nodeIdSet = true;
175     } else if ((nodeIdType != PUD_NODEIDTYPE_MAC) && (nodeIdType != PUD_NODEIDTYPE_IPV4)
176         && (nodeIdType != PUD_NODEIDTYPE_IPV6)) {
177       pudError(false, "No node ID set while one is required for nodeId type %u", nodeIdType);
178       return true;
179     }
180   }
181
182   if (!setupNodeIdBinaryAndValidate(nodeIdType)) {
183     pudError(false, "nodeId (type %u) is incorrectly configured", nodeIdType);
184     return true;
185   }
186
187   return false;
188 }
189
190 /*
191  * nodeId Validation
192  */
193
194 /**
195  Validate whether the configured nodeId is valid w.r.t. the configured
196  nodeIdType, for types that are MAC addresses
197
198  @return
199  - true when ok
200  - false on failure
201  */
202 static bool intSetupNodeIdBinaryMAC(void) {
203         unsigned char * mac = getMainIpMacAddress();
204         if (!mac) {
205                 return false;
206         }
207
208         return setupNodeIdBinaryMAC(&nodeIdBinary, mac);
209 }
210
211 /**
212  Validate whether the configured nodeId is valid w.r.t. the configured
213  nodeIdType, for types that fit in an unsigned long long (64 bits)
214
215  @param min
216  the minimum value
217  @param max
218  the maximum value
219  @param bytes
220  the number of bytes in the buffer
221
222  @return
223  - true when ok
224  - false on failure
225  */
226 static bool intSetupNodeIdBinaryLongLong(unsigned long long min,
227     unsigned long long max, unsigned int bytes) {
228   unsigned long long longValue = 0;
229   if (!readULL(PUD_NODE_ID_NAME, (char *) getNodeId(NULL), &longValue, 10)) {
230     return false;
231   }
232
233   if ((longValue < min) || (longValue > max)) {
234     pudError(false, "%s value %llu is out of range [%llu,%llu]",
235         PUD_NODE_ID_NAME, longValue, min, max);
236     return false;
237   }
238
239   return setupNodeIdBinaryLongLong(&nodeIdBinary, longValue, bytes);
240 }
241
242 /**
243  Validate whether the configured nodeId is valid w.r.t. the configured
244  nodeIdType, for types that fit in a double unsigned long long (128 bits) with
245  a certain split that defined by chars1
246
247  @param chars1
248  the number of characters of the first part
249  @param min1
250  the minimum value of the first part
251  @param max1
252  the maximum value of the first part
253  @param bytes1
254  the number of bytes of the first part in the buffer
255  @param min2
256  the minimum value of the second part
257  @param max2
258  the maximum value of the second part
259  @param bytes2
260  the number of bytes of the second part in the buffer
261  @param base
262  the base of the number conversion: 10 for decimal, 16 for hexadecimal
263
264  @return
265  - true when ok
266  - false on failure
267  */
268 static bool intSetupNodeIdBinaryDoubleLongLong(
269     unsigned char * dst,
270     unsigned int chars1,
271     unsigned long long min1, unsigned long long max1,
272     unsigned int bytes1,
273                 unsigned long long min2, unsigned long long max2,
274                 unsigned int bytes2,
275                 int base) {
276         unsigned long long longValue1 = 0;
277         unsigned long long longValue2 = 0;
278
279         unsigned char * node_id = getNodeId(NULL);
280         size_t node_id_len = strlen((char *)node_id);
281
282         assert(chars1 > 0);
283         assert(bytes1 > 0);
284         assert(bytes2 > 0);
285
286   /* part 1 */
287         if (node_id_len > 0) {
288     unsigned char first[chars1 + 1];
289     int cpylen = node_id_len < chars1 ? node_id_len : chars1;
290
291     memcpy(first, node_id, cpylen);
292     first[cpylen] = '\0';
293
294     if (!readULL(PUD_NODE_ID_NAME, (char *)first, &longValue1, base)) {
295       return false;
296     }
297
298     if ((longValue1 < min1) || (longValue1 > max1)) {
299       pudError(false, "First %u character(s) of %s value %llu are out of range [%llu,%llu]",
300           cpylen, PUD_NODE_ID_NAME, longValue1, min1, max1);
301       return false;
302     }
303         }
304
305   /* part 2 */
306         if (node_id_len > chars1) {
307     if (!readULL(PUD_NODE_ID_NAME, (char *)&node_id[chars1], &longValue2, base)) {
308       return false;
309     }
310
311     if ((longValue2 < min2) || (longValue2 > max2)) {
312       pudError(false, "Last %u character(s) of %s value %llu are out of range [%llu,%llu]",
313           (unsigned int)(node_id_len - chars1), PUD_NODE_ID_NAME, longValue2, min2, max2);
314       return false;
315     }
316   } else {
317     /* longvalue1 is the only value, so it is the least significant value:
318      * exchange the 2 values */
319     unsigned long long tmp = longValue1;
320     longValue1 = longValue2;
321     longValue2 = tmp;
322   }
323
324         return setupNodeIdBinaryDoubleLongLong(&nodeIdBinary,
325             longValue1, &dst[0], bytes1,
326             longValue2, &dst[bytes1], bytes2);
327 }
328
329 /**
330  Validate whether the configured nodeId is valid w.r.t. the configured
331  nodeIdType, for types that are strings
332
333  @return
334  - true when ok
335  - false on failure
336  */
337 static bool intSetupNodeIdBinaryString(void) {
338         char report[256];
339         size_t nodeidlength;
340         char * nodeid = (char *)getNodeId(&nodeidlength);
341
342         if (nmea_parse_sentence_has_invalid_chars(nodeid, nodeidlength, PUD_NODE_ID_NAME, &report[0], sizeof(report))) {
343                 pudError(false, "%s", &report[0]);
344                 return false;
345         }
346
347         if (nodeidlength > (PUD_TX_NODEID_BUFFERSIZE - 1)) {
348                 pudError(false, "Length of parameter %s (%s) is too great", PUD_NODE_ID_NAME, &nodeid[0]);
349                 return false;
350         }
351
352         return setupNodeIdBinaryString(&nodeIdBinary, nodeid, nodeidlength);
353 }
354
355 /**
356  Validate whether the configured nodeId is valid w.r.t. the configured
357  nodeIdType, for types that are IP addresses
358
359  @return
360  - true when ok
361  - false on failure
362  */
363 static bool intSetupNodeIdBinaryIp(void) {
364         void * src;
365         size_t length;
366         if (olsr_cnf->ip_version == AF_INET) {
367                 src = &olsr_cnf->main_addr.v4;
368                 length = sizeof(struct in_addr);
369         } else {
370                 src = &olsr_cnf->main_addr.v6;
371                 length = sizeof(struct in6_addr);
372         }
373
374         return setupNodeIdBinaryIp(&nodeIdBinary, src, length);
375 }
376
377 /**
378  Validate whether the configured nodeId is valid w.r.t. the configured
379  nodeIdType and setup the binary value
380
381  @return
382  - true when ok
383  - false on failure
384  */
385 static bool setupNodeIdBinaryAndValidate(NodeIdType nodeIdTypeNumber) {
386         switch (nodeIdTypeNumber) {
387                 case PUD_NODEIDTYPE_MAC: /* hardware address */
388                         return intSetupNodeIdBinaryMAC();
389
390                 case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
391                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_MSISDN_MIN,
392                                 PUD_NODEIDTYPE_MSISDN_MAX, PUD_NODEIDTYPE_MSISDN_BYTES);
393
394                 case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
395                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_TETRA_MIN,
396                                 PUD_NODEIDTYPE_TETRA_MAX, PUD_NODEIDTYPE_TETRA_BYTES);
397
398                 case PUD_NODEIDTYPE_DNS: /* DNS name */
399                         return intSetupNodeIdBinaryString();
400
401                 case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
402                 case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
403                         return intSetupNodeIdBinaryIp();
404
405                 case PUD_NODEIDTYPE_MMSI: /* an AIS MMSI number */
406                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_MMSI_MIN,
407                                 PUD_NODEIDTYPE_MMSI_MAX, PUD_NODEIDTYPE_MMSI_BYTES);
408
409                 case PUD_NODEIDTYPE_URN: /* a URN number */
410                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_URN_MIN,
411                                 PUD_NODEIDTYPE_URN_MAX, PUD_NODEIDTYPE_URN_BYTES);
412
413                 case PUD_NODEIDTYPE_MIP: /* a MIP OID number */
414                         return intSetupNodeIdBinaryDoubleLongLong(
415                             &nodeIdBinary.buffer.mip[0],
416                             PUD_NODEIDTYPE_MIP_CHARS1,
417                             PUD_NODEIDTYPE_MIP_MIN1, PUD_NODEIDTYPE_MIP_MAX1,
418                             PUD_NODEIDTYPE_MIP_BYTES1,
419                             PUD_NODEIDTYPE_MIP_MIN2, PUD_NODEIDTYPE_MIP_MAX2,
420                             PUD_NODEIDTYPE_MIP_BYTES - PUD_NODEIDTYPE_MIP_BYTES1,
421                             10);
422
423                 case PUD_NODEIDTYPE_192:
424                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_192_MIN,
425                                 PUD_NODEIDTYPE_192_MAX, PUD_NODEIDTYPE_192_BYTES);
426
427                 case PUD_NODEIDTYPE_193:
428                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_193_MIN,
429                                 PUD_NODEIDTYPE_193_MAX, PUD_NODEIDTYPE_193_BYTES);
430
431                 case PUD_NODEIDTYPE_194:
432                         return intSetupNodeIdBinaryLongLong(PUD_NODEIDTYPE_194_MIN,
433                                 PUD_NODEIDTYPE_194_MAX, PUD_NODEIDTYPE_194_BYTES);
434
435                 default:
436                   pudError(false, "nodeId type %u is not supported", nodeIdTypeNumber);
437                   return false;
438         }
439
440         return false;
441 }
442
443 /*
444  * rxNonOlsrIf
445  */
446
447 /** The maximum number of RX non-OLSR interfaces */
448 #define PUD_RX_NON_OLSR_IF_MAX 32
449
450 /** Array with RX non-OLSR interface names */
451 static unsigned char rxNonOlsrInterfaceNames[PUD_RX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
452
453 /** The number of RX non-OLSR interface names in the array */
454 static unsigned int rxNonOlsrInterfaceCount = 0;
455
456 /**
457  Determine whether a give interface name is configured as a receive non-OLSR
458  interface.
459
460  @param ifName
461  The interface name to check
462
463  @return
464  - true when the given interface name is configured as a receive non-OLSR
465  interface
466  - false otherwise
467  */
468 bool isRxNonOlsrInterface(const char *ifName) {
469         unsigned int i;
470
471         assert (ifName != NULL);
472
473         for (i = 0; i < rxNonOlsrInterfaceCount; i++) {
474                 if (strncmp((char *) &rxNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ
475                                 + 1) == 0) {
476                         return true;
477                 }
478         }
479
480         return false;
481 }
482
483 int addRxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
484                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
485         size_t valueLength;
486
487         if (rxNonOlsrInterfaceCount >= PUD_RX_NON_OLSR_IF_MAX) {
488                 pudError(false, "Can't configure more than %u receive interfaces",
489                                 PUD_RX_NON_OLSR_IF_MAX);
490                 return true;
491         }
492
493         assert (value != NULL);
494
495         valueLength = strlen(value);
496         if (valueLength > IFNAMSIZ) {
497                 pudError(false, "Value of parameter %s (%s) is too long,"
498                         " maximum length is %u, current length is %lu",
499                                 PUD_RX_NON_OLSR_IF_NAME, value, IFNAMSIZ, (long unsigned int)valueLength);
500                 return true;
501         }
502
503         if (!isRxNonOlsrInterface(value)) {
504                 strcpy((char *) &rxNonOlsrInterfaceNames[rxNonOlsrInterfaceCount][0],
505                                 value);
506                 rxNonOlsrInterfaceCount++;
507         }
508
509         return false;
510 }
511
512 /**
513  * @return the number of configured non-olsr receive interfaces
514  */
515 unsigned int getRxNonOlsrInterfaceCount(void) {
516         return rxNonOlsrInterfaceCount;
517 }
518
519 /**
520  * @param idx the index of the configured non-olsr receive interface
521  * @return the index-th interface name
522  */
523 unsigned char * getRxNonOlsrInterfaceName(unsigned int idx) {
524         return &rxNonOlsrInterfaceNames[idx][0];
525 }
526
527 /*
528  * rxAllowedSourceIpAddress
529  */
530
531 /** The maximum number of RX allowed source IP addresses */
532 #define PUD_RX_ALLOWED_SOURCE_IP_MAX 32
533
534 /** Array with RX allowed source IP addresses */
535 static union olsr_sockaddr rxAllowedSourceIpAddresses[PUD_RX_ALLOWED_SOURCE_IP_MAX];
536
537 /** The number of RX allowed source IP addresses in the array */
538 static unsigned int rxAllowedSourceIpAddressesCount = 0;
539
540 /**
541  Determine whether a give IP address is configured as an allowed source IP
542  address.
543
544  @param sender
545  The IP address to check
546
547  @return
548  - true when the given IP address is configured as an allowed source IP
549  address
550  - false otherwise
551  */
552 bool isRxAllowedSourceIpAddress(union olsr_sockaddr * sender) {
553         unsigned int i;
554
555         if (rxAllowedSourceIpAddressesCount == 0) {
556                 return true;
557         }
558
559         if (sender == NULL) {
560                 return false;
561         }
562
563         for (i = 0; i < rxAllowedSourceIpAddressesCount; i++) {
564                 if (sender->in.sa_family != rxAllowedSourceIpAddresses[i].in.sa_family) {
565                         continue;
566                 }
567
568                 if (sender->in.sa_family == AF_INET) {
569                         if (memcmp(&rxAllowedSourceIpAddresses[i].in4.sin_addr, &sender->in4.sin_addr, sizeof(struct in_addr))
570                                         == 0) {
571                                 return true;
572                         }
573                 } else {
574                         if (memcmp(&rxAllowedSourceIpAddresses[i].in6.sin6_addr, &sender->in6.sin6_addr, sizeof(struct in6_addr))
575                                         == 0) {
576                                 return true;
577                         }
578                 }
579         }
580
581         return false;
582 }
583
584 int addRxAllowedSourceIpAddress(const char *value, void *data __attribute__ ((unused)),
585                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
586         static const char * valueName = PUD_RX_ALLOWED_SOURCE_IP_NAME;
587         union olsr_sockaddr addr;
588         bool addrSet = false;
589
590         if (rxAllowedSourceIpAddressesCount >= PUD_RX_ALLOWED_SOURCE_IP_MAX) {
591                 pudError(false, "Can't configure more than %u allowed source IP"
592                         " addresses", PUD_RX_ALLOWED_SOURCE_IP_MAX);
593                 return true;
594         }
595
596         if (!readIPAddress(valueName, value, 0, &addr, &addrSet)) {
597                 return true;
598         }
599
600         if (!isRxAllowedSourceIpAddress(&addr)) {
601                 rxAllowedSourceIpAddresses[rxAllowedSourceIpAddressesCount] = addr;
602                 rxAllowedSourceIpAddressesCount++;
603         }
604
605         return false;
606 }
607
608 /*
609  * rxMcAddr + rxMcPort
610  */
611
612 /** The rx multicast address */
613 static union olsr_sockaddr rxMcAddr;
614
615 /** True when the rx multicast address is set */
616 static bool rxMcAddrSet = false;
617
618 /**
619  @return
620  The receive multicast address (in network byte order). Sets both the address
621  and the port to their default values when the address was not yet set.
622  */
623 union olsr_sockaddr * getRxMcAddr(void) {
624         if (!rxMcAddrSet) {
625                 setRxMcAddr((olsr_cnf->ip_version == AF_INET) ? PUD_RX_MC_ADDR_4_DEFAULT : PUD_RX_MC_ADDR_6_DEFAULT,
626                                 NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
627         }
628         return &rxMcAddr;
629 }
630
631 int setRxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
632         static const char * valueName = PUD_RX_MC_ADDR_NAME;
633
634         if (!readIPAddress(valueName, value, PUD_RX_MC_PORT_DEFAULT, &rxMcAddr, &rxMcAddrSet)) {
635                         return true;
636         }
637
638         if (!isMulticast(&rxMcAddr)) {
639                 pudError(false, "Value of parameter %s (%s) is not a multicast address",
640                                 valueName, value);
641                 return true;
642         }
643
644         return false;
645 }
646
647 /**
648  @return
649  The receive multicast port (in network byte order)
650  */
651 unsigned short getRxMcPort(void) {
652         return getOlsrSockaddrPort(getRxMcAddr(), PUD_RX_MC_PORT_DEFAULT);
653 }
654
655 int setRxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
656         static const char * valueName = PUD_RX_MC_PORT_NAME;
657         unsigned short rxMcPortNew;
658
659         if (!readUS(valueName, value, &rxMcPortNew)) {
660                 return true;
661         }
662
663         if (rxMcPortNew < 1) {
664                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, rxMcPortNew);
665                 return true;
666         }
667
668         setOlsrSockaddrPort(getRxMcAddr(), htons((in_port_t) rxMcPortNew));
669
670         return false;
671 }
672
673 /*
674  * positionFile
675  */
676
677 /** The positionFile buffer */
678 static char positionFile[PATH_MAX + 1];
679
680 /** True when the positionFile is set */
681 static bool positionFileSet = false;
682
683 /**
684  @return
685  The positionFile (NULL when not set)
686  */
687 char * getPositionFile(void) {
688         if (!positionFileSet) {
689                 return NULL;
690         }
691
692         return &positionFile[0];
693 }
694
695 int setPositionFile(const char *value, void *data __attribute__ ((unused)),
696                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
697         size_t valueLength;
698
699         assert(value != NULL);
700
701         valueLength = strlen(value);
702         if (valueLength > PATH_MAX) {
703                 pudError(false, "Value of parameter %s is too long, maximum length is"
704                                 " %u, current length is %lu", PUD_POSFILE_NAME, PATH_MAX, (unsigned long) valueLength);
705                 return true;
706         }
707
708         strcpy((char *) &positionFile[0], value);
709         positionFileSet = true;
710
711         return false;
712 }
713
714 /*
715  * positionFilePeriod
716  */
717
718 /** The positionFilePeriod value (milliseconds) */
719 unsigned long long positionFilePeriod = PUD_POSFILEPERIOD_DEFAULT;
720
721 /**
722  @return
723  The positionFilePeriod (in milliseconds)
724  */
725 unsigned long long getPositionFilePeriod(void) {
726         return positionFilePeriod;
727 }
728
729 /**
730  Set the positionFilePeriod
731
732  @param value
733  The positionFilePeriod (a number in string representation)
734  @param data
735  Unused
736  @param addon
737  Unused
738
739  @return
740  - true when an error is detected
741  - false otherwise
742  */
743 int setPositionFilePeriod(const char *value, void *data __attribute__ ((unused)),
744                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
745         static const char * valueName = PUD_POSFILEPERIOD_NAME;
746         unsigned long long positionFilePeriodNew;
747
748         assert(value != NULL);
749
750         if (!readULL(valueName, value, &positionFilePeriodNew, 10)) {
751                 return true;
752         }
753
754         if ((positionFilePeriodNew != 0)
755                         && ((positionFilePeriodNew < PUD_POSFILEPERIOD_MIN) || (positionFilePeriodNew > PUD_POSFILEPERIOD_MAX))) {
756                 pudError(false, "Configured %s (%llu) is outside of"
757                                 " valid range %llu-%llu", valueName, positionFilePeriodNew, PUD_POSFILEPERIOD_MIN, PUD_POSFILEPERIOD_MAX);
758                 return true;
759         }
760
761         positionFilePeriod = positionFilePeriodNew;
762
763         return false;
764 }
765
766 /*
767  * txNonOlsrIf
768  */
769
770 /** The maximum number of tx non-olsr interfaces */
771 #define PUD_TX_NON_OLSR_IF_MAX 32
772
773 /** Array with tx non-olsr interface names */
774 static unsigned char txNonOlsrInterfaceNames[PUD_TX_NON_OLSR_IF_MAX][IFNAMSIZ + 1];
775
776 /** The number of tx interface names in the array */
777 static unsigned int txNonOlsrInterfaceCount = 0;
778
779 /**
780  Determine whether a give interface name is configured as a transmit non-OLSR
781  interface.
782
783  @param ifName
784  The interface to check
785
786  @return
787  - true when the given interface name is configured as a transmit non-OLSR
788  interface
789  - false otherwise
790  */
791 bool isTxNonOlsrInterface(const char *ifName) {
792         unsigned int i;
793
794         assert (ifName != NULL);
795
796         for (i = 0; i < txNonOlsrInterfaceCount; i++) {
797                 if (strncmp((char *) &txNonOlsrInterfaceNames[i][0], ifName, IFNAMSIZ + 1) == 0) {
798                         return true;
799                 }
800         }
801
802         return false;
803 }
804
805 int addTxNonOlsrInterface(const char *value, void *data __attribute__ ((unused)),
806                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
807         size_t valueLength;
808
809         assert (value != NULL);
810
811         if (txNonOlsrInterfaceCount >= PUD_TX_NON_OLSR_IF_MAX) {
812                 pudError(false, "Can not configure more than %u transmit interfaces", PUD_TX_NON_OLSR_IF_MAX);
813                 return true;
814         }
815
816         valueLength = strlen(value);
817         if (valueLength > IFNAMSIZ) {
818                 pudError(false, "Value of parameter %s (%s) is too long, maximum length is %u, current length is %lu",
819                                 PUD_TX_NON_OLSR_IF_NAME, value, IFNAMSIZ, (long unsigned int)valueLength);
820                 return true;
821         }
822
823         if (!isTxNonOlsrInterface(value)) {
824                 strcpy((char *) &txNonOlsrInterfaceNames[txNonOlsrInterfaceCount][0], value);
825                 txNonOlsrInterfaceCount++;
826         }
827
828         return false;
829 }
830
831 /**
832  * @return the number of configured non-olsr transmit interfaces
833  */
834 unsigned int getTxNonOlsrInterfaceCount(void) {
835         return txNonOlsrInterfaceCount;
836 }
837
838 /**
839  * @param idx the index of the configured non-olsr transmit interface
840  * @return the index-th interface name
841  */
842 unsigned char * getTxNonOlsrInterfaceName(unsigned int idx) {
843         return &txNonOlsrInterfaceNames[idx][0];
844 }
845
846 /*
847  * txMcAddr + txMcPort
848  */
849
850 /** The tx multicast address */
851 static union olsr_sockaddr txMcAddr;
852
853 /** True when the tx multicast address is set */
854 static bool txMcAddrSet = false;
855
856 /**
857  @return
858  The transmit multicast address (in network byte order). Sets both the address
859  and the port to their default values when the address was not yet set.
860  */
861 union olsr_sockaddr * getTxMcAddr(void) {
862         if (!txMcAddrSet) {
863                 setTxMcAddr((olsr_cnf->ip_version == AF_INET) ? PUD_TX_MC_ADDR_4_DEFAULT : PUD_TX_MC_ADDR_6_DEFAULT,
864                                 NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
865         }
866         return &txMcAddr;
867 }
868
869 int setTxMcAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
870         static const char * valueName = PUD_TX_MC_ADDR_NAME;
871
872         if (!readIPAddress(valueName, value, PUD_TX_MC_PORT_DEFAULT, &txMcAddr, &txMcAddrSet)) {
873                         return true;
874         }
875
876         if (!isMulticast(&txMcAddr)) {
877                 pudError(false, "Value of parameter %s (%s) is not a multicast address",
878                                 valueName, value);
879                 return true;
880         }
881
882         return false;
883 }
884
885 /**
886  @return
887  The transmit multicast port (in network byte order)
888  */
889 unsigned short getTxMcPort(void) {
890         return getOlsrSockaddrPort(getTxMcAddr(), PUD_TX_MC_PORT_DEFAULT);
891 }
892
893 int setTxMcPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
894         static const char * valueName = PUD_TX_MC_PORT_NAME;
895         unsigned short txMcPortNew;
896
897         if (!readUS(valueName, value, &txMcPortNew)) {
898                 return true;
899         }
900
901         if (txMcPortNew < 1) {
902                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, txMcPortNew);
903                 return true;
904         }
905
906         setOlsrSockaddrPort(getTxMcAddr(), htons((in_port_t) txMcPortNew));
907
908         return false;
909 }
910
911 /*
912  * txTtl
913  */
914
915 /** The tx TTL */
916 static unsigned char txTtl = PUD_TX_TTL_DEFAULT;
917
918 /**
919  @return
920  The transmit multicast IP packet time-to-live
921  */
922 unsigned char getTxTtl(void) {
923         return txTtl;
924 }
925
926 int setTxTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
927         static const char * valueName = PUD_TX_TTL_NAME;
928
929         if (!readUC(valueName, value, &txTtl)) {
930                 return true;
931         }
932
933         if ((txTtl < 1) /* || (txTtl > MAX_TTL) */) {
934                 pudError(false, "Value of parameter %s (%u) is outside of"
935                         " valid range 1-%u", valueName, txTtl, MAX_TTL);
936                 return true;
937         }
938
939         return false;
940 }
941
942 /*
943  * txNmeaMessagePrefix
944  */
945
946 /** The exact length of the tx NMEA message prefix */
947 #define PUD_TXNMEAMESSAGEPREFIXLENGTH 4
948
949 /** The tx NMEA message prefix buffer */
950 static unsigned char txNmeaMessagePrefix[PUD_TXNMEAMESSAGEPREFIXLENGTH + 1];
951
952 /** True when the tx NMEA message prefix is set */
953 static bool txNmeaMessagePrefixSet = false;
954
955 /**
956  @return
957  The transmit multicast NMEA message prefix
958  */
959 unsigned char * getTxNmeaMessagePrefix(void) {
960         if (!txNmeaMessagePrefixSet) {
961                 setTxNmeaMessagePrefix(PUD_TX_NMEAMESSAGEPREFIX_DEFAULT, NULL,
962                                 (set_plugin_parameter_addon) {.pc = NULL});
963         }
964         return &txNmeaMessagePrefix[0];
965 }
966
967 int setTxNmeaMessagePrefix(const char *value, void *data __attribute__ ((unused)),
968                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
969         static const char * valueName = PUD_TX_NMEAMESSAGEPREFIX_NAME;
970         size_t valueLength;
971         char report[256];
972
973         assert (value != NULL);
974
975         valueLength = strlen(value);
976         if (valueLength != PUD_TXNMEAMESSAGEPREFIXLENGTH) {
977                 pudError(false, "Length of parameter %s (%s) must be exactly %u characters",
978                                 valueName, value, PUD_TXNMEAMESSAGEPREFIXLENGTH);
979                 return true;
980         }
981
982         if (nmea_parse_sentence_has_invalid_chars(value, valueLength, valueName, &report[0], sizeof(report))) {
983                 pudError(false, "%s", &report[0]);
984                 return true;
985         }
986
987         if ((strchr(value, ' ') != NULL) || (strchr(value, '\t') != NULL)) {
988                 pudError(false, "Value of parameter %s (%s) can not contain whitespace",
989                                 valueName, value);
990                 return true;
991         }
992
993         strcpy((char *) &txNmeaMessagePrefix[0], value);
994         txNmeaMessagePrefixSet = true;
995         return false;
996 }
997
998 /*
999  * uplinkAddr + uplinkPort
1000  */
1001
1002 /** The uplink address */
1003 static union olsr_sockaddr uplinkAddr;
1004
1005 /** True when the uplink address is set */
1006 static bool uplinkAddrSet = false;
1007
1008 /**
1009  @return
1010  - true when the uplink address is set
1011  - false otherwise
1012  */
1013 bool isUplinkAddrSet(void) {
1014         return uplinkAddrSet;
1015 }
1016
1017 /**
1018  @return
1019  The uplink address (in network byte order). Sets both the address
1020  and the port to their default values when the address was not yet set.
1021  */
1022 union olsr_sockaddr * getUplinkAddr(void) {
1023         if (!uplinkAddrSet) {
1024                 setUplinkAddr((olsr_cnf->ip_version == AF_INET) ? PUD_UPLINK_ADDR_4_DEFAULT : PUD_UPLINK_ADDR_6_DEFAULT,
1025                                 NULL, ((set_plugin_parameter_addon) {.pc = NULL}));
1026         }
1027         return &uplinkAddr;
1028 }
1029
1030 int setUplinkAddr(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1031         return !readIPAddress(PUD_UPLINK_ADDR_NAME, value, PUD_UPLINK_PORT_DEFAULT, &uplinkAddr, &uplinkAddrSet);
1032 }
1033
1034 /**
1035  @return
1036  The uplink port (in network byte order)
1037  */
1038 unsigned short getUplinkPort(void) {
1039         return getOlsrSockaddrPort(getUplinkAddr(), PUD_UPLINK_PORT_DEFAULT);
1040 }
1041
1042 int setUplinkPort(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1043         static const char * valueName = PUD_UPLINK_PORT_NAME;
1044         unsigned short uplinkPortNew;
1045
1046         if (!readUS(valueName, value, &uplinkPortNew)) {
1047                 return true;
1048         }
1049
1050         if (uplinkPortNew < 1) {
1051                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, uplinkPortNew);
1052                 return true;
1053         }
1054
1055         setOlsrSockaddrPort(getUplinkAddr(), htons((in_port_t) uplinkPortNew));
1056
1057         return false;
1058 }
1059
1060 /*
1061  * downlinkPort
1062  */
1063
1064 /** the downlink port */
1065 unsigned short downlinkPort = 0;
1066
1067 /** true when the downlinkPort is set */
1068 bool downlinkPortSet = false;
1069
1070 /**
1071  @return
1072  The downlink port (in network byte order)
1073  */
1074 unsigned short getDownlinkPort(void) {
1075         if (!downlinkPortSet) {
1076                 downlinkPort = htons(PUD_DOWNLINK_PORT_DEFAULT);
1077                 downlinkPortSet = true;
1078         }
1079
1080         return downlinkPort;
1081 }
1082
1083 int setDownlinkPort(const char *value, void *data __attribute__ ((unused)),
1084                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1085         static const char * valueName = PUD_DOWNLINK_PORT_NAME;
1086         unsigned short downlinkPortNew;
1087
1088         if (!readUS(valueName, value, &downlinkPortNew)) {
1089                 return true;
1090         }
1091
1092         if (downlinkPortNew < 1) {
1093                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-65535", valueName, downlinkPortNew);
1094                 return true;
1095         }
1096
1097         downlinkPort = htons(downlinkPortNew);
1098         downlinkPortSet = true;
1099
1100         return false;
1101 }
1102
1103 /*
1104  * olsrTtl
1105  */
1106
1107 /** The OLSR TTL */
1108 static unsigned char olsrTtl = PUD_OLSR_TTL_DEFAULT;
1109
1110 /**
1111  @return
1112  The OLSR multicast IP packet time-to-live
1113  */
1114 unsigned char getOlsrTtl(void) {
1115         return olsrTtl;
1116 }
1117
1118 int setOlsrTtl(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) {
1119         static const char * valueName = PUD_OLSR_TTL_NAME;
1120
1121         if (!readUC(valueName, value, &olsrTtl)) {
1122                 return true;
1123         }
1124
1125         if ((olsrTtl < 1) /* || (olsrTtl > MAX_TTL) */) {
1126                 pudError(false, "Value of parameter %s (%u) is outside of valid range 1-%u",
1127                                 valueName, olsrTtl, MAX_TTL);
1128                 return true;
1129         }
1130
1131         return false;
1132 }
1133
1134 /*
1135  * updateIntervalStationary
1136  */
1137
1138 /** The stationary interval update plugin parameter (in seconds) */
1139 static unsigned long long updateIntervalStationary = PUD_UPDATE_INTERVAL_STATIONARY_DEFAULT;
1140
1141 /**
1142  @return
1143  The stationary interval update plugin parameter (in seconds)
1144  */
1145 unsigned long long getUpdateIntervalStationary(void) {
1146         return updateIntervalStationary;
1147 }
1148
1149 int setUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
1150                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1151         static const char * valueName = PUD_UPDATE_INTERVAL_STATIONARY_NAME;
1152
1153         if (!readULL(valueName, value, &updateIntervalStationary, 10)) {
1154                 return true;
1155         }
1156
1157         if (updateIntervalStationary < 1) {
1158                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1159                 return true;
1160         }
1161
1162         return false;
1163 }
1164
1165 /*
1166  * updateIntervalMoving
1167  */
1168
1169 /** The moving interval update plugin parameter (in seconds) */
1170 static unsigned long long updateIntervalMoving = PUD_UPDATE_INTERVAL_MOVING_DEFAULT;
1171
1172 /**
1173  @return
1174  The moving interval update plugin parameter (in seconds)
1175  */
1176 unsigned long long getUpdateIntervalMoving(void) {
1177         return updateIntervalMoving;
1178 }
1179
1180 int setUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1181                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1182         static const char * valueName = PUD_UPDATE_INTERVAL_MOVING_NAME;
1183
1184         if (!readULL(valueName, value, &updateIntervalMoving, 10)) {
1185                 return true;
1186         }
1187
1188         if (updateIntervalMoving < 1) {
1189                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1190                 return true;
1191         }
1192
1193         return false;
1194 }
1195
1196 /*
1197  * uplinkUpdateIntervalStationary
1198  */
1199
1200 /** The uplink stationary interval update plugin parameter (in seconds) */
1201 static unsigned long long uplinkUpdateIntervalStationary = PUD_UPLINK_UPDATE_INTERVAL_STATIONARY_DEFAULT;
1202
1203 /**
1204  @return
1205  The uplink stationary interval update plugin parameter (in seconds)
1206  */
1207 unsigned long long getUplinkUpdateIntervalStationary(void) {
1208         return uplinkUpdateIntervalStationary;
1209 }
1210
1211 int setUplinkUpdateIntervalStationary(const char *value, void *data __attribute__ ((unused)),
1212                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1213         static const char * valueName = PUD_UPLINK_UPDATE_INTERVAL_STATIONARY_NAME;
1214
1215         if (!readULL(valueName, value, &uplinkUpdateIntervalStationary, 10)) {
1216                 return true;
1217         }
1218
1219         if (uplinkUpdateIntervalStationary < 1) {
1220                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1221                 return true;
1222         }
1223
1224         return false;
1225 }
1226
1227 /*
1228  * uplinkUpdateIntervalMoving
1229  */
1230
1231 /** The uplink moving interval update plugin parameter (in seconds) */
1232 static unsigned long long uplinkUpdateIntervalMoving = PUD_UPLINK_UPDATE_INTERVAL_MOVING_DEFAULT;
1233
1234 /**
1235  @return
1236  The uplink moving interval update plugin parameter (in seconds)
1237  */
1238 unsigned long long getUplinkUpdateIntervalMoving(void) {
1239         return uplinkUpdateIntervalMoving;
1240 }
1241
1242 int setUplinkUpdateIntervalMoving(const char *value, void *data __attribute__ ((unused)),
1243                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1244         static const char * valueName = PUD_UPLINK_UPDATE_INTERVAL_MOVING_NAME;
1245
1246         if (!readULL(valueName, value, &uplinkUpdateIntervalMoving, 10)) {
1247                 return true;
1248         }
1249
1250         if (uplinkUpdateIntervalMoving < 1) {
1251                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1252                 return true;
1253         }
1254
1255         return false;
1256 }
1257
1258 /*
1259  * gatewayDeterminationInterval
1260  */
1261
1262 /** The gateway determination interval plugin parameter (in seconds) */
1263 static unsigned long long gatewayDeterminationInterval = PUD_GATEWAY_DETERMINATION_INTERVAL_DEFAULT;
1264
1265 /**
1266  @return
1267  The gateway determination interval plugin parameter (in seconds)
1268  */
1269 unsigned long long getGatewayDeterminationInterval(void) {
1270         return gatewayDeterminationInterval;
1271 }
1272
1273 int setGatewayDeterminationInterval(const char *value, void *data __attribute__ ((unused)),
1274                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1275         static const char * valueName = PUD_GATEWAY_DETERMINATION_INTERVAL_NAME;
1276
1277         if (!readULL(valueName, value, &gatewayDeterminationInterval, 10)) {
1278                 return true;
1279         }
1280
1281         if (gatewayDeterminationInterval < 1) {
1282                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1283                 return true;
1284         }
1285
1286         return false;
1287 }
1288
1289 /*
1290  * movingSpeedThreshold
1291  */
1292
1293 /** The moving speed threshold plugin parameter (in kph) */
1294 static unsigned long long movingSpeedThreshold = PUD_MOVING_SPEED_THRESHOLD_DEFAULT;
1295
1296 /**
1297  @return
1298  The moving speed threshold plugin parameter (in kph)
1299  */
1300 unsigned long long getMovingSpeedThreshold(void) {
1301         return movingSpeedThreshold;
1302 }
1303
1304 int setMovingSpeedThreshold(const char *value, void *data __attribute__ ((unused)),
1305                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1306         return !readULL(PUD_MOVING_SPEED_THRESHOLD_NAME, value, &movingSpeedThreshold, 10);
1307 }
1308
1309 /*
1310  * movingDistanceThreshold
1311  */
1312
1313 /** The moving distance threshold plugin parameter (in meters) */
1314 static unsigned long long movingDistanceThreshold = PUD_MOVING_DISTANCE_THRESHOLD_DEFAULT;
1315
1316 /**
1317  @return
1318  The moving distance threshold plugin parameter (in meters)
1319  */
1320 unsigned long long getMovingDistanceThreshold(void) {
1321         return movingDistanceThreshold;
1322 }
1323
1324 int setMovingDistanceThreshold(const char *value, void *data __attribute__ ((unused)),
1325                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1326         return !readULL(PUD_MOVING_DISTANCE_THRESHOLD_NAME, value, &movingDistanceThreshold, 10);
1327 }
1328
1329 /*
1330  * dopMultiplier
1331  */
1332
1333 /** The DOP multiplier plugin parameter */
1334 static double dopMultiplier = PUD_DOP_MULTIPLIER_DEFAULT;
1335
1336 /**
1337  @return
1338  The DOP multiplier plugin parameter
1339  */
1340 double getDopMultiplier(void) {
1341         return dopMultiplier;
1342 }
1343
1344 int setDopMultiplier(const char *value, void *data __attribute__ ((unused)),
1345                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1346         return !readDouble(PUD_DOP_MULTIPLIER_NAME, value, &dopMultiplier);
1347 }
1348
1349 /*
1350  * defaultHdop
1351  */
1352
1353 /** The default HDOP plugin parameter (in meters) */
1354 static unsigned long long defaultHdop = PUD_DEFAULT_HDOP_DEFAULT;
1355
1356 /**
1357  @return
1358  The default HDOP plugin parameter (in meters)
1359  */
1360 unsigned long long getDefaultHdop(void) {
1361         return defaultHdop;
1362 }
1363
1364 int setDefaultHdop(const char *value, void *data __attribute__ ((unused)),
1365                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1366         return !readULL(PUD_DEFAULT_HDOP_NAME, value, &defaultHdop, 10);
1367 }
1368
1369 /*
1370  * defaultVdop
1371  */
1372
1373 /** The default VDOP plugin parameter (in meters) */
1374 static unsigned long long defaultVdop = PUD_DEFAULT_VDOP_DEFAULT;
1375
1376 /**
1377  @return
1378  The default VDOP plugin parameter (in meters)
1379  */
1380 unsigned long long getDefaultVdop(void) {
1381         return defaultVdop;
1382 }
1383
1384 int setDefaultVdop(const char *value, void *data __attribute__ ((unused)),
1385                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1386         return !readULL(PUD_DEFAULT_VDOP_NAME, value, &defaultVdop, 10);
1387 }
1388
1389 /*
1390  * averageDepth
1391  */
1392
1393 /** The depth of the average list */
1394 static unsigned long long averageDepth = PUD_AVERAGE_DEPTH_DEFAULT;
1395
1396 /**
1397  @return
1398  The depth of the average list
1399  */
1400 unsigned long long getAverageDepth(void) {
1401         return averageDepth;
1402 }
1403
1404 int setAverageDepth(const char *value, void *data __attribute__ ((unused)),
1405                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1406         static const char * valueName = PUD_AVERAGE_DEPTH_NAME;
1407
1408         if (!readULL(valueName, value, &averageDepth, 10)) {
1409                 return true;
1410         }
1411
1412         if (averageDepth < 1) {
1413                 pudError(false, "Value of parameter %s must be at least 1", valueName);
1414                 return true;
1415         }
1416
1417         return false;
1418 }
1419
1420 /*
1421  * hysteresisCountToStationary
1422  */
1423
1424 /** The hysteresis count for changing state from moving to stationary */
1425 static unsigned long long hysteresisCountToStationary = PUD_HYSTERESIS_COUNT_2STAT_DEFAULT;
1426
1427 /**
1428  @return
1429  The hysteresis count for changing state from moving to stationary
1430  */
1431 unsigned long long getHysteresisCountToStationary(void) {
1432         return hysteresisCountToStationary;
1433 }
1434
1435 int setHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1436                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1437         return !readULL(PUD_HYSTERESIS_COUNT_2STAT_NAME, value, &hysteresisCountToStationary, 10);
1438 }
1439
1440 /*
1441  * hysteresisCountToMoving
1442  */
1443
1444 /** The hysteresis count for changing state from stationary to moving */
1445 static unsigned long long hysteresisCountToMoving = PUD_HYSTERESIS_COUNT_2MOV_DEFAULT;
1446
1447 /**
1448  @return
1449  The hysteresis count for changing state from stationary to moving
1450  */
1451 unsigned long long getHysteresisCountToMoving(void) {
1452         return hysteresisCountToMoving;
1453 }
1454
1455 int setHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1456                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1457         return !readULL(PUD_HYSTERESIS_COUNT_2MOV_NAME, value, &hysteresisCountToMoving, 10);
1458 }
1459
1460 /*
1461  * gatewayHysteresisCountToStationary
1462  */
1463
1464 /** The hysteresis count for changing state from moving to stationary */
1465 static unsigned long long gatewayHysteresisCountToStationary = PUD_GAT_HYSTERESIS_COUNT_2STAT_DEFAULT;
1466
1467 /**
1468  @return
1469  The hysteresis count for changing state from moving to stationary
1470  */
1471 unsigned long long getGatewayHysteresisCountToStationary(void) {
1472         return gatewayHysteresisCountToStationary;
1473 }
1474
1475 int setGatewayHysteresisCountToStationary(const char *value, void *data __attribute__ ((unused)),
1476                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1477         return !readULL(PUD_GAT_HYSTERESIS_COUNT_2STAT_NAME, value, &gatewayHysteresisCountToStationary, 10);
1478 }
1479
1480 /*
1481  * gatewayHysteresisCountToMoving
1482  */
1483
1484 /** The hysteresis count for changing state from stationary to moving */
1485 static unsigned long long gatewayHysteresisCountToMoving = PUD_GAT_HYSTERESIS_COUNT_2MOV_DEFAULT;
1486
1487 /**
1488  @return
1489  The hysteresis count for changing state from stationary to moving
1490  */
1491 unsigned long long getGatewayHysteresisCountToMoving(void) {
1492         return gatewayHysteresisCountToMoving;
1493 }
1494
1495 int setGatewayHysteresisCountToMoving(const char *value, void *data __attribute__ ((unused)),
1496                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1497         return !readULL(PUD_GAT_HYSTERESIS_COUNT_2MOV_NAME, value, &gatewayHysteresisCountToMoving, 10);
1498 }
1499
1500 /*
1501  * useDeDup
1502  */
1503
1504 /** when true then duplicate message detection is performed */
1505 static bool useDeDup = PUD_USE_DEDUP_DEFAULT;
1506
1507 /**
1508  @return
1509  The duplicate message detection setting
1510  */
1511 bool getUseDeDup(void) {
1512         return useDeDup;
1513 }
1514
1515 int setUseDeDup(const char *value, void *data __attribute__ ((unused)),
1516                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1517         return !readBool(PUD_USE_DEDUP_NAME, value, &useDeDup);
1518 }
1519
1520 /*
1521  * deDupDepth
1522  */
1523
1524 /** The deduplication depth */
1525 static unsigned long long deDupDepth = PUD_DEDUP_DEPTH_DEFAULT;
1526
1527 /**
1528  @return
1529  The deduplication depth
1530  */
1531 unsigned long long getDeDupDepth(void) {
1532         return deDupDepth;
1533 }
1534
1535 int setDeDupDepth(const char *value, void *data __attribute__ ((unused)),
1536                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1537         return !readULL(PUD_DEDUP_DEPTH_NAME, value, &deDupDepth, 10);
1538 }
1539
1540 /*
1541  * useLoopback
1542  */
1543
1544 /** when true then loopback is performed */
1545 static bool useLoopback = PUD_USE_LOOPBACK_DEFAULT;
1546
1547 /**
1548  @return
1549  The loopback usage setting
1550  */
1551 bool getUseLoopback(void) {
1552         return useLoopback;
1553 }
1554
1555 int setUseLoopback(const char *value, void *data __attribute__ ((unused)),
1556                 set_plugin_parameter_addon addon __attribute__ ((unused))) {
1557         return !readBool(PUD_USE_LOOPBACK_NAME, value, &useLoopback);
1558 }
1559
1560 /*
1561  * Check Functions
1562  */
1563
1564 /**
1565  Check the configuration for consistency and validity.
1566
1567  @return
1568  - true when the configuration is consistent and valid
1569  - false otherwise
1570  */
1571 unsigned int checkConfig(void) {
1572         int retval = true;
1573
1574         if (rxNonOlsrInterfaceCount == 0) {
1575                 pudError(false, "No receive non-OLSR interfaces configured");
1576                 retval = false;
1577         }
1578
1579         if (txNonOlsrInterfaceCount == 0) {
1580                 pudError(false, "No transmit non-OLSR interfaces configured");
1581                 retval = false;
1582         }
1583
1584         if (updateIntervalMoving > updateIntervalStationary) {
1585                 pudError(false,"The update interval for moving situations must not be"
1586                 " larger than that for stationary situations");
1587                 retval = false;
1588         }
1589
1590         if (uplinkUpdateIntervalMoving > uplinkUpdateIntervalStationary) {
1591                 pudError(false,"The uplink update interval for moving situations must not be"
1592                 " larger than that for stationary situations");
1593                 retval = false;
1594         }
1595
1596         if (isUplinkAddrSet() && (getUplinkPort() == getDownlinkPort())) {
1597                 pudError(false, "The uplink port and the downlink port must not be the same");
1598                 retval = false;
1599         }
1600
1601         return retval;
1602 }
1603
1604 /**
1605  Check the configuration for consistency and validity after everything has been
1606  setup.
1607
1608  @return
1609  - true when the configuration is consistent and valid
1610  - false otherwise
1611  */
1612 unsigned int checkRunSetup(void) {
1613         return true;
1614 }