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