diff options
Diffstat (limited to 'shared')
-rw-r--r-- | shared/pclient.c | 122 | ||||
-rw-r--r-- | shared/pclient.h | 72 | ||||
-rw-r--r-- | shared/protocol.c | 6 | ||||
-rw-r--r-- | shared/protocol.h | 20 |
4 files changed, 218 insertions, 2 deletions
diff --git a/shared/pclient.c b/shared/pclient.c new file mode 100644 index 0000000..41ace27 --- /dev/null +++ b/shared/pclient.c @@ -0,0 +1,122 @@ +#include <memory.h> + +#include "protocol.h" +#include "pclient.h" +#include "bin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +cd_s_bin* cd_cmd_gen_ping() { + CD_CREATE_MSG_BIN(cd_s_cmd_ping, msg, bin); + + msg->opcode = CD_CMD_PING; + msg->id = cd_bin_hton16(cd_protocol_fresh_message_id()); + + return bin; +} + +cd_s_bin* cd_cmd_gen_get_node(bool all, cd_uuid_t uuid) { + CD_CREATE_MSG_BIN(cd_s_cmd_get_node, msg, bin); + + msg->opcode = CD_CMD_GET_NODE; + msg->id = cd_bin_hton16(cd_protocol_fresh_message_id()); + msg->all = all; + memcpy(&msg->uuid, &uuid, sizeof(cd_uuid_t)); + + return bin; +} + +cd_s_bin* cd_cmd_gen_post_led(bool on, cd_uuid_t uuid) { + CD_CREATE_MSG_BIN(cd_s_cmd_post_led, msg, bin); + + msg->opcode = CD_CMD_POST_LED; + msg->id = cd_bin_hton16(cd_protocol_fresh_message_id()); + msg->on = on; + memcpy(&msg->uuid, &uuid, sizeof(cd_uuid_t)); + + return bin; +} + +cd_s_bin* cd_cmd_gen_post_link_add(cd_uuid_t button, cd_uuid_t light, cd_e_cmd_link_type type) { + CD_CREATE_MSG_BIN(cd_s_cmd_post_link, msg, bin); + + msg->opcode = CD_CMD_POST_LINK; + msg->id = cd_bin_hton16(cd_protocol_fresh_message_id()); + msg->add = true; + memcpy(&msg->button, &button, sizeof(cd_uuid_t)); + memcpy(&msg->led, &light, sizeof(cd_uuid_t)); + msg->type = type; + + return bin; +} + +cd_s_bin* cd_cmd_gen_post_link_rm(cd_uuid_t button, cd_uuid_t light) { + CD_CREATE_MSG_BIN(cd_s_cmd_post_link, msg, bin); + + msg->opcode = CD_CMD_POST_LINK; + msg->id = cd_bin_hton16(cd_protocol_fresh_message_id()); + msg->add = false; + memcpy(&msg->button, &button, sizeof(cd_uuid_t)); + memcpy(&msg->led, &light, sizeof(cd_uuid_t)); + + return bin; +} + +cd_s_bin* cd_cmd_gen_post_net_add(cd_uuid_t uuid) { + CD_CREATE_MSG_BIN(cd_s_cmd_post_net, msg, bin); + + msg->opcode = CD_CMD_POST_NET; + msg->id = cd_bin_hton16(cd_protocol_fresh_message_id()); + msg->join = true; + memcpy(&msg->uuid, &uuid, sizeof(cd_uuid_t)); + + return bin; +} + +cd_s_bin* cd_cmd_gen_post_net_rm(cd_uuid_t uuid) { + CD_CREATE_MSG_BIN(cd_s_cmd_post_net, msg, bin); + + msg->opcode = CD_CMD_POST_NET; + msg->id = cd_bin_hton16(cd_protocol_fresh_message_id()); + msg->join = false; + memcpy(&msg->uuid, &uuid, sizeof(cd_uuid_t)); + + return bin; +} + +cd_s_bin* cd_cmd_res_status(cd_e_scmds cmd, cd_cmd_id_t id, bool error) { + CD_CREATE_MSG_BIN(cd_s_cmd_response, 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 = error; + msg->response_size = 0; + + 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); + + 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); + + return bin; +} + +#ifdef __cplusplus +} +#endif + diff --git a/shared/pclient.h b/shared/pclient.h new file mode 100644 index 0000000..cf0f182 --- /dev/null +++ b/shared/pclient.h @@ -0,0 +1,72 @@ +#pragma once + +/** @file pclient.h */ + +#include <stdbool.h> + +#include "protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief send data over platform standard serial out (doesn't free `data`) */ +void cd_pclient_send(cd_s_bin* data); + +/** @brief generate PING command */ +cd_s_bin* cd_cmd_gen_ping(); +/** + * @brief generate GET_NODE command + * @param all get all nodes + * @param uuid get specific node by uuid + */ +cd_s_bin* cd_cmd_gen_get_node(bool all, cd_uuid_t uuid); +/** + * @brief generate POST_LED command + * @param on light status + * @param uuid node to set light of + */ +cd_s_bin* cd_cmd_gen_post_led(bool on, cd_uuid_t uuid); +/** + * @brief generate POST_LINK command to add or update link + * @param button button node uuid + * @param light light node uuid + * @param type type of link to set + */ +cd_s_bin* cd_cmd_gen_post_link_add(cd_uuid_t button, cd_uuid_t light, cd_e_cmd_link_type type); +/** + * @brief generate POST_LINK command to remove link + * @param button button node uuid + * @param light light node uuid + */ +cd_s_bin* cd_cmd_gen_post_link_rm(cd_uuid_t button, cd_uuid_t light); +/** + * @brief generate POST_NET command to provision node into network + * @param uuid node uuid + */ +cd_s_bin* cd_cmd_gen_post_net_add(cd_uuid_t uuid); +/** + * @brief generate POST_NET command to provision node out of network + * @param uuid node uuid + */ +cd_s_bin* cd_cmd_gen_post_net_rm(cd_uuid_t uuid); + +/** + * @brief generate generic RESPONSE command with error field and no response_info + * @param cmd original command opcode + * @param id original command id + * @param error `true` if some error occurred + */ +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 + * @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` + */ +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); + +#ifdef __cplusplus +} +#endif diff --git a/shared/protocol.c b/shared/protocol.c index 1d66f17..fcc0f41 100644 --- a/shared/protocol.c +++ b/shared/protocol.c @@ -6,6 +6,8 @@ extern "C" { #endif +cd_cmd_id_t g_cd_protocol_fresh_message_id = 0; + size_t cd_cmd_sizeof(uint8_t data[CD_SERIAL_READ_BUFFER_SIZE], uint8_t data_length) { cd_cmd_opcode_t opcode = data[0]; if (CD_CMD_HANDLERS_SIZE[opcode] > 0) return CD_CMD_HANDLERS_SIZE[opcode]; @@ -47,6 +49,10 @@ size_t cd_cmd_response_sizeof(cd_s_bin* data) { return CD_DYN_MEMBER_SIZEOF(data, cd_s_cmd_response, response_size); } +cd_cmd_id_t cd_protocol_fresh_message_id() { + return g_cd_protocol_fresh_message_id++; +} + #ifdef __cplusplus } #endif diff --git a/shared/protocol.h b/shared/protocol.h index 7f06a52..63b4a9e 100644 --- a/shared/protocol.h +++ b/shared/protocol.h @@ -29,6 +29,12 @@ typedef uint8_t cd_cmd_bool_t; /** @brief cmd handler function signature */ typedef void (cd_cmd_handler_t)(cd_s_bin *data); +/** @brief used for numbering messages */ +extern cd_cmd_id_t g_cd_protocol_fresh_message_id; + +/** @brief get new message id */ +cd_cmd_id_t cd_protocol_fresh_message_id(); + #pragma pack(push, 1) typedef struct { @@ -50,9 +56,19 @@ typedef struct { cd_uuid_t uuid; /** @brief node uuid to set */ } cd_s_cmd_post_led; +typedef enum { + CD_CMD_LINK_TYPE_TOGGLE = 0x00, + CD_CMD_LINK_TYPE_TURN_ON = 0x01, + CD_CMD_LINK_TYPE_TURN_OFF = 0x02, +} cd_e_cmd_link_type; + typedef struct { cd_cmd_opcode_t opcode; /** @brief cmd opcode */ cd_cmd_id_t id; /** @brief message id */ + cd_uuid_t button; /** @brief uuid of button node */ + cd_uuid_t led; /** @brief uuid of led node */ + cd_cmd_bool_t add; /** @brief `true` to create/overwrite link, `false` to remove link */ + cd_e_cmd_link_type type; /** @brief link type */ } cd_s_cmd_post_link; typedef struct { @@ -80,9 +96,9 @@ typedef struct { typedef struct { cd_cmd_opcode_t opcode; /** @brief cmd opcode */ cd_cmd_id_t id; /** @brief response message id */ - cd_cmd_bool_t success; /** @brief `true` if some error occurred */ - cd_cmd_id_t response_id; /** @brief original message id */ + cd_cmd_bool_t error; /** @brief `true` if some error occurred */ cd_cmd_opcode_t response_type; /** @brief response type, used to cast type of `response_info` */ + cd_cmd_id_t response_id; /** @brief original message id */ uint16_t response_size; /** @brief size of remaining response */ uint8_t response_info[]; /** @brief (CAST) remaining response struct, not read if `response_size`=`0` */ } cd_s_cmd_response; |