pick up wakaama files from https://github.com/eclipse/wakaama

Revision:
0:1fa43ab66921
diff -r 000000000000 -r 1fa43ab66921 core/discover.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/discover.c	Wed Apr 19 11:30:02 2017 +0000
@@ -0,0 +1,442 @@
+/*******************************************************************************
+*
+* Copyright (c) 2015 Intel Corporation and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* and Eclipse Distribution License v1.0 which accompany this distribution.
+*
+* The Eclipse Public License is available at
+*    http://www.eclipse.org/legal/epl-v10.html
+* The Eclipse Distribution License is available at
+*    http://www.eclipse.org/org/documents/edl-v10.php.
+*
+* Contributors:
+*    David Navarro, Intel Corporation - initial API and implementation
+*
+*******************************************************************************/
+
+
+#include "internals.h"
+
+#define PRV_LINK_BUFFER_SIZE  1024
+
+
+#define PRV_CONCAT_STR(buf, len, index, str, str_len)    \
+    {                                                    \
+        if ((len)-(index) < (str_len)) return -1;        \
+        memcpy((buf)+(index), (str), (str_len));         \
+        (index) += (str_len);                            \
+    }
+
+
+#ifdef LWM2M_CLIENT_MODE
+
+static lwm2m_attributes_t * prv_findAttributes(lwm2m_context_t * contextP,
+                                               lwm2m_uri_t * uriP,
+                                               lwm2m_server_t * serverP)
+{
+    lwm2m_observed_t * observedP;
+    lwm2m_watcher_t * watcherP;
+    lwm2m_attributes_t * paramP;
+
+    paramP = NULL;
+
+    if (contextP == NULL) return NULL;
+    if (serverP == NULL) return NULL;
+
+    observedP = observe_findByUri(contextP, uriP);
+    if (observedP == NULL || observedP->watcherList == NULL) return NULL;
+
+    for (watcherP = observedP->watcherList; watcherP != NULL; watcherP = watcherP->next)
+    {
+        if (watcherP->server == serverP)
+        {
+            paramP = watcherP->parameters;
+        }
+    }
+
+    return paramP;
+}
+
+static int prv_serializeAttributes(lwm2m_context_t * contextP,
+                                   lwm2m_uri_t * uriP,
+                                   lwm2m_server_t * serverP,
+                                   lwm2m_attributes_t * objectParamP,
+                                   uint8_t * buffer,
+                                   size_t uriLen,
+                                   size_t bufferLen)
+{
+    int head;
+    int res;
+    lwm2m_attributes_t * paramP;
+
+    head = 0;
+
+    paramP = prv_findAttributes(contextP, uriP, serverP);
+    if (paramP == NULL) paramP = objectParamP;
+
+    if (paramP != NULL)
+    {
+        head = uriLen;
+
+        if (paramP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
+        {
+            PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
+            PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN);
+
+            res = utils_intToText(paramP->minPeriod, buffer + head, bufferLen - head);
+            if (res <= 0) return -1;
+            head += res;
+        }
+        else if (objectParamP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
+        {
+            PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
+            PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN);
+
+            res = utils_intToText(objectParamP->minPeriod, buffer + head, bufferLen - head);
+            if (res <= 0) return -1;
+            head += res;
+        }
+
+        if (paramP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
+        {
+            PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
+            PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN);
+
+            res = utils_intToText(paramP->maxPeriod, buffer + head, bufferLen - head);
+            if (res <= 0) return -1;
+            head += res;
+        }
+        else if (objectParamP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
+        {
+            PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
+            PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN);
+
+            res = utils_intToText(objectParamP->maxPeriod, buffer + head, bufferLen - head);
+            if (res <= 0) return -1;
+            head += res;
+        }
+
+        if (paramP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN)
+        {
+            PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
+            PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN);
+
+            res = utils_floatToText(paramP->greaterThan, buffer + head, bufferLen - head);
+            if (res <= 0) return -1;
+            head += res;
+        }
+        if (paramP->toSet & LWM2M_ATTR_FLAG_LESS_THAN)
+        {
+            PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
+            PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN);
+
+            res = utils_floatToText(paramP->lessThan, buffer + head, bufferLen - head);
+            if (res <= 0) return -1;
+            head += res;
+        }
+        if (paramP->toSet & LWM2M_ATTR_FLAG_STEP)
+        {
+            PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE);
+            PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_STEP_STR, ATTR_STEP_LEN);
+
+            res = utils_floatToText(paramP->step, buffer + head, bufferLen - head);
+            if (res <= 0) return -1;
+            head += res;
+        }
+        PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ITEM_ATTR_END, LINK_ITEM_ATTR_END_SIZE);
+    }
+
+    if (head > 0) head -= uriLen + 1;
+
+    return head;
+}
+
+static int prv_serializeLinkData(lwm2m_context_t * contextP,
+                                 lwm2m_data_t * tlvP,
+                                 lwm2m_server_t * serverP,
+                                 lwm2m_attributes_t * objectParamP,
+                                 lwm2m_uri_t * parentUriP,
+                                 uint8_t * parentUriStr,
+                                 size_t parentUriLen,
+                                 uint8_t * buffer,
+                                 size_t bufferLen)
+{
+    int head;
+    int res;
+    lwm2m_uri_t uri;
+
+    head = 0;
+
+    switch (tlvP->type)
+    {
+    case LWM2M_TYPE_UNDEFINED:
+    case LWM2M_TYPE_STRING:
+    case LWM2M_TYPE_OPAQUE:
+    case LWM2M_TYPE_INTEGER:
+    case LWM2M_TYPE_FLOAT:
+    case LWM2M_TYPE_BOOLEAN:
+    case LWM2M_TYPE_OBJECT_LINK:
+    case LWM2M_TYPE_MULTIPLE_RESOURCE:
+        if (bufferLen < LINK_ITEM_START_SIZE) return -1;
+        memcpy(buffer + head, LINK_ITEM_START, LINK_ITEM_START_SIZE);
+        head = LINK_ITEM_START_SIZE;
+
+        if (parentUriLen > 0)
+        {
+            if (bufferLen - head < parentUriLen) return -1;
+            memcpy(buffer + head, parentUriStr, parentUriLen);
+            head += parentUriLen;
+        }
+
+        if (bufferLen - head < LINK_URI_SEPARATOR_SIZE) return -1;
+        memcpy(buffer + head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
+        head += LINK_URI_SEPARATOR_SIZE;
+
+        res = utils_intToText(tlvP->id, buffer + head, bufferLen - head);
+        if (res <= 0) return -1;
+        head += res;
+
+        if (tlvP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)
+        {
+            if (bufferLen - head < LINK_ITEM_DIM_START_SIZE) return -1;
+            memcpy(buffer + head, LINK_ITEM_DIM_START, LINK_ITEM_DIM_START_SIZE);
+            head += LINK_ITEM_DIM_START_SIZE;
+
+            res = utils_intToText(tlvP->value.asChildren.count, buffer + head, bufferLen - head);
+            if (res <= 0) return -1;
+            head += res;
+
+            if (bufferLen - head < LINK_ITEM_ATTR_END_SIZE) return -1;
+            memcpy(buffer + head, LINK_ITEM_ATTR_END, LINK_ITEM_ATTR_END_SIZE);
+            head += LINK_ITEM_ATTR_END_SIZE;
+        }
+        else
+        {
+            if (bufferLen - head < LINK_ITEM_END_SIZE) return -1;
+            memcpy(buffer + head, LINK_ITEM_END, LINK_ITEM_END_SIZE);
+            head += LINK_ITEM_END_SIZE;
+        }
+
+        if (serverP != NULL)
+        {
+            memcpy(&uri, parentUriP, sizeof(lwm2m_uri_t));
+            uri.resourceId = tlvP->id;
+            uri.flag |= LWM2M_URI_FLAG_RESOURCE_ID;
+            res = prv_serializeAttributes(contextP, &uri, serverP, objectParamP, buffer, head - 1, bufferLen);
+            if (res < 0) return -1;    // careful, 0 is valid
+            if (res > 0) head += res;
+        }
+        break;
+
+    case LWM2M_TYPE_OBJECT_INSTANCE:
+    {
+        uint8_t uriStr[URI_MAX_STRING_LEN];
+        size_t uriLen;
+        size_t index;
+
+        if (parentUriLen > 0)
+        {
+            if (URI_MAX_STRING_LEN < parentUriLen) return -1;
+            memcpy(uriStr, parentUriStr, parentUriLen);
+            uriLen = parentUriLen;
+        }
+        else
+        {
+            uriLen = 0;
+        }
+
+        if (URI_MAX_STRING_LEN - uriLen < LINK_URI_SEPARATOR_SIZE) return -1;
+        memcpy(uriStr + uriLen, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
+        uriLen += LINK_URI_SEPARATOR_SIZE;
+
+        res = utils_intToText(tlvP->id, uriStr + uriLen, URI_MAX_STRING_LEN - uriLen);
+        if (res <= 0) return -1;
+        uriLen += res;
+
+        memcpy(&uri, parentUriP, sizeof(lwm2m_uri_t));
+        uri.instanceId = tlvP->id;
+        uri.flag |= LWM2M_URI_FLAG_INSTANCE_ID;
+
+        head = 0;
+        PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ITEM_START, LINK_ITEM_START_SIZE);
+        PRV_CONCAT_STR(buffer, bufferLen, head, uriStr, uriLen);
+        PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ITEM_END, LINK_ITEM_END_SIZE);
+        if (serverP != NULL)
+        {
+            res = prv_serializeAttributes(contextP, &uri, serverP, NULL, buffer, head - 1, bufferLen);
+            if (res < 0) return -1;    // careful, 0 is valid
+            if (res == 0) head = 0;    // rewind
+            else head += res;
+        }
+        for (index = 0; index < tlvP->value.asChildren.count; index++)
+        {
+            res = prv_serializeLinkData(contextP, tlvP->value.asChildren.array + index, serverP, objectParamP, &uri, uriStr, uriLen, buffer + head, bufferLen - head);
+            if (res < 0) return -1;
+            head += res;
+        }
+    }
+    break;
+
+    case LWM2M_TYPE_OBJECT:
+    default:
+        return -1;
+    }
+
+    return head;
+}
+
+int discover_serialize(lwm2m_context_t * contextP,
+                       lwm2m_uri_t * uriP,
+                       lwm2m_server_t * serverP,
+                       int size,
+                       lwm2m_data_t * dataP,
+                       uint8_t ** bufferP)
+{
+    uint8_t bufferLink[PRV_LINK_BUFFER_SIZE];
+    uint8_t baseUriStr[URI_MAX_STRING_LEN];
+    int baseUriLen;
+    int index;
+    size_t head;
+    int res;
+    lwm2m_uri_t parentUri;
+    lwm2m_attributes_t * paramP;
+    lwm2m_attributes_t mergedParam;
+
+    LOG_ARG("size: %d", size);
+    LOG_URI(uriP);
+
+    head = 0;
+    memset(&parentUri, 0, sizeof(lwm2m_uri_t));
+    parentUri.objectId = uriP->objectId;
+    parentUri.flag = LWM2M_URI_FLAG_OBJECT_ID;
+
+    if (LWM2M_URI_IS_SET_RESOURCE(uriP))
+    {
+        lwm2m_uri_t tempUri;
+        lwm2m_attributes_t * objParamP;
+        lwm2m_attributes_t * instParamP;
+
+        memset(&parentUri, 0, sizeof(lwm2m_uri_t));
+        tempUri.objectId = uriP->objectId;
+        tempUri.flag = LWM2M_URI_FLAG_OBJECT_ID;
+
+        // get object level attributes
+        objParamP = prv_findAttributes(contextP, &tempUri, serverP);
+        
+        // get object instance level attributes
+        tempUri.instanceId = uriP->instanceId;
+        tempUri.flag = LWM2M_URI_FLAG_INSTANCE_ID;
+        instParamP = prv_findAttributes(contextP, &tempUri, serverP);
+
+        if (objParamP != NULL)
+        {
+            if (instParamP != NULL)
+            {
+                memset(&mergedParam, 0, sizeof(lwm2m_attributes_t));
+                mergedParam.toSet = objParamP->toSet | instParamP->toSet;
+                if (mergedParam.toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
+                {
+                    if (instParamP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
+                    {
+                        mergedParam.minPeriod = instParamP->minPeriod;
+                    }
+                    else
+                    {
+                        mergedParam.minPeriod = objParamP->minPeriod;
+                    }
+                }
+                if (mergedParam.toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
+                {
+                    if (instParamP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
+                    {
+                        mergedParam.maxPeriod = instParamP->maxPeriod;
+                    }
+                    else
+                    {
+                        mergedParam.maxPeriod = objParamP->maxPeriod;
+                    }
+                }
+                paramP = &mergedParam;
+            }
+            else
+            {
+                paramP = objParamP;
+            }
+        }
+        else
+        {
+            paramP = instParamP;
+        }
+        uriP->flag &= ~LWM2M_URI_FLAG_RESOURCE_ID;
+    }
+    else
+    {
+        paramP = NULL;
+
+        if (LWM2M_URI_IS_SET_INSTANCE(uriP))
+        {
+            PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_START, LINK_ITEM_START_SIZE);
+            PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
+            res = utils_intToText(uriP->objectId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head);
+            if (res <= 0) return -1;
+            head += res;
+            PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
+            res = utils_intToText(uriP->instanceId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head);
+            if (res <= 0) return -1;
+            head += res;
+            PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_END, LINK_ITEM_END_SIZE);
+            parentUri.instanceId = uriP->instanceId;
+            parentUri.flag = LWM2M_URI_FLAG_INSTANCE_ID;
+            if (serverP != NULL)
+            {
+                res = prv_serializeAttributes(contextP, &parentUri, serverP, NULL, bufferLink, head - 1, PRV_LINK_BUFFER_SIZE);
+                if (res < 0) return -1;    // careful, 0 is valid
+            }
+            else
+            {
+                res = 0;
+            }
+            head += res;
+        }
+        else
+        {
+            PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_START, LINK_ITEM_START_SIZE);
+            PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE);
+            res = utils_intToText(uriP->objectId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head);
+            if (res <= 0) return -1;
+            head += res;
+            PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_END, LINK_ITEM_END_SIZE);
+
+            if (serverP != NULL)
+            {
+                res = prv_serializeAttributes(contextP, &parentUri, serverP, NULL, bufferLink, head - 1, PRV_LINK_BUFFER_SIZE);
+                if (res < 0) return -1;    // careful, 0 is valid
+                head += res;
+            }
+        }
+    }
+
+    baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, NULL);
+    if (baseUriLen < 0) return -1;
+    baseUriLen -= 1;
+
+    for (index = 0; index < size && head < PRV_LINK_BUFFER_SIZE; index++)
+    {
+        res = prv_serializeLinkData(contextP, dataP + index, serverP, paramP, uriP, baseUriStr, baseUriLen, bufferLink + head, PRV_LINK_BUFFER_SIZE - head);
+        if (res < 0) return -1;
+        head += res;
+    }
+
+    if (head > 0)
+    {
+        head -= 1;
+
+        *bufferP = (uint8_t *)lwm2m_malloc(head);
+        if (*bufferP == NULL) return 0;
+        memcpy(*bufferP, bufferLink, head);
+    }
+
+    return (int)head;
+}
+#endif
\ No newline at end of file