pick up wakaama files from https://github.com/eclipse/wakaama
Diff: core/objects.c
- Revision:
- 0:3f48af28ebcd
diff -r 000000000000 -r 3f48af28ebcd core/objects.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/objects.c Wed Apr 19 11:28:00 2017 +0000 @@ -0,0 +1,830 @@ +/******************************************************************************* + * + * Copyright (c) 2013, 2014 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 + * Fabien Fleutot - Please refer to git log + * Toby Jaffey - Please refer to git log + * Benjamin Cabé - Please refer to git log + * Bosch Software Innovations GmbH - Please refer to git log + * Pascal Rieux - Please refer to git log + * + *******************************************************************************/ + +/* + Copyright (c) 2013, 2014 Intel Corporation + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. + + David Navarro <david.navarro@intel.com> + +*/ +#include "internals.h" + +#ifdef LWM2M_CLIENT_MODE + + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + + +uint8_t object_checkReadable(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP) +{ + coap_status_t result; + lwm2m_object_t * targetP; + lwm2m_data_t * dataP = NULL; + int size; + + LOG_URI(uriP); + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); + if (NULL == targetP) return COAP_404_NOT_FOUND; + if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; + + if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) return COAP_205_CONTENT; + + if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; + + if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_205_CONTENT; + + size = 1; + dataP = lwm2m_data_new(1); + if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; + + dataP->id = uriP->resourceId; + + result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP); + lwm2m_data_free(1, dataP); + + return result; +} + +uint8_t object_checkNumeric(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP) +{ + coap_status_t result; + lwm2m_object_t * targetP; + lwm2m_data_t * dataP = NULL; + int size; + + LOG_URI(uriP); + if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_405_METHOD_NOT_ALLOWED; + + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); + if (NULL == targetP) return COAP_404_NOT_FOUND; + if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; + + size = 1; + dataP = lwm2m_data_new(1); + if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; + + dataP->id = uriP->resourceId; + + result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP); + if (result == COAP_205_CONTENT) + { + switch (dataP->type) + { + case LWM2M_TYPE_INTEGER: + case LWM2M_TYPE_FLOAT: + break; + default: + result = COAP_405_METHOD_NOT_ALLOWED; + } + } + + lwm2m_data_free(1, dataP); + + return result; +} + +coap_status_t object_readData(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP, + int * sizeP, + lwm2m_data_t ** dataP) +{ + coap_status_t result; + lwm2m_object_t * targetP; + + LOG_URI(uriP); + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); + if (NULL == targetP) return COAP_404_NOT_FOUND; + if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; + + if (LWM2M_URI_IS_SET_INSTANCE(uriP)) + { + if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; + + // single instance read + if (LWM2M_URI_IS_SET_RESOURCE(uriP)) + { + *sizeP = 1; + *dataP = lwm2m_data_new(*sizeP); + if (*dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; + + (*dataP)->id = uriP->resourceId; + } + + result = targetP->readFunc(uriP->instanceId, sizeP, dataP, targetP); + } + else + { + // multiple object instances read + lwm2m_list_t * instanceP; + int i; + + result = COAP_205_CONTENT; + + *sizeP = 0; + for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next) + { + (*sizeP)++; + } + + if (*sizeP == 0) + { + *dataP = NULL; + } + else + { + *dataP = lwm2m_data_new(*sizeP); + if (*dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; + + instanceP = targetP->instanceList; + i = 0; + while (instanceP != NULL && result == COAP_205_CONTENT) + { + result = targetP->readFunc(instanceP->id, (int*)&((*dataP)[i].value.asChildren.count), &((*dataP)[i].value.asChildren.array), targetP); + (*dataP)[i].type = LWM2M_TYPE_OBJECT_INSTANCE; + (*dataP)[i].id = instanceP->id; + i++; + instanceP = instanceP->next; + } + } + } + + LOG_ARG("result: %u.%2u, size: %d", (result & 0xFF) >> 5, (result & 0x1F), *sizeP); + return result; +} + +coap_status_t object_read(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP, + lwm2m_media_type_t * formatP, + uint8_t ** bufferP, + size_t * lengthP) +{ + coap_status_t result; + lwm2m_data_t * dataP = NULL; + int size = 0; + int res; + + LOG_URI(uriP); + result = object_readData(contextP, uriP, &size, &dataP); + + if (result == COAP_205_CONTENT) + { + res = lwm2m_data_serialize(uriP, size, dataP, formatP, bufferP); + if (res < 0) + { + result = COAP_500_INTERNAL_SERVER_ERROR; + } + else + { + *lengthP = (size_t)res; + } + } + lwm2m_data_free(size, dataP); + + LOG_ARG("result: %u.%2u, length: %d", (result & 0xFF) >> 5, (result & 0x1F), *lengthP); + + return result; +} + +coap_status_t object_write(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP, + lwm2m_media_type_t format, + uint8_t * buffer, + size_t length) +{ + coap_status_t result = NO_ERROR; + lwm2m_object_t * targetP; + lwm2m_data_t * dataP = NULL; + int size = 0; + + LOG_URI(uriP); + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); + if (NULL == targetP) + { + result = COAP_404_NOT_FOUND; + } + else if (NULL == targetP->writeFunc) + { + result = COAP_405_METHOD_NOT_ALLOWED; + } + else + { + size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); + if (size == 0) + { + result = COAP_406_NOT_ACCEPTABLE; + } + } + if (result == NO_ERROR) + { + result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP); + lwm2m_data_free(size, dataP); + } + + LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); + + return result; +} + +coap_status_t object_execute(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP, + uint8_t * buffer, + size_t length) +{ + lwm2m_object_t * targetP; + + LOG_URI(uriP); + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); + if (NULL == targetP) return COAP_404_NOT_FOUND; + if (NULL == targetP->executeFunc) return COAP_405_METHOD_NOT_ALLOWED; + if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; + + return targetP->executeFunc(uriP->instanceId, uriP->resourceId, buffer, length, targetP); +} + +coap_status_t object_create(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP, + lwm2m_media_type_t format, + uint8_t * buffer, + size_t length) +{ + lwm2m_object_t * targetP; + lwm2m_data_t * dataP = NULL; + int size = 0; + uint8_t result; + + LOG_URI(uriP); + + if (length == 0 || buffer == 0) + { + return COAP_400_BAD_REQUEST; + } + + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); + if (NULL == targetP) return COAP_404_NOT_FOUND; + if (NULL == targetP->createFunc) return COAP_405_METHOD_NOT_ALLOWED; + + size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); + if (size <= 0) return COAP_400_BAD_REQUEST; + + switch (dataP[0].type) + { + case LWM2M_TYPE_OBJECT: + result = COAP_400_BAD_REQUEST; + goto exit; + + case LWM2M_TYPE_OBJECT_INSTANCE: + if (size != 1) + { + result = COAP_400_BAD_REQUEST; + goto exit; + } + if (NULL != lwm2m_list_find(targetP->instanceList, dataP[0].id)) + { + // Instance already exists + result = COAP_406_NOT_ACCEPTABLE; + goto exit; + } + result = targetP->createFunc(dataP[0].id, dataP[0].value.asChildren.count, dataP[0].value.asChildren.array, targetP); + uriP->instanceId = dataP[0].id; + uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; + break; + + default: + if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) + { + uriP->instanceId = lwm2m_list_newId(targetP->instanceList); + uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; + } + result = targetP->createFunc(uriP->instanceId, size, dataP, targetP); + break; + } + +exit: + lwm2m_data_free(size, dataP); + + LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); + + return result; +} + +coap_status_t object_delete(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP) +{ + lwm2m_object_t * objectP; + coap_status_t result; + + LOG_URI(uriP); + objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); + if (NULL == objectP) return COAP_404_NOT_FOUND; + if (NULL == objectP->deleteFunc) return COAP_405_METHOD_NOT_ALLOWED; + + LOG("Entering"); + + if (LWM2M_URI_IS_SET_INSTANCE(uriP)) + { + result = objectP->deleteFunc(uriP->instanceId, objectP); + } + else + { + lwm2m_list_t * instanceP; + + result = COAP_202_DELETED; + instanceP = objectP->instanceList; + while (NULL != instanceP + && result == COAP_202_DELETED) + { + result = objectP->deleteFunc(instanceP->id, objectP); + instanceP = objectP->instanceList; + } + } + + LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); + + return result; +} + +coap_status_t object_discover(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP, + lwm2m_server_t * serverP, + uint8_t ** bufferP, + size_t * lengthP) +{ + coap_status_t result; + lwm2m_object_t * targetP; + lwm2m_data_t * dataP = NULL; + int size = 0; + + LOG_URI(uriP); + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); + if (NULL == targetP) return COAP_404_NOT_FOUND; + if (NULL == targetP->discoverFunc) return COAP_501_NOT_IMPLEMENTED; + + if (LWM2M_URI_IS_SET_INSTANCE(uriP)) + { + if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; + + // single instance read + if (LWM2M_URI_IS_SET_RESOURCE(uriP)) + { + size = 1; + dataP = lwm2m_data_new(size); + if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; + + dataP->id = uriP->resourceId; + } + + result = targetP->discoverFunc(uriP->instanceId, &size, &dataP, targetP); + } + else + { + // multiple object instances read + lwm2m_list_t * instanceP; + int i; + + result = COAP_205_CONTENT; + + size = 0; + for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next) + { + size++; + } + + if (size != 0) + { + dataP = lwm2m_data_new(size); + if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; + + instanceP = targetP->instanceList; + i = 0; + while (instanceP != NULL && result == COAP_205_CONTENT) + { + result = targetP->discoverFunc(instanceP->id, (int*)&(dataP[i].value.asChildren.count), &(dataP[i].value.asChildren.array), targetP); + dataP[i].type = LWM2M_TYPE_OBJECT_INSTANCE; + dataP[i].id = instanceP->id; + i++; + instanceP = instanceP->next; + } + } + } + + if (result == COAP_205_CONTENT) + { + int len; + + len = discover_serialize(contextP, uriP, serverP, size, dataP, bufferP); + if (len <= 0) result = COAP_500_INTERNAL_SERVER_ERROR; + else *lengthP = len; + } + lwm2m_data_free(size, dataP); + + LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); + + return result; +} + +bool object_isInstanceNew(lwm2m_context_t * contextP, + uint16_t objectId, + uint16_t instanceId) +{ + lwm2m_object_t * targetP; + + LOG("Entering"); + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, objectId); + if (targetP != NULL) + { + if (NULL != lwm2m_list_find(targetP->instanceList, instanceId)) + { + return false; + } + } + + return true; +} + +static int prv_getObjectTemplate(uint8_t * buffer, + size_t length, + uint16_t id) +{ + int index; + int result; + + if (length < REG_OBJECT_MIN_LEN) return -1; + + buffer[0] = '<'; + buffer[1] = '/'; + index = 2; + + result = utils_intCopy((char *)buffer + index, length - index, id); + if (result < 0) return -1; + index += result; + + if (length - index < REG_OBJECT_MIN_LEN - 3) return -1; + buffer[index] = '/'; + index++; + + return index; +} + +int object_getRegisterPayload(lwm2m_context_t * contextP, + uint8_t * buffer, + size_t bufferLen) +{ + size_t index; + int result; + lwm2m_object_t * objectP; + + LOG("Entering"); + // index can not be greater than bufferLen + index = 0; + + result = utils_stringCopy((char *)buffer, bufferLen, REG_START); + if (result < 0) return 0; + index += result; + + if ((contextP->altPath != NULL) + && (contextP->altPath[0] != 0)) + { + result = utils_stringCopy((char *)buffer + index, bufferLen - index, contextP->altPath); + } + else + { + result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_DEFAULT_PATH); + } + if (result < 0) return 0; + index += result; + + result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_LWM2M_RESOURCE_TYPE); + if (result < 0) return 0; + index += result; + + for (objectP = contextP->objectList; objectP != NULL; objectP = objectP->next) + { + size_t start; + size_t length; + + if (objectP->objID == LWM2M_SECURITY_OBJECT_ID) continue; + + start = index; + result = prv_getObjectTemplate(buffer + index, bufferLen - index, objectP->objID); + if (result < 0) return 0; + length = result; + index += length; + + if (objectP->instanceList == NULL) + { + index--; + result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_PATH_END); + if (result < 0) return 0; + index += result; + } + else + { + lwm2m_list_t * targetP; + for (targetP = objectP->instanceList ; targetP != NULL ; targetP = targetP->next) + { + if (bufferLen - index <= length) return 0; + + if (index != start + length) + { + memcpy(buffer + index, buffer + start, length); + index += length; + } + + result = utils_intCopy((char *)buffer + index, bufferLen - index, targetP->id); + if (result < 0) return 0; + index += result; + + result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_PATH_END); + if (result < 0) return 0; + index += result; + } + } + } + + if (index > 0) + { + index = index - 1; // remove trailing ',' + } + + buffer[index] = 0; + + return index; +} + +static lwm2m_list_t * prv_findServerInstance(lwm2m_object_t * objectP, + uint16_t shortID) +{ + lwm2m_list_t * instanceP; + + instanceP = objectP->instanceList; + while (NULL != instanceP) + { + int64_t value; + lwm2m_data_t * dataP; + int size; + + size = 1; + dataP = lwm2m_data_new(size); + if (dataP == NULL) return NULL; + dataP->id = LWM2M_SERVER_SHORT_ID_ID; + + if (objectP->readFunc(instanceP->id, &size, &dataP, objectP) != COAP_205_CONTENT) + { + lwm2m_data_free(size, dataP); + return NULL; + } + + if (1 == lwm2m_data_decode_int(dataP, &value)) + { + if (value == shortID) + { + lwm2m_data_free(size, dataP); + break; + } + } + lwm2m_data_free(size, dataP); + instanceP = instanceP->next; + } + + return instanceP; +} + +static int prv_getMandatoryInfo(lwm2m_object_t * objectP, + uint16_t instanceID, + lwm2m_server_t * targetP) +{ + lwm2m_data_t * dataP; + int size; + int64_t value; + + size = 2; + dataP = lwm2m_data_new(size); + if (dataP == NULL) return -1; + dataP[0].id = LWM2M_SERVER_LIFETIME_ID; + dataP[1].id = LWM2M_SERVER_BINDING_ID; + + if (objectP->readFunc(instanceID, &size, &dataP, objectP) != COAP_205_CONTENT) + { + lwm2m_data_free(size, dataP); + return -1; + } + + if (0 == lwm2m_data_decode_int(dataP, &value) + || value < 0 || value >0xFFFFFFFF) // This is an implementation limit + { + lwm2m_data_free(size, dataP); + return -1; + } + targetP->lifetime = value; + + targetP->binding = utils_stringToBinding(dataP[1].value.asBuffer.buffer, dataP[1].value.asBuffer.length); + + lwm2m_data_free(size, dataP); + + if (targetP->binding == BINDING_UNKNOWN) + { + return -1; + } + + return 0; +} + +int object_getServers(lwm2m_context_t * contextP) +{ + lwm2m_object_t * objectP; + lwm2m_object_t * securityObjP = NULL; + lwm2m_object_t * serverObjP = NULL; + lwm2m_list_t * securityInstP; // instanceID of the server in the LWM2M Security Object + + LOG("Entering"); + + for (objectP = contextP->objectList; objectP != NULL; objectP = objectP->next) + { + if (objectP->objID == LWM2M_SECURITY_OBJECT_ID) + { + securityObjP = objectP; + } + else if (objectP->objID == LWM2M_SERVER_OBJECT_ID) + { + serverObjP = objectP; + } + } + + if (NULL == securityObjP) return -1; + + securityInstP = securityObjP->instanceList; + while (securityInstP != NULL) + { + if (LWM2M_LIST_FIND(contextP->bootstrapServerList, securityInstP->id) == NULL + && LWM2M_LIST_FIND(contextP->serverList, securityInstP->id) == NULL) + { + // This server is new. eg created by last bootstrap + + lwm2m_data_t * dataP; + int size; + lwm2m_server_t * targetP; + bool isBootstrap; + int64_t value = 0; + + size = 3; + dataP = lwm2m_data_new(size); + if (dataP == NULL) return -1; + dataP[0].id = LWM2M_SECURITY_BOOTSTRAP_ID; + dataP[1].id = LWM2M_SECURITY_SHORT_SERVER_ID; + dataP[2].id = LWM2M_SECURITY_HOLD_OFF_ID; + + if (securityObjP->readFunc(securityInstP->id, &size, &dataP, securityObjP) != COAP_205_CONTENT) + { + lwm2m_data_free(size, dataP); + return -1; + } + + targetP = (lwm2m_server_t *)lwm2m_malloc(sizeof(lwm2m_server_t)); + if (targetP == NULL) { + lwm2m_data_free(size, dataP); + return -1; + } + memset(targetP, 0, sizeof(lwm2m_server_t)); + targetP->secObjInstID = securityInstP->id; + + if (0 == lwm2m_data_decode_bool(dataP + 0, &isBootstrap)) + { + lwm2m_free(targetP); + lwm2m_data_free(size, dataP); + return -1; + } + + if (0 == lwm2m_data_decode_int(dataP + 1, &value) + || value < (isBootstrap ? 0 : 1) || value > 0xFFFF) // 0 is forbidden as a Short Server ID + { + lwm2m_free(targetP); + lwm2m_data_free(size, dataP); + return -1; + } + targetP->shortID = value; + + if (isBootstrap == true) + { + if (0 == lwm2m_data_decode_int(dataP + 2, &value) + || value < 0 || value > 0xFFFFFFFF) // This is an implementation limit + { + lwm2m_free(targetP); + lwm2m_data_free(size, dataP); + return -1; + } + // lifetime of a bootstrap server is set to ClientHoldOffTime + targetP->lifetime = value; + + contextP->bootstrapServerList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->bootstrapServerList, targetP); + } + else + { + lwm2m_list_t * serverInstP; // instanceID of the server in the LWM2M Server Object + + serverInstP = prv_findServerInstance(serverObjP, targetP->shortID); + if (serverInstP == NULL) + { + lwm2m_free(targetP); + lwm2m_data_free(size, dataP); + return -1; + } + if (0 != prv_getMandatoryInfo(serverObjP, serverInstP->id, targetP)) + { + lwm2m_free(targetP); + lwm2m_data_free(size, dataP); + return -1; + } + targetP->status = STATE_DEREGISTERED; + contextP->serverList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->serverList, targetP); + } + lwm2m_data_free(size, dataP); + } + securityInstP = securityInstP->next; + } + + return 0; +} + +coap_status_t object_createInstance(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP, + lwm2m_data_t * dataP) +{ + lwm2m_object_t * targetP; + + LOG_URI(uriP); + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); + if (NULL == targetP) return COAP_404_NOT_FOUND; + + if (NULL == targetP->createFunc) + { + return COAP_405_METHOD_NOT_ALLOWED; + } + + return targetP->createFunc(lwm2m_list_newId(targetP->instanceList), dataP->value.asChildren.count, dataP->value.asChildren.array, targetP); +} + +coap_status_t object_writeInstance(lwm2m_context_t * contextP, + lwm2m_uri_t * uriP, + lwm2m_data_t * dataP) +{ + lwm2m_object_t * targetP; + + LOG_URI(uriP); + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); + if (NULL == targetP) return COAP_404_NOT_FOUND; + + if (NULL == targetP->writeFunc) + { + return COAP_405_METHOD_NOT_ALLOWED; + } + + return targetP->writeFunc(dataP->id, dataP->value.asChildren.count, dataP->value.asChildren.array, targetP); +} + +#endif