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.
object_server.c
- Committer:
- terence zhang
- Date:
- 2017-04-28
- Revision:
- 4:35892233a85d
- Parent:
- 2:5a8853c481ad
File content as of revision 4:35892233a85d:
/*******************************************************************************
*
* 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
* Julien Vermillard, Sierra Wireless
* Bosch Software Innovations GmbH - Please refer to git log
* Pascal Rieux - Please refer to git log
*
*******************************************************************************/
/*
* Resources:
*
* Name | ID | Operations | Instances | Mandatory | Type | Range | Units |
* Short ID | 0 | R | Single | Yes | Integer | 1-65535 | |
* Lifetime | 1 | R/W | Single | Yes | Integer | | s |
* Default Min Period | 2 | R/W | Single | No | Integer | | s |
* 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 | Boolean | | |
* Binding | 7 | R/W | Single | Yes | String | | |
* Registration Update | 8 | E | Single | Yes | | | |
*
*/
#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;
// 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;
}
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;
// is the server asking for the full object ?
if (*numDataP == 0)
{
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
{
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;
}
}
}
return result;
}
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)
{
*data = value;
result = COAP_204_CHANGED;
}
else
{
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)
{
if (0 < value && value <= 0xFFFF)
{
targetP->shortServerId = value;
}
else
{
result = COAP_406_NOT_ACCEPTABLE;
}
}
}
break;
case LWM2M_SERVER_LIFETIME_ID:
result = prv_set_int_value(dataArray + i, (uint32_t *)&(targetP->lifetime));
break;
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;
}
static uint8_t prv_server_execute(uint16_t instanceId,
uint16_t resourceId,
uint8_t * buffer,
int length,
lwm2m_object_t * objectP)
{
server_instance_t * targetP;
targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
switch (resourceId)
{
case LWM2M_SERVER_DISABLE_ID:
// executed in core, if COAP_204_CHANGED is returned
return COAP_204_CHANGED;
case LWM2M_SERVER_UPDATE_ID:
// executed in core, if COAP_204_CHANGED is returned
return COAP_204_CHANGED;
default:
return COAP_405_METHOD_NOT_ALLOWED;
}
}
static uint8_t prv_server_delete(uint16_t id,
lwm2m_object_t * objectP)
{
server_instance_t * serverInstance;
objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id, (lwm2m_list_t **)&serverInstance);
if (NULL == serverInstance) return COAP_404_NOT_FOUND;
lwm2m_free(serverInstance);
return COAP_202_DELETED;
}
static uint8_t prv_server_create(uint16_t instanceId,
int numData,
lwm2m_data_t * dataArray,
lwm2m_object_t * objectP)
{
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));
serverInstance->instanceId = instanceId;
objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, serverInstance);
result = prv_server_write(instanceId, numData, dataArray, objectP);
if (result != COAP_204_CHANGED)
{
(void)prv_server_delete(instanceId, objectP);
}
else
{
result = COAP_201_CREATED;
}
return result;
}
lwm2m_object_t * get_server_object()
{
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;
// Manually create an hardcoded server
serverInstance = (server_instance_t *)lwm2m_malloc(sizeof(server_instance_t));
if (NULL == serverInstance)
{
lwm2m_free(serverObj);
return NULL;
}
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;
}
void free_server_object(lwm2m_object_t * object)
{
while (object->instanceList != NULL)
{
server_instance_t * serverInstance = (server_instance_t *)object->instanceList;
object->instanceList = object->instanceList->next;
lwm2m_free(serverInstance);
}
lwm2m_free(object);
}