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