From 979d6a97a53b5c9738cfb7489ca05a3874042c8d Mon Sep 17 00:00:00 2001
From: Uros Majstorovic <majstor@majstor.org>
Date: Sun, 4 Sep 2022 18:26:23 +0200
Subject: wifi/cell driver improved

---
 fw/fe310/eos/net/cell.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++
 fw/fe310/eos/net/cell.h |  25 ++++++++-
 fw/fe310/eos/net/pwr.c  |  11 +++-
 fw/fe310/eos/net/wifi.c |  92 +++++++++++++++---------------
 fw/fe310/eos/net/wifi.h |  18 ++++--
 5 files changed, 235 insertions(+), 57 deletions(-)

(limited to 'fw/fe310')

diff --git a/fw/fe310/eos/net/cell.c b/fw/fe310/eos/net/cell.c
index 4bfbb35..c268b04 100644
--- a/fw/fe310/eos/net/cell.c
+++ b/fw/fe310/eos/net/cell.c
@@ -49,3 +49,149 @@ eos_evt_handler_t eos_cell_get_handler(unsigned char mtype) {
     if (idx < EOS_CELL_MAX_MTYPE) return evt_handler[idx];
     return NULL;
 }
+
+__attribute__ ((section (".itim")))
+int eos_cell_send_buffer(unsigned char *buffer, uint16_t buf_len, uint16_t offset, int sync) {
+    buffer -= offset;
+    return eos_net_send_async(EOS_NET_MTYPE_CELL, buffer, buf_len + offset, 1);
+}
+
+int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t *connected) {
+    if (len < 2) return EOS_ERR_SIZE;
+
+    if (buffer[0] != (EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS)) return EOS_ERR_NET;
+    buffer++;
+    len -= 1;
+
+    *status = buffer[0];
+    buffer++;
+    len -= 1;
+
+    if (*status == EOS_CELL_STATUS_PPP) {
+        if (len < 1) return EOS_ERR_SIZE;
+        if (connected) *connected = buffer[0];
+        buffer++;
+        len--;
+    }
+    return EOS_OK;
+}
+
+int eos_cell_status(uint8_t *status, uint8_t *connected, 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_DEV | EOS_CELL_MTYPE_STATUS;
+
+    rv = eos_net_xchg(&type, buffer, &len);
+    if (rv) goto cell_status_fin;
+
+    if (type != EOS_NET_MTYPE_CELL) {
+        rv = EOS_ERR_NET;
+        goto cell_status_fin;
+    }
+
+    rv = eos_cell_status_parse(buffer, len, status, connected);
+
+cell_status_fin:
+    if (do_release) eos_net_free(buffer, 1);
+    return rv;
+}
+
+int eos_cell_uart_take(unsigned char *buffer, int sync) {
+    int async;
+
+    if (buffer == NULL) {
+        buffer = eos_net_alloc();
+        async = 1;
+    } else {
+        async = !sync;
+    }
+    buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_TAKE;
+    return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1);
+}
+
+int eos_cell_uart_give(unsigned char *buffer, int sync) {
+    int async;
+
+    if (buffer == NULL) {
+        buffer = eos_net_alloc();
+        async = 1;
+    } else {
+        async = !sync;
+    }
+    buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_GIVE;
+    return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1);
+}
+
+unsigned char *eos_cell_uart_data_buffer(uint16_t *offset) {
+    unsigned char *buffer;
+
+    buffer = eos_net_alloc();
+    buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA;
+    *offset = 1;
+    return buffer + *offset;
+}
+
+int eos_cell_voice_dial(char *num, unsigned char *buffer, int sync) {
+    int async;
+    size_t num_len;
+
+    num_len = strlen(num);
+    if (num_len > EOS_CELL_MAX_DIAL_STR) return EOS_ERR_SIZE;
+
+    if (buffer == NULL) {
+        buffer = eos_net_alloc();
+        async = 1;
+    } else {
+        async = !sync;
+    }
+    buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_DIAL;
+    strcpy(buffer + 1, num);
+    return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1 + num_len, async, 1);
+}
+
+int eos_cell_voice_answer(unsigned char *buffer, int sync) {
+    int async;
+
+    if (buffer == NULL) {
+        buffer = eos_net_alloc();
+        async = 1;
+    } else {
+        async = !sync;
+    }
+    buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_ANSWER;
+    return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1);
+}
+
+int eos_cell_voice_hangup(unsigned char *buffer, int sync) {
+    int async;
+
+    if (buffer == NULL) {
+        buffer = eos_net_alloc();
+        async = 1;
+    } else {
+        async = !sync;
+    }
+    buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_HANGUP;
+    return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1);
+}
+
+__attribute__ ((section (".itim")))
+unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset) {
+    unsigned char *buffer;
+
+    buffer = eos_net_alloc();
+    buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM;
+    *offset = 1;
+    return buffer + *offset;
+}
diff --git a/fw/fe310/eos/net/cell.h b/fw/fe310/eos/net/cell.h
index f04eef2..1e6d1b2 100644
--- a/fw/fe310/eos/net/cell.h
+++ b/fw/fe310/eos/net/cell.h
@@ -12,7 +12,7 @@
 #define EOS_CELL_MAX_MTYPE              8
 
 /* EOS_CELL_MTYPE_DEV subtypes */
