diff --git a/CMakeLists.txt b/CMakeLists.txt index 78f9813..556a60b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(esp_nano_hosted) set(NH_SOURCES "proto/esp_hosted_config.pb.c" "src/nh_ctrl_api.c" - "src/nh_event.c" + "src/nh_event_helpers.c" "src/nh_shared_if.c" ) diff --git a/include/nh_event.h b/include/nh_event_helpers.h similarity index 76% rename from include/nh_event.h rename to include/nh_event_helpers.h index e921e03..4bc4feb 100644 --- a/include/nh_event.h +++ b/include/nh_event_helpers.h @@ -7,6 +7,13 @@ typedef enum { NH_EVENT_TYPE_INIT, } nh_event_type_t; +typedef enum { + NH_EVENT_INIT_TAG_CAP = 0U, + NH_EVENT_INIT_TAG_FREQ = 1U, + NH_EVENT_INIT_TAG_CHIP_ID = 2U, + NH_EVENT_INIT_TAG_RAW_TP = 3U, +} nh_event_init_tag_t; + typedef enum { NH_EVENT_INIT_CAP_WLAN_SDIO = (1U << 0U), NH_EVENT_INIT_CAP_BT_UART = (1U << 1U), @@ -33,4 +40,7 @@ typedef struct { uint8_t spi_freq; } nh_event_init_t; +nh_ret_t nh_event_get_type(nh_event_type_t *type, uint8_t *event); +nh_ret_t nh_event_parse_init(nh_event_init_t *init, uint8_t *event); + #endif // NH_EVENT_H diff --git a/include/nh_shared_if.h b/include/nh_shared_if.h index 92654c6..a2bc313 100644 --- a/include/nh_shared_if.h +++ b/include/nh_shared_if.h @@ -2,6 +2,7 @@ #define NH_SHARED_IF_H #include "nh_common.h" +#include "nh_event_helpers.h" /* OPS */ typedef nh_ret_t (*nh_shared_if_ops_spi_xfer_t)(void *handle, uint8_t *tx_data, uint8_t *rx_data, uint32_t len); @@ -9,7 +10,7 @@ typedef nh_ret_t (*nh_shared_if_ops_reset_t)(void *handle); typedef nh_ret_t (*nh_shared_if_ops_drdy_read_t)(void *handle, bool *rdy); /* Event callbacks */ -typedef void (*nh_shared_if_cb_event_t)(void *handle, uint8_t *data); +typedef void (*nh_shared_if_cb_event_init_t)(void *handle, nh_event_init_t *init_event); typedef struct { nh_shared_if_ops_spi_xfer_t xfer; @@ -18,7 +19,7 @@ typedef struct { } nh_shared_if_ops_t; typedef struct { - nh_shared_if_cb_event_t event; + nh_shared_if_cb_event_init_t init; } nh_shared_if_cb_t; typedef struct { diff --git a/src/nh_event.c b/src/nh_event.c deleted file mode 100644 index 5770887..0000000 --- a/src/nh_event.c +++ /dev/null @@ -1 +0,0 @@ -#include "nh_event.h" \ No newline at end of file diff --git a/src/nh_event_helpers.c b/src/nh_event_helpers.c new file mode 100644 index 0000000..02b631d --- /dev/null +++ b/src/nh_event_helpers.c @@ -0,0 +1,53 @@ +#include "nh_event_helpers.h" + +/** + * Espressif wraps Tag-Length-Value(TLV) data in the packet for events + * | 1 | 1 | N | + * | Tag | Length | Value | + */ + +nh_ret_t nh_event_get_type(nh_event_type_t *type, uint8_t *event) { + *type = event[0]; + + return NH_RET_SUCCESS; +} + +/** + * Parse Init event TLV data + * @param init + * @param data Event data + * @param max_len + * @return + */ +nh_ret_t nh_event_parse_init(nh_event_init_t *init, uint8_t *event) { + uint8_t ptr = 0; + uint8_t data_len = event[1]; + uint8_t *data = &event[2]; + + while (ptr < data_len) { + uint8_t tag = data[ptr]; + uint8_t len = data[ptr + 1]; + uint8_t *val = &data[ptr + 2]; + + switch (tag) { + case NH_EVENT_INIT_TAG_CAP: + /* Device capabilities, length should be 1 */ + init->capabilities = val[0]; + break; + case NH_EVENT_INIT_TAG_FREQ: + init->spi_freq = val[0]; + break; + case NH_EVENT_INIT_TAG_CHIP_ID: + init->chip_id = val[0]; + break; + case NH_EVENT_INIT_TAG_RAW_TP: + /* Not implemented */ + default: + break; + } + + ptr += 2 + len; /* Increment, total length is 2 + payload length */ + } + + return NH_RET_SUCCESS; +} \ No newline at end of file diff --git a/src/nh_shared_if.c b/src/nh_shared_if.c index 3884f6d..f0b556a 100644 --- a/src/nh_shared_if.c +++ b/src/nh_shared_if.c @@ -24,6 +24,10 @@ typedef enum { NH_SHARED_IF_TYPE_PRIV = 4U, } nh_xfer_type_t; +typedef enum { + NH_SHARED_IF_PRIV_TYPE_EVENT, +} nh_xfer_priv_type_t; + typedef struct { nh_xfer_type_t type; uint8_t *buf; @@ -46,6 +50,9 @@ typedef struct __attribute__((packed)) { }; /* Offset: 0x0B */ } nh_xfer_pkt_hdr_t; /* Size: 0x0C (12 bytes) */ +static void nh_shared_if_dispatch_if_serial(nh_shared_if_t *shared_if, uint8_t *payload, uint16_t len); +static void nh_shared_if_dispatch_if_priv(nh_shared_if_t *shared_if, nh_xfer_priv_type_t type, uint8_t *payload); + static uint16_t nh_shared_if_checksum_calculate(nh_xfer_pkt_hdr_t *hdr); static bool nh_shared_if_checksum_verify(nh_xfer_pkt_hdr_t *hdr); @@ -212,38 +219,69 @@ void nh_shared_if_task(nh_shared_if_t *shared_if) { item.type = LE16_TO_H(hdr->if_type); item.buf_len = LE16_TO_H(hdr->len); - - uint16_t payload_offset = LE16_TO_H(hdr->offset); + item.buf = &shared_if->p_buf_frame_rx[LE16_TO_H(hdr->offset)]; /* DO NOT FREE THIS!! */ if (item.type == NH_SHARED_IF_TYPE_SERIAL) { - if (item.buf_len) { - /* Allocate payload */ - ret = shared_if->osa->buf_allocate(shared_if->osa->user_data, &item.buf, item.buf_len); - if (ret != NH_RET_SUCCESS) { + if (!item.buf_len) { + return; + } + + nh_shared_if_dispatch_if_serial(shared_if, item.buf, item.buf_len); + } else if (item.type == NH_SHARED_IF_TYPE_PRIV) { + if (!item.buf_len) { + return; + } + + nh_shared_if_dispatch_if_priv(shared_if, hdr->priv_pkt_type, item.buf); + } + } +} + +static void nh_shared_if_dispatch_if_priv(nh_shared_if_t *shared_if, nh_xfer_priv_type_t type, uint8_t *payload) { + if (type == NH_SHARED_IF_PRIV_TYPE_EVENT) { + /* Event is using PRIV interface. */ + nh_event_type_t evt_type; + nh_event_get_type(&evt_type, payload); + + switch (evt_type) { + case NH_EVENT_TYPE_INIT: { + nh_event_init_t evt_init; + nh_event_parse_init(&evt_init, payload); + + if (!shared_if->cb.init) { return; } - memcpy(item.buf, &shared_if->p_buf_frame_rx[payload_offset], item.buf_len); - } - - /* Enqueue response */ - ret = shared_if->osa->queue_enqueue(shared_if->osa->user_data, shared_if->p_queue_rx_ctrl, &item, 0); - if (ret != NH_RET_SUCCESS) { - /* Queue is full, maybe the ctrl interface is not active. */ - shared_if->osa->buf_free(shared_if->osa->user_data, item.buf); - } - } else if (item.type == NH_SHARED_IF_TYPE_PRIV) { - /* Event is using PRIV interface. */ - if (item.buf_len) { - if (shared_if->cb.event) { - /* Note: This is a blocking callback !! */ - shared_if->cb.event(shared_if->user_data, &shared_if->p_buf_frame_rx[payload_offset]); - } + shared_if->cb.init(shared_if->user_data, &evt_init); } } } } +static void nh_shared_if_dispatch_if_serial(nh_shared_if_t *shared_if, uint8_t *payload, uint16_t len) { + nh_ret_t ret = NH_RET_SUCCESS; + + nh_xfer_queue_item_t item; + + item.type = NH_SHARED_IF_TYPE_SERIAL; + item.buf_len = len; + + /* Allocate payload */ + ret = shared_if->osa->buf_allocate(shared_if->osa->user_data, &item.buf, item.buf_len); + if (ret != NH_RET_SUCCESS) { + return; + } + + memcpy(item.buf, payload, item.buf_len); + + /* Enqueue response */ + ret = shared_if->osa->queue_enqueue(shared_if->osa->user_data, shared_if->p_queue_rx_ctrl, &item, 0); + if (ret != NH_RET_SUCCESS) { + /* Queue is full, maybe the ctrl interface is not active, drop the packet */ + shared_if->osa->buf_free(shared_if->osa->user_data, item.buf); + } +} + static uint16_t nh_shared_if_checksum_calculate(nh_xfer_pkt_hdr_t *hdr) { uint16_t checksum = 0U;