Correct handling of CoAP PUT and POST

Signed-off-by: David Navarro <david.navarro@intel.com>
This commit is contained in:
David Navarro 2014-04-16 15:16:07 +02:00
parent f5d0ddd1ef
commit c4c4452e48
5 changed files with 140 additions and 92 deletions

9
TODO
View File

@ -1,10 +1,5 @@
LWM2M Features
--------------
- Write/Create mechanism and object interface:
Write can be done using either a CoAP PUT for a single resource or a CoAP POST for
multiple resources just like a create.
This may impact the object interface.
- LWM2M Security and LWM2M Server Objects:
Implement these two objects in core as interfaces to lwm2m_server_t instances.
@ -51,7 +46,9 @@ LWM2M Features
- Switch to void* parameters in lwm2m_list_* APIs
- Change object interface to hide the whole TLV mechanism
Useful when the core will support JSON.
- Utility functions to easily implements objects
These would take care of the whole TLV mechanism.
The utility will just use read and write individual resources. Either statically or
throught callbacks. See [https://github.com/01org/libdmclient]/tests/mgtobj/utils/static_mo_util.h

View File

@ -86,8 +86,10 @@ lwm2m_uri_t * lwm2m_decode_uri(multi_option_t *uriPath);
// defined in objects.c
coap_status_t object_read(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, char ** bufferP, int * lengthP);
coap_status_t object_write(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, char * buffer, int length);
coap_status_t object_create_execute(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, char * buffer, int length);
coap_status_t object_create(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, char * buffer, int length);
coap_status_t object_execute(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, char * buffer, int length);
coap_status_t object_delete(lwm2m_context_t * contextP, lwm2m_uri_t * uriP);
bool object_isInstanceNew(lwm2m_context_t * contextP, uint16_t objectId, uint16_t instanceId);
int prv_getRegisterPayload(lwm2m_context_t * contextP, char * buffer, size_t length);
// defined in object_server.c

View File

@ -65,17 +65,10 @@ coap_status_t handle_dm_request(lwm2m_context_t * contextP,
break;
case COAP_POST:
{
//is the instanceId set in the requested uri?
bool isInstanceSet = uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID;
result = object_create_execute(contextP, uriP, message->payload, message->payload_len);
if (result == COAP_201_CREATED
|| result == COAP_204_CHANGED)
if (!LWM2M_URI_IS_SET_INSTANCE(uriP))
{
//create & instanceId not in the uri before processing the request
//so we have assigned an Id for the new Instance & must send it back
if ((result == COAP_201_CREATED)
&& !isInstanceSet)
result = object_create(contextP, uriP, message->payload, message->payload_len);
if (result == COAP_201_CREATED)
{
//longest uri is /65535/65535 =12 + 1 (null) chars
char location_path[12] = "";
@ -94,16 +87,45 @@ coap_status_t handle_dm_request(lwm2m_context_t * contextP,
coap_set_header_location_path(response, location_path);
}
}
else if (!LWM2M_URI_IS_SET_RESOURCE(uriP))
{
if (object_isInstanceNew(contextP, uriP->objectId, uriP->instanceId))
{
result = object_create(contextP, uriP, message->payload, message->payload_len);
}
else
{
result = object_write(contextP, uriP, message->payload, message->payload_len);
}
}
else
{
result = object_execute(contextP, uriP, message->payload, message->payload_len);
}
}
break;
case COAP_PUT:
{
result = object_write(contextP, uriP, message->payload, message->payload_len);
if (LWM2M_URI_IS_SET_INSTANCE(uriP) && LWM2M_URI_IS_SET_RESOURCE(uriP))
{
result = object_write(contextP, uriP, message->payload, message->payload_len);
}
else
{
result = BAD_REQUEST_4_00;
}
}
break;
case COAP_DELETE:
{
result = object_delete(contextP, uriP);
if (LWM2M_URI_IS_SET_INSTANCE(uriP) && !LWM2M_URI_IS_SET_RESOURCE(uriP))
{
result = object_delete(contextP, uriP);
}
else
{
result = BAD_REQUEST_4_00;
}
}
break;
default:
@ -246,9 +268,18 @@ int lwm2m_dm_write(lwm2m_context_t * contextP,
return COAP_400_BAD_REQUEST;
}
return prv_make_operation(contextP, clientID, uriP,
COAP_PUT, buffer, length,
callback, userData);
if (LWM2M_URI_IS_SET_RESOURCE(uriP))
{
return prv_make_operation(contextP, clientID, uriP,
COAP_PUT, buffer, length,
callback, userData);
}
else
{
return prv_make_operation(contextP, clientID, uriP,
COAP_POST, buffer, length,
callback, userData);
}
}
int lwm2m_dm_execute(lwm2m_context_t * contextP,

View File

@ -103,11 +103,6 @@ coap_status_t object_write(lwm2m_context_t * contextP,
{
lwm2m_object_t * targetP;
if (0 == (uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID))
{
return BAD_REQUEST_4_00;
}
targetP = prv_find_object(contextP, uriP->objectId);
if (NULL == targetP)
@ -124,81 +119,77 @@ coap_status_t object_write(lwm2m_context_t * contextP,
}
}
coap_status_t object_create_execute(lwm2m_context_t * contextP,
lwm2m_uri_t * uriP,
char * buffer,
int length)
coap_status_t object_execute(lwm2m_context_t * contextP,
lwm2m_uri_t * uriP,
char * buffer,
int length)
{
if ((uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID) != 0
&& (uriP->flag & LWM2M_URI_FLAG_RESOURCE_ID) != 0)
switch (uriP->objectId)
{
// This is an execute
switch (uriP->objectId)
case LWM2M_SECURITY_OBJECT_ID:
return NOT_FOUND_4_04;
case LWM2M_SERVER_OBJECT_ID:
return object_server_execute(contextP, uriP, buffer, length);
default:
{
case LWM2M_SECURITY_OBJECT_ID:
return NOT_FOUND_4_04;
lwm2m_object_t * targetP;
case LWM2M_SERVER_OBJECT_ID:
return object_server_execute(contextP, uriP, buffer, length);
targetP = prv_find_object(contextP, uriP->objectId);
default:
if (NULL == targetP)
{
lwm2m_object_t * targetP;
targetP = prv_find_object(contextP, uriP->objectId);
if (NULL == targetP)
{
return NOT_FOUND_4_04;
}
if (NULL == targetP->executeFunc)
{
return METHOD_NOT_ALLOWED_4_05;
}
return targetP->executeFunc(uriP, buffer, length, targetP);
return NOT_FOUND_4_04;
}
if (NULL == targetP->executeFunc)
{
return METHOD_NOT_ALLOWED_4_05;
}
return targetP->executeFunc(uriP, buffer, length, targetP);
}
}
else if ((uriP->flag & LWM2M_URI_FLAG_RESOURCE_ID) == 0
&& length != 0)
}
coap_status_t object_create(lwm2m_context_t * contextP,
lwm2m_uri_t * uriP,
char * buffer,
int length)
{
if (length == 0 || buffer == 0)
{
// This is a create
if (length == 0 || buffer == 0)
return BAD_REQUEST_4_00;
}
switch (uriP->objectId)
{
case LWM2M_SECURITY_OBJECT_ID:
return object_security_create(contextP, uriP, buffer, length);
case LWM2M_SERVER_OBJECT_ID:
return object_server_create(contextP, uriP, buffer, length);
default:
{
return BAD_REQUEST_4_00;
}
lwm2m_object_t * targetP;
switch (uriP->objectId)
{
case LWM2M_SECURITY_OBJECT_ID:
return object_security_create(contextP, uriP, buffer, length);
targetP = prv_find_object(contextP, uriP->objectId);
case LWM2M_SERVER_OBJECT_ID:
return object_server_create(contextP, uriP, buffer, length);
default:
if (NULL == targetP)
{
lwm2m_object_t * targetP;
targetP = prv_find_object(contextP, uriP->objectId);
if (NULL == targetP)
{
return NOT_FOUND_4_04;
}
if (NULL == targetP->createFunc)
{
return METHOD_NOT_ALLOWED_4_05;
}
return targetP->createFunc(uriP, buffer, length, targetP);
return NOT_FOUND_4_04;
}
if (NULL == targetP->createFunc)
{
return METHOD_NOT_ALLOWED_4_05;
}
return targetP->createFunc(uriP, buffer, length, targetP);
}
}
else return BAD_REQUEST_4_00;
}
coap_status_t object_delete(lwm2m_context_t * contextP,
@ -216,12 +207,6 @@ coap_status_t object_delete(lwm2m_context_t * contextP,
{
lwm2m_object_t * targetP;
if ((uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0
|| (uriP->flag & LWM2M_URI_FLAG_RESOURCE_ID) != 0)
{
return BAD_REQUEST_4_00;
}
targetP = prv_find_object(contextP, uriP->objectId);
if (NULL == targetP)
@ -238,6 +223,39 @@ coap_status_t object_delete(lwm2m_context_t * contextP,
}
}
bool object_isInstanceNew(lwm2m_context_t * contextP,
uint16_t objectId,
uint16_t instanceId)
{
switch (objectId)
{
case LWM2M_SECURITY_OBJECT_ID:
case LWM2M_SERVER_OBJECT_ID:
if (NULL != lwm2m_list_find((lwm2m_list_t *)contextP->serverList, instanceId))
{
return false;
}
break;
default:
{
lwm2m_object_t * targetP;
targetP = prv_find_object(contextP, objectId);
if (targetP != NULL)
{
if (NULL != lwm2m_list_find(targetP->instanceList, instanceId))
{
return false;
}
}
}
break;
}
return true;
}
int prv_getRegisterPayload(lwm2m_context_t * contextP,
char * buffer,
size_t length)

View File

@ -200,7 +200,7 @@ static uint8_t prv_write(lwm2m_uri_t * uriP,
targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, uriP->instanceId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) return COAP_501_NOT_IMPLEMENTED;
if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_501_NOT_IMPLEMENTED;
switch (uriP->resourceId)
{