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