summaryrefslogtreecommitdiff
path: root/code
diff options
context:
space:
mode:
Diffstat (limited to 'code')
-rw-r--r--code/esp32/components/eos/at_cmd.c26
-rw-r--r--code/esp32/components/eos/cell.c59
-rw-r--r--code/esp32/components/eos/cell_data.c20
-rw-r--r--code/esp32/components/eos/cell_modem.c169
-rw-r--r--code/esp32/components/eos/cell_pcm.c22
-rw-r--r--code/esp32/components/eos/cell_sms.c22
-rw-r--r--code/esp32/components/eos/cell_ussd.c34
-rw-r--r--code/esp32/components/eos/cell_voice.c20
-rw-r--r--code/esp32/components/eos/include/_net.h1
-rw-r--r--code/esp32/components/eos/include/at_cmd.h3
-rw-r--r--code/esp32/components/eos/include/cell.h53
-rw-r--r--code/esp32/main/app_main.c2
12 files changed, 291 insertions, 140 deletions
diff --git a/code/esp32/components/eos/at_cmd.c b/code/esp32/components/eos/at_cmd.c
index ea31485..4712ad7 100644
--- a/code/esp32/components/eos/at_cmd.c
+++ b/code/esp32/components/eos/at_cmd.c
@@ -27,7 +27,7 @@ static ATURCList urc_list;
static ATURCItem *urc_curr;
static SemaphoreHandle_t mutex;
-static char at_buf[128];
+static char at_buf[EOS_CELL_UART_SIZE_BUF];
void at_init(void) {
memset(&urc_list, 0, sizeof(ATURCList));
@@ -66,8 +66,11 @@ int at_urc_process(char *urc) {
urc_curr = NULL;
xSemaphoreGive(mutex);
}
+ ESP_LOGD(TAG, "URC Processed: %s", urc);
return 1;
}
+
+ ESP_LOGD(TAG, "URC NOT Processed: %s", urc);
return 0;
}
@@ -122,8 +125,12 @@ int at_urc_delete(char *pattern) {
return rv;
}
+void at_cmd(char *cmd) {
+ eos_modem_write(cmd, strlen(cmd));
+ ESP_LOGD(TAG, "Cmd: %s", cmd);
+}
+
int at_expect(char *str_ok, char *str_err, uint32_t timeout) {
- int r;
int rv;
regex_t re_ok;
regex_t re_err;
@@ -142,17 +149,16 @@ int at_expect(char *str_ok, char *str_err, uint32_t timeout) {
do {
rv = eos_modem_readln(at_buf, sizeof(at_buf), timeout - e);
- if (rv) return rv;
-
- if (at_buf[0] == '\0') continue;
+ ESP_LOGD(TAG, "Expect: %s", at_buf);
- if (str_ok && (regexec(&re_ok, at_buf, 0, NULL, 0) == 0)) return 1;
- if (str_err && (regexec(&re_err, at_buf, 0, NULL, 0) == 0)) return 0;
+ if (at_buf[0] != '\0') {
+ if (!rv && str_ok && (regexec(&re_ok, at_buf, 0, NULL, 0) == 0)) return 1;
+ if (!rv && str_err && (regexec(&re_err, at_buf, 0, NULL, 0) == 0)) return 0;
- r = at_urc_process(at_buf);
- if (!r) ESP_LOGD(TAG, "expect unhandled URC: %s", at_buf);
+ at_urc_process(at_buf);
+ }
e = (uint32_t)(esp_timer_get_time() - t_start) / 1000;
- if (e >= timeout) return EOS_ERR_TIMEOUT;
+ if (e > timeout) return EOS_ERR_TIMEOUT;
} while (1);
}
diff --git a/code/esp32/components/eos/cell.c b/code/esp32/components/eos/cell.c
index 2da1450..c2e03e1 100644
--- a/code/esp32/components/eos/cell.c
+++ b/code/esp32/components/eos/cell.c
@@ -10,27 +10,54 @@
static uint8_t cell_mode;
static void cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t size) {
- uint8_t mtype = buffer[0];
+ uint8_t mtype;
- switch (mtype) {
- case EOS_CELL_MTYPE_DATA:
- if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) eos_modem_write(buffer+1, size-1);
- break;
- case EOS_CELL_MTYPE_DATA_START:
- cell_mode = eos_modem_get_mode();
- eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY);
+ if (size < 1) return;
+ mtype = buffer[0];
+ switch (mtype & EOS_CELL_MTYPE_MASK) {
+ case EOS_CELL_MTYPE_DEV:
+ switch (mtype) {
+ case EOS_CELL_MTYPE_UART_DATA:
+ if (eos_modem_get_mode() == EOS_CELL_UART_MODE_RELAY) eos_modem_write(buffer+1, size-1);
+ break;
+
+ case EOS_CELL_MTYPE_UART_TAKE:
+ cell_mode = eos_modem_get_mode();
+ eos_modem_set_mode(EOS_CELL_UART_MODE_RELAY);
+ break;
+
+ case EOS_CELL_MTYPE_UART_GIVE:
+ eos_modem_set_mode(cell_mode);
+ break;
+
+ case EOS_CELL_MTYPE_PCM_DATA:
+ eos_cell_pcm_push(buffer+1, size-1);
+ break;
+
+ case EOS_CELL_MTYPE_PCM_START:
+ eos_cell_pcm_start();
+ break;
+
+ case EOS_CELL_MTYPE_PCM_STOP:
+ eos_cell_pcm_stop();
+ break;
+ }
break;
- case EOS_CELL_MTYPE_DATA_STOP:
- eos_modem_set_mode(cell_mode);
+
+ case EOS_CELL_MTYPE_VOICE:
+ eos_cell_voice_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, size);
break;
- case EOS_CELL_MTYPE_AUDIO:
- eos_pcm_push(buffer+1, size-1);
+
+ case EOS_CELL_MTYPE_SMS:
+ eos_cell_sms_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, size);
break;
- case EOS_CELL_MTYPE_AUDIO_START:
- eos_pcm_start();
+
+ case EOS_CELL_MTYPE_USSD:
+ eos_cell_ussd_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, size);
break;
- case EOS_CELL_MTYPE_AUDIO_STOP:
- eos_pcm_stop();
+
+ case EOS_CELL_MTYPE_DATA:
+ eos_cell_data_handler(mtype & ~EOS_CELL_MTYPE_MASK, buffer, size);
break;
}
}
diff --git a/code/esp32/components/eos/cell_data.c b/code/esp32/components/eos/cell_data.c
new file mode 100644
index 0000000..6732346
--- /dev/null
+++ b/code/esp32/components/eos/cell_data.c
@@ -0,0 +1,20 @@
+#include <stdlib.h>
+
+#include <esp_log.h>
+
+#include "eos.h"
+#include "cell.h"
+
+void eos_cell_data_handler(unsigned char mtype, unsigned char *buffer, uint16_t size) {
+ int rv;
+
+ rv = eos_modem_take(1000);
+ if (rv) return;
+
+ buffer += 1;
+ size -= 1;
+ switch (mtype) {
+ }
+
+ eos_modem_give();
+}
diff --git a/code/esp32/components/eos/cell_modem.c b/code/esp32/components/eos/cell_modem.c
index 5315861..c6d718f 100644
--- a/code/esp32/components/eos/cell_modem.c
+++ b/code/esp32/components/eos/cell_modem.c
@@ -21,8 +21,7 @@
// XXX: PPP reconnect on failure
-#define UART_SIZE_BUF 1024
-#define UART_SIZE_URC_BUF 128
+#define UART_SIZE_IO_BUF 1024
#define UART_GPIO_TXD 16
#define UART_GPIO_RXD 17
@@ -32,18 +31,27 @@
#define MODEM_ETYPE_INIT 1
#define MODEM_ETYPE_RI 2
+#define AT_CMD_INIT_SIZE 3
+
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
static const char *TAG = "EOS MODEM";
+static char *at_cmd_init[AT_CMD_INIT_SIZE] = {
+ "AT+CFGRI=1\r",
+ "AT+CSCLK=1\r",
+ "AT+CMGF=0\r"
+};
+
static SemaphoreHandle_t mutex;
static QueueHandle_t modem_queue;
static QueueHandle_t uart_queue;
-static char uart_buf[UART_SIZE_URC_BUF];
-static unsigned int uart_buf_len;
+static char urc_buf[EOS_CELL_UART_SIZE_BUF];
+static char uart_buf[EOS_CELL_UART_SIZE_BUF];
+static size_t uart_buf_len;
static uint8_t uart_mode = EOS_CELL_UART_MODE_ATCMD;
static SemaphoreHandle_t uart_mutex;
@@ -94,7 +102,7 @@ static void uart_data_read(uint8_t mode) {
int _rd;
buf = eos_net_alloc();
- buf[0] = EOS_CELL_MTYPE_DATA;
+ buf[0] = EOS_CELL_MTYPE_UART_DATA;
_rd = eos_modem_read(buf + 1, MIN(bsize - rd, EOS_NET_SIZE_BUF - 1), 100);
eos_net_send(EOS_NET_MTYPE_CELL, buf, _rd + 1, 0);
rd += _rd;
@@ -161,14 +169,14 @@ static int modem_atcmd_init(void) {
unsigned char *buf;
int echo_on = 0;
int tries = 3;
- int r;
+ int i, r;
int rv = EOS_OK;
rv = eos_modem_take(1000);
if (rv) return rv;
do {
- eos_modem_write("AT\r", 3);
+ at_cmd("AT\r");
r = at_expect("^AT", "^OK", 1000);
if (r >= 0) {
echo_on = r;
@@ -186,22 +194,22 @@ static int modem_atcmd_init(void) {
}
if (echo_on) {
- eos_modem_write("AT&F\r", 5);
+ at_cmd("AT&F\r");
r = at_expect("^AT&F", NULL, 1000);
r = at_expect("^OK", NULL, 1000);
} else {
- r = eos_modem_write("AT&F\r", 5);
+ at_cmd("AT&F\r");
r = at_expect("^OK", NULL, 1000);
}
- eos_modem_write("ATE0\r", 5);
+ at_cmd("ATE0\r");
r = at_expect("^ATE0", NULL, 1000);
r = at_expect("^OK", "^ERROR", 1000);
- eos_modem_write("AT+CFGRI=1\r", 11);
- r = at_expect("^OK", "^ERROR", 1000);
- eos_modem_write("AT+CSCLK=1\r", 11);
- r = at_expect("^OK", "^ERROR", 1000);
+ for (i=0; i<AT_CMD_INIT_SIZE; i++) {
+ at_cmd(at_cmd_init[i]);
+ r = at_expect("^OK", "^ERROR", 1000);
+ }
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_READY;
@@ -213,36 +221,34 @@ static int modem_atcmd_init(void) {
}
static void modem_atcmd_read(size_t bsize) {
- char *ln_begin, *ln_end, *ln_next;
+ char *ln_end;
int rd = 0;
do {
- int _rd = eos_modem_read(uart_buf + uart_buf_len, MIN(bsize - rd, sizeof(uart_buf) - uart_buf_len - 1), 100);
- ln_next = uart_buf + uart_buf_len;
- ln_begin = uart_buf;
- uart_buf_len += _rd;
+ 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(ln_next, '\n'))) {
- ln_end--;
- if ((ln_end > ln_begin) && (*ln_end == '\r')) {
- int r;
-
- *ln_end = '\0';
- r = at_urc_process(ln_begin);
- if (!r) {
- ESP_LOGD(TAG, "unhandled URC: %s", ln_begin);
- }
- }
- ln_next = ln_end + 2;
- ln_begin = ln_next;
+ while ((ln_end = strchr(uart_curr, '\n'))) {
+ size_t urc_buf_len = ln_end - uart_buf;
+
+ if ((ln_end > uart_buf) && (*(ln_end - 1) == '\r')) urc_buf_len--;
+ memcpy(urc_buf, uart_buf, urc_buf_len);
+ urc_buf[urc_buf_len] = '\0';
+
+ uart_buf_len -= ln_end - uart_buf + 1;
+ if (uart_buf_len) memmove(uart_buf, ln_end + 1, uart_buf_len);
+ uart_curr = uart_buf;
+ uart_buf[uart_buf_len] = '\0';
+
+ at_urc_process(urc_buf);
}
- if (ln_begin != uart_buf) {
- uart_buf_len -= ln_begin - uart_buf;
- if (uart_buf_len) memmove(uart_buf, ln_begin, uart_buf_len);
- } else if (uart_buf_len == sizeof(uart_buf) - 1) {
- memcpy(uart_buf, uart_buf + sizeof(uart_buf) / 2, sizeof(uart_buf) / 2);
- uart_buf_len = sizeof(uart_buf) / 2;
+ if (uart_buf_len == sizeof(uart_buf) - 1) {
+ uart_buf_len = 0;
+ memcpy(urc_buf, uart_buf, sizeof(urc_buf));
+ at_urc_process(urc_buf);
}
} while (rd != bsize);
}
@@ -407,7 +413,7 @@ static int ppp_pause(uint32_t timeout, uint8_t retries) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
modem_set_mode(EOS_CELL_UART_MODE_NONE);
xSemaphoreTake(uart_mutex, portMAX_DELAY);
- eos_modem_write("+++", 3);
+ at_cmd("+++");
t_start = esp_timer_get_time();
do {
@@ -440,7 +446,7 @@ static int ppp_pause(uint32_t timeout, uint8_t retries) {
done = 1;
} else {
retries--;
- eos_modem_write("+++", 3);
+ at_cmd("+++");
t_start = esp_timer_get_time();
}
}
@@ -453,7 +459,7 @@ static int ppp_resume(void) {
int r;
int rv = EOS_OK;
- eos_modem_write("ATO\r", 4);
+ at_cmd("ATO\r");
r = at_expect("^CONNECT", "^(ERROR|NO CARRIER)", 1000);
if (r <= 0) rv = EOS_ERR;
@@ -478,7 +484,7 @@ static int ppp_setup(void) {
return EOS_ERR_TIMEOUT;
}
- eos_modem_write(cmd, cmd_len);
+ at_cmd(cmd);
r = at_expect("^OK", "^ERROR", 1000);
if (r <= 0) {
modem_set_mode(uart_mode);
@@ -486,7 +492,7 @@ static int ppp_setup(void) {
return EOS_ERR;
}
- eos_modem_write("AT+CGDATA=\"PPP\",1\r", 18);
+ at_cmd("AT+CGDATA=\"PPP\",1\r");
r = at_expect("^CONNECT", "^(ERROR|\\+CME ERROR|NO CARRIER)", 1000);
if (r <= 0) {
modem_set_mode(uart_mode);
@@ -514,7 +520,7 @@ static int ppp_disconnect(void) {
rv = ppp_pause(1000, 2);
if (rv) return rv;
- eos_modem_write("ATH\r", 4);
+ at_cmd("ATH\r");
at_expect("^OK", NULL, 1000);
xSemaphoreGive(uart_mutex);
@@ -536,7 +542,7 @@ void eos_modem_init(void) {
};
uart_param_config(UART_NUM_2, &uart_config);
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_BUF, UART_SIZE_BUF, 10, &uart_queue, 0);
+ 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;
@@ -591,52 +597,45 @@ 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 done = 0;
- int len = 0;
- int rv = EOS_OK;
char *ln_end = NULL;
+ size_t buf_len = 0;
uint64_t t_start = esp_timer_get_time();
- uart_buf[uart_buf_len] = '\0';
- ln_end = strchr(uart_buf, '\n');
+ buf[0] = '\0';
+ if (uart_buf_len) {
+ buf_len = MIN(buf_size -1, uart_buf_len);
+ memcpy(buf, uart_buf, buf_len);
+ buf[buf_len] = '\0';
+ ln_end = strchr(buf, '\n');
- do {
- if (ln_end == NULL) {
- len = eos_modem_read(uart_buf + uart_buf_len, sizeof(uart_buf) - uart_buf_len - 1, 10);
- if (len > 0) {
- uart_buf[uart_buf_len + len] = '\0';
- ln_end = strchr(uart_buf + uart_buf_len, '\n');
- uart_buf_len += len;
- }
- }
- if (ln_end) {
- ln_end--;
- if ((ln_end >= uart_buf) && (*ln_end == '\r')) {
- if (buf) {
- if (buf_size > ln_end - uart_buf) {
- memcpy(buf, uart_buf, ln_end - uart_buf);
- buf[ln_end - uart_buf] = '\0';
- } else {
- rv = EOS_ERR;
- }
- }
- done = 1;
- }
- ln_end += 2;
- uart_buf_len -= ln_end - uart_buf;
- if (uart_buf_len) memmove(uart_buf, ln_end, uart_buf_len);
- ln_end = NULL;
- } else if (uart_buf_len == sizeof(uart_buf) - 1) {
- memcpy(uart_buf, uart_buf + sizeof(uart_buf) / 2, sizeof(uart_buf) / 2);
- uart_buf_len = sizeof(uart_buf) / 2;
- }
- if (timeout && !done && ((uint32_t)((esp_timer_get_time() - t_start) / 1000) > timeout)) {
- rv = EOS_ERR_TIMEOUT;
- done = 1;
+ uart_buf_len -= buf_len;
+ if (uart_buf_len) memmove(uart_buf, uart_buf + buf_len, uart_buf_len);
+ }
+
+ while (ln_end == NULL) {
+ int len;
+
+ if (buf_len == buf_size - 1) return EOS_ERR_FULL;
+ if (timeout && ((uint32_t)((esp_timer_get_time() - t_start) / 1000) > timeout)) return EOS_ERR_TIMEOUT;
+
+ len = eos_modem_read(buf + buf_len, MIN(buf_size - buf_len - 1, sizeof(uart_buf) - uart_buf_len), 10);
+ if (len > 0) {
+ buf[buf_len + len] = '\0';
+ ln_end = strchr(buf + buf_len, '\n');
+ buf_len += len;
}
- } while (!done);
+ }
+ buf_len -= ln_end - buf + 1;
+ if (buf_len) {
+ if (uart_buf_len) memmove(uart_buf + buf_len, uart_buf, uart_buf_len);
+ memcpy(uart_buf, ln_end + 1, buf_len);
+ uart_buf_len += buf_len;
+ }
- return rv;
+ if ((ln_end > buf) && (*(ln_end - 1) == '\r')) ln_end--;
+ *ln_end = '\0';
+
+ return EOS_OK;
}
uint8_t eos_modem_get_mode(void) {
diff --git a/code/esp32/components/eos/cell_pcm.c b/code/esp32/components/eos/cell_pcm.c
index c1419b8..5c59643 100644
--- a/code/esp32/components/eos/cell_pcm.c
+++ b/code/esp32/components/eos/cell_pcm.c
@@ -60,16 +60,16 @@ static void i2s_event_task(void *pvParameters) {
// Event of I2S receiving data
if (!hold_cnt) {
buf = eos_net_alloc();
- buf[0] = EOS_CELL_MTYPE_AUDIO;
- bytes_r = eos_pcm_read(buf + 1, PCM_MIC_WM);
+ buf[0] = EOS_CELL_MTYPE_PCM_DATA;
+ bytes_r = eos_cell_pcm_read(buf + 1, PCM_MIC_WM);
eos_net_send(EOS_NET_MTYPE_CELL, buf, bytes_r + 1, 0);
} else {
hold_cnt--;
if (hold_buf == NULL) {
hold_buf = eos_net_alloc();
- hold_buf[0] = EOS_CELL_MTYPE_AUDIO;
+ hold_buf[0] = EOS_CELL_MTYPE_PCM_DATA;
}
- if (1 + hold_bytes_r + PCM_MIC_WM <= EOS_NET_SIZE_BUF) hold_bytes_r += eos_pcm_read(hold_buf + 1 + hold_bytes_r, PCM_MIC_WM);
+ if (1 + hold_bytes_r + PCM_MIC_WM <= EOS_NET_SIZE_BUF) hold_bytes_r += eos_cell_pcm_read(hold_buf + 1 + hold_bytes_r, PCM_MIC_WM);
if (hold_cnt == 0) {
eos_net_send(EOS_NET_MTYPE_CELL, hold_buf, hold_bytes_r + 1, 0);
hold_bytes_r = 0;
@@ -104,7 +104,7 @@ static void i2s_event_task(void *pvParameters) {
vTaskDelete(NULL);
}
-void eos_pcm_init(void) {
+void eos_cell_pcm_init(void) {
int i;
i2s_config_t i2s_config = {
@@ -160,7 +160,7 @@ void eos_pcm_init(void) {
ESP_LOGI(TAG, "INIT");
}
-ssize_t eos_pcm_read(unsigned char *data, size_t size) {
+ssize_t eos_cell_pcm_read(unsigned char *data, size_t size) {
static unsigned char buf[PCM_SIZE_BUF];
size_t bytes_r;
int i;
@@ -178,7 +178,7 @@ ssize_t eos_pcm_read(unsigned char *data, size_t size) {
return bytes_r / 4;
}
-ssize_t eos_pcm_expand(unsigned char *buf, unsigned char *data, size_t size) {
+static ssize_t pcm_expand(unsigned char *buf, unsigned char *data, size_t size) {
int i;
if (size > PCM_MIC_WM) return EOS_ERR;
@@ -192,7 +192,7 @@ ssize_t eos_pcm_expand(unsigned char *buf, unsigned char *data, size_t size) {
return size * 4;
}
-int eos_pcm_push(unsigned char *data, size_t size) {
+int eos_cell_pcm_push(unsigned char *data, size_t size) {
unsigned char *buf = NULL;
ssize_t esize;
int rv;
@@ -212,7 +212,7 @@ int eos_pcm_push(unsigned char *data, size_t size) {
if (buf == NULL) return EOS_ERR_EMPTY;
- esize = eos_pcm_expand(buf, data, size);
+ esize = pcm_expand(buf, data, size);
if (esize < 0) {
xSemaphoreTake(mutex, portMAX_DELAY);
eos_bufq_push(&pcm_buf_q, buf);
@@ -228,7 +228,7 @@ int eos_pcm_push(unsigned char *data, size_t size) {
return rv;
}
-void eos_pcm_start(void) {
+void eos_cell_pcm_start(void) {
i2s_event_t evt;
xSemaphoreTake(mutex, portMAX_DELAY);
@@ -253,6 +253,6 @@ void eos_pcm_start(void) {
i2s_start(I2S_NUM_0);
}
-void eos_pcm_stop(void) {
+void eos_cell_pcm_stop(void) {
i2s_stop(I2S_NUM_0);
}
diff --git a/code/esp32/components/eos/cell_sms.c b/code/esp32/components/eos/cell_sms.c
new file mode 100644
index 0000000..05acc50
--- /dev/null
+++ b/code/esp32/components/eos/cell_sms.c
@@ -0,0 +1,22 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <esp_log.h>
+
+#include "eos.h"
+#include "cell.h"
+
+
+void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t size) {
+ int rv;
+
+ rv = eos_modem_take(1000);
+ if (rv) return;
+
+ buffer += 1;
+ size -= 1;
+ switch (mtype) {
+ }
+
+ eos_modem_give();
+}
diff --git a/code/esp32/components/eos/cell_ussd.c b/code/esp32/components/eos/cell_ussd.c
new file mode 100644
index 0000000..2daa00f
--- /dev/null
+++ b/code/esp32/components/eos/cell_ussd.c
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <esp_log.h>
+
+#include "at_cmd.h"
+#include "cell.h"
+#include "gsm.h"
+
+static char cmd[256];
+
+void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t size) {
+ int cmd_len, rv;
+
+ rv = eos_modem_take(1000);
+ if (rv) return;
+
+ buffer += 1;
+ size -= 1;
+ switch (mtype) {
+ case EOS_CELL_MTYPE_USSD_REQUEST:
+ if (size == 0) return;
+
+ buffer[size] = '\0';
+ cmd_len = snprintf(cmd, sizeof(cmd), "AT+CUSD=1,\"%s\",15\r", buffer);
+ if ((cmd_len < 0) || (cmd_len >= sizeof(cmd))) return;
+ at_cmd(cmd);
+
+ break;
+ }
+
+ eos_modem_give();
+}
+
diff --git a/code/esp32/components/eos/cell_voice.c b/code/esp32/components/eos/cell_voice.c
new file mode 100644
index 0000000..3f6a2a5
--- /dev/null
+++ b/code/esp32/components/eos/cell_voice.c
@@ -0,0 +1,20 @@
+#include <stdlib.h>
+
+#include <esp_log.h>
+
+#include "eos.h"
+#include "cell.h"
+
+void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t size) {
+ int rv;
+
+ rv = eos_modem_take(1000);
+ if (rv) return;
+
+ buffer += 1;
+ size -= 1;
+ switch (mtype) {
+ }
+
+ eos_modem_give();
+}
diff --git a/code/esp32/components/eos/include/_net.h b/code/esp32/components/eos/include/_net.h
new file mode 100644
index 0000000..35b5308
--- /dev/null
+++ b/code/esp32/components/eos/include/_net.h
@@ -0,0 +1 @@
+#include "net.h" \ No newline at end of file
diff --git a/code/esp32/components/eos/include/at_cmd.h b/code/esp32/components/eos/include/at_cmd.h
index ca46e23..615a1c1 100644
--- a/code/esp32/components/eos/include/at_cmd.h
+++ b/code/esp32/components/eos/include/at_cmd.h
@@ -16,4 +16,5 @@ void at_init(void);
int at_urc_process(char *urc);
int at_urc_insert(char *pattern, at_urc_cb_t cb, int flags);
int at_urc_delete(char *pattern);
-int at_expect(char *str_ok, char *str_err, uint32_t timeout); \ No newline at end of file
+void at_cmd(char *cmd);
+int at_expect(char *str_ok, char *str_err, uint32_t timeout);
diff --git a/code/esp32/components/eos/include/cell.h b/code/esp32/components/eos/include/cell.h
index 23adecf..3bf6b32 100644
--- a/code/esp32/components/eos/include/cell.h
+++ b/code/esp32/components/eos/include/cell.h
@@ -1,47 +1,68 @@
#include <sys/types.h>
+#include <stdint.h>
+
+#define EOS_CELL_MTYPE_DEV 0x00
+#define EOS_CELL_MTYPE_VOICE 0x10
+#define EOS_CELL_MTYPE_SMS 0x20
+#define EOS_CELL_MTYPE_CBS 0x30
+#define EOS_CELL_MTYPE_USSD 0x40
+#define EOS_CELL_MTYPE_DATA 0x70
+
+#define EOS_CELL_MTYPE_MASK 0xf0
+#define EOS_CELL_MAX_MTYPE 8
#define EOS_CELL_MTYPE_READY 0
-#define EOS_CELL_MTYPE_DATA 1
-#define EOS_CELL_MTYPE_AUDIO 2
+#define EOS_CELL_MTYPE_UART_DATA 1
+#define EOS_CELL_MTYPE_UART_TAKE 2
+#define EOS_CELL_MTYPE_UART_GIVE 3
+#define EOS_CELL_MTYPE_PCM_DATA 4
+#define EOS_CELL_MTYPE_PCM_START 5
+#define EOS_CELL_MTYPE_PCM_STOP 6
-#define EOS_CELL_MTYPE_DATA_START 4
-#define EOS_CELL_MTYPE_DATA_STOP 5
+#define EOS_CELL_MTYPE_VOICE_DIAL 1
+#define EOS_CELL_MTYPE_VOICE_RING 2
+#define EOS_CELL_MTYPE_VOICE_ANSWER 3
+#define EOS_CELL_MTYPE_VOICE_HANGUP 4
+#define EOS_CELL_MTYPE_VOICE_BEGIN 5
+#define EOS_CELL_MTYPE_VOICE_END 6
-#define EOS_CELL_MTYPE_AUDIO_START 6
-#define EOS_CELL_MTYPE_AUDIO_STOP 7
+#define EOS_CELL_MTYPE_USSD_REQUEST 1
+#define EOS_CELL_MTYPE_USSD_REPLY 2
#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
-void eos_pcm_init(void);
+#define EOS_CELL_UART_SIZE_BUF 128
-ssize_t eos_pcm_read(unsigned char *data, size_t size);
-int eos_pcm_push(unsigned char *data, size_t size);
-void eos_pcm_start(void);
-void eos_pcm_stop(void);
+void eos_cell_init(void);
void eos_modem_init(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);
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_wake(uint8_t source, uint8_t mode);
void eos_ppp_set_apn(char *apn);
void eos_ppp_set_auth(char *user, char *pass);
-
int eos_ppp_connect(void);
int eos_ppp_disconnect(void);
-void eos_cell_init(void);
+void eos_cell_pcm_init(void);
+ssize_t eos_cell_pcm_read(unsigned char *data, size_t size);
+int 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 size);
+void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t size);
+void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t size);
+void eos_cell_data_handler(unsigned char mtype, unsigned char *buffer, uint16_t size);
diff --git a/code/esp32/main/app_main.c b/code/esp32/main/app_main.c
index b700a8e..4babcdc 100644
--- a/code/esp32/main/app_main.c
+++ b/code/esp32/main/app_main.c
@@ -21,7 +21,7 @@ void app_main() {
eos_net_init();
- eos_pcm_init();
+ eos_cell_pcm_init();
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
eos_modem_init();