oma-lwm2m: Use Accept header to determine the writer object for the content
This commit is contained in:
parent
8d6a290382
commit
9832b356ba
1 changed files with 82 additions and 27 deletions
|
@ -50,6 +50,7 @@
|
|||
#include "er-coap-constants.h"
|
||||
#include "er-coap-engine.h"
|
||||
#include "oma-tlv.h"
|
||||
#include "oma-tlv-reader.h"
|
||||
#include "oma-tlv-writer.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include <stdio.h>
|
||||
|
@ -707,6 +708,59 @@ write_rd_json_data(const lwm2m_context_t *context,
|
|||
return rdlen;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Set the writer pointer to the proper writer based on the Accept: header
|
||||
*
|
||||
* @param[in] context LWM2M context to operate on
|
||||
* @param[in] accept Accept type number from CoAP headers
|
||||
*
|
||||
* @return The content type of the response if the selected writer is used
|
||||
*/
|
||||
static unsigned int
|
||||
lwm2m_engine_select_writer(lwm2m_context_t *context, unsigned int accept)
|
||||
{
|
||||
switch(accept) {
|
||||
case LWM2M_TLV:
|
||||
context->writer = &oma_tlv_writer;
|
||||
break;
|
||||
case LWM2M_TEXT_PLAIN:
|
||||
case TEXT_PLAIN:
|
||||
context->writer = &lwm2m_plain_text_writer;
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unknown Accept type %u, using LWM2M plain text\n", accept);
|
||||
context->writer = &lwm2m_plain_text_writer;
|
||||
/* Set the response type to plain text */
|
||||
accept = LWM2M_TEXT_PLAIN;
|
||||
break;
|
||||
}
|
||||
return accept;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Set the reader pointer to the proper reader based on the Content-format: header
|
||||
*
|
||||
* @param[in] context LWM2M context to operate on
|
||||
* @param[in] content_format Content-type type number from CoAP headers
|
||||
*/
|
||||
static void
|
||||
lwm2m_engine_select_reader(lwm2m_context_t *context, unsigned int content_format)
|
||||
{
|
||||
switch(content_format) {
|
||||
case LWM2M_TLV:
|
||||
context->reader = &oma_tlv_reader;
|
||||
break;
|
||||
case LWM2M_TEXT_PLAIN:
|
||||
case TEXT_PLAIN:
|
||||
context->reader = &lwm2m_plain_text_reader;
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unknown content type %u, using LWM2M plain text\n", accept);
|
||||
context->reader = &lwm2m_plain_text_reader;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
lwm2m_engine_handler(const lwm2m_object_t *object,
|
||||
void *request, void *response,
|
||||
|
@ -716,6 +770,8 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
|||
int len;
|
||||
const char *url;
|
||||
unsigned int format;
|
||||
unsigned int accept;
|
||||
unsigned int content_type;
|
||||
int depth;
|
||||
lwm2m_context_t context;
|
||||
rest_resource_flags_t method;
|
||||
|
@ -734,11 +790,19 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
|||
/* CoAP content format text plain - assume LWM2M text plain */
|
||||
format = LWM2M_TEXT_PLAIN;
|
||||
}
|
||||
if(!REST.get_header_accept(request, &accept)) {
|
||||
PRINTF("No Accept header, using same as Content-format...\n");
|
||||
accept = format;
|
||||
}
|
||||
|
||||
depth = lwm2m_engine_parse_context(object, url, len, &context);
|
||||
PRINTF("Context: %u/%u/%u found: %d\n", context.object_id,
|
||||
context.object_instance_id, context.resource_id, depth);
|
||||
|
||||
/* Select reader and writer based on provided Content type and Accept headers */
|
||||
lwm2m_engine_select_reader(&context, format);
|
||||
content_type = lwm2m_engine_select_writer(&context, accept);
|
||||
|
||||
#if (DEBUG) & DEBUG_PRINT
|
||||
/* for debugging */
|
||||
if(method == METHOD_GET) {
|
||||
|
@ -861,7 +925,7 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
|||
|
||||
if(depth == 3) {
|
||||
const lwm2m_resource_t *resource = get_resource(instance, &context);
|
||||
size_t tlvlen = 0;
|
||||
size_t content_len = 0;
|
||||
if(resource == NULL) {
|
||||
PRINTF("Error - do not have resource %d\n", context.resource_id);
|
||||
REST.set_response_status(response, NOT_FOUND_4_04);
|
||||
|
@ -879,9 +943,9 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
|||
context.reader = &lwm2m_plain_text_reader;
|
||||
PRINTF("PUT Callback with data: '%.*s'\n", plen, data);
|
||||
/* no specific reader for plain text */
|
||||
tlvlen = resource->value.callback.write(&context, data, plen,
|
||||
content_len = resource->value.callback.write(&context, data, plen,
|
||||
buffer, preferred_size);
|
||||
PRINTF("tlvlen:%u\n", (unsigned int)tlvlen);
|
||||
PRINTF("content_len:%u\n", (unsigned int)content_len);
|
||||
REST.set_response_status(response, CHANGED_2_04);
|
||||
} else {
|
||||
PRINTF("PUT callback with format %d\n", format);
|
||||
|
@ -899,48 +963,39 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
|||
} else if(method == METHOD_GET) {
|
||||
if(lwm2m_object_is_resource_string(resource)) {
|
||||
const uint8_t *value;
|
||||
uint16_t len;
|
||||
value = lwm2m_object_get_resource_string(resource, &context);
|
||||
len = lwm2m_object_get_resource_strlen(resource, &context);
|
||||
if(value != NULL) {
|
||||
uint16_t len = lwm2m_object_get_resource_strlen(resource, &context);
|
||||
PRINTF("Get string value: %.*s\n", (int)len, (char *)value);
|
||||
/* TODO check format */
|
||||
REST.set_response_payload(response, value, len);
|
||||
REST.set_header_content_type(response, LWM2M_TEXT_PLAIN);
|
||||
/* Done */
|
||||
return;
|
||||
content_len = context.writer->write_string(&context, buffer,
|
||||
preferred_size, (const char *)value, len);
|
||||
}
|
||||
} else if(lwm2m_object_is_resource_int(resource)) {
|
||||
int32_t value;
|
||||
if(lwm2m_object_get_resource_int(resource, &context, &value)) {
|
||||
/* export INT as TLV */
|
||||
tlvlen = oma_tlv_write_int32(resource->id, value, buffer, preferred_size);
|
||||
PRINTF("Exporting int as TLV: %" PRId32 ", len: %u\n",
|
||||
value, (unsigned int)tlvlen);
|
||||
content_len = context.writer->write_int(&context, buffer, preferred_size, value);
|
||||
}
|
||||
} else if(lwm2m_object_is_resource_floatfix(resource)) {
|
||||
int32_t value;
|
||||
if(lwm2m_object_get_resource_floatfix(resource, &context, &value)) {
|
||||
/* export FLOATFIX as TLV */
|
||||
/* export FLOATFIX */
|
||||
PRINTF("Exporting %d-bit fix as float: %" PRId32 "\n",
|
||||
LWM2M_FLOAT32_BITS, value);
|
||||
tlvlen = oma_tlv_write_float32(resource->id,
|
||||
value, LWM2M_FLOAT32_BITS,
|
||||
buffer, preferred_size);
|
||||
PRINTF("Exporting as TLV: len:%u\n", (unsigned int)tlvlen);
|
||||
content_len = context.writer->write_float32fix(&context, buffer,
|
||||
preferred_size, value, LWM2M_FLOAT32_BITS);
|
||||
}
|
||||
} else if(lwm2m_object_is_resource_callback(resource)) {
|
||||
if(resource->value.callback.read != NULL) {
|
||||
tlvlen = resource->value.callback.read(&context,
|
||||
content_len = resource->value.callback.read(&context,
|
||||
buffer, preferred_size);
|
||||
} else {
|
||||
REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(tlvlen > 0) {
|
||||
REST.set_response_payload(response, buffer, tlvlen);
|
||||
REST.set_header_content_type(response, LWM2M_TLV);
|
||||
if(content_len > 0) {
|
||||
REST.set_response_payload(response, buffer, content_len);
|
||||
REST.set_header_content_type(response, content_type);
|
||||
} else {
|
||||
/* failed to produce output - it is an internal error */
|
||||
REST.set_response_status(response, INTERNAL_SERVER_ERROR_5_00);
|
||||
|
@ -952,7 +1007,7 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
|||
const uint8_t *data;
|
||||
int plen = REST.get_request_payload(request, &data);
|
||||
PRINTF("Execute Callback with data: '%.*s'\n", plen, data);
|
||||
tlvlen = resource->value.callback.exec(&context,
|
||||
content_len = resource->value.callback.exec(&context,
|
||||
data, plen,
|
||||
buffer, preferred_size);
|
||||
REST.set_response_status(response, CHANGED_2_04);
|
||||
|
@ -973,7 +1028,7 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
|||
REST.set_response_status(response, NOT_FOUND_4_04);
|
||||
} else {
|
||||
int rdlen;
|
||||
if(format == APPLICATION_LINK_FORMAT) {
|
||||
if(accept == APPLICATION_LINK_FORMAT) {
|
||||
rdlen = write_rd_link_data(object, instance,
|
||||
(char *)buffer, preferred_size);
|
||||
} else {
|
||||
|
@ -986,10 +1041,10 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
|||
return;
|
||||
}
|
||||
REST.set_response_payload(response, buffer, rdlen);
|
||||
if(format == APPLICATION_LINK_FORMAT) {
|
||||
if(accept == APPLICATION_LINK_FORMAT) {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT);
|
||||
} else {
|
||||
REST.set_header_content_type(response, REST.type.APPLICATION_JSON);
|
||||
REST.set_header_content_type(response, LWM2M_JSON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue