diff --git a/apps/oma-lwm2m/Makefile.oma-lwm2m b/apps/oma-lwm2m/Makefile.oma-lwm2m index 8445530ed..000147939 100644 --- a/apps/oma-lwm2m/Makefile.oma-lwm2m +++ b/apps/oma-lwm2m/Makefile.oma-lwm2m @@ -1,5 +1,13 @@ -oma-lwm2m_src = lwm2m-object.c lwm2m-engine.c \ - lwm2m-device.c lwm2m-server.c lwm2m-security.c \ - oma-tlv.c oma-tlv-reader.c oma-tlv-writer.c \ - lwm2m-plain-text.c +oma-lwm2m_src = \ + lwm2m-object.c \ + lwm2m-engine.c \ + lwm2m-device.c \ + lwm2m-server.c \ + lwm2m-security.c \ + oma-tlv.c \ + oma-tlv-reader.c \ + oma-tlv-writer.c \ + lwm2m-plain-text.c \ + lwm2m-json.c \ + # CFLAGS += -DHAVE_OMA_LWM2M=1 diff --git a/apps/oma-lwm2m/lwm2m-engine.c b/apps/oma-lwm2m/lwm2m-engine.c index 3728e3505..0fe86bbbb 100644 --- a/apps/oma-lwm2m/lwm2m-engine.c +++ b/apps/oma-lwm2m/lwm2m-engine.c @@ -46,6 +46,7 @@ #include "lwm2m-object.h" #include "lwm2m-device.h" #include "lwm2m-plain-text.h" +#include "lwm2m-json.h" #include "rest-engine.h" #include "er-coap-constants.h" #include "er-coap-engine.h" @@ -727,6 +728,10 @@ lwm2m_engine_select_writer(lwm2m_context_t *context, unsigned int accept) case TEXT_PLAIN: context->writer = &lwm2m_plain_text_writer; break; + case LWM2M_JSON: + case APPLICATION_JSON: + context->writer = &lwm2m_json_writer; + break; default: PRINTF("Unknown Accept type %u, using LWM2M plain text\n", accept); context->writer = &lwm2m_plain_text_writer; diff --git a/apps/oma-lwm2m/lwm2m-json.c b/apps/oma-lwm2m/lwm2m-json.c new file mode 100644 index 000000000..8924ceb8c --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-json.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2016, Eistec AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M JSON writer + * \author + * Joakim Nohlgård + */ + +#include "lwm2m-object.h" +#include "lwm2m-json.h" +#include "lwm2m-plain-text.h" +#include +#include +#include +#include + +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +static size_t +write_boolean(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int value) +{ + int len = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"bv\":%s}]}\n", ctx->resource_id, value ? "true" : "false"); + if((len < 0) || (len >= outlen)) { + return 0; + } + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_int(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value) +{ + int len = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"v\":%" PRId32 "}]}\n", ctx->resource_id, value); + if((len < 0) || (len >= outlen)) { + return 0; + } + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_float32fix(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value, int bits) +{ + size_t len = 0; + int res; + res = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"v\":", ctx->resource_id); + if(res <= 0 || res >= outlen) { + return 0; + } + len += res; + outlen -= res; + res = lwm2m_plain_text_write_float32fix(&outbuf[len], outlen, value, bits); + if((res <= 0) || (res >= outlen)) { + return 0; + } + len += res; + outlen -= res; + res = snprintf((char *)&outbuf[len], outlen, "}]}\n"); + if((res <= 0) || (res >= outlen)) { + return 0; + } + len += res; + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_string(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + const char *value, size_t stringlen) +{ + size_t i; + size_t len = 0; + int res; + PRINTF("{\"e\":[{\"n\":\"%u\",\"sv\":\"", ctx->resource_id); + res = snprintf((char *)outbuf, outlen, "{\"e\":[{\"n\":\"%u\",\"sv\":\"", ctx->resource_id); + if(res < 0 || res >= outlen) { + return 0; + } + len += res; + for (i = 0; i < stringlen && len < outlen; ++i) { + /* Escape special characters */ + /* TODO: Handle UTF-8 strings */ + if(value[i] < '\x20') { + PRINTF("\\x%x", value[i]); + res = snprintf((char *)&outbuf[len], outlen - len, "\\x%x", value[i]); + if((res < 0) || (res >= (outlen - len))) { + return 0; + } + len += res; + continue; + } else if(value[i] == '"' || value[i] == '\\') { + PRINTF("\\"); + outbuf[len] = '\\'; + ++len; + if(len >= outlen) { + return 0; + } + } + PRINTF("%c", value[i]); + outbuf[len] = value[i]; + ++len; + if(len >= outlen) { + return 0; + } + } + PRINTF("\"}]}\n"); + res = snprintf((char *)&outbuf[len], outlen - len, "\"}]}\n"); + if((res < 0) || (res >= (outlen - len))) { + return 0; + } + len += res; + return len; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_writer_t lwm2m_json_writer = { + write_int, + write_string, + write_float32fix, + write_boolean +}; +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-json.h b/apps/oma-lwm2m/lwm2m-json.h new file mode 100644 index 000000000..bc1a1e32a --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-json.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, Eistec AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M JSON writer + * \author + * Joakim Nohlgård + */ + +#ifndef LWM2M_JSON_H_ +#define LWM2M_JSON_H_ + +#include "lwm2m-object.h" + +extern const lwm2m_writer_t lwm2m_json_writer; + +#endif /* LWM2M_JSON_H_ */ +/** @} */