summaryrefslogtreecommitdiff
path: root/fw/esp32/components/eos/at_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/esp32/components/eos/at_cmd.c')
-rw-r--r--fw/esp32/components/eos/at_cmd.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/fw/esp32/components/eos/at_cmd.c b/fw/esp32/components/eos/at_cmd.c
new file mode 100644
index 0000000..82baa92
--- /dev/null
+++ b/fw/esp32/components/eos/at_cmd.c
@@ -0,0 +1,174 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include <freertos/FreeRTOS.h>
+#include <freertos/semphr.h>
+#include <esp_timer.h>
+#include <esp_log.h>
+
+#include "eos.h"
+
+#include "cell.h"
+#include "at_cmd.h"
+
+static const char *TAG = "EOS ATCMD";
+
+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 SemaphoreHandle_t mutex;
+
+static char at_buf[EOS_CELL_UART_SIZE_BUF];
+
+void at_init(void) {
+ memset(&urc_list, 0, sizeof(ATURCList));
+
+ mutex = xSemaphoreCreateBinary();
+ xSemaphoreGive(mutex);
+}
+
+int at_urc_process(char *urc) {
+ regmatch_t match[AT_SIZE_NMATCH];
+ at_urc_cb_t cb = NULL;
+ int i;
+
+ if (urc[0] == '\0') return 0;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+
+ for (i=0; i<urc_list.len; i++) {
+ if (regexec(&urc_list.item[i].re, urc, AT_SIZE_NMATCH, match, 0) == 0) {
+ cb = urc_list.item[i].cb;
+ break;
+ }
+ }
+
+ xSemaphoreGive(mutex);
+
+ if (cb) {
+ cb(urc, match);
+ ESP_LOGI(TAG, "URC Processed: %s", urc);
+ return 1;
+ }
+
+ ESP_LOGI(TAG, "URC NOT Processed: %s", urc);
+ return 0;
+}
+
+int at_urc_insert(char *pattern, at_urc_cb_t cb, int flags) {
+ int r;
+ int rv = EOS_OK;
+
+ if (strlen(pattern) >= AT_SIZE_PATTERN) return EOS_ERR;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+
+ r = regcomp(&urc_list.item[urc_list.len].re, pattern, flags);
+ if (r) rv = EOS_ERR;
+
+ if (!rv && (urc_list.len == AT_SIZE_URC_LIST)) rv = EOS_ERR_FULL;
+ if (!rv) {
+ strcpy(urc_list.item[urc_list.len].pattern, pattern);
+ urc_list.item[urc_list.len].cb = cb;
+ urc_list.len++;
+ }
+
+ xSemaphoreGive(mutex);
+
+ return rv;
+}
+
+int at_urc_delete(char *pattern) {
+ int i;
+ int rv = EOS_ERR_NOTFOUND;
+
+ xSemaphoreTake(mutex, portMAX_DELAY);
+
+ for (i=0; i<urc_list.len; i++) {
+ if ((strcmp(pattern, urc_list.item[i].pattern) == 0)) {
+ regfree(&urc_list.item[i].re);
+ 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--;
+ memset(&urc_list.item[urc_list.len], 0, sizeof(ATURCItem));
+ rv = EOS_OK;
+ break;
+ }
+ }
+
+ xSemaphoreGive(mutex);
+
+ return rv;
+}
+
+void at_cmd(char *cmd) {
+ eos_modem_write(cmd, strlen(cmd));
+ ESP_LOGI(TAG, "Cmd: %s", cmd);
+}
+
+int at_expect(char *str_ok, char *str_err, uint32_t timeout) {
+ return at_expect_match(str_ok, str_err, NULL, NULL, 0, REG_EXTENDED, timeout);
+}
+
+int at_expect_match(char *str_ok, char *str_err, char **buf, regmatch_t match[], size_t match_size, int flags, uint32_t timeout) {
+ int rv;
+ regex_t re_ok;
+ regex_t re_err;
+ uint32_t e = 0;
+ uint64_t t_start = esp_timer_get_time();
+
+ if (str_ok) {
+ rv = regcomp(&re_ok, str_ok, flags);
+ if (rv) {
+ return EOS_ERR;
+ }
+ }
+
+ if (str_err) {
+ rv = regcomp(&re_err, str_err, flags);
+ if (rv) {
+ if (str_ok) regfree(&re_ok);
+ return EOS_ERR;
+ }
+ }
+
+ if (buf) *buf = at_buf;
+ do {
+ rv = eos_modem_readln(at_buf, sizeof(at_buf), timeout ? timeout - e : 0);
+ if (rv) {
+ if (str_ok) regfree(&re_ok);
+ if (str_err) regfree(&re_err);
+ return rv;
+ }
+
+ ESP_LOGI(TAG, "Expect: %s", at_buf);
+
+ if (str_ok && (regexec(&re_ok, at_buf, match_size, match, 0) == 0)) {
+ regfree(&re_ok);
+ if (str_err) regfree(&re_err);
+ return 1;
+ }
+ if (str_err && (regexec(&re_err, at_buf, match_size, match, 0) == 0)) {
+ if (str_ok) regfree(&re_ok);
+ regfree(&re_err);
+ return 0;
+ }
+
+ at_urc_process(at_buf);
+
+ e = (uint32_t)(esp_timer_get_time() - t_start) / 1000;
+ if (timeout && (e > timeout)) {
+ if (str_ok) regfree(&re_ok);
+ if (str_err) regfree(&re_err);
+ return EOS_ERR_TIMEOUT;
+ }
+ } while (1);
+}