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