Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: object_server.c
- Revision:
- 4:35892233a85d
- Parent:
- 2:5a8853c481ad
--- a/object_server.c Fri Apr 28 18:13:27 2017 +0800
+++ b/object_server.c Fri Apr 28 18:20:36 2017 +0800
@@ -13,6 +13,8 @@
* Contributors:
* David Navarro, Intel Corporation - initial API and implementation
* Julien Vermillard, Sierra Wireless
+ * Bosch Software Innovations GmbH - Please refer to git log
+ * Pascal Rieux - Please refer to git log
*
*******************************************************************************/
@@ -26,243 +28,398 @@
* Default Max Period | 3 | R/W | Single | No | Integer | | s |
* Disable | 4 | E | Single | No | | | |
* Disable Timeout | 5 | R/W | Single | No | Integer | | s |
- * Notification Storing | 6 | R/W | Single | Yes | String | | |
- * Binding | 7 | R/W | Single | Yes | | | |
+ * Notification Storing | 6 | R/W | Single | Yes | Boolean | | |
+ * Binding | 7 | R/W | Single | Yes | String | | |
* Registration Update | 8 | E | Single | Yes | | | |
*
*/
-#include "internals.h"
+#include "liblwm2m.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct _server_instance_
+{
+ struct _server_instance_ * next; // matches lwm2m_list_t::next
+ uint16_t instanceId; // matches lwm2m_list_t::id
+ uint16_t shortServerId;
+ uint32_t lifetime;
+ bool storing;
+ char binding[4];
+} server_instance_t;
+
+static uint8_t prv_get_value(lwm2m_data_t * dataP,
+ server_instance_t * targetP)
+{
+ switch (dataP->id)
+ {
+ case LWM2M_SERVER_SHORT_ID_ID:
+ lwm2m_data_encode_int(targetP->shortServerId, dataP);
+ return COAP_205_CONTENT;
+
+ case LWM2M_SERVER_LIFETIME_ID:
+ lwm2m_data_encode_int(targetP->lifetime, dataP);
+ return COAP_205_CONTENT;
+
+ case LWM2M_SERVER_DISABLE_ID:
+ return COAP_405_METHOD_NOT_ALLOWED;
+
+ case LWM2M_SERVER_STORING_ID:
+ lwm2m_data_encode_bool(targetP->storing, dataP);
+ return COAP_205_CONTENT;
+
+ case LWM2M_SERVER_BINDING_ID:
+ lwm2m_data_encode_string(targetP->binding, dataP);
+ return COAP_205_CONTENT;
+
+ case LWM2M_SERVER_UPDATE_ID:
+ return COAP_405_METHOD_NOT_ALLOWED;
+
+ default:
+ return COAP_404_NOT_FOUND;
+ }
+}
+
+static uint8_t prv_server_read(uint16_t instanceId,
+ int * numDataP,
+ lwm2m_data_t ** dataArrayP,
+ lwm2m_object_t * objectP)
+{
+ server_instance_t * targetP;
+ uint8_t result;
+ int i;
+
+ targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
+ if (NULL == targetP) return COAP_404_NOT_FOUND;
-#ifdef LWM2M_CLIENT_MODE
-#define RESOURCE_SHORTID_ID 0
-#define RESOURCE_LIFETIME_ID 1
-#define RESOURCE_MINPERIOD_ID 2
-#define RESOURCE_MAXPERIOD_ID 3
-#define RESOURCE_DISABLE_ID 4
-#define RESOURCE_TIMEOUT_ID 5
-#define RESOURCE_STORING_ID 6
-#define RESOURCE_BINDING_ID 7
-#define RESOURCE_UPDATE_ID 8
+ // is the server asking for the full instance ?
+ if (*numDataP == 0)
+ {
+ uint16_t resList[] = {
+ LWM2M_SERVER_SHORT_ID_ID,
+ LWM2M_SERVER_LIFETIME_ID,
+ LWM2M_SERVER_STORING_ID,
+ LWM2M_SERVER_BINDING_ID
+ };
+ int nbRes = sizeof(resList)/sizeof(uint16_t);
+
+ *dataArrayP = lwm2m_data_new(nbRes);
+ if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
+ *numDataP = nbRes;
+ for (i = 0 ; i < nbRes ; i++)
+ {
+ (*dataArrayP)[i].id = resList[i];
+ }
+ }
+
+ i = 0;
+ do
+ {
+ result = prv_get_value((*dataArrayP) + i, targetP);
+ i++;
+ } while (i < *numDataP && result == COAP_205_CONTENT);
+
+ return result;
+}
-#define LIFETIME_DEFAULT 86400
+static uint8_t prv_server_discover(uint16_t instanceId,
+ int * numDataP,
+ lwm2m_data_t ** dataArrayP,
+ lwm2m_object_t * objectP)
+{
+ uint8_t result;
+ int i;
+
+ result = COAP_205_CONTENT;
-coap_status_t object_server_read(lwm2m_context_t * contextP,
- lwm2m_uri_t * uriP,
- char ** bufferP,
- int * lengthP)
-{
- if (!LWM2M_URI_IS_SET_INSTANCE(uriP))
+ // is the server asking for the full object ?
+ if (*numDataP == 0)
{
- return COAP_501_NOT_IMPLEMENTED;
+ uint16_t resList[] = {
+ LWM2M_SERVER_SHORT_ID_ID,
+ LWM2M_SERVER_LIFETIME_ID,
+ LWM2M_SERVER_MIN_PERIOD_ID,
+ LWM2M_SERVER_MAX_PERIOD_ID,
+ LWM2M_SERVER_DISABLE_ID,
+ LWM2M_SERVER_TIMEOUT_ID,
+ LWM2M_SERVER_STORING_ID,
+ LWM2M_SERVER_BINDING_ID,
+ LWM2M_SERVER_UPDATE_ID
+ };
+ int nbRes = sizeof(resList)/sizeof(uint16_t);
+
+ *dataArrayP = lwm2m_data_new(nbRes);
+ if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
+ *numDataP = nbRes;
+ for (i = 0 ; i < nbRes ; i++)
+ {
+ (*dataArrayP)[i].id = resList[i];
+ }
}
else
{
- lwm2m_server_t * serverP;
+ for (i = 0; i < *numDataP && result == COAP_205_CONTENT; i++)
+ {
+ switch ((*dataArrayP)[i].id)
+ {
+ case LWM2M_SERVER_SHORT_ID_ID:
+ case LWM2M_SERVER_LIFETIME_ID:
+ case LWM2M_SERVER_MIN_PERIOD_ID:
+ case LWM2M_SERVER_MAX_PERIOD_ID:
+ case LWM2M_SERVER_DISABLE_ID:
+ case LWM2M_SERVER_TIMEOUT_ID:
+ case LWM2M_SERVER_STORING_ID:
+ case LWM2M_SERVER_BINDING_ID:
+ case LWM2M_SERVER_UPDATE_ID:
+ break;
+ default:
+ result = COAP_404_NOT_FOUND;
+ }
+ }
+ }
- serverP = (lwm2m_server_t *)lwm2m_list_find((lwm2m_list_t *)contextP->serverList, uriP->instanceId);
- if (serverP == NULL) return COAP_404_NOT_FOUND;
+ return result;
+}
- if (!LWM2M_URI_IS_SET_RESOURCE(uriP))
+static uint8_t prv_set_int_value(lwm2m_data_t * dataArray,
+ uint32_t * data)
+{
+ uint8_t result;
+ int64_t value;
+
+ if (1 == lwm2m_data_decode_int(dataArray, &value))
+ {
+ if (value >= 0 && value <= 0xFFFFFFFF)
{
- return COAP_501_NOT_IMPLEMENTED;
+ *data = value;
+ result = COAP_204_CHANGED;
}
else
{
- switch (uriP->resourceId)
+ result = COAP_406_NOT_ACCEPTABLE;
+ }
+ }
+ else
+ {
+ result = COAP_400_BAD_REQUEST;
+ }
+ return result;
+}
+
+static uint8_t prv_server_write(uint16_t instanceId,
+ int numData,
+ lwm2m_data_t * dataArray,
+ lwm2m_object_t * objectP)
+{
+ server_instance_t * targetP;
+ int i;
+ uint8_t result;
+
+ targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
+ if (NULL == targetP)
+ {
+ return COAP_404_NOT_FOUND;
+ }
+
+ i = 0;
+ do
+ {
+ switch (dataArray[i].id)
+ {
+ case LWM2M_SERVER_SHORT_ID_ID:
+ {
+ uint32_t value;
+
+ result = prv_set_int_value(dataArray + i, &value);
+ if (COAP_204_CHANGED == result)
{
- case RESOURCE_SHORTID_ID:
- *lengthP = lwm2m_int32ToPlainText(serverP->shortID, bufferP);
- if (0 != *lengthP)
+ if (0 < value && value <= 0xFFFF)
{
- return COAP_205_CONTENT;
+ targetP->shortServerId = value;
}
else
{
- return COAP_500_INTERNAL_SERVER_ERROR;
+ result = COAP_406_NOT_ACCEPTABLE;
}
- break;
-
- case RESOURCE_LIFETIME_ID:
- {
- int lifetime = serverP->lifetime;
- if (lifetime == 0) lifetime = LIFETIME_DEFAULT;
-
- *lengthP = lwm2m_int32ToPlainText(lifetime,bufferP);
+ }
+ }
+ break;
- if (0 != *lengthP)
- {
- return COAP_205_CONTENT;
- }
- else
- {
- return COAP_500_INTERNAL_SERVER_ERROR;
- }
- }
- break;
+ case LWM2M_SERVER_LIFETIME_ID:
+ result = prv_set_int_value(dataArray + i, (uint32_t *)&(targetP->lifetime));
+ break;
- case RESOURCE_MINPERIOD_ID:
- return COAP_404_NOT_FOUND;
- case RESOURCE_MAXPERIOD_ID:
- return COAP_404_NOT_FOUND;
- case RESOURCE_TIMEOUT_ID:
- return COAP_404_NOT_FOUND;
- case RESOURCE_STORING_ID:
- return COAP_501_NOT_IMPLEMENTED;
- case RESOURCE_BINDING_ID:
- {
- char * value;
- int len;
- switch (serverP->binding) {
- case BINDING_U:
- value = "U";
- *lengthP = 1;
- break;
- case BINDING_UQ:
- value = "UQ";
- *lengthP = 2;
- break;
- case BINDING_S:
- value="S";
- *lengthP = 1;
- break;
- case BINDING_SQ:
- value = "SQ";
- *lengthP = 2;
- break;
- case BINDING_US:
- value = "US";
- *lengthP = 2;
- break;
- case BINDING_UQS:
- value = "USQ";
- *lengthP = 3;
- break;
- default:
- return COAP_500_INTERNAL_SERVER_ERROR;
- }
- *bufferP = lwm2m_malloc(*lengthP);
- if (NULL == *bufferP) return COAP_500_INTERNAL_SERVER_ERROR;
- memcpy(*bufferP, value, *lengthP);
- return COAP_205_CONTENT;
- }
- default:
- return COAP_405_METHOD_NOT_ALLOWED;
+ case LWM2M_SERVER_DISABLE_ID:
+ result = COAP_405_METHOD_NOT_ALLOWED;
+ break;
+
+ case LWM2M_SERVER_STORING_ID:
+ {
+ bool value;
+
+ if (1 == lwm2m_data_decode_bool(dataArray + i, &value))
+ {
+ targetP->storing = value;
+ result = COAP_204_CHANGED;
+ }
+ else
+ {
+ result = COAP_400_BAD_REQUEST;
}
}
- }
+ break;
+
+ case LWM2M_SERVER_BINDING_ID:
+ if ((dataArray[i].type == LWM2M_TYPE_STRING || dataArray[i].type == LWM2M_TYPE_OPAQUE)
+ && dataArray[i].value.asBuffer.length > 0 && dataArray[i].value.asBuffer.length <= 3
+ && (strncmp((char*)dataArray[i].value.asBuffer.buffer, "U", dataArray[i].value.asBuffer.length) == 0
+ || strncmp((char*)dataArray[i].value.asBuffer.buffer, "UQ", dataArray[i].value.asBuffer.length) == 0
+ || strncmp((char*)dataArray[i].value.asBuffer.buffer, "S", dataArray[i].value.asBuffer.length) == 0
+ || strncmp((char*)dataArray[i].value.asBuffer.buffer, "SQ", dataArray[i].value.asBuffer.length) == 0
+ || strncmp((char*)dataArray[i].value.asBuffer.buffer, "US", dataArray[i].value.asBuffer.length) == 0
+ || strncmp((char*)dataArray[i].value.asBuffer.buffer, "UQS", dataArray[i].value.asBuffer.length) == 0))
+ {
+ strncpy(targetP->binding, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length);
+ result = COAP_204_CHANGED;
+ }
+ else
+ {
+ result = COAP_400_BAD_REQUEST;
+ }
+ break;
+
+ case LWM2M_SERVER_UPDATE_ID:
+ result = COAP_405_METHOD_NOT_ALLOWED;
+ break;
+
+ default:
+ return COAP_404_NOT_FOUND;
+ }
+ i++;
+ } while (i < numData && result == COAP_204_CHANGED);
+
+ return result;
}
-coap_status_t object_server_write(lwm2m_context_t * contextP,
- lwm2m_uri_t * uriP,
- char * buffer,
- int length)
+static uint8_t prv_server_execute(uint16_t instanceId,
+ uint16_t resourceId,
+ uint8_t * buffer,
+ int length,
+ lwm2m_object_t * objectP)
+
{
- if (!LWM2M_URI_IS_SET_INSTANCE(uriP))
- {
- return COAP_501_NOT_IMPLEMENTED;
- }
- else
- {
- lwm2m_server_t * serverP;
-
- serverP = (lwm2m_server_t *)lwm2m_list_find((lwm2m_list_t *)contextP->serverList, uriP->instanceId);
- if (serverP == NULL) return COAP_404_NOT_FOUND;
+ server_instance_t * targetP;
- if (!LWM2M_URI_IS_SET_RESOURCE(uriP))
- {
- return COAP_501_NOT_IMPLEMENTED;
- }
- else
- {
- switch (uriP->resourceId)
- {
- case RESOURCE_LIFETIME_ID:
- return COAP_501_NOT_IMPLEMENTED;
- case RESOURCE_MINPERIOD_ID:
- return COAP_404_NOT_FOUND;
- case RESOURCE_MAXPERIOD_ID:
- return COAP_404_NOT_FOUND;
- case RESOURCE_TIMEOUT_ID:
- return COAP_404_NOT_FOUND;
- case RESOURCE_STORING_ID:
- return COAP_501_NOT_IMPLEMENTED;
- case RESOURCE_BINDING_ID:
- return COAP_501_NOT_IMPLEMENTED;
- default:
- return COAP_405_METHOD_NOT_ALLOWED;
- }
- }
- }
-}
+ targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
+ if (NULL == targetP) return COAP_404_NOT_FOUND;
-coap_status_t object_server_execute(lwm2m_context_t * contextP,
- lwm2m_uri_t * uriP,
- char * buffer,
- int length)
-{
- lwm2m_server_t * serverP;
+ switch (resourceId)
+ {
+ case LWM2M_SERVER_DISABLE_ID:
+ // executed in core, if COAP_204_CHANGED is returned
+ return COAP_204_CHANGED;
- serverP = (lwm2m_server_t *)lwm2m_list_find((lwm2m_list_t *)contextP->serverList, uriP->instanceId);
- if (serverP == NULL) return COAP_404_NOT_FOUND;
+ case LWM2M_SERVER_UPDATE_ID:
+ // executed in core, if COAP_204_CHANGED is returned
+ return COAP_204_CHANGED;
- switch (uriP->resourceId)
- {
- case RESOURCE_DISABLE_ID:
- return COAP_404_NOT_FOUND;
- case RESOURCE_UPDATE_ID:
- return COAP_501_NOT_IMPLEMENTED;
default:
return COAP_405_METHOD_NOT_ALLOWED;
}
}
-coap_status_t object_server_create(lwm2m_context_t * contextP,
- lwm2m_uri_t * uriP,
- char * buffer,
- int length)
+static uint8_t prv_server_delete(uint16_t id,
+ lwm2m_object_t * objectP)
{
- lwm2m_server_t * serverP;
+ server_instance_t * serverInstance;
- serverP = (lwm2m_server_t *)lwm2m_list_find((lwm2m_list_t *)contextP->serverList, uriP->instanceId);
- if (serverP == NULL) return COAP_404_NOT_FOUND;
+ objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id, (lwm2m_list_t **)&serverInstance);
+ if (NULL == serverInstance) return COAP_404_NOT_FOUND;
- return COAP_501_NOT_IMPLEMENTED;
+ lwm2m_free(serverInstance);
+
+ return COAP_202_DELETED;
}
-coap_status_t object_server_delete(lwm2m_context_t * contextP,
- lwm2m_uri_t * uriP)
+static uint8_t prv_server_create(uint16_t instanceId,
+ int numData,
+ lwm2m_data_t * dataArray,
+ lwm2m_object_t * objectP)
{
- lwm2m_server_t * serverP;
+ server_instance_t * serverInstance;
+ uint8_t result;
+
+ serverInstance = (server_instance_t *)lwm2m_malloc(sizeof(server_instance_t));
+ if (NULL == serverInstance) return COAP_500_INTERNAL_SERVER_ERROR;
+ memset(serverInstance, 0, sizeof(server_instance_t));
- serverP = (lwm2m_server_t *)lwm2m_list_find((lwm2m_list_t *)contextP->serverList, uriP->instanceId);
- if (serverP == NULL) return COAP_404_NOT_FOUND;
+ serverInstance->instanceId = instanceId;
+ objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, serverInstance);
+
+ result = prv_server_write(instanceId, numData, dataArray, objectP);
- return COAP_501_NOT_IMPLEMENTED;
+ if (result != COAP_204_CHANGED)
+ {
+ (void)prv_server_delete(instanceId, objectP);
+ }
+ else
+ {
+ result = COAP_201_CREATED;
+ }
+
+ return result;
}
-coap_status_t object_security_create(lwm2m_context_t * contextP,
- lwm2m_uri_t * uriP,
- char * buffer,
- int length)
+lwm2m_object_t * get_server_object()
{
- lwm2m_server_t * serverP;
+ lwm2m_object_t * serverObj;
+
+ serverObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
+
+ if (NULL != serverObj)
+ {
+ server_instance_t * serverInstance;
+
+ memset(serverObj, 0, sizeof(lwm2m_object_t));
+
+ serverObj->objID = 1;
- serverP = (lwm2m_server_t *)lwm2m_list_find((lwm2m_list_t *)contextP->serverList, uriP->instanceId);
- if (serverP == NULL) return COAP_404_NOT_FOUND;
+ // Manually create an hardcoded server
+ serverInstance = (server_instance_t *)lwm2m_malloc(sizeof(server_instance_t));
+ if (NULL == serverInstance)
+ {
+ lwm2m_free(serverObj);
+ return NULL;
+ }
- return COAP_501_NOT_IMPLEMENTED;
+ memset(serverInstance, 0, sizeof(server_instance_t));
+ serverInstance->instanceId = 0;
+ serverInstance->shortServerId = 123;
+ serverInstance->lifetime = 300;
+ serverInstance->storing = false;
+ serverInstance->binding[0] = 'U';
+ serverObj->instanceList = LWM2M_LIST_ADD(serverObj->instanceList, serverInstance);
+
+ serverObj->readFunc = prv_server_read;
+ serverObj->writeFunc = prv_server_write;
+ serverObj->createFunc = prv_server_create;
+ serverObj->deleteFunc = prv_server_delete;
+ serverObj->executeFunc = prv_server_execute;
+ serverObj->discoverFunc = prv_server_discover;
+ }
+
+ return serverObj;
}
-coap_status_t object_security_delete(lwm2m_context_t * contextP,
- lwm2m_uri_t * uriP)
+void free_server_object(lwm2m_object_t * object)
{
- lwm2m_server_t * serverP;
-
- serverP = (lwm2m_server_t *)lwm2m_list_find((lwm2m_list_t *)contextP->serverList, uriP->instanceId);
- if (serverP == NULL) return COAP_404_NOT_FOUND;
-
- return COAP_501_NOT_IMPLEMENTED;
+ while (object->instanceList != NULL)
+ {
+ server_instance_t * serverInstance = (server_instance_t *)object->instanceList;
+ object->instanceList = object->instanceList->next;
+ lwm2m_free(serverInstance);
+ }
+ lwm2m_free(object);
}
-
-#endif