diff options
-rw-r--r-- | confui/makefile | 3 | ||||
-rw-r--r-- | confui/serial.cpp | 24 | ||||
-rw-r--r-- | shared/bin.h | 2 | ||||
-rw-r--r-- | shared/pclient.c | 33 | ||||
-rw-r--r-- | shared/pclient.h | 19 | ||||
-rw-r--r-- | shared/protocol.h | 17 |
6 files changed, 81 insertions, 17 deletions
diff --git a/confui/makefile b/confui/makefile index e1faed6..2e22e20 100644 --- a/confui/makefile +++ b/confui/makefile @@ -18,3 +18,6 @@ FMT_FILES := $(filter-out %.pro,$(FMT_FILES)) # filter *.pro format: clang-format -i $(FMT_FILES) clang-tidy --fix-errors $(FMT_FILES) + +compile_commands: + compiledb make -Bn diff --git a/confui/serial.cpp b/confui/serial.cpp index 1518abd..c0e686b 100644 --- a/confui/serial.cpp +++ b/confui/serial.cpp @@ -92,10 +92,26 @@ void cd_cmd_ping(cd_s_bin* data) { std::cout << "ping request with id " << cast->id << " received!" << std::endl; - cd_s_bin* response = cd_cmd_res_status((cd_e_scmds) cast->opcode, cast->id, false); - cd_pclient_send(response); - free(response); - response = nullptr; + // cd_s_bin* response = cd_cmd_res_status((cd_e_scmds) cast->opcode, cast->id, false); + // cd_pclient_send(response); + // free(response); + // response = nullptr; + + cd_uuid_t 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", { + .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); + + cd_pclient_send(testres); + free(testres); } void cd_cmd_response(cd_s_bin* data) { diff --git a/shared/bin.h b/shared/bin.h index 0e16ec0..7506655 100644 --- a/shared/bin.h +++ b/shared/bin.h @@ -18,7 +18,7 @@ extern "C" { extern uint8_t g_cd_endianness; -/** cast `in.data` to `type out` */ +/** @brief cast `in.data` to `type out` */ #define CD_CAST_BIN(type, in, out) type *out = (type *)&in->data; #define CD_CREATE_MSG_BIN(type, normal, bin) CD_CREATE_MSG_SIZE_BIN(type, sizeof(type), normal, bin) /** @brief */ diff --git a/shared/pclient.c b/shared/pclient.c index 41ace27..be0e0a7 100644 --- a/shared/pclient.c +++ b/shared/pclient.c @@ -99,23 +99,42 @@ cd_s_bin* cd_cmd_res_status(cd_e_scmds cmd, cd_cmd_id_t id, bool error) { return bin; } -cd_s_bin* cd_cmd_res_get_node(cd_e_scmds cmd, cd_cmd_id_t id, uint16_t node_count, cd_s_cmd_node* nodes) { - CD_CREATE_MSG_BIN(cd_s_cmd_response, msg, bin); +cd_s_bin* cd_cmd_res(cd_e_scmds cmd, cd_cmd_id_t id, uint16_t len, uint8_t* data) { + CD_CREATE_MSG_SIZE_BIN(cd_s_cmd_response, sizeof(cd_s_cmd_response) + len, msg, bin); msg->opcode = CD_CMD_RESPONSE; msg->id = cd_bin_hton16(cd_protocol_fresh_message_id()); msg->response_type = cmd; msg->response_id = id; msg->error = false; - - // TODO: test this?? - msg->response_size = sizeof(cd_s_cmd_response_get_node) + sizeof(cd_s_cmd_node) * node_count; - cd_s_cmd_response_get_node* get_node_response_ptr = (cd_s_cmd_response_get_node*) msg->response_info; - memcpy(get_node_response_ptr->nodes, nodes, sizeof(cd_s_cmd_node) * node_count); + msg->response_size = cd_bin_hton16(len); + memcpy(msg->response_info, data, len); return bin; } +cd_s_cmd_node* cd_cmd_node_alloc(const char* name, cd_s_cmd_node base, uint16_t link_count, cd_uuid_t* links) { + size_t name_len = strlen(name); + size_t links_size = sizeof(cd_uuid_t) * link_count; + size_t remaining_size = sizeof(char) * name_len + links_size; + cd_s_cmd_node* node = malloc(sizeof(cd_s_cmd_node) + remaining_size); + + memcpy(&node->uuid, &base.uuid, sizeof(cd_uuid_t)); + memcpy(&node->address, &base.address, sizeof(cd_mac_addr_t)); + node->name_len = name_len; + node->light_on = base.light_on; + node->provisioned = base.provisioned; + node->button_pub = cd_bin_hton32(base.button_pub); + node->link_count = cd_bin_hton16(link_count); + node->remaining_size = cd_bin_hton16(remaining_size); + void* cursor = (void*) &node->remaining_data[0]; + memcpy(cursor, name, name_len); // copy name + cursor += name_len; + memcpy(cursor, links, links_size); // copy links + + return node; +} + #ifdef __cplusplus } #endif diff --git a/shared/pclient.h b/shared/pclient.h index cf0f182..e1bb7e7 100644 --- a/shared/pclient.h +++ b/shared/pclient.h @@ -59,13 +59,24 @@ cd_s_bin* cd_cmd_gen_post_net_rm(cd_uuid_t uuid); */ cd_s_bin* cd_cmd_res_status(cd_e_scmds cmd, cd_cmd_id_t id, bool error); /** - * @brief generate RESPONSE command with GET_NODE response_info + * @brief generate RESPONSE command with response_info * @param cmd original command opcode * @param id original command id - * @param node_count amount of nodes in `nodes` - * @param nodes pointer to array of `cd_s_cmd_node` + * @param len size of `data` in bytes + * @param data pointer to data */ -cd_s_bin* cd_cmd_res_get_node(cd_e_scmds cmd, cd_cmd_id_t id, uint16_t node_count, cd_s_cmd_node* nodes); +cd_s_bin* cd_cmd_res(cd_e_scmds cmd, cd_cmd_id_t id, uint16_t len, uint8_t* data); +/** + * @brief allocate and fill cd_s_cmd_node struct + * + * @param base base struct with values that can be initialized using an initialization list + * @param name node name (length is calculated at runtime using strlen()) + * @param link_count amount of lights this node controls + * @param links array of light node uuids + */ +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 */) #ifdef __cplusplus } diff --git a/shared/protocol.h b/shared/protocol.h index 63b4a9e..dd5bcc6 100644 --- a/shared/protocol.h +++ b/shared/protocol.h @@ -19,6 +19,9 @@ typedef uint8_t cd_mac_addr_t[6]; /** @brief uuid (ffeeddcc-bbaa-9988-7766-554433221100) */ typedef uint8_t cd_uuid_t[16]; +/** @brief pub/sub address type */ +typedef uint32_t cd_mesh_psub_addr; + /** @brief command opcode (identifies message type) */ typedef uint8_t cd_cmd_opcode_t; /** @brief command id (identifies messages uniquely) */ @@ -85,7 +88,19 @@ typedef struct { uint8_t name_len; /** @brief name length in bytes */ cd_cmd_bool_t light_on; /** @brief state of light on node */ cd_cmd_bool_t provisioned; /** @brief whether the node is provisioned into the network */ - const char name[]; /** @brief user-friendly node name */ + cd_mesh_psub_addr button_pub; /** @brief button publish address */ + uint16_t link_count; /** @brief amount of addresses to publish button press to */ + uint16_t remaining_size; /** @brief calculated size of remaining_data for convenience */ + const uint8_t remaining_data[]; /** + * @brief remaining data (name and link array) + * + * this data is stored adjacently in memory + * and is cast when reading/writing this + * struct + * + * 1. char[] name + * 2. cd_uuid_t[] light_publish_addresses; + */ } cd_s_cmd_node; typedef struct { |