diff options
Diffstat (limited to 'code/esp32/components/eos')
| -rw-r--r-- | code/esp32/components/eos/at_urc.c | 109 | ||||
| -rw-r--r-- | code/esp32/components/eos/bq25895.c | 3 | ||||
| -rw-r--r-- | code/esp32/components/eos/cell.c | 5 | ||||
| -rw-r--r-- | code/esp32/components/eos/cell_modem.c | 533 | ||||
| -rw-r--r-- | code/esp32/components/eos/cell_pcm.c | 3 | ||||
| -rw-r--r-- | code/esp32/components/eos/drv2605l.c | 3 | ||||
| -rw-r--r-- | code/esp32/components/eos/i2c.c | 3 | ||||
| -rw-r--r-- | code/esp32/components/eos/include/at_urc.h | 17 | ||||
| -rw-r--r-- | code/esp32/components/eos/include/cell.h | 16 | ||||
| -rw-r--r-- | code/esp32/components/eos/include/eos.h | 3 | ||||
| -rw-r--r-- | code/esp32/components/eos/net.c | 5 | ||||
| -rw-r--r-- | code/esp32/components/eos/sock.c | 2 | 
12 files changed, 656 insertions, 46 deletions
| diff --git a/code/esp32/components/eos/at_urc.c b/code/esp32/components/eos/at_urc.c new file mode 100644 index 0000000..b362d6f --- /dev/null +++ b/code/esp32/components/eos/at_urc.c @@ -0,0 +1,109 @@ +#include <stdlib.h> +#include <string.h> + +#include <freertos/FreeRTOS.h> +#include <freertos/semphr.h> + +#include "eos.h" +#include "at_urc.h" + +typedef struct ATURCItem { +    regex_t re; +    at_urc_cb_t cb; +    char pattern[AT_SIZE_PATTERN]; +} ATURCItem; + +typedef struct ATURCList { +    ATURCItem item[AT_SIZE_URC_LIST]; +    int len; +} ATURCList; + +static ATURCList urc_list; +static ATURCItem *urc_curr; +static SemaphoreHandle_t mutex; + +int at_urc_process(char *urc) { +    regmatch_t match[AT_SIZE_NMATCH]; +    at_urc_cb_t cb = NULL; +    regmatch_t *m = NULL; + +    xSemaphoreTake(mutex, portMAX_DELAY); + +    if (urc_curr == NULL) { +        int i; + +        for (i=0; i<urc_list.len; i++) { +            if (regexec(&urc_list.item[i].re, urc, AT_SIZE_NMATCH, match, 0) == 0) { +                urc_curr = &urc_list.item[i]; +                m = match; +                break; +            } +        } +    } +    if (urc_curr) cb = urc_curr->cb; + +    xSemaphoreGive(mutex); + +    if (cb) { +        int r = cb(urc, m); + +        if (r != AT_URC_MORE) { +            xSemaphoreTake(mutex, portMAX_DELAY); +            urc_curr = NULL; +            xSemaphoreGive(mutex); +        } +        return 1; +    } +    return 0; +} + +int at_urc_insert(char *pattern, at_urc_cb_t cb, int flags) { +    int r = EOS_OK; + +    if (strlen(pattern) >= AT_SIZE_PATTERN) return EOS_ERR; + +    r = regcomp(&urc_list.item[urc_list.len].re, pattern, flags); +    if (r) return EOS_ERR; + +    xSemaphoreTake(mutex, portMAX_DELAY); + +    if (urc_list.len == AT_SIZE_URC_LIST) r = EOS_ERR_FULL; + +    if (!r) { +        strcpy(urc_list.item[urc_list.len].pattern, pattern); +        urc_list.item[urc_list.len].cb = cb; +        urc_list.len++; +    } + +    xSemaphoreGive(mutex); + +    return r; +} + +int at_urc_delete(char *pattern) { +    int i; +    int r = EOS_ERR_NOTFOUND; + +    xSemaphoreTake(mutex, portMAX_DELAY); + +    for (i=0; i<urc_list.len; i++) { +        if ((strcmp(pattern, urc_list.item[i].pattern) == 0)) { +            if (i != urc_list.len - 1) memmove(&urc_list.item[i], &urc_list.item[i + 1], (urc_list.len - i - 1) * sizeof(ATURCItem)); +            urc_list.len--; +            if (urc_curr) { +                if (urc_curr == &urc_list.item[i]) { +                    urc_curr = NULL; +                } else if (urc_curr > &urc_list.item[i]) { +                    urc_curr--; +                } +            } + +            r = EOS_OK; +            break; +        } +    } + +    xSemaphoreGive(mutex); + +    return r; +} diff --git a/code/esp32/components/eos/bq25895.c b/code/esp32/components/eos/bq25895.c index 03116ca..0d1bb8d 100644 --- a/code/esp32/components/eos/bq25895.c +++ b/code/esp32/components/eos/bq25895.c @@ -1,4 +1,5 @@ -#include <stdio.h> +#include <stdlib.h> +  #include <esp_log.h>  #include "eos.h" diff --git a/code/esp32/components/eos/cell.c b/code/esp32/components/eos/cell.c index 26ad454..138a4e4 100644 --- a/code/esp32/components/eos/cell.c +++ b/code/esp32/components/eos/cell.c @@ -7,6 +7,8 @@  #include "net.h"  #include "cell.h" +static uint8_t cell_mode; +  static void cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t size) {      uint8_t mtype = buffer[0]; @@ -15,10 +17,11 @@ static void cell_handler(unsigned char _mtype, unsigned char *buffer, uint16_t s              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);              break;          case EOS_CELL_MTYPE_DATA_STOP: -            eos_modem_set_mode(0); +            eos_modem_set_mode(cell_mode);              break;          case EOS_CELL_MTYPE_AUDIO:              eos_pcm_push(buffer+1, size-1); diff --git a/code/esp32/components/eos/cell_modem.c b/code/esp32/components/eos/cell_modem.c index 4c964e1..50aa23a 100644 --- a/code/esp32/components/eos/cell_modem.c +++ b/code/esp32/components/eos/cell_modem.c @@ -1,66 +1,132 @@ -#include <stdio.h> +#include <stdlib.h>  #include <string.h>  #include <freertos/FreeRTOS.h> +#include <freertos/semphr.h>  #include <freertos/task.h>  #include <freertos/queue.h> +#include <netif/ppp/pppos.h> +#include <netif/ppp/pppapi.h>  #include <driver/uart.h>  #include <driver/gpio.h>  #include <esp_log.h>  #include "eos.h"  #include "net.h" +#include "at_urc.h"  #include "cell.h"  #define MIN(X, Y)               (((X) < (Y)) ? (X) : (Y))  #define MAX(X, Y)               (((X) > (Y)) ? (X) : (Y)) -#define UART_BUF_SIZE   1024 +#define UART_SIZE_BUF       1024 +#define UART_SIZE_URC_BUF   128 -#define UART_GPIO_TXD   16 -#define UART_GPIO_RXD   17 -#define UART_GPIO_DTR   32 -#define UART_GPIO_RI    35 +#define UART_GPIO_TXD       16 +#define UART_GPIO_RXD       17 +#define UART_GPIO_DTR       32 +#define UART_GPIO_RI        35  static QueueHandle_t uart_queue;  static QueueHandle_t uart_ri_queue;  static const char *TAG = "EOS MODEM"; +static SemaphoreHandle_t mutex; + +static char at_resp[128]; +static char uart_buf[UART_SIZE_URC_BUF]; +static unsigned int uart_buf_len; +static uint8_t uart_mode = EOS_CELL_UART_MODE_NONE; +static SemaphoreHandle_t uart_mutex; + +static char ppp_apn[64]; +static char ppp_user[64]; +static char ppp_pass[64]; +static SemaphoreHandle_t ppp_mutex; + +static ppp_pcb *ppp_handle; +static struct netif ppp_netif; + +typedef enum { +    UART_EEVT_MODE = UART_EVENT_MAX +} uart_eevt_type_t; + +static void modem_atcmd_read(size_t bsize); + +static void uart_data_read(uint8_t mode) { +    unsigned char *buf; +    int rd; +    size_t bsize; + +    uart_get_buffered_data_len(UART_NUM_2, &bsize); +    switch (mode) { +        case EOS_CELL_UART_MODE_ATCMD: +            modem_atcmd_read(bsize); +            break; + +        case EOS_CELL_UART_MODE_PPP: +            rd = 0; + +            do { +                int _rd = eos_modem_read(uart_buf, MIN(bsize - rd, sizeof(uart_buf)), 100); +                pppos_input_tcpip(ppp_handle, (uint8_t *)uart_buf, _rd); +                rd += _rd; +            } while (rd != bsize); +            break; + +        case EOS_CELL_UART_MODE_RELAY: +            rd = 0; + +            do { +                int _rd; + +                buf = eos_net_alloc(); +                buf[0] = EOS_CELL_MTYPE_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; +            } while (rd != bsize); +            break; + +        default: +            break; + +    } +} +  static void uart_event_task(void *pvParameters) {      char mode = EOS_CELL_UART_MODE_NONE; +    char _mode = EOS_CELL_UART_MODE_NONE;      uart_event_t event; -    size_t len; -    unsigned char *buf;      while (1) {          /* Waiting for UART event.           */ -        if (xQueueReceive(uart_queue, (void * )&event, (portTickType)portMAX_DELAY)) { +        if (xQueueReceive(uart_queue, (void *)&event, (portTickType)portMAX_DELAY)) {              switch (event.type) {                  case UART_DATA:                      /* Event of UART receiving data                       */ -                    switch (mode) { -                        case EOS_CELL_UART_MODE_PPP: -                            break; - -                        case EOS_CELL_UART_MODE_RELAY: -                            buf = eos_net_alloc(); -                            buf[0] = EOS_CELL_MTYPE_DATA; -                            len = uart_read_bytes(UART_NUM_2, buf+1, MIN(event.size, EOS_NET_SIZE_BUF-1), 100 / portTICK_RATE_MS); -                            eos_net_send(EOS_NET_MTYPE_CELL, buf, len+1, 0); -                            break; - -                        default: -                            break; +                    if (mode != EOS_CELL_UART_MODE_NONE) uart_data_read(mode); +                    if ((mode != _mode) && (uart_buf_len == 0)) { +                        if (_mode == EOS_CELL_UART_MODE_NONE) xSemaphoreGive(uart_mutex); +                        mode = _mode;                      }                      break; -                case UART_EVENT_MAX: +                case UART_EEVT_MODE:                      /* Mode change                       */ -                    mode = (char)event.size; +                    _mode = (char)event.size; +                    if ((_mode != mode) && ((uart_buf_len == 0) || (mode == EOS_CELL_UART_MODE_NONE))) { +                        if (mode == EOS_CELL_UART_MODE_NONE) { +                            xSemaphoreTake(uart_mutex, portMAX_DELAY); +                            uart_data_read(_mode); +                        } +                        if (_mode == EOS_CELL_UART_MODE_NONE) xSemaphoreGive(uart_mutex); +                        mode = _mode; +                    }                      break;                  default: @@ -75,11 +141,11 @@ static void uart_ri_event_task(void *pvParameters) {      int level;      while (1) { -        if (xQueueReceive(uart_ri_queue, (void * )&level, (portTickType)portMAX_DELAY) && (level == 0)) { +        if (xQueueReceive(uart_ri_queue, (void *)&level, (portTickType)portMAX_DELAY) && (level == 0)) {              uint64_t t_start = esp_timer_get_time(); -            if (xQueueReceive(uart_ri_queue, (void * )&level, 200 / portTICK_RATE_MS) && (level == 1)) { +            if (xQueueReceive(uart_ri_queue, (void *)&level, 200 / portTICK_RATE_MS) && (level == 1)) {                  uint64_t t_end = esp_timer_get_time(); -                ESP_LOGI(TAG, "TDELTA:%u", (uint32_t)(t_end - t_start)); +                ESP_LOGI(TAG, "URC:%u", (uint32_t)(t_end - t_start));              } else {                  ESP_LOGI(TAG, "RING");              } @@ -93,6 +159,268 @@ static void IRAM_ATTR uart_ri_isr_handler(void *arg) {      xQueueSendFromISR(uart_ri_queue, &level, NULL);  } +static void modem_atcmd_read(size_t bsize) { +    char *ln_begin, *ln_end, *ln_next; +    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; +        rd += _rd; +        uart_buf[uart_buf_len] = '\0'; +        while ((ln_end = strchr(ln_next, '\n'))) { +            ln_end--; +            if ((ln_end > ln_begin) && (*ln_end == '\r')) { +                *ln_end = '\0'; +                at_urc_process(ln_begin); +            } +            ln_next = ln_end + 2; +            ln_begin = ln_next; +        } +        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; +        } +    } while (rd != bsize); +} + +static void modem_set_mode(uint8_t mode) { +    uart_event_t evt; + +    evt.type = UART_EEVT_MODE; +    evt.size = mode; +    xQueueSend(uart_queue, (void *)&evt, portMAX_DELAY); +} + +static char *memstr(char *mem, size_t size, char *str) { +    size_t i = 0; +    char *max_mem; + +    if (str[0] == '\0') return NULL; + +    max_mem = mem + size; + +    while (mem < max_mem) { +        if (*mem != str[i]) { +            mem -= i; +            i = 0; +        } else { +            if (str[i+1] == '\0') return mem - i; +            i++; +        } +        mem++; +    } + +    return NULL; +} + +static uint32_t ppp_output_cb(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *ctx) { +    size_t rv; + +	xSemaphoreTake(ppp_mutex, portMAX_DELAY); +    rv = eos_modem_write(data, len); +	xSemaphoreGive(ppp_mutex); + +    return rv; +} + +/* PPP status callback */ +static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) { +    // struct netif *pppif = ppp_netif(pcb); +    // LWIP_UNUSED_ARG(ctx); + +    switch(err_code) { +        case PPPERR_NONE: { +            ESP_LOGE(TAG, "status_cb: Connect"); +            break; +        } +        case PPPERR_PARAM: { +            ESP_LOGE(TAG, "status_cb: Invalid parameter"); +            break; +        } +        case PPPERR_OPEN: { +            ESP_LOGE(TAG, "status_cb: Unable to open PPP session"); +            break; +        } +        case PPPERR_DEVICE: { +            ESP_LOGE(TAG, "status_cb: Invalid I/O device for PPP"); +            break; +        } +        case PPPERR_ALLOC: { +            ESP_LOGE(TAG, "status_cb: Unable to allocate resources"); +            break; +        } +        case PPPERR_USER: { +            ESP_LOGE(TAG, "status_cb: User interrupt"); +            break; +        } +        case PPPERR_CONNECT: { +            ESP_LOGE(TAG, "status_cb: Connection lost"); +            break; +        } +        case PPPERR_AUTHFAIL: { +            ESP_LOGE(TAG, "status_cb: Failed authentication challenge"); +            break; +        } +        case PPPERR_PROTOCOL: { +            ESP_LOGE(TAG, "status_cb: Failed to meet protocol"); +            break; +        } +        case PPPERR_PEERDEAD: { +            ESP_LOGE(TAG, "status_cb: Connection timeout"); +            break; +        } +        case PPPERR_IDLETIMEOUT: { +            ESP_LOGE(TAG, "status_cb: Idle Timeout"); +            break; +        } +        case PPPERR_CONNECTTIME: { +            ESP_LOGE(TAG, "status_cb: Max connect time reached"); +            break; +        } +        case PPPERR_LOOPBACK: { +            ESP_LOGE(TAG, "status_cb: Loopback detected"); +            break; +        } +        default: { +            ESP_LOGE(TAG, "status_cb: Unknown error code %d", err_code); +            break; +        } +    } +} + +static int ppp_pause(void) { +    int done = 0; +    int len = 0; +    int ret = EOS_OK; +    char *ok_str = NULL; +    uint64_t t_start; +    uint32_t timeout = 500; +    uint8_t retries = 1; + +    xSemaphoreTake(ppp_mutex, portMAX_DELAY); +    eos_modem_flush(); +    vTaskDelay(1000 / portTICK_PERIOD_MS); +    modem_set_mode(EOS_CELL_UART_MODE_NONE); +    xSemaphoreTake(uart_mutex, portMAX_DELAY); +    eos_modem_write("+++", 3); +    t_start = esp_timer_get_time(); + +    do { +        len = eos_modem_read(uart_buf + uart_buf_len, sizeof(uart_buf) - uart_buf_len, 10); +        if (len > 0) { +            if (uart_buf_len > 5) { +                ok_str = memstr(uart_buf + uart_buf_len - 5, len + 5, "\r\nOK\r\n"); +            } else { +                ok_str = memstr(uart_buf, len + uart_buf_len, "\r\nOK\r\n"); +            } +            uart_buf_len += len; +        } +        if (ok_str) { +            pppos_input_tcpip(ppp_handle, (uint8_t *)uart_buf, ok_str - uart_buf); +            ok_str += 6; +            uart_buf_len -= ok_str - uart_buf; +            if (uart_buf_len) memmove(uart_buf, ok_str, uart_buf_len); +            done = 1; +        } else if (uart_buf_len == sizeof(uart_buf)) { +            pppos_input_tcpip(ppp_handle, (uint8_t *)uart_buf, sizeof(uart_buf) / 2); +            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)) { +            if (!retries) { +                ret = EOS_ERR_TIMEOUT; +                done = 1; +                modem_set_mode(EOS_CELL_UART_MODE_PPP); +                xSemaphoreGive(uart_mutex); +                xSemaphoreGive(ppp_mutex); +            } else { +                retries--; +                eos_modem_write("+++", 3); +                t_start = esp_timer_get_time(); +            } +        } +    } while (!done); + +    return ret; +} + +static int ppp_resume(void) { +    int r; +    int rv = EOS_OK; + +    eos_modem_write("ATO\r", 4); +    r = eos_modem_resp("^CONNECT", "^(ERROR|NO CARRIER)", 1000); +    if (r <= 0) rv = EOS_ERR; + +    modem_set_mode(EOS_CELL_UART_MODE_PPP); +    xSemaphoreGive(uart_mutex); +    xSemaphoreGive(ppp_mutex); + +    return rv; +} + +static int ppp_setup(void) { +    int r; +    char cmd[64]; +    int cmd_len = snprintf(cmd, sizeof(cmd), "AT+CGDCONT=1,\"IP\",\"%s\"\r", ppp_apn); + +    if ((cmd_len < 0) || (cmd_len >= sizeof(cmd))) return EOS_ERR; + +    modem_set_mode(EOS_CELL_UART_MODE_NONE); +    xSemaphoreTake(uart_mutex, portMAX_DELAY); + +    eos_modem_write(cmd, cmd_len); +    r = eos_modem_resp("^OK", "^ERROR", 1000); +    if (r <= 0) { +        modem_set_mode(uart_mode); +        xSemaphoreGive(uart_mutex); +        return EOS_ERR; +    } + +    eos_modem_write("AT+CGDATA=\"PPP\",1\r", 18); +    r = eos_modem_resp("^CONNECT", "^(ERROR|\\+CME ERROR|NO CARRIER)", 1000); +    if (r <= 0) { +        modem_set_mode(uart_mode); +        xSemaphoreGive(uart_mutex); +        return EOS_ERR; +    } + +    ppp_handle = pppapi_pppos_create(&ppp_netif, ppp_output_cb, ppp_status_cb, NULL); +    ppp_set_usepeerdns(ppp_handle, 1); +    pppapi_set_default(ppp_handle); +	pppapi_set_auth(ppp_handle, PPPAUTHTYPE_PAP, ppp_user, ppp_pass); +    pppapi_connect(ppp_handle, 0); + +    modem_set_mode(EOS_CELL_UART_MODE_PPP); +    xSemaphoreGive(uart_mutex); + +    return EOS_OK; +} + +static int ppp_disconnect(void) { +    int rv; + +    pppapi_close(ppp_handle, 0); + +    rv = ppp_pause(); +    if (rv) return rv; + +    eos_modem_write("ATH\r", 4); +    eos_modem_resp("^OK", NULL, 1000); + +    xSemaphoreGive(uart_mutex); +    xSemaphoreGive(ppp_mutex); +    ppp_handle = NULL; + +    return EOS_OK; +} +  void eos_modem_init(void) {      /* Configure parameters of an UART driver,       * communication pins and install the driver */ @@ -105,7 +433,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_BUF_SIZE, UART_BUF_SIZE, 10, &uart_queue, 0); +    uart_driver_install(UART_NUM_2, UART_SIZE_BUF, UART_SIZE_BUF, 10, &uart_queue, 0);      // Configuration for the DTR/RI lines      gpio_config_t io_conf; @@ -125,6 +453,15 @@ void eos_modem_init(void) {      io_conf.pull_down_en = 0;      gpio_config(&io_conf); +    mutex = xSemaphoreCreateBinary(); +    xSemaphoreGive(mutex); + +    uart_mutex = xSemaphoreCreateBinary(); +    xSemaphoreGive(uart_mutex); + +    ppp_mutex = xSemaphoreCreateBinary(); +    xSemaphoreGive(ppp_mutex); +      uart_ri_queue = xQueueCreate(4, sizeof(int));      // Create a task to handle uart event from ISR      xTaskCreate(uart_event_task, "uart_event", EOS_TASK_SSIZE_UART, NULL, EOS_TASK_PRIORITY_UART, NULL); @@ -134,14 +471,142 @@ void eos_modem_init(void) {      ESP_LOGI(TAG, "INIT");  } -ssize_t eos_modem_write(void *data, size_t size) { +void eos_modem_flush(void){ +    uart_wait_tx_done(UART_NUM_2, portMAX_DELAY); +} + +size_t eos_modem_write(void *data, size_t size) {      return uart_write_bytes(UART_NUM_2, (const char *)data, size);  } -void eos_modem_set_mode(char mode) { -    uart_event_t evt; +size_t eos_modem_read(void *data, size_t size, uint32_t timeout) { +    return uart_read_bytes(UART_NUM_2, (uint8_t *)data, size, timeout / portTICK_RATE_MS); +} -    evt.type = UART_EVENT_MAX;  /* my type */ -    evt.size = mode; -    xQueueSend(uart_queue, (void *)&evt, portMAX_DELAY); +int eos_modem_readln(char *buf, size_t buf_size, uint32_t timeout) { +    int done = 0; +    int len = 0; +    int ret = EOS_OK; +    char *ln_end = NULL; +    uint64_t t_start = esp_timer_get_time(); + +    ln_end = strchr(uart_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_size > ln_end - uart_buf) { +                    memcpy(buf, uart_buf, ln_end - uart_buf); +                    buf[ln_end - uart_buf] = '\0'; +                    ret = EOS_OK; +                } else { +                    ret = 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)) { +            ret = EOS_ERR_TIMEOUT; +            done = 1; +        } +    } while (!done); + +    return ret; +} + +int eos_modem_resp(char *ok_str, char *err_str, uint32_t timeout) { +    int rv; +    regex_t re; +    uint32_t e = 0; +    uint64_t t_start = esp_timer_get_time(); + +    do { +        rv = eos_modem_readln(at_resp, sizeof(at_resp), timeout - e); +        if (rv) return EOS_ERR; + +        if (ok_str) { +            rv = regcomp(&re, ok_str, REG_EXTENDED | REG_NOSUB); +            if (rv) return EOS_ERR; +            if (regexec(&re, at_resp, 0, NULL, 0) == 0) return 1; +        } + +        if (err_str) { +            rv = regcomp(&re, err_str, REG_EXTENDED | REG_NOSUB); +            if (rv) return EOS_ERR; +            if (regexec(&re, at_resp, 0, NULL, 0) == 0) return 0; +        } + +        at_urc_process(at_resp); +        e = (uint32_t)(esp_timer_get_time() - t_start) / 1000; +        if (e >= timeout) return EOS_ERR; +    } while (1); +} + +uint8_t eos_modem_get_mode(void) { +    uint8_t ret; + +    xSemaphoreTake(mutex, portMAX_DELAY); +    ret = uart_mode; +    xSemaphoreGive(mutex); + +    return ret; +} + +int eos_modem_set_mode(uint8_t mode) { +    int rv = EOS_OK; + +    xSemaphoreTake(mutex, portMAX_DELAY); +    if (mode != uart_mode) { +        if (uart_mode == EOS_CELL_UART_MODE_PPP) rv = ppp_disconnect(); +        if (!rv) { +            if (mode == EOS_CELL_UART_MODE_PPP) { +                rv = ppp_setup(); +            } else { +                modem_set_mode(mode); +            } +            if (!rv) uart_mode = mode; +        } +    } +    xSemaphoreGive(mutex); + +    return rv; +} + +int eos_modem_take(void) { +    int rv = EOS_OK; + +    xSemaphoreTake(mutex, portMAX_DELAY); +    if (uart_mode == EOS_CELL_UART_MODE_PPP) { +        rv = ppp_pause(); +    } else { +        modem_set_mode(EOS_CELL_UART_MODE_NONE); +        xSemaphoreTake(uart_mutex, portMAX_DELAY); +    } +    return rv; +} + +void eos_modem_give(void) { +    if (uart_mode == EOS_CELL_UART_MODE_PPP) { +        ppp_resume(); +    } else { +        modem_set_mode(uart_mode); +        xSemaphoreGive(uart_mutex); +    } +    xSemaphoreGive(mutex);  } diff --git a/code/esp32/components/eos/cell_pcm.c b/code/esp32/components/eos/cell_pcm.c index 79d654a..46c64d9 100644 --- a/code/esp32/components/eos/cell_pcm.c +++ b/code/esp32/components/eos/cell_pcm.c @@ -1,7 +1,8 @@ -#include <stdio.h> +#include <stdlib.h>  #include <string.h>  #include <freertos/FreeRTOS.h> +#include <freertos/semphr.h>  #include <freertos/task.h>  #include <freertos/queue.h>  #include <driver/i2s.h> diff --git a/code/esp32/components/eos/drv2605l.c b/code/esp32/components/eos/drv2605l.c index 023367e..3944289 100644 --- a/code/esp32/components/eos/drv2605l.c +++ b/code/esp32/components/eos/drv2605l.c @@ -1,4 +1,5 @@ -#include <stdio.h> +#include <stdlib.h> +  #include <esp_log.h>  #include "eos.h" diff --git a/code/esp32/components/eos/i2c.c b/code/esp32/components/eos/i2c.c index 38ad6ba..5b8fcc7 100644 --- a/code/esp32/components/eos/i2c.c +++ b/code/esp32/components/eos/i2c.c @@ -1,4 +1,5 @@ -#include <stdio.h> +#include <stdlib.h> +  #include <esp_log.h>  #include <driver/i2c.h> diff --git a/code/esp32/components/eos/include/at_urc.h b/code/esp32/components/eos/include/at_urc.h new file mode 100644 index 0000000..9a4c641 --- /dev/null +++ b/code/esp32/components/eos/include/at_urc.h @@ -0,0 +1,17 @@ +#include <sys/types.h> +#include <stdint.h> +#include <regex.h> + +#define AT_SIZE_NMATCH      4 +#define AT_SIZE_PATTERN     64 + +#define AT_SIZE_URC_LIST    16 + +#define AT_URC_OK           0 +#define AT_URC_MORE         1 + +typedef int (*at_urc_cb_t) (char *, regmatch_t[]); + +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);
\ No newline at end of file diff --git a/code/esp32/components/eos/include/cell.h b/code/esp32/components/eos/include/cell.h index f3eb89d..4a2cfbc 100644 --- a/code/esp32/components/eos/include/cell.h +++ b/code/esp32/components/eos/include/cell.h @@ -11,7 +11,8 @@  #define EOS_CELL_UART_MODE_NONE     0  #define EOS_CELL_UART_MODE_PPP      1 -#define EOS_CELL_UART_MODE_RELAY    2 +#define EOS_CELL_UART_MODE_ATCMD    2 +#define EOS_CELL_UART_MODE_RELAY    3  void eos_pcm_init(void); @@ -21,7 +22,16 @@ void eos_pcm_start(void);  void eos_pcm_stop(void);  void eos_modem_init(void); -ssize_t eos_modem_write(void *data, size_t size); -void eos_modem_set_mode(char mode); + +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(void); +void eos_modem_give(void);  void eos_cell_init(void);
\ No newline at end of file diff --git a/code/esp32/components/eos/include/eos.h b/code/esp32/components/eos/include/eos.h index c3f83bb..59f0ddb 100644 --- a/code/esp32/components/eos/include/eos.h +++ b/code/esp32/components/eos/include/eos.h @@ -1,7 +1,10 @@  #define EOS_OK                      0  #define EOS_ERR                     -1 +#define EOS_ERR_TIMEOUT             -2 +  #define EOS_ERR_FULL                -10  #define EOS_ERR_EMPTY               -11 +#define EOS_ERR_NOTFOUND            -12  #define EOS_TASK_PRIORITY_UART      1  #define EOS_TASK_PRIORITY_UART_RI   1 diff --git a/code/esp32/components/eos/net.c b/code/esp32/components/eos/net.c index 7fb2dc7..4eb4983 100644 --- a/code/esp32/components/eos/net.c +++ b/code/esp32/components/eos/net.c @@ -1,11 +1,10 @@ -#include <stdio.h> +#include <stdlib.h>  #include <stdint.h> -#include <stddef.h>  #include <string.h>  #include <freertos/FreeRTOS.h> -#include <freertos/task.h>  #include <freertos/semphr.h> +#include <freertos/task.h>  #include <esp_system.h>  #include <esp_log.h> diff --git a/code/esp32/components/eos/sock.c b/code/esp32/components/eos/sock.c index 8994b62..17357e4 100644 --- a/code/esp32/components/eos/sock.c +++ b/code/esp32/components/eos/sock.c @@ -3,8 +3,8 @@  #include <string.h>  #include <freertos/FreeRTOS.h> -#include <freertos/task.h>  #include <freertos/semphr.h> +#include <freertos/task.h>  #include <esp_system.h>  #include <esp_event.h> | 
