From 759d73e4ef0167c654535637488bdfcd423015a0 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 5 Jan 2023 15:03:58 +0100 Subject: improve parseability of get-nodes response --- confui/serial.cpp | 19 +++--- shared/pclient.c | 21 +++++++ shared/pclient.h | 10 ++- shared/protocol-tests/get-node-response.src | 98 +++++++++++++++-------------- shared/protocol.h | 5 +- 5 files changed, 95 insertions(+), 58 deletions(-) diff --git a/confui/serial.cpp b/confui/serial.cpp index c0e686b..dd2a702 100644 --- a/confui/serial.cpp +++ b/confui/serial.cpp @@ -97,21 +97,26 @@ void cd_cmd_ping(cd_s_bin* data) { // free(response); // response = nullptr; - cd_uuid_t light_addrs[] = { + cd_uuid_t test_node_light_addrs[] = { { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00 }, }; - cd_s_cmd_node* test = cd_cmd_node_alloc("gert", { + cd_s_cmd_node* test_node = cd_cmd_node_alloc("gert", { .uuid = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00 }, .address = { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, }, .light_on = false, .provisioned = false, .button_pub = 0xdeadbeef, - }, 1, light_addrs); - cd_s_bin* testres = cd_cmd_res(CD_CMD_GET_NODE, 0xf88f, cd_cmd_node_sizeof(test), (uint8_t*) test); - free(test); + }, 1, test_node_light_addrs); - cd_pclient_send(testres); - free(testres); + cd_s_cmd_node* nodes[] = { test_node }; + cd_s_cmd_response_get_node* response_get_nodes = cd_cmd_get_node_res_from_node_arr(1, nodes); + free(test_node); + + cd_s_bin* response = cd_cmd_res(CD_CMD_GET_NODE, 0xf88f, cd_cmd_response_get_node_sizeof(response_get_nodes), (uint8_t*) response_get_nodes); + free(response_get_nodes); + + cd_pclient_send(response); + free(response); } void cd_cmd_response(cd_s_bin* data) { diff --git a/shared/pclient.c b/shared/pclient.c index be0e0a7..728bfa0 100644 --- a/shared/pclient.c +++ b/shared/pclient.c @@ -135,6 +135,27 @@ cd_s_cmd_node* cd_cmd_node_alloc(const char* name, cd_s_cmd_node base, uint16_t return node; } +cd_s_cmd_response_get_node* cd_cmd_get_node_res_from_node_arr(uint16_t size, cd_s_cmd_node* arr[]) { + size_t remaining_size = 0; + + for (unsigned int i = 0; i < size; i++) { + remaining_size += sizeof(cd_s_cmd_node) + cd_bin_ntoh16(arr[i]->remaining_size); + } + + cd_s_cmd_response_get_node* response = malloc(sizeof(cd_s_cmd_response_get_node) + remaining_size); + response->node_count = cd_bin_hton16(size); + response->remaining_size = cd_bin_hton16(remaining_size); + + void* cursor = response->nodes; + for (unsigned int i = 0; i < size; i++) { + size_t size = sizeof(cd_s_cmd_node) + cd_bin_ntoh16(arr[i]->remaining_size); + memcpy(cursor, arr[i], size); + cursor += size; + } + + return response; +} + #ifdef __cplusplus } #endif diff --git a/shared/pclient.h b/shared/pclient.h index e1bb7e7..03a8a25 100644 --- a/shared/pclient.h +++ b/shared/pclient.h @@ -66,6 +66,12 @@ cd_s_bin* cd_cmd_res_status(cd_e_scmds cmd, cd_cmd_id_t id, bool error); * @param data pointer to data */ cd_s_bin* cd_cmd_res(cd_e_scmds cmd, cd_cmd_id_t id, uint16_t len, uint8_t* data); +/** + * @brief generate cd_s_cmd_response_get_node struct from array of cd_s_cmd_node pointers + * @param size length of array + * @param arr array of pointer to cd_s_cmd_node + */ +cd_s_cmd_response_get_node* cd_cmd_get_node_res_from_node_arr(uint16_t size, cd_s_cmd_node* arr[]); /** * @brief allocate and fill cd_s_cmd_node struct * @@ -76,7 +82,9 @@ cd_s_bin* cd_cmd_res(cd_e_scmds cmd, cd_cmd_id_t id, uint16_t len, uint8_t* data */ cd_s_cmd_node* cd_cmd_node_alloc(const char* name, cd_s_cmd_node base, uint16_t link_count, cd_uuid_t* links); -#define cd_cmd_node_sizeof(node) ((sizeof(cd_s_cmd_node) + cd_bin_ntoh16(node->remaining_size)) /* NOLINT */) +#define cd_remaining_sizeof(type, input_struct) ((sizeof(type) + cd_bin_ntoh16(input_struct->remaining_size)) /* NOLINT */) +#define cd_cmd_node_sizeof(node) (cd_remaining_sizeof(cd_s_cmd_node, node) /* NOLINT */) +#define cd_cmd_response_get_node_sizeof(res) (cd_remaining_sizeof(cd_s_cmd_response_get_node, res) /* NOLINT */) #ifdef __cplusplus } diff --git a/shared/protocol-tests/get-node-response.src b/shared/protocol-tests/get-node-response.src index f10ffe0..31bf1ff 100644 --- a/shared/protocol-tests/get-node-response.src +++ b/shared/protocol-tests/get-node-response.src @@ -6,74 +6,76 @@ 05: 01 ; response type (0x01 = get node) 06: 8f ; original message id (0x8ff8) 07: f8 ; ^ -08: 00 ; remaining response size (0x35 = 53 bytes) -09: 35 ; ^ +08: 00 ; remaining response size (0x39 = 57 bytes) +09: 39 ; ^ -------; |- remaining response (cd_s_cmd_response_get_node) 0a: 00 ; | node count (0x0001 = 1) 0b: 01 ; | ^ +0c: 00 ; | remaining response size (0x35 = 53 bytes) +0d: 35 ; | ^ -------; | |- remaining response (cd_s_cmd_node[1]) -0c: ff ; | | [esc] -0d: ff ; | | uuid (ffffffff-0000-0000-dead-beef00000000) 0e: ff ; | | [esc] -0f: ff ; | | ^ +0f: ff ; | | uuid (ffffffff-0000-0000-dead-beef00000000) 10: ff ; | | [esc] 11: ff ; | | ^ 12: ff ; | | [esc] 13: ff ; | | ^ -14: 00 ; | | ^ -15: 00 ; | | ^ +14: ff ; | | [esc] +15: ff ; | | ^ 16: 00 ; | | ^ 17: 00 ; | | ^ -18: de ; | | ^ -19: ad ; | | ^ -1a: be ; | | ^ -1b: ef ; | | ^ -1c: 00 ; | | ^ -1d: 00 ; | | ^ +18: 00 ; | | ^ +19: 00 ; | | ^ +1a: de ; | | ^ +1b: ad ; | | ^ +1c: be ; | | ^ +1d: ef ; | | ^ 1e: 00 ; | | ^ 1f: 00 ; | | ^ -20: ff ; | | [esc] -21: ff ; | | mac address (ff:00:ff:00:ff:00) -22: 00 ; | | ^ -23: ff ; | | [esc] -24: ff ; | | ^ -25: 00 ; | | ^ -26: ff ; | | [esc] -27: ff ; | | ^ -28: 00 ; | | ^ -29: 04 ; | | name length (0x04 = 4) -2a: 00 ; | | light on (0x00 = false) -2b: 00 ; | | provisioned (0x00 = false) -2c: de ; | | button publish address (0xdeadbeef) -2d: ad ; | | ^ -2e: be ; | | ^ -2f: ef ; | | ^ -30: 00 ; | | link count (0x0001 = 1) -31: 01 ; | | ^ -32: 00 ; | | remaining size (0x14 = 20 bytes) -33: 14 ; | | ^ +20: 00 ; | | ^ +21: 00 ; | | ^ +22: ff ; | | [esc] +23: ff ; | | mac address (ff:00:ff:00:ff:00) +24: 00 ; | | ^ +25: ff ; | | [esc] +26: ff ; | | ^ +27: 00 ; | | ^ +28: ff ; | | [esc] +29: ff ; | | ^ +2a: 00 ; | | ^ +2b: 04 ; | | name length (0x04 = 4) +2c: 00 ; | | light on (0x00 = false) +2d: 00 ; | | provisioned (0x00 = false) +2e: de ; | | button publish address (0xdeadbeef) +2f: ad ; | | ^ +30: be ; | | ^ +31: ef ; | | ^ +32: 00 ; | | link count (0x0001 = 1) +33: 01 ; | | ^ +34: 00 ; | | remaining size (0x14 = 20 bytes) +35: 14 ; | | ^ -------; | | |- remaining response (char[4], cd_uuid_t[1]) -34: 67 ; | | | node name ("gert") -35: 65 ; | | | ^ -36: 72 ; | | | ^ -37: 74 ; | | | ^ -38: ff ; | | | [esc] -39: ff ; | | | link[0] uuid (ffffffff-0000-0000-dead-beef00000000) +36: 67 ; | | | node name ("gert") +37: 65 ; | | | ^ +38: 72 ; | | | ^ +39: 74 ; | | | ^ 3a: ff ; | | | [esc] -3b: ff ; | | | ^ +3b: ff ; | | | link[0] uuid (ffffffff-0000-0000-dead-beef00000000) 3c: ff ; | | | [esc] 3d: ff ; | | | ^ 3e: ff ; | | | [esc] 3f: ff ; | | | ^ -40: 00 ; | | | ^ -41: 00 ; | | | ^ +40: ff ; | | | [esc] +41: ff ; | | | ^ 42: 00 ; | | | ^ 43: 00 ; | | | ^ -44: de ; | | | ^ -45: ad ; | | | ^ -46: be ; | | | ^ -47: ef ; | | | ^ -48: 00 ; | | | ^ -49: 00 ; | | | ^ +44: 00 ; | | | ^ +45: 00 ; | | | ^ +46: de ; | | | ^ +47: ad ; | | | ^ +48: be ; | | | ^ +49: ef ; | | | ^ 4a: 00 ; | | | ^ 4b: 00 ; | | | ^ +4c: 00 ; | | | ^ +4d: 00 ; | | | ^ diff --git a/shared/protocol.h b/shared/protocol.h index dd5bcc6..cad9a1c 100644 --- a/shared/protocol.h +++ b/shared/protocol.h @@ -104,8 +104,9 @@ typedef struct { } cd_s_cmd_node; typedef struct { - uint16_t node_count; - cd_s_cmd_node nodes[]; + uint16_t node_count; /** amount of nodes in nodes[] */ + uint16_t remaining_size; /** remaining size (for convenience) */ + cd_s_cmd_node nodes[]; /** nodes adjacent in memory (should be accessed using pointer arithmetic) */ } cd_s_cmd_response_get_node; typedef struct { -- cgit v1.2.3