PUD: add getNodeIdType function
[olsrd.git] / lib / pud / src / nodeIdConversion.c
index 0bc60d5..d6b1cef 100644 (file)
  * Node Information
  * ************************************************************************ */
 
-/** The size of the cached nodeId buffer */
-#define PUD_CACHED_NODEID_BUFFER_SIZE 16
-
-/** The cached nodeId buffer: contains a pre-processed version of the nodeId
- in order to improve performance. It is currently used for nodeIdTypes
- PUD_NODEIDTYPE_MSISDN, PUD_NODEIDTYPE_TETRA, PUD_NODEIDTYPE_192,
- PUD_NODEIDTYPE_193 (so basically for numbers that will not change) */
-static unsigned char cachedNodeIdBuffer[PUD_CACHED_NODEID_BUFFER_SIZE];
-
-/** The number of bytes stored in cachedNodeIdBuffer */
-static unsigned char cachedNodeIdBufferLength = 0;
-
-/**
- Check a nodeId number for validity and if valid set it up in the
- cachedNodeIdBuffer. The valid range for the number is [min, max].
-
- @param min
- The lower bound for a valid number
- @param max
- The upper bound for a valid number
- @param bytes
- The number of bytes used by the number in the wire format
-
- @return
- - true when the number is valid
- - false otherwise
- */
-static bool setupNodeIdNumberForOlsr(unsigned long long min,
-               unsigned long long max, unsigned int bytes) {
-       unsigned long long val;
-
-       assert (bytes <= PUD_CACHED_NODEID_BUFFER_SIZE);
-
-       if (!getNodeIdAsNumber(&val)) {
-               return false;
-       }
-
-       if ((val >= min) && (val <= max)) {
-               int i = bytes - 1;
-               while (i >= 0) {
-                       cachedNodeIdBuffer[i] = val & 0xff;
-                       val >>= 8;
-                       i--;
-               }
-
-               assert(val == 0);
-
-               cachedNodeIdBufferLength = bytes;
-               return true;
-       }
-
-       pudError(false, "%s value %llu is out of range [%llu,%llu]",
-                       PUD_NODE_ID_NAME, val, min, max);
-       return false;
-}
-
-/**
- Validate whether the configured nodeId is valid w.r.t. the configured
- nodeIdType
-
- @return
- - true when ok
- - false on failure
- */
-bool validateNodeId(NodeIdType nodeIdTypeNumber) {
-       switch (nodeIdTypeNumber) {
-               case PUD_NODEIDTYPE_IPV4: /* IPv4 address */
-               case PUD_NODEIDTYPE_IPV6: /* IPv6 address */
-               case PUD_NODEIDTYPE_MAC: /* hardware address */
-                       /* explicit return: configured nodeId is not relevant */
-                       return true;
-
-               case PUD_NODEIDTYPE_MSISDN: /* an MSISDN number */
-                       return setupNodeIdNumberForOlsr(0LL, 999999999999999LL, 7);
-
-               case PUD_NODEIDTYPE_TETRA: /* a Tetra number */
-                       return setupNodeIdNumberForOlsr(0LL, 99999999999999999LL, 8);
-
-               case PUD_NODEIDTYPE_DNS: /* DNS name */
-               {
-                       bool invalidChars;
-                       char report[256];
-
-                       invalidChars = nmea_string_has_invalid_chars((char *) getNodeId(),
-                                       PUD_NODE_ID_NAME, &report[0], sizeof(report));
-                       if (invalidChars) {
-                               pudError(false, &report[0]);
-                       }
-                       return !invalidChars;
-               }
-
-               case PUD_NODEIDTYPE_192:
-                       return setupNodeIdNumberForOlsr(0LL, 9999999LL, 3);
-
-               case PUD_NODEIDTYPE_193:
-                       return setupNodeIdNumberForOlsr(0LL, 999999LL, 3);
-
-               case PUD_NODEIDTYPE_194:
-                       return setupNodeIdNumberForOlsr(1LL, 8191LL, 2);
-
-               default: /* unsupported */
-                       /* explicit return: configured nodeId is not relevant, will
-                        * fallback to IP addresses */
-                       return true;
-       }
-
-       return false;
-}
-
 /**
  Convert the node information to the node information for an OLSR message and
  put it in the PUD message in the OLSR message. Also updates the PUD message
@@ -143,7 +34,8 @@ bool validateNodeId(NodeIdType nodeIdTypeNumber) {
 size_t setupNodeInfoForOlsr(PudOlsrWireFormat * olsrGpsMessage,
                unsigned int olsrMessageSize) {
        NodeIdType nodeIdTypeNumber = getNodeIdTypeNumber();
-       size_t length = 0;
+       unsigned char * buffer;
+       unsigned int length = 0;
 
        olsrGpsMessage->nodeInfo.nodeIdType = nodeIdTypeNumber;
        switch (nodeIdTypeNumber) {
@@ -158,9 +50,8 @@ size_t setupNodeInfoForOlsr(PudOlsrWireFormat * olsrGpsMessage,
                case PUD_NODEIDTYPE_192:
                case PUD_NODEIDTYPE_193:
                case PUD_NODEIDTYPE_194:
-                       length = cachedNodeIdBufferLength;
-                       memcpy(&olsrGpsMessage->nodeInfo.nodeId, &cachedNodeIdBuffer[0],
-                                       length);
+                       getNodeIdNumberForOlsrCache(&buffer, &length);
+                       memcpy(&olsrGpsMessage->nodeInfo.nodeId, buffer, length);
                        break;
 
                case PUD_NODEIDTYPE_DNS: /* DNS name */
