diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..1430b10 --- /dev/null +++ b/.clang-format @@ -0,0 +1,33 @@ +# Format definition for Libre Solar firmware +# +# Use Clang-Format plugin in VS Code and add "editor.formatOnSave": true to settings + +# Generic format +BasedOnStyle: LLVM +UseTab: Never +IndentWidth: 4 +TabWidth: 4 +ColumnLimit: 100 +AccessModifierOffset: -4 + +# Indentation and alignment +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AlignConsecutiveAssignments: false +AlignConsecutiveMacros: true +AlignEscapedNewlines: DontAlign +BreakBeforeBinaryOperators: NonAssignment +IndentCaseLabels: true + +# Braces +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: true + AfterControlStatement: MultiLine + AfterEnum: true + AfterStruct: true + AfterFunction: true + BeforeElse: true + SplitEmptyFunction: false +Cpp11BracedListStyle: false diff --git a/src/thingset.c b/src/thingset.c index 06b3b8c..2eefea8 100644 --- a/src/thingset.c +++ b/src/thingset.c @@ -59,8 +59,8 @@ int ts_init_global(struct ts_context *ts) #endif -int ts_process(struct ts_context *ts, const uint8_t *request, size_t request_len, - uint8_t *response, size_t response_size) +int ts_process(struct ts_context *ts, const uint8_t *request, size_t request_len, uint8_t *response, + size_t response_size) { // check if proper request was set before asking for a response if (request == NULL || request_len < 1) { @@ -77,8 +77,9 @@ int ts_process(struct ts_context *ts, const uint8_t *request, size_t request_len // binary mode request return ts_bin_process(ts); } - else if (ts->req[0] == '?' || ts->req[0] == '=' || ts->req[0] == '+' - || ts->req[0] == '-' || ts->req[0] == '!') { + else if (ts->req[0] == '?' || ts->req[0] == '=' || ts->req[0] == '+' || ts->req[0] == '-' + || ts->req[0] == '!') + { // text mode request return ts_txt_process(ts); } @@ -100,16 +101,16 @@ void ts_set_update_callback(struct ts_context *ts, const uint16_t subsets, void ts->update_cb = update_cb; } -struct ts_data_object *ts_get_object_by_name(struct ts_context *ts, const char *name, - size_t len, int32_t parent) +struct ts_data_object *ts_get_object_by_name(struct ts_context *ts, const char *name, size_t len, + int32_t parent) { for (unsigned int i = 0; i < ts->num_objects; i++) { if (parent != -1 && ts->data_objects[i].parent != parent) { continue; } else if (strncmp(ts->data_objects[i].name, name, len) == 0 - // without length check foo and fooBar would be recognized as equal - && strlen(ts->data_objects[i].name) == len) + // without length check foo and fooBar would be recognized as equal + && strlen(ts->data_objects[i].name) == len) { return &(ts->data_objects[i]); } @@ -128,7 +129,7 @@ struct ts_data_object *ts_get_object_by_id(struct ts_context *ts, ts_object_id_t } struct ts_data_object *ts_get_endpoint_by_path(struct ts_context *ts, const char *path, size_t len, - int *index) + int *index) { struct ts_data_object *object = NULL; const char *start = path; @@ -140,8 +141,8 @@ struct ts_data_object *ts_get_endpoint_by_path(struct ts_context *ts, const char end = strchr(start, '/'); if (end == NULL || end >= path + len) { // we are at the end of the path - if (object != NULL && object->type == TS_T_RECORDS && - start[0] >= '0' && start[0] <= '9') + if (object != NULL && object->type == TS_T_RECORDS && start[0] >= '0' + && start[0] <= '9') { // numeric ID, only valid to select index in an array of records if (index != NULL) { @@ -186,13 +187,16 @@ int ts_get_path(struct ts_context *ts, char *buf, size_t size, const struct ts_d else { struct ts_data_object *parent_obj = ts_get_object_by_id(ts, obj->parent); if (parent_obj != NULL) { - pos = snprintf(buf, size, "%s/%s", parent_obj->name, obj->name); + pos = ts_get_path(ts, buf, size, parent_obj); } else { return 0; } + if (pos >= size) { + return 0; + } + pos += snprintf(&buf[pos], size - pos, "/%s", obj->name); } - if (pos < size) { return pos; } diff --git a/src/thingset_txt.c b/src/thingset_txt.c index e38c97e..7055eac 100644 --- a/src/thingset_txt.c +++ b/src/thingset_txt.c @@ -1060,7 +1060,11 @@ static int ts_serialize_statement(struct ts_context *ts, char *buf, size_t buf_s buf[len] = '\0'; } else { - return 0; + len += ts_json_serialize_value(ts, &buf[len], buf_size - len, object); + if (len >= buf_size - 1) { + return 0; + } + buf[--len] = '\0'; // overwrite comma } return len; diff --git a/test/main.cpp b/test/main.cpp index 85b8904..b976f0d 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -71,6 +71,7 @@ void tests_text_mode() RUN_TEST(test_txt_statement_subset); RUN_TEST(test_txt_statement_group); RUN_TEST(test_txt_statement_record); + RUN_TEST(test_txt_statement_item); RUN_TEST(test_txt_pub_list_channels); RUN_TEST(test_txt_pub_enable); RUN_TEST(test_txt_pub_delete_append_object); diff --git a/test/test.h b/test/test.h index f89f108..0acdec2 100644 --- a/test/test.h +++ b/test/test.h @@ -34,6 +34,7 @@ extern "C" { #define ID_DFU 0x0D // device firmware upgrade #define ID_RPC 0x0E // remote procedure calls #define ID_PUB 0x0F // publication setup +#define ID_TXT 0x10 // txt statement test #define SUBSET_REPORT (1U << 0) // report subset of data items for publication #define SUBSET_CAN (1U << 1) // data nodes used for CAN bus publication messages @@ -163,6 +164,7 @@ void test_txt_fn_int32(void); void test_txt_statement_subset(void); void test_txt_statement_group(void); void test_txt_statement_record(void); +void test_txt_statement_item(void); void test_txt_pub_list_channels(void); void test_txt_pub_enable(void); void test_txt_pub_delete_append_object(void); diff --git a/test/test_data.c b/test/test_data.c index ff3cbc5..e69619e 100644 --- a/test/test_data.c +++ b/test/test_data.c @@ -38,6 +38,21 @@ bool pub_report_enable = false; uint16_t pub_report_interval = 1000; bool pub_info_enable = true; +// txt_statement +static float txt_st_float_pos = 12.53; +static float txt_st_float_neg = -2.3; +static int8_t txt_st_int8_pos = 120; +static int8_t txt_st_int8_neg = -123; +static int16_t txt_st_int16_pos = 32760; +static int16_t txt_st_int16_neg = -32750; +static int32_t txt_st_int32_pos = 2147483568; +static int32_t txt_st_int32_neg = -2147483450; +static uint8_t txt_st_uint8 = 254; +static uint16_t txt_st_uint16 = 64050; +static uint32_t txt_st_uint32 = 3399612978; +static bool txt_st_bool_true = true; +static bool txt_st_bool_false = false; + // exec void reset_function(void); void auth_function(void); @@ -240,6 +255,52 @@ struct ts_data_object data_objects[] = { TS_ITEM_BOOL(0xF6, "wOnChange", &pub_info_enable, 0xF5, TS_ANY_RW, 0), + + // TXT STATEMTENT DATA /////////////////////////////////////////////////////// + + TS_GROUP(ID_TXT,"TXT",TS_NO_CALLBACK,ID_ROOT), + + TS_ITEM_FLOAT(0x101, "rFloatPos", &txt_st_float_pos, 2, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_FLOAT(0x102, "rFloatNeg", &txt_st_float_neg, 2, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_INT8(0x103, "rInt8Pos", &txt_st_int8_pos, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_INT8(0x104, "rInt8Neg", &txt_st_int8_neg, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_INT16(0x105, "rInt16Pos", &txt_st_int16_pos, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_INT16(0x106, "rInt16Neg", &txt_st_int16_neg, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_INT32(0x107, "rInt32Pos", &txt_st_int32_pos, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_INT32(0x108, "rInt32Neg", &txt_st_int32_neg, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_UINT8(0x109, "rUint8", &txt_st_uint8, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_UINT16(0x10A, "rUint16", &txt_st_uint16, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_UINT32(0x10B, "rUint32", &txt_st_uint32, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_BOOL(0x10C, "rBoolTrue", &txt_st_bool_true, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + TS_ITEM_BOOL(0x10D, "rBoolFalse", &txt_st_bool_false, + ID_TXT, TS_ANY_R, SUBSET_REPORT), + + + // UNIT TEST DATA ///////////////////////////////////////////////////////// // using IDs >= 0x1000 diff --git a/test/test_txt.c b/test/test_txt.c index 7388d27..7cbccc7 100644 --- a/test/test_txt.c +++ b/test/test_txt.c @@ -237,6 +237,40 @@ void test_txt_statement_record(void) TEST_ASSERT_TXT_RESP(resp_len, expected); } + + +void test_txt_statement_item(void) +{ + + const struct { + const char* path; + const char* value; + } tests[] ={ + {"TXT/rFloatPos","12.53"}, + {"TXT/rFloatNeg","-2.30"}, + {"TXT/rInt8Pos","120"}, + {"TXT/rInt8Neg","-123"}, + {"TXT/rInt16Pos","32760"}, + {"TXT/rInt16Pos","-32750"}, + {"TXT/rInt32Pos","2147483568"}, + {"TXT/rInt32Pos","-2147483450"}, + {"TXT/rUint8","254"}, + {"TXT/rUint16","64050"}, + {"TXT/rUint32","3399612978"}, + {"TXT/rBoolTrue","true"}, + {"TXT/rBoolFalse","false"}, + }; + + for (size_t i=0;i