-#define EOS_CELL_MTYPE_READY            1
+#define EOS_CELL_MTYPE_STATUS           1
 #define EOS_CELL_MTYPE_UART_DATA        2
 #define EOS_CELL_MTYPE_UART_TAKE        3
 #define EOS_CELL_MTYPE_UART_GIVE        4
@@ -47,6 +47,11 @@
 #define EOS_CELL_MTYPE_PDP_CONNECT      7
 #define EOS_CELL_MTYPE_PDP_DISCONNECT   8
 
+#define EOS_CELL_STATUS_RESET           0
+#define EOS_CELL_STATUS_IDLE            1
+#define EOS_CELL_STATUS_RELAY           2
+#define EOS_CELL_STATUS_PPP             3
+
 #define EOS_CELL_SMS_ADDRTYPE_INTL      1
 #define EOS_CELL_SMS_ADDRTYPE_ALPHA     2
 #define EOS_CELL_SMS_ADDRTYPE_OTHER     3
@@ -56,6 +61,22 @@
 #define EOS_CELL_PDP_SIZE_PWD           64
 #define EOS_CELL_PDP_SIZE_ARG           64
 
+#define EOS_CELL_MAX_USSD_STR           128
+#define EOS_CELL_MAX_DIAL_STR           128
+
 void eos_cell_init(void);
 void eos_cell_set_handler(unsigned char mtype, eos_evt_handler_t handler);
-eos_evt_handler_t eos_cell_get_handler(unsigned char mtype);
\ No newline at end of file
+eos_evt_handler_t eos_cell_get_handler(unsigned char mtype);
+int eos_cell_send_buffer(unsigned char *buffer, uint16_t buf_len, uint16_t offset, int sync);
+
+int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t *connected);
+int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer);
+
+int eos_cell_uart_take(unsigned char *buffer, int sync);
+int eos_cell_uart_give(unsigned char *buffer, int sync);
+unsigned char *eos_cell_uart_data_buffer(uint16_t *offset);
+
+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);
diff --git a/fw/fe310/eos/net/pwr.c b/fw/fe310/eos/net/pwr.c
index 734e3cd..89f1817 100644
--- a/fw/fe310/eos/net/pwr.c
+++ b/fw/fe310/eos/net/pwr.c
@@ -8,6 +8,7 @@
 #include "soc/pwr.h"
 #include "soc/spi.h"
 #include "dev/spi.h"
+#include "dev/lcd.h"
 #include "eve/eve.h"
 
 #include "pwr.h"
@@ -42,9 +43,13 @@ static void pwr_handle_btn(unsigned char type, unsigned char *buffer, uint16_t l
     }
     if (!power_btn_down) return;
 
-    eos_spi_select(EOS_SPI_DEV_EVE);
-    eve_pwr_sleep();
-    eos_spi_deselect();
+    rv = eos_lcd_sleep();
+
+    rv = eos_spi_select(EOS_SPI_DEV_EVE);
+    if (!rv) {
+        eve_pwr_sleep();
+        eos_spi_deselect();
+    }
 
     rv = eos_pwr_sleep();
 }
