PUD: move setupNodeInfoForOlsr into gpsConversion
[olsrd.git] / lib / pud / src / nodeIdConversion.c
1 #include "nodeIdConversion.h"
2
3 /* Plugin includes */
4 #include "compiler.h"
5
6 /* OLSR includes */
7
8 /* System includes */
9 #include <assert.h>
10 #include <arpa/inet.h>
11 #include <nmea/util.h>
12 #include <net/if.h>
13
14 /* ************************************************************************
15  * Node Information
16  * ************************************************************************ */
17
18 /**
19  Convert the nodeIdType of an OLSR message into a string.
20
21  @param ipVersion
22  The ip version, either AF_INET or AF_INET6
23  @param olsrMessage
24  A pointer to the OLSR message. Used to be able to retrieve the IP address of
25  the sender.
26  @param nodeIdTypeBuffer
27  A pointer to the buffer in which the nodeIdType string representation is
28  written (the buffer needs to be at least PUD_TX_NODEIDTYPE_DIGITS + 1 bytes).
29  When NULL then the nodeIdType string is not written.
30  @param nodeIdTypeBufferSize
31  The size of the nodeIdTypeBuffer
32  */
33 void getNodeTypeStringFromOlsr(int ipVersion, union olsr_message * olsrMessage,
34                 char * nodeIdTypeBuffer, int nodeIdTypeBufferSize) {
35         int chars;
36
37         if (unlikely(!nodeIdTypeBuffer || (nodeIdTypeBufferSize == 0))) {
38                 return;
39         }
40
41         assert(nodeIdTypeBufferSize >= (PUD_TX_NODEIDTYPE_DIGITS + 1));
42
43         /* message has NO nodeId information */
44         chars = snprintf(&nodeIdTypeBuffer[0], nodeIdTypeBufferSize, "%u",
45                         getNodeIdType(ipVersion, olsrMessage));
46         if (likely(chars < nodeIdTypeBufferSize)) {
47                 nodeIdTypeBuffer[chars] = '\0';
48         } else {
49                 nodeIdTypeBuffer[nodeIdTypeBufferSize] = '\0';
50         }
51
52         return;
53 }
54
55 /**
56  Get a nodeId number (in string representation), using a certain number of
57  bytes, from the message of an OLSR message.
58
59  @param buffer
60  A pointer to the buffer that holds the nodeId
61  @param bufferSize
62  The number of bytes used by the number in the buffer
63  @param nodeIdBuffer
64  The buffer in which to place the nodeId number in string representation
65  @param nodeIdBufferSize
66  The size of the nodeIdbuffer
67
68  @return
69  A pointer to the nodeId string representation (&nodeIdBuffer[0])
70  */
71 static char *getNodeIdNumberFromOlsr(unsigned char * buffer,
72                 unsigned int bufferSize, char *nodeIdBuffer, socklen_t nodeIdBufferSize) {
73         unsigned long long val = 0;
74         unsigned int i = 0;
75         int chars;
76
77         while (i < bufferSize) {
78                 val <<= 8;
79                 val += buffer[i];
80                 i++;
81         }
82
83         chars = snprintf(nodeIdBuffer, nodeIdBufferSize, "%llu", val);
84         if (likely(chars < (int) nodeIdBufferSize)) {
85                 nodeIdBuffer[chars] = '\0';
86         } else {
87                 nodeIdBuffer[nodeIdBufferSize] = '\0';
88         }
89         return &nodeIdBuffer[0];
90 }
91
92 /**
93  Convert the nodeId of an OLSR message into a string.
94
95  @param ipVersion
96  The ip version, either AF_INET or AF_INET6
97  @param olsrMessage
98  A pointer to the OLSR message. Used to be able to retrieve the IP address of
99  the sender.
100  @param nodeIdStr
101  A pointer to a variable in which to store the pointer to the buffer in which
102  the nodeId string representation is written (the buffer needs to be at least
103  PUD_TX_NODEIDTYPE_DIGITS + 1 bytes). Not written to when nodeIdStrBuffer or
104  nodeIdStr is NULL or when nodeIdStrBufferSize is zero. Can point to
105  nodeIdStrBuffer or straight into the olsrMessage
106  @param nodeIdStrBuffer
107  A pointer to the buffer in which the nodeId string representation can be
108  written. Not written to when nodeIdStrBuffer or nodeIdStr is NULL or when
109  nodeIdStrBufferSize is zero.
110  @param nodeIdStrBufferSize
111  The size of the nodeIdStrBuffer. When zero then nodeIdStrBuffer and nodeIdStr
112  are not written to.
113  */
114 void getNodeIdStringFromOlsr(int ipVersion, union olsr_message *olsrMessage,
115                 const char **nodeIdStr, char *nodeIdStrBuffer,
116                 unsigned int nodeIdStrBufferSize) {
117         PudOlsrWireFormat * olsrGpsMessage;
118         unsigned char * buffer;
119         unsigned int bufferSize;
120
121         if (unlikely(!nodeIdStrBuffer || (nodeIdStrBufferSize == 0) || !nodeIdStr)) {
122                 return;
123         }
124
125         assert(nodeIdStrBufferSize >= (PUD_TX_NODEID_BUFFERSIZE + 1));
126
127         olsrGpsMessage = getOlsrMessagePayload(ipVersion, olsrMessage);
128
129         getNodeIdPointers(ipVersion, olsrMessage, &buffer, &bufferSize);
130
131         if (olsrGpsMessage->smask & PUD_FLAGS_ID) {
132                 switch (olsrGpsMessage->nodeInfo.nodeIdType) {
133                         case PUD_NODEIDTYPE_MAC: /* hardware address */
134                         {
135                                 int chars;
136
137                                 assert(bufferSize == 6);
138
139                                 chars = snprintf(nodeIdStrBuffer, nodeIdStrBufferSize,
140                                                 "%02x:%02x:%02x:%02x:%02x:%02x", buffer[0], buffer[1],
141                                                 buffer[2], buffer[3], buffer[4], buffer[5]);
142                                 if (likely(chars < (int) nodeIdStrBufferSize)) {
143                                         nodeIdStrBuffer[chars] = '\0';
144                                 } else {
145                                         nodeIdStrBuffer[nodeIdStrBufferSize - 1] = '\0';
146                                 }
147                                 *nodeIdStr = &nodeIdStrBuffer[0];
148                         }
149                                 break;
150
151                         case PUD_NODEIDTYPE_DNS: /* DNS name */
152                                 *nodeIdStr = (char *) &olsrGpsMessage->nodeInfo.nodeId;
153                                 break;
154
155                         case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
156                         case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
157                         case PUD_NODEIDTYPE_192:
158                         case PUD_NODEIDTYPE_193:
159                         case PUD_NODEIDTYPE_194:
160                                 *nodeIdStr = getNodeIdNumberFromOlsr(buffer, bufferSize,
161                                                 nodeIdStrBuffer, nodeIdStrBufferSize);
162                                 break;
163
164                         case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
165                         case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
166                         default: /* unsupported */
167                                 goto noId;
168                 }
169
170                 return;
171         }
172
173         /* message has NO nodeId information */
174         noId: {
175                 void * addr = getOlsrMessageOriginator(ipVersion, olsrMessage);
176                 *nodeIdStr = inet_ntop(ipVersion, addr, nodeIdStrBuffer,
177                                 nodeIdStrBufferSize);
178         }
179
180         return;
181 }