diff options
Diffstat (limited to 'fw/esp32')
| -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);  | 