diff --git a/fw/fe310/eos/net/wifi.c b/fw/fe310/eos/net/wifi.c
index 4db49f8..113321b 100644
--- a/fw/fe310/eos/net/wifi.c
+++ b/fw/fe310/eos/net/wifi.c
@@ -8,9 +8,6 @@
 
 #include "wifi.h"
 
-#define WIFI_SIZE_SSID      33
-#define WIFI_SIZE_PWD       64
-
 static eos_evt_handler_t evt_handler[EOS_WIFI_MAX_MTYPE];
 
 static void wifi_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) {
@@ -47,8 +44,33 @@ eos_evt_handler_t eos_wifi_get_handler(unsigned char mtype) {
     return NULL;
 }
 
-int eos_wifi_status(unsigned char *buffer, uint8_t *status, uint8_t ip_addr[], char *ssid) {
-    unsigned char *buf;
+int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t ip_addr[], char *ssid) {
+    if (len < 2) return EOS_ERR_SIZE;
+
+    if (buffer[0] != EOS_WIFI_MTYPE_STATUS) return EOS_ERR_NET;
+    buffer++;
+    len -= 1;
+
+    *status = buffer[0];
+    buffer++;
+    len -= 1;
+
+    switch (*status) {
+        case EOS_WIFI_STATUS_GOT_IP:
+            if (len < sizeof(uint32_t)) return EOS_ERR_SIZE;
+            if (ip_addr) memcpy(ip_addr, buffer, sizeof(uint32_t));
+            buffer += sizeof(uint32_t);
+            len -= sizeof(uint32_t);
+        case EOS_WIFI_STATUS_CONNECTED:
+            if ((len == 0) || (len > EOS_WIFI_SIZE_SSID)) return EOS_ERR_SIZE;
+            buffer[len - 1] = '\0';
+            if (ssid) strcpy(ssid, buffer);
+            break;
+    }
+    return EOS_OK;
+}
+
+int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, unsigned char *buffer) {
     unsigned char type;
     uint16_t len;
     int do_release;
@@ -71,89 +93,67 @@ int eos_wifi_status(unsigned char *buffer, uint8_t *status, uint8_t ip_addr[], c
         rv = EOS_ERR_NET;
         goto wifi_status_fin;
     }
-    if (len < 2) {
-        rv = EOS_ERR_SIZE;
-        goto wifi_status_fin;
-    }
-
-    *status = buffer[1];
-    buf = buffer + 2;
-    len -= 2;
-
-    switch (*status) {
-        case EOS_WIFI_STATUS_GOT_IP:
-            if (len < sizeof(uint32_t)) {
-                rv = EOS_ERR_SIZE;
-                goto wifi_status_fin;
-            }
-            if (ip_addr) memcpy(ip_addr, buf, sizeof(uint32_t));
-            buf += sizeof(uint32_t);
-            len -= sizeof(uint32_t);
-        case EOS_WIFI_STATUS_CONNECTED:
-            if ((len == 0) || (len > WIFI_SIZE_SSID)) {
-                rv = EOS_ERR_SIZE;
-                goto wifi_status_fin;
-            }
-            buf[len - 1] = '\0';
-            if (ssid) strcpy(ssid, buf);
-            break;
-    }
+    rv = eos_wifi_status_parse(buffer, len, status, ip_addr, ssid);
 
 wifi_status_fin:
     if (do_release) eos_net_free(buffer, 1);
     return rv;
 }
 
-int eos_wifi_start(unsigned char *buffer) {
+int eos_wifi_start(unsigned char *buffer, int sync) {
     int async;
 
-    async = 0;
     if (buffer == NULL) {
         buffer = eos_net_alloc();
         async = 1;
+    } else {
+        async = !sync;
     }
     buffer[0] = EOS_WIFI_MTYPE_START;
     return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1);
 }
 
-int eos_wifi_stop(unsigned char *buffer) {
+int eos_wifi_stop(unsigned char *buffer, int sync) {
     int async;
 
-    async = 0;
     if (buffer == NULL) {
         buffer = eos_net_alloc();
         async = 1;
+    } else {
+        async = !sync;
     }
     buffer[0] = EOS_WIFI_MTYPE_STOP;
     return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1);
 }
 
