From ec892bf2e7620fb58e635b900ab4a0e44e3488bd Mon Sep 17 00:00:00 2001
From: Uros Majstorovic <majstor@majstor.org>
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