Skip to content

Binary mode: Add support for importing reports #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions include/thingset.h
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,25 @@ struct thingset_data_object *thingset_iterate_subsets(struct thingset_context *t
int thingset_import_data(struct thingset_context *ts, const uint8_t *data, size_t len,
uint8_t auth_flags, enum thingset_data_format format);

/**
* Import report into data objects.
*
* This function allows importing data objects from a received report.
*
* Unknown data items are silently ignored.
*
* @param ts Pointer to ThingSet context.
* @param data Buffer containing ID/value map that should be written to the data objects
* @param len Length of the data in the buffer
* @param auth_flags Authentication flags to be used in this function (to override auth_flags)
* @param format Protocol data format to be used (text, binary with IDs or binary with names)
* @param subset The subset associated with the published report
*
* @returns 0 for success or negative ThingSet response code in case of error
*/
int thingset_import_report(struct thingset_context *ts, const uint8_t *data, size_t len,
uint8_t auth_flags, enum thingset_data_format format, uint16_t subset);

/**
* EXPERIMENTAL
*
Expand Down
35 changes: 35 additions & 0 deletions src/thingset.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,41 @@ int thingset_import_data(struct thingset_context *ts, const uint8_t *data, size_
return err;
}

int thingset_import_report(struct thingset_context *ts, const uint8_t *data, size_t len,
uint8_t auth_flags, enum thingset_data_format format, uint16_t subset)
{
int err;

if (k_sem_take(&ts->lock, K_MSEC(THINGSET_CONTEXT_LOCK_TIMEOUT_MS)) != 0) {
LOG_ERR("ThingSet context lock timed out");
return -THINGSET_ERR_INTERNAL_SERVER_ERR;
}

ts->msg = data;
ts->msg_len = len;
ts->msg_pos = 0;
ts->rsp = NULL;
ts->rsp_size = 0;
ts->rsp_pos = 0;

switch (format) {
case THINGSET_BIN_IDS_VALUES:
ts->endpoint.use_ids = true;
thingset_bin_setup(ts, 0);
ts->decoder->elem_count = 2;
ts->msg_payload = data;
err = thingset_bin_import_report(ts, auth_flags, subset);
break;
default:
err = -THINGSET_ERR_NOT_IMPLEMENTED;
break;
}

k_sem_give(&ts->lock);

return err;
}

static int deserialize_value_callback(struct thingset_context *ts,
const struct thingset_data_object *item_offset)
{
Expand Down
16 changes: 16 additions & 0 deletions src/thingset_bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,22 @@ int thingset_bin_import_data(struct thingset_context *ts, uint8_t auth_flags,
return ts->api->deserialize_finish(ts);
}

int thingset_bin_import_report(struct thingset_context *ts, uint8_t auth_flags, uint16_t subset)
{
uint32_t id = 0;

if (ts->msg_payload[0] != THINGSET_BIN_REPORT) {
return -THINGSET_ERR_UNSUPPORTED_FORMAT;
}

zcbor_uint32_decode(ts->decoder, &id);
if (id != subset) {
return -THINGSET_ERR_NOT_FOUND;
}

return thingset_bin_import_data(ts, auth_flags, subset);
}

int thingset_bin_process(struct thingset_context *ts)
{
int ret;
Expand Down
2 changes: 2 additions & 0 deletions src/thingset_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ void thingset_bin_setup(struct thingset_context *ts, size_t buf_offset);
int thingset_bin_import_data(struct thingset_context *ts, uint8_t auth_flags,
enum thingset_data_format format);

int thingset_bin_import_report(struct thingset_context *ts, uint8_t auth_flags, uint16_t subset);

int thingset_bin_import_data_progressively(struct thingset_context *ts, uint8_t auth_flags,
size_t size, uint32_t *last_id, size_t *consumed);

Expand Down
20 changes: 20 additions & 0 deletions tests/common/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,3 +423,23 @@ struct thingset_data_object data_objects[] = {
};

size_t data_objects_size = ARRAY_SIZE(data_objects);

/*
* Test case for importing reports with initial zero values.
*/
uint32_t report_timestamp = 0;
bool report_b = false;
int32_t report_nested_beginning = 0;
float report_nested_obj2_item2 = 0.0;

struct thingset_data_object report_data_objects[] = {
THINGSET_ITEM_UINT32(THINGSET_ID_ROOT, 0x10, "t_s", &report_timestamp, THINGSET_ANY_RW,
SUBSET_LIVE),
THINGSET_ITEM_BOOL(0x200, 0x201, "wBool", &report_b, THINGSET_ANY_RW, SUBSET_LIVE),
THINGSET_ITEM_INT32(0x700, 0x701, "rBeginning", &report_nested_beginning, THINGSET_ANY_RW,
SUBSET_LIVE),
THINGSET_ITEM_FLOAT(0x706, 0x708, "rItem2_V", &report_nested_obj2_item2, 1, THINGSET_ANY_RW,
SUBSET_LIVE),
};

size_t report_data_objects_size = ARRAY_SIZE(report_data_objects);
64 changes: 64 additions & 0 deletions tests/protocol/src/bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
#include "data.h"
#include "test_utils.h"

extern struct thingset_data_object report_data_objects[];
extern size_t report_data_objects_size;
extern uint32_t report_timestamp;
extern bool report_b;
extern int32_t report_nested_beginning;
extern float report_nested_obj2_item2;

static struct thingset_context ts;

ZTEST(thingset_bin, test_get_root_ids)
Expand Down Expand Up @@ -985,6 +992,63 @@ ZTEST(thingset_bin, test_import_data)
b = true;
}

