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