mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
9d61bdbb06
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.
156 lines
5.2 KiB
C
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);
|
|
}
|