From 6a4b3ef0e72ee134b81a523ce41fd4c45f3b4429 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Sun, 4 Sep 2022 18:43:50 +0200 Subject: fixed wifi and cell --- fw/esp32/components/eos/app.c | 2 +- fw/esp32/components/eos/at_cmd.c | 6 +- fw/esp32/components/eos/cell.c | 50 ++- fw/esp32/components/eos/cell_modem.c | 546 ++++++++++++++++++++------------ fw/esp32/components/eos/cell_pcm.c | 21 +- fw/esp32/components/eos/cell_pdp.c | 93 ++++-- fw/esp32/components/eos/cell_sms.c | 48 +-- fw/esp32/components/eos/cell_ussd.c | 9 +- fw/esp32/components/eos/cell_voice.c | 38 ++- fw/esp32/components/eos/gsm.c | 6 +- fw/esp32/components/eos/include/cell.h | 41 ++- fw/esp32/components/eos/include/net.h | 2 +- fw/esp32/components/eos/include/power.h | 8 +- fw/esp32/components/eos/include/wifi.h | 21 +- fw/esp32/components/eos/net.c | 29 +- fw/esp32/components/eos/power.c | 190 +++++++---- fw/esp32/components/eos/rng.c | 2 +- fw/esp32/components/eos/sock.c | 22 +- fw/esp32/components/eos/wifi.c | 451 +++++++++++++------------- 19 files changed, 954 insertions(+), 631 deletions(-) (limited to 'fw/esp32/components') diff --git a/fw/esp32/components/eos/app.c b/fw/esp32/components/eos/app.c index c4244df..8396376 100644 --- a/fw/esp32/components/eos/app.c +++ b/fw/esp32/components/eos/app.c @@ -151,7 +151,7 @@ void eos_app_init(void) { int i; // Configuration for the handshake lines - gpio_config_t io_conf; + gpio_config_t io_conf = {}; io_conf.intr_type = GPIO_INTR_DISABLE; io_conf.mode = GPIO_MODE_OUTPUT; diff --git a/fw/esp32/components/eos/at_cmd.c b/fw/esp32/components/eos/at_cmd.c index 82baa92..37de990 100644 --- a/fw/esp32/components/eos/at_cmd.c +++ b/fw/esp32/components/eos/at_cmd.c @@ -149,17 +149,17 @@ int at_expect_match(char *str_ok, char *str_err, char **buf, regmatch_t match[], return rv; } - ESP_LOGI(TAG, "Expect: %s", at_buf); + if (strlen(at_buf)) ESP_LOGI(TAG, "Expect: %s", at_buf); if (str_ok && (regexec(&re_ok, at_buf, match_size, match, 0) == 0)) { regfree(&re_ok); if (str_err) regfree(&re_err); - return 1; + return 0; } if (str_err && (regexec(&re_err, at_buf, match_size, match, 0) == 0)) { if (str_ok) regfree(&re_ok); regfree(&re_err); - return 0; + return 1; } at_urc_process(at_buf); diff --git a/fw/esp32/components/eos/cell.c b/fw/esp32/components/eos/cell.c index 19245bb..2584884 100644 --- a/fw/esp32/components/eos/cell.c +++ b/fw/esp32/components/eos/cell.c @@ -31,46 +31,66 @@ static void _cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t if (buf_len < 1) return; mtype = buffer[0]; - buffer++; - buf_len--; - switch (mtype & EOS_CELL_MTYPE_MASK) { - case EOS_CELL_MTYPE_DEV: + case EOS_CELL_MTYPE_DEV: { switch (mtype & ~EOS_CELL_MTYPE_MASK) { - case EOS_CELL_MTYPE_RESET: - eos_modem_reset(); + case EOS_CELL_MTYPE_STATUS: { + size_t rv; + + rv = eos_modem_get_status(buffer + 1); + eos_net_reply(EOS_NET_MTYPE_CELL, buffer, rv + 1); break; + } - case EOS_CELL_MTYPE_UART_DATA: - if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) eos_modem_write(buffer, buf_len); + case EOS_CELL_MTYPE_RESET: { + eos_modem_reset(); break; + } + + case EOS_CELL_MTYPE_UART_TAKE: { + uint8_t mode; + + mode = eos_modem_get_mode(); + if (mode == EOS_CELL_UART_MODE_NONE) break; - case EOS_CELL_MTYPE_UART_TAKE: - cell_mode = eos_modem_get_mode(); eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY); + cell_mode = mode; break; + } - case EOS_CELL_MTYPE_UART_GIVE: + case EOS_CELL_MTYPE_UART_GIVE: { + eos_modem_atinit(); eos_modem_set_mode(cell_mode); break; + } + + case EOS_CELL_MTYPE_UART_DATA: { + if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) eos_modem_write(buffer + 1, buf_len - 1); + break; + } } break; + } - case EOS_CELL_MTYPE_VOICE: + case EOS_CELL_MTYPE_VOICE: { eos_cell_voice_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); break; + } - case EOS_CELL_MTYPE_SMS: + case EOS_CELL_MTYPE_SMS: { eos_cell_sms_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); break; + } - case EOS_CELL_MTYPE_USSD: + case EOS_CELL_MTYPE_USSD: { eos_cell_ussd_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); break; + } - case EOS_CELL_MTYPE_PDP: + case EOS_CELL_MTYPE_PDP: { eos_cell_pdp_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); break; + } } } diff --git a/fw/esp32/components/eos/cell_modem.c b/fw/esp32/components/eos/cell_modem.c index 09d65d9..029abe1 100644 --- a/fw/esp32/components/eos/cell_modem.c +++ b/fw/esp32/components/eos/cell_modem.c @@ -29,8 +29,9 @@ #define UART_GPIO_DTR 32 #define UART_GPIO_RI 35 -#define MODEM_ETYPE_INIT 1 -#define MODEM_ETYPE_RI 2 +#define MODEM_ETYPE_ATINIT 1 +#define MODEM_ETYPE_STATUS 2 +#define MODEM_ETYPE_RING 3 #define AT_CMD_INIT_SIZE 5 @@ -47,7 +48,6 @@ static char *at_cmd_init[AT_CMD_INIT_SIZE] = { "AT+CPMS=\"ME\",\"ME\",\"ME\"\r" }; -static char modem_initialized = 0; static SemaphoreHandle_t mutex; static QueueHandle_t modem_queue; @@ -58,16 +58,19 @@ static char uart_buf[EOS_CELL_UART_SIZE_BUF]; static size_t uart_buf_len; static char uart_buf_dirty = 0; -static uint8_t uart_mode = EOS_CELL_UART_MODE_ATCMD; -static uint8_t _uart_mode = EOS_CELL_UART_MODE_UNDEF; +static uint8_t RTC_NOINIT_ATTR modem_initialized; +static uint8_t RTC_NOINIT_ATTR uart_mode; +static uint8_t uart_mode_next = EOS_CELL_UART_MODE_NONE; static SemaphoreHandle_t uart_mutex; -static char ppp_apn[64]; -static char ppp_user[64]; -static char ppp_pass[64]; +static char ppp_apn[EOS_CELL_PDP_SIZE_APN]; +static char ppp_usr[EOS_CELL_PDP_SIZE_USR]; +static char ppp_pwd[EOS_CELL_PDP_SIZE_PWD]; static SemaphoreHandle_t ppp_mutex; static ppp_pcb *ppp_handle; +static int ppp_connected; +static ip_addr_t ppp_ipaddr; static struct netif ppp_netif; typedef enum { @@ -76,22 +79,57 @@ typedef enum { typedef struct { uint8_t type; + unsigned char param[2]; + size_t param_len; } modem_event_t; -static void modem_atcmd_read(size_t bsize); +static void modem_send_status(void); + +static void atcmd_read(size_t bsize) { + char *ln_end; + int rd = 0; + + do { + char *uart_curr = uart_buf + uart_buf_len; + int _rd = eos_modem_read(uart_curr, MIN(bsize - rd, sizeof(uart_buf) - uart_buf_len - 1), 100); + + rd += _rd; + uart_buf_len += _rd; + uart_buf[uart_buf_len] = '\0'; + while ((ln_end = strchr(uart_curr, '\n'))) { + char *_ln_end = ln_end; + + while ((_ln_end > uart_buf) && (*(_ln_end - 1) == '\r')) _ln_end--; + memcpy(urc_buf, uart_buf, _ln_end - uart_buf); + urc_buf[_ln_end - uart_buf] = '\0'; + + uart_buf_len -= ln_end - uart_buf + 1; + if (uart_buf_len) memmove(uart_buf, ln_end + 1, uart_buf_len); + if (!uart_buf_dirty) at_urc_process(urc_buf); + + uart_curr = uart_buf; + uart_buf[uart_buf_len] = '\0'; + uart_buf_dirty = 0; + } + if (uart_buf_len == sizeof(uart_buf) - 1) { + uart_buf_len = 0; + uart_buf_dirty = 1; + } + } while (rd != bsize); +} static void uart_data_read(uint8_t mode) { - unsigned char *buf; int rd; size_t bsize; uart_get_buffered_data_len(UART_NUM_2, &bsize); switch (mode) { - case EOS_CELL_UART_MODE_ATCMD: - modem_atcmd_read(bsize); + case EOS_CELL_UART_MODE_ATCMD: { + atcmd_read(bsize); break; + } - case EOS_CELL_UART_MODE_PPP: + case EOS_CELL_UART_MODE_PPP: { rd = 0; do { @@ -100,8 +138,10 @@ static void uart_data_read(uint8_t mode) { rd += _rd; } while (rd != bsize); break; + } - case EOS_CELL_UART_MODE_RELAY: + case EOS_CELL_UART_MODE_RELAY: { + unsigned char *buf; rd = 0; do { @@ -114,25 +154,45 @@ static void uart_data_read(uint8_t mode) { rd += _rd; } while (rd != bsize); break; - - default: - break; - + } } } static void uart_event_task(void *pvParameters) { - char mode = EOS_CELL_UART_MODE_ATCMD; - char _mode = EOS_CELL_UART_MODE_ATCMD; + char mode; + char _mode; uart_event_t event; + eos_power_wait4wake(); + + xSemaphoreTake(mutex, portMAX_DELAY); + _mode = uart_mode; xSemaphoreTake(uart_mutex, portMAX_DELAY); + + if (!modem_initialized) { + int r; + + at_cmd("\r\rAT\r"); + r = at_expect("^OK", NULL, 500); + if (!r) { + r = eos_modem_atinit(); + if (r) { + _mode = EOS_CELL_UART_MODE_NONE; + ESP_LOGE(TAG, "Modem init failed"); + } + } + } + + if (_mode == EOS_CELL_UART_MODE_NONE) xSemaphoreGive(uart_mutex); + mode = _mode; + xSemaphoreGive(mutex); + while (1) { /* Waiting for UART event. */ if (xQueueReceive(uart_queue, &event, portMAX_DELAY)) { switch (event.type) { - case UART_DATA: + case UART_DATA: { /* Event of UART receiving data */ if (mode != EOS_CELL_UART_MODE_NONE) uart_data_read(mode); @@ -141,8 +201,9 @@ static void uart_event_task(void *pvParameters) { mode = _mode; } break; + } - case UART_EEVT_MODE: + case UART_EEVT_MODE: { /* Mode change */ _mode = (char)event.size; @@ -155,6 +216,7 @@ static void uart_event_task(void *pvParameters) { mode = _mode; } break; + } default: break; @@ -164,14 +226,7 @@ static void uart_event_task(void *pvParameters) { vTaskDelete(NULL); } -static void IRAM_ATTR uart_ri_isr_handler(void *arg) { - modem_event_t evt; - - evt.type = MODEM_ETYPE_RI; - xQueueSendFromISR(modem_queue, &evt, NULL); -} - -static void modem_set_mode(uint8_t mode) { +static void uart_change_mode(uint8_t mode) { uart_event_t evt; evt.type = UART_EEVT_MODE; @@ -179,110 +234,97 @@ static void modem_set_mode(uint8_t mode) { xQueueSend(uart_queue, &evt, portMAX_DELAY); } -static int modem_atcmd_init(void) { - unsigned char *buf; - int echo_on = 0; - int tries = 3; - int i, r; +static void IRAM_ATTR uart_ring_handler(void *arg) { + modem_event_t evt; - xSemaphoreTake(mutex, portMAX_DELAY); - modem_set_mode(EOS_CELL_UART_MODE_NONE); - r = xSemaphoreTake(uart_mutex, 1000); - if (r == pdFALSE) { - modem_set_mode(uart_mode); - xSemaphoreGive(mutex); - return EOS_ERR_TIMEOUT; - } + evt.type = MODEM_ETYPE_RING; + xQueueSendFromISR(modem_queue, &evt, NULL); +} - do { - at_cmd("AT\r"); - r = at_expect("^AT", "^OK", 1000); - if (r >= 0) { - echo_on = r; - if (echo_on) { - r = at_expect("^OK", NULL, 1000); - } - break; - } - tries--; - } while (tries); +static void modem_init_gpio(void) { + // Configuration for the DTR/RI lines + gpio_config_t io_conf = {}; - if (tries == 0) { - modem_set_mode(uart_mode); - xSemaphoreGive(uart_mutex); - xSemaphoreGive(mutex); + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_OUTPUT; + io_conf.pin_bit_mask = ((uint64_t)1 << UART_GPIO_DTR); + io_conf.pull_up_en = 0; + io_conf.pull_down_en = 0; + gpio_config(&io_conf); + gpio_set_level(UART_GPIO_DTR, 0); - return EOS_ERR_TIMEOUT; - } + io_conf.intr_type = GPIO_INTR_NEGEDGE; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = ((uint64_t)1 << UART_GPIO_RI); + io_conf.pull_up_en = 0; + io_conf.pull_down_en = 0; + gpio_config(&io_conf); + gpio_isr_handler_add(UART_GPIO_RI, uart_ring_handler, NULL); +} - if (echo_on) { - at_cmd("AT&F\r"); - r = at_expect("^AT&F", NULL, 1000); - r = at_expect("^OK", NULL, 1000); - } else { - at_cmd("AT&F\r"); - r = at_expect("^OK", NULL, 1000); - } - at_cmd("ATE0\r"); - r = at_expect("^ATE0", NULL, 1000); - r = at_expect("^OK", "^ERROR", 1000); +static size_t modem_get_status(unsigned char *buffer) { + size_t len; - for (i=0; i uart_buf) && (*(_ln_end - 1) == '\r')) _ln_end--; - memcpy(urc_buf, uart_buf, _ln_end - uart_buf); - urc_buf[_ln_end - uart_buf] = '\0'; + evt.type = MODEM_ETYPE_ATINIT; + xQueueSend(modem_queue, &evt, portMAX_DELAY); +} - uart_buf_len -= ln_end - uart_buf + 1; - if (uart_buf_len) memmove(uart_buf, ln_end + 1, uart_buf_len); - if (!uart_buf_dirty) at_urc_process(urc_buf); +static int modem_atinit(void) { + int r; - uart_curr = uart_buf; - uart_buf[uart_buf_len] = '\0'; - uart_buf_dirty = 0; - } - if (uart_buf_len == sizeof(uart_buf) - 1) { - uart_buf_len = 0; - uart_buf_dirty = 1; - } - } while (rd != bsize); -} + xSemaphoreTake(mutex, portMAX_DELAY); + uart_change_mode(EOS_CELL_UART_MODE_NONE); + r = xSemaphoreTake(uart_mutex, 1000); + if (r == pdFALSE) { + uart_change_mode(uart_mode); + xSemaphoreGive(mutex); + return EOS_ERR_TIMEOUT; + } -static void modem_urc_init_handler(char *urc, regmatch_t m[]) { - modem_event_t evt; + r = eos_modem_atinit(); + uart_change_mode(uart_mode); + xSemaphoreGive(uart_mutex); + xSemaphoreGive(mutex); - evt.type = MODEM_ETYPE_INIT; - xQueueSend(modem_queue, &evt, portMAX_DELAY); + return r; } static void modem_event_task(void *pvParameters) { @@ -291,16 +333,28 @@ static void modem_event_task(void *pvParameters) { while (1) { if (xQueueReceive(modem_queue, &evt, portMAX_DELAY)) { switch (evt.type) { - case MODEM_ETYPE_INIT: - modem_atcmd_init(); + case MODEM_ETYPE_ATINIT: { + int r; + + r = modem_atinit(); + if (r) ESP_LOGE(TAG, "Modem init failed"); break; + } - case MODEM_ETYPE_RI: - ESP_LOGI(TAG, "URC from RI"); + case MODEM_ETYPE_STATUS: { + unsigned char *buf; + + buf = eos_net_alloc(); + buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; + memcpy(buf + 1, evt.param, evt.param_len); + eos_net_send(EOS_NET_MTYPE_CELL, buf, evt.param_len + 1); break; + } - default: + case MODEM_ETYPE_RING: { + ESP_LOGI(TAG, "URC from RI"); break; + } } /* Obsolete uint64_t t_start = esp_timer_get_time(); @@ -350,21 +404,23 @@ static uint32_t ppp_output_cb(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *c /* PPP status callback */ static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) { - unsigned char *rbuf; struct netif *pppif = ppp_netif(pcb); LWIP_UNUSED_ARG(ctx); - switch(err_code) { + switch (err_code) { case PPPERR_NONE: { ESP_LOGI(TAG, "status_cb: Connect"); ESP_LOGI(TAG," our_ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr)); ESP_LOGI(TAG," his_ipaddr = %s\n", ipaddr_ntoa(&pppif->gw)); ESP_LOGI(TAG," netmask = %s\n", ipaddr_ntoa(&pppif->netmask)); - rbuf = eos_net_alloc(); - rbuf[0] = EOS_CELL_MTYPE_PDP | EOS_CELL_MTYPE_PDP_CONNECT; - rbuf[1] = EOS_OK; - eos_net_send(EOS_NET_MTYPE_CELL, rbuf, 2); + + xSemaphoreTake(mutex, portMAX_DELAY); + ppp_connected = 1; + ip_addr_copy(ppp_ipaddr, pppif->ip_addr); + modem_send_status(); + xSemaphoreGive(mutex); + return; } case PPPERR_PARAM: { @@ -422,16 +478,20 @@ static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) { } xSemaphoreTake(mutex, portMAX_DELAY); - - if (_uart_mode == EOS_CELL_UART_MODE_UNDEF) _uart_mode = EOS_CELL_UART_MODE_ATCMD; - uart_mode = _uart_mode; - _uart_mode = EOS_CELL_UART_MODE_UNDEF; - - modem_set_mode(EOS_CELL_UART_MODE_NONE); + if (uart_mode_next != EOS_CELL_UART_MODE_NONE) { + uart_mode = uart_mode_next; + uart_mode_next = EOS_CELL_UART_MODE_NONE; + } else { + uart_mode = EOS_CELL_UART_MODE_ATCMD; + } + ppp_connected = 0; + ip_addr_set_zero(&ppp_ipaddr); + modem_send_status(); + uart_change_mode(EOS_CELL_UART_MODE_NONE); xSemaphoreTake(uart_mutex, portMAX_DELAY); ppp_handle = NULL; - modem_set_mode(uart_mode); + uart_change_mode(uart_mode); xSemaphoreGive(uart_mutex); xSemaphoreGive(mutex); @@ -450,7 +510,7 @@ static int ppp_pause(uint32_t timeout) { uint64_t t_start; uint32_t dt, _dt; - modem_set_mode(EOS_CELL_UART_MODE_NONE); + uart_change_mode(EOS_CELL_UART_MODE_NONE); t_start = esp_timer_get_time(); r = xSemaphoreTake(uart_mutex, timeout ? timeout / portTICK_PERIOD_MS : portMAX_DELAY); @@ -458,14 +518,14 @@ static int ppp_pause(uint32_t timeout) { if (timeout) { dt = ((esp_timer_get_time() - t_start) / 1000); if (dt >= timeout) { - modem_set_mode(EOS_CELL_UART_MODE_PPP); + uart_change_mode(EOS_CELL_UART_MODE_PPP); xSemaphoreGive(uart_mutex); return EOS_ERR_TIMEOUT; } } r = xSemaphoreTake(ppp_mutex, timeout ? (timeout - dt) / portTICK_PERIOD_MS : portMAX_DELAY); if (r == pdFALSE) { - modem_set_mode(EOS_CELL_UART_MODE_PPP); + uart_change_mode(EOS_CELL_UART_MODE_PPP); xSemaphoreGive(uart_mutex); return EOS_ERR_TIMEOUT; } @@ -500,7 +560,7 @@ static int ppp_pause(uint32_t timeout) { uart_buf_len = sizeof(uart_buf) / 2; } if (!done && timeout && (dt >= timeout)) { - modem_set_mode(EOS_CELL_UART_MODE_PPP); + uart_change_mode(EOS_CELL_UART_MODE_PPP); xSemaphoreGive(uart_mutex); xSemaphoreGive(ppp_mutex); return EOS_ERR_TIMEOUT; @@ -516,9 +576,9 @@ static int ppp_resume(void) { at_cmd("ATO\r"); r = at_expect("^CONNECT", "^(ERROR|NO CARRIER)", 1000); - if (r <= 0) rv = EOS_ERR; + if (r) rv = EOS_ERR; - modem_set_mode(EOS_CELL_UART_MODE_PPP); + uart_change_mode(EOS_CELL_UART_MODE_PPP); xSemaphoreGive(uart_mutex); xSemaphoreGive(ppp_mutex); @@ -533,25 +593,25 @@ static int ppp_setup(void) { cmd_len = snprintf(cmd, sizeof(cmd), "AT+CGDCONT=1,\"IP\",\"%s\"\r", ppp_apn); if ((cmd_len < 0) || (cmd_len >= sizeof(cmd))) return EOS_ERR; - modem_set_mode(EOS_CELL_UART_MODE_NONE); + uart_change_mode(EOS_CELL_UART_MODE_NONE); r = xSemaphoreTake(uart_mutex, 1000 / portTICK_PERIOD_MS); if (r == pdFALSE) { - modem_set_mode(uart_mode); + uart_change_mode(uart_mode); return EOS_ERR_TIMEOUT; } at_cmd(cmd); r = at_expect("^OK", "^ERROR", 1000); - if (r <= 0) { - modem_set_mode(uart_mode); + if (r) { + uart_change_mode(uart_mode); xSemaphoreGive(uart_mutex); return EOS_ERR; } at_cmd("AT+CGDATA=\"PPP\",1\r"); r = at_expect("^CONNECT", "^NO CARRIER", 1000); - if (r <= 0) { - modem_set_mode(uart_mode); + if (r) { + uart_change_mode(uart_mode); xSemaphoreGive(uart_mutex); return EOS_ERR; } @@ -559,18 +619,16 @@ static int ppp_setup(void) { ppp_handle = pppapi_pppos_create(&ppp_netif, ppp_output_cb, ppp_status_cb, NULL); ppp_set_usepeerdns(ppp_handle, 1); ppp_set_default(ppp_handle); - ppp_set_auth(ppp_handle, PPPAUTHTYPE_ANY, ppp_user, ppp_pass); + ppp_set_auth(ppp_handle, PPPAUTHTYPE_ANY, ppp_usr, ppp_pwd); ppp_connect(ppp_handle, 0); - modem_set_mode(EOS_CELL_UART_MODE_PPP); + uart_change_mode(EOS_CELL_UART_MODE_PPP); xSemaphoreGive(uart_mutex); return EOS_OK; } void eos_modem_init(void) { - /* Configure parameters of an UART driver, - * communication pins and install the driver */ uart_config_t uart_config = { .baud_rate = 115200, .data_bits = UART_DATA_8_BITS, @@ -582,23 +640,11 @@ void eos_modem_init(void) { uart_set_pin(UART_NUM_2, UART_GPIO_TXD, UART_GPIO_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); uart_driver_install(UART_NUM_2, UART_SIZE_IO_BUF, UART_SIZE_IO_BUF, 10, &uart_queue, 0); - // Configuration for the DTR/RI lines - gpio_config_t io_conf; - - io_conf.intr_type = GPIO_INTR_DISABLE; - io_conf.mode = GPIO_MODE_OUTPUT; - io_conf.pin_bit_mask = ((uint64_t)1 << UART_GPIO_DTR); - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); - gpio_set_level(UART_GPIO_DTR, 0); - - io_conf.intr_type = GPIO_INTR_NEGEDGE; - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pin_bit_mask = ((uint64_t)1 << UART_GPIO_RI); - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); + if (eos_power_wakeup_cause() == EOS_PWR_WAKE_RST) { + uart_mode = EOS_CELL_UART_MODE_ATCMD; + modem_initialized = 0; + modem_init_gpio(); + } mutex = xSemaphoreCreateBinary(); xSemaphoreGive(mutex); @@ -613,16 +659,59 @@ void eos_modem_init(void) { xTaskCreate(uart_event_task, "uart_event", EOS_TASK_SSIZE_UART, NULL, EOS_TASK_PRIORITY_UART, NULL); xTaskCreate(modem_event_task, "modem_event", EOS_TASK_SSIZE_MODEM, NULL, EOS_TASK_PRIORITY_MODEM, NULL); - gpio_isr_handler_add(UART_GPIO_RI, uart_ri_isr_handler, NULL); - at_init(); - at_urc_insert("^PB DONE", modem_urc_init_handler, REG_EXTENDED); - eos_modem_set_mode(EOS_CELL_UART_MODE_ATCMD); + at_urc_insert("^PB DONE", modem_atinit_handler, REG_EXTENDED); + at_urc_insert("^\\+CME ERROR: SIM not inserted", modem_atinit_handler, REG_EXTENDED); + + ESP_LOGI(TAG, "INIT"); +} + +int eos_modem_atinit(void) { + int echo_on = 0; + int tries = 3; + int i, r; + + do { + at_cmd("AT\r"); + r = at_expect("^AT", "^OK", 1000); + if (r >= 0) { + echo_on = !r; + if (echo_on) { + r = at_expect("^OK", NULL, 1000); + } + break; + } + tries--; + } while (tries); + + if (tries == 0) return EOS_ERR_TIMEOUT; + + if (echo_on) { + at_cmd("AT&F\r"); + r = at_expect("^AT&F", NULL, 1000); + r = at_expect("^OK", NULL, 1000); + } else { + at_cmd("AT&F\r"); + r = at_expect("^OK", NULL, 1000); + } + at_cmd("ATE0\r"); + r = at_expect("^ATE0", NULL, 1000); + r = at_expect("^OK", "^ERROR", 1000); + + for (i=0; i #include "eos.h" +#include "net.h" #include "cell.h" void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { - char *apn, *user, *pass, *_buf; - uint16_t _buf_len; - switch (mtype) { - case EOS_CELL_MTYPE_PDP_CONFIG: - _buf = (char *)buffer; - _buf_len = 0; - - apn = _buf; - _buf_len = strnlen(_buf, buf_len); - if (_buf_len == buf_len) break; - _buf += _buf_len + 1; - buf_len -= _buf_len + 1; - - user = _buf; - _buf_len = strnlen(_buf, buf_len); - if (_buf_len == buf_len) break; - _buf += _buf_len + 1; - buf_len -= _buf_len + 1; - - pass = _buf; - _buf_len = strnlen(_buf, buf_len); - if (_buf_len == buf_len) break; - _buf += _buf_len + 1; - buf_len -= _buf_len + 1; - - eos_ppp_set_apn(apn); - eos_ppp_set_auth(user, pass); + case EOS_CELL_MTYPE_PDP_SET_APN: + case EOS_CELL_MTYPE_PDP_SET_USR: + case EOS_CELL_MTYPE_PDP_SET_PWD: { + char *arg; + size_t arg_len; + + buffer++; + buf_len--; + + arg = (char *)buffer; + arg_len = strnlen(arg, buf_len); + if (arg_len == buf_len) break; + if (arg_len >= EOS_CELL_PDP_SIZE_ARG) break; + + switch (mtype) { + case EOS_CELL_MTYPE_PDP_SET_APN: { + eos_ppp_set_apn(arg); + break; + + } + case EOS_CELL_MTYPE_PDP_SET_USR: { + eos_ppp_set_usr(arg); + break; + + } + case EOS_CELL_MTYPE_PDP_SET_PWD: { + eos_ppp_set_pwd(arg); + break; + } + } + break; + } + + case EOS_CELL_MTYPE_PDP_GET_APN: + case EOS_CELL_MTYPE_PDP_GET_USR: + case EOS_CELL_MTYPE_PDP_GET_PWD: { + char *arg; + + 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); + break; + + } + case EOS_CELL_MTYPE_PDP_GET_USR: { + eos_ppp_get_usr(arg); + break; + + } + case EOS_CELL_MTYPE_PDP_GET_PWD: { + eos_ppp_get_pwd(arg); + break; + } + } + + eos_net_reply(EOS_NET_MTYPE_CELL, buffer, 1 + strlen(arg)); break; + } - case EOS_CELL_MTYPE_PDP_CONNECT: + case EOS_CELL_MTYPE_PDP_CONNECT: { eos_ppp_connect(); break; + } - case EOS_CELL_MTYPE_PDP_DISCONNECT: + case EOS_CELL_MTYPE_PDP_DISCONNECT: { eos_ppp_disconnect(); break; + } } } diff --git a/fw/esp32/components/eos/cell_sms.c b/fw/esp32/components/eos/cell_sms.c index 9876ef8..56e282a 100644 --- a/fw/esp32/components/eos/cell_sms.c +++ b/fw/esp32/components/eos/cell_sms.c @@ -139,7 +139,7 @@ static int sms_encode(unsigned char *buffer, uint16_t len) { len -= 2; if (len < 2) return EOS_ERR; - switch(buffer[0]) { + switch (buffer[0]) { case EOS_CELL_SMS_ADDRTYPE_INTL: addr_type = GSM_EXT | GSM_TON_INTERNATIONAL | GSM_NPI_TELEPHONE; break; @@ -183,10 +183,11 @@ static int sms_encode(unsigned char *buffer, uint16_t len) { void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { int rv; - char b[4]; + buffer++; + buf_len--; switch (mtype) { - case EOS_CELL_MTYPE_SMS_LIST: + case EOS_CELL_MTYPE_SMS_LIST: { if (buf_len < 1) return; rv = snprintf(cmd, sizeof(cmd), "AT+CMGL=%d\r", buffer[0]); @@ -201,7 +202,7 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b uint16_t len; rv = at_expect("^\\+CMGL: [0-9]+,[0-9],.*,[0-9]+$", "^OK", 1000); - if (rv != 1) break; + if (rv) break; rv = eos_modem_readln(pdu, sizeof(pdu), 1000); if (rv) break; @@ -220,8 +221,11 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b eos_modem_give(); break; + } + + case EOS_CELL_MTYPE_SMS_SEND: { + char b[4]; - case EOS_CELL_MTYPE_SMS_SEND: rv = sms_encode(buffer, buf_len); if (rv) return; @@ -236,14 +240,17 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b eos_modem_read(b, 4, 1000); at_cmd(pdu); rv = at_expect("^\\+CMGS: [0-9]+", "^ERROR", 5000); - if (rv == 1) rv = at_expect("^OK", "^ERROR", 1000); + if (!rv) rv = at_expect("^OK", "^ERROR", 1000); eos_modem_give(); break; + } } } static void sms_received_handler(char *urc, regmatch_t m[]) { + unsigned char *buf; + uint16_t len; int ref, rv; sscanf(urc + m[1].rm_so, "%d", &ref); @@ -254,26 +261,23 @@ static void sms_received_handler(char *urc, regmatch_t m[]) { at_cmd(cmd); rv = at_expect("^\\+CMGR: [0-9],.*,[0-9]+$", "^ERROR", 1000); - if (rv == 1) { - unsigned char *buf; - uint16_t len; + if (rv) return; - rv = eos_modem_readln(pdu, sizeof(pdu), 1000); - if (rv) return; + rv = eos_modem_readln(pdu, sizeof(pdu), 1000); + if (rv) return; - pdu_len = strlen(pdu); + pdu_len = strlen(pdu); - rv = at_expect("^OK", NULL, 1000); + rv = at_expect("^OK", NULL, 1000); - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG_NEW; - rv = sms_decode(buf + 1, &len); - if (rv) { - eos_net_free(buf); - } else { - len++; - eos_net_send(EOS_NET_MTYPE_CELL, buf, len); - } + buf = eos_net_alloc(); + buf[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG_NEW; + rv = sms_decode(buf + 1, &len); + if (rv) { + eos_net_free(buf); + } else { + len++; + eos_net_send(EOS_NET_MTYPE_CELL, buf, len); } } diff --git a/fw/esp32/components/eos/cell_ussd.c b/fw/esp32/components/eos/cell_ussd.c index 5b90e35..976fd51 100644 --- a/fw/esp32/components/eos/cell_ussd.c +++ b/fw/esp32/components/eos/cell_ussd.c @@ -17,8 +17,10 @@ static int cmd_len; void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { int rv; + buffer++; + buf_len--; switch (mtype) { - case EOS_CELL_MTYPE_USSD_REQUEST: + case EOS_CELL_MTYPE_USSD_REQUEST: { if (buf_len > EOS_CELL_MAX_USSD_STR) return; buffer[buf_len] = '\0'; @@ -33,8 +35,9 @@ void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t eos_modem_give(); break; + } - case EOS_CELL_MTYPE_USSD_CANCEL: + case EOS_CELL_MTYPE_USSD_CANCEL: { rv = eos_modem_take(1000); if (rv) return; @@ -43,8 +46,8 @@ void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t eos_modem_give(); break; + } } - } static void ussd_reply_handler(char *urc, regmatch_t m[]) { diff --git a/fw/esp32/components/eos/cell_voice.c b/fw/esp32/components/eos/cell_voice.c index c0b9a7d..89233f0 100644 --- a/fw/esp32/components/eos/cell_voice.c +++ b/fw/esp32/components/eos/cell_voice.c @@ -2,6 +2,9 @@ #include #include +#include +#include + #include #include @@ -16,8 +19,10 @@ static int cmd_len; void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { int rv; + buffer++; + buf_len--; switch (mtype) { - case EOS_CELL_MTYPE_VOICE_DIAL: + case EOS_CELL_MTYPE_VOICE_DIAL: { if (buf_len > EOS_CELL_MAX_DIAL_STR) return; buffer[buf_len] = '\0'; @@ -33,19 +38,21 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t eos_modem_give(); eos_cell_pcm_start(); break; + } - case EOS_CELL_MTYPE_VOICE_ANSWER: + case EOS_CELL_MTYPE_VOICE_ANSWER: { rv = eos_modem_take(1000); if (rv) return; at_cmd("ATA\r"); - rv = at_expect("^OK", "^ERROR", 1000); + rv = at_expect("^OK", "^NO CARRIER", 1000); eos_modem_give(); eos_cell_pcm_start(); break; + } - case EOS_CELL_MTYPE_VOICE_HANGUP: + case EOS_CELL_MTYPE_VOICE_HANGUP: { eos_cell_pcm_stop(); rv = eos_modem_take(1000); @@ -56,10 +63,12 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t eos_modem_give(); break; + } - case EOS_CELL_MTYPE_VOICE_PCM: + case EOS_CELL_MTYPE_VOICE_PCM: { eos_cell_pcm_push(buffer, buf_len); break; + } } } @@ -74,7 +83,7 @@ static void ring_handler(char *urc, regmatch_t m[]) { buf[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); - if (rv == 1) { + if (!rv) { ring_buf[match[1].rm_eo] = '\0'; strcpy((char *)buf + 1, ring_buf + match[1].rm_so); len += 1 + match[1].rm_eo - match[1].rm_so; @@ -88,6 +97,23 @@ static void call_begin_handler(char *urc, regmatch_t m[]) { buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BEGIN; eos_net_send(EOS_NET_MTYPE_CELL, buf, 1); + + vTaskDelay(100 / portTICK_PERIOD_MS); + at_cmd("AT+CECH=0x0000\r"); + at_expect("^OK", "^ERROR", 1000); + + at_cmd("AT+CECDT=0x0000\r"); + at_expect("^OK", "^ERROR", 1000); + + at_cmd("AT+CECWB=0x0000\r"); + at_expect("^OK", "^ERROR", 1000); + + at_cmd("AT+CNSLIM=0x0000\r"); + at_expect("^OK", "^ERROR", 1000); + /* + at_cmd("AT+CECRX=0\r"); + at_expect("^OK", "^ERROR", 1000); + */ } static void call_end_handler(char *urc, regmatch_t m[]) { diff --git a/fw/esp32/components/eos/gsm.c b/fw/esp32/components/eos/gsm.c index 9a0874a..920e121 100644 --- a/fw/esp32/components/eos/gsm.c +++ b/fw/esp32/components/eos/gsm.c @@ -56,7 +56,7 @@ void gsm_dcs_dec(uint8_t dcs, uint8_t *enc, uint16_t *flags) { switch (group) { case GSM_DCS_MWI_DISCARD: case GSM_DCS_MWI_STORE_GSM7: - case GSM_DCS_MWI_STORE_UCS2: + case GSM_DCS_MWI_STORE_UCS2: { if (group == GSM_DCS_MWI_STORE_UCS2) { *enc = GSM_ENC_UCS2; } else { @@ -66,12 +66,14 @@ void gsm_dcs_dec(uint8_t dcs, uint8_t *enc, uint16_t *flags) { *flags |= GSM_FLAG_MWI; *flags |= (uint16_t)(dcs & (GSM_DCS_MWI_SENSE | GSM_DCS_MWI_TYPE)) << 12; break; + } - case GSM_DCS_ENCLASS: + case GSM_DCS_ENCLASS: { *flags |= GSM_FLAG_CLASS; *flags |= (uint16_t)(dcs & GSM_DCS_CLASS) << 8; *enc = dcs & GSM_DCS_ENCLASS_ENC ? GSM_ENC_8BIT : GSM_ENC_7BIT; break; + } } } } diff --git a/fw/esp32/components/eos/include/cell.h b/fw/esp32/components/eos/include/cell.h index 2cbba7e..269615d 100644 --- a/fw/esp32/components/eos/include/cell.h +++ b/fw/esp32/components/eos/include/cell.h @@ -12,7 +12,7 @@ #define EOS_CELL_MAX_MTYPE 8 /* EOS_CELL_MTYPE_DEV subtypes */ -#define EOS_CELL_MTYPE_READY 1 +#define EOS_CELL_MTYPE_STATUS 1 #define EOS_CELL_MTYPE_UART_DATA 2 #define EOS_CELL_MTYPE_UART_TAKE 3 #define EOS_CELL_MTYPE_UART_GIVE 4 @@ -38,43 +38,64 @@ #define EOS_CELL_MTYPE_USSD_REPLY 2 #define EOS_CELL_MTYPE_USSD_CANCEL 3 -#define EOS_CELL_MTYPE_PDP_CONFIG 1 -#define EOS_CELL_MTYPE_PDP_CONNECT 2 -#define EOS_CELL_MTYPE_PDP_DISCONNECT 3 +#define EOS_CELL_MTYPE_PDP_GET_APN 1 +#define EOS_CELL_MTYPE_PDP_GET_USR 2 +#define EOS_CELL_MTYPE_PDP_GET_PWD 3 +#define EOS_CELL_MTYPE_PDP_SET_APN 4 +#define EOS_CELL_MTYPE_PDP_SET_USR 5 +#define EOS_CELL_MTYPE_PDP_SET_PWD 6 +#define EOS_CELL_MTYPE_PDP_CONNECT 7 +#define EOS_CELL_MTYPE_PDP_DISCONNECT 8 + +#define EOS_CELL_STATUS_RESET 0 +#define EOS_CELL_STATUS_IDLE 1 +#define EOS_CELL_STATUS_RELAY 2 +#define EOS_CELL_STATUS_PPP 3 #define EOS_CELL_SMS_ADDRTYPE_INTL 1 #define EOS_CELL_SMS_ADDRTYPE_ALPHA 2 #define EOS_CELL_SMS_ADDRTYPE_OTHER 3 +#define EOS_CELL_PDP_SIZE_APN 64 +#define EOS_CELL_PDP_SIZE_USR 64 +#define EOS_CELL_PDP_SIZE_PWD 64 +#define EOS_CELL_PDP_SIZE_ARG 64 + #define EOS_CELL_UART_MODE_NONE 0 #define EOS_CELL_UART_MODE_ATCMD 1 #define EOS_CELL_UART_MODE_PPP 2 #define EOS_CELL_UART_MODE_RELAY 3 -#define EOS_CELL_UART_MODE_UNDEF 0xff -#define EOS_CELL_UART_SIZE_BUF 1024 +#define EOS_CELL_MAX_USSD_STR 128 +#define EOS_CELL_MAX_DIAL_STR 128 -#define EOS_CELL_MAX_USSD_STR 256 -#define EOS_CELL_MAX_DIAL_STR 256 +#define EOS_CELL_UART_SIZE_BUF 1024 void eos_cell_init(void); void eos_modem_init(void); +int eos_modem_atinit(void); void eos_modem_flush(void); size_t eos_modem_write(void *data, size_t size); size_t eos_modem_read(void *data, size_t size, uint32_t timeout); int eos_modem_readln(char *buf, size_t buf_size, uint32_t timeout); int eos_modem_resp(char *ok_str, char *err_str, uint32_t timeout); uint8_t eos_modem_get_mode(void); +size_t eos_modem_get_status(unsigned char *buffer); int eos_modem_set_mode(uint8_t mode); int eos_modem_take(uint32_t timeout); void eos_modem_give(void); -void eos_modem_sleep(uint8_t mode); +void eos_modem_sleep(void); +void eos_modem_deep_sleep(void); void eos_modem_wake(uint8_t source, uint8_t mode); int eos_modem_reset(void); +void eos_ppp_get_apn(char *apn); void eos_ppp_set_apn(char *apn); -void eos_ppp_set_auth(char *user, char *pass); +void eos_ppp_get_usr(char *usr); +void eos_ppp_set_usr(char *usr); +void eos_ppp_get_pwd(char *pwd); +void eos_ppp_set_pwd(char *pwd); int eos_ppp_connect(void); void eos_ppp_disconnect(void); diff --git a/fw/esp32/components/eos/include/net.h b/fw/esp32/components/eos/include/net.h index 5bccc57..3e9e625 100644 --- a/fw/esp32/components/eos/include/net.h +++ b/fw/esp32/components/eos/include/net.h @@ -32,5 +32,5 @@ void eos_net_free(unsigned char *buf); int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len); void eos_net_reply(unsigned char mtype, unsigned char *buffer, uint16_t len); void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler); -void eos_net_sleep_done(uint8_t mode); +void eos_net_sleep(void); void eos_net_wake(uint8_t source, uint8_t mode); diff --git a/fw/esp32/components/eos/include/power.h b/fw/esp32/components/eos/include/power.h index 3d2e0bc..2215907 100644 --- a/fw/esp32/components/eos/include/power.h +++ b/fw/esp32/components/eos/include/power.h @@ -4,9 +4,10 @@ #define EOS_PWR_WAKE_RST 0 #define EOS_PWR_WAKE_BTN 1 -#define EOS_PWR_WAKE_NET 2 -#define EOS_PWR_WAKE_MSG 3 -#define EOS_PWR_WAKE_UART 4 +#define EOS_PWR_WAKE_UART 2 +#define EOS_PWR_WAKE_NET 3 +#define EOS_PWR_WAKE_NETQ 4 +#define EOS_PWR_WAKE_UNDEF 5 #define EOS_PWR_SMODE_LIGHT 1 #define EOS_PWR_SMODE_DEEP 2 @@ -14,6 +15,7 @@ void eos_power_init(void); void eos_power_wait4init(void); +void eos_power_wait4wake(void); uint8_t eos_power_wakeup_cause(void); void eos_power_sleep(void); void eos_power_wake(uint8_t source); diff --git a/fw/esp32/components/eos/include/wifi.h b/fw/esp32/components/eos/include/wifi.h index 5a668fb..c1819e7 100644 --- a/fw/esp32/components/eos/include/wifi.h +++ b/fw/esp32/components/eos/include/wifi.h @@ -1,9 +1,16 @@ -#define EOS_WIFI_MTYPE_SCAN 1 -#define EOS_WIFI_MTYPE_AUTH 2 -#define EOS_WIFI_MTYPE_CONNECT 3 -#define EOS_WIFI_MTYPE_DISCONNECT 4 +#define EOS_WIFI_MTYPE_STATUS 0 +#define EOS_WIFI_MTYPE_SCAN 1 +#define EOS_WIFI_MTYPE_START 2 +#define EOS_WIFI_MTYPE_STOP 3 +#define EOS_WIFI_MTYPE_CONNECT 4 +#define EOS_WIFI_MTYPE_DISCONNECT 5 -#define EOS_WIFI_MAX_MTYPE 5 +#define EOS_WIFI_STATUS_OFF 0 +#define EOS_WIFI_STATUS_DISCONNECTED 1 +#define EOS_WIFI_STATUS_CONNECTED 2 +#define EOS_WIFI_STATUS_GOT_IP 3 + +#define EOS_WIFI_MAX_SCAN_RECORDS 20 void eos_wifi_init(void); @@ -11,3 +18,7 @@ int eos_wifi_scan(void); 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); +void eos_wifi_send_status(void); +void eos_wifi_send_scan(void); \ No newline at end of file diff --git a/fw/esp32/components/eos/net.c b/fw/esp32/components/eos/net.c index 73d1c43..56ec940 100644 --- a/fw/esp32/components/eos/net.c +++ b/fw/esp32/components/eos/net.c @@ -28,7 +28,8 @@ #define SPI_SIZE_BUF (EOS_NET_SIZE_BUF + 4) #define SPI_SIZE_HDR 3 -static volatile char net_sleep = 0; +static volatile int net_sleep = 0; +static volatile int net_wake = 0; static EOSBufQ net_buf_q; static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ]; @@ -96,7 +97,7 @@ static void net_xchg_task(void *pvParameters) { spi_tr.rx_buffer = buf_recv; spi_tr.length = SPI_SIZE_BUF * 8; - if (eos_power_wakeup_cause()) { + if (eos_power_wakeup_cause() != EOS_PWR_WAKE_RST) { wake = 1; skip_msg = 1; } @@ -143,22 +144,20 @@ static void net_xchg_task(void *pvParameters) { if (buf_recv[0] == 0xFF) { // Sleep req if (buf_send[0] == 0) { - int abort = 0; + spi_slave_free(VSPI_HOST); + eos_power_sleep(); xSemaphoreTake(mutex, portMAX_DELAY); net_sleep = 1; - if (eos_msgq_len(&net_send_q)) abort = 1; + if (eos_msgq_len(&net_send_q)) net_wake = 1; xSemaphoreGive(mutex); - spi_slave_free(VSPI_HOST); - - eos_power_sleep(); - if (abort) eos_power_wake(EOS_PWR_WAKE_MSG); - + if (net_wake) eos_power_wake(EOS_PWR_WAKE_NETQ); vTaskSuspend(NULL); xSemaphoreTake(mutex, portMAX_DELAY); net_sleep = 0; + net_wake = 0; xSemaphoreGive(mutex); spi_slave_initialize(VSPI_HOST, &spi_bus_cfg, &spi_slave_cfg, 1); @@ -174,9 +173,9 @@ static void net_xchg_task(void *pvParameters) { len |= (uint16_t)buf_recv[2] & 0xFF; buffer = buf_recv + SPI_SIZE_HDR; if ((mtype <= EOS_NET_MAX_MTYPE) && (len <= EOS_NET_MTU)) { - net_handler[mtype - 1](mtype, buffer, len); + net_handler[mtype - 1](buf_recv[0], buffer, len); } else { - bad_handler(mtype, buffer, len); + bad_handler(buf_recv[0], buffer, len); } if ((mtype_flags & EOS_NET_MTYPE_FLAG_ONEW) && buf_send[0]) { skip_msg = 1; @@ -196,7 +195,7 @@ void eos_net_init(void) { int i; // Configuration for the handshake lines - gpio_config_t io_conf; + gpio_config_t io_conf = {}; io_conf.intr_type = GPIO_INTR_DISABLE; io_conf.mode = GPIO_MODE_OUTPUT; @@ -254,14 +253,14 @@ int eos_net_send(unsigned char mtype, unsigned char *buffer, uint16_t len) { int sleep; xSemaphoreTake(mutex, portMAX_DELAY); - sleep = net_sleep; + sleep = net_sleep && !net_wake; gpio_set_level(SPI_GPIO_RTS, 1); rv = eos_msgq_push(&net_send_q, mtype, buffer, len); xSemaphoreGive(mutex); if (rv) eos_net_free(buffer); - if (sleep) eos_power_wake(EOS_PWR_WAKE_MSG); + if (sleep) eos_power_wake(EOS_PWR_WAKE_NETQ); return rv; } @@ -278,7 +277,7 @@ void eos_net_set_handler(unsigned char mtype, eos_net_fptr_t handler) { if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler; } -void eos_net_sleep_done(uint8_t mode) { +void eos_net_sleep(void) { gpio_set_level(SPI_GPIO_CTS, 1); vTaskDelay(200 / portTICK_PERIOD_MS); gpio_set_level(SPI_GPIO_CTS, 0); diff --git a/fw/esp32/components/eos/power.c b/fw/esp32/components/eos/power.c index 0cbb4e0..c659481 100644 --- a/fw/esp32/components/eos/power.c +++ b/fw/esp32/components/eos/power.c @@ -5,8 +5,10 @@ #include #include #include +#include #include #include +#include #include "eos.h" #include "net.h" @@ -18,9 +20,10 @@ #define POWER_GPIO_UART 35 #define POWER_ETYPE_BTN 1 -#define POWER_ETYPE_SLEEP 2 -#define POWER_ETYPE_WAKE 3 -#define POWER_ETYPE_NETRDY 4 +#define POWER_ETYPE_SLEEP1 2 +#define POWER_ETYPE_SLEEP2 3 +#define POWER_ETYPE_WAKE 4 +#define POWER_ETYPE_NETRDY 5 typedef struct { uint8_t type; @@ -30,6 +33,8 @@ typedef struct { }; } power_event_t; +static esp_timer_handle_t timer; + static esp_pm_lock_handle_t power_lock_cpu_freq; static esp_pm_lock_handle_t power_lock_apb_freq; static esp_pm_lock_handle_t power_lock_no_sleep; @@ -39,6 +44,7 @@ static const char *TAG = "EOS POWER"; static QueueHandle_t power_queue; static volatile int init_done = 0; +static volatile int wake_done = 0; static void IRAM_ATTR btn_handler(void *arg) { power_event_t evt; @@ -79,62 +85,79 @@ static void IRAM_ATTR uart_wake_handler(void *arg) { xQueueSendFromISR(power_queue, &evt, NULL); } -void power_sleep(uint8_t mode) { - gpio_config_t io_conf; +static void timer_handler(void *arg) { + power_event_t evt; - eos_modem_sleep(mode); - eos_net_sleep_done(mode); + evt.type = POWER_ETYPE_SLEEP2; + xQueueSendFromISR(power_queue, &evt, NULL); +} - switch (mode) { - case EOS_PWR_SMODE_LIGHT: - io_conf.intr_type = GPIO_INTR_DISABLE; - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_NET); - io_conf.pull_up_en = 0; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); +void power_sleep_stage1(void) { + gpio_config_t io_conf = {}; + + eos_modem_sleep(); + eos_net_sleep(); + + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = ((uint64_t)1 << POWER_GPIO_NET); + io_conf.pull_up_en = 0; + io_conf.pull_down_en = 0; + gpio_config(&io_conf); - gpio_isr_handler_add(POWER_GPIO_BTN, btn_wake_handler, NULL); - gpio_isr_handler_add(POWER_GPIO_NET, net_wake_handler, NULL); - gpio_isr_handler_add(POWER_GPIO_UART, uart_wake_handler, NULL); + gpio_isr_handler_add(POWER_GPIO_BTN, btn_wake_handler, NULL); + gpio_isr_handler_add(POWER_GPIO_NET, net_wake_handler, NULL); + gpio_isr_handler_add(POWER_GPIO_UART, uart_wake_handler, NULL); - esp_sleep_enable_gpio_wakeup(); - gpio_wakeup_enable(POWER_GPIO_BTN, GPIO_INTR_LOW_LEVEL); - gpio_wakeup_enable(POWER_GPIO_NET, GPIO_INTR_LOW_LEVEL); - gpio_wakeup_enable(POWER_GPIO_UART, GPIO_INTR_LOW_LEVEL); + esp_sleep_enable_gpio_wakeup(); + gpio_wakeup_enable(POWER_GPIO_BTN, GPIO_INTR_LOW_LEVEL); + gpio_wakeup_enable(POWER_GPIO_NET, GPIO_INTR_LOW_LEVEL); + gpio_wakeup_enable(POWER_GPIO_UART, GPIO_INTR_LOW_LEVEL); - ESP_LOGI(TAG, "SLEEP"); + esp_timer_start_once(timer, 10 * 1000000); - esp_pm_lock_release(power_lock_apb_freq); - esp_pm_lock_release(power_lock_no_sleep); + esp_pm_lock_release(power_lock_cpu_freq); + esp_pm_lock_release(power_lock_apb_freq); + esp_pm_lock_release(power_lock_no_sleep); +} +void power_sleep_stage2(uint8_t mode) { + switch (mode) { + case EOS_PWR_SMODE_LIGHT: { + ESP_LOGI(TAG, "LIGHT SLEEP"); + + esp_light_sleep_start(); break; + } + + case EOS_PWR_SMODE_DEEP: { + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); - case EOS_PWR_SMODE_DEEP: gpio_deep_sleep_hold_en(); esp_sleep_enable_ext0_wakeup(POWER_GPIO_BTN, 0); - esp_sleep_enable_ext1_wakeup((uint64_t)1 << POWER_GPIO_UART, ESP_EXT1_WAKEUP_ALL_LOW); + // esp_sleep_enable_ext1_wakeup((uint64_t)1 << POWER_GPIO_UART, ESP_EXT1_WAKEUP_ALL_LOW); - ESP_LOGI(TAG, "SLEEP"); + ESP_LOGI(TAG, "DEEP SLEEP"); + eos_modem_deep_sleep(); esp_deep_sleep_start(); break; - - default: - break; + } } } void power_wake_stage1(uint8_t source, uint8_t mode) { - gpio_config_t io_conf; - if (mode == EOS_PWR_SMODE_LIGHT) { + gpio_config_t io_conf = {}; + + esp_pm_lock_acquire(power_lock_cpu_freq); esp_pm_lock_acquire(power_lock_apb_freq); esp_pm_lock_acquire(power_lock_no_sleep); gpio_wakeup_disable(POWER_GPIO_BTN); gpio_wakeup_disable(POWER_GPIO_NET); gpio_wakeup_disable(POWER_GPIO_UART); + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); gpio_isr_handler_remove(POWER_GPIO_NET); io_conf.intr_type = GPIO_INTR_DISABLE; @@ -147,8 +170,8 @@ void power_wake_stage1(uint8_t source, uint8_t mode) { gpio_intr_disable(POWER_GPIO_BTN); if ((source != EOS_PWR_WAKE_BTN) && (source != EOS_PWR_WAKE_NET)) { - gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_OUTPUT); gpio_set_level(POWER_GPIO_BTN, 0); + gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_OUTPUT); vTaskDelay(200 / portTICK_PERIOD_MS); gpio_set_direction(POWER_GPIO_BTN, GPIO_MODE_INPUT); } @@ -163,58 +186,77 @@ void power_wake_stage2(uint8_t source, uint8_t mode) { gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL); ESP_LOGI(TAG, "WAKE"); + wake_done = 1; } static void power_event_task(void *pvParameters) { - unsigned char *buf; power_event_t evt; uint8_t source; uint8_t wakeup_cause; uint8_t mode; - int sleep; + int sleep1, sleep2; + mode = 0; source = 0; wakeup_cause = eos_power_wakeup_cause(); - if (wakeup_cause) { + if (wakeup_cause != EOS_PWR_WAKE_RST) { mode = EOS_PWR_SMODE_DEEP; - sleep = 1; + sleep1 = 1; } else { - mode = EOS_PWR_SMODE_LIGHT; - sleep = 0; + sleep1 = 0; } + sleep2 = 0; while (1) { if (xQueueReceive(power_queue, &evt, portMAX_DELAY)) { switch (evt.type) { - case POWER_ETYPE_SLEEP: - if (!sleep) { + case POWER_ETYPE_SLEEP1: { + if (!sleep1) { + mode = EOS_PWR_SMODE_LIGHT; + power_sleep_stage1(); + sleep1 = 1; + sleep2 = 1; + } + break; + } + + case POWER_ETYPE_SLEEP2: { + if (sleep2) { mode = EOS_PWR_SMODE_DEEP; - power_sleep(mode); - sleep = 1; + power_sleep_stage2(mode); + sleep2 = 0; } break; + } - case POWER_ETYPE_WAKE: - if (sleep) { + case POWER_ETYPE_WAKE: { + if (sleep1) { source = evt.source; power_wake_stage1(source, mode); + if (sleep2) { + esp_timer_stop(timer); + sleep2 = 0; + } } break; + } - case POWER_ETYPE_NETRDY: - if (sleep && source) { - power_wake_stage2(source, mode); - sleep = 0; - source = 0; - } + case POWER_ETYPE_NETRDY: { + power_wake_stage2(source, mode); + sleep1 = 0; + source = 0; break; + } + + case POWER_ETYPE_BTN: { + unsigned char *buf; - case POWER_ETYPE_BTN: buf = eos_net_alloc(); buf[0] = EOS_PWR_MTYPE_BUTTON; buf[1] = evt.level; eos_net_send(EOS_NET_MTYPE_POWER, buf, 2); break; + } default: break; @@ -226,7 +268,8 @@ static void power_event_task(void *pvParameters) { void eos_power_init(void) { esp_err_t ret; - gpio_config_t io_conf; + gpio_config_t io_conf = {}; + esp_timer_create_args_t timer_args = {}; esp_pm_config_esp32_t pwr_conf; uint8_t wakeup_cause; @@ -238,6 +281,13 @@ void eos_power_init(void) { gpio_config(&io_conf); gpio_isr_handler_add(POWER_GPIO_BTN, btn_handler, NULL); + timer_args.callback = timer_handler, + timer_args.arg = NULL; + timer_args.name = "sleep"; + + ret = esp_timer_create(&timer_args, &timer); + assert(ret == ESP_OK); + /* ret = esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); assert(ret == ESP_OK); @@ -272,7 +322,9 @@ void eos_power_init(void) { xTaskCreate(power_event_task, "power_event", EOS_TASK_SSIZE_PWR, NULL, EOS_TASK_PRIORITY_PWR, NULL); wakeup_cause = eos_power_wakeup_cause(); - if (wakeup_cause) eos_power_wake(wakeup_cause); + if (wakeup_cause != EOS_PWR_WAKE_RST) { + eos_power_wake(wakeup_cause); + } init_done = 1; ESP_LOGI(TAG, "INIT"); @@ -282,25 +334,35 @@ void eos_power_wait4init(void) { while (!init_done); } +void eos_power_wait4wake(void) { + if (eos_power_wakeup_cause() == EOS_PWR_WAKE_RST) return; + while (!wake_done); +} + uint8_t eos_power_wakeup_cause(void) { - esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); + esp_reset_reason_t reset_cause = esp_reset_reason(); + esp_sleep_wakeup_cause_t wakeup_cause = esp_sleep_get_wakeup_cause(); - switch (cause) { - case ESP_SLEEP_WAKEUP_EXT0: - return EOS_PWR_WAKE_BTN; + if (reset_cause == ESP_RST_DEEPSLEEP) { + switch (wakeup_cause) { + case ESP_SLEEP_WAKEUP_EXT0: + return EOS_PWR_WAKE_BTN; - case ESP_SLEEP_WAKEUP_EXT1: - return EOS_PWR_WAKE_UART; + case ESP_SLEEP_WAKEUP_EXT1: + return EOS_PWR_WAKE_UART; - default: - return EOS_PWR_WAKE_RST; + default: + return EOS_PWR_WAKE_UNDEF; + } + } else { + return EOS_PWR_WAKE_RST; } } void eos_power_sleep(void) { power_event_t evt; - evt.type = POWER_ETYPE_SLEEP; + evt.type = POWER_ETYPE_SLEEP1; evt.source = 0; xQueueSend(power_queue, &evt, portMAX_DELAY); } diff --git a/fw/esp32/components/eos/rng.c b/fw/esp32/components/eos/rng.c index 79eca21..ca9e051 100644 --- a/fw/esp32/components/eos/rng.c +++ b/fw/esp32/components/eos/rng.c @@ -7,7 +7,7 @@ static const char *TAG = "EOS RNG"; -static void rng_handler(unsigned char type, unsigned char *buffer, uint16_t buf_len) { +static void rng_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { uint16_t rng_len = 0; if (buf_len < sizeof(uint16_t)) goto rng_handler_fin; diff --git a/fw/esp32/components/eos/sock.c b/fw/esp32/components/eos/sock.c index ec198f0..e1b703f 100644 --- a/fw/esp32/components/eos/sock.c +++ b/fw/esp32/components/eos/sock.c @@ -108,15 +108,18 @@ static void udp_rcvr_task(void *pvParameters) { vTaskDelete(NULL); } -static void sock_handler(unsigned char type, unsigned char *buffer, uint16_t buf_len) { - EOSNetAddr addr; +static void sock_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { + unsigned char mtype; uint8_t sock_i; int sock, i; if (buf_len < 1) return; - switch(buffer[0]) { - case EOS_SOCK_MTYPE_PKT: + mtype = buffer[0]; + switch (mtype) { + case EOS_SOCK_MTYPE_PKT: { + EOSNetAddr addr; + if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return; sock_i = buffer[1]-1; @@ -131,8 +134,9 @@ static void sock_handler(unsigned char type, unsigned char *buffer, uint16_t buf buffer += sizeof(addr.port); t_sendto(sock, buffer, buf_len - EOS_SOCK_SIZE_UDP_HDR, &addr); break; + } - case EOS_SOCK_MTYPE_OPEN_DGRAM: + case EOS_SOCK_MTYPE_OPEN_DGRAM: { sock = t_open_dgram(); sock_i = 0; if (sock > 0) { @@ -151,8 +155,9 @@ static void sock_handler(unsigned char type, unsigned char *buffer, uint16_t buf buffer[1] = sock_i; eos_net_reply(EOS_NET_MTYPE_SOCK, buffer, 2); break; + } - case EOS_SOCK_MTYPE_CLOSE: + case EOS_SOCK_MTYPE_CLOSE: { if (buf_len < 2) return; sock_i = buffer[1]-1; @@ -161,10 +166,7 @@ static void sock_handler(unsigned char type, unsigned char *buffer, uint16_t buf sock = _socks[sock_i]; t_close(sock); break; - - default: - ESP_LOGE(TAG, "BAD TYPE:%d", buffer[0]); - break; + } } } diff --git a/fw/esp32/components/eos/wifi.c b/fw/esp32/components/eos/wifi.c index d294f45..537aeba 100755 --- a/fw/esp32/components/eos/wifi.c +++ b/fw/esp32/components/eos/wifi.c @@ -18,214 +18,196 @@ // XXX: WiFi fail due to no DHCP server -#define WIFI_MAX_SCAN_RECORDS 20 #define WIFI_MAX_CONNECT_ATTEMPTS 3 -#define WIFI_STATE_STOPPED 0 -#define WIFI_STATE_SCANNING 1 -#define WIFI_STATE_CONNECTING 2 -#define WIFI_STATE_CONNECTED 3 -#define WIFI_STATE_DISCONNECTING 4 -#define WIFI_STATE_DISCONNECTED 5 - -#define WIFI_ACTION_NONE 0 -#define WIFI_ACTION_SCAN 1 -#define WIFI_ACTION_CONNECT 2 -#define WIFI_ACTION_DISCONNECT 3 - static const char *TAG = "EOS WIFI"; -static SemaphoreHandle_t mutex; - -static wifi_config_t wifi_sta_config; -static wifi_scan_config_t wifi_scan_config; - -static int wifi_connect_cnt = 0; -static uint8_t wifi_action; -static uint8_t wifi_state; -static wifi_ap_record_t scan_r[WIFI_MAX_SCAN_RECORDS]; -static uint16_t scan_n; +static esp_netif_t *wifi_netif; static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { - esp_err_t ret = ESP_OK; - char _disconnect; - uint8_t _action, _state; - unsigned char *rbuf, *p; - int i, len; - ip_event_got_ip_t *got_ip; + static int reconnect_cnt = 0; + static int stop = 0; if (event_base == WIFI_EVENT) { - switch(event_id) { - case WIFI_EVENT_SCAN_DONE: - scan_n = WIFI_MAX_SCAN_RECORDS; - memset(scan_r, 0, sizeof(scan_r)); - esp_wifi_scan_get_ap_records(&scan_n, scan_r); - - ESP_LOGI(TAG, "Scan done: %d", scan_n); - xSemaphoreTake(mutex, portMAX_DELAY); - _state = wifi_state; - if (wifi_state == WIFI_STATE_CONNECTED) wifi_action = WIFI_ACTION_NONE; - xSemaphoreGive(mutex); - - if (_state != WIFI_STATE_CONNECTED) ret = esp_wifi_stop(); - - rbuf = eos_net_alloc(); - rbuf[0] = EOS_WIFI_MTYPE_SCAN; - p = rbuf + 1; - for (i=0; i EOS_NET_MTU) break; - - strcpy((char *)p, (char *)scan_r[i].ssid); - p += len + 1; - } - eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, p - rbuf); + switch (event_id) { + case WIFI_EVENT_SCAN_DONE: { + ESP_LOGI(TAG, "Event scan done"); + eos_wifi_send_scan(); break; + } case WIFI_EVENT_STA_START: - xSemaphoreTake(mutex, portMAX_DELAY); - _action = wifi_action; - xSemaphoreGive(mutex); + case WIFI_EVENT_STA_STOP: + case WIFI_EVENT_STA_CONNECTED: { + ESP_LOGI(TAG, "Event start/stop/conneced"); + stop = 0; + reconnect_cnt = 0; + eos_wifi_send_status(); + break; + } - switch (_action) { - case WIFI_ACTION_SCAN: - ret = esp_wifi_scan_start(&wifi_scan_config, 0); - break; + case WIFI_EVENT_STA_DISCONNECTED: { + wifi_event_sta_disconnected_t *sta_disconnected; - case WIFI_ACTION_CONNECT: - ret = esp_wifi_connect(); - break; + sta_disconnected = (wifi_event_sta_disconnected_t *)event_data; + ESP_LOGI(TAG, "Event disconnected - reason: %d", sta_disconnected->reason); - default: - break; + if (sta_disconnected->reason == WIFI_REASON_ASSOC_LEAVE) { + stop = 0; + reconnect_cnt = 0; + eos_wifi_send_status(); + break; } - break; - - case WIFI_EVENT_STA_STOP: - xSemaphoreTake(mutex, portMAX_DELAY); - wifi_state = WIFI_STATE_STOPPED; - wifi_action = WIFI_ACTION_NONE; - xSemaphoreGive(mutex); - break; - - case WIFI_EVENT_STA_CONNECTED: - xSemaphoreTake(mutex, portMAX_DELAY); - wifi_state = WIFI_STATE_CONNECTED; - wifi_action = WIFI_ACTION_NONE; - wifi_connect_cnt = WIFI_MAX_CONNECT_ATTEMPTS; - xSemaphoreGive(mutex); - break; + if ((reconnect_cnt == 0) && (sta_disconnected->reason == WIFI_REASON_BEACON_TIMEOUT)) { + stop = 1; + } + if (reconnect_cnt < WIFI_MAX_CONNECT_ATTEMPTS) { + esp_wifi_connect(); - case WIFI_EVENT_STA_DISCONNECTED: - xSemaphoreTake(mutex, portMAX_DELAY); - if (wifi_connect_cnt) wifi_connect_cnt--; - _action = wifi_action; - _disconnect = (wifi_connect_cnt == 0); - if (_disconnect) wifi_state = WIFI_STATE_DISCONNECTED; - xSemaphoreGive(mutex); - - if (_disconnect) { - rbuf = eos_net_alloc(); - rbuf[0] = EOS_WIFI_MTYPE_DISCONNECT; - eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, 1); - if (!_action) ret = esp_wifi_stop(); + reconnect_cnt++; } else { - ret = esp_wifi_connect(); + eos_wifi_send_status(); + + reconnect_cnt = 0; + if (stop) { + esp_wifi_stop(); + stop = 0; + } } break; + } - default: // Ignore the other event types + default: // Ignore the other event types break; } } else if (event_base == IP_EVENT) { - switch(event_id) { - case IP_EVENT_STA_GOT_IP: + switch (event_id) { + case IP_EVENT_STA_GOT_IP: { + ip_event_got_ip_t *got_ip; + got_ip = (ip_event_got_ip_t *)event_data; - ESP_LOGI(TAG, "IP address: " IPSTR, IP2STR(&got_ip->ip_info.ip)); - rbuf = eos_net_alloc(); - rbuf[0] = EOS_WIFI_MTYPE_CONNECT; - rbuf[1] = EOS_OK; - eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, 2); + ESP_LOGI(TAG, "Event got IP - addres: " IPSTR, IP2STR(&got_ip->ip_info.ip)); + eos_wifi_send_status(); - /* ip_changed is set even at normal connect! + /* if (got_ip->ip_changed) { - ESP_LOGI(TAG, "IP changed"); - // send wifi reconnect - } else { - rbuf = eos_net_alloc(); - rbuf[0] = EOS_WIFI_MTYPE_CONNECT; - rbuf[1] = EOS_OK; - eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, 2); + recreate all sockets } */ break; + } - default: // Ignore the other event types + default: // Ignore the other event types break; } } - if (ret != ESP_OK) ESP_LOGE(TAG, "EVT HANDLER ERR:%d EVT:%d", ret, event_id); } static void wifi_handler(unsigned char _mtype, unsigned char *buffer, uint16_t buf_len) { + esp_err_t ret = ESP_OK; uint8_t mtype; - int rv; - char *ssid, *pass, *_buf; - uint16_t _buf_len; if (buf_len < 1) return; - rv = EOS_OK; - mtype = buffer[0]; - buffer++; - buf_len--; - switch (mtype) { - case EOS_WIFI_MTYPE_SCAN: - rv = eos_wifi_scan(); - break; + case EOS_WIFI_MTYPE_STATUS: { + int reply; + ssize_t rv; + + reply = _mtype & EOS_NET_MTYPE_FLAG_REPL; - case EOS_WIFI_MTYPE_AUTH: - _buf = (char *)buffer; - _buf_len = 0; + if (reply) { + rv = eos_wifi_get_status(buffer + 1); + if (rv < 0) break; - ssid = _buf; - _buf_len = strnlen(_buf, buf_len); - if (_buf_len == buf_len) break; - _buf += _buf_len + 1; - buf_len -= _buf_len + 1; + eos_net_reply(EOS_NET_MTYPE_WIFI, buffer, rv + 1); + } else { + unsigned char *buf; - pass = _buf; - _buf_len = strnlen(_buf, buf_len); - if (_buf_len == buf_len) break; - _buf += _buf_len + 1; - buf_len -= _buf_len + 1; + buf = eos_net_alloc(); + buf[0] = EOS_WIFI_MTYPE_STATUS; + rv = eos_wifi_get_status(buf + 1); + if (rv < 0) break; - rv = eos_wifi_auth(ssid, pass); + eos_net_send(EOS_NET_MTYPE_WIFI, buf, rv + 1); + } break; + } - case EOS_WIFI_MTYPE_CONNECT: - rv = eos_wifi_connect(); + case EOS_WIFI_MTYPE_START: { + ret = esp_wifi_start(); break; + } - case EOS_WIFI_MTYPE_DISCONNECT: - rv = eos_wifi_disconnect(); + case EOS_WIFI_MTYPE_STOP: { + ret = esp_wifi_stop(); break; + } + + case EOS_WIFI_MTYPE_SCAN: { + ret = esp_wifi_scan_start(NULL, 0); + break; + } + + case EOS_WIFI_MTYPE_CONNECT: { + wifi_config_t wifi_sta_config; + size_t ssid_size = sizeof(wifi_sta_config.sta.ssid); + size_t pwd_size = sizeof(wifi_sta_config.sta.password) - 1; + size_t ssid_len, pwd_len; + char *ssid, *pwd; + + buffer++; + buf_len--; + + ssid = (char *)buffer; + ssid_len = strnlen(ssid, buf_len); + if (ssid_len == buf_len) break; + if (ssid_len > ssid_size) break; + buffer += ssid_len + 1; + buf_len -= ssid_len + 1; + + pwd = (char *)buffer; + pwd_len = strnlen(pwd, buf_len); + if (pwd_len == buf_len) break; + if (pwd_len >= pwd_size) break; + buffer += pwd_len + 1; + buf_len -= pwd_len + 1; + + memset(&wifi_sta_config, 0, sizeof(wifi_sta_config)); + if (ssid_len < ssid_size) { + strcpy((char *)wifi_sta_config.sta.ssid, ssid); + } else { + memcpy(wifi_sta_config.sta.ssid, ssid, ssid_size); + } + strcpy((char *)wifi_sta_config.sta.password, pwd); + wifi_sta_config.sta.password[pwd_size] = '\0'; + + ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_sta_config); + if (ret) break; + + ret = esp_wifi_connect(); + break; + } + + case EOS_WIFI_MTYPE_DISCONNECT: { + ret = esp_wifi_disconnect(); + break; + } } - if (rv) ESP_LOGE(TAG, "MSG HANDLER ERR:%d MSG:%d", rv, mtype); + if (ret) { + ESP_LOGE(TAG, "HANDLER ERR:%d MTYPE:%d", ret, mtype); + eos_wifi_send_status(); + } } void eos_wifi_init(void) { esp_err_t ret; wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT(); - memset(&wifi_sta_config, 0, sizeof(wifi_sta_config)); - - esp_netif_create_default_wifi_sta(); + wifi_netif = esp_netif_create_default_wifi_sta(); ret = esp_wifi_init(&wifi_config); assert(ret == ESP_OK); @@ -242,118 +224,119 @@ void eos_wifi_init(void) { ret = esp_wifi_set_mode(WIFI_MODE_STA); assert(ret == ESP_OK); - ret = esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_sta_config); - assert(ret == ESP_OK); - ret = esp_wifi_stop(); assert(ret == ESP_OK); - mutex = xSemaphoreCreateBinary(); - xSemaphoreGive(mutex); - eos_net_set_handler(EOS_NET_MTYPE_WIFI, wifi_handler); ESP_LOGI(TAG, "INIT"); } -int eos_wifi_scan(void) { - int rv = EOS_OK; - esp_err_t ret = ESP_OK; - uint8_t _wifi_state = 0; +ssize_t eos_wifi_get_status(unsigned char *buffer) { + unsigned char *p; + wifi_ap_record_t ap_info; + esp_err_t ret; - xSemaphoreTake(mutex, portMAX_DELAY); - if (!wifi_action) { - _wifi_state = wifi_state; + p = buffer; + ret = esp_wifi_sta_get_ap_info(&ap_info); + switch (ret) { + case ESP_OK: { // Station connected + size_t len; + esp_netif_ip_info_t ip_info; + + len = strnlen((char *)ap_info.ssid, sizeof(ap_info.ssid)); + if (len == sizeof(ap_info.ssid)) { + ESP_LOGE(TAG, "STATUS BAD SSID"); + return EOS_ERR; + } + ret = esp_netif_get_ip_info(wifi_netif, &ip_info); + if (ret) { + ESP_LOGE(TAG, "STATUS GET IP INFO ERR:%d", ret); + return EOS_ERR; + } + + if (ip_info.ip.addr) { + *p = EOS_WIFI_STATUS_GOT_IP; + p++; + + memcpy(p, &ip_info.ip.addr, sizeof(uint32_t)); + p += sizeof(uint32_t); + } else { + *p = EOS_WIFI_STATUS_CONNECTED; + p++; + } + + strcpy((char *)p, (char *)ap_info.ssid); + p += len + 1; - wifi_action = WIFI_ACTION_SCAN; - if (wifi_state == WIFI_STATE_STOPPED) wifi_state = WIFI_STATE_SCANNING; + break; + } - memset(&wifi_scan_config, 0, sizeof(wifi_scan_config)); - } else { - rv = EOS_ERR_BUSY; - } - xSemaphoreGive(mutex); + case ESP_ERR_WIFI_NOT_CONNECT: { + *p = EOS_WIFI_STATUS_DISCONNECTED; + p++; + break; + } - if (rv) return rv; + case ESP_ERR_WIFI_STOP_STATE: + case ESP_ERR_WIFI_CONN: { + *p = EOS_WIFI_STATUS_OFF; + p++; + break; + } - if (_wifi_state == WIFI_STATE_STOPPED) { - ret = esp_wifi_start(); - } else { - ret = esp_wifi_scan_start(&wifi_scan_config, 0); + default: { + ESP_LOGE(TAG, "STATUS GET AP INFO ERR:%d", ret); + return EOS_ERR; + } } - if (ret != ESP_OK) rv = EOS_ERR; - return rv; + return p - buffer; } -int eos_wifi_auth(char *ssid, char *pass) { - int rv = EOS_OK; - - xSemaphoreTake(mutex, portMAX_DELAY); - if (!wifi_action) { - if (ssid) strncpy((char *)wifi_sta_config.sta.ssid, ssid, sizeof(wifi_sta_config.sta.ssid) - 1); - if (pass) strncpy((char *)wifi_sta_config.sta.password, pass, sizeof(wifi_sta_config.sta.password) - 1); - } else { - rv = EOS_ERR_BUSY; +void eos_wifi_send_status(void) { + unsigned char *rbuf; + ssize_t rv; + rbuf = eos_net_alloc(); + rbuf[0] = EOS_WIFI_MTYPE_STATUS; + rv = eos_wifi_get_status(rbuf + 1); + if (rv < 0) { + eos_net_free(rbuf); + return; } - xSemaphoreGive(mutex); - return rv; + eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, rv + 1); } -int eos_wifi_connect(void) { - int rv = EOS_OK; - esp_err_t ret = ESP_OK; - uint8_t _wifi_state = 0; - - xSemaphoreTake(mutex, portMAX_DELAY); - if (!wifi_action) { - _wifi_state = wifi_state; - - wifi_action = WIFI_ACTION_CONNECT; - wifi_state = WIFI_STATE_CONNECTING; - wifi_connect_cnt = WIFI_MAX_CONNECT_ATTEMPTS; - } else { - rv = EOS_ERR_BUSY; - } - xSemaphoreGive(mutex); - - if (rv) return rv; - - esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_sta_config); +void eos_wifi_send_scan(void) { + static wifi_ap_record_t scan_r[EOS_WIFI_MAX_SCAN_RECORDS]; + static uint16_t scan_n; + unsigned char *rbuf, *p; + int i; + size_t len; + esp_err_t ret; - if (_wifi_state == WIFI_STATE_STOPPED) { - ret = esp_wifi_start(); - } else { - ret = esp_wifi_connect(); + scan_n = EOS_WIFI_MAX_SCAN_RECORDS; + memset(scan_r, 0, sizeof(scan_r)); + ret = esp_wifi_scan_get_ap_records(&scan_n, scan_r); + if (ret) { + ESP_LOGE(TAG, "SCAN GET RECORDS ERR:%d", ret); + return; } - if (ret != ESP_OK) rv = EOS_ERR; - return rv; -} + ESP_LOGI(TAG, "Scan done: %d", scan_n); -int eos_wifi_disconnect(void) { - int rv = EOS_OK; - esp_err_t ret = ESP_OK; + rbuf = eos_net_alloc(); + rbuf[0] = EOS_WIFI_MTYPE_SCAN; + p = rbuf + 1; - xSemaphoreTake(mutex, portMAX_DELAY); - if (!wifi_action) { - wifi_action = WIFI_ACTION_DISCONNECT; - wifi_state = WIFI_STATE_DISCONNECTING; - wifi_connect_cnt = 0; + for (i=0; i EOS_NET_MTU) break; - memset(wifi_sta_config.sta.ssid, 0, sizeof(wifi_sta_config.sta.ssid)); - memset(wifi_sta_config.sta.password, 0, sizeof(wifi_sta_config.sta.password)); - } else { - rv = EOS_ERR_BUSY; + strcpy((char *)p, (char *)scan_r[i].ssid); + p += len + 1; } - xSemaphoreGive(mutex); - - if (rv) return rv; - - ret = esp_wifi_stop(); - if (ret != ESP_OK) rv = EOS_ERR; - - return rv; + eos_net_send(EOS_NET_MTYPE_WIFI, rbuf, p - rbuf); } - -- cgit v1.2.3