1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/sys/senml/cbor.c
Silke Hofstra 9d61bdbb06 sys/senml: add SenML modules
Add a basic SenML module and submodules with support for:

- Encoding SenML values as CBOR using NanoCBOR.
- Converting from Phydat to SenML.
- Reading and encoding SAUL sensors.
2022-02-11 12:38:21 +01:00

156 lines
5.2 KiB
C

/*
* Copyright (C) 2021 Silke Hofstra
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
#include "senml.h"
#include "senml/cbor.h"
#include "nanocbor/nanocbor.h"
static int senml_encode_numeric_cbor(nanocbor_encoder_t *enc, const senml_numeric_t *v)
{
switch (v->type) {
case SENML_TYPE_NUMERIC_FLOAT:
return nanocbor_fmt_float(enc, v->value.f);
case SENML_TYPE_NUMERIC_DOUBLE:
return nanocbor_fmt_double(enc, v->value.d);
case SENML_TYPE_NUMERIC_INT:
return nanocbor_fmt_int(enc, v->value.i);
case SENML_TYPE_NUMERIC_UINT:
return nanocbor_fmt_uint(enc, v->value.u);
case SENML_TYPE_NUMERIC_DECFRAC:
return nanocbor_fmt_decimal_frac(enc, v->value.df.e, v->value.df.m);
default:
return 0;
}
}
static int senml_encode_start_cbor(nanocbor_encoder_t *enc, const senml_attr_t *attr,
bool sum_value)
{
int n = nanocbor_fmt_map(enc, !sum_value
+ (attr->base_name != NULL)
+ (attr->base_time.value.u != 0)
+ (attr->base_unit != SENML_UNIT_NONE)
+ (attr->base_value.value.u != 0)
#if IS_ACTIVE(CONFIG_SENML_ATTR_SUM)
+ (attr->base_sum.value.u != 0)
#endif
#if IS_ACTIVE(CONFIG_SENML_ATTR_VERSION)
+ (attr->base_version != 0 && attr->base_version != 10)
#endif
+ (attr->name != NULL)
+ (attr->unit != SENML_UNIT_NONE)
#if IS_ACTIVE(CONFIG_SENML_ATTR_SUM)
+ (sum_value || attr->sum.value.u != 0)
#endif
+ (attr->time.value.u != 0)
#if IS_ACTIVE(CONFIG_SENML_ATTR_UPDATE_TIME)
+ (attr->update_time.value.u != 0)
#endif
);
if (attr->base_name != NULL) {
n += nanocbor_fmt_int(enc, SENML_LABEL_BASE_NAME);
n += nanocbor_put_tstr(enc, attr->base_name);
}
if (attr->base_time.value.u != 0) {
n += nanocbor_fmt_int(enc, SENML_LABEL_BASE_TIME);
n += senml_encode_numeric_cbor(enc, &attr->base_time);
}
if (attr->base_unit != SENML_UNIT_NONE) {
n += nanocbor_fmt_int(enc, SENML_LABEL_BASE_UNIT);
n += nanocbor_put_tstr(enc, senml_unit_to_str(attr->base_unit));
}
if (attr->base_value.value.u != 0) {
n += nanocbor_fmt_int(enc, SENML_LABEL_BASE_VALUE);
n += senml_encode_numeric_cbor(enc, &attr->base_value);
}
#if IS_ACTIVE(CONFIG_SENML_ATTR_SUM)
if (attr->base_sum.value.u != 0) {
n += nanocbor_fmt_int(enc, SENML_LABEL_BASE_SUM);
n += senml_encode_numeric_cbor(enc, &attr->base_sum);
}
#endif
#if IS_ACTIVE(CONFIG_SENML_ATTR_VERSION)
if (attr->base_version != 0 && attr->base_version != 10) {
n += nanocbor_fmt_int(enc, SENML_LABEL_BASE_VERSION);
n += nanocbor_fmt_uint(enc, attr->base_version);
}
#endif
if (attr->name != NULL) {
n += nanocbor_fmt_int(enc, SENML_LABEL_NAME);
n += nanocbor_put_tstr(enc, attr->name);
}
if (attr->unit != SENML_UNIT_NONE) {
n += nanocbor_fmt_int(enc, SENML_LABEL_UNIT);
n += nanocbor_put_tstr(enc, senml_unit_to_str(attr->unit));
}
#if IS_ACTIVE(CONFIG_SENML_ATTR_SUM)
if (sum_value || attr->sum.value.u != 0) {
n += nanocbor_fmt_int(enc, SENML_LABEL_SUM);
n += senml_encode_numeric_cbor(enc, &attr->sum);
}
#endif
if (attr->time.value.u != 0) {
n += nanocbor_fmt_int(enc, SENML_LABEL_TIME);
n += senml_encode_numeric_cbor(enc, &attr->time);
}
#if IS_ACTIVE(CONFIG_SENML_ATTR_UPDATE_TIME)
if (attr->update_time.value.u != 0) {
n += nanocbor_fmt_int(enc, SENML_LABEL_UPDATE_TIME);
n += senml_encode_numeric_cbor(enc, &attr->update_time);
}
#endif
return n;
}
#if IS_ACTIVE(CONFIG_SENML_ATTR_SUM)
int senml_encode_sum_cbor(nanocbor_encoder_t *enc, const senml_attr_t *attr)
{
return senml_encode_start_cbor(enc, attr, true);
}
#endif
int senml_encode_bool_cbor(nanocbor_encoder_t *enc, const senml_bool_value_t *val)
{
return senml_encode_start_cbor(enc, &val->attr, false) +
nanocbor_fmt_int(enc, SENML_LABEL_BOOLEAN_VALUE) +
nanocbor_fmt_bool(enc, val->value);
}
int senml_encode_value_cbor(nanocbor_encoder_t *enc, const senml_value_t *val)
{
return senml_encode_start_cbor(enc, &val->attr, false) +
nanocbor_fmt_int(enc, SENML_LABEL_VALUE) +
senml_encode_numeric_cbor(enc, &val->value);
}
int senml_encode_string_cbor(nanocbor_encoder_t *enc, const senml_string_value_t *val)
{
return senml_encode_start_cbor(enc, &val->attr, false) +
nanocbor_fmt_int(enc, SENML_LABEL_STRING_VALUE) +
nanocbor_put_tstrn(enc, val->value, val->len);
}
int senml_encode_data_cbor(nanocbor_encoder_t *enc, const senml_data_value_t *val)
{
return senml_encode_start_cbor(enc, &val->attr, false) +
nanocbor_fmt_int(enc, SENML_LABEL_DATA_VALUE) +
nanocbor_put_bstr(enc, val->value, val->len);
}