diff options
author | Uros Majstorovic <majstor@majstor.org> | 2024-09-04 21:07:29 +0200 |
---|---|---|
committer | Uros Majstorovic <majstor@majstor.org> | 2024-09-04 21:07:29 +0200 |
commit | 9da5f8409c85637361d7bc69b721f6d9d3087b7b (patch) | |
tree | f53bd2d8f9f59b683519ce87551db6ee23be2062 | |
parent | ec892bf2e7620fb58e635b900ab4a0e44e3488bd (diff) |
esp32 cellular modem driver fix
-rw-r--r-- | fw/esp32/components/eos/at_cmd.c | 3 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell.c | 2 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell_modem.c | 10 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell_pcm.c | 38 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell_pdp.c | 8 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell_sms.c | 340 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell_ussd.c | 55 | ||||
-rw-r--r-- | fw/esp32/components/eos/cell_voice.c | 27 | ||||
-rw-r--r-- | fw/esp32/components/eos/gsm.c | 352 | ||||
-rw-r--r-- | fw/esp32/components/eos/gsm_cp.c | 22 | ||||
-rw-r--r-- | fw/esp32/components/eos/include/at_cmd.h | 1 | ||||
-rw-r--r-- | fw/esp32/components/eos/include/cell.h | 19 | ||||
-rw-r--r-- | fw/esp32/components/eos/include/eos.h | 10 | ||||
-rw-r--r-- | fw/esp32/components/eos/include/gsm.h | 37 |
14 files changed, 539 insertions, 385 deletions
diff --git a/fw/esp32/components/eos/at_cmd.c b/fw/esp32/components/eos/at_cmd.c index 37de990..a1c329e 100644 --- a/fw/esp32/components/eos/at_cmd.c +++ b/fw/esp32/components/eos/at_cmd.c @@ -29,6 +29,9 @@ static SemaphoreHandle_t mutex; static char at_buf[EOS_CELL_UART_SIZE_BUF]; +/* should be used from net cell handlers only! */ +char at_cmd_buf[AT_SIZE_CMD_BUF]; + void at_init(void) { memset(&urc_list, 0, sizeof(ATURCList)); diff --git a/fw/esp32/components/eos/cell.c b/fw/esp32/components/eos/cell.c index 2584884..d34172e 100644 --- a/fw/esp32/components/eos/cell.c +++ b/fw/esp32/components/eos/cell.c @@ -117,7 +117,7 @@ static void cell_handler(unsigned char type, unsigned char *buffer, uint16_t len xSemaphoreGive(mutex); if (buf == NULL) { - ESP_LOGE(TAG, "Cell message NOT handled: %2x", type); + if (len) ESP_LOGE(TAG, "Cell message NOT handled: %2x", buffer[0]); return; } diff --git a/fw/esp32/components/eos/cell_modem.c b/fw/esp32/components/eos/cell_modem.c index 26be56e..b279db1 100644 --- a/fw/esp32/components/eos/cell_modem.c +++ b/fw/esp32/components/eos/cell_modem.c @@ -64,9 +64,9 @@ static uint8_t RTC_NOINIT_ATTR uart_mode; static uint8_t uart_mode_next = EOS_CELL_UART_MODE_NONE; static SemaphoreHandle_t uart_mutex; -static char ppp_apn[EOS_CELL_PDP_SIZE_APN]; -static char ppp_usr[EOS_CELL_PDP_SIZE_USR]; -static char ppp_pwd[EOS_CELL_PDP_SIZE_PWD]; +static char ppp_apn[EOS_CELL_PDP_SIZE_APN + 1]; +static char ppp_usr[EOS_CELL_PDP_SIZE_USR + 1]; +static char ppp_pwd[EOS_CELL_PDP_SIZE_PWD + 1]; static SemaphoreHandle_t ppp_mutex; static ppp_pcb *ppp_handle; @@ -150,7 +150,7 @@ static void uart_data_read(uint8_t mode) { buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; - _rd = eos_modem_read(buf + 1, MIN(bsize - rd, EOS_NET_MTU - 1), 100); + _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); rd += _rd; } while (rd != bsize); @@ -594,7 +594,7 @@ static int ppp_resume(void) { static int ppp_setup(void) { int r; - char cmd[64]; + char cmd[EOS_CELL_PDP_SIZE_APN + 32]; int cmd_len; cmd_len = snprintf(cmd, sizeof(cmd), "AT+CGDCONT=1,\"IP\",\"%s\"\r", ppp_apn); diff --git a/fw/esp32/components/eos/cell_pcm.c b/fw/esp32/components/eos/cell_pcm.c index 0648be7..b993021 100644 --- a/fw/esp32/components/eos/cell_pcm.c +++ b/fw/esp32/components/eos/cell_pcm.c @@ -59,23 +59,42 @@ static void i2s_event_task(void *pvParameters) { unsigned char _type; unsigned char *buf; + if (!pcm_active) { + if (hold_buf) { + eos_net_free(hold_buf); + hold_buf = NULL; + } + break; + } + // Event of I2S receiving data if (!hold_cnt) { - buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; bytes_r = eos_cell_pcm_read(buf + 1, PCM_MIC_WM); + if (bytes_r < 0) { + ESP_LOGE(TAG, "*** I2S READ ERROR ***"); + eos_net_free(buf); + break; + } eos_net_send(EOS_NET_MTYPE_CELL, buf, bytes_r + 1); } else { - hold_cnt--; if (hold_buf == NULL) { hold_buf = eos_net_alloc(); hold_buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; + hold_bytes_r = 0; + } + if (1 + hold_bytes_r + PCM_MIC_WM <= EOS_NET_SIZE_BUF) { + bytes_r = eos_cell_pcm_read(hold_buf + 1 + hold_bytes_r, PCM_MIC_WM); + if (bytes_r < 0) { + ESP_LOGE(TAG, "*** I2S READ ERROR ***"); + break; + } + hold_bytes_r += bytes_r; } - if (1 + hold_bytes_r + PCM_MIC_WM <= EOS_NET_MTU) hold_bytes_r += eos_cell_pcm_read(hold_buf + 1 + hold_bytes_r, PCM_MIC_WM); + hold_cnt--; if (hold_cnt == 0) { eos_net_send(EOS_NET_MTYPE_CELL, hold_buf, hold_bytes_r + 1); - hold_bytes_r = 0; hold_buf = NULL; } } @@ -87,10 +106,16 @@ static void i2s_event_task(void *pvParameters) { xSemaphoreGive(mutex); if (buf) { - i2s_write(I2S_NUM_0, (const void *)buf, bytes_e, &bytes_w, portMAX_DELAY); + esp_err_t ret; + + ret = i2s_write(I2S_NUM_0, (const void *)buf, bytes_e, &bytes_w, 1000 / portTICK_RATE_MS); xSemaphoreTake(mutex, portMAX_DELAY); eos_bufq_push(&pcm_buf_q, buf); xSemaphoreGive(mutex); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "*** I2S WRITE ERROR ***"); + break; + } } break; } @@ -172,11 +197,12 @@ void eos_cell_pcm_init(void) { ssize_t eos_cell_pcm_read(unsigned char *data, size_t size) { static unsigned char buf[PCM_SIZE_BUF]; size_t bytes_r; + esp_err_t ret; int i; if (size > PCM_MIC_WM) return EOS_ERR; - esp_err_t ret = i2s_read(I2S_NUM_0, (void *)buf, size * 4, &bytes_r, portMAX_DELAY); + ret = i2s_read(I2S_NUM_0, (void *)buf, size * 4, &bytes_r, 1000 / portTICK_RATE_MS); if (ret != ESP_OK) return EOS_ERR; for (i=0; i<size/2; i++) { diff --git a/fw/esp32/components/eos/cell_pdp.c b/fw/esp32/components/eos/cell_pdp.c index fc4739a..d04b66b 100644 --- a/fw/esp32/components/eos/cell_pdp.c +++ b/fw/esp32/components/eos/cell_pdp.c @@ -13,16 +13,14 @@ void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t b case EOS_CELL_MTYPE_PDP_SET_USR: case EOS_CELL_MTYPE_PDP_SET_PWD: { char *arg; - size_t arg_len; buffer++; buf_len--; arg = (char *)buffer; - arg_len = strnlen(arg, buf_len); - if (arg_len == buf_len) break; - if (arg_len >= EOS_CELL_PDP_SIZE_ARG) break; + if (buf_len > EOS_CELL_PDP_SIZE_ARG) break; + buffer[buf_len] = '\0'; switch (mtype) { case EOS_CELL_MTYPE_PDP_SET_APN: { eos_ppp_set_apn(arg); @@ -66,7 +64,7 @@ void eos_cell_pdp_handler(unsigned char mtype, unsigned char *buffer, uint16_t b } } - eos_net_reply(EOS_NET_MTYPE_CELL, buffer, 1 + strlen(arg)); + eos_net_reply(EOS_NET_MTYPE_CELL, buffer, strlen(arg) + 1); break; } diff --git a/fw/esp32/components/eos/cell_sms.c b/fw/esp32/components/eos/cell_sms.c index ac710f9..f1f8b33 100644 --- a/fw/esp32/components/eos/cell_sms.c +++ b/fw/esp32/components/eos/cell_sms.c @@ -15,170 +15,213 @@ static const char *TAG = "EOS SMS"; -static char cmd[256]; +static char _pdu_in[2048]; +static char _pdu_out[2048]; -static char pdu[4096]; -static int pdu_len; +extern char *at_cmd_buf; -static uint8_t udh[GSM_UDH_SIZE]; -static int udh_len; +static ssize_t sms_encode(unsigned char *buffer, uint16_t buf_len, char *pdu, size_t pdu_size) { + ucp_t ch; + size_t pdu_len; + ssize_t rv; + int i; -static uint8_t msg[GSM_MSG_SIZE]; -static int msg_len; -static uint8_t msg_enc; + char *addr; + uint8_t addr_type; + size_t addr_len; + + uint8_t txt[GSM_UD_SIZE]; + size_t txt_len; + + uint16_t flags; + + if (buf_len < 2) return EOS_ERR_SIZE; + flags = buffer[0] << 8; + flags |= buffer[1]; + buffer += 2; + buf_len -= 2; + + if (buf_len < 2) return EOS_ERR_SIZE; + 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; -static char orig_addr[GSM_ADDR_SIZE]; -static int orig_addr_len; -static uint8_t orig_addr_type; + if (buf_len < 2 + addr_len) return EOS_ERR_SIZE; + buffer += 2 + addr_len; + buf_len -= 2 + addr_len; -static char smsc_addr[GSM_ADDR_SIZE]; -static int smsc_addr_len; -static uint8_t smsc_addr_type; + i = 0; + txt_len = 0; + while (i < buf_len) { + int _rv; + + if (buf_len - i < 4) { + _rv = utf8_len_str(buffer + i); + if (_rv < 0) return EOS_ERR; + if (buf_len - i < _rv) return EOS_ERR_SIZE; + } -static char smsc_timestamp[GSM_TS_SIZE]; + _rv = utf8_dec(buffer + i, &ch); + if (_rv < 0) return EOS_ERR; + if (ch >= 0xffff) return EOS_ERR; + i += _rv; -uint16_t flags; + _rv = gsm_ucs2_to_7bit((char *)txt + txt_len, sizeof(txt) - txt_len, ch); + if (_rv < 0) return EOS_ERR; + txt_len += _rv; + } + + if (pdu_size < 2) return EOS_ERR_SIZE; + pdu_putc(pdu, 0); -static int sms_decode(unsigned char *buf, uint16_t *_len) { - int i, j, rv; - uint16_t len = 0; - uint8_t smsc_info, smsc_info_len; + rv = gsm_sms_enc(pdu + 2, pdu_size - 2, addr, addr_len, addr_type, NULL, 0, txt, txt_len, GSM_ENC_7BIT, flags); + if (rv < 0) return EOS_ERR; + pdu_len = rv + 2; + + return pdu_len; +} - if (pdu_len < 2) return EOS_ERR; - smsc_info = pdu_getc(pdu); +static ssize_t sms_decode(char *pdu, size_t pdu_len, unsigned char *buf, uint16_t buf_size) { + uint16_t buf_len = 0; + ssize_t rv; + int i, j; + + char smsc_addr[GSM_ADDR_SIZE]; + size_t smsc_addr_len; + uint8_t smsc_info, smsc_info_len, smsc_addr_type; + + char orig_addr[GSM_ADDR_SIZE]; + size_t orig_addr_len; + uint8_t orig_addr_type; + + uint8_t udh[GSM_UDH_SIZE]; + size_t udh_len; + + uint8_t txt[GSM_UD_SIZE]; + size_t txt_len; + uint8_t txt_enc; + + char smsc_timestamp[GSM_TS_SIZE]; + uint16_t flags; + + if (pdu_len < 2) return EOS_ERR_SIZE; + rv = pdu_getc(pdu, &smsc_info); + if (rv < 0) return rv; smsc_info_len = 2 * (smsc_info + 1); - if (pdu_len < smsc_info_len) return EOS_ERR; + if (pdu_len < smsc_info_len) return EOS_ERR_SIZE; if (smsc_info > 1) { - pdu_putc((smsc_info - 1) * 2, pdu); + /* SMSC address - currently not used */ + pdu_putc(pdu, (smsc_info - 1) * 2); 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, orig_addr, &orig_addr_len, &orig_addr_type, udh, &udh_len, msg, &msg_len, smsc_timestamp, &msg_enc, &flags); - if (rv == GSM_ERR_NOT_SUPPORTED) ESP_LOGE(TAG, "Message not supported: %s", pdu); - if (rv < 0) return rv; - if (msg_enc == GSM_ENC_8BIT) return EOS_ERR; + rv = gsm_sms_dec(pdu + smsc_info_len, pdu_len - smsc_info_len, orig_addr, &orig_addr_len, &orig_addr_type, udh, &udh_len, txt, &txt_len, &txt_enc, smsc_timestamp, &flags); + if ((rv == GSM_ERR_NOTSUPPORTED) || (txt_enc == GSM_ENC_8BIT)) { + ESP_LOGE(TAG, "Message not supported: %s", pdu); + return EOS_ERR_NOTSUPPORTED; + } + if (rv < 0) return EOS_ERR; + if (buf_size < buf_len + 2) return EOS_ERR_SIZE; buf[0] = flags >> 8; buf[1] = flags; - len += 2; + buf_len += 2; - memcpy(buf + len, smsc_timestamp, GSM_TS_SIZE); - len += GSM_TS_SIZE; + if (buf_size < buf_len + GSM_TS_SIZE) return EOS_ERR_SIZE; + memcpy(buf + buf_len, smsc_timestamp, GSM_TS_SIZE); + buf_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; + if (buf_size < buf_len + 2) return EOS_ERR_SIZE; + buf[buf_len] = EOS_CELL_SMS_ADDRTYPE_ALPHA; + buf[buf_len + 1] = 0; + buf_len += 2; i = 0; j = 0; while (i < orig_addr_len) { uint16_t ch; + int _rv; - 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; + _rv = gsm_7bit_to_ucs2((char *)orig_addr + i, orig_addr_len - i, &ch); + if (_rv < 0) return EOS_ERR; + i += _rv; + + if (buf_size - buf_len - j < 4) { + _rv = utf8_len_ch(ch); + if (_rv < 0) return EOS_ERR; + if (buf_size - buf_len - j < _rv) return EOS_ERR_SIZE; + } + + _rv = utf8_enc(ch, buf + buf_len + j); + if (_rv < 0) return EOS_ERR; + j += _rv; } - buf[len - 1] = j; - len += j; + buf[buf_len - 1] = j; + buf_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; + if (buf_size < buf_len + 2) return EOS_ERR_SIZE; + buf[buf_len] = ((orig_addr_type & GSM_TON) == GSM_TON_INTERNATIONAL) ? EOS_CELL_SMS_ADDRTYPE_INTL : EOS_CELL_SMS_ADDRTYPE_OTHER; + buf[buf_len + 1] = orig_addr_len; + buf_len += 2; + + if (buf_size < buf_len + orig_addr_len) return EOS_ERR_SIZE; + memcpy(buf + buf_len, orig_addr, orig_addr_len); + buf_len += orig_addr_len; } i = 0; j = 0; - while (i < msg_len) { - utf32_t ch; + while (i < txt_len) { + ucp_t ch; + int _rv; - if (msg_enc == GSM_ENC_7BIT) { + if (txt_enc == GSM_ENC_7BIT) { uint16_t _ch; - rv = gsm_7bit_to_ucs2((char *)msg + i, msg_len - i, &_ch); + _rv = gsm_7bit_to_ucs2((char *)txt + i, txt_len - i, &_ch); + if (_rv < 0) return EOS_ERR; ch = _ch; } else { - if (((msg_len - i) < 4) && (utf16_len(msg + i) > 2)) { - rv = EOS_ERR; - } else { - rv = utf16_dec(msg + i, &ch); + if (txt_len - i < 2) return EOS_ERR_SIZE; + if (txt_len - i < 4) { + _rv = utf16_len_str(txt + i); + if (_rv < 0) return EOS_ERR; + if (txt_len - i < _rv) return EOS_ERR_SIZE; } + _rv = utf16_dec(txt + i, &ch); + if (_rv < 0) return EOS_ERR; } - if (rv < 0) return EOS_ERR; - i += rv; + i += _rv; - rv = utf8_enc(ch, buf + len + j); - if (rv < 0) return EOS_ERR; - j += rv; - } - buf[len + j] = '\0'; - len += j + 1; - *_len = len; - - return EOS_OK; -} - -static int sms_encode(unsigned char *buffer, uint16_t len) { - utf32_t ch; - int i, rv; - char *addr; - uint8_t addr_type; - int addr_len; - - if (len < 2) return EOS_ERR; - flags = buffer[0] << 8; - flags |= buffer[1]; - buffer += 2; - len -= 2; - - if (len < 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 (len < 2 + addr_len) return EOS_ERR; - buffer += 2 + addr_len; - len -= 2 + addr_len; - - i = 0; - msg_len = 0; - while (i < len) { - rv = utf8_dec(buffer + i, &ch); - if (rv < 0) return EOS_ERR; - if (ch >= 0xffff) return EOS_ERR; - i += rv; + if (buf_size - buf_len - j < 4) { + _rv = utf8_len_ch(ch); + if (_rv < 0) return EOS_ERR; + if (buf_size - buf_len - j < _rv) return EOS_ERR_SIZE; + } - rv = gsm_ucs2_to_7bit(ch, (char *)msg + msg_len, sizeof(msg) - msg_len); - if (rv < 0) return EOS_ERR; - msg_len += rv; + _rv = utf8_enc(ch, buf + buf_len + j); + if (_rv < 0) return EOS_ERR; + j += _rv; } + if (buf_size < buf_len + j + 1) return EOS_ERR_SIZE; + buf[buf_len + j] = '\0'; + buf_len += j + 1; - pdu_putc(0, pdu); - rv = gsm_sms_enc(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; + return buf_len; } void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { @@ -190,34 +233,40 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b case EOS_CELL_MTYPE_SMS_LIST: { if (buf_len < 1) return; - rv = snprintf(cmd, sizeof(cmd), "AT+CMGL=%d\r", buffer[0]); - if ((rv < 0) || (rv >= sizeof(cmd))) return; + rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CMGL=%d\r", buffer[0]); + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; rv = eos_modem_take(1000); if (rv) return; - at_cmd(cmd); + at_cmd(at_cmd_buf); do { unsigned char *buf; - uint16_t len; + uint16_t buf_len; + + char *pdu = _pdu_in; + size_t pdu_size = sizeof(_pdu_in); + size_t pdu_len; + ssize_t _rv; rv = at_expect("^\\+CMGL: [0-9]+,[0-9],.*,[0-9]+$", "^OK", 1000); if (rv) break; - rv = eos_modem_readln(pdu, sizeof(pdu), 1000); + rv = eos_modem_readln(pdu, pdu_size, 1000); if (rv) break; pdu_len = strlen(pdu); buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_LIST_ITEM; - rv = sms_decode(buf + 1, &len); - if (rv) { + _rv = sms_decode(pdu, pdu_len, buf + 1, EOS_NET_SIZE_BUF - 1); + if (_rv < 0) { eos_net_free(buf); continue; } - eos_net_send(EOS_NET_MTYPE_CELL, buf, len + 1); + buf_len = _rv; + eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1); } while (1); eos_modem_give(); @@ -227,16 +276,26 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b case EOS_CELL_MTYPE_SMS_MSG: { char b[4]; - rv = sms_encode(buffer, buf_len); - if (rv) return; + char *pdu = _pdu_in; + size_t pdu_size = sizeof(_pdu_in); + size_t pdu_len; + ssize_t _rv; + + _rv = sms_encode(buffer, buf_len, pdu, pdu_size); + if (_rv < 0) return; - rv = snprintf(cmd, sizeof(cmd), "AT+CMGS=%d\r", pdu_len / 2); - if ((rv < 0) || (rv >= sizeof(cmd))) return; + pdu_len = _rv; + if (pdu_size < pdu_len + 2) return; + pdu[pdu_len] = CTRL_Z; + pdu[pdu_len + 1] = '\0'; + + rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CMGS=%d\r", pdu_len / 2); + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; rv = eos_modem_take(1000); if (rv) return; - at_cmd(cmd); + at_cmd(at_cmd_buf); // wait for: '> ' (0d 0a 3e 20) eos_modem_read(b, 4, 1000); at_cmd(pdu); @@ -250,10 +309,16 @@ void eos_cell_sms_handler(unsigned char mtype, unsigned char *buffer, uint16_t b } static void sms_received_handler(char *urc, regmatch_t m[]) { + char cmd[32]; unsigned char *buf; - uint16_t len; + uint16_t buf_len; int ref, rv; + char *pdu = _pdu_out; + size_t pdu_size = sizeof(_pdu_out); + size_t pdu_len; + ssize_t _rv; + sscanf(urc + m[1].rm_so, "%d", &ref); rv = snprintf(cmd, sizeof(cmd), "AT+CMGR=%d\r", ref); @@ -264,7 +329,7 @@ static void sms_received_handler(char *urc, regmatch_t m[]) { rv = at_expect("^\\+CMGR: [0-9],.*,[0-9]+$", "^ERROR", 1000); if (rv) return; - rv = eos_modem_readln(pdu, sizeof(pdu), 1000); + rv = eos_modem_readln(pdu, pdu_size, 1000); if (rv) return; pdu_len = strlen(pdu); @@ -273,13 +338,14 @@ static void sms_received_handler(char *urc, regmatch_t m[]) { buf = eos_net_alloc(); buf[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG; - rv = sms_decode(buf + 1, &len); - if (rv) { + _rv = sms_decode(pdu, pdu_len, buf + 1, EOS_NET_SIZE_BUF - 1); + if (_rv < 0) { eos_net_free(buf); return; } - eos_net_send(EOS_NET_MTYPE_CELL, buf, len + 1); + buf_len = _rv; + eos_net_send(EOS_NET_MTYPE_CELL, buf, buf_len + 1); } void eos_cell_sms_init(void) { diff --git a/fw/esp32/components/eos/cell_ussd.c b/fw/esp32/components/eos/cell_ussd.c index 976fd51..375025f 100644 --- a/fw/esp32/components/eos/cell_ussd.c +++ b/fw/esp32/components/eos/cell_ussd.c @@ -11,8 +11,7 @@ static const char *TAG = "EOS USSD"; -static char cmd[256]; -static int cmd_len; +extern char *at_cmd_buf; void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { int rv; @@ -21,16 +20,16 @@ void eos_cell_ussd_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len--; switch (mtype) { case EOS_CELL_MTYPE_USSD_REQUEST: { - if (buf_len > EOS_CELL_MAX_USSD_STR) return; + if (buf_len > EOS_CELL_USSD_SIZE_REQ) return; buffer[buf_len] = '\0'; - cmd_len = snprintf(cmd, sizeof(cmd), "AT+CUSD=1,\"%s\",15\r", buffer); - if ((cmd_len < 0) || (cmd_len >= sizeof(cmd))) return; + rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "AT+CUSD=1,\"%s\",15\r", buffer); + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; rv = eos_modem_take(1000); if (rv) return; - at_cmd(cmd); + at_cmd(at_cmd_buf); rv = at_expect("^OK", "^ERROR", 1000); eos_modem_give(); @@ -56,11 +55,6 @@ static void ussd_reply_handler(char *urc, regmatch_t m[]) { uint16_t len; char *_buf; size_t _len; - regex_t re; - regmatch_t match[2]; - - rv = regcomp(&re, ".*(\",[0-9]+)$", REG_EXTENDED); - if (rv) return; sscanf(urc + m[1].rm_so, "%1d", &rep); @@ -69,15 +63,27 @@ static void ussd_reply_handler(char *urc, regmatch_t m[]) { buf[1] = rep; len = 2; - rv = EOS_OK; + if (m[2].rm_so == -1) { + eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + return; + } + _buf = (char *)buf + len; - strcpy(_buf, urc + m[2].rm_so); + _len = m[2].rm_eo - m[2].rm_so - 2; + if (_len > EOS_NET_SIZE_BUF - len) { + eos_net_free(buf); + return; + } + memcpy(_buf, urc + m[2].rm_so + 2, _len); + len += _len; + + rv = EOS_OK; do { - if (regexec(&re, _buf, 2, match, 0) == 0) { - ESP_LOGI(TAG, "MATCH:%ld %s", match[1].rm_so, _buf); - _buf[match[1].rm_so] = '\0'; - _len = strlen(_buf); - len += _len + 1; + char *end; + + end = strchr(_buf, '"'); + if (end) { + len += end - _buf; break; } else { _len = strlen(_buf); @@ -85,20 +91,19 @@ static void ussd_reply_handler(char *urc, regmatch_t m[]) { _buf += _len + 1; len += _len + 1; } - rv = eos_modem_readln(_buf, EOS_NET_MTU - len, 1000); + rv = eos_modem_readln(_buf, EOS_NET_SIZE_BUF - len, 1000); if (rv) break; } while (1); if (rv) { ESP_LOGE(TAG, "error"); eos_net_free(buf); - } else { - eos_net_send(EOS_NET_MTYPE_CELL, buf, len); + return; } - regfree(&re); + + eos_net_send(EOS_NET_MTYPE_CELL, buf, len); } void eos_cell_ussd_init(void) { - at_urc_insert("\\+CUSD: ([0-9]),\"(.*)", ussd_reply_handler, REG_EXTENDED); - -}
\ No newline at end of file + at_urc_insert("^\\+CUSD: ([0-9])(,\".*)?", ussd_reply_handler, REG_EXTENDED); +} diff --git a/fw/esp32/components/eos/cell_voice.c b/fw/esp32/components/eos/cell_voice.c index 7a9b823..2a7bb18 100644 --- a/fw/esp32/components/eos/cell_voice.c +++ b/fw/esp32/components/eos/cell_voice.c @@ -13,8 +13,7 @@ #include "at_cmd.h" #include "cell.h" -static char cmd[256]; -static int cmd_len; +extern char *at_cmd_buf; void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len) { int rv; @@ -23,17 +22,17 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t buf_len--; switch (mtype) { case EOS_CELL_MTYPE_VOICE_DIAL: { - if (buf_len > EOS_CELL_MAX_DIAL_STR) return; + if (buf_len > EOS_CELL_SIZE_PHNUM) return; buffer[buf_len] = '\0'; - cmd_len = snprintf(cmd, sizeof(cmd), "ATD%s;\r", buffer); - if ((cmd_len < 0) || (cmd_len >= sizeof(cmd))) return; + rv = snprintf(at_cmd_buf, AT_SIZE_CMD_BUF, "ATD%s;\r", buffer); + if ((rv < 0) || (rv >= AT_SIZE_CMD_BUF)) return; rv = eos_modem_take(1000); if (rv) return; - at_cmd(cmd); - rv = at_expect("^OK", "^ERROR", 1000); + at_cmd(at_cmd_buf); + rv = at_expect("^OK", "^(ERROR|\\+CME ERROR: [0-9]+)", 1000); eos_modem_give(); eos_cell_pcm_start(); @@ -45,7 +44,7 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t if (rv) return; at_cmd("ATA\r"); - rv = at_expect("^OK", "^NO CARRIER", 1000); + // Response will be picked up by urc handler eos_modem_give(); eos_cell_pcm_start(); @@ -59,7 +58,7 @@ void eos_cell_voice_handler(unsigned char mtype, unsigned char *buffer, uint16_t if (rv) return; at_cmd("AT+CHUP\r"); - rv = at_expect("^OK", "^ERROR", 1000); + // Response will be picked up by urc handler eos_modem_give(); break; @@ -87,7 +86,7 @@ static void ring_handler(char *urc, regmatch_t m[]) { regoff_t num_len; num_len = match[1].rm_eo - match[1].rm_so; - if (num_len > EOS_CELL_MAX_DIAL_STR) { + if (num_len > EOS_CELL_SIZE_PHNUM) { eos_net_free(buf); return; } @@ -124,10 +123,6 @@ static void miss_handler(char *urc, regmatch_t m[]) { static void call_begin_handler(char *urc, regmatch_t m[]) { unsigned char *buf; - buf = eos_net_alloc(); - buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BEGIN; - eos_net_send(EOS_NET_MTYPE_CELL, buf, 1); - vTaskDelay(100 / portTICK_PERIOD_MS); at_cmd("AT+CECH=0x0000\r"); at_expect("^OK", "^ERROR", 1000); @@ -144,6 +139,10 @@ static void call_begin_handler(char *urc, regmatch_t m[]) { at_cmd("AT+CECRX=0\r"); at_expect("^OK", "^ERROR", 1000); */ + + buf = eos_net_alloc(); + buf[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_BEGIN; + eos_net_send(EOS_NET_MTYPE_CELL, buf, 1); } static void call_end_handler(char *urc, regmatch_t m[]) { diff --git a/fw/esp32/components/eos/gsm.c b/fw/esp32/components/eos/gsm.c index 920e121..551dc2c 100644 --- a/fw/esp32/components/eos/gsm.c +++ b/fw/esp32/components/eos/gsm.c @@ -1,36 +1,30 @@ -#include <stdlib.h> -#include <string.h> #include <stdio.h> #include "gsm.h" #define DIVC(x,y) ((x) / (y) + ((x) % (y) != 0)) -uint8_t pdu_getc(char *pdu) { - int ch; - - sscanf(pdu, "%2X", &ch); - return ch; -} - -void pdu_putc(uint8_t ch, char *pdu) { +size_t pdu_putc(char *pdu, uint8_t ch) { char b[3]; sprintf(b, "%.2X", ch); *pdu = b[0]; *(pdu + 1) = b[1]; + + return 2; } -void pdu_gets(char *pdu, uint8_t *s, int s_len) { - int i, ch; +ssize_t pdu_getc(char *pdu, uint8_t *ch) { + int rv, _ch; - for (i=0; i<s_len; i++) { - sscanf(pdu + 2 * i, "%2X", &ch); - s[i] = ch; - } + rv = sscanf(pdu, "%2X", &_ch); + if (rv != 1) return GSM_ERR; + + *ch = _ch; + return 2; } -void pdu_puts(uint8_t *s, int s_len, char *pdu) { +size_t pdu_puts(char *pdu, uint8_t *s, size_t s_len) { int i; char b[3]; @@ -39,6 +33,108 @@ void pdu_puts(uint8_t *s, int s_len, char *pdu) { *(pdu + 2 * i) = b[0]; *(pdu + 2 * i + 1) = b[1]; } + + return s_len * 2; +} + +ssize_t pdu_gets(char *pdu, uint8_t *s, size_t s_len) { + int i, rv, _ch; + + for (i=0; i<s_len; i++) { + rv = sscanf(pdu + 2 * i, "%2X", &_ch); + if (rv != 1) return GSM_ERR; + s[i] = _ch; + } + + return s_len * 2; +} + +size_t pdu_7bit_enc(char *pdu, char *text, size_t text_len, int padb) { + uint8_t carry = 0; + size_t pdu_len = 0; + int i = 0, shc = 0; + + if (!text_len) return 0; + + if (padb) { + shc = 7 - padb; + } else { + carry = *text; + i++; + } + + while (i < text_len) { + pdu_putc(pdu + pdu_len, carry | (*(text + i) << (7 - shc))); + pdu_len += 2; + + shc++; + shc = shc % 7; + if (!shc) { + i++; + if (i == text_len) return pdu_len; + } + + carry = *(text + i) >> shc; + i++; + } + pdu_putc(pdu + pdu_len, carry); + pdu_len += 2; + + return pdu_len; +} + +ssize_t pdu_7bit_dec(char *pdu, char *text, size_t text_len, int padb) { + uint8_t ch; + uint8_t carry = 0; + int i = 0, shc = 0; + size_t pdu_len = 0; + ssize_t rv; + + if (!text_len) return 0; + + if (padb) { + rv = pdu_getc(pdu, &ch); + if (rv < 0) return rv; + pdu_len += 2; + + if (padb == 1) { + *text = ch >> 1; + i++; + } else { + carry = ch >> padb; + shc = 8 - padb; + } + } + + while (i < text_len) { + rv = pdu_getc(pdu + pdu_len, &ch); + if (rv < 0) return rv; + pdu_len += 2; + + *(text + i) = ((ch << shc) | carry) & 0x7f; + carry = ch >> (7 - shc); + i++; + + shc++; + shc = shc % 7; + if (!shc && (i < text_len)) { + *(text + i) = carry; + carry = 0; + i++; + } + } + + return pdu_len; +} + +void gsm_dcs_enc(uint8_t enc, uint16_t flags, uint8_t *dcs) { + *dcs = enc; + if (flags & GSM_FLAG_CLASS) { + *dcs |= GSM_DCS_CLASS_IND; + *dcs |= (flags >> 8) & GSM_DCS_CLASS; + } + if (flags & GSM_FLAG_COMPRESS) *dcs |= GSM_DCS_COMPRESS_IND; + if (flags & GSM_FLAG_DELETE) *dcs |= GSM_DCS_DELETE_IND; } void gsm_dcs_dec(uint8_t dcs, uint8_t *enc, uint16_t *flags) { @@ -78,17 +174,7 @@ void gsm_dcs_dec(uint8_t dcs, uint8_t *enc, uint16_t *flags) { } } -void gsm_dcs_enc(uint8_t enc, uint16_t flags, uint8_t *dcs) { - *dcs = enc; - if (flags & GSM_FLAG_CLASS) { - *dcs |= GSM_DCS_CLASS_IND; - *dcs |= (flags >> 8) & GSM_DCS_CLASS; - } - if (flags & GSM_FLAG_COMPRESS) *dcs |= GSM_DCS_COMPRESS_IND; - if (flags & GSM_FLAG_DELETE) *dcs |= GSM_DCS_DELETE_IND; -} - -int gsm_ts_enc(char *ts, char *pdu, int pdu_size) { +ssize_t gsm_ts_enc(char *pdu, size_t pdu_size, char *ts) { uint8_t tz; int tz_hh, tz_mm; @@ -117,13 +203,14 @@ int gsm_ts_enc(char *ts, char *pdu, int pdu_size) { tz = (tz / 10) | ((tz % 10) << 4); if (ts[19] == '-') tz |= 0x08; - pdu_putc(tz, pdu + 12); + pdu_putc(pdu + 12, tz); return 14; } -int gsm_ts_dec(char *pdu, int pdu_len, char *ts) { +ssize_t gsm_ts_dec(char *pdu, size_t pdu_len, char *ts) { uint8_t tz; + ssize_t rv; if (pdu_len < 14) return GSM_ERR_SIZE; @@ -147,7 +234,9 @@ int gsm_ts_dec(char *pdu, int pdu_len, char *ts) { ts[17] = pdu[11]; // ss ts[18] = pdu[10]; - tz = pdu_getc(pdu + 12); + rv = pdu_getc(pdu + 12, &tz); + if (rv < 0) return rv; + if (tz & 0x08) { ts[19] = '-'; tz = tz & ~0x08; @@ -160,80 +249,8 @@ int gsm_ts_dec(char *pdu, int pdu_len, char *ts) { return 14; } -int gsm_7bit_enc(char *text, int text_len, char *pdu, int padb) { - uint8_t carry = 0; - int i = 0, pdu_len = 0, shc = 0; - - if (!text_len) return 0; - - if (padb) { - shc = 7 - padb; - } else { - carry = *text; - i++; - } - - while (i < text_len) { - pdu_putc(carry | (*(text + i) << (7 - shc)), pdu + pdu_len); - pdu_len += 2; - - shc++; - shc = shc % 7; - if (!shc) { - i++; - if (i == text_len) return pdu_len; - } - - carry = *(text + i) >> shc; - i++; - } - pdu_putc(carry, pdu + pdu_len); - pdu_len += 2; - - return pdu_len; -} - -int gsm_7bit_dec(char *pdu, char *text, int text_len, int padb) { - uint8_t ch; - uint8_t carry = 0; - int i = 0, pdu_len = 0, shc = 0; - - if (!text_len) return 0; - - if (padb) { - ch = pdu_getc(pdu); - pdu_len += 2; - if (padb == 1) { - *text = ch >> 1; - i++; - } else { - carry = ch >> padb; - shc = 8 - padb; - } - } - - while (i < text_len) { - ch = pdu_getc(pdu + pdu_len); - pdu_len += 2; - - *(text + i) = ((ch << shc) | carry) & 0x7f; - carry = ch >> (7 - shc); - i++; - - shc++; - shc = shc % 7; - if (!shc && (i < text_len)) { - *(text + i) = carry; - carry = 0; - i++; - } - } - - return pdu_len; -} - -int gsm_addr_enc(char *addr, int addr_len, uint8_t addr_type, char *pdu, int pdu_size) { - int _pdu_len; +ssize_t gsm_addr_enc(char *pdu, size_t pdu_size, char *addr, size_t addr_len, uint8_t addr_type) { + size_t _pdu_len; addr_type |= GSM_EXT; @@ -243,17 +260,17 @@ int gsm_addr_enc(char *addr, int addr_len, uint8_t addr_type, char *pdu, int pdu _pdu_len = 4 + DIVC(_addr_len, 2) * 2; if (pdu_size < _pdu_len) return GSM_ERR_SIZE; - pdu_putc(_addr_len, pdu); - pdu_putc(addr_type, pdu + 2); - gsm_7bit_enc(addr, addr_len, pdu, 0); + pdu_putc(pdu, _addr_len); + pdu_putc(pdu + 2, addr_type); + pdu_7bit_enc(pdu + 4, addr, addr_len, 0); } else { int i; _pdu_len = 4 + DIVC(addr_len, 2) * 2; if (pdu_size < _pdu_len) return GSM_ERR_SIZE; - pdu_putc(addr_len, pdu); - pdu_putc(addr_type, pdu + 2); + pdu_putc(pdu, addr_len); + pdu_putc(pdu + 2, addr_type); for (i=0; i<addr_len / 2; i++) { pdu[4 + 2 * i] = addr[2 * i + 1]; pdu[4 + 2 * i + 1] = addr[2 * i]; @@ -267,16 +284,22 @@ 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_len, uint8_t *addr_type) { - int _pdu_len; +ssize_t gsm_addr_dec(char *pdu, size_t pdu_len, char *addr, size_t *addr_len, uint8_t *addr_type) { + uint8_t pdu_ch; + size_t _pdu_len; + ssize_t rv; if (pdu_len < 4) return GSM_ERR_SIZE; - *addr_len = pdu_getc(pdu); - *addr_type = pdu_getc(pdu + 2); + rv = pdu_getc(pdu, &pdu_ch); + if (rv < 0) return rv; + rv = pdu_getc(pdu + 2, addr_type); + if (rv < 0) return rv; + + *addr_len = pdu_ch; if (*addr_len > GSM_ADDR_SIZE) return GSM_ERR_SIZE; - if (!(*addr_type & GSM_EXT)) return GSM_ERR; + if (!(*addr_type & GSM_EXT)) return GSM_ERR_NOTSUPPORTED; _pdu_len = 4 + DIVC(*addr_len, 2) * 2; if (pdu_len < _pdu_len) return GSM_ERR_SIZE; @@ -284,7 +307,8 @@ int gsm_addr_dec(char *pdu, int pdu_len, char *addr, int *addr_len, uint8_t *add if ((*addr_type & GSM_TON) == GSM_TON_ALPHANUMERIC) { *addr_len = (*addr_len * 4) / 7; - gsm_7bit_dec(pdu + 4, addr, *addr_len, 0); + rv = pdu_7bit_dec(pdu + 4, addr, *addr_len, 0); + if (rv < 0) return rv; } else { int i; @@ -300,13 +324,14 @@ int gsm_addr_dec(char *pdu, int pdu_len, char *addr, int *addr_len, uint8_t *add return _pdu_len; } -int gsm_sms_enc(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 rv, _pdu_len = 0; +ssize_t gsm_sms_enc(char *pdu, size_t pdu_size, char *addr, size_t addr_len, uint8_t addr_type, uint8_t *udh, size_t udh_len, uint8_t *txt, size_t txt_len, uint8_t enc, uint16_t flags) { + size_t _pdu_len = 0; uint8_t mti; uint8_t mr; uint8_t pid; uint8_t dcs; uint8_t udl; + ssize_t rv; mti = GSM_MTI_SUBMIT; if (udh_len) mti |= GSM_UDHI; @@ -315,11 +340,11 @@ int gsm_sms_enc(char *addr, int addr_len, uint8_t addr_type, uint8_t *udh, int u mr = 0; if (pdu_size < 4) return GSM_ERR_SIZE; - pdu_putc(mti, pdu); - pdu_putc(mr, pdu + 2); + pdu_putc(pdu, mti); + pdu_putc(pdu + 2, mr); _pdu_len += 4; - rv = gsm_addr_enc(addr, addr_len, addr_type, pdu + _pdu_len, pdu_size - _pdu_len); + rv = gsm_addr_enc(pdu + _pdu_len, pdu_size - _pdu_len, addr, addr_len, addr_type); if (rv < 0) return rv; _pdu_len += rv; @@ -329,10 +354,10 @@ int gsm_sms_enc(char *addr, int addr_len, uint8_t addr_type, uint8_t *udh, int u } else { pid = GSM_PID_DEFAULT; } - pid = 37; - pdu_putc(pid, pdu + _pdu_len); gsm_dcs_enc(enc, flags, &dcs); - pdu_putc(dcs, pdu + _pdu_len + 2); + + pdu_putc(pdu + _pdu_len, pid); + pdu_putc(pdu + _pdu_len + 2, dcs); _pdu_len += 4; if (enc == GSM_ENC_7BIT) { @@ -343,55 +368,57 @@ int gsm_sms_enc(char *addr, int addr_len, uint8_t addr_type, uint8_t *udh, int u udh_blen = 8 * (udh_len + 1); padb = DIVC(udh_blen, 7) * 7 - udh_blen; } - udl = DIVC(udh_blen, 7) + msg_len; + udl = DIVC(udh_blen, 7) + txt_len; if (pdu_size < _pdu_len + (DIVC(udl * 7, 8) + 1) * 2) return GSM_ERR_SIZE; - pdu_putc(udl, pdu + _pdu_len); + pdu_putc(pdu + _pdu_len, udl); _pdu_len += 2; if (udh_len) { - pdu_putc(udh_len, pdu + _pdu_len); - pdu_puts(udh, udh_len, pdu + _pdu_len + 2); + pdu_putc(pdu + _pdu_len, udh_len); + pdu_puts(pdu + _pdu_len + 2, udh, udh_len); _pdu_len += (udh_len + 1) * 2; } - rv = gsm_7bit_enc((char *)msg, msg_len, pdu + _pdu_len, padb); + rv = pdu_7bit_enc(pdu + _pdu_len, (char *)txt, txt_len, padb); if (rv < 0) return rv; _pdu_len += rv; } else { - udl = msg_len + (udh_len ? udh_len + 1 : 0); + udl = txt_len + (udh_len ? udh_len + 1 : 0); if (pdu_size < _pdu_len + (udl + 1) * 2) return GSM_ERR_SIZE; - pdu_putc(udl, pdu + _pdu_len); + pdu_putc(pdu + _pdu_len, udl); _pdu_len += 2; if (udh_len) { - pdu_putc(udh_len, pdu + _pdu_len); - pdu_puts(udh, udh_len, pdu + _pdu_len + 2); + pdu_putc(pdu + _pdu_len, udh_len); + pdu_puts(pdu + _pdu_len + 2, udh, udh_len); _pdu_len += (udh_len + 1) * 2; } - pdu_puts(msg, msg_len, pdu + _pdu_len); - _pdu_len += msg_len * 2; + pdu_puts(pdu + _pdu_len, txt, txt_len); + _pdu_len += txt_len * 2; } return _pdu_len; } -int gsm_sms_dec(char *pdu, int pdu_len, 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; +ssize_t gsm_sms_dec(char *pdu, size_t pdu_len, char *addr, size_t *addr_len, uint8_t *addr_type, uint8_t *udh, size_t *udh_len, uint8_t *txt, size_t *txt_len, uint8_t *enc, char *ts, uint16_t *flags) { + size_t _pdu_len = 0; uint8_t mti; uint8_t pid; uint8_t dcs; uint8_t udl; + ssize_t rv; *enc = 0xff; *flags = 0; if (pdu_len < 2) return GSM_ERR_SIZE; - mti = pdu_getc(pdu); + rv = pdu_getc(pdu, &mti); + if (rv < 0) return rv; _pdu_len += 2; - if ((mti & GSM_MTI) != GSM_MTI_DELIVER) return GSM_ERR_NOT_SUPPORTED; + if ((mti & GSM_MTI) != GSM_MTI_DELIVER) return GSM_ERR_NOTSUPPORTED; if (mti & GSM_SRI) *flags |= GSM_FLAG_STATUS_REPORT; if (mti & GSM_RP) *flags |= GSM_FLAG_REPLY_PATH; @@ -400,13 +427,15 @@ int gsm_sms_dec(char *pdu, int pdu_len, char *addr, int *addr_len, uint8_t *addr _pdu_len += rv; if (pdu_len < _pdu_len + 4) return GSM_ERR_SIZE; - pid = pdu_getc(pdu + _pdu_len); + rv = pdu_getc(pdu + _pdu_len, &pid); + if (rv < 0) return rv; if (pid == GSM_PID_TYPE0) { *flags |= GSM_FLAG_TYPE0; } else if (pid != GSM_PID_DEFAULT) { - return GSM_ERR_NOT_SUPPORTED; + return GSM_ERR_NOTSUPPORTED; } - dcs = pdu_getc(pdu + _pdu_len + 2); + rv = pdu_getc(pdu + _pdu_len + 2, &dcs); + if (rv < 0) return rv; gsm_dcs_dec(dcs, enc, flags); _pdu_len += 4; @@ -415,7 +444,8 @@ int gsm_sms_dec(char *pdu, int pdu_len, char *addr, int *addr_len, uint8_t *addr _pdu_len += rv; if (pdu_len < _pdu_len + 2) return GSM_ERR_SIZE; - udl = pdu_getc(pdu + _pdu_len); + rv = pdu_getc(pdu + _pdu_len, &udl); + if (rv < 0) return rv; _pdu_len += 2; if ((mti & GSM_UDHI) && (udl == 0)) return GSM_ERR; @@ -428,46 +458,58 @@ int gsm_sms_dec(char *pdu, int pdu_len, char *addr, int *addr_len, uint8_t *addr 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); + uint8_t pdu_ch; + + rv = pdu_getc(pdu + _pdu_len, &pdu_ch); + if (rv < 0) return rv; + + *udh_len = pdu_ch; udh_blen = 8 * (*udh_len + 1); padb = DIVC(udh_blen, 7) * 7 - udh_blen; if (udl * 7 < udh_blen) return GSM_ERR; if (*udh_len > GSM_UDH_SIZE) return GSM_ERR_SIZE; - pdu_gets(pdu + _pdu_len + 2, udh, *udh_len); + rv = pdu_gets(pdu + _pdu_len + 2, udh, *udh_len); + if (rv < 0) return rv; _pdu_len += (*udh_len + 1) * 2; } else { *udh_len = 0; } - *msg_len = udl - DIVC(udh_blen, 7); - if (*msg_len > GSM_UD_SIZE) return GSM_ERR_SIZE; + *txt_len = udl - DIVC(udh_blen, 7); + if (*txt_len > GSM_UD_SIZE) return GSM_ERR_SIZE; - rv = gsm_7bit_dec(pdu + _pdu_len, (char *)msg, *msg_len, padb); + rv = pdu_7bit_dec(pdu + _pdu_len, (char *)txt, *txt_len, padb); if (rv < 0) return rv; _pdu_len += rv; } else { if (pdu_len < _pdu_len + udl * 2) return GSM_ERR_SIZE; if (mti & GSM_UDHI) { - *udh_len = pdu_getc(pdu + _pdu_len); + uint8_t pdu_ch; + rv = pdu_getc(pdu + _pdu_len, &pdu_ch); + if (rv < 0) return rv; + + *udh_len = pdu_ch; if (udl < *udh_len + 1) return GSM_ERR; if (*udh_len > GSM_UDH_SIZE) return GSM_ERR_SIZE; - pdu_gets(pdu + _pdu_len + 2, udh, *udh_len); + rv = pdu_gets(pdu + _pdu_len + 2, udh, *udh_len); + if (rv < 0) return rv; _pdu_len += (*udh_len + 1) * 2; } else { *udh_len = 0; } - *msg_len = udl - (*udh_len ? *udh_len + 1 : 0); - if (*msg_len > GSM_UD_SIZE) return GSM_ERR_SIZE; - if ((*enc == GSM_ENC_UCS2) && ((*msg_len % 2) != 0)) return GSM_ERR; + *txt_len = udl - (*udh_len ? *udh_len + 1 : 0); + if (*txt_len > GSM_UD_SIZE) return GSM_ERR_SIZE; + if ((*enc == GSM_ENC_UCS2) && ((*txt_len % 2) != 0)) return GSM_ERR; - pdu_gets(pdu + _pdu_len, msg, *msg_len); - _pdu_len += *msg_len * 2; + rv = pdu_gets(pdu + _pdu_len, txt, *txt_len); + if (rv < 0) return rv; + _pdu_len += *txt_len * 2; } return _pdu_len; diff --git a/fw/esp32/components/eos/gsm_cp.c b/fw/esp32/components/eos/gsm_cp.c index 508aa54..5478a8f 100644 --- a/fw/esp32/components/eos/gsm_cp.c +++ b/fw/esp32/components/eos/gsm_cp.c @@ -1,5 +1,3 @@ -#include <stdint.h> - #include "gsm.h" #define UCS2_SUPL_SIZE 11 @@ -60,9 +58,9 @@ static const uint16_t ucs2_to_gsm7_supl[UCS2_SUPL_SIZE][2] = { {0x20ac, 0x1b65} }; -int gsm_ucs2_to_7bit(uint16_t ucs2, char *gsm7, int gsm7_size) { +int gsm_ucs2_to_7bit(char *gsm7, size_t gsm7_size, uint16_t ucs2) { uint16_t ch = 0xffff; - int ret = 0; + int rv = 0; if (gsm7_size < 1) return GSM_ERR_SIZE; @@ -83,28 +81,28 @@ int gsm_ucs2_to_7bit(uint16_t ucs2, char *gsm7, int gsm7_size) { if (gsm7_size < 2) return GSM_ERR_SIZE; *gsm7 = 0x1b; gsm7++; - ret++; + rv++; } *gsm7 = ch & 0x7f; - ret++; + rv++; - return ret; + return rv; } -int gsm_7bit_to_ucs2(char *gsm7, int gsm7_len, uint16_t *ucs2) { - int ret; +int gsm_7bit_to_ucs2(char *gsm7, size_t gsm7_len, uint16_t *ucs2) { + int rv; if (gsm7_len < 1) return GSM_ERR_SIZE; if (*gsm7 != 0x1b) { *ucs2 = gsm7_to_ucs2[*gsm7 & 0x7f]; - ret = 1; + rv = 1; } else { if (gsm7_len < 2) return GSM_ERR_SIZE; gsm7++; - ret = 2; + rv = 2; *ucs2 = gsm7e_to_ucs2[*gsm7 & 0x7f]; } if (*ucs2 == 0xffff) return GSM_ERR; - return ret; + return rv; } diff --git a/fw/esp32/components/eos/include/at_cmd.h b/fw/esp32/components/eos/include/at_cmd.h index 2d0813e..9dd355b 100644 --- a/fw/esp32/components/eos/include/at_cmd.h +++ b/fw/esp32/components/eos/include/at_cmd.h @@ -6,6 +6,7 @@ #define AT_SIZE_PATTERN 64 #define AT_SIZE_URC_LIST 32 +#define AT_SIZE_CMD_BUF 256 typedef void (*at_urc_cb_t) (char *, regmatch_t[]); diff --git a/fw/esp32/components/eos/include/cell.h b/fw/esp32/components/eos/include/cell.h index af2dda8..cb9f49c 100644 --- a/fw/esp32/components/eos/include/cell.h +++ b/fw/esp32/components/eos/include/cell.h @@ -55,19 +55,24 @@ #define EOS_CELL_SMS_ADDRTYPE_ALPHA 2 #define EOS_CELL_SMS_ADDRTYPE_OTHER 3 -#define EOS_CELL_PDP_SIZE_APN 64 -#define EOS_CELL_PDP_SIZE_USR 64 -#define EOS_CELL_PDP_SIZE_PWD 64 -#define EOS_CELL_PDP_SIZE_ARG 64 +#define EOS_CELL_SIZE_PHNUM 16 + +#define EOS_CELL_SMS_SIZE_ADDR 20 +#define EOS_CELL_SMS_SIZE_TS 25 +#define EOS_CELL_SMS_SIZE_TXT 160 + +#define EOS_CELL_USSD_SIZE_REQ 128 + +#define EOS_CELL_PDP_SIZE_APN 63 +#define EOS_CELL_PDP_SIZE_USR 63 +#define EOS_CELL_PDP_SIZE_PWD 63 +#define EOS_CELL_PDP_SIZE_ARG 63 #define EOS_CELL_UART_MODE_NONE 0 #define EOS_CELL_UART_MODE_ATCMD 1 #define EOS_CELL_UART_MODE_PPP 2 #define EOS_CELL_UART_MODE_RELAY 3 -#define EOS_CELL_MAX_USSD_STR 128 -#define EOS_CELL_MAX_DIAL_STR 16 - #define EOS_CELL_UART_SIZE_BUF 1024 void eos_cell_init(void); diff --git a/fw/esp32/components/eos/include/eos.h b/fw/esp32/components/eos/include/eos.h index 6f420ea..bc9dc51 100644 --- a/fw/esp32/components/eos/include/eos.h +++ b/fw/esp32/components/eos/include/eos.h @@ -3,9 +3,13 @@ #define EOS_ERR_TIMEOUT -2 #define EOS_ERR_BUSY -3 -#define EOS_ERR_FULL -10 -#define EOS_ERR_EMPTY -11 -#define EOS_ERR_NOTFOUND -12 +#define EOS_ERR_SIZE -10 +#define EOS_ERR_FULL -11 +#define EOS_ERR_EMPTY -12 +#define EOS_ERR_NOTFOUND -13 +#define EOS_ERR_NOTSUPPORTED -14 + +#define EOS_ERR_NOMEM -100 #define EOS_TASK_PRIORITY_NET_XCHG 1 #define EOS_TASK_PRIORITY_APP_XCHG 1 diff --git a/fw/esp32/components/eos/include/gsm.h b/fw/esp32/components/eos/include/gsm.h index 7864b09..eb893d6 100644 --- a/fw/esp32/components/eos/include/gsm.h +++ b/fw/esp32/components/eos/include/gsm.h @@ -1,12 +1,14 @@ +#include <sys/types.h> +#include <stdint.h> + #define GSM_OK 0 #define GSM_ERR -1 #define GSM_ERR_SIZE -10 -#define GSM_ERR_NOT_SUPPORTED -11 +#define GSM_ERR_NOTSUPPORTED -11 #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 */ @@ -124,16 +126,21 @@ #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(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, 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); +size_t pdu_putc(char *pdu, uint8_t ch); +ssize_t pdu_getc(char *pdu, uint8_t *ch); +size_t pdu_puts(char *pdu, uint8_t *s, size_t s_len); +ssize_t pdu_gets(char *pdu, uint8_t *s, size_t s_len); +size_t pdu_7bit_enc(char *pdu, char *text, size_t text_len, int padb); +ssize_t pdu_7bit_dec(char *pdu, char *text, size_t text_len, int padb); + +void gsm_dcs_enc(uint8_t enc, uint16_t flags, uint8_t *dcs); +void gsm_dcs_dec(uint8_t dcs, uint8_t *enc, uint16_t *flags); +ssize_t gsm_ts_enc(char *pdu, size_t pdu_size, char *ts); +ssize_t gsm_ts_dec(char *pdu, size_t pdu_len, char *ts); +int gsm_addr_enc(char *pdu, size_t pdu_size, char *addr, size_t addr_len, uint8_t addr_type); +int gsm_addr_dec(char *pdu, size_t pdu_len, char *addr, size_t *addr_len, uint8_t *addr_type); +int gsm_sms_enc(char *pdu, size_t pdu_size, char *addr, size_t addr_len, uint8_t addr_type, uint8_t *udh, size_t udh_len, uint8_t *txt, size_t txt_len, uint8_t enc, uint16_t flags); +int gsm_sms_dec(char *pdu, size_t pdu_len, char *addr, size_t *addr_len, uint8_t *addr_type, uint8_t *udh, size_t *udh_len, uint8_t *txt, size_t *txt_len, uint8_t *enc, char *ts, uint16_t *flags); + +int gsm_ucs2_to_7bit(char *gsm7, size_t gsm7_size, uint16_t ucs2); +int gsm_7bit_to_ucs2(char *gsm7, size_t gsm7_len, uint16_t *ucs2); |