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