ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/services/lwm2m/tests/lightclient/test_object.c b/marvell/services/lwm2m/tests/lightclient/test_object.c
new file mode 100644
index 0000000..d145698
--- /dev/null
+++ b/marvell/services/lwm2m/tests/lightclient/test_object.c
@@ -0,0 +1,336 @@
+/*******************************************************************************
+ *
+ * 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
+ * domedambrosio - Please refer to git log
+ * Fabien Fleutot - Please refer to git log
+ * Axel Lorente - Please refer to git log
+ * Achim Kraus, 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>
+
+*/
+
+/*
+ * Implements an object for testing purpose
+ *
+ * Multiple
+ * Object | ID | Instances | Mandatoty |
+ * Test | 1024 | Yes | No |
+ *
+ * Ressources:
+ * Supported Multiple
+ * Name | ID | Operations | Instances | Mandatory | Type | Range | Units | Description |
+ * test | 1 | R/W | No | Yes | Integer | 0-255 | | |
+ * exec | 2 | E | No | Yes | | | | |
+ * dec | 3 | R/W | No | Yes | Float | | | |
+ *
+ */
+
+#include "liblwm2m.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+static void prv_output_buffer(uint8_t * buffer,
+ int length)
+{
+ int i;
+ uint8_t array[16];
+
+ i = 0;
+ while (i < length)
+ {
+ int j;
+ fprintf(stderr, " ");
+
+ memcpy(array, buffer+i, 16);
+
+ for (j = 0 ; j < 16 && i+j < length; j++)
+ {
+ fprintf(stderr, "%02X ", array[j]);
+ }
+ while (j < 16)
+ {
+ fprintf(stderr, " ");
+ j++;
+ }
+ fprintf(stderr, " ");
+ for (j = 0 ; j < 16 && i+j < length; j++)
+ {
+ if (isprint(array[j]))
+ fprintf(stderr, "%c ", array[j]);
+ else
+ fprintf(stderr, ". ");
+ }
+ fprintf(stderr, "\n");
+
+ i += 16;
+ }
+}
+
+/*
+ * Multiple instance objects can use userdata to store data that will be shared between the different instances.
+ * The lwm2m_object_t object structure - which represent every object of the liblwm2m as seen in the single instance
+ * object - contain a chained list called instanceList with the object specific structure prv_instance_t:
+ */
+typedef struct _prv_instance_
+{
+ /*
+ * The first two are mandatories and represent the pointer to the next instance and the ID of this one. The rest
+ * is the instance scope user data (uint8_t test in this case)
+ */
+ struct _prv_instance_ * next; // matches lwm2m_list_t::next
+ uint16_t shortID; // matches lwm2m_list_t::id
+ uint8_t test;
+ double dec;
+} prv_instance_t;
+
+static uint8_t prv_read(uint16_t instanceId,
+ int * numDataP,
+ lwm2m_tlv_t ** dataArrayP,
+ lwm2m_object_t * objectP)
+{
+ prv_instance_t * targetP;
+ int i;
+
+ targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
+ if (NULL == targetP) return COAP_404_NOT_FOUND;
+
+ if (*numDataP == 0)
+ {
+ *dataArrayP = lwm2m_tlv_new(2);
+ if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
+ *numDataP = 2;
+ (*dataArrayP)[0].id = 1;
+ (*dataArrayP)[1].id = 3;
+ }
+
+ for (i = 0 ; i < *numDataP ; i++)
+ {
+ switch ((*dataArrayP)[i].id)
+ {
+ case 1:
+ (*dataArrayP)[i].type = LWM2M_TYPE_RESOURCE;
+ lwm2m_tlv_encode_int(targetP->test, *dataArrayP + i);
+ break;
+ case 2:
+ return COAP_405_METHOD_NOT_ALLOWED;
+ case 3:
+ (*dataArrayP)[i].type = LWM2M_TYPE_RESOURCE;
+ lwm2m_tlv_encode_float(targetP->dec, *dataArrayP + i);
+ break;
+ default:
+ return COAP_404_NOT_FOUND;
+ }
+ if ((*dataArrayP)[i].length == 0) return COAP_500_INTERNAL_SERVER_ERROR;
+ }
+
+ return COAP_205_CONTENT;
+}
+
+static uint8_t prv_write(uint16_t instanceId,
+ int numData,
+ lwm2m_tlv_t * dataArray,
+ lwm2m_object_t * objectP)
+{
+ prv_instance_t * targetP;
+ int i;
+
+ targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
+ if (NULL == targetP) return COAP_404_NOT_FOUND;
+
+ for (i = 0 ; i < numData ; i++)
+ {
+ switch (dataArray[i].id)
+ {
+ case 1:
+ {
+ int64_t value;
+
+ if (1 != lwm2m_tlv_decode_int(dataArray + i, &value) || value < 0 || value > 0xFF)
+ {
+ return COAP_400_BAD_REQUEST;
+ }
+ targetP->test = (uint8_t)value;
+ }
+ break;
+ case 2:
+ return COAP_405_METHOD_NOT_ALLOWED;
+ case 3:
+ if (1 != lwm2m_tlv_decode_float(dataArray + i, &(targetP->dec)))
+ {
+ return COAP_400_BAD_REQUEST;
+ }
+ break;
+ default:
+ return COAP_404_NOT_FOUND;
+ }
+ }
+
+ return COAP_204_CHANGED;
+}
+
+static uint8_t prv_delete(uint16_t id,
+ lwm2m_object_t * objectP)
+{
+ prv_instance_t * targetP;
+
+ objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id, (lwm2m_list_t **)&targetP);
+ if (NULL == targetP) return COAP_404_NOT_FOUND;
+
+ lwm2m_free(targetP);
+
+ return COAP_202_DELETED;
+}
+
+static uint8_t prv_create(uint16_t instanceId,
+ int numData,
+ lwm2m_tlv_t * dataArray,
+ lwm2m_object_t * objectP)
+{
+ prv_instance_t * targetP;
+ uint8_t result;
+
+
+ targetP = (prv_instance_t *)lwm2m_malloc(sizeof(prv_instance_t));
+ if (NULL == targetP) return COAP_500_INTERNAL_SERVER_ERROR;
+ memset(targetP, 0, sizeof(prv_instance_t));
+
+ targetP->shortID = instanceId;
+ objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, targetP);
+
+ result = prv_write(instanceId, numData, dataArray, objectP);
+
+ if (result != COAP_204_CHANGED)
+ {
+ (void)prv_delete(instanceId, objectP);
+ }
+ else
+ {
+ result = COAP_201_CREATED;
+ }
+
+ return result;
+}
+
+static uint8_t prv_exec(uint16_t instanceId,
+ uint16_t resourceId,
+ uint8_t * buffer,
+ int length,
+ lwm2m_object_t * objectP)
+{
+
+ if (NULL == lwm2m_list_find(objectP->instanceList, instanceId)) return COAP_404_NOT_FOUND;
+
+ switch (resourceId)
+ {
+ case 1:
+ return COAP_405_METHOD_NOT_ALLOWED;
+ case 2:
+ fprintf(stdout, "\r\n-----------------\r\n"
+ "Execute on %hu/%d/%d\r\n"
+ " Parameter (%d bytes):\r\n",
+ objectP->objID, instanceId, resourceId, length);
+ prv_output_buffer((uint8_t*)buffer, length);
+ fprintf(stdout, "-----------------\r\n\r\n");
+ return COAP_204_CHANGED;
+ case 3:
+ return COAP_405_METHOD_NOT_ALLOWED;
+ default:
+ return COAP_404_NOT_FOUND;
+ }
+}
+
+static void prv_test_close(lwm2m_object_t * object)
+{
+ LWM2M_LIST_FREE(object->instanceList);
+ if (object->userData != NULL)
+ {
+ lwm2m_free(object->userData);
+ object->userData = NULL;
+ }
+}
+
+lwm2m_object_t * get_test_object(void)
+{
+ lwm2m_object_t * testObj;
+
+ testObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
+
+ if (NULL != testObj)
+ {
+ int i;
+ prv_instance_t * targetP;
+
+ memset(testObj, 0, sizeof(lwm2m_object_t));
+
+ testObj->objID = 1024;
+ for (i=0 ; i < 3 ; i++)
+ {
+ targetP = (prv_instance_t *)lwm2m_malloc(sizeof(prv_instance_t));
+ if (NULL == targetP) return NULL;
+ memset(targetP, 0, sizeof(prv_instance_t));
+ targetP->shortID = 10 + i;
+ targetP->test = 20 + i;
+ targetP->dec = -30 + i + (double)i/100.0;
+ testObj->instanceList = LWM2M_LIST_ADD(testObj->instanceList, targetP);
+ }
+ /*
+ * From a single instance object, two more functions are available.
+ * - The first one (createFunc) create a new instance and filled it with the provided informations. If an ID is
+ * provided a check is done for verifying his disponibility, or a new one is generated.
+ * - The other one (deleteFunc) delete an instance by removing it from the instance list (and freeing the memory
+ * allocated to it)
+ */
+ testObj->readFunc = prv_read;
+ testObj->writeFunc = prv_write;
+ testObj->executeFunc = prv_exec;
+ testObj->createFunc = prv_create;
+ testObj->deleteFunc = prv_delete;
+ testObj->closeFunc = prv_test_close;
+ }
+
+ return testObj;
+}