text/plain
•
5.73 KB
•
212 lines
#include "wifi_screen.h"
#include <stdio.h>
#include <stdlib.h>
#include "../config.h"
#include "../network.h"
#include "../topbar.h"
static wifi_screen_state_t* screen_state;
static void back_event_cb(lv_event_t* e) {
if (lv_event_get_code(e) == LV_EVENT_CLICKED) {
navigate_back(SCREEN_SETTINGS);
}
}
static void test_http_cb(lv_event_t* e) {
if (lv_event_get_code(e) != LV_EVENT_CLICKED) {
return;
}
screen_state->test_url = "http://example.com";
if (network_is_connected()) {
screen_state->test_phase = WIFI_TEST_RUNNING;
} else {
screen_state->test_phase = WIFI_TEST_CONNECTING;
}
lv_label_set_text(screen_state->result_label, "Testing HTTP...");
}
static void test_https_cb(lv_event_t* e) {
if (lv_event_get_code(e) != LV_EVENT_CLICKED) {
return;
}
screen_state->test_url = "https://detectportal.firefox.com/canonical.html";
if (network_is_connected()) {
screen_state->test_phase = WIFI_TEST_RUNNING;
} else {
screen_state->test_phase = WIFI_TEST_CONNECTING;
}
lv_label_set_text(screen_state->result_label, "Testing HTTPS...");
}
static void scan_cb(lv_event_t* e) {
if (lv_event_get_code(e) != LV_EVENT_CLICKED) {
return;
}
screen_state->test_phase = WIFI_TEST_SCANNING;
lv_label_set_text(screen_state->result_label, "Scanning...");
}
static void menu_cancel_cb(lv_event_t* e) {
(void)e;
navigate_back(SCREEN_SETTINGS);
}
static void update_status_labels(wifi_screen_state_t* state) {
char buf[128];
if (network_is_connected()) {
int rssi = network_get_rssi();
if (rssi != 0) {
const char* quality;
if (rssi >= -50) {
quality = "Excellent";
} else if (rssi >= -60) {
quality = "Good";
} else if (rssi >= -70) {
quality = "Fair";
} else {
quality = "Weak";
}
snprintf(buf, sizeof(buf), "Connected - %s (%d dBm)", quality,
rssi);
} else {
snprintf(buf, sizeof(buf), "Connected");
}
} else {
snprintf(buf, sizeof(buf), "Not connected");
}
lv_label_set_text(state->status_label, buf);
}
ui_state_t setup_wifi_screen(lv_obj_t* parent) {
wifi_screen_state_t* state = calloc(1, sizeof(wifi_screen_state_t));
screen_state = state;
topbar_set_title("WiFi");
// Status label above the list
state->status_label = lv_label_create(parent);
lv_obj_set_width(state->status_label, SCREEN_WIDTH - 8);
lv_obj_set_pos(state->status_label, 4, TOPBAR_H + 2);
lv_label_set_long_mode(state->status_label, LV_LABEL_LONG_CLIP);
// Result label below status
state->result_label = lv_label_create(parent);
lv_obj_set_width(state->result_label, SCREEN_WIDTH - 8);
lv_obj_set_pos(state->result_label, 4, TOPBAR_H + 18);
lv_label_set_long_mode(state->result_label, LV_LABEL_LONG_CLIP);
lv_label_set_text(state->result_label, "");
update_status_labels(state);
// Show configured networks
config_t cfg;
if (config_load(&cfg) && cfg.wifi_count > 0) {
char buf[128];
int n = 0;
for (int i = 0; i < cfg.wifi_count && n < (int)sizeof(buf) - 1; i++) {
if (i > 0) {
n += snprintf(buf + n, sizeof(buf) - (size_t)n, ", ");
}
n += snprintf(buf + n, sizeof(buf) - (size_t)n, "%s",
cfg.wifi[i].ssid);
}
lv_label_set_text(state->result_label, buf);
} else {
lv_label_set_text(state->result_label, "No config found");
}
// Button list below the labels
state->list = bvs_list_create(parent);
lv_obj_set_pos(state->list, 0, TOPBAR_H + 34);
lv_obj_set_size(state->list, SCREEN_WIDTH, SCREEN_HEIGHT - TOPBAR_H - 34);
lv_obj_t* http_btn = bvs_list_add_nav_button(
state->list, NULL, "Test HTTP", test_http_cb, NULL, menu_cancel_cb);
bvs_list_add_nav_button(state->list, NULL, "Test HTTPS", test_https_cb,
NULL, menu_cancel_cb);
bvs_list_add_nav_button(state->list, NULL, "Scan Networks", scan_cb, NULL,
menu_cancel_cb);
bvs_list_add_nav_button(state->list, NULL, "Back", back_event_cb, NULL,
menu_cancel_cb);
lv_group_focus_obj(http_btn);
return (ui_state_t){.type = SCREEN_WIFI, .wifi = state};
}
void free_wifi_screen(wifi_screen_state_t* state) {
if (!state) {
return;
}
network_set_enabled(false);
screen_state = NULL;
free(state);
}
void update_wifi_screen(wifi_screen_state_t* state) {
if (!state) {
return;
}
switch (state->test_phase) {
case WIFI_TEST_IDLE:
break;
case WIFI_TEST_CONNECTING:
if (!network_set_enabled(true)) {
lv_label_set_text(state->result_label,
"WiFi connection failed");
state->test_phase = WIFI_TEST_IDLE;
break;
}
update_status_labels(state);
state->test_phase = WIFI_TEST_RUNNING;
break;
case WIFI_TEST_RUNNING:
state->test_result = network_test_url(state->test_url);
state->test_phase = WIFI_TEST_DONE;
break;
case WIFI_TEST_DONE: {
const char* proto = (state->test_url[4] == 's') ? "HTTPS" : "HTTP";
char buf[64];
snprintf(buf, sizeof(buf), "%s: %s", proto,
state->test_result ? "OK" : "Failed");
lv_label_set_text(state->result_label, buf);
network_set_enabled(false);
update_status_labels(state);
state->test_phase = WIFI_TEST_IDLE;
break;
}
case WIFI_TEST_SCANNING: {
char ssids[8][33];
int count = network_scan(ssids, 8);
if (count > 0) {
char buf[256];
int n = 0;
for (int i = 0; i < count && n < (int)sizeof(buf) - 1; i++) {
if (i > 0) {
n += snprintf(buf + n, sizeof(buf) - (size_t)n, ", ");
}
n += snprintf(buf + n, sizeof(buf) - (size_t)n, "%s",
ssids[i]);
}
lv_label_set_text(state->result_label, buf);
} else if (count == 0) {
lv_label_set_text(state->result_label, "No networks found");
} else {
char buf[64];
snprintf(buf, sizeof(buf), "Scan error: %d", count);
lv_label_set_text(state->result_label, buf);
}
state->test_phase = WIFI_TEST_IDLE;
break;
}
}
}