PUD: compile fixes for debug defines
[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 /**
409  Determine the size of an OLSR message
410
411  @param ipVersion
412  The IP version
413  @param olsrMessage
414  A pointer to the OLSR message
415  @return
416  The size of the OLSR message
417  */
418 static inline unsigned short getOlsrMessageSize(int ipVersion,
419                 union olsr_message * olsrMessage) {
420         if (ipVersion == AF_INET) {
421                 return ntohs(olsrMessage->v4.olsr_msgsize);
422         }
423
424         return ntohs(olsrMessage->v6.olsr_msgsize);
425 }
426
427 /**
428  Get the originator of an OLSR message
429
430  @param ipVersion
431  The IP version (AF_INET or AF_INET6)
432  @param olsrMessage
433  A pointer to the OLSR message
434  @return
435  A pointer to the originator address
436  */
437 static inline union olsr_ip_addr * getOlsrMessageOriginator(int ipVersion,
438                 union olsr_message * olsrMessage) {
439         if (ipVersion == AF_INET) {
440                 return (union olsr_ip_addr *) &olsrMessage->v4.originator;
441         }
442
443         return (union olsr_ip_addr *) &olsrMessage->v6.originator;
444 }
445
446 /**
447  Get the position update message in an OLSR message
448
449  @param ipVersion
450  The IP version (AF_INET or AF_INET6)
451  @param olsrMessage
452  A pointer to the OLSR message
453  @return
454  A pointer to the position update message
455  */
456 static inline PudOlsrPositionUpdate * getOlsrMessagePayload(int ipVersion,
457                 union olsr_message * olsrMessage) {
458         if (ipVersion == AF_INET) {
459                 return (PudOlsrPositionUpdate *) &olsrMessage->v4.message;
460         }
461
462         return (PudOlsrPositionUpdate *) &olsrMessage->v6.message;
463 }
464
465 /*
466  * PudOlsrPositionUpdate
467  */
468
469 /**
470  Get the version of the position update message
471
472  @param olsrGpsMessage
473  A pointer to the position update message
474  @return
475  The version of the position update message
476  */
477 static inline uint8_t getPositionUpdateVersion(
478                 PudOlsrPositionUpdate * olsrGpsMessage) {
479         return olsrGpsMessage->version;
480 }
481
482 /**
483  Set the version of the position update message
484
485  @param olsrGpsMessage
486  A pointer to the position update message
487  @param version
488  The version of the position update message
489  */
490 static inline void setPositionUpdateVersion(
491                 PudOlsrPositionUpdate * olsrGpsMessage, uint8_t version) {
492         olsrGpsMessage->version = version;
493 }
494
495 /**
496  Get the smask of the position update message
497
498  @param olsrGpsMessage
499  A pointer to the position update message
500  @return
501  The smask of the position update message
502  */
503 static inline uint8_t getPositionUpdateSmask(
504                 PudOlsrPositionUpdate * olsrGpsMessage) {
505         return olsrGpsMessage->smask;
506 }
507
508 /**
509  Set the smask of the position update message
510
511  @param olsrGpsMessage
512  A pointer to the position update message
513  @param smask
514  The smask of the position update message
515  */
516 static inline void setPositionUpdateSmask(
517                 PudOlsrPositionUpdate * olsrGpsMessage, uint8_t smask) {
518         olsrGpsMessage->smask = smask;
519 }
520
521 /*
522  * GpsInfo
523  */
524
525 void getPositionUpdateTime(PudOlsrPositionUpdate * olsrGpsMessage,
526                 time_t baseDate, struct tm *nowStruct);
527
528 /**
529  Set the time of the position update message (the number of seconds after
530  midnight)
531
532  @param olsrGpsMessage
533  A pointer to the position update message
534  @param hour
535  The hours
536  @param min
537  The minutes
538  @param sec
539  The seconds
540  */
541 static inline void setPositionUpdateTime(PudOlsrPositionUpdate * olsrGpsMessage,
542                 int hour, int min, int sec) {
543         olsrGpsMessage->gpsInfo.time = ((hour * 60 * 60) + (min * 60) + sec);
544 }
545
546 /**
547  Get the latitude of the position update message
548
549  @param olsrGpsMessage
550  A pointer to the position update message
551
552  @return
553  The latitude converted to degrees: [-90, 90>
554  */
555 static inline double getPositionUpdateLatitude(
556                 PudOlsrPositionUpdate * olsrGpsMessage) {
557         uint32_t olsrLat = olsrGpsMessage->gpsInfo.lat;
558         double lat = (double) olsrLat;
559
560         /* lat is in [0, 2^LATITUDE_BITS> */
561
562         /* take half of the rounding error */
563         lat += 0.5;
564
565         lat /= (double) (1 << PUD_LATITUDE_BITS);
566         /* lat is now in [0, 1> */
567
568         lat -= 0.5;
569         /* lat is now in [-0.5, 0.5> */
570
571         lat *= 180.0;
572         /* lat is now in [-90, 90> */
573
574         return lat;
575 }
576
577 /**
578  Set the latitude of the position update message
579
580  @param olsrGpsMessage
581  A pointer to the position update message
582  @param latitude
583  The latitude in degrees: [-90, 90]
584  */
585 static inline void setPositionUpdateLatitude(
586                 PudOlsrPositionUpdate * olsrGpsMessage, double latitude) {
587         double lat = latitude;
588
589         /* lat is in [-90, 90] */
590         assert(lat >= -90.0);
591         assert(lat <= 90.0);
592
593         lat /= 180.0;
594         /* lat is now in [-0.5, 0.5] */
595
596         lat += 0.5;
597         /* lat is now in [0, 1] */
598
599         lat *= (double) (1 << PUD_LATITUDE_BITS);
600         /* lat is now in [0, LATITUDE_BITS] */
601
602         /* clip max */
603         if (unlikely(lat > (double)((1 << PUD_LATITUDE_BITS) - 1))) {
604                 lat = (double) ((1 << PUD_LATITUDE_BITS) - 1);
605         }
606         /* lat is now in [0, 2^LATITUDE_BITS> */
607
608         olsrGpsMessage->gpsInfo.lat = lrint(lat);
609 }
610
611 /**
612  Get the longitude of the position update message
613
614  @param olsrGpsMessage
615  A pointer to the position update message
616
617  @return
618  The longitude converted to degrees: [-180, 180>
619  */
620 static inline double getPositionUpdateLongitude(
621                 PudOlsrPositionUpdate * olsrGpsMessage) {
622         uint32_t olsrLon = olsrGpsMessage->gpsInfo.lon;
623         double lon = (double) olsrLon;
624
625         /* lon is in [0, 2^LONGITUDE_BITS> */
626
627         /* take half of the rounding error */
628         lon += 0.5;
629
630         lon /= (1 << PUD_LONGITUDE_BITS);
631         /* lon is now in [0, 1> */
632
633         lon -= 0.5;
634         /* lon is now in [-0.5, 0.5> */
635
636         lon *= 360.0;
637         /* lon is now in [-180, 180> */
638
639         return lon;
640 }
641
642 /**
643  Set the longitude of the position update message
644
645  @param olsrGpsMessage
646  A pointer to the position update message
647  @param longitude
648  The longitude in degrees: [-90, 90]
649  */
650 static inline void setPositionUpdateLongitude(
651                 PudOlsrPositionUpdate * olsrGpsMessage, double longitude) {
652         double lon = longitude;
653
654         /* lon is in [-180, 180] */
655         assert(lon >= -180.0);
656         assert(lon <= 180.0);
657
658         lon /= 360.0;
659         /* lon is now in [-0.5, 0.5] */
660
661         lon += 0.5;
662         /* lon is now in [0, 1] */
663
664         lon *= (double) (1 << PUD_LONGITUDE_BITS);
665         /* lon is now in [0, LONGITUDE_BITS] */
666
667         /* clip max */
668         if (unlikely(lon > (double)((1 << PUD_LATITUDE_BITS) - 1))) {
669                 lon = (double) ((1 << PUD_LATITUDE_BITS) - 1);
670         }
671
672         /* lon is now in [0, 2^LONGITUDE_BITS> */
673
674         olsrGpsMessage->gpsInfo.lon = lrint(lon);
675 }
676
677 /**
678  Get the altitude of the position update message
679
680  @param olsrGpsMessage
681  A pointer to the position update message
682
683  @return
684  The altitude in meters
685  */
686 static inline long getPositionUpdateAltitude(
687                 PudOlsrPositionUpdate * olsrGpsMessage) {
688         return ((long) olsrGpsMessage->gpsInfo.alt + PUD_ALTITUDE_MIN);
689 }
690
691 /**
692  Set the altitude of the position update message
693
694  @param olsrGpsMessage
695  A pointer to the position update message
696  @param altitude
697  The altitude in meters
698  */
699 static inline void setPositionUpdateAltitude(
700                 PudOlsrPositionUpdate * olsrGpsMessage, double altitude) {
701         double alt = altitude;
702
703         if (unlikely(alt > PUD_ALTITUDE_MAX)) {
704                 alt = PUD_ALTITUDE_MAX;
705         } else if (unlikely(alt < PUD_ALTITUDE_MIN)) {
706                 alt = PUD_ALTITUDE_MIN;
707         }
708
709         alt -= PUD_ALTITUDE_MIN;
710
711         olsrGpsMessage->gpsInfo.alt = lrint(alt);
712 }
713
714 /**
715  Get the speed of the position update message
716
717  @param olsrGpsMessage
718  A pointer to the position update message
719
720  @return
721  The speed in kph
722  */
723 static inline unsigned long getPositionUpdateSpeed(
724                 PudOlsrPositionUpdate * olsrGpsMessage) {
725         return olsrGpsMessage->gpsInfo.speed;
726 }
727
728 /**
729  Set the speed of the position update message
730
731  @param olsrGpsMessage
732  A pointer to the position update message
733  @param speed
734  The speed in kph
735  */
736 static inline void setPositionUpdateSpeed(
737                 PudOlsrPositionUpdate * olsrGpsMessage, double speed) {
738         double spd = speed;
739
740         if (unlikely(speed < 0)) {
741                 spd = 0;
742         } else if (unlikely(speed > PUD_SPEED_MAX)) {
743                 spd = PUD_SPEED_MAX;
744         }
745
746         olsrGpsMessage->gpsInfo.speed = lrint(spd);
747 }
748
749 /**
750  Get the track angle of the position update message
751
752  @param olsrGpsMessage
753  A pointer to the position update message
754
755  @return
756  The track angle in degrees
757  */
758 static inline unsigned long getPositionUpdateTrack(
759                 PudOlsrPositionUpdate * olsrGpsMessage) {
760         return olsrGpsMessage->gpsInfo.track;
761 }
762
763 /**
764  Set the track angle of the position update message
765
766  @param olsrGpsMessage
767  A pointer to the position update message
768  @param track
769  The track angle in degrees
770  */
771 static inline void setPositionUpdateTrack(
772                 PudOlsrPositionUpdate * olsrGpsMessage, double track) {
773         olsrGpsMessage->gpsInfo.track = lrint(track);
774 }
775
776 /**
777  Get the HDOP of the position update message
778
779  @param olsrGpsMessage
780  A pointer to the position update message
781
782  @return
783  The HDOP
784  */
785 static inline double getPositionUpdateHdop(
786                 PudOlsrPositionUpdate * olsrGpsMessage) {
787         return (olsrGpsMessage->gpsInfo.hdop * PUD_HDOP_RESOLUTION);
788 }
789
790 /**
791  Set the HDOP of the position update message
792
793  @param olsrGpsMessage
794  A pointer to the position update message
795  @param hdop
796  The HDOP
797  */
798 static inline void setPositionUpdateHdop(PudOlsrPositionUpdate * olsrGpsMessage,
799                 double hdop) {
800         double hdopInternal = hdop;
801
802         if (unlikely(hdopInternal > PUD_HDOP_MAX)) {
803                 hdopInternal = PUD_HDOP_MAX;
804         }
805
806         olsrGpsMessage->gpsInfo.hdop = lrint(hdopInternal / PUD_HDOP_RESOLUTION);
807 }
808
809 /*
810  * NodeInfo
811  */
812
813 bool setupNodeIdNumberForOlsrCache(/*const char * nodeIdParameterName,*/
814 unsigned long long val, unsigned long long min, unsigned long long max,
815                 unsigned int bytes);
816
817 /**
818  Get the nodeIdType of the position update message
819
820  @param ipVersion
821  The IP version (AF_INET or AF_INET6)
822  @param olsrGpsMessage
823  A pointer to the position update message
824
825  @return
826  The nodeIdType
827  */
828 static inline NodeIdType getPositionUpdateNodeIdType(int ipVersion,
829                 PudOlsrPositionUpdate * olsrGpsMessage) {
830         if (getPositionUpdateSmask(olsrGpsMessage) & PUD_FLAGS_ID) {
831                 return olsrGpsMessage->nodeInfo.nodeIdType;
832         }
833
834         return ((ipVersion == AF_INET) ? PUD_NODEIDTYPE_IPV4 : PUD_NODEIDTYPE_IPV6);
835 }
836
837 /**
838  Set the nodeIdType of the position update message
839
840  @param olsrGpsMessage
841  A pointer to the position update message
842  @param nodeIdType
843  The nodeIdType
844  */
845 static inline void setPositionUpdateNodeIdType(
846                 PudOlsrPositionUpdate * olsrGpsMessage, NodeIdType nodeIdType) {
847         olsrGpsMessage->nodeInfo.nodeIdType = nodeIdType;
848 }
849
850 void getPositionUpdateNodeId(int ipVersion, union olsr_message * olsrMessage,
851                 unsigned char ** nodeId, unsigned int * nodeIdSize);
852
853 /**
854  Set the nodeId of the position update message
855
856  @param olsrGpsMessage
857  A pointer to the position update message
858  @param nodeId
859  The nodeId
860  @param nodeIdSize
861  The number of bytes in nodeId
862  @param padWithNullByte
863  When true then an extra '\0' byte will be added at the end
864  */
865 static inline void setPositionUpdateNodeId(
866                 PudOlsrPositionUpdate * olsrGpsMessage, unsigned char * nodeId,
867                 unsigned int nodeIdSize, bool padWithNullByte) {
868         memcpy(&olsrGpsMessage->nodeInfo.nodeId, nodeId, nodeIdSize);
869         if (unlikely(padWithNullByte)) {
870                 (&olsrGpsMessage->nodeInfo.nodeId)[nodeIdSize] = '\0';
871         }
872 }
873
874 size_t setPositionUpdateNodeInfo(int ipVersion,
875                 PudOlsrPositionUpdate * olsrGpsMessage, unsigned int olsrMessageSize,
876                 NodeIdType nodeIdType, unsigned char * nodeId, size_t nodeIdLength);
877
878 /*
879  * UplinkClusterLeader
880  */
881
882 /**
883  Get the version of the cluster leader message
884
885  @param clusterLeaderMessage
886  A pointer to the cluster leader message
887  @return
888  The version of the cluster leader message
889  */
890 static inline uint8_t getClusterLeaderVersion(
891                 UplinkClusterLeader * clusterLeaderMessage) {
892         return clusterLeaderMessage->version;
893 }
894
895 /**
896  Set the version of the cluster leader message
897
898  @param clusterLeaderMessage
899  A pointer to the cluster leader message
900  @param version
901  The version of the cluster leader message
902  */
903 static inline void setClusterLeaderVersion(
904                 UplinkClusterLeader * clusterLeaderMessage, uint8_t version) {
905         clusterLeaderMessage->version = version;
906 }
907
908 /**
909  Get the downlink port of the cluster leader message
910
911  @param clusterLeaderMessage
912  A pointer to the cluster leader message
913  @return
914  The downlink port of the cluster leader message
915  */
916 static inline uint16_t getClusterLeaderDownlinkPort(
917                 UplinkClusterLeader * clusterLeaderMessage) {
918         return clusterLeaderMessage->downlinkPort;
919 }
920
921 /**
922  Set the downlink port of the cluster leader message
923
924  @param clusterLeaderMessage
925  A pointer to the cluster leader message
926  @param port
927  The downlink port of the cluster leader message
928  */
929 static inline void setClusterLeaderDownlinkPort(
930                 UplinkClusterLeader * clusterLeaderMessage, uint16_t port) {
931         clusterLeaderMessage->downlinkPort = port;
932 }
933
934 /**
935  Get the originator of a cluster leader message
936
937  @param ipVersion
938  The IP version (AF_INET or AF_INET6)
939  @param clusterLeaderMessage
940  A pointer to the cluster leader message
941  @return
942  A pointer to the originator address
943  */
944 static inline union olsr_ip_addr * getClusterLeaderOriginator(int ipVersion,
945                 UplinkClusterLeader * clusterLeaderMessage) {
946         if (ipVersion == AF_INET) {
947                 return (union olsr_ip_addr *) &clusterLeaderMessage->leader.v4.originator;
948         }
949
950         return (union olsr_ip_addr *) &clusterLeaderMessage->leader.v6.originator;
951 }
952
953 /**
954  Get the cluster leader of a cluster leader message
955
956  @param ipVersion
957  The IP version (AF_INET or AF_INET6)
958  @param clusterLeaderMessage
959  A pointer to the cluster leader message
960  @return
961  A pointer to the clust leader address
962  */
963 static inline union olsr_ip_addr * getClusterLeaderClusterLeader(int ipVersion,
964                 UplinkClusterLeader * clusterLeaderMessage) {
965         if (ipVersion == AF_INET) {
966                 return (union olsr_ip_addr *) &clusterLeaderMessage->leader.v4.clusterLeader;
967         }
968
969         return (union olsr_ip_addr *) &clusterLeaderMessage->leader.v6.clusterLeader;
970 }
971
972 #endif /* _PUD_WIREFORMAT_H_ */