diff options
Diffstat (limited to 'fw/esp32/components')
26 files changed, 964 insertions, 705 deletions
diff --git a/fw/esp32/components/eos/CMakeLists.txt b/fw/esp32/components/eos/CMakeLists.txt index 404b855..8750f85 100644 --- a/fw/esp32/components/eos/CMakeLists.txt +++ b/fw/esp32/components/eos/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRCS "app_main.c" "msgq.c" "unicode.c" "gsm.c" "gsm_cp.c" "at_cmd.c" "cell.c" "cell_modem.c" "cell_pcm.c" "cell_voice.c" "cell_ussd.c" "cell_sms.c" "cell_pdp.c" "wifi.c" "net.c" "power.c" "rng.c" "sock.c" "app.c" "tun.c" +idf_component_register(SRCS "app_main.c" "msgq.c" "unicode.c" "power.c" "net.c" "app.c" "rng.c" "wifi.c" "sock.c" "tun.c" "gsm.c" "gsm_cp.c" "at_cmd.c" "cell.c" "cell_modem.c" "cell_pcm.c" "cell_voice.c" "cell_ussd.c" "cell_sms.c" "cell_pdp.c" INCLUDE_DIRS "include" REQUIRES esp_driver_gpio esp_driver_spi esp_driver_uart esp_driver_i2s esp_event esp_netif esp_wifi esp_timer vfs) diff --git a/fw/esp32/components/eos/app.c b/fw/esp32/components/eos/app.c index 662da17..ab04c2c 100644 --- a/fw/esp32/components/eos/app.c +++ b/fw/esp32/components/eos/app.c @@ -16,48 +16,62 @@ #include "eos.h" #include "msgq.h" #include "power.h" +#include "net.h" #include "app.h" #include "net_priv.h" -#define SPI_GPIO_CTS 9 #define SPI_GPIO_RTS 47 +#define SPI_GPIO_CTS 9 #define SPI_GPIO_MOSI 11 #define SPI_GPIO_MISO 13 #define SPI_GPIO_SCLK 12 #define SPI_GPIO_CS 10 -#define SPI_SIZE_BUF (EOS_APP_SIZE_BUF + 4) -#define SPI_SIZE_HDR 3 - #define SPI_HOST SPI2_HOST +#define APP_SIZE_BUFQ 16 +#define APP_SIZE_SNDQ 16 + static EOSBufQ app_buf_q; -static unsigned char *app_bufq_array[EOS_APP_SIZE_BUFQ]; +static unsigned char *app_bufq_array[APP_SIZE_BUFQ]; static EOSMsgQ app_send_q; -static EOSMsgItem app_sndq_array[EOS_APP_SIZE_SNDQ]; +static EOSMsgItem app_sndq_array[APP_SIZE_SNDQ]; static NETConfig app_config; static eos_net_handler_t app_handler[EOS_APP_MAX_MTYPE]; static spi_bus_config_t app_spi_bus_cfg; static spi_slave_interface_config_t app_spi_iface_cfg; -static spi_slave_transaction_t app_spi_tr_cfg; static const char *TAG = "EOS APP"; -static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t len) { - ESP_LOGE(TAG, "bad handler: 0x%.2X len: %d", mtype, len); +static void bad_handler(unsigned char mtype, EOSMessage *msg, uint16_t len) { + ESP_LOGE(TAG, "BAD HANDLER: 0x%.2X LEN: %d", mtype, len); +} + +static void IRAM_ATTR app_bridge(unsigned char mtype, EOSMessage *msg, uint16_t len) { + EOSMessage _msg; + int rv; + + eos_net_alloc(&_msg); + if (len > _msg.size) { + eos_net_free(&_msg); + return; + } + memcpy(_msg.buffer, msg->buffer, len); + rv = eos_net_send(mtype & EOS_NET_MTYPE_MASK, &_msg, len); + if (rv) ESP_LOGE(TAG, "BRIDGE ERR: %d", rv); } -static void app_msg_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { +static void IRAM_ATTR app_msg_handler(unsigned char mtype, EOSMessage *msg, uint16_t len) { uint8_t idx; - idx = mtype & EOS_NET_MTYPE_MASK; - if (idx && (idx <= EOS_APP_MAX_MTYPE) && (buf_len <= EOS_APP_MTU)) { - app_handler[idx - 1](mtype, buffer, buf_len); + idx = mtype & EOS_NET_MTYPE_FLAG_BRIDGE ? EOS_NET_MTYPE_BRIDGE : mtype & EOS_NET_MTYPE_MASK; + if ((idx < EOS_APP_MAX_MTYPE) && (len <= msg->size)) { + app_handler[idx](mtype, msg, len); } else { - bad_handler(mtype, buffer, buf_len); + bad_handler(mtype, msg, len); } } @@ -67,12 +81,12 @@ void eos_app_init(void) { SemaphoreHandle_t bufq_semaph; int i; - eos_msgq_init(&app_send_q, app_sndq_array, EOS_APP_SIZE_SNDQ); - eos_bufq_init(&app_buf_q, app_bufq_array, EOS_APP_SIZE_BUFQ); - for (i=0; i<EOS_APP_SIZE_BUFQ; i++) { + eos_msgq_init(&app_send_q, app_sndq_array, APP_SIZE_SNDQ); + eos_bufq_init(&app_buf_q, app_bufq_array, APP_SIZE_BUFQ); + for (i=0; i<APP_SIZE_BUFQ; i++) { unsigned char *buffer; - buffer = malloc(EOS_APP_SIZE_BUF); + buffer = malloc(EOS_NET_MTU); assert(buffer != NULL); eos_bufq_push(&app_buf_q, buffer); } @@ -85,38 +99,42 @@ void eos_app_init(void) { assert(mutex != NULL); bufq_mutex = xSemaphoreCreateBinary(); assert(bufq_mutex != NULL); - bufq_semaph = xSemaphoreCreateCounting(EOS_APP_SIZE_BUFQ, EOS_APP_SIZE_BUFQ); + bufq_semaph = xSemaphoreCreateCounting(APP_SIZE_BUFQ, APP_SIZE_BUFQ); assert(bufq_semaph != NULL); xSemaphoreGive(mutex); xSemaphoreGive(bufq_mutex); - app_config.sleep = 0; + app_config.sleep = esp_reset_reason() == ESP_RST_DEEPSLEEP ? 1 : 0; app_config.sleep_req = 0; - app_config.present = 0; + app_config.present = 1; app_config.dev = NET_DEV_APP; - app_config.gpio_mosi = SPI_GPIO_MOSI; - app_config.gpio_miso = SPI_GPIO_MISO; - app_config.gpio_sclk = SPI_GPIO_SCLK; - app_config.gpio_cs = SPI_GPIO_CS; app_config.gpio_rts = SPI_GPIO_RTS; app_config.gpio_cts = SPI_GPIO_CTS; app_config.spi_host = SPI_HOST; app_config.spi_bus_cfg = &app_spi_bus_cfg; app_config.spi_iface_cfg = &app_spi_iface_cfg; - app_config.spi_tr_cfg = &app_spi_tr_cfg; app_config.mutex = mutex; app_config.bufq_mutex = bufq_mutex; app_config.bufq_semaph = bufq_semaph; app_config.buf_q = &app_buf_q; app_config.send_q = &app_send_q; - app_config.msg_handler = app_msg_handler; + app_config.handler = app_msg_handler; - _eos_net_init_gpio(&app_config); + /* Configuration for the SPI bus */ + app_spi_bus_cfg.mosi_io_num = SPI_GPIO_MOSI; + app_spi_bus_cfg.miso_io_num = SPI_GPIO_MISO; + app_spi_bus_cfg.sclk_io_num = SPI_GPIO_SCLK; + app_spi_bus_cfg.intr_flags = ESP_INTR_FLAG_IRAM; - if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { - gpio_hold_dis(app_config.gpio_cts); - } + /* Configuration for the SPI slave interface */ + app_spi_iface_cfg.mode = 0; + app_spi_iface_cfg.spics_io_num = SPI_GPIO_CS; + app_spi_iface_cfg.queue_size = 2; + app_spi_iface_cfg.flags = 0; + + _eos_net_init_gpio(&app_config); + eos_app_set_handler(EOS_NET_MTYPE_BRIDGE, app_bridge); ESP_LOGI(TAG, "INIT"); } @@ -130,16 +148,16 @@ void eos_app_run(void) { ESP_LOGI(TAG, "RUN"); } -unsigned char *eos_app_alloc(void) { - return _eos_net_alloc(&app_config); +void eos_app_alloc(EOSMessage *msg) { + _eos_net_alloc(&app_config, msg); } -void eos_app_free(unsigned char *buf) { - _eos_net_free(&app_config, buf); +void eos_app_free(EOSMessage *msg) { + _eos_net_free(&app_config, msg); } -int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { - return _eos_net_send(&app_config, mtype, buffer, buf_len); +int eos_app_send(unsigned char mtype, EOSMessage *msg, uint16_t len) { + return _eos_net_send(&app_config, mtype, msg, len); } void eos_app_sleep_req(void) { @@ -150,7 +168,15 @@ void eos_app_wake(void) { _eos_net_wake(&app_config); } +void eos_app_deep_sleep(void) { + _eos_net_deep_sleep(&app_config); +} + +void eos_app_deep_wake(void) { + _eos_net_deep_wake(&app_config); +} + void eos_app_set_handler(unsigned char mtype, eos_net_handler_t handler) { if (handler == NULL) handler = bad_handler; - if (mtype && (mtype <= EOS_APP_MAX_MTYPE)) app_handler[mtype - 1] = handler; + if (mtype < EOS_APP_MAX_MTYPE) app_handler[mtype] = handler; } diff --git a/fw/esp32/components/eos/app_main.c b/fw/esp32/components/eos/app_main.c index 941e01c..885f9c8 100644 --- a/fw/esp32/components/eos/app_main.c +++ b/fw/esp32/components/eos/app_main.c @@ -9,14 +9,14 @@ #include <esp_err.h> #include <esp_log.h> -#include "cell.h" +#include "power.h" #include "net.h" +#include "app.h" +#include "rng.h" #include "wifi.h" #include "sock.h" -#include "rng.h" -#include "app.h" #include "tun.h" -#include "power.h" +#include "cell.h" #define ESP_INTR_FLAG_DEFAULT 0 @@ -33,6 +33,7 @@ void app_main() { ret = gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); assert(ret == ESP_OK); + /* first one */ eos_power_init(); eos_net_init(); @@ -47,11 +48,13 @@ void app_main() { eos_sock_init(); eos_rng_init(); - eos_power_run(); eos_net_run(); eos_app_run(); eos_modem_run(); eos_cell_run(); eos_wifi_run(); eos_sock_run(); + + /* last one */ + eos_power_run(); } diff --git a/fw/esp32/components/eos/cell.c b/fw/esp32/components/eos/cell.c index 8665616..7dc4a32 100644 --- a/fw/esp32/components/eos/cell.c +++ b/fw/esp32/components/eos/cell.c @@ -23,24 +23,29 @@ static unsigned char *cell_bufq_array[CELL_SIZE_QUEUE]; static SemaphoreHandle_t mutex; static QueueHandle_t cell_queue; -static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { - uint8_t mtype; +static void _cell_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char mtype; + unsigned char *buffer = msg->buffer; + int rv; + + if (len < 1) return; mtype = buffer[0]; switch (mtype & EOS_CELL_MTYPE_MASK) { case EOS_CELL_MTYPE_DEV: { switch (mtype & ~EOS_CELL_MTYPE_MASK) { case EOS_CELL_MTYPE_STATUS: { - size_t rv; + size_t _rv; + + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) break; + if (msg->size < 3) break; - rv = eos_modem_get_status(buffer + 1); - eos_net_reply(EOS_NET_MTYPE_CELL, buffer, rv + 1); + _rv = eos_modem_get_status(buffer + 1); + eos_net_reply(EOS_NET_MTYPE_CELL, msg, _rv + 1); break; } case EOS_CELL_MTYPE_RESET: { - int rv; - rv = eos_modem_take(1000); if (rv) { ESP_LOGE(TAG, "Reset modem failed: %d", rv); @@ -52,8 +57,6 @@ static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t } case EOS_CELL_MTYPE_UART_TAKE: { - int rv; - if (eos_modem_get_mode() == EOS_CELL_UART_MODE_ATCMD) { rv = eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY); if (rv) ESP_LOGE(TAG, "Set RELAY mode failed: %d", rv); @@ -62,8 +65,6 @@ static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t } case EOS_CELL_MTYPE_UART_GIVE: { - int rv; - if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) { rv = eos_modem_take(1000); if (!rv) { @@ -78,7 +79,7 @@ static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t case EOS_CELL_MTYPE_UART_DATA: { if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) { - eos_modem_write(buffer + 1, buf_len - 1); + eos_modem_write(buffer + 1, len - 1); } break; } @@ -87,33 +88,35 @@ static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t } case EOS_CELL_MTYPE_VOICE: { - eos_cell_voice_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); + eos_cell_voice_handler(_mtype, msg, len); break; } case EOS_CELL_MTYPE_SMS: { - eos_cell_sms_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); + eos_cell_sms_handler(_mtype, msg, len); break; } case EOS_CELL_MTYPE_USSD: { - eos_cell_ussd_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); + eos_cell_ussd_handler(_mtype, msg, len); break; } case EOS_CELL_MTYPE_PDP: { - eos_cell_pdp_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); + eos_cell_pdp_handler(_mtype, msg, len); break; } } } static void cell_handler_task(void *pvParameters) { + EOSMessage msg; EOSMsgItem mi; while (1) { if (xQueueReceive(cell_queue, &mi, portMAX_DELAY)) { - _cell_handler(mi.type, mi.buffer, mi.len); + eos_msg_init(&msg, mi.buffer, mi.size); + _cell_handler(mi.type, &msg, mi.len); xSemaphoreTake(mutex, portMAX_DELAY); eos_bufq_push(&cell_buf_q, mi.buffer); xSemaphoreGive(mutex); @@ -122,30 +125,32 @@ static void cell_handler_task(void *pvParameters) { vTaskDelete(NULL); } -static void cell_handler(unsigned char type, unsigned char *buffer, uint16_t buf_len) { +static void cell_handler(unsigned char type, EOSMessage *msg, uint16_t len) { EOSMsgItem mi; - unsigned char *_buffer; + unsigned char *buffer; - if (buf_len < 1) return; + if (len < 1) return; + if (len > EOS_CELL_MTU) return; - if (type & EOS_NET_MTYPE_FLAG_REPL) { - _cell_handler(type, buffer, buf_len); + if (eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ) { + _cell_handler(type, msg, len); return; } xSemaphoreTake(mutex, portMAX_DELAY); - _buffer = eos_bufq_pop(&cell_buf_q); + buffer = eos_bufq_pop(&cell_buf_q); xSemaphoreGive(mutex); - if (_buffer == NULL) { - ESP_LOGE(TAG, "Cell message NOT handled: %2x", buffer[0]); + if (buffer == NULL) { + ESP_LOGE(TAG, "CELL MESSAGE NOT HANDLED: %2x", msg->buffer[0]); return; } - memcpy(_buffer, buffer, buf_len); mi.type = type; - mi.buffer = _buffer; - mi.len = buf_len; + mi.buffer = buffer; + mi.size = EOS_CELL_MTU; + memcpy(mi.buffer, msg->buffer, len); + mi.len = len; xQueueSend(cell_queue, &mi, portMAX_DELAY); } @@ -156,7 +161,7 @@ void eos_cell_init(void) { for (i=0; i<CELL_SIZE_QUEUE; i++) { unsigned char *buffer; - buffer = malloc(EOS_NET_SIZE_BUF); + buffer = malloc(EOS_CELL_MTU); assert(buffer != NULL); eos_bufq_push(&cell_buf_q, buffer); } diff --git a/fw/esp32/components/eos/cell_modem.c b/fw/esp32/components/eos/cell_modem.c index 4f8efd1..9a024ae 100644 --- a/fw/esp32/components/eos/cell_modem.c +++ b/fw/esp32/components/eos/cell_modem.c @@ -152,17 +152,21 @@ static void uart_data_read(uint8_t mode) { } case EOS_CELL_UART_MODE_RELAY: { - unsigned char *buf; + EOSMessage msg; int rv; rd = 0; do { int _rd; - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; - _rd = eos_modem_read(buf + 1, MIN(bsize - rd, EOS_NET_SIZE_BUF - 1), 100); - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, _rd + 1); + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + break; + } + msg.buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; + _rd = eos_modem_read(msg.buffer + 1, MIN(bsize - rd, msg.size - 1), 100); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, _rd + 1); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); rd += _rd; } while (rd != bsize); @@ -330,13 +334,18 @@ static void modem_event_task(void *pvParameters) { } case MODEM_ETYPE_STATUS: { - unsigned char *buf; + EOSMessage msg; int rv; - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; - memcpy(buf + 1, evt.param, evt.param_len); - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, evt.param_len + 1); + eos_net_alloc(&msg); + if (msg.size < 3) { + eos_net_free(&msg); + break; + } + + msg.buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; + memcpy(msg.buffer + 1, evt.param, evt.param_len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, evt.param_len + 1); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); break; } @@ -633,6 +642,19 @@ static int ppp_setup(void) { return EOS_OK; } +static void modem_init_ri(void) { + gpio_config_t io_conf = { + .pin_bit_mask = BIT64(UART_GPIO_RI), + .mode = GPIO_MODE_INPUT, + .intr_type = GPIO_INTR_NEGEDGE, + .pull_up_en = 1, + .pull_down_en = 0, + }; + + gpio_config(&io_conf); + gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL); +} + void eos_modem_init(void) { gpio_config_t io_conf = {}; uart_config_t uart_config = { @@ -652,6 +674,25 @@ void eos_modem_init(void) { ret = uart_driver_install(UART_PORT, UART_SIZE_IO_BUF, UART_SIZE_IO_BUF, 10, &uart_queue, 0); assert(ret == ESP_OK); + mutex = xSemaphoreCreateBinary(); + assert(mutex != NULL); + if (esp_reset_reason() != ESP_RST_DEEPSLEEP) { + xSemaphoreGive(mutex); + } + + uart_mutex = xSemaphoreCreateBinary(); + assert(uart_mutex != NULL); + if (esp_reset_reason() != ESP_RST_DEEPSLEEP) { + xSemaphoreGive(uart_mutex); + } + + ppp_mutex = xSemaphoreCreateBinary(); + assert(ppp_mutex != NULL); + xSemaphoreGive(ppp_mutex); + + modem_queue = xQueueCreate(4, sizeof(modem_event_t)); + assert(modem_queue != NULL); + // Configuration for the RST/DTR/USB/RI lines gpio_set_level(MODEM_GPIO_RST, 1); io_conf.intr_type = GPIO_INTR_DISABLE; @@ -661,7 +702,7 @@ void eos_modem_init(void) { io_conf.pull_down_en = 0; gpio_config(&io_conf); - gpio_set_level(UART_GPIO_DTR, 0); + gpio_set_level(UART_GPIO_DTR, esp_reset_reason() == ESP_RST_DEEPSLEEP ? 1 : 0); /* enable USB MUX and grab signals */ gpio_set_level(MODEM_GPIO_USB_EN, 0); gpio_set_level(MODEM_GPIO_USB_S, 1); @@ -672,37 +713,10 @@ void eos_modem_init(void) { io_conf.pull_down_en = 0; gpio_config(&io_conf); - io_conf.intr_type = GPIO_INTR_NEGEDGE; - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pin_bit_mask = BIT64(UART_GPIO_RI); - io_conf.pull_up_en = 1; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); - - if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { - gpio_hold_dis(UART_GPIO_DTR); - gpio_hold_dis(MODEM_GPIO_USB_EN); - gpio_hold_dis(MODEM_GPIO_USB_S); - } else { - modem_present = 0; - modem_initialized = 0; + if (esp_reset_reason() != ESP_RST_DEEPSLEEP) { + modem_init_ri(); } - mutex = xSemaphoreCreateBinary(); - assert(mutex != NULL); - xSemaphoreGive(mutex); - - uart_mutex = xSemaphoreCreateBinary(); - assert(uart_mutex != NULL); - xSemaphoreGive(uart_mutex); - - ppp_mutex = xSemaphoreCreateBinary(); - assert(ppp_mutex != NULL); - xSemaphoreGive(ppp_mutex); - - modem_queue = xQueueCreate(4, sizeof(modem_event_t)); - assert(modem_queue != NULL); - at_init(); rv = at_urc_insert("^RDY", modem_atinit_handler, REG_EXTENDED); assert(rv == EOS_OK); @@ -717,7 +731,13 @@ void eos_modem_init(void) { void eos_modem_run(void) { BaseType_t rv; - gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL); + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + eos_modem_deep_wake(); + } else { + uart_mode = EOS_CELL_UART_MODE_NONE; + modem_present = 0; + modem_initialized = 0; + } rv = xTaskCreate(uart_event_task, "uart_event", EOS_TASK_SSIZE_UART, NULL, EOS_TASK_PRIORITY_UART, NULL); assert(rv == pdPASS); @@ -952,43 +972,30 @@ void eos_modem_sleep_req(void) { if (rv == pdFALSE) ESP_LOGE(TAG, "Obtaining UART mutex before sleep failed"); gpio_isr_handler_remove(UART_GPIO_RI); gpio_reset_pin(UART_GPIO_RI); - /* for deep sleep */ - gpio_hold_en(UART_GPIO_DTR); - gpio_hold_en(MODEM_GPIO_USB_EN); - gpio_hold_en(MODEM_GPIO_USB_S); + eos_power_sleep_rdy(EOS_PWR_DEV_MODEM); } void eos_modem_wake(void) { - gpio_config_t io_conf = { - .pin_bit_mask = BIT64(UART_GPIO_RI), - .mode = GPIO_MODE_INPUT, - .intr_type = GPIO_INTR_NEGEDGE, - }; - uint32_t dev; - - gpio_hold_dis(UART_GPIO_DTR); - gpio_hold_dis(MODEM_GPIO_USB_EN); - gpio_hold_dis(MODEM_GPIO_USB_S); - - gpio_config(&io_conf); - gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL); - + modem_init_ri(); uart_change_mode(uart_mode); xSemaphoreGive(uart_mutex); xSemaphoreGive(mutex); gpio_set_level(UART_GPIO_DTR, 0); +} - dev = eos_power_wakeup_source(); - if (dev == EOS_PWR_DEV_MODEM) { - modem_event_t evt; - - evt.type = MODEM_ETYPE_RING; - xQueueSend(modem_queue, &evt, portMAX_DELAY); - } +void eos_modem_deep_sleep(void) { + gpio_hold_en(UART_GPIO_DTR); + gpio_hold_en(MODEM_GPIO_USB_EN); + gpio_hold_en(MODEM_GPIO_USB_S); } +void eos_modem_deep_wake(void) { + gpio_hold_dis(UART_GPIO_DTR); + gpio_hold_dis(MODEM_GPIO_USB_EN); + gpio_hold_dis(MODEM_GPIO_USB_S); +} void eos_ppp_get_apn(char *apn) { xSemaphoreTake(mutex, portMAX_DELAY); diff --git a/fw/esp32/components/eos/cell_pcm.c b/fw/esp32/components/eos/cell_pcm.c index 3f5089d..67a3a08 100644 --- a/fw/esp32/components/eos/cell_pcm.c +++ b/fw/esp32/components/eos/cell_pcm.c @@ -23,16 +23,20 @@ static i2s_chan_handle_t rx_chan; static const char *TAG = "EOS CELL PCM"; static void pcm_rcvr_task(void *pvParameters) { - unsigned char *buffer; + EOSMessage msg; size_t size_r; esp_err_t ret; int done = 0; int rv; while (!done) { - buffer = eos_net_alloc(); - buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; - ret = i2s_channel_read(rx_chan, buffer + 1, PCM_RX_WM, &size_r, 1000); + eos_net_alloc(&msg); + if (msg.size < PCM_RX_WM + 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; + ret = i2s_channel_read(rx_chan, msg.buffer + 1, PCM_RX_WM, &size_r, 1000); switch (ret) { case ESP_OK: { assert(size_r == PCM_RX_WM); @@ -51,10 +55,10 @@ static void pcm_rcvr_task(void *pvParameters) { } } if (ret == ESP_OK) { - rv = eos_net_send(EOS_NET_MTYPE_CELL, buffer, size_r + 1); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, size_r + 1); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } else { - eos_net_free(buffer); + eos_net_free(&msg); } } vTaskDelete(NULL); diff --git a/fw/esp32/components/eos/cell_pdp.c b/fw/esp32/components/eos/cell_pdp.c index d04b66b..9ff3ed7 100644 --- a/fw/esp32/components/eos/cell_pdp.c +++ b/fw/esp32/components/eos/cell_pdp.c @@ -7,20 +7,28 @@ #include "net.h" #include "cell.h" -void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { +void eos_cell_pdp_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char mtype; + unsigned char *buffer = msg->buffer; + + if (len < 1) return; + + mtype = buffer[0] & ~EOS_CELL_MTYPE_MASK; + switch (mtype) { case EOS_CELL_MTYPE_PDP_SET_APN: case EOS_CELL_MTYPE_PDP_SET_USR: case EOS_CELL_MTYPE_PDP_SET_PWD: { - char *arg; + char arg[EOS_CELL_PDP_SIZE_ARG + 1]; buffer++; - buf_len--; + len--; - arg = (char *)buffer; - if (buf_len > EOS_CELL_PDP_SIZE_ARG) break; + if (len > EOS_CELL_PDP_SIZE_ARG) break; + + memcpy(arg, buffer, len); + arg[len] = '\0'; - buffer[buf_len] = '\0'; switch (mtype) { case EOS_CELL_MTYPE_PDP_SET_APN: { eos_ppp_set_apn(arg); @@ -43,10 +51,12 @@ void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t b case EOS_CELL_MTYPE_PDP_GET_APN: case EOS_CELL_MTYPE_PDP_GET_USR: case EOS_CELL_MTYPE_PDP_GET_PWD: { - char *arg; + char arg[EOS_CELL_PDP_SIZE_ARG + 1]; + + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) break; + if (msg->size < EOS_CELL_PDP_SIZE_ARG + 1) break; buffer[0] = EOS_CELL_MTYPE_PDP | mtype; - arg = (char *)(buffer + 1); switch (mtype) { case EOS_CELL_MTYPE_PDP_GET_APN: { eos_ppp_get_apn(arg); @@ -63,8 +73,9 @@ void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t b break; } } + memcpy(buffer + 1, arg, strlen(arg)); - eos_net_reply(EOS_NET_MTYPE_CELL, buffer, strlen(arg) + 1); + eos_net_reply(EOS_NET_MTYPE_CELL, msg, strlen(arg) + 1); break; } diff --git a/fw/esp32/components/eos/cell_sms.c b/fw/esp32/components/eos/cell_sms.c index 1cd4cda..c162d4d 100644 --- a/fw/esp32/components/eos/cell_sms.c +++ b/fw/esp32/components/eos/cell_sms.c @@ -224,26 +224,30 @@ static ssize_t sms_decode(char *pdu, size_t pdu_len, unsigned char *buf, uint16_ return buf_len; } -void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { +void eos_cell_sms_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char mtype; + unsigned char *buffer = msg->buffer; int rv; + if (len < 1) return; + + mtype = buffer[0] & ~EOS_CELL_MTYPE_MASK; buffer++; - buf_len--; + len--; + switch (mtype) { case EOS_CELL_MTYPE_SMS_LIST: { - if (buf_len < 1) return; + if (len < 1) break; rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CMGL=%d\r", buffer[0]); - if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) break; rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd(at_cmd_buf); do { - unsigned char *buf; - uint16_t buf_len; - + EOSMessage _msg; char *pdu = _pdu_in; size_t pdu_size = sizeof(_pdu_in); size_t pdu_len; @@ -257,16 +261,19 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b pdu_len = strlen(pdu); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_LIST_ITEM; - _rv = sms_decode(pdu, pdu_len, buf + 1, EOS_NET_SIZE_BUF - 1); + eos_net_alloc(&_msg); + if (_msg.size < 1) { + eos_net_free(&_msg); + continue; + } + _msg.buffer[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_LIST_ITEM; + _rv = sms_decode(pdu, pdu_len, _msg.buffer + 1, _msg.size - 1); if (_rv < 0) { - eos_net_free(buf); + eos_net_free(&_msg); continue; } - buf_len = _rv; - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &_msg, _rv + 1); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } while (1); @@ -282,19 +289,19 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b size_t pdu_len; ssize_t _rv; - _rv = sms_encode(buffer, buf_len, pdu, pdu_size); - if (_rv < 0) return; + _rv = sms_encode(buffer, len, pdu, pdu_size); + if (_rv < 0) break; pdu_len = _rv; - if (pdu_size < pdu_len + 2) return; + if (pdu_size < pdu_len + 2) break; pdu[pdu_len] = CTRL_Z; pdu[pdu_len + 1] = '\0'; rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CMGS=%d\r", pdu_len / 2); - if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) break; rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd(at_cmd_buf); // wait for: '> ' (0d 0a 3e 20) @@ -310,15 +317,13 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b } static void sms_received_handler(char *urc, regmatch_t m[]) { + EOSMessage msg; char cmd[32]; - unsigned char *buf; - uint16_t buf_len; - int ref, rv; - char *pdu = _pdu_out; size_t pdu_size = sizeof(_pdu_out); size_t pdu_len; ssize_t _rv; + int ref, rv; sscanf(urc + m[1].rm_so, "%d", &ref); @@ -337,16 +342,19 @@ static void sms_received_handler(char *urc, regmatch_t m[]) { rv = at_expect("^OK", NULL, 1000); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG; - _rv = sms_decode(pdu, pdu_len, buf + 1, EOS_NET_SIZE_BUF - 1); + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG; + _rv = sms_decode(pdu, pdu_len, msg.buffer + 1, msg.size - 1); if (_rv < 0) { - eos_net_free(buf); + eos_net_free(&msg); return; } - buf_len = _rv; - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, _rv + 1); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } diff --git a/fw/esp32/components/eos/cell_ussd.c b/fw/esp32/components/eos/cell_ussd.c index fb77b67..002391e 100644 --- a/fw/esp32/components/eos/cell_ussd.c +++ b/fw/esp32/components/eos/cell_ussd.c @@ -13,21 +13,26 @@ static const char *TAG = "EOS CELL USSD"; extern char *at_cmd_buf; -void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { +void eos_cell_ussd_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char mtype; + unsigned char *buffer = msg->buffer; int rv; + if (len < 1) return; + + mtype = buffer[0] & ~EOS_CELL_MTYPE_MASK; buffer++; - buf_len--; + len--; + switch (mtype) { case EOS_CELL_MTYPE_USSD_REQUEST: { - if (buf_len > EOS_CELL_USSD_SIZE_REQ) return; + if (len > EOS_CELL_USSD_SIZE_REQ) break; - buffer[buf_len] = '\0'; - rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CUSD=1,\"%s\",15\r", buffer); - if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; + rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CUSD=1,\"%.*s\",15\r", len, buffer); + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) break; rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd(at_cmd_buf); rv = at_expect("^OK", "^ERROR", 1000); @@ -38,7 +43,7 @@ void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t case EOS_CELL_MTYPE_USSD_CANCEL: { rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd("AT+CUSD=2\r"); rv = at_expect("^OK", "^ERROR", 1000); @@ -50,59 +55,63 @@ void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t } static void ussd_reply_handler(char *urc, regmatch_t m[]) { - int rep, rv; - unsigned char *buf; + EOSMessage msg; uint16_t len; - char *_buf; - size_t _len; + char *rbuf; + size_t rlen; + int rep, rv; sscanf(urc + m[1].rm_so, "%1d", &rep); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_USSD | EOS_CELL_MTYPE_USSD_REPLY; - buf[1] = rep; + eos_net_alloc(&msg); + if (msg.size < 2) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_USSD | EOS_CELL_MTYPE_USSD_REPLY; + msg.buffer[1] = rep; len = 2; if (m[2].rm_so == -1) { - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, len); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); return; } - _buf = (char *)buf + len; - _len = m[2].rm_eo - m[2].rm_so - 2; - if (_len > EOS_NET_SIZE_BUF - len) { - eos_net_free(buf); + rbuf = (char *)msg.buffer + len; + rlen = m[2].rm_eo - m[2].rm_so - 2; + if (msg.size < rlen + len + 1) { + eos_net_free(&msg); return; } - memcpy(_buf, urc + m[2].rm_so + 2, _len); - len += _len; + memcpy(rbuf, urc + m[2].rm_so + 2, rlen); + rbuf[rlen] = '\0'; rv = EOS_OK; do { char *end; - end = strchr(_buf, '"'); + end = strchr(rbuf, '"'); if (end) { - len += end - _buf; + len += end - rbuf; break; } else { - _len = strlen(_buf); - _buf[_len] = '\n'; - _buf += _len + 1; - len += _len + 1; + rlen = strlen(rbuf); + rbuf[rlen] = '\n'; + rbuf += rlen + 1; + len += rlen + 1; } - rv = eos_modem_readln(_buf, EOS_NET_SIZE_BUF - len, 1000); + rv = eos_modem_readln(rbuf, msg.size - len, 1000); if (rv) break; } while (1); if (rv) { - ESP_LOGE(TAG, "error"); - eos_net_free(buf); + ESP_LOGE(TAG, "ERROR"); + eos_net_free(&msg); return; } - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, len); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } diff --git a/fw/esp32/components/eos/cell_voice.c b/fw/esp32/components/eos/cell_voice.c index 273b402..0ec543b 100644 --- a/fw/esp32/components/eos/cell_voice.c +++ b/fw/esp32/components/eos/cell_voice.c @@ -17,21 +17,26 @@ static const char *TAG = "EOS CELL VOICE"; extern char *at_cmd_buf; -void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { +void eos_cell_voice_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char mtype; + unsigned char *buffer = msg->buffer; int rv; + if (len < 1) return; + + mtype = buffer[0] & ~EOS_CELL_MTYPE_MASK; buffer++; - buf_len--; + len--; + switch (mtype) { case EOS_CELL_MTYPE_VOICE_DIAL: { - if (buf_len > EOS_CELL_SIZE_PHNUM) return; + if (len > EOS_CELL_SIZE_PHNUM) break; - buffer[buf_len] = '\0'; - rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "ATD%s;\r", buffer); - if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; + rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "ATD%.*s;\r", len, buffer); + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) break; rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd(at_cmd_buf); rv = at_expect("^OK", "^(ERROR|\\+CME ERROR: [0-9]+)", 1000); @@ -43,7 +48,7 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t case EOS_CELL_MTYPE_VOICE_ANSWER: { rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd("ATA\r"); // Response will be picked up by urc handler @@ -57,7 +62,7 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t eos_cell_pcm_stop(); rv = eos_modem_take(1000); - if (rv) return; + if (rv) break; at_cmd("AT+CHUP\r"); // Response will be picked up by urc handler @@ -67,70 +72,84 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t } case EOS_CELL_MTYPE_VOICE_PCM: { - eos_cell_pcm_push(buffer, buf_len); + eos_cell_pcm_push(buffer, len); break; } } } static void ring_handler(char *urc, regmatch_t m[]) { - unsigned char *buf; - char *ring_buf; + EOSMessage msg; uint16_t len; + char *buffer; regmatch_t match[2]; int rv = EOS_OK; - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_RING; + eos_net_alloc(&msg); + if (msg.size < EOS_CELL_SIZE_PHNUM + 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_RING; len = 1; - rv = at_expect_match("^\\+CLIP: \"(\\+?[0-9]+)\"", NULL, &ring_buf, match, 2, REG_EXTENDED, 1000); + rv = at_expect_match("^\\+CLIP: \"(\\+?[0-9]+)\"", NULL, &buffer, match, 2, REG_EXTENDED, 1000); if (!rv) { regoff_t num_len; num_len = match[1].rm_eo - match[1].rm_so; if (num_len > EOS_CELL_SIZE_PHNUM) { - eos_net_free(buf); + eos_net_free(&msg); return; } - memcpy(buf + 1, ring_buf + match[1].rm_so, num_len); + memcpy(msg.buffer + 1, buffer + match[1].rm_so, num_len); len += num_len; } - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, len); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } static void busy_handler(char *urc, regmatch_t m[]) { - unsigned char *buf; - uint16_t len; + EOSMessage msg; int rv; eos_cell_pcm_stop(); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BUSY; - len = 1; - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BUSY; + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, 1); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } static void miss_handler(char *urc, regmatch_t m[]) { - unsigned char *buf; - uint16_t len; + EOSMessage msg; int rv; eos_cell_pcm_stop(); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_MISS; - len = 1; - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_MISS; + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, 1); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } static void call_begin_handler(char *urc, regmatch_t m[]) { - unsigned char *buf; + EOSMessage msg; int rv; + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + vTaskDelay(100 / portTICK_PERIOD_MS); at_cmd("AT+CECH=0x0000\r"); at_expect("^OK", "^ERROR", 1000); @@ -148,27 +167,31 @@ static void call_begin_handler(char *urc, regmatch_t m[]) { at_expect("^OK", "^ERROR", 1000); */ - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BEGIN; - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, 1); + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BEGIN; + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, 1); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } static void call_end_handler(char *urc, regmatch_t m[]) { - unsigned char *buf; + EOSMessage msg; int duration = 0; int rv; eos_cell_pcm_stop(); + eos_net_alloc(&msg); + if (msg.size < 5) { + eos_net_free(&msg); + return; + } + sscanf(urc + m[1].rm_so, "%6d", &duration); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_END; - buf[1] = duration >> 24; - buf[2] = duration >> 16; - buf[3] = duration >> 8; - buf[4] = duration; - rv = eos_net_send(EOS_NET_MTYPE_CELL, buf, 5); + msg.buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_END; + msg.buffer[1] = duration >> 24; + msg.buffer[2] = duration >> 16; + msg.buffer[3] = duration >> 8; + msg.buffer[4] = duration; + rv = eos_net_send(EOS_NET_MTYPE_CELL, &msg, 5); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } diff --git a/fw/esp32/components/eos/include/app.h b/fw/esp32/components/eos/include/app.h index b6dba99..38fba1a 100644 --- a/fw/esp32/components/eos/include/app.h +++ b/fw/esp32/components/eos/include/app.h @@ -2,25 +2,20 @@ #include "net.h" -/* common */ -#define EOS_APP_MTU 1500 -#define EOS_APP_SIZE_BUF EOS_APP_MTU - #define EOS_APP_MTYPE_TUN 1 #define EOS_APP_MAX_MTYPE 8 -/* esp32 specific */ -#define EOS_APP_SIZE_BUFQ 4 -#define EOS_APP_SIZE_SNDQ 4 - void eos_app_init(void); void eos_app_run(void); -unsigned char *eos_app_alloc(void); -void eos_app_free(unsigned char *buf); +void eos_app_alloc(EOSMessage *msg); +void eos_app_free(EOSMessage *msg); -int eos_app_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); +int eos_app_send(unsigned char mtype, EOSMessage *msg, uint16_t len); void eos_app_sleep_req(void); void eos_app_wake(void); +void eos_app_deep_sleep(void); +void eos_app_deep_wake(void); + void eos_app_set_handler(unsigned char mtype, eos_net_handler_t handler); diff --git a/fw/esp32/components/eos/include/cell.h b/fw/esp32/components/eos/include/cell.h index c1e7545..30347c1 100644 --- a/fw/esp32/components/eos/include/cell.h +++ b/fw/esp32/components/eos/include/cell.h @@ -1,6 +1,10 @@ #include <sys/types.h> #include <stdint.h> +#include "net.h" + +#define EOS_CELL_MTU EOS_NET_MTU + #define EOS_CELL_MTYPE_DEV 0x10 #define EOS_CELL_MTYPE_VOICE 0x20 #define EOS_CELL_MTYPE_SMS 0x30 @@ -95,6 +99,8 @@ void eos_modem_give(void); void eos_modem_sleep_req(void); void eos_modem_wake(void); +void eos_modem_deep_sleep(void); +void eos_modem_deep_wake(void); void eos_ppp_get_apn(char *apn); void eos_ppp_set_apn(char *apn); @@ -110,10 +116,10 @@ void eos_cell_pcm_push(unsigned char *data, size_t size); void eos_cell_pcm_start(void); void eos_cell_pcm_stop(void); -void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); -void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); -void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); -void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); +void eos_cell_voice_handler(unsigned char mtype, EOSMessage *msg, uint16_t len); +void eos_cell_sms_handler(unsigned char mtype, EOSMessage *msg, uint16_t len); +void eos_cell_ussd_handler(unsigned char mtype, EOSMessage *msg, uint16_t len); +void eos_cell_pdp_handler(unsigned char mtype, EOSMessage *msg, uint16_t len); void eos_cell_voice_init(void); void eos_cell_sms_init(void); diff --git a/fw/esp32/components/eos/include/eos.h b/fw/esp32/components/eos/include/eos.h index e772637..3f9755d 100644 --- a/fw/esp32/components/eos/include/eos.h +++ b/fw/esp32/components/eos/include/eos.h @@ -11,14 +11,14 @@ #define EOS_ERR_NOMEM -100 -#define EOS_TASK_PRIORITY_NET 1 -#define EOS_TASK_PRIORITY_APP 1 -#define EOS_TASK_PRIORITY_SOCK 1 -#define EOS_TASK_PRIORITY_UART 1 -#define EOS_TASK_PRIORITY_MODEM 1 -#define EOS_TASK_PRIORITY_PCM 1 -#define EOS_TASK_PRIORITY_CELL 1 -#define EOS_TASK_PRIORITY_PWR 1 +#define EOS_TASK_PRIORITY_NET 16 +#define EOS_TASK_PRIORITY_APP 17 +#define EOS_TASK_PRIORITY_SOCK 10 +#define EOS_TASK_PRIORITY_UART 10 +#define EOS_TASK_PRIORITY_MODEM 10 +#define EOS_TASK_PRIORITY_PCM 10 +#define EOS_TASK_PRIORITY_CELL 10 +#define EOS_TASK_PRIORITY_PWR 10 #define EOS_TASK_SSIZE_NET 8192 #define EOS_TASK_SSIZE_APP 8192 diff --git a/fw/esp32/components/eos/include/msgq.h b/fw/esp32/components/eos/include/msgq.h index b5ae9ac..2b216d1 100644 --- a/fw/esp32/components/eos/include/msgq.h +++ b/fw/esp32/components/eos/include/msgq.h @@ -1,8 +1,27 @@ #include <stdint.h> +#ifndef _EOS_MSGQ_H_ +#define _EOS_MSGQ_H_ + +#define EOS_MSG_FLAG_WAKE 0x01 +#define EOS_MSG_FLAG_RPLY_REQ 0x02 +#define EOS_MSG_FLAG_RPLY_REP 0x04 + +typedef struct EOSMessage { + unsigned char *buffer; + uint16_t size; + uint8_t flags; +} EOSMessage; + +void eos_msg_init(EOSMessage *msg, unsigned char *buffer, uint16_t size); +void eos_msg_set_flags(EOSMessage *msg, uint8_t flags); +void eos_msg_clear_flags(EOSMessage *msg, uint8_t flags); +uint8_t eos_msg_flags(EOSMessage *msg); + typedef struct EOSMsgItem { unsigned char type; unsigned char *buffer; + uint16_t size; uint16_t len; } EOSMsgItem; @@ -15,8 +34,8 @@ typedef struct EOSMsgQ { void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); uint8_t eos_msgq_len(EOSMsgQ *msgq); -int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len); -void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len); +int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, EOSMessage *msg, uint16_t len); +void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, EOSMessage *msg, uint16_t *len); typedef struct EOSBufQ { uint8_t idx_r; @@ -29,3 +48,5 @@ void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size); uint8_t eos_bufq_len(EOSBufQ *bufq); int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer); unsigned char *eos_bufq_pop(EOSBufQ *bufq); + +#endif /* _EOS_MSGQ_H_ */ diff --git a/fw/esp32/components/eos/include/net.h b/fw/esp32/components/eos/include/net.h index b500e82..edf1a58 100644 --- a/fw/esp32/components/eos/include/net.h +++ b/fw/esp32/components/eos/include/net.h @@ -1,40 +1,40 @@ #include <stdint.h> -/* common */ +#include "msgq.h" + #define EOS_NET_MTU 1500 -#define EOS_NET_SIZE_BUF EOS_NET_MTU -#define EOS_NET_MTYPE_SOCK 1 -#define EOS_NET_MTYPE_WIFI 2 -#define EOS_NET_MTYPE_CELL 3 -#define EOS_NET_MTYPE_APP 4 -#define EOS_NET_MTYPE_RNG 5 +#define EOS_NET_MTYPE_BRIDGE 0 /* handler only */ +#define EOS_NET_MTYPE_WIFI 1 +#define EOS_NET_MTYPE_CELL 2 +#define EOS_NET_MTYPE_SOCK 3 +#define EOS_NET_MTYPE_RNG 4 #define EOS_NET_MAX_MTYPE 5 -#define EOS_NET_MTYPE_SLEEP 0x10 /* does not have net handler */ +#define EOS_NET_MTYPE_SLEEP 0x20 /* does not have net handler */ -#define EOS_NET_MTYPE_FLAG_ONEW 0x40 -#define EOS_NET_MTYPE_FLAG_REPL 0x80 -#define EOS_NET_MTYPE_MASK 0x3F /* 0x0F if mtype is handled by evtq */ +#define EOS_NET_MTYPE_FLAG_ONEW 0x80 +#define EOS_NET_MTYPE_FLAG_REPL 0x40 +#define EOS_NET_MTYPE_FLAG_BRIDGE 0x08 -/* esp32 specific */ -#define EOS_NET_SIZE_BUFQ 4 -#define EOS_NET_SIZE_SNDQ 4 +#define EOS_NET_MTYPE_MASK 0x0F -typedef void (*eos_net_handler_t) (unsigned char, unsigned char *, uint16_t); +typedef void (*eos_net_handler_t) (unsigned char, EOSMessage *msg, uint16_t); void eos_net_xchg_task(void *param); void eos_net_init(void); void eos_net_run(void); -unsigned char *eos_net_alloc(void); -void eos_net_free(unsigned char *buf); +void eos_net_alloc(EOSMessage *msg); +void eos_net_free(EOSMessage *msg); -int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); -void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t buf_len); +int eos_net_send(unsigned char mtype, EOSMessage *msg, uint16_t len); +void eos_net_reply(unsigned char mtype, EOSMessage *msg, uint16_t len); void eos_net_sleep_req(void); void eos_net_wake(void); +void eos_net_deep_sleep(void); +void eos_net_deep_wake(void); void eos_net_set_handler(unsigned char mtype, eos_net_handler_t handler); diff --git a/fw/esp32/components/eos/include/net_priv.h b/fw/esp32/components/eos/include/net_priv.h index fa1de61..5627e12 100644 --- a/fw/esp32/components/eos/include/net_priv.h +++ b/fw/esp32/components/eos/include/net_priv.h @@ -5,29 +5,26 @@ typedef struct NETConfig { int sleep; int sleep_req; int present; - int gpio_mosi; - int gpio_miso; - int gpio_sclk; - int gpio_cs; int gpio_rts; int gpio_cts; uint32_t dev; spi_host_device_t spi_host; spi_bus_config_t *spi_bus_cfg; spi_slave_interface_config_t *spi_iface_cfg; - spi_slave_transaction_t *spi_tr_cfg; TaskHandle_t xchg_task_handle; SemaphoreHandle_t mutex; SemaphoreHandle_t bufq_mutex; SemaphoreHandle_t bufq_semaph; EOSBufQ *buf_q; EOSMsgQ *send_q; - eos_net_handler_t msg_handler; + eos_net_handler_t handler; } NETConfig; void _eos_net_init_gpio(NETConfig *config); -unsigned char *_eos_net_alloc(NETConfig *config); -void _eos_net_free(NETConfig *config, unsigned char *buf); -int _eos_net_send(NETConfig *config, unsigned char mtype, unsigned char *buffer, uint16_t buf_len); +void _eos_net_alloc(NETConfig *config, EOSMessage *msg); +void _eos_net_free(NETConfig *config, EOSMessage *msg); +int _eos_net_send(NETConfig *config, unsigned char mtype, EOSMessage *msg, uint16_t len); void _eos_net_sleep_req(NETConfig *config); void _eos_net_wake(NETConfig *config); +void _eos_net_deep_sleep(NETConfig *config); +void _eos_net_deep_wake(NETConfig *config); diff --git a/fw/esp32/components/eos/include/power.h b/fw/esp32/components/eos/include/power.h index 2590b80..c7d184c 100644 --- a/fw/esp32/components/eos/include/power.h +++ b/fw/esp32/components/eos/include/power.h @@ -20,6 +20,7 @@ void eos_power_sys_sleep(uint8_t mode); void eos_power_sys_wake(uint8_t mode) ; uint32_t eos_power_wakeup_source(void); -void eos_power_sleep_req(uint8_t mode, uint32_t dev); +void eos_power_set_mode(uint8_t mode); +void eos_power_sleep_req(uint32_t dev); void eos_power_sleep_rdy(uint32_t dev); void eos_power_wake(uint32_t dev); diff --git a/fw/esp32/components/eos/include/tun.h b/fw/esp32/components/eos/include/tun.h index 3acb2a6..ab1e0f4 100644 --- a/fw/esp32/components/eos/include/tun.h +++ b/fw/esp32/components/eos/include/tun.h @@ -1 +1,5 @@ +#include <stdint.h> + +void eos_tun_portmap_add(uint32_t ext_addr); +void eos_tun_portmap_remove(void); void eos_tun_init(void);
\ No newline at end of file diff --git a/fw/esp32/components/eos/include/wifi.h b/fw/esp32/components/eos/include/wifi.h index d080e25..0aae73a 100644 --- a/fw/esp32/components/eos/include/wifi.h +++ b/fw/esp32/components/eos/include/wifi.h @@ -1,3 +1,5 @@ +#include <sys/types.h> + #define EOS_WIFI_MTYPE_STATUS 0 #define EOS_WIFI_MTYPE_SCAN 1 #define EOS_WIFI_MTYPE_START 2 @@ -20,6 +22,6 @@ int eos_wifi_auth(char *ssid, char *pass); int eos_wifi_connect(void); int eos_wifi_disconnect(void); -ssize_t eos_wifi_get_status(unsigned char *buffer); +ssize_t eos_wifi_get_status(unsigned char *buffer, size_t size); void eos_wifi_send_status(void); void eos_wifi_send_scan(void); diff --git a/fw/esp32/components/eos/msgq.c b/fw/esp32/components/eos/msgq.c index 57fb669..50dbd3e 100644 --- a/fw/esp32/components/eos/msgq.c +++ b/fw/esp32/components/eos/msgq.c @@ -5,6 +5,24 @@ #define IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) +void eos_msg_init(EOSMessage *msg, unsigned char *buffer, uint16_t size) { + msg->buffer = buffer; + msg->size = size; + msg->flags = 0; +} + +void eos_msg_set_flags(EOSMessage *msg, uint8_t flags) { + msg->flags |= flags; +} + +void eos_msg_clear_flags(EOSMessage *msg, uint8_t flags) { + msg->flags &= ~flags; +} + +uint8_t eos_msg_flags(EOSMessage *msg) { + return msg->flags; +} + void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { msgq->idx_r = 0; msgq->idx_w = 0; @@ -16,26 +34,37 @@ uint8_t eos_msgq_len(EOSMsgQ *msgq) { return (uint8_t)(msgq->idx_w - msgq->idx_r); } -int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len) { +int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, EOSMessage *msg, uint16_t len) { + uint8_t idx; + if ((uint8_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return EOS_ERR_FULL; - uint8_t idx = IDX_MASK(msgq->idx_w, msgq->size); + idx = IDX_MASK(msgq->idx_w, msgq->size); msgq->array[idx].type = type; - msgq->array[idx].buffer = buffer; - msgq->array[idx].len = len; + if (msg) { + msgq->array[idx].buffer = msg->buffer; + msgq->array[idx].size = msg->size; + msgq->array[idx].len = len; + } else { + msgq->array[idx].buffer = NULL; + msgq->array[idx].size = 0; + msgq->array[idx].len = 0; + } msgq->idx_w++; + return EOS_OK; } -void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len) { +void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, EOSMessage *msg, uint16_t *len) { if (msgq->idx_r == msgq->idx_w) { *type = 0; - *buffer = NULL; + eos_msg_init(msg, NULL, 0); *len = 0; } else { uint8_t idx = IDX_MASK(msgq->idx_r, msgq->size); + *type = msgq->array[idx].type; - *buffer = msgq->array[idx].buffer; + eos_msg_init(msg, msgq->array[idx].buffer, msgq->array[idx].size); *len = msgq->array[idx].len; msgq->idx_r++; } diff --git a/fw/esp32/components/eos/net.c b/fw/esp32/components/eos/net.c index 0ba2a2d..dd3180a 100644 --- a/fw/esp32/components/eos/net.c +++ b/fw/esp32/components/eos/net.c @@ -27,60 +27,77 @@ #define SPI_GPIO_SCLK 38 #define SPI_GPIO_CS 8 -#define SPI_SIZE_BUF (EOS_NET_SIZE_BUF + 4) -#define SPI_SIZE_HDR 3 - #define SPI_HOST SPI3_HOST +#define NET_SIZE_BUFQ 8 +#define NET_SIZE_SNDQ 8 + +#define NET_SIZE_HDR 3 +#define NET_SIZE_BUF (EOS_NET_MTU + 4) + +// #define EOS_DEBUG 1 + static EOSBufQ net_buf_q; -static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ]; +static unsigned char *net_bufq_array[NET_SIZE_BUFQ]; static EOSMsgQ net_send_q; -static EOSMsgItem net_sndq_array[EOS_NET_SIZE_SNDQ]; +static EOSMsgItem net_sndq_array[NET_SIZE_SNDQ]; static NETConfig net_config; static eos_net_handler_t net_handler[EOS_NET_MAX_MTYPE]; static spi_bus_config_t net_spi_bus_cfg; static spi_slave_interface_config_t net_spi_iface_cfg; -static spi_slave_transaction_t net_spi_tr_cfg; static const char *TAG = "EOS NET"; -static void bad_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { - ESP_LOGE(TAG, "bad handler: 0x%.2X len: %d", mtype, buf_len); +static void bad_handler(unsigned char mtype, EOSMessage *msg, uint16_t len) { + ESP_LOGE(TAG, "BAD HANDLER: 0x%.2X LEN: %d", mtype, len); +} + +static void IRAM_ATTR net_bridge(unsigned char mtype, EOSMessage *msg, uint16_t len) { + EOSMessage _msg; + int rv; + + eos_app_alloc(&_msg); + if (len > _msg.size) { + eos_app_free(&_msg); + return; + } + memcpy(_msg.buffer, msg->buffer, len); + rv = eos_app_send(mtype & EOS_NET_MTYPE_MASK, &_msg, len); + if (rv) ESP_LOGE(TAG, "BRIDGE ERR: %d", rv); } -static void net_msg_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { +static void IRAM_ATTR net_msg_handler(unsigned char mtype, EOSMessage *msg, uint16_t len) { uint8_t idx; - idx = mtype & EOS_NET_MTYPE_MASK; - if (idx && (idx <= EOS_NET_MAX_MTYPE) && (buf_len <= EOS_NET_MTU)) { - net_handler[idx - 1](mtype, buffer, buf_len); + idx = mtype & EOS_NET_MTYPE_FLAG_BRIDGE ? EOS_NET_MTYPE_BRIDGE : mtype & EOS_NET_MTYPE_MASK; + if ((idx < EOS_NET_MAX_MTYPE) && (len <= msg->size)) { + net_handler[idx](mtype, msg, len); } else { - bad_handler(mtype, buffer, buf_len); + bad_handler(mtype, msg, len); } } /* Called after a transaction is queued and ready for pickup by master */ -static void _post_setup_cb(spi_slave_transaction_t *trans) { +static void IRAM_ATTR _post_setup_cb(spi_slave_transaction_t *trans) { NETConfig *config = trans->user; gpio_set_level(config->gpio_cts, 0); } /* Called after transaction is sent/received */ -static void _post_trans_cb(spi_slave_transaction_t *trans) { +static void IRAM_ATTR _post_trans_cb(spi_slave_transaction_t *trans) { NETConfig *config = trans->user; gpio_set_level(config->gpio_cts, 1); } -static void net_goto_sleep(NETConfig *config) { +static void net_sleep(NETConfig *config) { esp_err_t ret; uint8_t msgq_len; - xSemaphoreTake(config->mutex, portMAX_DELAY); msgq_len = eos_msgq_len(config->send_q); if (msgq_len) { @@ -93,13 +110,12 @@ static void net_goto_sleep(NETConfig *config) { ret = spi_slave_free(config->spi_host); assert(ret == ESP_OK); - /* for deep sleep */ - gpio_hold_en(config->gpio_cts); - eos_power_sleep_rdy(config->dev); - vTaskSuspend(NULL); +} - gpio_hold_dis(config->gpio_cts); +static void net_wake(NETConfig *config) { + esp_err_t ret; + uint8_t msgq_len; ret = spi_slave_initialize(config->spi_host, config->spi_bus_cfg, config->spi_iface_cfg, SPI_DMA_CH_AUTO); assert(ret == ESP_OK); @@ -115,180 +131,164 @@ static void net_goto_sleep(NETConfig *config) { xSemaphoreGive(config->mutex); } -void eos_net_xchg_task(void *param) { +void IRAM_ATTR eos_net_xchg_task(void *param) { NETConfig *config = param; - int present, skip_msg = 0, sleep_msg = 0; + int skip_msg = 0, sleep_msg = 0; unsigned char mtype = 0; unsigned char mtype_flags = 0; - unsigned char *buffer; - unsigned char *buf_send = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA); - unsigned char *buf_recv = heap_caps_malloc(SPI_SIZE_BUF, MALLOC_CAP_DMA); - uint16_t buf_len; + unsigned char *snd_buf; + unsigned char *rcv_buf; + EOSMessage msg; + uint16_t snd_buf_len, rcv_buf_len; size_t trans_len; spi_bus_config_t *spi_bus_cfg = config->spi_bus_cfg; spi_slave_interface_config_t *spi_iface_cfg = config->spi_iface_cfg; - spi_slave_transaction_t *spi_tr_cfg = config->spi_tr_cfg; + spi_slave_transaction_t _spi_tr_cfg, *spi_tr_cfg; esp_err_t ret; - assert(buf_send != NULL); - assert(buf_recv != NULL); + if (!config->present) { + vTaskDelete(NULL); + return; + } - /* Configuration for the SPI bus */ - spi_bus_cfg->mosi_io_num = config->gpio_mosi; - spi_bus_cfg->miso_io_num = config->gpio_miso; - spi_bus_cfg->sclk_io_num = config->gpio_sclk; + snd_buf = spi_bus_dma_memory_alloc(config->spi_host, NET_SIZE_BUF, MALLOC_CAP_DMA); + assert(snd_buf != NULL); + + rcv_buf = spi_bus_dma_memory_alloc(config->spi_host, NET_SIZE_BUF, MALLOC_CAP_DMA); + assert(rcv_buf != NULL); + + memset(&_spi_tr_cfg, 0, sizeof(_spi_tr_cfg)); + spi_tr_cfg = &_spi_tr_cfg; - /* Configuration for the SPI slave interface */ - spi_iface_cfg->mode = 0; - spi_iface_cfg->spics_io_num = config->gpio_cs; - spi_iface_cfg->queue_size = 2; - spi_iface_cfg->flags = 0; spi_iface_cfg->post_setup_cb = _post_setup_cb; spi_iface_cfg->post_trans_cb = _post_trans_cb; - spi_tr_cfg->tx_buffer = buf_send; - spi_tr_cfg->rx_buffer = buf_recv; - spi_tr_cfg->length = SPI_SIZE_BUF * 8; + spi_tr_cfg->tx_buffer = snd_buf; + spi_tr_cfg->rx_buffer = rcv_buf; + spi_tr_cfg->length = NET_SIZE_BUF * 8; spi_tr_cfg->user = config; - xSemaphoreTake(config->mutex, portMAX_DELAY); - present = config->present; - xSemaphoreGive(config->mutex); - if (!present) { + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + _eos_net_deep_wake(config); vTaskSuspend(NULL); + net_wake(config); + } else { + ret = spi_slave_initialize(config->spi_host, spi_bus_cfg, spi_iface_cfg, SPI_DMA_CH_AUTO); + assert(ret == ESP_OK); } - /* Initialize SPI slave interface */ - ret = spi_slave_initialize(config->spi_host, spi_bus_cfg, spi_iface_cfg, SPI_DMA_CH_AUTO); - assert(ret == ESP_OK); - while (1) { if (!skip_msg) { + int msg_free; + xSemaphoreTake(config->mutex, portMAX_DELAY); - eos_msgq_pop(config->send_q, &mtype, &buffer, &buf_len); + msg_free = 0; + snd_buf_len = 0; + eos_msgq_pop(config->send_q, &mtype, &msg, &snd_buf_len); if (mtype) { - buf_send[0] = mtype; - buf_send[1] = buf_len >> 8; - buf_send[2] = buf_len & 0xFF; - if (buffer) { - memcpy(buf_send + SPI_SIZE_HDR, buffer, buf_len); - xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); - eos_bufq_push(config->buf_q, buffer); - xSemaphoreGive(config->bufq_mutex); - xSemaphoreGive(config->bufq_semaph); +#ifdef EOS_DEBUG + ESP_LOGI(TAG, "SEND:0x%.2X DEV:0x%.8lX LEN:%d", mtype, config->dev, snd_buf_len); +#endif + snd_buf[0] = mtype; + snd_buf[1] = snd_buf_len >> 8; + snd_buf[2] = snd_buf_len & 0xFF; + if (msg.buffer) { + memcpy(snd_buf + NET_SIZE_HDR, msg.buffer, snd_buf_len); + msg_free = 1; } } else if (!sleep_msg && config->sleep_req) { - buf_send[0] = EOS_NET_MTYPE_SLEEP; - buf_send[1] = 0; - buf_send[2] = 0; + snd_buf[0] = EOS_NET_MTYPE_SLEEP; + snd_buf[1] = 0; + snd_buf[2] = 0; sleep_msg = 1; config->sleep_req = 0; - if (config->dev == NET_DEV_NET) config->sleep = 1; + config->sleep = 1; } else { gpio_set_level(config->gpio_rts, 1); - buf_send[0] = 0; - buf_send[1] = 0; - buf_send[2] = 0; + snd_buf[0] = 0; + snd_buf[1] = 0; + snd_buf[2] = 0; } xSemaphoreGive(config->mutex); + + if (msg_free) _eos_net_free(config, &msg); } skip_msg = 0; - buf_recv[0] = 0; - buf_recv[1] = 0; - buf_recv[2] = 0; + rcv_buf[0] = 0; + rcv_buf[1] = 0; + rcv_buf[2] = 0; + ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); assert(ret == ESP_OK); trans_len = spi_tr_cfg->trans_len / 8; - ESP_LOGI(TAG, "RECV:0x%.2X DEV:0x%.8lX LEN:%d", buf_recv[0], config->dev, trans_len); +#ifdef EOS_DEBUG + ESP_LOGI(TAG, "RECV:0x%.2X DEV:0x%.8lX LEN:%d", rcv_buf[0], config->dev, trans_len); +#endif - if (sleep_msg && (config->dev == NET_DEV_NET)) { - net_goto_sleep(config); + if (sleep_msg) { + net_sleep(config); + vTaskSuspend(NULL); + net_wake(config); sleep_msg = 0; continue; } - if (trans_len < 1) { - ESP_LOGE(TAG, "RECV LEN:%d", trans_len); - continue; - } - /* SPI reset */ - if ((trans_len == 1) && (buf_recv[0] == 0)) { - if (buf_send[0]) skip_msg = 1; + if (trans_len < NET_SIZE_HDR) { + if (snd_buf[0]) skip_msg = 1; continue; } - mtype = buf_recv[0] & EOS_NET_MTYPE_MASK; - mtype_flags = buf_recv[0] & ~EOS_NET_MTYPE_MASK; - if (buf_send[0] && (mtype_flags & EOS_NET_MTYPE_FLAG_ONEW)) { + mtype = rcv_buf[0] & EOS_NET_MTYPE_MASK; + mtype_flags = rcv_buf[0] & ~EOS_NET_MTYPE_MASK; + if (snd_buf[0] && (mtype_flags & EOS_NET_MTYPE_FLAG_ONEW)) { skip_msg = 1; } + rcv_buf_len = (uint16_t)rcv_buf[1] << 8; + rcv_buf_len |= (uint16_t)rcv_buf[2] & 0xFF; + + if (snd_buf[0] && (trans_len < snd_buf_len + NET_SIZE_HDR) && !skip_msg) { + spi_tr_cfg->tx_buffer = snd_buf + trans_len; + spi_tr_cfg->rx_buffer = rcv_buf + trans_len; + spi_tr_cfg->length = (NET_SIZE_BUF - trans_len) * 8; - if (buf_send[0] && (trans_len < buf_len + SPI_SIZE_HDR) && !skip_msg) { - spi_tr_cfg->tx_buffer = buf_send + trans_len; - spi_tr_cfg->rx_buffer = buf_recv + trans_len; - spi_tr_cfg->length = (SPI_SIZE_BUF - trans_len) * 8; ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); assert(ret == ESP_OK); + trans_len += spi_tr_cfg->trans_len / 8; - spi_tr_cfg->tx_buffer = buf_send; - spi_tr_cfg->rx_buffer = buf_recv; - spi_tr_cfg->length = SPI_SIZE_BUF * 8; + spi_tr_cfg->tx_buffer = snd_buf; + spi_tr_cfg->rx_buffer = rcv_buf; + spi_tr_cfg->length = NET_SIZE_BUF * 8; } - if (mtype == 0) continue; - - if (mtype == EOS_NET_MTYPE_SLEEP) { - uint8_t mode; - - mode = EOS_PWR_SMODE_LIGHT; - - switch (config->dev) { - case NET_DEV_NET: { - eos_power_sleep_req(mode, EOS_PWR_DEV_ALL); - break; - } - case NET_DEV_APP: { - uint8_t msgq_len; - - xSemaphoreTake(config->mutex, portMAX_DELAY); - msgq_len = eos_msgq_len(config->send_q); - if (msgq_len == 0) { - config->sleep = 1; - config->sleep_req = 0; - } - xSemaphoreGive(config->mutex); - if (msgq_len == 0) { - net_goto_sleep(config); - sleep_msg = 0; - } - break; - } - } + if (rcv_buf[0] == EOS_NET_MTYPE_SLEEP) { + eos_power_sleep_req(config->dev); continue; } - if (trans_len < SPI_SIZE_HDR) { - ESP_LOGE(TAG, "RECV LEN:%d", trans_len); - continue; - } - buf_len = (uint16_t)buf_recv[1] << 8; - buf_len |= (uint16_t)buf_recv[2] & 0xFF; - buffer = buf_recv + SPI_SIZE_HDR; - config->msg_handler(buf_recv[0], buffer, buf_len); + if (mtype == 0) continue; + + eos_msg_init(&msg, rcv_buf + NET_SIZE_HDR, EOS_NET_MTU); + if (mtype_flags & EOS_NET_MTYPE_FLAG_REPL) eos_msg_set_flags(&msg, EOS_MSG_FLAG_RPLY_REQ); + config->handler(rcv_buf[0], &msg, rcv_buf_len); - if (mtype_flags & EOS_NET_MTYPE_FLAG_REPL) { - spi_tr_cfg->tx_buffer = buf_recv; + if (eos_msg_flags(&msg) & EOS_MSG_FLAG_RPLY_REQ) { + if (!(eos_msg_flags(&msg) & EOS_MSG_FLAG_RPLY_REP)) { + // eos_net_reply(EOS_MTYPE_ERR, msg, 0); + } + spi_tr_cfg->tx_buffer = rcv_buf; spi_tr_cfg->rx_buffer = NULL; + ret = spi_slave_transmit(config->spi_host, spi_tr_cfg, portMAX_DELAY); assert(ret == ESP_OK); - spi_tr_cfg->tx_buffer = buf_send; - spi_tr_cfg->rx_buffer = buf_recv; + + spi_tr_cfg->tx_buffer = snd_buf; + spi_tr_cfg->rx_buffer = rcv_buf; } } @@ -315,12 +315,12 @@ void eos_net_init(void) { SemaphoreHandle_t bufq_semaph; int i; - eos_msgq_init(&net_send_q, net_sndq_array, EOS_NET_SIZE_SNDQ); - eos_bufq_init(&net_buf_q, net_bufq_array, EOS_NET_SIZE_BUFQ); - for (i=0; i<EOS_NET_SIZE_BUFQ; i++) { + eos_msgq_init(&net_send_q, net_sndq_array, NET_SIZE_SNDQ); + eos_bufq_init(&net_buf_q, net_bufq_array, NET_SIZE_BUFQ); + for (i=0; i<NET_SIZE_BUFQ; i++) { unsigned char *buffer; - buffer = malloc(EOS_NET_SIZE_BUF); + buffer = malloc(EOS_NET_MTU); assert(buffer != NULL); eos_bufq_push(&net_buf_q, buffer); } @@ -333,38 +333,42 @@ void eos_net_init(void) { assert(mutex != NULL); bufq_mutex = xSemaphoreCreateBinary(); assert(bufq_mutex != NULL); - bufq_semaph = xSemaphoreCreateCounting(EOS_NET_SIZE_BUFQ, EOS_NET_SIZE_BUFQ); + bufq_semaph = xSemaphoreCreateCounting(NET_SIZE_BUFQ, NET_SIZE_BUFQ); assert(bufq_semaph != NULL); xSemaphoreGive(mutex); xSemaphoreGive(bufq_mutex); - net_config.sleep = 0; + net_config.sleep = esp_reset_reason() == ESP_RST_DEEPSLEEP ? 1 : 0; net_config.sleep_req = 0; net_config.present = 1; net_config.dev = NET_DEV_NET; - net_config.gpio_mosi = SPI_GPIO_MOSI; - net_config.gpio_miso = SPI_GPIO_MISO; - net_config.gpio_sclk = SPI_GPIO_SCLK; - net_config.gpio_cs = SPI_GPIO_CS; net_config.gpio_rts = SPI_GPIO_RTS; net_config.gpio_cts = SPI_GPIO_CTS; net_config.spi_host = SPI_HOST; net_config.spi_bus_cfg = &net_spi_bus_cfg; net_config.spi_iface_cfg = &net_spi_iface_cfg; - net_config.spi_tr_cfg = &net_spi_tr_cfg; net_config.mutex = mutex; net_config.bufq_mutex = bufq_mutex; net_config.bufq_semaph = bufq_semaph; net_config.buf_q = &net_buf_q; net_config.send_q = &net_send_q; - net_config.msg_handler = net_msg_handler; + net_config.handler = net_msg_handler; - _eos_net_init_gpio(&net_config); + /* Configuration for the SPI bus */ + net_spi_bus_cfg.mosi_io_num = SPI_GPIO_MOSI; + net_spi_bus_cfg.miso_io_num = SPI_GPIO_MISO; + net_spi_bus_cfg.sclk_io_num = SPI_GPIO_SCLK; + net_spi_bus_cfg.intr_flags = ESP_INTR_FLAG_IRAM; - if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { - gpio_hold_dis(net_config.gpio_cts); - } + /* Configuration for the SPI slave interface */ + net_spi_iface_cfg.mode = 0; + net_spi_iface_cfg.spics_io_num = SPI_GPIO_CS; + net_spi_iface_cfg.queue_size = 2; + net_spi_iface_cfg.flags = 0; + + _eos_net_init_gpio(&net_config); + eos_net_set_handler(EOS_NET_MTYPE_BRIDGE, net_bridge); ESP_LOGI(TAG, "INIT"); } @@ -378,57 +382,70 @@ void eos_net_run(void) { ESP_LOGI(TAG, "RUN"); } -unsigned char *_eos_net_alloc(NETConfig *config) { - unsigned char *ret; - +void _eos_net_alloc(NETConfig *config, EOSMessage *msg) { xSemaphoreTake(config->bufq_semaph, portMAX_DELAY); xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); - ret = eos_bufq_pop(config->buf_q); + msg->buffer = eos_bufq_pop(config->buf_q); + msg->size = EOS_NET_MTU; xSemaphoreGive(config->bufq_mutex); - - return ret; } -void _eos_net_free(NETConfig *config, unsigned char *buf) { +void _eos_net_free(NETConfig *config, EOSMessage *msg) { xSemaphoreTake(config->bufq_mutex, portMAX_DELAY); - eos_bufq_push(config->buf_q, buf); + eos_bufq_push(config->buf_q, msg->buffer); xSemaphoreGive(config->bufq_semaph); xSemaphoreGive(config->bufq_mutex); } -unsigned char *eos_net_alloc(void) { - return _eos_net_alloc(&net_config); +void eos_net_alloc(EOSMessage *msg) { + _eos_net_alloc(&net_config, msg); } -void eos_net_free(unsigned char *buf) { - _eos_net_free(&net_config, buf); +void eos_net_free(EOSMessage *msg) { + _eos_net_free(&net_config, msg); } -int _eos_net_send(NETConfig *config, unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { - int rv = EOS_OK; - int sleep; +int _eos_net_send(NETConfig *config, unsigned char mtype, EOSMessage *msg, uint16_t len) { + int wake, rv; + + wake = eos_msg_flags(msg) & EOS_MSG_FLAG_WAKE; + rv = EOS_OK; xSemaphoreTake(config->mutex, portMAX_DELAY); - sleep = config->sleep; - rv = eos_msgq_push(config->send_q, mtype, buffer, buf_len); - if (!rv && !sleep) gpio_set_level(config->gpio_rts, 0); + + if (!config->present) rv = EOS_ERR_NOTFOUND; + if (rv) goto net_send_fin; + + if (!wake && (config->sleep || config->sleep_req)) rv = EOS_ERR_BUSY; + if (rv) goto net_send_fin; + + rv = eos_msgq_push(config->send_q, mtype, msg, len); + if (rv) goto net_send_fin; + + /* we can't wake app module by pulling rts low */ + gpio_set_level(config->gpio_rts, 0); + +net_send_fin: xSemaphoreGive(config->mutex); - if (!rv && sleep) eos_power_wake(config->dev); - if (rv) _eos_net_free(config, buffer); + if (rv) _eos_net_free(config, msg); return rv; } -int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { - return _eos_net_send(&net_config, mtype, buffer, buf_len); +int eos_net_send(unsigned char mtype, EOSMessage *msg, uint16_t len) { + return _eos_net_send(&net_config, mtype, msg, len); } -void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { - buffer -= SPI_SIZE_HDR; +void eos_net_reply(unsigned char mtype, EOSMessage *msg, uint16_t len) { + unsigned char *buffer = msg->buffer - NET_SIZE_HDR; + + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) return; + if (eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REP) return; buffer[0] = mtype; - buffer[1] = buf_len >> 8; - buffer[2] = buf_len & 0xFF; + buffer[1] = len >> 8; + buffer[2] = len & 0xFF; + eos_msg_set_flags(msg, EOS_MSG_FLAG_RPLY_REP); } void _eos_net_sleep_req(NETConfig *config) { @@ -463,6 +480,14 @@ void _eos_net_wake(NETConfig *config) { } while (sleep); } +void _eos_net_deep_sleep(NETConfig *config) { + gpio_hold_en(config->gpio_cts); +} + +void _eos_net_deep_wake(NETConfig *config) { + gpio_hold_dis(config->gpio_cts); +} + void eos_net_sleep_req(void) { _eos_net_sleep_req(&net_config); } @@ -471,7 +496,15 @@ void eos_net_wake(void) { _eos_net_wake(&net_config); } +void eos_net_deep_sleep(void) { + _eos_net_deep_sleep(&net_config); +} + +void eos_net_deep_wake(void) { + _eos_net_deep_wake(&net_config); +} + void eos_net_set_handler(unsigned char mtype, eos_net_handler_t handler) { if (handler == NULL) handler = bad_handler; - if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler; + if (mtype < EOS_NET_MAX_MTYPE) net_handler[mtype] = handler; } diff --git a/fw/esp32/components/eos/power.c b/fw/esp32/components/eos/power.c index 27c44a5..1f58f77 100644 --- a/fw/esp32/components/eos/power.c +++ b/fw/esp32/components/eos/power.c @@ -18,14 +18,14 @@ #include "cell.h" #include "power.h" -#define PWR_ETYPE_SLEEP_REQ 1 -#define PWR_ETYPE_SLEEP_RDY 2 -#define PWR_ETYPE_WAKE 3 +#define PWR_ETYPE_SET_MODE 1 +#define PWR_ETYPE_SLEEP_REQ 2 +#define PWR_ETYPE_SLEEP_RDY 3 +#define PWR_ETYPE_WAKE 4 typedef struct { uint8_t type; - uint8_t mode; - uint32_t dev; + uint32_t param; } power_event_t; static esp_pm_lock_handle_t power_lock_cpu_freq; @@ -40,7 +40,7 @@ static void IRAM_ATTR net_wake_handler(void *arg) { power_event_t evt; evt.type = PWR_ETYPE_WAKE; - evt.dev = EOS_PWR_DEV_NET; + evt.param = EOS_PWR_DEV_NET; xQueueSendFromISR(power_queue, &evt, NULL); } @@ -48,7 +48,7 @@ static void IRAM_ATTR app_wake_handler(void *arg) { power_event_t evt; evt.type = PWR_ETYPE_WAKE; - evt.dev = EOS_PWR_DEV_APP; + evt.param = EOS_PWR_DEV_APP; xQueueSendFromISR(power_queue, &evt, NULL); } @@ -56,65 +56,112 @@ static void IRAM_ATTR modem_wake_handler(void *arg) { power_event_t evt; evt.type = PWR_ETYPE_WAKE; - evt.dev = EOS_PWR_DEV_MODEM; + evt.param = EOS_PWR_DEV_MODEM; xQueueSendFromISR(power_queue, &evt, NULL); } +static void power_sleep_req(uint32_t dev) { + if (dev & EOS_PWR_DEV_NET) { + eos_net_sleep_req(); + } + if (dev & EOS_PWR_DEV_APP) { + eos_app_sleep_req(); + } + if (dev & EOS_PWR_DEV_MODEM) { + eos_modem_sleep_req(); + } +} + +static void power_sleep_rdy(uint32_t dev) { + gpio_config_t io_conf = { + .mode = GPIO_MODE_INPUT, + .intr_type = GPIO_INTR_NEGEDGE, + .pull_up_en = 1, + .pull_down_en = 0, + }; + + if (dev & EOS_PWR_DEV_NET) { + io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_NET); + gpio_config(&io_conf); + gpio_isr_handler_add(EOS_PWR_GPIO_NET, net_wake_handler, NULL); + } + if (dev & EOS_PWR_DEV_APP) { + io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_APP); + gpio_config(&io_conf); + gpio_isr_handler_add(EOS_PWR_GPIO_APP, app_wake_handler, NULL); + } + if (dev & EOS_PWR_DEV_MODEM) { + io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_MODEM); + gpio_config(&io_conf); + gpio_isr_handler_add(EOS_PWR_GPIO_MODEM, modem_wake_handler, NULL); + } +} + +static void power_wake(uint32_t dev) { + if (dev & EOS_PWR_DEV_NET) { + gpio_isr_handler_remove(EOS_PWR_GPIO_NET); + gpio_reset_pin(EOS_PWR_GPIO_NET); + eos_net_wake(); + } + if (dev & EOS_PWR_DEV_APP) { + gpio_isr_handler_remove(EOS_PWR_GPIO_APP); + gpio_reset_pin(EOS_PWR_GPIO_APP); + eos_app_wake(); + } + if (dev & EOS_PWR_DEV_MODEM) { + gpio_isr_handler_remove(EOS_PWR_GPIO_MODEM); + gpio_reset_pin(EOS_PWR_GPIO_MODEM); + eos_modem_wake(); + } +} + static void power_event_task(void *pvParameters) { power_event_t evt; uint8_t mode; uint32_t sleep_req, sleep_rdy; int sys_sleep; + mode = 0; sys_sleep = 0; sleep_req = 0; sleep_rdy = 0; + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + mode = EOS_PWR_SMODE_DEEP; + sys_sleep = 1; + sleep_rdy = EOS_PWR_DEV_ALL; + power_sleep_rdy(sleep_rdy); + } + while (1) { if (xQueueReceive(power_queue, &evt, portMAX_DELAY)) { switch (evt.type) { - case PWR_ETYPE_SLEEP_REQ: { - if (evt.mode) mode = evt.mode; - if ((evt.dev & EOS_PWR_DEV_NET) && !(sleep_req & EOS_PWR_DEV_NET)) { - eos_net_sleep_req(); - } - if ((evt.dev & EOS_PWR_DEV_APP) && !(sleep_req & EOS_PWR_DEV_APP)) { - eos_app_sleep_req(); - } - if ((evt.dev & EOS_PWR_DEV_MODEM) && !(sleep_req & EOS_PWR_DEV_MODEM)) { - eos_modem_sleep_req(); - } - sleep_req |= evt.dev; + case PWR_ETYPE_SET_MODE: { + mode = evt.param; if (sleep_rdy == EOS_PWR_DEV_ALL) { eos_power_sleep_rdy(0); } break; } + case PWR_ETYPE_SLEEP_REQ: { + evt.param &= ~sleep_req; + evt.param &= ~sleep_rdy; + + power_sleep_req(evt.param); + + sleep_req |= evt.param; + break; + } + case PWR_ETYPE_SLEEP_RDY: { - gpio_config_t io_conf = { - .mode = GPIO_MODE_INPUT, - .intr_type = GPIO_INTR_NEGEDGE, - .pull_up_en = 1, - .pull_down_en = 0, - }; - - if (evt.dev & EOS_PWR_DEV_NET) { - io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_NET); - gpio_config(&io_conf); - gpio_isr_handler_add(EOS_PWR_GPIO_NET, net_wake_handler, NULL); - } - if (evt.dev & EOS_PWR_DEV_APP) { - io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_APP); - gpio_config(&io_conf); - gpio_isr_handler_add(EOS_PWR_GPIO_APP, app_wake_handler, NULL); - } - if (evt.dev & EOS_PWR_DEV_MODEM) { - io_conf.pin_bit_mask = BIT64(EOS_PWR_GPIO_MODEM); - gpio_config(&io_conf); - gpio_isr_handler_add(EOS_PWR_GPIO_MODEM, modem_wake_handler, NULL); - } - sleep_rdy |= evt.dev; + evt.param &= sleep_req; + evt.param &= ~sleep_rdy; + + power_sleep_rdy(evt.param); + + sleep_req &= ~evt.param; + sleep_rdy |= evt.param; if (!sys_sleep && mode && (sleep_rdy == EOS_PWR_DEV_ALL)) { sys_sleep = 1; eos_power_sys_sleep(mode); @@ -123,30 +170,18 @@ static void power_event_task(void *pvParameters) { } case PWR_ETYPE_WAKE: { - ESP_LOGI(TAG, "WAKE:0x%.8lX", evt.dev); + evt.param &= ~sleep_req; + evt.param &= sleep_rdy; + if (sys_sleep) { eos_power_sys_wake(mode); sys_sleep = 0; mode = 0; } - if ((evt.dev & EOS_PWR_DEV_NET) && (sleep_rdy & EOS_PWR_DEV_NET)) { - gpio_isr_handler_remove(EOS_PWR_GPIO_NET); - gpio_reset_pin(EOS_PWR_GPIO_NET); - eos_net_wake(); - } - if ((evt.dev & EOS_PWR_DEV_APP) && (sleep_rdy & EOS_PWR_DEV_APP)) { - gpio_isr_handler_remove(EOS_PWR_GPIO_APP); - gpio_reset_pin(EOS_PWR_GPIO_APP); - eos_app_wake(); - } - if ((evt.dev & EOS_PWR_DEV_MODEM) && (sleep_rdy & EOS_PWR_DEV_MODEM)) { - gpio_isr_handler_remove(EOS_PWR_GPIO_MODEM); - gpio_reset_pin(EOS_PWR_GPIO_MODEM); - eos_modem_wake(); - } - sleep_req &= ~evt.dev; - sleep_rdy &= ~evt.dev; - ESP_LOGI(TAG, "WAKE DONE:0x%.8lX", evt.dev); + + power_wake(evt.param); + + sleep_rdy &= ~evt.param; break; } } @@ -186,7 +221,6 @@ void eos_power_init(void) { rtc_gpio_deinit(EOS_PWR_GPIO_NET); rtc_gpio_deinit(EOS_PWR_GPIO_APP); rtc_gpio_deinit(EOS_PWR_GPIO_MODEM); - eos_power_sys_wake(EOS_PWR_SMODE_DEEP); } power_queue = xQueueCreate(4, sizeof(power_event_t)); @@ -201,6 +235,10 @@ void eos_power_run(void) { rv = xTaskCreate(power_event_task, "power_event", EOS_TASK_SSIZE_PWR, NULL, EOS_TASK_PRIORITY_PWR, NULL); assert(rv == pdPASS); + if (esp_reset_reason() == ESP_RST_DEEPSLEEP) { + eos_power_wake(eos_power_wakeup_source()); + } + ESP_LOGI(TAG, "RUN"); } @@ -221,6 +259,10 @@ void eos_power_sys_sleep(uint8_t mode) { rtc_gpio_pullup_en(EOS_PWR_GPIO_MODEM); esp_sleep_enable_ext1_wakeup_io(EOS_PWR_DEV_ALL, ESP_EXT1_WAKEUP_ANY_LOW); if (mode == EOS_PWR_SMODE_DEEP) { + eos_net_deep_sleep(); + eos_app_deep_sleep(); + eos_modem_deep_sleep(); + gpio_deep_sleep_hold_en(); esp_deep_sleep_start(); } else { @@ -270,12 +312,19 @@ uint32_t eos_power_wakeup_source(void) { return dev; } -void eos_power_sleep_req(uint8_t mode, uint32_t dev) { +void eos_power_set_mode(uint8_t mode) { + power_event_t evt; + + evt.type = PWR_ETYPE_SET_MODE; + evt.param = mode; + xQueueSend(power_queue, &evt, portMAX_DELAY); +} + +void eos_power_sleep_req(uint32_t dev) { power_event_t evt; evt.type = PWR_ETYPE_SLEEP_REQ; - evt.mode = mode; - evt.dev = dev; + evt.param = dev; xQueueSend(power_queue, &evt, portMAX_DELAY); } @@ -283,7 +332,7 @@ void eos_power_sleep_rdy(uint32_t dev) { power_event_t evt; evt.type = PWR_ETYPE_SLEEP_RDY; - evt.dev = dev; + evt.param = dev; xQueueSend(power_queue, &evt, portMAX_DELAY); } @@ -292,6 +341,6 @@ void eos_power_wake(uint32_t dev) { ESP_LOGI(TAG, "WAKE SENT"); evt.type = PWR_ETYPE_WAKE; - evt.dev = dev; + evt.param = dev; xQueueSend(power_queue, &evt, portMAX_DELAY); } diff --git a/fw/esp32/components/eos/rng.c b/fw/esp32/components/eos/rng.c index 675a79c..6f53a0b 100644 --- a/fw/esp32/components/eos/rng.c +++ b/fw/esp32/components/eos/rng.c @@ -7,21 +7,19 @@ static const char *TAG = "EOS RNG"; -static void rng_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { +static void rng_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char *buffer = msg->buffer; uint16_t rng_len = 0; - if (buf_len < sizeof(uint16_t)) goto rng_handler_fin; + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) return; + if (len < sizeof(uint16_t)) return; rng_len = (uint16_t)buffer[0] << 8; rng_len |= (uint16_t)buffer[1]; - if (rng_len > EOS_NET_SIZE_BUF) { - rng_len = 0; - goto rng_handler_fin; - } - esp_fill_random(buffer, rng_len); + if (rng_len > msg->size) return; -rng_handler_fin: - eos_net_reply(EOS_NET_MTYPE_RNG, buffer, rng_len); + esp_fill_random(buffer, rng_len); + eos_net_reply(EOS_NET_MTYPE_RNG, msg, rng_len); } void eos_rng_init(void) { diff --git a/fw/esp32/components/eos/sock.c b/fw/esp32/components/eos/sock.c index b6ed3e9..dcad8b2 100644 --- a/fw/esp32/components/eos/sock.c +++ b/fw/esp32/components/eos/sock.c @@ -101,10 +101,27 @@ static void populate_fds(fd_set *fds, int *max_fd) { } } +static void cmd_xchg(uint8_t *cmd) { + int rv; + + xSemaphoreTake(mutex, portMAX_DELAY); + + rv = write(cmd_fd, cmd, sizeof(uint64_t)); + assert(rv == sizeof(uint64_t)); + + do { + rv = read(rep_fd, cmd, sizeof(uint64_t)); + assert(rv == sizeof(uint64_t)); + } while (cmd[0] == 0); + + xSemaphoreGive(mutex); +} + static void udp_rcvr_task(void *pvParameters) { EOSNetAddr addr; + EOSMessage msg; unsigned char *buffer; - uint16_t buf_len; + uint16_t len; fd_set all_fds, read_fds; uint8_t sock_i; uint8_t cmd[8]; @@ -112,8 +129,6 @@ static void udp_rcvr_task(void *pvParameters) { int sock, max_fd, i; int rv; - assert(sizeof(buffer) == 4); - populate_fds(&all_fds, &max_fd); while (1) { memcpy(&read_fds, &all_fds, sizeof(fd_set)); @@ -126,24 +141,27 @@ static void udp_rcvr_task(void *pvParameters) { for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { sock = _socks[i]; if (sock && FD_ISSET(sock, &read_fds)) { - unsigned char *_buf; - - buffer = eos_net_alloc(); - _rv = t_recvfrom(sock, buffer + EOS_SOCK_SIZE_UDP_HDR, EOS_NET_SIZE_BUF - EOS_SOCK_SIZE_UDP_HDR, &addr); + eos_net_alloc(&msg); + if (msg.size < EOS_SOCK_SIZE_UDP_HDR) { + eos_net_free(&msg); + continue; + } + _rv = t_recvfrom(sock, msg.buffer + EOS_SOCK_SIZE_UDP_HDR, msg.size - EOS_SOCK_SIZE_UDP_HDR, &addr); if (_rv < 0) { - eos_net_free(buffer); + eos_net_free(&msg); ESP_LOGE(TAG, "RECV ERR:%d", _rv); + continue; } - _buf = buffer; - _buf[0] = EOS_SOCK_MTYPE_PKT; - _buf[1] = i + 1; - _buf += 2; - memcpy(_buf, addr.host, sizeof(addr.host)); - _buf += sizeof(addr.host); - _buf[0] = addr.port >> 8; - _buf[1] = addr.port; - _buf += sizeof(addr.port); - rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, _rv + EOS_SOCK_SIZE_UDP_HDR); + buffer = msg.buffer; + buffer[0] = EOS_SOCK_MTYPE_PKT; + buffer[1] = i + 1; + buffer += 2; + memcpy(buffer, addr.host, sizeof(addr.host)); + buffer += sizeof(addr.host); + buffer[0] = addr.port >> 8; + buffer[1] = addr.port; + buffer += sizeof(addr.port); + rv = eos_net_send(EOS_NET_MTYPE_SOCK, &msg, _rv + EOS_SOCK_SIZE_UDP_HDR); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } } @@ -167,7 +185,6 @@ static void udp_rcvr_task(void *pvParameters) { populate_fds(&all_fds, &max_fd); } } - memset(cmd, 0, sizeof(cmd)); cmd[1] = sock_i; rv = write(rep_fd, cmd, sizeof(cmd)); @@ -193,21 +210,21 @@ static void udp_rcvr_task(void *pvParameters) { case CMD_SEND: { sock_i = cmd[1] - 1; - buf_len = (uint16_t)cmd[2] << 8; - buf_len |= (uint16_t)cmd[3]; - memcpy(&buffer, cmd + 4, sizeof(buffer)); - sock = _socks[sock_i]; - memcpy(addr.host, buffer, sizeof(addr.host)); - buffer += sizeof(addr.host); - buf_len -= sizeof(addr.host); - addr.port = (uint16_t)buffer[0] << 8; - addr.port |= (uint16_t)buffer[1]; - buffer += sizeof(addr.port); - buf_len -= sizeof(addr.port); - _rv = t_sendto(sock, buffer, buf_len, &addr); - - memset(cmd, 0, sizeof(cmd)); + if (sock) { + len = (uint16_t)cmd[2] << 8; + len |= (uint16_t)cmd[3]; + memcpy(&buffer, cmd + 4, sizeof(buffer)); + + memcpy(addr.host, buffer, sizeof(addr.host)); + buffer += sizeof(addr.host); + len -= sizeof(addr.host); + addr.port = (uint16_t)buffer[0] << 8; + addr.port |= (uint16_t)buffer[1]; + buffer += sizeof(addr.port); + len -= sizeof(addr.port); + _rv = t_sendto(sock, buffer, len, &addr); + } rv = write(rep_fd, cmd, sizeof(cmd)); assert(rv == sizeof(cmd)); @@ -216,9 +233,6 @@ static void udp_rcvr_task(void *pvParameters) { } case CMD_REOPEN: { - buffer = NULL; - buf_len = 0; - for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { sock = _socks[i]; if (sock) { @@ -226,6 +240,9 @@ static void udp_rcvr_task(void *pvParameters) { _socks[i] = -1; } } + + len = 0; + eos_msg_init(&msg, NULL, 0); for (i=0; i<EOS_SOCK_MAX_SOCK; i++) { sock = _socks[i]; if (sock) { @@ -234,20 +251,22 @@ static void udp_rcvr_task(void *pvParameters) { _socks[i] = sock; } else { _socks[i] = 0; - if (buffer) { - buffer[buf_len] = i + 1; - buf_len++; + if (msg.buffer) { + if (msg.size == len) break; + msg.buffer[len] = i + 1; + len++; } else { - buffer = eos_net_alloc(); - buffer[0] = EOS_SOCK_MTYPE_CLOSE; - buffer[1] = i + 1; - buf_len = 2; + eos_net_alloc(&msg); + if (msg.size < 2) break; + msg.buffer[0] = EOS_SOCK_MTYPE_CLOSE; + msg.buffer[1] = i + 1; + len = 2; } } } } - if (buffer) { - rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, buf_len); + if (msg.buffer) { + rv = eos_net_send(EOS_NET_MTYPE_SOCK, &msg, len); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } @@ -268,13 +287,13 @@ static void udp_rcvr_task(void *pvParameters) { vTaskDelete(NULL); } -static void sock_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { +static void sock_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { unsigned char mtype; + unsigned char *buffer = msg->buffer; uint8_t sock_i; uint8_t cmd[8]; - int rv; - if (buf_len < 1) return; + if (len < 1) return; memset(cmd, 0, sizeof(cmd)); @@ -282,72 +301,55 @@ static void sock_handler(unsigned char _mtype, unsigned char *buffer, uint16_t b switch (mtype) { case EOS_SOCK_MTYPE_PKT: { unsigned char *_buf = buffer; + uint16_t _len = len; - if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return; + if (len < EOS_SOCK_SIZE_UDP_HDR) break; sock_i = buffer[1]; - if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) return; + if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) break; _buf += 2; + _len -= 2; cmd[0] = CMD_SEND; cmd[1] = sock_i; - cmd[2] = buf_len >> 8; - cmd[3] = buf_len; + cmd[2] = _len >> 8; + cmd[3] = _len; memcpy(cmd + 4, &_buf, sizeof(_buf)); - xSemaphoreTake(mutex, portMAX_DELAY); - - rv = write(cmd_fd, cmd, sizeof(cmd)); - assert(rv == sizeof(cmd)); - - rv = read(rep_fd, cmd, sizeof(cmd)); - assert(rv == sizeof(cmd)); - - xSemaphoreGive(mutex); + cmd_xchg(cmd); assert(cmd[0] == CMD_SEND); break; } case EOS_SOCK_MTYPE_OPEN_DGRAM: { - cmd[0] = CMD_OPEN; - - xSemaphoreTake(mutex, portMAX_DELAY); + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) break; + if (msg->size < 2) break; - rv = write(cmd_fd, cmd, sizeof(cmd)); - assert(rv == sizeof(cmd)); - - rv = read(rep_fd, cmd, sizeof(cmd)); - assert(rv == sizeof(cmd)); + cmd[0] = CMD_OPEN; - xSemaphoreGive(mutex); + cmd_xchg(cmd); assert(cmd[0] == CMD_OPEN); + sock_i = cmd[1]; buffer[0] = EOS_SOCK_MTYPE_OPEN_DGRAM; buffer[1] = sock_i; - eos_net_reply(EOS_NET_MTYPE_SOCK, buffer, 2); + + eos_net_reply(EOS_NET_MTYPE_SOCK, msg, 2); break; } case EOS_SOCK_MTYPE_CLOSE: { - if (buf_len < 2) return; + if (len < 2) break; sock_i = buffer[1]; - if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) return; + if ((sock_i == 0) || (sock_i > EOS_SOCK_MAX_SOCK)) break; cmd[0] = CMD_CLOSE; cmd[1] = sock_i; - xSemaphoreTake(mutex, portMAX_DELAY); - - rv = write(cmd_fd, cmd, sizeof(cmd)); - assert(rv == sizeof(cmd)); - - rv = read(rep_fd, cmd, sizeof(cmd)); - assert(rv == sizeof(cmd)); - - xSemaphoreGive(mutex); + cmd_xchg(cmd); assert(cmd[0] == CMD_CLOSE); break; @@ -388,17 +390,10 @@ void eos_sock_run(void) { void eos_sock_reopen(void) { uint8_t cmd[8]; - int rv; cmd[0] = CMD_REOPEN; - xSemaphoreTake(mutex, portMAX_DELAY); - rv = write(cmd_fd, cmd, sizeof(cmd)); - assert(rv == sizeof(cmd)); + cmd_xchg(cmd); - rv = read(rep_fd, cmd, sizeof(cmd)); - assert(rv == sizeof(cmd)); - - xSemaphoreGive(mutex); assert(cmd[0] == CMD_REOPEN); } diff --git a/fw/esp32/components/eos/tun.c b/fw/esp32/components/eos/tun.c index f27fcfe..cb1dde6 100644 --- a/fw/esp32/components/eos/tun.c +++ b/fw/esp32/components/eos/tun.c @@ -4,40 +4,49 @@ #include <lwip/pbuf.h> #include <lwip/netif.h> #include <lwip/tcpip.h> -#include <lwip/etharp.h> +#include <lwip/ip.h> +#include <lwip/lwip_napt.h> + +#include <esp_log.h> #include "net.h" #include "app.h" #include "tun.h" +static const char *TAG = "EOS TUN"; + static ip4_addr_t ipaddr, netmask, gw; static struct netif netif_tun; static err_t IRAM_ATTR tun_output(struct netif *netif, struct pbuf *p, const struct ip4_addr *ipaddr) { - unsigned char *buf; + EOSMessage msg; struct pbuf *q; for (q = p; q != NULL; q = q->next) { - if (q->len > EOS_APP_MTU) continue; - - buf = eos_app_alloc(); - memcpy(buf, q->payload, q->len); - eos_app_send(EOS_APP_MTYPE_TUN, buf, q->len); + eos_app_alloc(&msg); + if (q->len > msg.size) { + eos_app_free(&msg); + continue; + } + + memcpy(msg.buffer, q->payload, q->len); + eos_app_send(EOS_APP_MTYPE_TUN, &msg, q->len); } return ERR_OK; } -static void IRAM_ATTR tun_input(unsigned char mtype, unsigned char *buffer, uint16_t len) { +static void IRAM_ATTR tun_input(unsigned char mtype, EOSMessage *msg, uint16_t len) { struct netif *netif = &netif_tun; struct pbuf *p; int rv; if (!netif_is_up(netif)) return; - p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); + p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM); if (p == NULL) return; - memcpy(p->payload, buffer, len); + + memcpy(p->payload, msg->buffer, len); rv = netif->input(p, netif); if (rv != ERR_OK) { pbuf_free(p); @@ -55,16 +64,31 @@ static err_t tun_init(struct netif *netif) { return ERR_OK; } +void eos_tun_portmap_add(uint32_t ext_addr) { + ip4_addr_t app_addr; + + IP4_ADDR(&app_addr, 192,168,152,1); + ip_portmap_add(IP_PROTO_TCP, ext_addr, 22, app_addr.addr, 22); +} + +void eos_tun_portmap_remove(void) { + ip_portmap_remove(IP_PROTO_TCP, 22); +} + void eos_tun_init(void) { struct netif *rv; IP4_ADDR(&gw, 0,0,0,0); - IP4_ADDR(&ipaddr, 192,168,10,2); + IP4_ADDR(&ipaddr, 192,168,152,2); IP4_ADDR(&netmask, 255,255,255,0); rv = netif_add(&netif_tun, &ipaddr, &netmask, &gw, NULL, tun_init, tcpip_input); assert(rv != NULL); netif_set_up(&netif_tun); + ip_napt_enable_netif(&netif_tun, 1); eos_app_set_handler(EOS_APP_MTYPE_TUN, tun_input); + + ESP_LOGI(TAG, "INIT"); + ESP_LOGI(TAG, "addres: %x", (unsigned int)ipaddr.addr); } diff --git a/fw/esp32/components/eos/wifi.c b/fw/esp32/components/eos/wifi.c index 77f9143..fe1b382 100755 --- a/fw/esp32/components/eos/wifi.c +++ b/fw/esp32/components/eos/wifi.c @@ -13,6 +13,7 @@ #include "eos.h" #include "net.h" +#include "tun.h" #include "wifi.h" // XXX: WiFi fail due to no DHCP server @@ -53,6 +54,7 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e if (sta_disconnected->reason == WIFI_REASON_ASSOC_LEAVE) { eos_wifi_send_status(); + eos_tun_portmap_remove(); break; } if ((reconnect_cnt == 0) && (sta_disconnected->reason == WIFI_REASON_BEACON_TIMEOUT)) { @@ -64,6 +66,7 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e reconnect_cnt++; } else { eos_wifi_send_status(); + eos_tun_portmap_remove(); reconnect_cnt = 0; if (stop) { @@ -84,13 +87,17 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e got_ip = (ip_event_got_ip_t *)event_data; ESP_LOGI(TAG, "Event got IP - addres: " IPSTR, IP2STR(&got_ip->ip_info.ip)); + ESP_LOGI(TAG, "Event got IP - addres: %x", (unsigned int)got_ip->ip_info.ip.addr); eos_wifi_send_status(); + eos_tun_portmap_remove(); + eos_tun_portmap_add(got_ip->ip_info.ip.addr); /* if (got_ip->ip_changed) { recreate all sockets } */ + break; } @@ -101,35 +108,25 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t e } -static void wifi_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { +static void wifi_handler(unsigned char _mtype, EOSMessage *msg, uint16_t len) { + unsigned char *buffer = msg->buffer; + uint16_t buf_size = msg->size; esp_err_t ret = ESP_OK; - uint8_t mtype; + unsigned char mtype; - if (buf_len < 1) return; + if (len < 1) return; mtype = buffer[0]; switch (mtype) { case EOS_WIFI_MTYPE_STATUS: { - unsigned char *_buffer; - ssize_t _rv; - int reply, rv; - - reply = _mtype & EOS_NET_MTYPE_FLAG_REPL; + ssize_t rv; - if (reply) { - _rv = eos_wifi_get_status(buffer + 1); - if (_rv < 0) break; + if (!(eos_msg_flags(msg) & EOS_MSG_FLAG_RPLY_REQ)) break; - eos_net_reply(EOS_NET_MTYPE_WIFI, buffer, _rv + 1); - } else { - _buffer = eos_net_alloc(); - _buffer[0] = EOS_WIFI_MTYPE_STATUS; - _rv = eos_wifi_get_status(_buffer + 1); - if (_rv < 0) break; + rv = eos_wifi_get_status(buffer + 1, buf_size - 1); + if (rv < 0) break; - rv = eos_net_send(EOS_NET_MTYPE_WIFI, _buffer, _rv + 1); - if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); - } + eos_net_reply(EOS_NET_MTYPE_WIFI, msg, rv + 1); break; } @@ -233,11 +230,14 @@ void eos_wifi_run(void) { ESP_LOGI(TAG, "RUN"); } -ssize_t eos_wifi_get_status(unsigned char *buffer) { +ssize_t eos_wifi_get_status(unsigned char *buffer, size_t size) { unsigned char *p; wifi_ap_record_t ap_info; esp_err_t ret; + /* 1 + sizeof(uint32_t) + sizeof(ap_info.ssid) - 1 */ + if (size < sizeof(uint32_t) + sizeof(ap_info.ssid)) return EOS_ERR_SIZE; + p = buffer; ret = esp_wifi_sta_get_ap_info(&ap_info); switch (ret) { @@ -296,28 +296,33 @@ ssize_t eos_wifi_get_status(unsigned char *buffer) { } void eos_wifi_send_status(void) { - unsigned char *rbuf; + EOSMessage msg; ssize_t _rv; int rv; - rbuf = eos_net_alloc(); - rbuf[0] = EOS_WIFI_MTYPE_STATUS; - _rv = eos_wifi_get_status(rbuf + 1); + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_WIFI_MTYPE_STATUS; + _rv = eos_wifi_get_status(msg.buffer + 1, msg.size - 1); if (_rv < 0) { - eos_net_free(rbuf); + eos_net_free(&msg); return; } - rv = eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, _rv + 1); + rv = eos_net_send(EOS_NET_MTYPE_WIFI, &msg, _rv + 1); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } void eos_wifi_send_scan(void) { + EOSMessage msg; static wifi_ap_record_t scan_r[EOS_WIFI_MAX_SCAN_RECORDS]; static uint16_t scan_n; size_t len; esp_err_t ret; - unsigned char *rbuf, *p; + unsigned char *p; int i, rv; scan_n = EOS_WIFI_MAX_SCAN_RECORDS; @@ -330,19 +335,23 @@ void eos_wifi_send_scan(void) { ESP_LOGI(TAG, "Scan done: %d", scan_n); - rbuf = eos_net_alloc(); - rbuf[0] = EOS_WIFI_MTYPE_SCAN; - p = rbuf + 1; + eos_net_alloc(&msg); + if (msg.size < 1) { + eos_net_free(&msg); + return; + } + msg.buffer[0] = EOS_WIFI_MTYPE_SCAN; + p = msg.buffer + 1; for (i=0; i<scan_n; i++) { len = strnlen((char *)scan_r[i].ssid, sizeof(scan_r[i].ssid)); if (len == sizeof(scan_r[i].ssid)) continue; - if (p - rbuf + len + 1 > EOS_NET_SIZE_BUF) break; + if (p - msg.buffer + len + 1 > msg.size) break; strcpy((char *)p, (char *)scan_r[i].ssid); p += len + 1; } - rv = eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, p - rbuf); + rv = eos_net_send(EOS_NET_MTYPE_WIFI, &msg, p - msg.buffer); if (rv) ESP_LOGE(TAG, "NET SEND ERR:%d", rv); } |