-int eos_wifi_scan(unsigned char *buffer) {
+int eos_wifi_scan(unsigned char *buffer, int sync) {
     int async;
 
-    async = 0;
     if (buffer == NULL) {
         buffer = eos_net_alloc();
         async = 1;
+    } else {
+        async = !sync;
     }
     buffer[0] = EOS_WIFI_MTYPE_SCAN;
     return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1);
 }
 
-int eos_wifi_connect(const char *ssid, const char *pwd, unsigned char *buffer) {
+int eos_wifi_connect(char *ssid, char *pwd, unsigned char *buffer, int sync) {
     unsigned char *buf;
     size_t ssid_len, pwd_len;
     int async;
 
     ssid_len = strlen(ssid);
     pwd_len = strlen(pwd);
-    if (ssid_len > WIFI_SIZE_SSID - 1) return EOS_ERR_SIZE;
-    if (pwd_len > WIFI_SIZE_PWD - 1) return EOS_ERR_SIZE;
+    if (ssid_len > EOS_WIFI_SIZE_SSID - 1) return EOS_ERR_SIZE;
+    if (pwd_len > EOS_WIFI_SIZE_PWD - 1) return EOS_ERR_SIZE;
 
-    async = 0;
     if (buffer == NULL) {
         buffer = eos_net_alloc();
         async = 1;
+    } else {
+        async = !sync;
     }
     buf = buffer;
     buf[0] = EOS_WIFI_MTYPE_CONNECT;
@@ -162,17 +162,17 @@ int eos_wifi_connect(const char *ssid, const char *pwd, unsigned char *buffer) {
     buf += ssid_len + 1;
     strcpy(buf, pwd);
     buf += pwd_len + 1;
-
-    return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1);
+    return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 3 + ssid_len + pwd_len, async, 1);
 }
 
-int eos_wifi_disconnect(unsigned char *buffer) {
+int eos_wifi_disconnect(unsigned char *buffer, int sync) {
     int async;
 
-    async = 0;
     if (buffer == NULL) {
         buffer = eos_net_alloc();
         async = 1;
+    } else {
+        async = !sync;
     }
     buffer[0] = EOS_WIFI_MTYPE_DISCONNECT;
     return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1);
diff --git a/fw/fe310/eos/net/wifi.h b/fw/fe310/eos/net/wifi.h
index 2100144..997329f 100644
--- a/fw/fe310/eos/net/wifi.h
+++ b/fw/fe310/eos/net/wifi.h
@@ -15,13 +15,19 @@
 #define EOS_WIFI_STATUS_CONNECTED       2
 #define EOS_WIFI_STATUS_GOT_IP          3
 
+#define EOS_WIFI_SIZE_SSID              33
+#define EOS_WIFI_SIZE_PWD               64
+
+#define EOS_WIFI_MAX_SCAN_RECORDS       20
+
 void eos_wifi_init(void);
 void eos_wifi_set_handler(unsigned char mtype, eos_evt_handler_t handler);
 eos_evt_handler_t eos_wifi_get_handler(unsigned char mtype);
 
-int eos_wifi_status(unsigned char *buffer, uint8_t *status, uint8_t ip_addr[], char *ssid);
-int eos_wifi_start(unsigned char *buffer);
-int eos_wifi_stop(unsigned char *buffer);
-int eos_wifi_scan(unsigned char *buffer);
-int eos_wifi_connect(const char *ssid, const char *pwd, unsigned char *buffer);
-int eos_wifi_disconnect(unsigned char *buffer);
\ No newline at end of file
+int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t ip_addr[], char *ssid);
+int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, unsigned char *buffer);
+int eos_wifi_start(unsigned char *buffer, int sync);
+int eos_wifi_stop(unsigned char *buffer, int sync);
+int eos_wifi_scan(unsigned char *buffer, int sync);
+int eos_wifi_connect(char *ssid, char *pwd, unsigned char *buffer, int sync);
+int eos_wifi_disconnect(unsigned char *buffer, int sync);
\ No newline at end of file
-- 
cgit v1.2.3