diff options
author | Uros Majstorovic <majstor@majstor.org> | 2020-08-09 02:03:25 +0200 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2020-08-09 02:03:25 +0200 |
commit | 587729b76869eb56decbf72d3a1e7f2bc2041a24 (patch) | |
tree | 8e17f8304831c684e273196816dfa5862ed0f3b3 | |
parent | 6c0542f5aaafc0d463876ade4427ccbec0ee5eda (diff) |
sms service added/tested
-rw-r--r-- | fw/esp32/components/eos/at_cmd.c | 17 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell_modem.c | 4 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell_sms.c | 268 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell_ussd.c | 13 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell_voice.c | 54 | ||||
-rw-r--r-- | fw/esp32/components/eos/gsm.c | 78 | ||||
-rw-r--r-- | fw/esp32/components/eos/gsm_cp.c | 11 | ||||
-rw-r--r-- | fw/esp32/components/eos/include/at_cmd.h | 3 | ||||
-rw-r--r-- | fw/esp32/components/eos/include/cell.h | 9 | ||||
-rw-r--r-- | fw/esp32/components/eos/include/gsm.h | 18 |
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); |