Merge pull request #1652 from gebart/pr/lwm2m-accept
oma-lwm2m: Use Accept header to determine writer object
This commit is contained in:
commit
2ad6d18c9d
|
@ -50,6 +50,7 @@
|
||||||
#include "er-coap-constants.h"
|
#include "er-coap-constants.h"
|
||||||
#include "er-coap-engine.h"
|
#include "er-coap-engine.h"
|
||||||
#include "oma-tlv.h"
|
#include "oma-tlv.h"
|
||||||
|
#include "oma-tlv-reader.h"
|
||||||
#include "oma-tlv-writer.h"
|
#include "oma-tlv-writer.h"
|
||||||
#include "net/ipv6/uip-ds6.h"
|
#include "net/ipv6/uip-ds6.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -707,6 +708,59 @@ write_rd_json_data(const lwm2m_context_t *context,
|
||||||
return rdlen;
|
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
|
void
|
||||||
lwm2m_engine_handler(const lwm2m_object_t *object,
|
lwm2m_engine_handler(const lwm2m_object_t *object,
|
||||||
void *request, void *response,
|
void *request, void *response,
|
||||||
|
@ -716,6 +770,8 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
||||||
int len;
|
int len;
|
||||||
const char *url;
|
const char *url;
|
||||||
unsigned int format;
|
unsigned int format;
|
||||||
|
unsigned int accept;
|
||||||
|
unsigned int content_type;
|
||||||
int depth;
|
int depth;
|
||||||
lwm2m_context_t context;
|
lwm2m_context_t context;
|
||||||
rest_resource_flags_t method;
|
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 */
|
/* CoAP content format text plain - assume LWM2M text plain */
|
||||||
format = 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);
|
depth = lwm2m_engine_parse_context(object, url, len, &context);
|
||||||
PRINTF("Context: %u/%u/%u found: %d\n", context.object_id,
|
PRINTF("Context: %u/%u/%u found: %d\n", context.object_id,
|
||||||
context.object_instance_id, context.resource_id, depth);
|
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
|
#if (DEBUG) & DEBUG_PRINT
|
||||||
/* for debugging */
|
/* for debugging */
|
||||||
if(method == METHOD_GET) {
|
if(method == METHOD_GET) {
|
||||||
|
@ -861,7 +925,7 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
||||||
|
|
||||||
if(depth == 3) {
|
if(depth == 3) {
|
||||||
const lwm2m_resource_t *resource = get_resource(instance, &context);
|
const lwm2m_resource_t *resource = get_resource(instance, &context);
|
||||||
size_t tlvlen = 0;
|
size_t content_len = 0;
|
||||||
if(resource == NULL) {
|
if(resource == NULL) {
|
||||||
PRINTF("Error - do not have resource %d\n", context.resource_id);
|
PRINTF("Error - do not have resource %d\n", context.resource_id);
|
||||||
REST.set_response_status(response, NOT_FOUND_4_04);
|
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;
|
context.reader = &lwm2m_plain_text_reader;
|
||||||
PRINTF("PUT Callback with data: '%.*s'\n", plen, data);
|
PRINTF("PUT Callback with data: '%.*s'\n", plen, data);
|
||||||
/* no specific reader for plain text */
|
/* 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);
|
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);
|
REST.set_response_status(response, CHANGED_2_04);
|
||||||
} else {
|
} else {
|
||||||
PRINTF("PUT callback with format %d\n", format);
|
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) {
|
} else if(method == METHOD_GET) {
|
||||||
if(lwm2m_object_is_resource_string(resource)) {
|
if(lwm2m_object_is_resource_string(resource)) {
|
||||||
const uint8_t *value;
|
const uint8_t *value;
|
||||||
uint16_t len;
|
|
||||||
value = lwm2m_object_get_resource_string(resource, &context);
|
value = lwm2m_object_get_resource_string(resource, &context);
|
||||||
len = lwm2m_object_get_resource_strlen(resource, &context);
|
|
||||||
if(value != NULL) {
|
if(value != NULL) {
|
||||||
|
uint16_t len = lwm2m_object_get_resource_strlen(resource, &context);
|
||||||
PRINTF("Get string value: %.*s\n", (int)len, (char *)value);
|
PRINTF("Get string value: %.*s\n", (int)len, (char *)value);
|
||||||
/* TODO check format */
|
content_len = context.writer->write_string(&context, buffer,
|
||||||
REST.set_response_payload(response, value, len);
|
preferred_size, (const char *)value, len);
|
||||||
REST.set_header_content_type(response, LWM2M_TEXT_PLAIN);
|
|
||||||
/* Done */
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else if(lwm2m_object_is_resource_int(resource)) {
|
} else if(lwm2m_object_is_resource_int(resource)) {
|
||||||
int32_t value;
|
int32_t value;
|
||||||
if(lwm2m_object_get_resource_int(resource, &context, &value)) {
|
if(lwm2m_object_get_resource_int(resource, &context, &value)) {
|
||||||
/* export INT as TLV */
|
content_len = context.writer->write_int(&context, buffer, preferred_size, value);
|
||||||
tlvlen = oma_tlv_write_int32(resource->id, value, buffer, preferred_size);
|
|
||||||
PRINTF("Exporting int as TLV: %" PRId32 ", len: %u\n",
|
|
||||||
value, (unsigned int)tlvlen);
|
|
||||||
}
|
}
|
||||||
} else if(lwm2m_object_is_resource_floatfix(resource)) {
|
} else if(lwm2m_object_is_resource_floatfix(resource)) {
|
||||||
int32_t value;
|
int32_t value;
|
||||||
if(lwm2m_object_get_resource_floatfix(resource, &context, &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",
|
PRINTF("Exporting %d-bit fix as float: %" PRId32 "\n",
|
||||||
LWM2M_FLOAT32_BITS, value);
|
LWM2M_FLOAT32_BITS, value);
|
||||||
tlvlen = oma_tlv_write_float32(resource->id,
|
content_len = context.writer->write_float32fix(&context, buffer,
|
||||||
value, LWM2M_FLOAT32_BITS,
|
preferred_size, value, LWM2M_FLOAT32_BITS);
|
||||||
buffer, preferred_size);
|
|
||||||
PRINTF("Exporting as TLV: len:%u\n", (unsigned int)tlvlen);
|
|
||||||
}
|
}
|
||||||
} else if(lwm2m_object_is_resource_callback(resource)) {
|
} else if(lwm2m_object_is_resource_callback(resource)) {
|
||||||
if(resource->value.callback.read != NULL) {
|
if(resource->value.callback.read != NULL) {
|
||||||
tlvlen = resource->value.callback.read(&context,
|
content_len = resource->value.callback.read(&context,
|
||||||
buffer, preferred_size);
|
buffer, preferred_size);
|
||||||
} else {
|
} else {
|
||||||
REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05);
|
REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(tlvlen > 0) {
|
if(content_len > 0) {
|
||||||
REST.set_response_payload(response, buffer, tlvlen);
|
REST.set_response_payload(response, buffer, content_len);
|
||||||
REST.set_header_content_type(response, LWM2M_TLV);
|
REST.set_header_content_type(response, content_type);
|
||||||
} else {
|
} else {
|
||||||
/* failed to produce output - it is an internal error */
|
/* failed to produce output - it is an internal error */
|
||||||
REST.set_response_status(response, INTERNAL_SERVER_ERROR_5_00);
|
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;
|
const uint8_t *data;
|
||||||
int plen = REST.get_request_payload(request, &data);
|
int plen = REST.get_request_payload(request, &data);
|
||||||
PRINTF("Execute Callback with data: '%.*s'\n", plen, 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,
|
data, plen,
|
||||||
buffer, preferred_size);
|
buffer, preferred_size);
|
||||||
REST.set_response_status(response, CHANGED_2_04);
|
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);
|
REST.set_response_status(response, NOT_FOUND_4_04);
|
||||||
} else {
|
} else {
|
||||||
int rdlen;
|
int rdlen;
|
||||||
if(format == APPLICATION_LINK_FORMAT) {
|
if(accept == APPLICATION_LINK_FORMAT) {
|
||||||
rdlen = write_rd_link_data(object, instance,
|
rdlen = write_rd_link_data(object, instance,
|
||||||
(char *)buffer, preferred_size);
|
(char *)buffer, preferred_size);
|
||||||
} else {
|
} else {
|
||||||
|
@ -986,10 +1041,10 @@ lwm2m_engine_handler(const lwm2m_object_t *object,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
REST.set_response_payload(response, buffer, rdlen);
|
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);
|
REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT);
|
||||||
} else {
|
} 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