From ec892bf2e7620fb58e635b900ab4a0e44e3488bd Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 4 Sep 2024 21:06:23 +0200 Subject: cellular modem driver fix --- fw/fe310/eos/net/cell.c | 203 ++++++++++++++++++++++++++++++++++++------------ fw/fe310/eos/net/cell.h | 35 ++++++--- 2 files changed, 178 insertions(+), 60 deletions(-) (limited to 'fw') diff --git a/fw/fe310/eos/net/cell.c b/fw/fe310/eos/net/cell.c index b560f52..96216ba 100644 --- a/fw/fe310/eos/net/cell.c +++ b/fw/fe310/eos/net/cell.c @@ -8,8 +8,6 @@ #include "cell.h" -#define GSM_TS_SIZE 25 - static eos_evt_handler_t evt_handler[EOS_CELL_MAX_MTYPE]; static void cell_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { @@ -62,11 +60,11 @@ int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, if (buffer[0] != (EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS)) return EOS_ERR_NET; buffer++; - len -= 1; + len--; *status = buffer[0]; buffer++; - len -= 1; + len--; if (*status == EOS_CELL_STATUS_PPP) { if (len < 1) return EOS_ERR_SIZE; @@ -148,7 +146,7 @@ int eos_cell_voice_dial(char *num, unsigned char *buffer, int sync) { size_t num_len; num_len = strlen(num); - if (num_len > EOS_CELL_MAX_DIAL_STR) return EOS_ERR_SIZE; + if (num_len > EOS_CELL_SIZE_PHNUM) return EOS_ERR_SIZE; if (buffer == NULL) { buffer = eos_net_alloc(); @@ -157,7 +155,7 @@ int eos_cell_voice_dial(char *num, unsigned char *buffer, int sync) { async = !sync; } buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_DIAL; - strcpy(buffer + 1, num); + memcpy(buffer + 1, num, num_len); return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1 + num_len, async, 1); } @@ -196,15 +194,15 @@ unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset) { return buffer + *offset; } -int eos_cell_sms_send(char *num, char *text, unsigned char *buffer, int sync) { +int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync) { int async; - size_t num_len, text_len; + size_t addr_len, txt_len; uint16_t len; - num_len = strlen(num); - text_len = strlen(text); - if (num_len > EOS_CELL_MAX_DIAL_STR) return EOS_ERR_SIZE; - if (text_len > EOS_CELL_MAX_SMS_TEXT) return EOS_ERR_SIZE; + addr_len = strlen(addr); + txt_len = strlen(txt); + if (addr_len > EOS_CELL_SMS_SIZE_ADDR) return EOS_ERR_SIZE; + if (txt_len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE; if (buffer == NULL) { buffer = eos_net_alloc(); @@ -215,63 +213,168 @@ int eos_cell_sms_send(char *num, char *text, unsigned char *buffer, int sync) { buffer[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG; buffer[1] = 0; buffer[2] = 0; - if (*num == '+') { + if (*addr == '+') { buffer[3] = EOS_CELL_SMS_ADDRTYPE_INTL; - num++; - num_len--; + addr++; + addr_len--; } else { buffer[3] = EOS_CELL_SMS_ADDRTYPE_OTHER; } - buffer[4] = num_len; + buffer[4] = addr_len; len = 5; - strcpy(buffer + len, num); - len += num_len; - strcpy(buffer + len, text); - len += text_len; + memcpy(buffer + len, addr, addr_len); + len += addr_len; + memcpy(buffer + len, txt, txt_len); + len += txt_len; return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, len, async, 1); } -int eos_cell_sms_recv(unsigned char *buffer, uint16_t len, char *num, uint16_t num_size, char *text, uint16_t text_size) { - char *_num, *_text; - uint16_t _num_len, _text_len; +int _eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len) { + uint16_t _addr_len; + + if (len < 4 + EOS_CELL_SMS_SIZE_TS) return EOS_ERR_SIZE; + + if (buffer[0] != (EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG)) return EOS_ERR_NET; + buffer += 3 + EOS_CELL_SMS_SIZE_TS; + len -= 3 + EOS_CELL_SMS_SIZE_TS; + + _addr_len = *buffer; + if (_addr_len > EOS_CELL_SMS_SIZE_ADDR) return EOS_ERR_SIZE; + if ((_addr_len == 0) || (len < (_addr_len + 1))) return EOS_ERR_SIZE; + if (addr && addr_len) { + *addr = buffer + 1; + *addr_len = _addr_len; + } + buffer += _addr_len + 1; + len -= _addr_len + 1; + + if (len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE; + if (txt && txt_len) { + *txt = buffer; + *txt_len = len; + } + + return EOS_OK; +} + +int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size) { + char *_addr, *_txt; + uint16_t _addr_len, _txt_len; int rv; - rv = eos_cell_sms_parse(buffer, len, &_num, &_num_len, &_text, &_text_len); + rv = _eos_cell_sms_parse(buffer, len, &_addr, &_addr_len, &_txt, &_txt_len); if (rv) return rv; - if (num_size < _num_len + 1) return EOS_ERR_SIZE; - if (text_size < _text_len + 1) return EOS_ERR_SIZE; - memcpy(num, _num, _num_len); - num[_num_len] = '\0'; - memcpy(text, _text, _text_len); - text[_text_len] = '\0'; + if (addr_size < _addr_len + 1) return EOS_ERR_SIZE; + if (txt_size < _txt_len + 1) return EOS_ERR_SIZE; + memcpy(addr, _addr, _addr_len); + addr[_addr_len] = '\0'; + memcpy(txt, _txt, _txt_len); + txt[_txt_len] = '\0'; return EOS_OK; } -int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **num, uint16_t *num_len, char **text, uint16_t *text_len) { - uint16_t _num_len; +int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned char *buffer) { + unsigned char type; + uint16_t len; + int do_release; + int rv; + + do_release = 0; + if (buffer == NULL) { + buffer = eos_net_alloc(); + do_release = 1; + } + + type = EOS_NET_MTYPE_CELL; + len = 1; + buffer[0] = EOS_CELL_MTYPE_PDP | atype; - if (len < 4 + GSM_TS_SIZE) return EOS_ERR_SIZE; + rv = eos_net_xchg(&type, buffer, &len); + if (rv) goto cell_pdp_get_fin; - if (buffer[0] != (EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG)) return EOS_ERR_NET; - buffer += 3 + GSM_TS_SIZE; - len -= 3 + GSM_TS_SIZE; - - _num_len = *buffer; - if (_num_len > EOS_CELL_MAX_DIAL_STR) return EOS_ERR_SIZE; - if ((_num_len == 0) || (len < (_num_len + 1))) return EOS_ERR_SIZE; - if (num && num_len) { - *num = buffer + 1; - *num_len = _num_len; + if ((type != EOS_NET_MTYPE_CELL) || (len == 0) || (buffer[0] != EOS_CELL_MTYPE_PDP | atype)) { + rv = EOS_ERR_NET; + goto cell_pdp_get_fin; } - buffer += _num_len + 1; - len -= _num_len + 1; - if (len > EOS_CELL_MAX_SMS_TEXT) return EOS_ERR_SIZE; - if (text && text_len) { - *text = buffer; - *text_len = len; + len--; + if ((len > EOS_CELL_PDP_SIZE_ARG) || (len > arg_size - 1)) { + rv = EOS_ERR_SIZE; + goto cell_pdp_get_fin; } + memcpy(buffer + 1, arg, len); + arg[len] = '\0'; - return EOS_OK; +cell_pdp_get_fin: + if (do_release) eos_net_free(buffer, 1); + return rv; +} + +int eos_cell_pdp_set(unsigned char atype, char *arg, unsigned char *buffer, int sync) { + int async; + size_t arg_len; + + arg_len = strlen(arg); + if (arg_len > EOS_CELL_PDP_SIZE_ARG) return EOS_ERR_SIZE; + + if (buffer == NULL) { + buffer = eos_net_alloc(); + async = 1; + } else { + async = !sync; + } + buffer[0] = EOS_CELL_MTYPE_PDP | atype; + memcpy(buffer + 1, arg, arg_len); + return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1 + arg_len, async, 1); +} + +int eos_cell_pdp_get_apn(char *apn, uint16_t apn_size, unsigned char *buffer) { + return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_APN, apn, apn_size, buffer); +} + +int eos_cell_pdp_set_apn(char *apn, unsigned char *buffer, int sync) { + return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_APN, apn, buffer, sync); +} + +int eos_cell_pdp_get_usr(char *usr, uint16_t usr_size, unsigned char *buffer) { + return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_USR, usr, usr_size, buffer); +} + +int eos_cell_pdp_set_usr(char *usr, unsigned char *buffer, int sync) { + return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_USR, usr, buffer, sync); +} + +int eos_cell_pdp_get_pwd(char *pwd, uint16_t pwd_size, unsigned char *buffer) { + return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_PWD, pwd, pwd_size, buffer); +} + +int eos_cell_pdp_set_pwd(char *pwd, unsigned char *buffer, int sync) { + return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_PWD, pwd, buffer, sync); +} + +int eos_cell_pdp_connect(unsigned char *buffer, int sync) { + int async; + + if (buffer == NULL) { + buffer = eos_net_alloc(); + async = 1; + } else { + async = !sync; + } + buffer[0] = EOS_CELL_MTYPE_PDP | EOS_CELL_MTYPE_PDP_CONNECT; + return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); +} + +int eos_cell_pdp_disconnect(unsigned char *buffer, int sync) { + int async; + + if (buffer == NULL) { + buffer = eos_net_alloc(); + async = 1; + } else { + async = !sync; + } + buffer[0] = EOS_CELL_MTYPE_PDP | EOS_CELL_MTYPE_PDP_DISCONNECT; + return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); } diff --git a/fw/fe310/eos/net/cell.h b/fw/fe310/eos/net/cell.h index 2717eb5..ac334e9 100644 --- a/fw/fe310/eos/net/cell.h +++ b/fw/fe310/eos/net/cell.h @@ -55,14 +55,18 @@ #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_MAX_USSD_STR 128 -#define EOS_CELL_MAX_DIAL_STR 16 -#define EOS_CELL_MAX_SMS_TEXT 160 +#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 void eos_cell_init(void); void eos_cell_set_handler(unsigned char mtype, eos_evt_handler_t handler); @@ -80,6 +84,17 @@ int eos_cell_voice_dial(char *num, unsigned char *buffer, int sync); int eos_cell_voice_answer(unsigned char *buffer, int sync); int eos_cell_voice_hangup(unsigned char *buffer, int sync); unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset); -int eos_cell_sms_send(char *num, char *text, unsigned char *buffer, int sync); -int eos_cell_sms_recv(unsigned char *buffer, uint16_t len, char *num, uint16_t num_size, char *text, uint16_t text_size); -int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **num, uint16_t *num_len, char **text, uint16_t *text_len); +int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync); +int _eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len); +int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size); + +int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned char *buffer); +int eos_cell_pdp_set(unsigned char atype, char *arg, unsigned char *buffer, int sync); +int eos_cell_pdp_get_apn(char *apn, uint16_t apn_size, unsigned char *buffer); +int eos_cell_pdp_set_apn(char *apn, unsigned char *buffer, int sync); +int eos_cell_pdp_get_usr(char *usr, uint16_t usr_size, unsigned char *buffer); +int eos_cell_pdp_set_usr(char *usr, unsigned char *buffer, int sync); +int eos_cell_pdp_get_pwd(char *pwd, uint16_t pwd_size, unsigned char *buffer); +int eos_cell_pdp_set_pwd(char *pwd, unsigned char *buffer, int sync); +int eos_cell_pdp_connect(unsigned char *buffer, int sync); +int eos_cell_pdp_disconnect(unsigned char *buffer, int sync); -- cgit v1.2.3