@@ -248,32 +139,45 @@ static char *getNodeIdNumberFromOlsr(PudOlsrWireFormat * olsrGpsMessage,
 }
 
 /**
- Convert the node information of an OLSR message to the node information for
- internal use and set it up in the given buffers.
+ Convert the nodeId of an OLSR message into a string.
 
+ @param ipVersion
+ The ip version, either AF_INET or AF_INET6
  @param olsrMessage
  A pointer to the OLSR message. Used to be able to retrieve the IP address of
  the sender.
- @param olsrGpsMessage
- A pointer to the GPS message in the OLSR message
  @param nodeId
- A pointer a variable in which to store the pointer to the buffer in which the
- nodeId string representation can be found
+ A pointer to a variable in which to store the pointer to the buffer in which
+ the nodeId string representation is written (the buffer needs to be at least
+ PUD_TX_NODEIDTYPE_DIGITS + 1 bytes). Not written to when nodeIdBuffer or
+ nodeId is NULL or when nodeIdBufferSize is zero. Can point to nodeIdBuffer
+ or straight into the olsrMessage
  @param nodeIdBuffer
  A pointer to the buffer in which the nodeId string representation can be
- written
+ written. Not written to when nodeIdBuffer or nodeId is NULL or when
+ nodeIdBufferSize is zero.
  @param nodeIdBufferSize
- The size of the nodeIdBuffer
- @param nodeIdTypeString
- A pointer to the buffer in which the nodeIdType string representation can be
- written
+ The size of the nodeIdBuffer. When zero then nodeIdBuffer and nodeId are not
+ written to.
  */
