summaryrefslogtreecommitdiff
path: root/fw/esp32
diff options
context:
space:
mode:
Diffstat (limited to 'fw/esp32')
-rw-r--r--fw/esp32/components/eos/CMakeLists.txt2
-rw-r--r--fw/esp32/components/eos/app.c102
-rw-r--r--fw/esp32/components/eos/app_main.c13
-rw-r--r--fw/esp32/components/eos/cell.c63
-rw-r--r--fw/esp32/components/eos/cell_modem.c139
-rw-r--r--fw/esp32/components/eos/cell_pcm.c16
-rw-r--r--fw/esp32/components/eos/cell_pdp.c29
-rw-r--r--fw/esp32/components/eos/cell_sms.c66
-rw-r--r--fw/esp32/components/eos/cell_ussd.c73
-rw-r--r--fw/esp32/components/eos/cell_voice.c107
-rw-r--r--fw/esp32/components/eos/include/app.h17
-rw-r--r--fw/esp32/components/eos/include/cell.h14
-rw-r--r--fw/esp32/components/eos/include/eos.h16
-rw-r--r--fw/esp32/components/eos/include/msgq.h25
-rw-r--r--fw/esp32/components/eos/include/net.h38
-rw-r--r--fw/esp32/components/eos/include/net_priv.h15
-rw-r--r--fw/esp32/components/eos/include/power.h3
-rw-r--r--fw/esp32/components/eos/include/tun.h4
-rw-r--r--fw/esp32/components/eos/include/wifi.h4
-rw-r--r--fw/esp32/components/eos/msgq.c43
-rw-r--r--fw/esp32/components/eos/net.c383
-rw-r--r--fw/esp32/components/eos/power.c185
-rw-r--r--fw/esp32/components/eos/rng.c16
-rw-r--r--fw/esp32/components/eos/sock.c175
-rw-r--r--fw/esp32/components/eos/tun.c46
-rwxr-xr-xfw/esp32/components/eos/wifi.c75
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);
}