PUD: add wireformat libraries
[olsrd.git] / lib / pud / wireformat / include / OlsrdPudWireFormat / wireFormat.h
1 #ifndef _PUD_WIREFORMAT_H_
2 #define _PUD_WIREFORMAT_H_
3
4 #include "olsr_protocol.h"
5
6 #include <OlsrdPudWireFormat/compiler.h>
7 #include <stdint.h>
8 #include <stdbool.h>
9 #include <time.h>
10 #include <math.h>
11 #include <sys/socket.h>
12 #include <assert.h>
13
14 /*
15  * Version
16  */
17
18 /** The version of the wire format */
19 #define PUD_WIRE_FORMAT_VERSION         0
20
21 /*
22  * Flags
23  * We use the smask of nmeaINFO and the flags below on top of that
24  */
25
26 /** Flags that the GPS information contains the nodeId */
27 #define PUD_FLAGS_ID                            0x80
28
29 /*
30  * Time
31  */
32
33 /** The number of bits for the time field */
34 #define PUD_TIME_BITS                           17
35
36 /*
37  * Latitude
38  */
39
40 /** The number of bits for the latitude field */
41 #define PUD_LATITUDE_BITS                       28
42
43 /** The maximum size of the string representation of the latitude
44  * sign [0,90] [0,59] dot [0,59] [0,999] */
45 #define PUD_TX_LATITUDE_DIGITS          (1 + 2 + 2 + 1 + 2 + 3)
46
47 /** The number of decimals of the latitude in the transmit sentence */
48 #define PUD_TX_LATITUDE_DECIMALS        "5"
49
50 /*
51  * Longitude
52  */
53
54 /** The number of bits for the longitude field */
55 #define PUD_LONGITUDE_BITS                      27
56
57 /** The maximum size of the string representation of the longitude
58  * sign [0,180] [0,59] dot [0,59] [0,999] */
59 #define PUD_TX_LONGITUDE_DIGITS         (1 + 3 + 2 + 1 + 2 + 3)
60
61 /** The number of decimals of the longitude in the transmit sentence */
62 #define PUD_TX_LONGITUDE_DECIMALS       "5"
63
64 /*
65  * Altitude
66  */
67
68 /** The number of bits for the altitude field */
69 #define PUD_ALTITUDE_BITS                       16
70
71 /** The minimum altitude */
72 #define PUD_ALTITUDE_MIN                        (-400)
73
74 /** The maximum altitude */
75 #define PUD_ALTITUDE_MAX        (((1 << PUD_ALTITUDE_BITS) - 1) + PUD_ALTITUDE_MIN)
76
77 /** The maximum size of the string representation of the altitude */
78 #define PUD_TX_ALTITUDE_DIGITS          6
79
80 /*
81  * Speed
82  */
83
84 /** The number of bits for the speed field */
85 #define PUD_SPEED_BITS                          12
86
87 /** The maximum speed value */
88 #define PUD_SPEED_MAX                           ((1 << PUD_SPEED_BITS) - 1)
89
90 /** The maximum size of the string representation of the speed */
91 #define PUD_TX_SPEED_DIGITS                     4
92
93 /*
94  * Track
95  */
96
97 /** The number of bits for the track angle field */
98 #define PUD_TRACK_BITS                          9
99
100 /** The maximum size of the string representation of the track angle */
101 #define PUD_TX_TRACK_DIGITS                     3
102
103 /*
104  * HDOP
105  */
106
107 /** The number of bits for the HDOP field */
108 #define PUD_HDOP_BITS                           11
109
110 /** The HDOP resolution (in m) */
111 #define PUD_HDOP_RESOLUTION                     (0.1)
112
113 /** The maximum HDOP value (in m) */
114 #define PUD_HDOP_MAX            (((1 << PUD_HDOP_BITS) - 1) * PUD_HDOP_RESOLUTION)
115
116 /** The maximum size of the string representation of the HDOP */
117 #define PUD_TX_HDOP_DIGITS                      5
118
119 /** The number of decimals of the HDOP in the transmit sentence */
120 #define PUD_TX_HDOP_DECIMALS            "3"
121
122 /*
123  * Node ID Type
124  */
125
126 /** nodeIdType legal values */
127 typedef enum _NodeIdType {
128         /** MAC address, 48 bits, 6 bytes */
129         PUD_NODEIDTYPE_MAC = 0,
130
131         /** MSISDN number, 15 digits, 50 bits, 7 bytes */
132         PUD_NODEIDTYPE_MSISDN = 1,
133
134         /** TETRA number, 17 digits, 57 bits, 8 bytes */
135         PUD_NODEIDTYPE_TETRA = 2,
136
137         /** DNS name, variable length */
138         PUD_NODEIDTYPE_DNS = 3,
139
140         /** IPv4 address, 32 bits, 4 bytes */
141         PUD_NODEIDTYPE_IPV4 = 4,
142
143         /** IPv6 address, 128 bits, 16 bytes */
144         PUD_NODEIDTYPE_IPV6 = 6,
145
146         /** Brandweer number, 7 digits, 24 bits, 3 bytes */
147         PUD_NODEIDTYPE_192 = 192,
148
149         /** Ambulance number, 6 digits, 20 bits, 3 bytes */
150         PUD_NODEIDTYPE_193 = 193,
151
152         /** Number in the range [1, 8191], 4 digits, 13 bits, 2 bytes */
153         PUD_NODEIDTYPE_194 = 194
154 } NodeIdType;
155
156 /** the number of nodeId bytes for PUD_NODEIDTYPE_MAC (IFHWADDRLEN) */
157 #define PUD_NODEIDTYPE_MAC_BYTES                6
158
159 /** the number of nodeId bytes for PUD_NODEIDTYPE_MSISDN */
160 #define PUD_NODEIDTYPE_MSISDN_BYTES             7
161
162 /** the number of nodeId bytes for PUD_NODEIDTYPE_TETRA */
163 #define PUD_NODEIDTYPE_TETRA_BYTES              8
164
165 /** the number of nodeId bytes for PUD_NODEIDTYPE_192 */
166 #define PUD_NODEIDTYPE_192_BYTES                3
167
168 /** the number of nodeId bytes for PUD_NODEIDTYPE_193 */
169 #define PUD_NODEIDTYPE_193_BYTES                3
170
171 /** the number of nodeId bytes for PUD_NODEIDTYPE_194 */
172 #define PUD_NODEIDTYPE_194_BYTES                2
173
174 /** the number of nodeId bytes for PUD_NODEIDTYPE_IPV4 (sizeof(struct in_addr)) */
175 #define PUD_NODEIDTYPE_IPV4_BYTES               4
176
177 /** the number of nodeId bytes for PUD_NODEIDTYPE_IPV6 (sizeof(struct in6_addr)) */
178 #define PUD_NODEIDTYPE_IPV6_BYTES               16
179
180 /** The maximum size of the string representation of the nodeIdType */
181 #define PUD_TX_NODEIDTYPE_DIGITS                3
182
183 /*
184  * Node ID
185  */
186
187 /** The maximum size of the string representation of the nodeId */
188 #define PUD_TX_NODEID_BUFFERSIZE                1023
189
190 /*
191  * Wire Format Structures
192  */
193
194 /** Sub-format GPS information, 120 bits = 15 bytes */
195 typedef struct _GpsInfo {
196         uint32_t time :PUD_TIME_BITS; /**< the number of seconds since midnight, ALWAYS present */
197         uint32_t lat :PUD_LATITUDE_BITS; /**< latitude */
198         uint32_t lon :PUD_LONGITUDE_BITS; /**< longitude */
199         uint32_t alt :PUD_ALTITUDE_BITS; /**< altitude */
200         uint32_t speed :PUD_SPEED_BITS; /**< speed */
201         uint32_t track :PUD_TRACK_BITS; /**< track angle */
202         uint32_t hdop :PUD_HDOP_BITS; /**< HDOP */
203 }__attribute__((__packed__)) GpsInfo;
204
205 /** Sub-format Node information, 8 + variable bits = 1 + variable bytes */
206 typedef struct _NodeInfo {
207         uint8_t nodeIdType; /**< the nodeIdType */
208         unsigned char nodeId; /**< placeholder for variable length nodeId string */
209 }__attribute__((__packed__)) NodeInfo;
210
211 /** Complete format, 8+8+8+120+(8+variable) bits =  18+(1+variable) bytes*/
212 typedef struct _PudOlsrPositionUpdate {
213         uint8_t version; /**< the version of the sentence */
214         uint8_t validityTime; /**< the validity time of the sentence */
215         uint8_t smask; /**< mask signaling the contents of the sentence */
216         GpsInfo gpsInfo; /**< the GPS information (MANDATORY) */
217         NodeInfo nodeInfo; /**< placeholder for node information (OPTIONAL) */
218 }__attribute__((__packed__)) PudOlsrPositionUpdate;
219
220 /** The size of the wire format, minus the size of the node information */
221 #define PUD_OLSRWIREFORMATSIZE (sizeof(PudOlsrPositionUpdate) - sizeof(NodeInfo))
222
223 /*
224  * Uplink
225  */
226
227 /** the types of the uplink messages */
228 typedef enum _UplinkMessageType {
229         POSITION = 0,
230         CLUSTERLEADER = 1
231 } UplinkMessageType;
232
233 /** cluster leader message, 10 bytes (IPv4), 34 bytes (IPv6) */
234 typedef struct _UplinkClusterLeader {
235         uint8_t version; /**< the version of the message */
236         uint8_t validityTime; /**< the validity time of the sentence */
237         union _leader {
238                 struct _v4 {
239                         struct in_addr originator;
240                         struct in_addr clusterLeader;
241                 } v4;
242                 struct _v6 {
243                         struct in6_addr originator;
244                         struct in6_addr clusterLeader;
245                 } v6;
246         } leader;
247 }__attribute__((__packed__)) UplinkClusterLeader;
248
249 /** TLV header for uplink messages, 4 bytes */
250 typedef struct _UplinkHeader {
251         uint8_t type; /**< stores a UplinkMessageType */
252         uint16_t length; /**< the length of the payload in txBuffer */
253         uint8_t ipv6 :1; /**< clear when IPv4, set when IPv6 */
254         uint8_t pad :7; /**< padding to align to 4 bytes */
255 }__attribute__((__packed__)) UplinkHeader;
256
257 /** uplink message */
258 typedef struct _UplinkMessage {
259         UplinkHeader header; /**< the uplink TLV header */
260         union _msg {
261                 /** an olsr message (position update) */
262                 union olsr_message olsrMessage;
263
264                 /** a cluster leader message */
265                 UplinkClusterLeader clusterLeader;
266         } msg;
267 }__attribute__((__packed__)) UplinkMessage;
268
269 /* ************************************************************************
270  * FUNCTIONS
271  * ************************************************************************ */
272
273 /*
274  * Validity Time
275  */
276
277 /** Determine the validity time in seconds from the OLSR wire format value */
278 #define PUD_VALIDITY_TIME_FROM_OLSR(msn, lsn) ((((lsn) + 16) * (1 << (msn))) - 16)
279
280 /**
281  Get the validity time from a message
282
283  @param validityTimeField
284  A pointer to the validity time field
285
286  @return
287  The validity time in seconds
288  */
289 static inline unsigned long getValidityTime(uint8_t * validityTimeField) {
290         return PUD_VALIDITY_TIME_FROM_OLSR(*validityTimeField >> 4, *validityTimeField % 16);
291 }
292
293 void setValidityTime(uint8_t * validityTimeField,
294                 unsigned long long validityTime);
295
296 /*
297  * UplinkHeader
298  */
299
300 /**
301  Get the type of the uplink message
302
303  @param uplinkHeader
304  A pointer to the uplink message
305  @return
306  The type of the uplink message
307  */
308 static inline uint8_t getUplinkMessageType(UplinkHeader * uplinkHeader) {
309         return uplinkHeader->type;
310 }
311
312 /**
313  Set the type of the uplink message
314
315  @param uplinkHeader
316  A pointer to the uplink message
317  @param type
318  The type of the uplink message
319  */
320 static inline void setUplinkMessageType(UplinkHeader * uplinkHeader,
321                 uint8_t type) {
322         uplinkHeader->type = type;
323 }
324
325 /**
326  Get the length of the uplink message
327
328  @param uplinkHeader
329  A pointer to the uplink message
330  @return
331  The length of the uplink message
332  */
333 static inline uint16_t getUplinkMessageLength(UplinkHeader * uplinkHeader) {
334         return ntohs(uplinkHeader->length);
335 }
336
337 /**
338  Set the length of the uplink message
339
340  @param uplinkHeader
341  A pointer to the uplink message
342  @param length
343  The length of the uplink message
344  */
345 static inline void setUplinkMessageLength(UplinkHeader * uplinkHeader,
346                 uint16_t length) {
347         uplinkHeader->length = ntohs(length);
348 }
349
350 /**
351  Get the IPv6 status of the uplink message
352
353  @param uplinkHeader
354  A pointer to the uplink message
355  @return
356  true when the uplink message is sent from an olsrd stack in IPv6 mode, false
357  otherwise
358  */
359 static inline bool getUplinkMessageIPv6(UplinkHeader * uplinkHeader) {
360         return (uplinkHeader->ipv6 == 1);
361 }
362
363 /**
364  Set the IPv6 status of the uplink message
365
366  @param uplinkHeader
367  A pointer to the uplink message
368  @param ipv6
369  The IPv6 status of the uplink message (true when the uplink message is sent
370  from olsrd stack in IPv6 mode, false otherwise)
371  */
372 static inline void setUplinkMessageIPv6(UplinkHeader * uplinkHeader,
373                 bool ipv6) {
374         uplinkHeader->ipv6 = ipv6 ? 1 : 0;
375 }
376
377 /**
378  Set the padding of the uplink message header
379
380  @param uplinkHeader
381  A pointer to the uplink message
382  @param pad
383  The padding of the uplink message header
384  */
385 static inline void setUplinkMessagePadding(UplinkHeader * uplinkHeader,
386                 uint8_t pad) {
387         uplinkHeader->pad = pad;
388 }
389
390 /*
391  * OLSR header
392  */
393
394 /**
395  Get the originator of an OLSR message
396
397  @param ipVersion
398  The IP version (AF_INET or AF_INET6)
399  @param olsrMessage
400  A pointer to the OLSR message
401  @return
402  A pointer to the originator address
403  */
404 static inline union olsr_ip_addr * getOlsrMessageOriginator(int ipVersion,
405                 union olsr_message * olsrMessage) {
406         if (ipVersion == AF_INET) {
407                 return (union olsr_ip_addr *) &olsrMessage->v4.originator;
408         }
409
410         return (union olsr_ip_addr *) &olsrMessage->v6.originator;
411 }
412
413 /**
414  Get the position update message in an OLSR message
415
416  @param ipVersion
417  The IP version (AF_INET or AF_INET6)
418  @param olsrMessage
419  A pointer to the OLSR message
420  @return
421  A pointer to the position update message
422  */
423 static inline PudOlsrPositionUpdate * getOlsrMessagePayload(int ipVersion,
424                 union olsr_message * olsrMessage) {
425         if (ipVersion == AF_INET) {
426                 return (PudOlsrPositionUpdate *) &olsrMessage->v4.message;
427         }
428
429         return (PudOlsrPositionUpdate *) &olsrMessage->v6.message;
430 }
431
432 /*
433  * PudOlsrPositionUpdate
434  */
435
436 /**
437  Get the version of the position update message
438
439  @param olsrGpsMessage
440  A pointer to the position update message
441  @return
442  The version of the position update message
443  */
444 static inline uint8_t getPositionUpdateVersion(
445                 PudOlsrPositionUpdate * olsrGpsMessage) {
446         return olsrGpsMessage->version;
447 }
448
449 /**
450  Set the version of the position update message
451
452  @param olsrGpsMessage
453  A pointer to the position update message
454  @param version
455  The version of the position update message
456  */
457 static inline void setPositionUpdateVersion(
458                 PudOlsrPositionUpdate * olsrGpsMessage, uint8_t version) {
459         olsrGpsMessage->version = version;
460 }
461
462 /**
463  Get the smask of the position update message
464
465  @param olsrGpsMessage
466  A pointer to the position update message
467  @return
468  The smask of the position update message
469  */
470 static inline uint8_t getPositionUpdateSmask(
471                 PudOlsrPositionUpdate * olsrGpsMessage) {
472         return olsrGpsMessage->smask;
473 }
474
475 /**
476  Set the smask of the position update message
477
478  @param olsrGpsMessage
479  A pointer to the position update message
480  @param smask
481  The smask of the position update message
482  */
483 static inline void setPositionUpdateSmask(
484                 PudOlsrPositionUpdate * olsrGpsMessage, uint8_t smask) {
485         olsrGpsMessage->smask = smask;
486 }
487
488 /*
489  * GpsInfo
490  */
491
492 void getPositionUpdateTime(PudOlsrPositionUpdate * olsrGpsMessage,
493                 time_t baseDate, struct tm *nowStruct);
494
495 /**
496  Set the time of the position update message (the number of seconds after
497  midnight)
498
499  @param olsrGpsMessage
500  A pointer to the position update message
501  @param hour
502  The hours
503  @param min
504  The minutes
505  @param sec
506  The seconds
507  */
508 static inline void setPositionUpdateTime(PudOlsrPositionUpdate * olsrGpsMessage,
509                 int hour, int min, int sec) {
510         olsrGpsMessage->gpsInfo.time = ((hour * 60 * 60) + (min * 60) + sec);
511 }
512
513 /**
514  Get the latitude of the position update message
515
516  @param olsrGpsMessage
517  A pointer to the position update message
518
519  @return
520  The latitude converted to degrees: [-90, 90>
521  */
522 static inline double getPositionUpdateLatitude(
523                 PudOlsrPositionUpdate * olsrGpsMessage) {
524         uint32_t olsrLat = olsrGpsMessage->gpsInfo.lat;
525         double lat = (double) olsrLat;
526
527         /* lat is in [0, 2^LATITUDE_BITS> */
528
529         /* take half of the rounding error */
530         lat += 0.5;
531
532         lat /= (double) (1 << PUD_LATITUDE_BITS);
533         /* lat is now in [0, 1> */
534
535         lat -= 0.5;
536         /* lat is now in [-0.5, 0.5> */
537
538         lat *= 180.0;
539         /* lat is now in [-90, 90> */
540
541         return lat;
542 }
543
544 /**
545  Set the latitude of the position update message
546
547  @param olsrGpsMessage
548  A pointer to the position update message
549  @param latitude
550  The latitude in degrees: [-90, 90]
551  */
552 static inline void setPositionUpdateLatitude(
553                 PudOlsrPositionUpdate * olsrGpsMessage, double latitude) {
554         double lat = latitude;
555
556         /* lat is in [-90, 90] */
557         assert(lat >= -90.0);
558         assert(lat <= 90.0);
559
560         lat /= 180.0;
561         /* lat is now in [-0.5, 0.5] */
562
563         lat += 0.5;
564         /* lat is now in [0, 1] */
565
566         lat *= (double) (1 << PUD_LATITUDE_BITS);
567         /* lat is now in [0, LATITUDE_BITS] */
568
569         /* clip max */
570         if (unlikely(lat > (double)((1 << PUD_LATITUDE_BITS) - 1))) {
571                 lat = (double) ((1 << PUD_LATITUDE_BITS) - 1);
572         }
573         /* lat is now in [0, 2^LATITUDE_BITS> */
574
575         olsrGpsMessage->gpsInfo.lat = lrint(lat);
576 }
577
578 /**
579  Get the longitude of the position update message
580
581  @param olsrGpsMessage
582  A pointer to the position update message
583
584  @return
585  The longitude converted to degrees: [-180, 180>
586  */
587 static inline double getPositionUpdateLongitude(
588                 PudOlsrPositionUpdate * olsrGpsMessage) {
589         uint32_t olsrLon = olsrGpsMessage->gpsInfo.lon;
590         double lon = (double) olsrLon;
591
592         /* lon is in [0, 2^LONGITUDE_BITS> */
593
594         /* take half of the rounding error */
595         lon += 0.5;
596
597         lon /= (1 << PUD_LONGITUDE_BITS);
598         /* lon is now in [0, 1> */
599
600         lon -= 0.5;
601         /* lon is now in [-0.5, 0.5> */
602
603         lon *= 360.0;
604         /* lon is now in [-180, 180> */
605
606         return lon;
607 }
608
609 /**
610  Set the longitude of the position update message
611
612  @param olsrGpsMessage
613  A pointer to the position update message
614  @param longitude
615  The longitude in degrees: [-90, 90]
616  */
617 static inline void setPositionUpdateLongitude(
618                 PudOlsrPositionUpdate * olsrGpsMessage, double longitude) {
619         double lon = longitude;
620
621         /* lon is in [-180, 180] */
622         assert(lon >= -180.0);
623         assert(lon <= 180.0);
624
625         lon /= 360.0;
626         /* lon is now in [-0.5, 0.5] */
627
628         lon += 0.5;
629         /* lon is now in [0, 1] */
630
631         lon *= (double) (1 << PUD_LONGITUDE_BITS);
632         /* lon is now in [0, LONGITUDE_BITS] */
633
634         /* clip max */
635         if (unlikely(lon > (double)((1 << PUD_LATITUDE_BITS) - 1))) {
636                 lon = (double) ((1 << PUD_LATITUDE_BITS) - 1);
637         }
638
639         /* lon is now in [0, 2^LONGITUDE_BITS> */
640
641         olsrGpsMessage->gpsInfo.lon = lrint(lon);
642 }
643
644 /**
645  Get the altitude of the position update message
646
647  @param olsrGpsMessage
648  A pointer to the position update message
649
650  @return
651  The altitude in meters
652  */
653 static inline long getPositionUpdateAltitude(
654                 PudOlsrPositionUpdate * olsrGpsMessage) {
655         return ((long) olsrGpsMessage->gpsInfo.alt + PUD_ALTITUDE_MIN);
656 }
657
658 /**
659  Set the altitude of the position update message
660
661  @param olsrGpsMessage
662  A pointer to the position update message
663  @param altitude
664  The altitude in meters
665  */
666 static inline void setPositionUpdateAltitude(
667                 PudOlsrPositionUpdate * olsrGpsMessage, double altitude) {
668         double alt = altitude;
669
670         if (unlikely(alt > PUD_ALTITUDE_MAX)) {
671                 alt = PUD_ALTITUDE_MAX;
672         } else if (unlikely(alt < PUD_ALTITUDE_MIN)) {
673                 alt = PUD_ALTITUDE_MIN;
674         }
675
676         alt -= PUD_ALTITUDE_MIN;
677
678         olsrGpsMessage->gpsInfo.alt = lrint(alt);
679 }
680
681 /**
682  Get the speed of the position update message
683
684  @param olsrGpsMessage
685  A pointer to the position update message
686
687  @return
688  The speed in kph
689  */
690 static inline unsigned long getPositionUpdateSpeed(
691                 PudOlsrPositionUpdate * olsrGpsMessage) {
692         return olsrGpsMessage->gpsInfo.speed;
693 }
694
695 /**
696  Set the speed of the position update message
697
698  @param olsrGpsMessage
699  A pointer to the position update message
700  @param speed
701  The speed in kph
702  */
703 static inline void setPositionUpdateSpeed(
704                 PudOlsrPositionUpdate * olsrGpsMessage, double speed) {
705         double spd = speed;
706
707         if (unlikely(speed < 0)) {
708                 spd = 0;
709         } else if (unlikely(speed > PUD_SPEED_MAX)) {
710                 spd = PUD_SPEED_MAX;
711         }
712
713         olsrGpsMessage->gpsInfo.speed = lrint(spd);
714 }
715
716 /**
717  Get the track angle of the position update message
718
719  @param olsrGpsMessage
720  A pointer to the position update message
721
722  @return
723  The track angle in degrees
724  */
725 static inline unsigned long getPositionUpdateTrack(
726                 PudOlsrPositionUpdate * olsrGpsMessage) {
727         return olsrGpsMessage->gpsInfo.track;
728 }
729
730 /**
731  Set the track angle of the position update message
732
733  @param olsrGpsMessage
734  A pointer to the position update message
735  @param track
736  The track angle in degrees
737  */
738 static inline void setPositionUpdateTrack(
739                 PudOlsrPositionUpdate * olsrGpsMessage, double track) {
740         olsrGpsMessage->gpsInfo.track = lrint(track);
741 }
742
743 /**
744  Get the HDOP of the position update message
745
746  @param olsrGpsMessage
747  A pointer to the position update message
748
749  @return
750  The HDOP
751  */
752 static inline double getPositionUpdateHdop(
753                 PudOlsrPositionUpdate * olsrGpsMessage) {
754         return (olsrGpsMessage->gpsInfo.hdop * PUD_HDOP_RESOLUTION);
755 }
756
757 /**
758  Set the HDOP of the position update message
759
760  @param olsrGpsMessage
761  A pointer to the position update message
762  @param hdop
763  The HDOP
764  */
765 static inline void setPositionUpdateHdop(PudOlsrPositionUpdate * olsrGpsMessage,
766                 double hdop) {
767         double hdopInternal = hdop;
768
769         if (unlikely(hdopInternal > PUD_HDOP_MAX)) {
770                 hdopInternal = PUD_HDOP_MAX;
771         }
772
773         olsrGpsMessage->gpsInfo.hdop = lrint(hdopInternal / PUD_HDOP_RESOLUTION);
774 }
775
776 /*
777  * NodeInfo
778  */
779
780 bool setupNodeIdNumberForOlsrCache(/*const char * nodeIdParameterName,*/
781 unsigned long long val, unsigned long long min, unsigned long long max,
782                 unsigned int bytes);
783
784 /**
785  Get the nodeIdType of the position update message
786
787  @param ipVersion
788  The IP version (AF_INET or AF_INET6)
789  @param olsrGpsMessage
790  A pointer to the position update message
791
792  @return
793  The nodeIdType
794  */
795 static inline NodeIdType getPositionUpdateNodeIdType(int ipVersion,
796                 PudOlsrPositionUpdate * olsrGpsMessage) {
797         if (getPositionUpdateSmask(olsrGpsMessage) & PUD_FLAGS_ID) {
798                 return olsrGpsMessage->nodeInfo.nodeIdType;
799         }
800
801         return ((ipVersion == AF_INET) ? PUD_NODEIDTYPE_IPV4 : PUD_NODEIDTYPE_IPV6);
802 }
803
804 /**
805  Set the nodeIdType of the position update message
806
807  @param olsrGpsMessage
808  A pointer to the position update message
809  @param nodeIdType
810  The nodeIdType
811  */
812 static inline void setPositionUpdateNodeIdType(
813                 PudOlsrPositionUpdate * olsrGpsMessage, NodeIdType nodeIdType) {
814         olsrGpsMessage->nodeInfo.nodeIdType = nodeIdType;
815 }
816
817 void getPositionUpdateNodeId(int ipVersion, union olsr_message * olsrMessage,
818                 unsigned char ** nodeId, unsigned int * nodeIdSize);
819
820 /**
821  Set the nodeId of the position update message
822
823  @param olsrGpsMessage
824  A pointer to the position update message
825  @param nodeId
826  The nodeId
827  @param nodeIdSize
828  The number of bytes in nodeId
829  @param padWithNullByte
830  When true then an extra '\0' byte will be added at the end
831  */
832 static inline void setPositionUpdateNodeId(
833                 PudOlsrPositionUpdate * olsrGpsMessage, unsigned char * nodeId,
834                 unsigned int nodeIdSize, bool padWithNullByte) {
835         memcpy(&olsrGpsMessage->nodeInfo.nodeId, nodeId, nodeIdSize);
836         if (unlikely(padWithNullByte)) {
837                 (&olsrGpsMessage->nodeInfo.nodeId)[nodeIdSize] = '\0';
838         }
839 }
840
841 size_t setPositionUpdateNodeInfo(int ipVersion,
842                 PudOlsrPositionUpdate * olsrGpsMessage, unsigned int olsrMessageSize,
843                 NodeIdType nodeIdType, unsigned char * nodeId, size_t nodeIdLength);
844
845 /*
846  * UplinkClusterLeader
847  */
848
849 /**
850  Get the version of the cluster leader message
851
852  @param clusterLeaderMessage
853  A pointer to the cluster leader message
854  @return
855  The version of the cluster leader message
856  */
857 static inline uint8_t getClusterLeaderVersion(
858                 UplinkClusterLeader * clusterLeaderMessage) {
859         return clusterLeaderMessage->version;
860 }
861
862 /**
863  Set the version of the cluster leader message
864
865  @param clusterLeaderMessage
866  A pointer to the cluster leader message
867  @param version
868  The version of the cluster leader message
869  */
870 static inline void setClusterLeaderVersion(
871                 UplinkClusterLeader * clusterLeaderMessage, uint8_t version) {
872         clusterLeaderMessage->version = version;
873 }
874
875 /**
876  Get the originator of a cluster leader message
877
878  @param ipVersion
879  The IP version (AF_INET or AF_INET6)
880  @param clusterLeaderMessage
881  A pointer to the cluster leader message
882  @return
883  A pointer to the originator address
884  */
885 static inline union olsr_ip_addr * getClusterLeaderOriginator(int ipVersion,
886                 UplinkClusterLeader * clusterLeaderMessage) {
887         if (ipVersion == AF_INET) {
888                 return (union olsr_ip_addr *) &clusterLeaderMessage->leader.v4.originator;
889         }
890
891         return (union olsr_ip_addr *) &clusterLeaderMessage->leader.v6.originator;
892 }
893
894 /**
895  Get the cluster leader of a cluster leader message
896
897  @param ipVersion
898  The IP version (AF_INET or AF_INET6)
899  @param clusterLeaderMessage
900  A pointer to the cluster leader message
901  @return
902  A pointer to the clust leader address
903  */
904 static inline union olsr_ip_addr * getClusterLeaderClusterLeader(int ipVersion,
905                 UplinkClusterLeader * clusterLeaderMessage) {
906         if (ipVersion == AF_INET) {
907                 return (union olsr_ip_addr *) &clusterLeaderMessage->leader.v4.clusterLeader;
908         }
909
910         return (union olsr_ip_addr *) &clusterLeaderMessage->leader.v6.clusterLeader;
911 }
912
913 #endif /* _PUD_WIREFORMAT_H_ */