ZTEST(thingset_bin, test_import_report)
{
uint8_t data[THINGSET_TEST_BUF_SIZE];

const char rpt_exp_hex[] =
"1F 19 08 00 A5 "
"10 19 03 E8 " /* t_s */
"19 02 01 F5 " /* Types/wBool */
"19 06 00 02 " /* Records: 2 */
"19 07 01 01 " /* Nested/rBeginning */
"19 07 08 FA 40 0C CC CD"; /* Nested/Obj2/rItem2_V */

struct thingset_context ts_local;
thingset_init(&ts_local, report_data_objects, report_data_objects_size);

int data_len = hex2bin_spaced(rpt_exp_hex, data, sizeof(data));

int status = thingset_import_report(&ts_local, data, data_len, THINGSET_WRITE_MASK,
THINGSET_BIN_IDS_VALUES, 0x800);

zassert_equal(status, 0);
zassert_equal(report_timestamp, 1000);
zassert_equal(report_b, true);
zassert_equal(report_nested_beginning, 1);
zassert_equal(report_nested_obj2_item2, 2.2F);
}

ZTEST(thingset_bin, test_import_report_error)
{
uint8_t data[THINGSET_TEST_BUF_SIZE];

const char rpt_exp_hex[] =
"1F 19 08 00 A5 "
"10 19 03 E8 " /* t_s */
"19 02 01 F5 " /* Types/wBool */
"19 06 00 02 " /* Records: 2 */
"19 07 01 01 " /* Nested/rBeginning */
"19 07 08 FA 40 0C CC CD"; /* Nested/Obj2/rItem2_V */

struct thingset_context ts_local;
thingset_init(&ts_local, report_data_objects, report_data_objects_size);

int data_len = hex2bin_spaced(rpt_exp_hex, data, sizeof(data));

/* no report */
data[0] = 0x00;
int status = thingset_import_report(&ts_local, data, data_len, THINGSET_WRITE_MASK,
THINGSET_BIN_IDS_VALUES, 0x800);
zassert_equal(status, -THINGSET_ERR_UNSUPPORTED_FORMAT);

/* wrong subset */
data[0] = 0x1f;
status = thingset_import_report(&ts_local, data, data_len, THINGSET_WRITE_MASK,
THINGSET_BIN_IDS_VALUES, 0x0);
zassert_equal(status, -THINGSET_ERR_NOT_FOUND);
}

ZTEST(thingset_bin, test_import_record)
{
struct thingset_endpoint endpoint;
Expand Down