-void getNodeInfoFromOlsr(const union olsr_message *olsrMessage,
-               PudOlsrWireFormat *olsrGpsMessage, char *nodeIdBuffer,
-               unsigned int nodeIdBufferSize, const char **nodeId,
-               char *nodeIdTypeString) {
+void getNodeIdStringFromOlsr(int ipVersion, union olsr_message *olsrMessage,
+               const char **nodeId, char *nodeIdBuffer, unsigned int nodeIdBufferSize) {
+       PudOlsrWireFormat *olsrGpsMessage;
        int chars;
 
+       if (unlikely(!nodeIdBuffer || (nodeIdBufferSize == 0) || !nodeId)) {
+               return;
+       }
+
+       assert (nodeIdBufferSize >= (PUD_TX_NODEID_BUFFERSIZE + 1));
+
+       /* determine the originator of the message */
+       if (ipVersion == AF_INET) {
+               olsrGpsMessage = (PudOlsrWireFormat *) &olsrMessage->v4.message;
+       } else {
+               olsrGpsMessage = (PudOlsrWireFormat *) &olsrMessage->v6.message;
+       }
+
        if (olsrGpsMessage->smask & PUD_FLAGS_ID) {
                switch (olsrGpsMessage->nodeInfo.nodeIdType) {
                        case PUD_NODEIDTYPE_MAC: /* hardware address */
@@ -328,21 +232,12 @@ void getNodeInfoFromOlsr(const union olsr_message *olsrMessage,
                                                "Reception of unsupported %s %u, using %u",
                                                PUD_NODE_ID_TYPE_NAME,
                                                olsrGpsMessage->nodeInfo.nodeIdType,
-                                               ((olsr_cnf->ip_version == AF_INET) ? PUD_NODEIDTYPE_IPV4
+                                               ((ipVersion == AF_INET) ? PUD_NODEIDTYPE_IPV4
                                                                : PUD_NODEIDTYPE_IPV6));
                                olsrGpsMessage->smask &= ~PUD_FLAGS_ID;
                                goto noId;
                }
 
-               /* nodeIdType */
-               chars = snprintf(nodeIdTypeString, PUD_TX_NODEIDTYPE_DIGITS + 1, "%u",
-                               olsrGpsMessage->nodeInfo.nodeIdType);
-               if (likely(chars < PUD_TX_NODEIDTYPE_DIGITS)) {
-                       nodeIdTypeString[chars] = '\0';
-               } else {
-                       nodeIdTypeString[PUD_TX_NODEIDTYPE_DIGITS] = '\0';
-               }
-
                return;
        }
 
@@ -350,24 +245,50 @@ void getNodeInfoFromOlsr(const union olsr_message *olsrMessage,
        noId: {
                const void * addr;
 
-               /* nodeIdType */
-               chars = snprintf(&nodeIdTypeString[0], PUD_TX_NODEIDTYPE_DIGITS + 1,
-                               "%u", ((olsr_cnf->ip_version == AF_INET) ? PUD_NODEIDTYPE_IPV4
-                               : PUD_NODEIDTYPE_IPV6));
-               if (likely(chars < PUD_TX_NODEIDTYPE_DIGITS)) {
-                       nodeIdTypeString[chars] = '\0';
-               } else {
-                       nodeIdTypeString[PUD_TX_NODEIDTYPE_DIGITS] = '\0';
-               }
-
-               if (olsr_cnf->ip_version == AF_INET) {
+               if (ipVersion == AF_INET) {
                        addr = (const void *) &olsrMessage->v4.originator;
                } else {
                        addr = (const void *) &olsrMessage->v6.originator;
                }
 
-               *nodeId = inet_ntop(olsr_cnf->ip_version, addr, nodeIdBuffer,
-                               nodeIdBufferSize);
+               *nodeId = inet_ntop(ipVersion, addr, nodeIdBuffer, nodeIdBufferSize);
+       }
+
+       return;
+}
+
+/**
+ Convert the nodeIdType of an OLSR message into a string.
+
+ @param ipVersion
+ The ip version, either AF_INET or AF_INET6
+ @param olsrMessage
+ A pointer to the OLSR message. Used to be able to retrieve the IP address of
+ the sender.
+ @param nodeIdTypeBuffer
+ A pointer to the buffer in which the nodeIdType string representation is
+ written (the buffer needs to be at least PUD_TX_NODEIDTYPE_DIGITS + 1 bytes).
+ When NULL then the nodeIdType string is not written.
+ @param nodeIdTypeBufferSize
+ The size of the nodeIdTypeBuffer
+ */
+void getNodeTypeStringFromOlsr(int ipVersion, union olsr_message * olsrMessage,
+               char * nodeIdTypeBuffer, int nodeIdTypeBufferSize) {
+       int chars;
+
+       if (unlikely(!nodeIdTypeBuffer || (nodeIdTypeBufferSize == 0))) {
+               return;
+       }
+
+       assert(nodeIdTypeBufferSize >= (PUD_TX_NODEIDTYPE_DIGITS + 1));
+
+       /* message has NO nodeId information */
+       chars = snprintf(&nodeIdTypeBuffer[0], nodeIdTypeBufferSize, "%u",
+                       getNodeIdType(ipVersion, olsrMessage));
+       if (likely(chars < nodeIdTypeBufferSize)) {
+               nodeIdTypeBuffer[chars] = '\0';
+       } else {
+               nodeIdTypeBuffer[nodeIdTypeBufferSize] = '\0';
        }
 
        return;