summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2020-08-09 02:03:25 +0200
committerUros Majstorovic <majstor@majstor.org>2020-08-09 02:03:25 +0200
commit587729b76869eb56decbf72d3a1e7f2bc2041a24 (patch)
tree8e17f8304831c684e273196816dfa5862ed0f3b3
parent6c0542f5aaafc0d463876ade4427ccbec0ee5eda (diff)
sms service added/tested
-rw-r--r--fw/esp32/components/eos/at_cmd.c17
-rw-r--r--fw/esp32/components/eos/cell_modem.c4
-rw-r--r--fw/esp32/components/eos/cell_sms.c268
-rw-r--r--fw/esp32/components/eos/cell_ussd.c13
-rw-r--r--fw/esp32/components/eos/cell_voice.c54
-rw-r--r--fw/esp32/components/eos/gsm.c78
-rw-r--r--fw/esp32/components/eos/gsm_cp.c11
-rw-r--r--fw/esp32/components/eos/include/at_cmd.h3
-rw-r--r--fw/esp32/components/eos/include/cell.h9
-rw-r--r--fw/esp32/components/eos/include/gsm.h18
10 files changed, 375 insertions, 100 deletions
diff --git a/fw/esp32/components/eos/at_cmd.c b/fw/esp32/components/eos/at_cmd.c
index dd2c9ea..1f39afa 100644
--- a/fw/esp32/components/eos/at_cmd.c
+++ b/fw/esp32/components/eos/at_cmd.c
@@ -60,7 +60,7 @@ int at_urc_process(char *urc) {
return 1;
}
- ESP_LOGI(TAG, "URC NOT Processed: %d %d %d %d", urc[0], urc[1], urc[0] == '\r', strlen(urc));
+ ESP_LOGI(TAG, "URC NOT Processed: %s", urc);
return 0;
}
@@ -114,6 +114,10 @@ void at_cmd(char *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;
@@ -121,21 +125,24 @@ int at_expect(char *str_ok, char *str_err, uint32_t timeout) {
uint64_t t_start = esp_timer_get_time();
if (str_ok) {
- rv = regcomp(&re_ok, str_ok, REG_EXTENDED | REG_NOSUB);
+ rv = regcomp(&re_ok, str_ok, flags);
if (rv) return EOS_ERR;
}
+ if (buf) *buf = at_buf;
if (str_err) {
- rv = regcomp(&re_err, str_err, REG_EXTENDED | REG_NOSUB);
+ rv = regcomp(&re_err, str_err, flags);
if (rv) return EOS_ERR;
}
do {
rv = eos_modem_readln(at_buf, sizeof(at_buf), timeout ? timeout - e : 0);
+ if (rv) return rv;
+
ESP_LOGI(TAG, "Expect: %s", at_buf);
- 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;
+ if (str_ok && (regexec(&re_ok, at_buf, match_size, match, 0) == 0)) return 1;
+ if (str_err && (regexec(&re_err, at_buf, match_size, match, 0) == 0)) return 0;
at_urc_process(at_buf);
diff --git a/fw/esp32/components/eos/cell_modem.c b/fw/esp32/components/eos/cell_modem.c
index 537bbbe..4c9271f 100644
--- a/fw/esp32/components/eos/cell_modem.c
+++ b/fw/esp32/components/eos/cell_modem.c
@@ -22,7 +22,7 @@
// XXX: PPP reconnect on failure
-#define UART_SIZE_IO_BUF 1024
+#define UART_SIZE_IO_BUF 8192
#define UART_GPIO_TXD 16
#define UART_GPIO_RXD 17
@@ -250,8 +250,6 @@ static void modem_atcmd_read(size_t bsize) {
}
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);
}
diff --git a/fw/esp32/components/eos/cell_sms.c b/fw/esp32/components/eos/cell_sms.c
index ef8a8c9..2648dc0 100644
--- a/fw/esp32/components/eos/cell_sms.c
+++ b/fw/esp32/components/eos/cell_sms.c
@@ -1,24 +1,282 @@
#include <stdlib.h>
+#include <string.h>
#include <stdio.h>
#include <esp_log.h>
#include "eos.h"
+#include "net.h"
+#include "unicode.h"
+#include "gsm.h"
+#include "at_cmd.h"
#include "cell.h"
+#define CTRL_Z 0x1a
+
+static const char *TAG = "EOS SMS";
+
+static char cmd[256];
+
+static char pdu[4096];
+static int pdu_len;
+
+static uint8_t udh[GSM_UDH_SIZE];
+static int udh_len;
+
+static uint8_t msg[GSM_MSG_SIZE];
+static int msg_len;
+static uint8_t msg_enc;
+
+static char orig_addr[GSM_ADDR_SIZE];
+static int orig_addr_len;
+static uint8_t orig_addr_type;
+
+static char smsc_addr[GSM_ADDR_SIZE];
+static int smsc_addr_len;
+static uint8_t smsc_addr_type;
+
+static char smsc_timestamp[GSM_TS_SIZE];
+
+uint16_t flags;
+
+static int sms_decode(unsigned char *buf, uint16_t *_len) {
+ int i, j, rv;
+ uint16_t len = 0;
+ uint8_t pid;
+ uint8_t smsc_info, smsc_info_len;
+
+ if (pdu_len < 2) return GSM_ERR_SIZE;
+ smsc_info = pdu_getc(pdu);
+ smsc_info_len = 2 * (smsc_info + 1);
+ if (pdu_len < smsc_info_len) return GSM_ERR_SIZE;
+
+ if (smsc_info > 1) {
+ pdu_putc((smsc_info - 1) * 2, pdu);
+ rv = gsm_addr_dec(pdu, pdu_len, smsc_addr, &smsc_addr_len, &smsc_addr_type);
+ if (rv < 0) smsc_addr_len = 0;
+ }
+
+ rv = gsm_sms_dec(pdu + smsc_info_len, pdu_len - smsc_info_len, &pid, orig_addr, &orig_addr_len, &orig_addr_type, udh, &udh_len, msg, &msg_len, smsc_timestamp, &msg_enc, &flags);
+ if (rv < 0) return rv;
+ if (msg_enc == GSM_ENC_8BIT) return EOS_ERR;
+
+ buf[0] = flags;
+ len += 1;
+
+ memcpy(buf + len, smsc_timestamp, GSM_TS_SIZE);
+ len += GSM_TS_SIZE;
+
+ if ((orig_addr_type & GSM_TON) == GSM_TON_ALPHANUMERIC) {
+ buf[len] = EOS_CELL_SMS_ADDRTYPE_ALPHA;
+ buf[len + 1] = 0;
+ len += 2;
+
+ i = 0;
+ j = 0;
+ while (i < orig_addr_len) {
+ uint16_t ch;
+
+ rv = gsm_7bit_to_ucs2((char *)orig_addr + i, orig_addr_len - i, &ch);
+ if (rv < 0) return EOS_ERR;
+ i += rv;
+ rv = utf8_enc(ch, buf + len + j);
+ if (rv < 0) return EOS_ERR;
+ j += rv;
+ }
+ buf[len - 1] = j;
+ len += j;
+ } else {
+ buf[len] = ((orig_addr_type & GSM_TON) == GSM_TON_INTERNATIONAL) ? EOS_CELL_SMS_ADDRTYPE_INTL : EOS_CELL_SMS_ADDRTYPE_OTHER;
+ buf[len + 1] = orig_addr_len;
+ len += 2;
+ memcpy(buf + len, orig_addr, orig_addr_len);
+ len += orig_addr_len;
+ }
+
+ i = 0;
+ j = 0;
+ while (i < msg_len) {
+ utf32_t ch;
+
+ if (msg_enc == GSM_ENC_7BIT) {
+ uint16_t _ch;
+
+ rv = gsm_7bit_to_ucs2((char *)msg + i, msg_len - i, &_ch);
+ ch = _ch;
+ } else {
+ if (((msg_len - i) < 4) && (utf16_len(msg + i) > 2)) {
+ rv = EOS_ERR;
+ } else {
+ rv = utf16_dec(msg + i, &ch);
+ }
+ }
+ if (rv < 0) return EOS_ERR;
+ i += rv;
+
+ rv = utf8_enc(ch, buf + len + j);
+ if (rv < 0) return EOS_ERR;
+ j += rv;
+ }
+ buf[len + j] = '\0';
+
+ buf = buf + len;
+ printf("BODY: %s\n", buf);
+ /*
+ while (*buf) {
+ printf("%02x ", *buf);
+ buf++;
+ }
+ printf("\n");
+ */
+
+ len += j + 1;
+ *_len = len;
+
+ return EOS_OK;
+}
+
+static int sms_encode(unsigned char *buffer, uint16_t size) {
+ utf32_t ch;
+ int i, rv;
+ char *addr;
+ uint8_t addr_type;
+ int addr_len;
+
+ if (size == 0) return EOS_ERR;
+
+ flags = buffer[0];
+ buffer += 1;
+ size -= 1;
+
+ if (size < 2) return EOS_ERR;
+ switch(buffer[0]) {
+ case EOS_CELL_SMS_ADDRTYPE_INTL:
+ addr_type = GSM_EXT | GSM_TON_INTERNATIONAL | GSM_NPI_TELEPHONE;
+ break;
+
+ case EOS_CELL_SMS_ADDRTYPE_OTHER:
+ addr_type = GSM_EXT | GSM_TON_UNKNOWN | GSM_NPI_TELEPHONE;
+ break;
+
+ default: return EOS_ERR;
+ }
+ addr_len = buffer[1];
+ addr = (char *)buffer + 2;
+
+ if (size < 2 + addr_len) return EOS_ERR;
+ buffer += 2 + addr_len;
+ size -= 2 + addr_len;
+
+ i = 0;
+ msg_len = 0;
+ while (i < size) {
+ rv = utf8_dec(buffer + i, &ch);
+ if (rv < 0) return EOS_ERR;
+ if (ch >= 0xffff) return EOS_ERR;
+ i += rv;
+
+ rv = gsm_ucs2_to_7bit(ch, (char *)msg + msg_len, sizeof(msg) - msg_len);
+ if (rv < 0) return EOS_ERR;
+ msg_len += rv;
+ }
+
+ pdu_putc(0, pdu);
+ rv = gsm_sms_enc(0, addr, addr_len, addr_type, NULL, 0, msg, msg_len, GSM_ENC_7BIT, flags, pdu + 2, sizeof(pdu) - 4);
+ if (rv < 0) return EOS_ERR;
+ pdu_len = rv;
+ pdu[pdu_len + 2] = CTRL_Z;
+ pdu[pdu_len + 3] = '\0';
+
+ return EOS_OK;
+}
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) {
+ case EOS_CELL_MTYPE_SMS_LIST:
+ if (size == 0) return;
+ snprintf(cmd, sizeof(cmd), "AT+CMGL=%d\r", buffer[0]);
+
+ rv = eos_modem_take(1000);
+ if (rv) return;
+ at_cmd(cmd);
+ do {
+ unsigned char *buf;
+ uint16_t len;
+
+ rv = at_expect("^\\+CMGL: [0-9]+,[0-9],.*,[0-9]+$", "^OK", 1000);
+ if (rv != 1) break;
+
+ rv = eos_modem_readln(pdu, sizeof(pdu), 1000);
+ if (rv) break;
+ pdu_len = strlen(pdu);
+
+ buf = eos_net_alloc();
+ buf[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG_ITEM;
+ rv = sms_decode(buf + 1, &len);
+ if (rv) {
+ eos_net_free(buf);
+ } else {
+ len++;
+ eos_net_free(buf);
+ // eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ }
+ } while (1);
+ eos_modem_give();
+
+ break;
+
+ case EOS_CELL_MTYPE_SMS_SEND:
+ rv = sms_encode(buffer, size);
+ if (rv) return;
+
+ snprintf(cmd, sizeof(cmd), "AT+CMGS=%d\r", pdu_len / 2);
+
+ rv = eos_modem_take(1000);
+ if (rv) return;
+ at_cmd(cmd);
+ at_cmd(pdu);
+ rv = at_expect("^OK", "^ERROR", 1000);
+ eos_modem_give();
+
+ break;
}
+}
- eos_modem_give();
+static void sms_received_handler(char *urc, regmatch_t m[]) {
+ int ref, rv;
+
+ sscanf(urc + m[1].rm_so, "%6d", &ref);
+
+ snprintf(cmd, sizeof(cmd), "AT+CMGR=%d\r", ref);
+ at_cmd(cmd);
+
+ rv = at_expect("^\\+CMGR: [0-9],.*,[0-9]+$", "^ERROR", 1000);
+ if (rv == 1) {
+ unsigned char *buf;
+ uint16_t len;
+
+ rv = eos_modem_readln(pdu, sizeof(pdu), 1000);
+ if (rv) return;
+ pdu_len = strlen(pdu);
+
+ rv = at_expect("^OK", NULL, 1000);
+
+ buf = eos_net_alloc();
+ buf[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG_NEW;
+ rv = sms_decode(buf + 1, &len);
+ if (rv) {
+ eos_net_free(buf);
+ } else {
+ len++;
+ eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
+ }
+ }
}
-void eos_cell_sms_init(void) {}
+void eos_cell_sms_init(void) {
+ at_urc_insert("^\\+CMTI: .*,([0-9]+)$", sms_received_handler, REG_EXTENDED);
+}
diff --git a/fw/esp32/components/eos/cell_ussd.c b/fw/esp32/components/eos/cell_ussd.c
index 3f5ea3b..3113886 100644
--- a/fw/esp32/components/eos/cell_ussd.c
+++ b/fw/esp32/components/eos/cell_ussd.c
@@ -8,12 +8,10 @@
#include "cell.h"
static char cmd[256];
+static int cmd_len;
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;
+ int rv;
buffer += 1;
size -= 1;
@@ -24,13 +22,18 @@ void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t
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;
+
+ rv = eos_modem_take(1000);
+ if (rv) return;
+
at_cmd(cmd);
rv = at_expect("^OK", "^ERROR", 1000);
+ eos_modem_give();
+
break;
}
- eos_modem_give();
}
void eos_cell_ussd_init(void) {} \ No newline at end of file
diff --git a/fw/esp32/components/eos/cell_voice.c b/fw/esp32/components/eos/cell_voice.c
index 8162690..499458f 100644
--- a/fw/esp32/components/eos/cell_voice.c
+++ b/fw/esp32/components/eos/cell_voice.c
@@ -13,13 +13,10 @@
static const char *TAG = "EOS VOICE";
static char cmd[256];
-static char ring_buf[256];
+static int cmd_len;
void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t size) {
- int cmd_len, rv;
-
- rv = eos_modem_take(1000);
- if (rv) return;
+ int rv;
buffer += 1;
size -= 1;
@@ -30,59 +27,54 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t
buffer[size] = '\0';
cmd_len = snprintf(cmd, sizeof(cmd), "ATD%s;\r", buffer);
if ((cmd_len < 0) || (cmd_len >= sizeof(cmd))) return;
+
+ rv = eos_modem_take(1000);
+ if (rv) return;
at_cmd(cmd);
rv = at_expect("^OK", "^ERROR", 1000);
+ eos_modem_give();
+
eos_cell_pcm_start();
break;
case EOS_CELL_MTYPE_VOICE_ANSWER:
+ rv = eos_modem_take(1000);
+ if (rv) return;
at_cmd("ATA\r");
rv = at_expect("^OK", "^ERROR", 1000);
+ eos_modem_give();
+
eos_cell_pcm_start();
break;
case EOS_CELL_MTYPE_VOICE_HANGUP:
eos_cell_pcm_stop();
+
+ rv = eos_modem_take(1000);
+ if (rv) return;
at_cmd("AT+CHUP\r");
rv = at_expect("^OK", "^ERROR", 1000);
+ eos_modem_give();
+
break;
}
-
- eos_modem_give();
}
static void ring_handler(char *urc, regmatch_t m[]) {
unsigned char *buf;
+ char *ring_buf;
uint16_t len;
- uint32_t timeout = 1000, e = 0;
- uint64_t t_start = esp_timer_get_time();
+ regmatch_t match[2];
int rv = EOS_OK;
- ring_buf[0] = '\0';
- while (ring_buf[0] == '\0') {
- rv = eos_modem_readln(ring_buf, sizeof(ring_buf), timeout - e);
- if (rv) break;
-
- e = (uint32_t)(esp_timer_get_time() - t_start) / 1000;
- if (timeout && (e > timeout)) {
- rv = EOS_ERR_TIMEOUT;
- break;
- }
- }
-
buf = eos_net_alloc();
buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_RING;
len = 1;
- if (!rv) {
- regex_t re;
- regmatch_t match[2];
-
- regcomp(&re, "^\\+CLIP: \"(\\+?[0-9]+)\"", REG_EXTENDED);
- if (regexec(&re, ring_buf, 2, match, 0) == 0) {
- ring_buf[match[1].rm_eo] = '\0';
- strcpy((char *)buf + 1, ring_buf + match[1].rm_so);
- len += 1 + match[1].rm_eo - match[1].rm_so;
- }
+ rv = at_expect_match("^\\+CLIP: \"(\\+?[0-9]+)\"", NULL, &ring_buf, match, 2, REG_EXTENDED, 1000);
+ if (rv == 1) {
+ ring_buf[match[1].rm_eo] = '\0';
+ strcpy((char *)buf + 1, ring_buf + match[1].rm_so);
+ len += 1 + match[1].rm_eo - match[1].rm_so;
}
eos_net_send(EOS_NET_MTYPE_CELL, buf, len);
}
diff --git a/fw/esp32/components/eos/gsm.c b/fw/esp32/components/eos/gsm.c
index 788722e..552af66 100644
--- a/fw/esp32/components/eos/gsm.c
+++ b/fw/esp32/components/eos/gsm.c
@@ -16,20 +16,20 @@ void pdu_putc(uint8_t ch, char *pdu) {
sprintf(pdu, "%.2X", ch);
}
-void pdu_puts(uint8_t *s, int s_len, char *pdu) {
- int i;
+void pdu_gets(char *pdu, uint8_t *s, int s_len) {
+ int i, ch;
for (i=0; i<s_len; i++) {
- sprintf(pdu + 2 * i, "%.2X", s[i]);
+ sscanf(pdu + 2 * i, "%2X", &ch);
+ s[i] = ch;
}
}
-void pdu_gets(char *pdu, uint8_t *s, int s_len) {
- int i, ch;
+void pdu_puts(uint8_t *s, int s_len, char *pdu) {
+ int i;
for (i=0; i<s_len; i++) {
- sscanf(pdu + 2 * i, "%2X", &ch);
- s[i] = ch;
+ sprintf(pdu + 2 * i, "%.2X", s[i]);
}
}
@@ -82,7 +82,7 @@ int gsm_ts_enc(char *ts, char *pdu, int pdu_size) {
uint8_t tz;
int tz_hh, tz_mm;
- if (pdu_size < 14) return GSM_ERR;
+ if (pdu_size < 14) return GSM_ERR_SIZE;
pdu[1] = ts[2]; // YY
pdu[0] = ts[3];
@@ -115,7 +115,7 @@ int gsm_ts_enc(char *ts, char *pdu, int pdu_size) {
int gsm_ts_dec(char *pdu, int pdu_len, char *ts) {
uint8_t tz;
- if (pdu_len < 14) return GSM_ERR;
+ if (pdu_len < 14) return GSM_ERR_SIZE;
ts[0] = '2';
ts[1] = '0';
@@ -231,7 +231,7 @@ int gsm_addr_enc(char *addr, int addr_len, uint8_t addr_type, char *pdu, int pdu
int _addr_len = DIVC(addr_len * 7, 4);
_pdu_len = 4 + DIVC(_addr_len, 2) * 2;
- if (pdu_size < _pdu_len) return GSM_ERR;
+ if (pdu_size < _pdu_len) return GSM_ERR_SIZE;
pdu_putc(_addr_len, pdu);
pdu_putc(addr_type, pdu + 2);
@@ -239,13 +239,8 @@ int gsm_addr_enc(char *addr, int addr_len, uint8_t addr_type, char *pdu, int pdu
} else {
int i;
- if (addr_type & GSM_TON_INTERNATIONAL) {
- if (addr[0] != '+') return GSM_ERR;
- addr++;
- addr_len--;
- }
_pdu_len = 4 + DIVC(addr_len, 2) * 2;
- if (pdu_size < _pdu_len) return GSM_ERR;
+ if (pdu_size < _pdu_len) return GSM_ERR_SIZE;
pdu_putc(addr_len, pdu);
pdu_putc(addr_type, pdu + 2);
@@ -262,40 +257,32 @@ int gsm_addr_enc(char *addr, int addr_len, uint8_t addr_type, char *pdu, int pdu
return _pdu_len;
}
-int gsm_addr_dec(char *pdu, int pdu_len, char *addr, int addr_size, int *addr_len, uint8_t *addr_type) {
+int gsm_addr_dec(char *pdu, int pdu_len, char *addr, int *addr_len, uint8_t *addr_type) {
int _pdu_len;
- if (pdu_len < 4) return GSM_ERR;
+ if (pdu_len < 4) return GSM_ERR_SIZE;
*addr_len = pdu_getc(pdu);
*addr_type = pdu_getc(pdu + 2);
+ if (*addr_len > GSM_ADDR_SIZE) return GSM_ERR_SIZE;
if (!(*addr_type & GSM_EXT)) return GSM_ERR;
_pdu_len = 4 + DIVC(*addr_len, 2) * 2;
- if (pdu_len < _pdu_len) return GSM_ERR;
+ if (pdu_len < _pdu_len) return GSM_ERR_SIZE;
if ((*addr_type & GSM_TON) == GSM_TON_ALPHANUMERIC) {
*addr_len = (*addr_len * 4) / 7;
- if (addr_size < *addr_len) return GSM_ERR;
gsm_7bit_dec(pdu + 4, addr, *addr_len, 0);
} else {
int i;
- int _addr_len = *addr_len;
-
- if (*addr_type & GSM_TON_INTERNATIONAL) {
- addr[0] = '+';
- addr++;
- (*addr_len)++;
- }
- if (addr_size < *addr_len) return GSM_ERR;
- for (i=0; i<_addr_len / 2; i++) {
+ for (i=0; i<*addr_len / 2; i++) {
addr[2 * i] = pdu[4 + 2 * i + 1];
addr[2 * i + 1] = pdu[4 + 2 * i];
}
- if (_addr_len % 2 != 0) {
+ if (*addr_len % 2 != 0) {
addr[2 * i] = pdu[4 + 2 * i + 1];
}
}
@@ -311,7 +298,7 @@ int gsm_sms_enc(uint8_t pid, char *addr, int addr_len, uint8_t addr_type, uint8_
if (udh_len) mti |= GSM_UDHI;
- if (pdu_size < 4) return GSM_ERR;
+ if (pdu_size < 4) return GSM_ERR_SIZE;
pdu_putc(mti, pdu);
pdu_putc(00, pdu + 2);
_pdu_len += 4;
@@ -320,7 +307,7 @@ int gsm_sms_enc(uint8_t pid, char *addr, int addr_len, uint8_t addr_type, uint8_
if (rv < 0) return rv;
_pdu_len += rv;
- if (pdu_size < _pdu_len + 4) return GSM_ERR;
+ if (pdu_size < _pdu_len + 4) return GSM_ERR_SIZE;
gsm_dcs_enc(enc, flags, &dcs);
pdu_putc(pid, pdu + _pdu_len);
pdu_putc(dcs, pdu + _pdu_len + 2);
@@ -336,7 +323,7 @@ int gsm_sms_enc(uint8_t pid, char *addr, int addr_len, uint8_t addr_type, uint8_
}
udl = DIVC(udh_blen, 7) + msg_len;
- if (pdu_size < _pdu_len + (DIVC(udl * 7, 8) + 1) * 2) return GSM_ERR;
+ if (pdu_size < _pdu_len + (DIVC(udl * 7, 8) + 1) * 2) return GSM_ERR_SIZE;
pdu_putc(udl, pdu + _pdu_len);
_pdu_len += 2;
@@ -352,7 +339,7 @@ int gsm_sms_enc(uint8_t pid, char *addr, int addr_len, uint8_t addr_type, uint8_
} else {
udl = msg_len + (udh_len ? udh_len + 1 : 0);
- if (pdu_size < _pdu_len + (udl + 1) * 2) return GSM_ERR;
+ if (pdu_size < _pdu_len + (udl + 1) * 2) return GSM_ERR_SIZE;
pdu_putc(udl, pdu + _pdu_len);
_pdu_len += 2;
@@ -369,22 +356,22 @@ int gsm_sms_enc(uint8_t pid, char *addr, int addr_len, uint8_t addr_type, uint8_
return _pdu_len;
}
-int gsm_sms_dec(char *pdu, int pdu_len, uint8_t *pid, char *addr, int addr_size, int *addr_len, uint8_t *addr_type, uint8_t *udh, int udh_size, int *udh_len, uint8_t *msg, int msg_size, int *msg_len, char *ts, uint8_t *enc, uint16_t *flags) {
+int gsm_sms_dec(char *pdu, int pdu_len, uint8_t *pid, char *addr, int *addr_len, uint8_t *addr_type, uint8_t *udh, int *udh_len, uint8_t *msg, int *msg_len, char *ts, uint8_t *enc, uint16_t *flags) {
int rv, _pdu_len = 0;
uint8_t mti;
uint8_t dcs;
uint8_t udl;
- if (pdu_len < 2) return GSM_ERR;
+ if (pdu_len < 2) return GSM_ERR_SIZE;
mti = pdu_getc(pdu);
_pdu_len += 2;
if ((mti & GSM_MTI) != GSM_MTI_DELIVER) return GSM_ERR;
- rv = gsm_addr_dec(pdu + _pdu_len, pdu_len - _pdu_len, addr, addr_size, addr_len, addr_type);
+ rv = gsm_addr_dec(pdu + _pdu_len, pdu_len - _pdu_len, addr, addr_len, addr_type);
if (rv < 0) return rv;
_pdu_len += rv;
- if (pdu_len < _pdu_len + 4) return GSM_ERR;
+ if (pdu_len < _pdu_len + 4) return GSM_ERR_SIZE;
*pid = pdu_getc(pdu + _pdu_len);
dcs = pdu_getc(pdu + _pdu_len + 2);
_pdu_len += 4;
@@ -394,7 +381,7 @@ int gsm_sms_dec(char *pdu, int pdu_len, uint8_t *pid, char *addr, int addr_size,
if (rv < 0) return rv;
_pdu_len += rv;
- if (pdu_len < _pdu_len + 2) return GSM_ERR;
+ if (pdu_len < _pdu_len + 2) return GSM_ERR_SIZE;
udl = pdu_getc(pdu + _pdu_len);
_pdu_len += 2;
@@ -405,7 +392,7 @@ int gsm_sms_dec(char *pdu, int pdu_len, uint8_t *pid, char *addr, int addr_size,
int udh_blen = 0;
int padb = 0;
- if (pdu_len < _pdu_len + DIVC(udl * 7, 8) * 2) return GSM_ERR;
+ if (pdu_len < _pdu_len + DIVC(udl * 7, 8) * 2) return GSM_ERR_SIZE;
if (mti & GSM_UDHI) {
*udh_len = pdu_getc(pdu + _pdu_len);
@@ -413,7 +400,7 @@ int gsm_sms_dec(char *pdu, int pdu_len, uint8_t *pid, char *addr, int addr_size,
padb = DIVC(udh_blen, 7) * 7 - udh_blen;
if (udl * 7 < udh_blen) return GSM_ERR;
- if (udh_size < *udh_len) return GSM_ERR;
+ if (*udh_len > GSM_UDH_SIZE) return GSM_ERR_SIZE;
pdu_gets(pdu + _pdu_len + 2, udh, *udh_len);
_pdu_len += (*udh_len + 1) * 2;
@@ -422,19 +409,19 @@ int gsm_sms_dec(char *pdu, int pdu_len, uint8_t *pid, char *addr, int addr_size,
}
*msg_len = udl - DIVC(udh_blen, 7);
- if (msg_size < *msg_len) return GSM_ERR;
+ if (*msg_len > GSM_UD_SIZE) return GSM_ERR_SIZE;
rv = gsm_7bit_dec(pdu + _pdu_len, (char *)msg, *msg_len, padb);
if (rv < 0) return rv;
_pdu_len += rv;
} else {
- if (pdu_len < _pdu_len + udl * 2) return GSM_ERR;
+ if (pdu_len < _pdu_len + udl * 2) return GSM_ERR_SIZE;
if (mti & GSM_UDHI) {
*udh_len = pdu_getc(pdu + _pdu_len);
if (udl < *udh_len + 1) return GSM_ERR;
- if (udh_size < *udh_len) return GSM_ERR;
+ if (*udh_len > GSM_UDH_SIZE) return GSM_ERR_SIZE;
pdu_gets(pdu + _pdu_len + 2, udh, *udh_len);
_pdu_len += (*udh_len + 1) * 2;
@@ -443,7 +430,8 @@ int gsm_sms_dec(char *pdu, int pdu_len, uint8_t *pid, char *addr, int addr_size,
}
*msg_len = udl - (*udh_len ? *udh_len + 1 : 0);
- if (msg_size < *msg_len) return GSM_ERR;
+ if (*msg_len > GSM_UD_SIZE) return GSM_ERR_SIZE;
+ if ((*enc == GSM_ENC_UCS2) && ((*msg_len % 2) != 0)) return GSM_ERR;
pdu_gets(pdu + _pdu_len, msg, *msg_len);
_pdu_len += *msg_len * 2;
diff --git a/fw/esp32/components/eos/gsm_cp.c b/fw/esp32/components/eos/gsm_cp.c
index 3ab98c5..508aa54 100644
--- a/fw/esp32/components/eos/gsm_cp.c
+++ b/fw/esp32/components/eos/gsm_cp.c
@@ -15,9 +15,10 @@ static const uint16_t gsm7_to_ucs2[128] = {
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00f1, 0x00fc, 0x00e0
};
+// Ext table ss2 (0x1b 0x1b) is mapped to space
static const uint16_t gsm7e_to_ucs2[128] = {
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x000c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- 0xffff, 0xffff, 0xffff, 0xffff, 0x005e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0x005e, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0020, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x007b, 0x007d, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x005c,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x005b, 0x007e, 0x005d, 0xffff,
0x007c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
@@ -63,7 +64,7 @@ int gsm_ucs2_to_7bit(uint16_t ucs2, char *gsm7, int gsm7_size) {
uint16_t ch = 0xffff;
int ret = 0;
- if (gsm7_size < 1) return GSM_ERR;
+ if (gsm7_size < 1) return GSM_ERR_SIZE;
if (ucs2 < 256) {
ch = ucs2_to_gsm7[ucs2];
@@ -79,7 +80,7 @@ int gsm_ucs2_to_7bit(uint16_t ucs2, char *gsm7, int gsm7_size) {
}
if (ch == 0xffff) return GSM_ERR;
if (ch & 0xff00) {
- if (gsm7_size < 2) return GSM_ERR;
+ if (gsm7_size < 2) return GSM_ERR_SIZE;
*gsm7 = 0x1b;
gsm7++;
ret++;
@@ -93,12 +94,12 @@ int gsm_ucs2_to_7bit(uint16_t ucs2, char *gsm7, int gsm7_size) {
int gsm_7bit_to_ucs2(char *gsm7, int gsm7_len, uint16_t *ucs2) {
int ret;
- if (gsm7_len < 1) return GSM_ERR;
+ if (gsm7_len < 1) return GSM_ERR_SIZE;
if (*gsm7 != 0x1b) {
*ucs2 = gsm7_to_ucs2[*gsm7 & 0x7f];
ret = 1;
} else {
- if (gsm7_len < 2) return GSM_ERR;
+ if (gsm7_len < 2) return GSM_ERR_SIZE;
gsm7++;
ret = 2;
*ucs2 = gsm7e_to_ucs2[*gsm7 & 0x7f];
diff --git a/fw/esp32/components/eos/include/at_cmd.h b/fw/esp32/components/eos/include/at_cmd.h
index 2fdd159..2d0813e 100644
--- a/fw/esp32/components/eos/include/at_cmd.h
+++ b/fw/esp32/components/eos/include/at_cmd.h
@@ -5,7 +5,7 @@
#define AT_SIZE_NMATCH 4
#define AT_SIZE_PATTERN 64
-#define AT_SIZE_URC_LIST 16
+#define AT_SIZE_URC_LIST 32
typedef void (*at_urc_cb_t) (char *, regmatch_t[]);
@@ -15,3 +15,4 @@ int at_urc_insert(char *pattern, at_urc_cb_t cb, int flags);
int at_urc_delete(char *pattern);
void at_cmd(char *cmd);
int at_expect(char *str_ok, char *str_err, uint32_t 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);
diff --git a/fw/esp32/components/eos/include/cell.h b/fw/esp32/components/eos/include/cell.h
index abba977..65b4b1a 100644
--- a/fw/esp32/components/eos/include/cell.h
+++ b/fw/esp32/components/eos/include/cell.h
@@ -27,6 +27,11 @@
#define EOS_CELL_MTYPE_VOICE_END 6
#define EOS_CELL_MTYPE_VOICE_MISSED 7
+#define EOS_CELL_MTYPE_SMS_LIST 1
+#define EOS_CELL_MTYPE_SMS_SEND 2
+#define EOS_CELL_MTYPE_SMS_MSG_NEW 3
+#define EOS_CELL_MTYPE_SMS_MSG_ITEM 4
+
#define EOS_CELL_MTYPE_USSD_REQUEST 1
#define EOS_CELL_MTYPE_USSD_REPLY 2
@@ -34,6 +39,10 @@
#define EOS_CELL_MTYPE_DATA_CONNECT 2
#define EOS_CELL_MTYPE_DATA_DISCONNECT 3
+#define EOS_CELL_SMS_ADDRTYPE_INTL 1
+#define EOS_CELL_SMS_ADDRTYPE_ALPHA 2
+#define EOS_CELL_SMS_ADDRTYPE_OTHER 3
+
#define EOS_CELL_UART_MODE_NONE 0
#define EOS_CELL_UART_MODE_ATCMD 1
#define EOS_CELL_UART_MODE_PPP 2
diff --git a/fw/esp32/components/eos/include/gsm.h b/fw/esp32/components/eos/include/gsm.h
index 2c4f7b4..8f7b75f 100644
--- a/fw/esp32/components/eos/include/gsm.h
+++ b/fw/esp32/components/eos/include/gsm.h
@@ -1,5 +1,12 @@
#define GSM_OK 0
#define GSM_ERR -1
+#define GSM_ERR_SIZE -10
+
+#define GSM_TS_SIZE 25
+#define GSM_UD_SIZE 160
+#define GSM_UDH_SIZE 140
+#define GSM_MSG_SIZE GSM_UD_SIZE
+#define GSM_ADDR_SIZE 20
/* Message-Type-Indicator */
#define GSM_MTI 0x03
@@ -113,5 +120,16 @@
#define GSM_FLAG_MWI_OTHER 0x3000
#define GSM_FLAG_MWI_MASK 0xf000
+uint8_t pdu_getc(char *pdu);
+void pdu_putc(uint8_t ch, char *pdu);
+void pdu_gets(char *pdu, uint8_t *s, int s_len);
+void pdu_puts(uint8_t *s, int s_len, char *pdu);
+int gsm_ucs2_to_7bit(uint16_t ucs2, char *gsm7, int gsm7_size);
+int gsm_7bit_to_ucs2(char *gsm7, int gsm7_len, uint16_t *ucs2);
+
int gsm_7bit_enc(char *text, int text_len, char *pdu, int padb);
int gsm_7bit_dec(char *pdu, char *text, int text_len, int padb);
+int gsm_addr_enc(char *addr, int addr_len, uint8_t addr_type, char *pdu, int pdu_size);
+int gsm_addr_dec(char *pdu, int pdu_len, char *addr, int *addr_len, uint8_t *addr_type);
+int gsm_sms_enc(uint8_t pid, char *addr, int addr_len, uint8_t addr_type, uint8_t *udh, int udh_len, uint8_t *msg, int msg_len, uint8_t enc, uint16_t flags, char *pdu, int pdu_size);
+int gsm_sms_dec(char *pdu, int pdu_len, uint8_t *pid, char *addr, int *addr_len, uint8_t *addr_type, uint8_t *udh, int *udh_len, uint8_t *msg, int *msg_len, char *ts, uint8_t *enc, uint16_t *flags);