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