summaryrefslogtreecommitdiff
path: root/fw/fe310/phone/wifi.c
diff options
context:
space:
mode:
authorUros Majstorovic <majstor@majstor.org>2022-09-04 18:37:42 +0200
committerUros Majstorovic <majstor@majstor.org>2022-09-04 18:37:42 +0200
commitfc98d3809e0db36d634f290417b9152f87f83e3e (patch)
treed7c0cbb883571dccfcd4028d8b7b2a2144fc2d2b /fw/fe310/phone/wifi.c
parent07e6abe5d5a1813298805bea2bf9d62ad895aaaa (diff)
new phone firmware
Diffstat (limited to 'fw/fe310/phone/wifi.c')
-rw-r--r--fw/fe310/phone/wifi.c351
1 files changed, 351 insertions, 0 deletions
diff --git a/fw/fe310/phone/wifi.c b/fw/fe310/phone/wifi.c
new file mode 100644
index 0000000..cb8a816
--- /dev/null
+++ b/fw/fe310/phone/wifi.c
@@ -0,0 +1,351 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <eos.h>
+#include <dev/net.h>
+
+#include <eve/eve.h>
+#include <eve/eve_kbd.h>
+#include <eve/eve_font.h>
+
+#include <eve/screen/window.h>
+#include <eve/screen/page.h>
+#include <eve/screen/form.h>
+
+#include "app/app.h"
+#include "app/status.h"
+
+#include "wifi.h"
+
+#define WIFI_ACTION_NONE -1
+#define WIFI_ACTION_IDLE 0
+#define WIFI_ACTION_START 1
+#define WIFI_ACTION_STOP 2
+#define WIFI_ACTION_SCAN 3
+#define WIFI_ACTION_CONNECT 4
+#define WIFI_ACTION_DISCONNECT 5
+
+static void handle_status(unsigned char type, unsigned char *buffer, uint16_t size) {
+ EVEPage *page;
+ WIFIStatus *status;
+ int action;
+ int rv;
+
+ if (app_current_view() != wifi_app) goto handle_status_fin;
+
+ page = (EVEPage *)app_search_view("main");
+ status = page->v.param;
+
+ rv = eos_wifi_status_parse(buffer, size, &status->status, status->ip_addr, status->ssid);
+ if (rv) {
+ APP_LOG(APP_LOG_ERR, "BAD STATUS ERR:%d\n", rv);
+ goto handle_status_fin;
+ }
+
+ action = WIFI_ACTION_NONE;
+ switch (status->action) {
+ case WIFI_ACTION_IDLE: {
+ break;
+ }
+ case WIFI_ACTION_START: {
+ if (status->status == EOS_WIFI_STATUS_DISCONNECTED) {
+ action = WIFI_ACTION_SCAN;
+ }
+ break;
+ }
+ case WIFI_ACTION_STOP: {
+ if (status->status == EOS_WIFI_STATUS_OFF) {
+ action = WIFI_ACTION_IDLE;
+ }
+ break;
+ }
+ case WIFI_ACTION_CONNECT: {
+ if (status->status == EOS_WIFI_STATUS_CONNECTED) {
+ action = WIFI_ACTION_IDLE;
+ } else {
+ app_status_set_msg("CONNECT FAILED");
+ action = WIFI_ACTION_SCAN;
+ }
+ break;
+ }
+ case WIFI_ACTION_DISCONNECT: {
+ if (status->status == EOS_WIFI_STATUS_DISCONNECTED) {
+ action = WIFI_ACTION_SCAN;
+ }
+ break;
+ }
+ case WIFI_ACTION_SCAN: {
+ /* ignore status updates during scan */
+ goto handle_status_fin;
+ }
+ }
+
+ if (action == WIFI_ACTION_SCAN) {
+ rv = eos_wifi_scan(buffer, 0);
+ if (rv) {
+ APP_LOG(APP_LOG_ERR, "WIFI SCAN ERR:%d\n", rv);
+ goto handle_status_fin;
+ }
+ buffer = NULL;
+ }
+ wifi_update_status(page, action);
+ app_refresh();
+
+handle_status_fin:
+ if (buffer) eos_net_free(buffer, 0);
+}
+
+static void handle_scan(unsigned char type, unsigned char *buffer, uint16_t size) {
+ EVEPage *page;
+ EVESelectWidget *selw;
+
+ if (app_current_view() != wifi_app) goto handle_scan_fin;
+
+ page = (EVEPage *)app_search_view("main");
+ wifi_update_scanr(page, buffer + 1, size - 1);
+ app_refresh();
+
+handle_scan_fin:
+ eos_net_free(buffer, 0);
+}
+
+static void widget_ssid_draw(EVEFreeWidget *widget) {
+ EVEWidget *_widget = &widget->w;
+ WIFIStatus *status = _widget->page->v.param;
+
+ if (_widget->flags & EVE_WIDGET_FLAG_BUSY) {
+ eve_freew_tag(widget);
+ eve_cmd(CMD_TEXT, "hhhhs", _widget->g.x, _widget->g.y, app_font()->id, 0, "BUSY!");
+ } else if (status->status >= EOS_WIFI_STATUS_CONNECTED) {
+ char text[51];
+
+ if (status->status == EOS_WIFI_STATUS_CONNECTED) {
+ strcpy(text, status->ssid);
+ } else {
+ sprintf(text, "%s (%d.%d.%d.%d)", status->ssid, status->ip_addr[0], status->ip_addr[1], status->ip_addr[2], status->ip_addr[3]);
+ }
+
+ eve_freew_tag(widget);
+ eve_cmd(CMD_TEXT, "hhhhs", _widget->g.x, _widget->g.y, app_font()->id, 0, text);
+ }
+}
+
+static int widget_ssid_touch(EVEFreeWidget *widget, EVETouch *touch, uint16_t evt) {
+ if (evt & EVE_TOUCH_ETYPE_POINT_UP) {
+ EVEPage *page = widget->w.page;
+ int rv;
+
+ rv = eos_wifi_disconnect(NULL, 0);
+ if (!rv) wifi_update_status(page, WIFI_ACTION_DISCONNECT);
+ return 1;
+ }
+ return 0;
+}
+
+static int widget_enable_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) {
+ EVEToggleWidget *widget = (EVEToggleWidget *)_widget;
+ EVEPage *page = _widget->page;
+ WIFIStatus *status = page->v.param;
+
+ if (evt & EVE_TOUCH_ETYPE_TAG_UP) {
+ int rv;
+
+ if (widget->state) {
+ rv = eos_wifi_stop(NULL, 0);
+ if (!rv) wifi_update_status(page, WIFI_ACTION_STOP);
+ } else {
+ rv = eos_wifi_start(NULL, 0);
+ if (!rv) wifi_update_status(page, WIFI_ACTION_START);
+ }
+ if (rv) (APP_LOG_ERR, "WIFI START ERR:%d\n", rv);
+ return 1;
+ }
+
+ return 0;
+}
+
+void wifi_init(void) {
+ eos_wifi_set_handler(EOS_WIFI_MTYPE_STATUS, handle_status);
+ eos_wifi_set_handler(EOS_WIFI_MTYPE_SCAN, handle_scan);
+}
+
+int wifi_app(EVEWindow *window, EVEViewStack *stack) {
+ EVEFormSpec spec[] = {
+ APP_SPACERW(APP_SCREEN_W,20),
+ {
+ .label.title = "Enable:",
+ .label.g.w = APP_SCREEN_W - 100,
+
+ .widget.type = EVE_WIDGET_TYPE_TOGGLE,
+ .widget.g.w = 100,
+ .widget.tspec.toggle.labels = "off\xffon",
+ },
+ {
+ .widget.type = EVE_WIDGET_TYPE_FREE,
+ .widget.g.h = eve_font_h(app_font()),
+ .widget.tspec.free.draw = widget_ssid_draw,
+ .widget.tspec.free.touch = widget_ssid_touch,
+ },
+ {
+ .label.g.w = APP_SCREEN_W,
+ .label.title = "Select network:",
+
+ .widget.type = EVE_WIDGET_TYPE_SELECT,
+ .widget.g.w = APP_SCREEN_W,
+ .widget.tspec.select.option_size = EOS_WIFI_MAX_SCAN_RECORDS * EOS_WIFI_SIZE_SSID,
+ },
+ APP_SPACERW(APP_SCREEN_W,50),
+ {
+ .label.title = "Password:",
+
+ .widget.type = EVE_WIDGET_TYPE_STR,
+ .widget.tspec.str.str_size = EOS_WIFI_SIZE_PWD,
+ },
+ };
+ EVEPage *page;
+ EVEWidget *widget;
+ WIFIStatus *status;
+ int rv;
+ int action;
+
+ page = eve_form_create(window, stack, spec, APP_SPEC_SIZE(spec), wifi_uievt, wifi_close);
+ if (page == NULL) {
+ rv = EVE_ERR_NOMEM;
+ APP_LOG(APP_LOG_ERR, "OUT OF MEMORY\n");
+ return rv;
+ }
+
+ status = eve_malloc(sizeof(WIFIStatus));
+ if (status == NULL) {
+ rv = EVE_ERR_NOMEM;
+ eve_form_destroy(page);
+ APP_LOG(APP_LOG_ERR, "OUT OF MEMORY\n");
+ return rv;
+ }
+
+ page->v.param = status;
+ widget = eve_page_widget(page, 0);
+ widget->touch = widget_enable_touch;
+
+ rv = eos_wifi_status(&status->status, status->ip_addr, status->ssid, NULL);
+ if (rv) {
+ wifi_close(page);
+ APP_LOG(APP_LOG_ERR, "BAD STATUS ERR:%d\n", rv);
+ return rv;
+ }
+
+ action = WIFI_ACTION_IDLE;
+ if (status->status == EOS_WIFI_STATUS_DISCONNECTED) {
+ rv = eos_wifi_scan(NULL, 0);
+ if (rv) {
+ wifi_close(page);
+ APP_LOG(APP_LOG_ERR, "WIFI SCAN ERR:%d\n", rv);
+ return rv;
+ }
+ action = WIFI_ACTION_SCAN;
+ }
+ wifi_update_status(page, action);
+
+ return EVE_OK;
+}
+
+int wifi_uievt(EVEPage *page, uint16_t evt, void *param) {
+ int ret = 0;
+
+ switch (evt) {
+ case EVE_UIEVT_WIDGET_FOCUS_OUT: {
+ if (param == eve_page_widget(page, 3)) {
+ EVESelectWidget *selw;
+ utf8_t *ssid;
+
+ selw = (EVESelectWidget *)eve_page_widget(page, 2);
+ ssid = eve_selectw_option_selected(selw);
+ if (ssid) {
+ EVEStrWidget *strw = param;
+ WIFIStatus *status = page->v.param;
+ int rv;
+
+ rv = eos_wifi_connect((char *)ssid, (char *)strw->str, NULL, 0);
+ if (!rv) wifi_update_status(page, WIFI_ACTION_CONNECT);
+ if (rv) APP_LOG(APP_LOG_ERR, "WIFI CONNECT ERR:%d\n", rv);
+ }
+ }
+ break;
+ }
+
+ default: {
+ ret = eve_form_uievt(page, evt, param);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+void wifi_close(EVEPage *page) {
+ eve_free(page->v.param);
+ eve_form_destroy(page);
+}
+
+void wifi_update_status(EVEPage *page, int action) {
+ WIFIStatus *status = page->v.param;
+ EVEWidget *widget;
+ int i;
+
+ /* enable */
+ widget = eve_page_widget(page, 0);
+ if (status->status == EOS_WIFI_STATUS_OFF) {
+ ((EVEToggleWidget *)widget)->state = 0;
+ } else {
+ ((EVEToggleWidget *)widget)->state = 1;
+ }
+
+ /* ssid */
+ widget = eve_page_widget(page, 1);
+ eve_widget_clr_flags(widget, (EVE_WIDGET_FLAG_HIDDEN | EVE_WIDGET_FLAG_BUSY));
+ if (action >= WIFI_ACTION_SCAN) {
+ eve_widget_set_flags(widget, EVE_WIDGET_FLAG_BUSY);
+ }
+ if ((status->status < EOS_WIFI_STATUS_CONNECTED) && !(widget->flags & EVE_WIDGET_FLAG_BUSY)) {
+ eve_widget_set_flags(widget, EVE_WIDGET_FLAG_HIDDEN);
+ }
+
+ /* select network and password */
+ widget = eve_page_widget(page, 2);
+ for (i=0; i<3; i++) {
+ eve_widget_set_flags(widget, EVE_WIDGET_FLAG_HIDDEN);
+ widget = eve_widget_next(widget);
+ }
+ if (action != WIFI_ACTION_NONE) status->action = action;
+ eve_form_update_g(page, NULL);
+}
+
+void wifi_update_scanr(EVEPage *page, unsigned char *buffer, size_t size) {
+ WIFIStatus *status = page->v.param;
+ EVEWidget *widget;
+ EVESelectWidget *selw;
+ int i, rv;
+
+ selw = (EVESelectWidget *)eve_page_widget(page, 2);
+ rv = eve_selectw_set_option(selw, buffer, size);
+ if (rv) {
+ APP_LOG(APP_LOG_ERR, "BAD SCAN ERR:%d\n", rv);
+ return;
+ }
+
+ /* ssid */
+ widget = eve_page_widget(page, 1);
+ eve_widget_clr_flags(widget, EVE_WIDGET_FLAG_BUSY);
+ eve_widget_set_flags(widget, EVE_WIDGET_FLAG_HIDDEN);
+
+ /* select network and password */
+ widget = eve_page_widget(page, 2);
+ for (i=0; i<3; i++) {
+ eve_widget_clr_flags(widget, EVE_WIDGET_FLAG_HIDDEN);
+ widget = eve_widget_next(widget);
+ }
+ status->action = WIFI_ACTION_IDLE;
+ eve_form_update_g(page, NULL);
+}