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