mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-23 02:41:27 +00:00
ui fixes for wifi
This commit is contained in:
1 parent
afa7ada095
commit
319369f173
17 files changed
+487
-60
No files matched your search
@@ -975,7 +975,9 @@ Color TFT panels (T114, T096, Wireless Tracker) are wrapped as 1bpp displays for
|
||||
|
||||
### 8.2 Pages (Button UI)
|
||||
|
||||
**Companion** (up to 12 pages): Messages, Recent, Radio, Bluetooth, Advert, GPS, Buzzer (if buzzer present), LEDs, Sensors, Offgrid, DFU, Shutdown
|
||||
**Companion** (up to 14 pages): Messages, Recent, Radio, Traffic, Bluetooth, WiFi (WiFi companion builds only), Advert, GPS, Buzzer (if buzzer present), LEDs, Sensors, Offgrid, DFU, Shutdown
|
||||
|
||||
Connection state on these pages: "an app is connected" (`UI_EVENT_APP_CONNECTED` / `_DISCONNECTED`, any transport) gates the buzzer, the message LED flash and the "Connected" line; which transport it is comes from `ui_set_link_transports()` (`UI_LINK_BLE` / `_USB` / `_TCP`, pushed by `process_link_change()` on every link edge). The Messages badge names the transport; the Bluetooth page says "Connected" only for a BLE client. The WiFi page shows the station state, SSID, IPv4 address, TCP port and whether an app is on the socket, pushed every housekeeping tick by `companion_wifi_ui_refresh()` through `ui_set_wifi()` (redraws only on a change, e-paper included). The joystick UI shows the same WiFi details as System > Info > WiFi (`WifiScreen`) on WiFi companion builds (ThinkNode M9); elsewhere its two hooks are no-ops.
|
||||
|
||||
**Repeater** (3 pages): Status, Radio, Shutdown
|
||||
|
||||
@@ -1007,8 +1009,8 @@ Pages with a **shared** flow that only tints per-row (Recent, GPS, Sensors,
|
||||
Status) stay as single functions with inline `if (mc_display_has_color())` —
|
||||
that already is the "one layout, colored" ideal, and the color branch
|
||||
dead-code-eliminates on mono via the constant-false `mc_display_has_color()`.
|
||||
Split pages: Messages, Radio, Traffic, Bluetooth, Advert, LEDs, Offgrid, DFU,
|
||||
Shutdown.
|
||||
Split pages: Messages, Radio, Traffic, Bluetooth, WiFi, Advert, LEDs, Offgrid,
|
||||
DFU, Shutdown.
|
||||
|
||||
### 8.3 Multi-Tap Input
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ZephCore 1.18.0-zephcore
|
||||
|
||||
Safer off-grid mode, working buttons on four boards with a display, a GPS clock fix, a new KISS
|
||||
modem role, and the changes from upstream MeshCore 1.18.0.
|
||||
Safer off-grid mode, working buttons on four boards with a display, a WiFi page on the display of
|
||||
WiFi companions, a GPS clock fix, a new KISS modem role, and the changes from upstream MeshCore 1.18.0.
|
||||
|
||||
> [!NOTE]
|
||||
> A normal upgrade keeps your identity, settings, contacts and phone pairing.
|
||||
@@ -31,6 +31,20 @@ More in [OFFGRID.md](../docs/OFFGRID.md). Thanks to **N8HOP** for the report.
|
||||
confirmed again.
|
||||
- On all four boards the confirmation is a second **hold** within 3 seconds.
|
||||
|
||||
## Display: WiFi page, and the right connection shown
|
||||
|
||||
- **New WiFi page** on WiFi companions with a one-button display (Heltec V3, V4, V4.3, Wireless
|
||||
Tracker, T3S3, Station G2 and others), next to the Bluetooth page. It shows whether WiFi is off,
|
||||
joining or connected, and once connected the network, IP address and port to enter in the app,
|
||||
and whether the app is connected over WiFi. On the ThinkNode M9 the same details are under
|
||||
**System > Info > WiFi**.
|
||||
- **The home page names the connection:** "WiFi OK", "USB OK" or "BLE OK" instead of always
|
||||
"BLE OK", and "BLE OFF" when Bluetooth is turned off and no app is connected.
|
||||
- **The Bluetooth page says "Connected" only for a Bluetooth connection.** An app connected over
|
||||
WiFi or USB used to show there too.
|
||||
|
||||
Thanks to **bisbille** for the report.
|
||||
|
||||
## GPS no longer sets the clock to an old time
|
||||
|
||||
Just after waking, a GPS receiver can report its last position and its own, possibly stale, clock
|
||||
|
||||
@@ -503,6 +503,11 @@ bool zephcore_usb_companion_is_text_session(void)
|
||||
return usb_session_is_text;
|
||||
}
|
||||
|
||||
bool zephcore_usb_companion_link_up(void)
|
||||
{
|
||||
return usb_link_up;
|
||||
}
|
||||
|
||||
void zephcore_usb_companion_set_cli_line_cb(void (*cb)(const char *line))
|
||||
{
|
||||
s_cli_line_cb = cb;
|
||||
|
||||
@@ -74,6 +74,12 @@ void zephcore_usb_companion_write_text(const char *text, size_t len);
|
||||
*/
|
||||
bool zephcore_usb_companion_is_text_session(void);
|
||||
|
||||
/**
|
||||
* True while a session of either kind (binary app or text CLI) is open and
|
||||
* the bus is not suspended: the state behind the link callbacks' edges.
|
||||
*/
|
||||
bool zephcore_usb_companion_link_up(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <helpers/TxtDataHelpers.h>
|
||||
#include <ZephyrWiFiStation.h>
|
||||
#include <helpers/pm_sleep_guard.h>
|
||||
#include "ui_task.h"
|
||||
|
||||
LOG_MODULE_REGISTER(zephcore_wifi_companion, CONFIG_ZEPHCORE_MAIN_LOG_LEVEL);
|
||||
|
||||
@@ -49,6 +50,19 @@ void companion_wifi_start(const NodePrefs &prefs)
|
||||
}
|
||||
}
|
||||
|
||||
/* Off when start() did not join (s_ssid stays empty); up once there is a
|
||||
* lease, which is what the app needs to connect. */
|
||||
void companion_wifi_ui_refresh(void)
|
||||
{
|
||||
char ip[16] = "";
|
||||
uint8_t state = UI_WIFI_OFF;
|
||||
|
||||
if (s_ssid[0] != '\0') {
|
||||
state = zc_wifi_station_ip(ip, sizeof(ip)) ? UI_WIFI_UP : UI_WIFI_JOINING;
|
||||
}
|
||||
ui_set_wifi(state, s_ssid, ip, CONFIG_ZEPHCORE_TCP_PORT);
|
||||
}
|
||||
|
||||
bool companion_wifi_cli(const char *command, NodePrefs &prefs, void (*save)(void), char *reply)
|
||||
{
|
||||
if (memcmp(command, "set wifi.ssid ", 14) == 0) {
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
* wifi.* change applies on the next reboot. */
|
||||
void companion_wifi_start(const NodePrefs &prefs);
|
||||
|
||||
/* Push the station's state, SSID and IP to the display (ui_set_wifi). From
|
||||
* the main loop's housekeeping tick. */
|
||||
void companion_wifi_ui_refresh(void);
|
||||
|
||||
/* Upstream's companion wifi.* commands. True when `command` was one of them
|
||||
* (reply filled); save persists the prefs. */
|
||||
bool companion_wifi_cli(const char *command, NodePrefs &prefs, void (*save)(void), char *reply);
|
||||
@@ -170,6 +170,9 @@ static const enum ui_page active_pages[] = {
|
||||
UI_PAGE_RADIO,
|
||||
UI_PAGE_TRAFFIC,
|
||||
UI_PAGE_BLUETOOTH,
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
UI_PAGE_WIFI,
|
||||
#endif
|
||||
UI_PAGE_ADVERT,
|
||||
UI_PAGE_GPS,
|
||||
#ifdef CONFIG_ZEPHCORE_UI_BUZZER
|
||||
@@ -454,6 +457,40 @@ static const char *radio_state_label(void)
|
||||
state.lora_radio_ready ? "RDY" : "WAIT";
|
||||
}
|
||||
|
||||
/* The transport the app is connected on (BLE first when several are), for the
|
||||
* home page. Meaningful only while state.app_connected. */
|
||||
static const char *link_label(void)
|
||||
{
|
||||
return (state.link_transports & UI_LINK_BLE) ? "BLE" :
|
||||
(state.link_transports & UI_LINK_TCP) ? "WiFi" :
|
||||
(state.link_transports & UI_LINK_USB) ? "USB" : "App";
|
||||
}
|
||||
|
||||
#if MC_DISPLAY_COLOR_PANEL
|
||||
/* The home page's link badge: "<transport> OK" while an app is connected,
|
||||
* else whether BLE is advertising or off. */
|
||||
static const char *link_badge(char *buf, size_t len)
|
||||
{
|
||||
if (state.app_connected) {
|
||||
snprintf(buf, len, "%s OK", link_label());
|
||||
return buf;
|
||||
}
|
||||
return state.ble_enabled ? "BLE ADV" : "BLE OFF";
|
||||
}
|
||||
|
||||
static uint16_t link_badge_color(void)
|
||||
{
|
||||
return state.app_connected ? UI_COLOR_OK :
|
||||
state.ble_enabled ? UI_COLOR_WARN : UI_COLOR_DISABLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* True when BLE itself has a client (not just some transport). */
|
||||
static bool ble_link_up(void)
|
||||
{
|
||||
return (state.link_transports & UI_LINK_BLE) != 0;
|
||||
}
|
||||
|
||||
#if MC_DISPLAY_COLOR_PANEL
|
||||
static uint8_t clamp_activity_delta(uint32_t delta)
|
||||
{
|
||||
@@ -565,6 +602,7 @@ static const char *tiny_page_title(enum ui_page p)
|
||||
case UI_PAGE_RADIO: return "RADIO";
|
||||
case UI_PAGE_TRAFFIC: return "TRAFFIC";
|
||||
case UI_PAGE_BLUETOOTH: return "BLUETOOTH";
|
||||
case UI_PAGE_WIFI: return "WIFI";
|
||||
case UI_PAGE_ADVERT: return "ADVERT";
|
||||
case UI_PAGE_GPS: return "GPS";
|
||||
case UI_PAGE_BUZZER: return "BUZZER";
|
||||
@@ -601,14 +639,19 @@ static void render_tiny_title(void)
|
||||
*/
|
||||
static void render_messages_mono(void)
|
||||
{
|
||||
/* 3 centered rows: msg count, BLE status, offgrid status */
|
||||
/* 3 centered rows: msg count, link status, offgrid status */
|
||||
char buf[24];
|
||||
|
||||
if (ui_tiny()) {
|
||||
snprintf(buf, sizeof(buf), "MSG:%u", state.msg_count);
|
||||
draw_centered(centered_row(0, 3), buf);
|
||||
draw_centered(centered_row(1, 3),
|
||||
state.ble_connected ? "BLE:conn" : "BLE:adv");
|
||||
if (state.app_connected) {
|
||||
snprintf(buf, sizeof(buf), "%s:conn", link_label());
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "BLE:%s",
|
||||
state.ble_enabled ? "adv" : "off");
|
||||
}
|
||||
draw_centered(centered_row(1, 3), buf);
|
||||
|
||||
uint32_t up_s = (uint32_t)(k_uptime_get() / 1000);
|
||||
|
||||
@@ -621,8 +664,9 @@ static void render_messages_mono(void)
|
||||
snprintf(buf, sizeof(buf), "MSG: %u", state.msg_count);
|
||||
draw_centered(centered_row(0, 4), buf);
|
||||
|
||||
if (state.ble_connected) {
|
||||
draw_centered(centered_row(1, 4), "< Connected >");
|
||||
if (state.app_connected) {
|
||||
snprintf(buf, sizeof(buf), "< Connected: %s >", link_label());
|
||||
draw_centered(centered_row(1, 4), buf);
|
||||
} else {
|
||||
draw_centered(centered_row(1, 4), "Waiting for app...");
|
||||
}
|
||||
@@ -644,15 +688,15 @@ static void render_messages_color(void)
|
||||
|
||||
if (use_compact_color_home()) {
|
||||
int y = CONTENT_Y;
|
||||
uint16_t ble_color = state.ble_connected ? UI_COLOR_OK : UI_COLOR_WARN;
|
||||
const char *ble = state.ble_connected ? "BLE OK" : "BLE ADV";
|
||||
char badge[12];
|
||||
const char *link = link_badge(badge, sizeof(badge));
|
||||
const char *radio = radio_state_label();
|
||||
uint16_t radio_color = state.lora_tx_active ? UI_COLOR_TX :
|
||||
state.lora_in_rx ? UI_COLOR_RX :
|
||||
state.lora_radio_ready ? UI_COLOR_OK
|
||||
: UI_COLOR_WARN;
|
||||
|
||||
draw_badge(0, y, ble, ble_color);
|
||||
draw_badge(0, y, link, link_badge_color());
|
||||
draw_badge(DISP_W - color_text_width(radio) - 4, y, radio,
|
||||
radio_color);
|
||||
y += LINE_H + 2;
|
||||
@@ -663,7 +707,7 @@ static void render_messages_color(void)
|
||||
state.msg_count ? UI_COLOR_WARN : UI_COLOR_VALUE);
|
||||
y += LINE_H;
|
||||
|
||||
if (state.ble_connected) {
|
||||
if (state.app_connected) {
|
||||
draw_centered_color(y, "Connected", UI_COLOR_OK);
|
||||
} else {
|
||||
mc_display_color_text(30, y, "Waiting for app", UI_COLOR_WARN);
|
||||
@@ -685,10 +729,9 @@ static void render_messages_color(void)
|
||||
}
|
||||
|
||||
int y = CONTENT_Y;
|
||||
uint16_t ble_color = state.ble_connected ? UI_COLOR_OK : UI_COLOR_WARN;
|
||||
const char *ble = state.ble_connected ? "BLE OK" : "BLE ADV";
|
||||
char badge[12];
|
||||
|
||||
draw_badge(0, y, ble, ble_color);
|
||||
draw_badge(0, y, link_badge(badge, sizeof(badge)), link_badge_color());
|
||||
draw_badge(DISP_W - color_text_width(state.offgrid_enabled ? "GRID" : "LOCAL") - 4,
|
||||
y, state.offgrid_enabled ? "GRID" : "LOCAL",
|
||||
state.offgrid_enabled ? UI_COLOR_ACTIVE : UI_COLOR_DISABLED);
|
||||
@@ -700,7 +743,7 @@ static void render_messages_color(void)
|
||||
state.msg_count ? UI_COLOR_WARN : UI_COLOR_VALUE);
|
||||
y += LINE_H;
|
||||
|
||||
if (state.ble_connected) {
|
||||
if (state.app_connected) {
|
||||
draw_centered_color(y, "Connected", UI_COLOR_OK);
|
||||
} else {
|
||||
draw_centered_color(y, "Waiting for app", UI_COLOR_WARN);
|
||||
@@ -1008,7 +1051,7 @@ static void render_bluetooth_mono(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.ble_connected) {
|
||||
if (ble_link_up()) {
|
||||
draw_centered(centered_row(0, 2), "BLE: Connected");
|
||||
draw_centered(centered_row(1, 2), "Press to Disable");
|
||||
} else {
|
||||
@@ -1022,12 +1065,12 @@ static void render_bluetooth_color(void)
|
||||
{
|
||||
int y = CONTENT_Y;
|
||||
uint16_t color = !state.ble_enabled ? UI_COLOR_DISABLED :
|
||||
state.ble_connected ? UI_COLOR_OK : UI_COLOR_WARN;
|
||||
ble_link_up() ? UI_COLOR_OK : UI_COLOR_WARN;
|
||||
|
||||
draw_badge(0, y, "BLE", color);
|
||||
mc_display_color_text(32, y,
|
||||
!state.ble_enabled ? "disabled" :
|
||||
state.ble_connected ? "connected" : "advertising",
|
||||
ble_link_up() ? "connected" : "advertising",
|
||||
color);
|
||||
y += LINE_H + (FONT_H / 4);
|
||||
draw_centered_color(y,
|
||||
@@ -1048,6 +1091,81 @@ static void render_bluetooth(void)
|
||||
render_bluetooth_mono();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
/* WiFi page: state, network, and the address the app connects to. */
|
||||
static void render_wifi_mono(void)
|
||||
{
|
||||
char buf[24];
|
||||
|
||||
if (state.wifi_state == UI_WIFI_OFF) {
|
||||
draw_centered(centered_row(0, 2), "WiFi: OFF");
|
||||
draw_centered(centered_row(1, 2), "Set up via CLI");
|
||||
return;
|
||||
}
|
||||
if (state.wifi_state == UI_WIFI_JOINING) {
|
||||
draw_centered(centered_row(0, 2), "WiFi: Joining");
|
||||
draw_centered(centered_row(1, 2), state.wifi_ssid);
|
||||
return;
|
||||
}
|
||||
|
||||
draw_centered(centered_row(0, 4), state.wifi_ssid);
|
||||
draw_centered(centered_row(1, 4), state.wifi_ip);
|
||||
snprintf(buf, sizeof(buf), "Port %u", state.wifi_port);
|
||||
draw_centered(centered_row(2, 4), buf);
|
||||
draw_centered(centered_row(3, 4),
|
||||
(state.link_transports & UI_LINK_TCP) ? "App connected"
|
||||
: "No app");
|
||||
}
|
||||
|
||||
#if MC_DISPLAY_COLOR_PANEL
|
||||
static void render_wifi_color(void)
|
||||
{
|
||||
int y = CONTENT_Y;
|
||||
char buf[8];
|
||||
uint16_t color = state.wifi_state == UI_WIFI_UP ? UI_COLOR_OK :
|
||||
state.wifi_state == UI_WIFI_JOINING ? UI_COLOR_WARN :
|
||||
UI_COLOR_DISABLED;
|
||||
|
||||
draw_badge(0, y, "WiFi", color);
|
||||
mc_display_color_text(color_text_width("WiFi") + 8, y,
|
||||
state.wifi_state == UI_WIFI_UP ? "connected" :
|
||||
state.wifi_state == UI_WIFI_JOINING ? "joining" : "off",
|
||||
color);
|
||||
y += LINE_H + (FONT_H / 4);
|
||||
|
||||
if (state.wifi_state == UI_WIFI_OFF) {
|
||||
draw_centered_color(y, "Set up via CLI", UI_COLOR_VALUE);
|
||||
return;
|
||||
}
|
||||
draw_color_segments(y, "SSID ", state.wifi_ssid, UI_COLOR_VALUE);
|
||||
y += LINE_H;
|
||||
if (state.wifi_state == UI_WIFI_JOINING) {
|
||||
return;
|
||||
}
|
||||
draw_color_segments(y, "IP ", state.wifi_ip, UI_COLOR_VALUE);
|
||||
y += LINE_H;
|
||||
snprintf(buf, sizeof(buf), "%u", state.wifi_port);
|
||||
draw_color_segments(y, "Port ", buf, UI_COLOR_VALUE);
|
||||
y += LINE_H;
|
||||
draw_color_segments(y, "App ",
|
||||
(state.link_transports & UI_LINK_TCP) ? "connected" : "none",
|
||||
(state.link_transports & UI_LINK_TCP) ? UI_COLOR_OK
|
||||
: UI_COLOR_DISABLED);
|
||||
}
|
||||
#endif /* MC_DISPLAY_COLOR_PANEL */
|
||||
|
||||
static void render_wifi(void)
|
||||
{
|
||||
#if MC_DISPLAY_COLOR_PANEL
|
||||
if (mc_display_has_color()) {
|
||||
render_wifi_color();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
render_wifi_mono();
|
||||
}
|
||||
#endif /* CONFIG_ZEPHCORE_COMPANION_WIFI */
|
||||
|
||||
static void render_advert_mono(void)
|
||||
{
|
||||
/* Check for recent "Sent!" feedback (show for 2 seconds) */
|
||||
@@ -1643,6 +1761,9 @@ static const page_render_fn renderers[] = {
|
||||
[UI_PAGE_RADIO] = render_radio,
|
||||
[UI_PAGE_TRAFFIC] = render_traffic,
|
||||
[UI_PAGE_BLUETOOTH] = render_bluetooth,
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
[UI_PAGE_WIFI] = render_wifi,
|
||||
#endif
|
||||
[UI_PAGE_ADVERT] = render_advert,
|
||||
[UI_PAGE_GPS] = render_gps,
|
||||
[UI_PAGE_BUZZER] = render_buzzer,
|
||||
|
||||
@@ -25,6 +25,7 @@ enum ui_page {
|
||||
UI_PAGE_RADIO, /* LoRa params (freq, SF, BW, CR, power, noise) */
|
||||
UI_PAGE_TRAFFIC, /* TX/RX packet activity graph */
|
||||
UI_PAGE_BLUETOOTH, /* BLE toggle */
|
||||
UI_PAGE_WIFI, /* WiFi companion state and IP (WiFi builds) */
|
||||
UI_PAGE_ADVERT, /* Send broadcast advert */
|
||||
UI_PAGE_GPS, /* GPS status / position */
|
||||
UI_PAGE_BUZZER, /* Buzzer mute toggle */
|
||||
@@ -49,7 +50,8 @@ struct ui_state {
|
||||
|
||||
/* Messages page */
|
||||
uint16_t msg_count;
|
||||
bool ble_connected;
|
||||
bool app_connected; /* an app is connected, on any transport */
|
||||
uint8_t link_transports; /* UI_LINK_* bits: which transports have one */
|
||||
|
||||
/* Recently heard */
|
||||
struct {
|
||||
@@ -79,6 +81,14 @@ struct ui_state {
|
||||
/* Bluetooth page */
|
||||
bool ble_enabled; /* true = BLE active, false = serial mode */
|
||||
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
/* WiFi page */
|
||||
uint8_t wifi_state; /* enum ui_wifi_state */
|
||||
uint16_t wifi_port; /* TCP port of the app socket */
|
||||
char wifi_ssid[33];
|
||||
char wifi_ip[16]; /* dotted IPv4, "" without a lease */
|
||||
#endif
|
||||
|
||||
/* GPS page */
|
||||
bool gps_available; /* true = GNSS hardware detected at boot */
|
||||
bool gps_enabled; /* GPS hardware on/off */
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/input/input.h>
|
||||
#include <zephyr/dt-bindings/input/input-event-codes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zephyr_poweroff.h>
|
||||
@@ -195,7 +196,7 @@ static void splash_work_handler(struct k_work *work)
|
||||
|
||||
static void schedule_render(void);
|
||||
static void schedule_render_auto(void);
|
||||
static void set_ble_connected(bool connected);
|
||||
static void set_app_connected(bool connected);
|
||||
|
||||
static void advert_defer_handler(struct k_work *work)
|
||||
{
|
||||
@@ -819,7 +820,7 @@ void ui_notify(enum ui_event event)
|
||||
is_msg_event = true;
|
||||
#ifdef CONFIG_ZEPHCORE_UI_BUZZER
|
||||
/* Only buzz if no phone is connected to receive the message */
|
||||
if (!get_state()->ble_connected) {
|
||||
if (!get_state()->app_connected) {
|
||||
buzzer_play(MELODY_MSG_CONTACT);
|
||||
}
|
||||
#endif
|
||||
@@ -828,7 +829,7 @@ void ui_notify(enum ui_event event)
|
||||
case UI_EVENT_CHANNEL_MSG:
|
||||
is_msg_event = true;
|
||||
#ifdef CONFIG_ZEPHCORE_UI_BUZZER
|
||||
if (!get_state()->ble_connected) {
|
||||
if (!get_state()->app_connected) {
|
||||
buzzer_play(MELODY_MSG_CHANNEL);
|
||||
}
|
||||
#endif
|
||||
@@ -837,7 +838,7 @@ void ui_notify(enum ui_event event)
|
||||
case UI_EVENT_ROOM_MSG:
|
||||
is_msg_event = true;
|
||||
#ifdef CONFIG_ZEPHCORE_UI_BUZZER
|
||||
if (!get_state()->ble_connected) {
|
||||
if (!get_state()->app_connected) {
|
||||
buzzer_play(MELODY_MSG_CHANNEL);
|
||||
}
|
||||
#endif
|
||||
@@ -849,23 +850,23 @@ void ui_notify(enum ui_event event)
|
||||
#endif
|
||||
break;
|
||||
|
||||
case UI_EVENT_BLE_CONNECTED:
|
||||
set_ble_connected(true);
|
||||
case UI_EVENT_APP_CONNECTED:
|
||||
set_app_connected(true);
|
||||
break;
|
||||
|
||||
case UI_EVENT_BLE_DISCONNECTED:
|
||||
set_ble_connected(false);
|
||||
case UI_EVENT_APP_DISCONNECTED:
|
||||
set_app_connected(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_msg_event && !get_state()->ble_connected) {
|
||||
if (is_msg_event && !get_state()->app_connected) {
|
||||
ui_led_flash_msg();
|
||||
}
|
||||
|
||||
/* Wake display on non-message notifications (BLE connect/disconnect etc).
|
||||
/* Wake display on non-message notifications (app connect/disconnect etc).
|
||||
* Message notifications use buzzer + LED flash instead of waking the display. */
|
||||
#ifdef CONFIG_ZEPHCORE_UI_DISPLAY
|
||||
#ifndef ZEPHCORE_REPEATER
|
||||
@@ -910,11 +911,11 @@ void ui_set_msg_count(uint16_t count)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void set_ble_connected(bool connected)
|
||||
static void set_app_connected(bool connected)
|
||||
{
|
||||
struct ui_state *s = get_state();
|
||||
|
||||
s->ble_connected = connected;
|
||||
s->app_connected = connected;
|
||||
|
||||
if (ui_initialized) {
|
||||
schedule_render();
|
||||
@@ -1125,6 +1126,53 @@ void ui_set_ble_enabled(bool enabled)
|
||||
s->ble_enabled = enabled;
|
||||
}
|
||||
|
||||
void ui_set_link_transports(uint8_t mask)
|
||||
{
|
||||
struct ui_state *s = get_state();
|
||||
|
||||
if (s->link_transports == mask) {
|
||||
return;
|
||||
}
|
||||
s->link_transports = mask;
|
||||
if (ui_initialized) {
|
||||
schedule_render();
|
||||
}
|
||||
}
|
||||
|
||||
void ui_set_wifi(uint8_t state, const char *ssid, const char *ip, uint16_t port)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_ZEPHCORE_COMPANION_WIFI)
|
||||
struct ui_state *s = get_state();
|
||||
char new_ssid[sizeof(s->wifi_ssid)];
|
||||
char new_ip[sizeof(s->wifi_ip)];
|
||||
|
||||
snprintf(new_ssid, sizeof(new_ssid), "%s", ssid ? ssid : "");
|
||||
snprintf(new_ip, sizeof(new_ip), "%s", ip ? ip : "");
|
||||
|
||||
if (s->wifi_state == state && s->wifi_port == port &&
|
||||
strcmp(s->wifi_ssid, new_ssid) == 0 && strcmp(s->wifi_ip, new_ip) == 0) {
|
||||
return;
|
||||
}
|
||||
s->wifi_state = state;
|
||||
s->wifi_port = port;
|
||||
memcpy(s->wifi_ssid, new_ssid, sizeof(new_ssid));
|
||||
memcpy(s->wifi_ip, new_ip, sizeof(new_ip));
|
||||
|
||||
/* Repaint only a page that shows it; e-paper included, since this
|
||||
* changes rarely. */
|
||||
#ifdef CONFIG_ZEPHCORE_UI_DISPLAY
|
||||
if (ui_initialized && ui_pages_current() == UI_PAGE_WIFI) {
|
||||
schedule_render();
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
ARG_UNUSED(state);
|
||||
ARG_UNUSED(ssid);
|
||||
ARG_UNUSED(ip);
|
||||
ARG_UNUSED(port);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ui_set_buzzer_mode(uint8_t mode)
|
||||
{
|
||||
struct ui_state *s = get_state();
|
||||
|
||||
@@ -287,6 +287,17 @@ public:
|
||||
bool handleInput(char c) override;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
/* ===== WifiScreen: WiFi companion state and the address the app uses ===== */
|
||||
class WifiScreen : public UIScreen {
|
||||
JoystickUITask *_task;
|
||||
public:
|
||||
WifiScreen(JoystickUITask *task);
|
||||
int render(JoystickDisplay &display) override;
|
||||
bool handleInput(char c) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* ===== StopwatchScreen ===== */
|
||||
class StopwatchScreen : public UIScreen {
|
||||
JoystickUITask *_task;
|
||||
|
||||
@@ -117,13 +117,13 @@ extern "C" void ui_notify(enum ui_event event)
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case UI_EVENT_BLE_CONNECTED:
|
||||
s_task->setBLEConnected(true);
|
||||
case UI_EVENT_APP_CONNECTED:
|
||||
s_task->setAppConnected(true);
|
||||
s_task->notify();
|
||||
break;
|
||||
|
||||
case UI_EVENT_BLE_DISCONNECTED:
|
||||
s_task->setBLEConnected(false);
|
||||
case UI_EVENT_APP_DISCONNECTED:
|
||||
s_task->setAppConnected(false);
|
||||
s_task->notify();
|
||||
break;
|
||||
|
||||
@@ -269,4 +269,24 @@ extern "C" void ui_set_gps_enabled(bool) {}
|
||||
extern "C" void ui_set_gps_state(uint8_t, uint32_t, uint32_t) {}
|
||||
extern "C" void ui_set_buzzer_mode(uint8_t) {}
|
||||
extern "C" void ui_set_offgrid_mode(bool) {}
|
||||
/* Kept for the WiFi screen (System > Info > WiFi); WiFi companion builds only.
|
||||
* Both arrive on the main thread, where the UI runs. */
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
extern "C" void ui_set_link_transports(uint8_t mask)
|
||||
{
|
||||
if (s_task) {
|
||||
s_task->setLinkTransports(mask);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ui_set_wifi(uint8_t state, const char *ssid, const char *ip, uint16_t port)
|
||||
{
|
||||
if (s_task) {
|
||||
s_task->setWifi(state, ssid, ip, port);
|
||||
}
|
||||
}
|
||||
#else
|
||||
extern "C" void ui_set_link_transports(uint8_t) {}
|
||||
extern "C" void ui_set_wifi(uint8_t, const char *, const char *, uint16_t) {}
|
||||
#endif
|
||||
extern "C" void ui_set_msg_count(uint16_t count) {}
|
||||
@@ -512,7 +512,7 @@ JoystickUITask::JoystickUITask()
|
||||
_next_refresh(0), _last_blt_ms(0), _pending_render(false), _render_immediate(false),
|
||||
_screen_off_ms(AUTO_OFF_MILLIS), _was_display_on(false),
|
||||
_cached_batt_mv(0), _battery_display_mode(0),
|
||||
_brightness(100), _wake_on_msg(true), _ble_connected(false),
|
||||
_brightness(100), _wake_on_msg(true), _app_connected(false),
|
||||
_ble_enabled(true), _noise_floor(-120),
|
||||
_pkt_recv(0), _pkt_sent(0), _pkt_errors(0), _alert_expiry(0),
|
||||
_locked(false), _lock_step(0),
|
||||
@@ -596,6 +596,9 @@ void JoystickUITask::begin(BaseChatMesh *mesh, mesh::ZephyrRTCClock *rtc, NodePr
|
||||
_rename_node = new RenameNodeScreen(this);
|
||||
_ble_code = new BLECodeScreen(this);
|
||||
_stats = new StatsScreen(this);
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
_wifi = new WifiScreen(this);
|
||||
#endif
|
||||
_stopwatch = new StopwatchScreen(this);
|
||||
_countdown = new CountdownScreen(this);
|
||||
_snake = new SnakeScreen(this);
|
||||
@@ -646,6 +649,17 @@ void JoystickUITask::gotoT9InputScreenWithPrefix(const char *prefix)
|
||||
void JoystickUITask::gotoRenameNodeScreen() { setCurrScreen(_rename_node); }
|
||||
void JoystickUITask::gotoBLECodeScreen() { setCurrScreen(_ble_code); }
|
||||
void JoystickUITask::gotoStatsScreen() { setCurrScreen(_stats); }
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
void JoystickUITask::gotoWifiScreen() { setCurrScreen(_wifi); }
|
||||
|
||||
void JoystickUITask::setWifi(uint8_t state, const char *ssid, const char *ip, uint16_t port)
|
||||
{
|
||||
_wifi_state = state;
|
||||
_wifi_port = port;
|
||||
snprintf(_wifi_ssid, sizeof(_wifi_ssid), "%s", ssid ? ssid : "");
|
||||
snprintf(_wifi_ip, sizeof(_wifi_ip), "%s", ip ? ip : "");
|
||||
}
|
||||
#endif
|
||||
void JoystickUITask::gotoStopwatchScreen() { setCurrScreen(_stopwatch); }
|
||||
void JoystickUITask::gotoCountdownScreen() { setCurrScreen(_countdown); }
|
||||
void JoystickUITask::gotoSnakeScreen() { setCurrScreen(_snake); }
|
||||
@@ -1165,19 +1179,19 @@ void JoystickUITask::newMsg(uint8_t path_len, const char *from_name, const char
|
||||
{
|
||||
(void)msgcount; /* tracked by CompanionMesh */
|
||||
if (_unread) {
|
||||
/* When BLE phone is connected it pulls offline queue and marks read;
|
||||
* keep the message in our local history but don't count as unread. */
|
||||
/* A connected app (any transport) pulls the offline queue and marks it
|
||||
* read; keep the message in our local history but don't count as unread. */
|
||||
_unread->addPreview(path_len, from_name, text,
|
||||
/*initially_read=*/_ble_connected);
|
||||
/*initially_read=*/_app_connected);
|
||||
}
|
||||
/* Wake display if wake on msg is enabled and no BLE peer is connected.
|
||||
/* Wake display if wake on msg is enabled and no app is connected.
|
||||
* mc_display_on() already reschedules display.c's auto-off timer. */
|
||||
if (_wake_on_msg && !_ble_connected && !_display.isOn()) {
|
||||
if (_wake_on_msg && !_app_connected && !_display.isOn()) {
|
||||
_display.turnOn();
|
||||
}
|
||||
_next_refresh = 0;
|
||||
#ifdef CONFIG_ZEPHCORE_UI_BUZZER
|
||||
if (!_ble_connected) {
|
||||
if (!_app_connected) {
|
||||
buzzer_play("MsgRcv3:d=4,o=6,b=200:32e,32g,32b,16c7");
|
||||
}
|
||||
#endif
|
||||
@@ -1201,16 +1215,16 @@ void JoystickUITask::newChannelMsg(const char *channel_name, const char *text,
|
||||
if (_unread) {
|
||||
char ch_from[48];
|
||||
snprintf(ch_from, sizeof(ch_from), "#%s", channel_name ? channel_name : "?");
|
||||
/* BLE-connected → phone reads via offline queue, don't count as unread. */
|
||||
/* App connected → it reads via the offline queue, don't count as unread. */
|
||||
_unread->addPreview(path_len, ch_from, text,
|
||||
/*initially_read=*/_ble_connected);
|
||||
/*initially_read=*/_app_connected);
|
||||
}
|
||||
if (_wake_on_msg && !_ble_connected && !_display.isOn()) {
|
||||
if (_wake_on_msg && !_app_connected && !_display.isOn()) {
|
||||
_display.turnOn(); /* display.c reschedules auto-off internally */
|
||||
}
|
||||
_next_refresh = 0;
|
||||
#ifdef CONFIG_ZEPHCORE_UI_BUZZER
|
||||
if (!_ble_connected) {
|
||||
if (!_app_connected) {
|
||||
buzzer_play("kerplop:d=16,o=6,b=120:32g#,32c#");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -74,6 +74,9 @@ public:
|
||||
void gotoRenameNodeScreen();
|
||||
void gotoBLECodeScreen();
|
||||
void gotoStatsScreen();
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
void gotoWifiScreen();
|
||||
#endif
|
||||
void gotoStopwatchScreen();
|
||||
void gotoCountdownScreen();
|
||||
void gotoSnakeScreen();
|
||||
@@ -180,11 +183,23 @@ public:
|
||||
uint32_t getPktSent() const { return _pkt_sent; }
|
||||
uint32_t getPktErrors() const { return _pkt_errors; }
|
||||
|
||||
/* BLE status (fed from main companion loop) */
|
||||
void setBLEConnected(bool connected) { _ble_connected = connected; }
|
||||
bool isBLEConnected() const { return _ble_connected; }
|
||||
/* An app is connected on some transport (fed from main companion loop) */
|
||||
void setAppConnected(bool connected) { _app_connected = connected; }
|
||||
bool isAppConnected() const { return _app_connected; }
|
||||
void setBLEEnabled(bool enabled) { _ble_enabled = enabled; }
|
||||
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
/* WiFi companion state, pushed by ui_set_wifi() / ui_set_link_transports()
|
||||
* on the main thread, read by WifiScreen. */
|
||||
void setWifi(uint8_t state, const char *ssid, const char *ip, uint16_t port);
|
||||
void setLinkTransports(uint8_t mask) { _link_transports = mask; }
|
||||
uint8_t getWifiState() const { return _wifi_state; }
|
||||
const char *getWifiSsid() const { return _wifi_ssid; }
|
||||
const char *getWifiIp() const { return _wifi_ip; }
|
||||
uint16_t getWifiPort() const { return _wifi_port; }
|
||||
uint8_t getLinkTransports() const { return _link_transports; }
|
||||
#endif
|
||||
|
||||
/* RepeaterAdmin callbacks */
|
||||
void onRepeaterAdminLoginResult(const uint8_t *pub_key_prefix, bool success,
|
||||
uint8_t permissions, uint32_t server_time);
|
||||
@@ -233,6 +248,9 @@ private:
|
||||
RenameNodeScreen *_rename_node;
|
||||
BLECodeScreen *_ble_code;
|
||||
StatsScreen *_stats;
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
WifiScreen *_wifi = nullptr;
|
||||
#endif
|
||||
StopwatchScreen *_stopwatch;
|
||||
CountdownScreen *_countdown;
|
||||
SnakeScreen *_snake;
|
||||
@@ -264,8 +282,15 @@ private:
|
||||
int _battery_display_mode;
|
||||
uint8_t _brightness;
|
||||
bool _wake_on_msg;
|
||||
bool _ble_connected;
|
||||
bool _app_connected;
|
||||
bool _ble_enabled;
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
uint8_t _wifi_state = 0; /* enum ui_wifi_state */
|
||||
uint8_t _link_transports = 0; /* UI_LINK_* bits */
|
||||
uint16_t _wifi_port = 0;
|
||||
char _wifi_ssid[33] = {};
|
||||
char _wifi_ip[16] = {};
|
||||
#endif
|
||||
int16_t _noise_floor;
|
||||
uint32_t _pkt_recv, _pkt_sent, _pkt_errors;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <helpers/time_sync.h>
|
||||
#include <helpers/ui/display.h>
|
||||
#include <helpers/ui/ui_mesh_actions.h>
|
||||
#include <helpers/ui/ui_task.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/random/random.h>
|
||||
#include <math.h>
|
||||
@@ -40,7 +41,11 @@ enum SysDspItem { SYSDSP_BRIGHT=0, SYSDSP_SCROFF, SYSDSP_BATT, SYSDSP_WAKE,
|
||||
#endif
|
||||
SYSDSP_INPUT_ROTATE, SYSDSP_COUNT };
|
||||
/* Info submenu items */
|
||||
enum SysInfoItem { SYSINFO_TIME=0, SYSINFO_STATS, SYSINFO_RADIO, SYSINFO_COUNT };
|
||||
enum SysInfoItem { SYSINFO_TIME=0, SYSINFO_STATS, SYSINFO_RADIO,
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
SYSINFO_WIFI,
|
||||
#endif
|
||||
SYSINFO_COUNT };
|
||||
/* Power submenu items */
|
||||
enum SysPwrItem { SYSPWR_REBOOT=0, SYSPWR_SHUTDOWN, SYSPWR_COUNT };
|
||||
|
||||
@@ -112,7 +117,11 @@ int SystemScreen::render(JoystickDisplay &display)
|
||||
return 500;
|
||||
}
|
||||
if (_mode == SYSMODE_INFO) {
|
||||
static const char * const kItems[SYSINFO_COUNT] = { "Time", "System Stats", "Radio Stats" };
|
||||
static const char * const kItems[SYSINFO_COUNT] = { "Time", "System Stats", "Radio Stats",
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
"WiFi",
|
||||
#endif
|
||||
};
|
||||
renderSubMenu(display, "Info", _selected, kItems, SYSINFO_COUNT);
|
||||
return 500;
|
||||
}
|
||||
@@ -258,6 +267,9 @@ bool SystemScreen::handleInput(char c)
|
||||
case SYSINFO_TIME: _task->gotoSystemTimeScreen(); return true;
|
||||
case SYSINFO_STATS: _task->gotoStatsScreen(); return true;
|
||||
case SYSINFO_RADIO: _task->gotoRadioStatsScreen(); return true;
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
case SYSINFO_WIFI: _task->gotoWifiScreen(); return true;
|
||||
#endif
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
@@ -970,6 +982,60 @@ bool StatsScreen::handleInput(char c)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ZEPHCORE_COMPANION_WIFI
|
||||
WifiScreen::WifiScreen(JoystickUITask *task)
|
||||
: _task(task)
|
||||
{
|
||||
}
|
||||
|
||||
/* Same states and wording as the button UI's WiFi page; redrawn every second. */
|
||||
int WifiScreen::render(JoystickDisplay &display)
|
||||
{
|
||||
renderScreenHeader(display, "WiFi", 0, 0);
|
||||
display.setTextSize(1);
|
||||
|
||||
char line[48];
|
||||
int y = kContentY + 2;
|
||||
uint8_t state = _task->getWifiState();
|
||||
|
||||
if (state == UI_WIFI_OFF) {
|
||||
display.setColor(JoystickDisplay::LIGHT);
|
||||
display.drawTextLeftAlign(0, y, "Status: off");
|
||||
y += kMenuLineH;
|
||||
display.drawTextLeftAlign(0, y, "Set up via CLI");
|
||||
return 1000;
|
||||
}
|
||||
|
||||
display.setColor(state == UI_WIFI_UP ? JoystickDisplay::GREEN : JoystickDisplay::YELLOW);
|
||||
display.drawTextLeftAlign(0, y, state == UI_WIFI_UP ? "Status: connected" : "Status: joining");
|
||||
y += kMenuLineH;
|
||||
|
||||
display.setColor(JoystickDisplay::LIGHT);
|
||||
snprintf(line, sizeof(line), "SSID: %s", _task->getWifiSsid());
|
||||
display.drawTextLeftAlign(0, y, line);
|
||||
y += kMenuLineH;
|
||||
if (state != UI_WIFI_UP) {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
snprintf(line, sizeof(line), "IP: %s", _task->getWifiIp());
|
||||
display.drawTextLeftAlign(0, y, line);
|
||||
y += kMenuLineH;
|
||||
snprintf(line, sizeof(line), "Port: %u", (unsigned)_task->getWifiPort());
|
||||
display.drawTextLeftAlign(0, y, line);
|
||||
y += kMenuLineH;
|
||||
display.drawTextLeftAlign(0, y, (_task->getLinkTransports() & UI_LINK_TCP)
|
||||
? "App: connected" : "App: none");
|
||||
return 1000;
|
||||
}
|
||||
|
||||
bool WifiScreen::handleInput(char c)
|
||||
{
|
||||
if (c == KEY_CANCEL || c == KEY_HOME) { _task->gotoSystemScreen(); return true; }
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
TelemetryScreen::TelemetryScreen(JoystickUITask *task, mesh::RTCClock *rtc)
|
||||
: _task(task), _rtc(rtc), _selected(0)
|
||||
{
|
||||
|
||||
@@ -115,6 +115,17 @@ WEAK void ui_set_ble_enabled(bool enabled)
|
||||
ARG_UNUSED(enabled);
|
||||
}
|
||||
|
||||
WEAK void ui_set_link_transports(uint8_t mask)
|
||||
{
|
||||
ARG_UNUSED(mask);
|
||||
}
|
||||
|
||||
WEAK void ui_set_wifi(uint8_t state, const char *ssid, const char *ip,
|
||||
uint16_t port)
|
||||
{
|
||||
ARG_UNUSED(state); ARG_UNUSED(ssid); ARG_UNUSED(ip); ARG_UNUSED(port);
|
||||
}
|
||||
|
||||
WEAK void ui_set_buzzer_mode(uint8_t mode)
|
||||
{
|
||||
ARG_UNUSED(mode);
|
||||
|
||||
@@ -26,8 +26,20 @@ enum ui_event {
|
||||
UI_EVENT_CHANNEL_MSG, /* New channel message received */
|
||||
UI_EVENT_ROOM_MSG, /* New room message received */
|
||||
UI_EVENT_ACK, /* ACK received */
|
||||
UI_EVENT_BLE_CONNECTED, /* BLE peer connected */
|
||||
UI_EVENT_BLE_DISCONNECTED, /* BLE peer disconnected */
|
||||
UI_EVENT_APP_CONNECTED, /* an app connected, on any transport */
|
||||
UI_EVENT_APP_DISCONNECTED, /* the last app session ended */
|
||||
};
|
||||
|
||||
/* Companion transports with a client connected (ui_set_link_transports). */
|
||||
#define UI_LINK_BLE (1u << 0)
|
||||
#define UI_LINK_USB (1u << 1) /* wired serial: a binary app or a text-CLI session */
|
||||
#define UI_LINK_TCP (1u << 2) /* the WiFi companion's app socket */
|
||||
|
||||
/* WiFi companion station state (ui_set_wifi). */
|
||||
enum ui_wifi_state {
|
||||
UI_WIFI_OFF = 0, /* wifi.enabled 0, or no network set */
|
||||
UI_WIFI_JOINING, /* joining, or waiting for a DHCP lease */
|
||||
UI_WIFI_UP, /* associated with an IPv4 address */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -163,6 +175,22 @@ void ui_set_gps_state(uint8_t state, uint32_t last_fix_age_s, uint32_t next_sear
|
||||
*/
|
||||
void ui_set_ble_enabled(bool enabled);
|
||||
|
||||
/**
|
||||
* Which companion transports have a client connected (UI_LINK_* bits).
|
||||
* Pushed on every link edge; the app-connected state itself comes from
|
||||
* UI_EVENT_APP_CONNECTED / _DISCONNECTED.
|
||||
*/
|
||||
void ui_set_link_transports(uint8_t mask);
|
||||
|
||||
/**
|
||||
* WiFi companion state for the WiFi page. ssid and ip are copied; either may
|
||||
* be NULL or empty. Repaints only when something changed.
|
||||
*
|
||||
* @param state enum ui_wifi_state
|
||||
* @param port TCP port the app connects to
|
||||
*/
|
||||
void ui_set_wifi(uint8_t state, const char *ssid, const char *ip, uint16_t port);
|
||||
|
||||
/**
|
||||
* Set notification mode (for display page).
|
||||
*/
|
||||
|
||||
@@ -284,16 +284,41 @@ static void companion_session_cleanup(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Which transports have a client right now, for the display (UI_LINK_*). */
|
||||
static uint8_t link_transports(void)
|
||||
{
|
||||
uint8_t mask = 0;
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT)
|
||||
if (zephcore_ble_is_connected()) {
|
||||
mask |= UI_LINK_BLE;
|
||||
}
|
||||
#endif
|
||||
#if ZEPHCORE_USB_STACK
|
||||
if (zephcore_usb_companion_link_up()) {
|
||||
mask |= UI_LINK_USB;
|
||||
}
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_ZEPHCORE_TRANSPORT_TCP)
|
||||
if (tcp_companion_is_connected()) {
|
||||
mask |= UI_LINK_TCP;
|
||||
}
|
||||
#endif
|
||||
return mask;
|
||||
}
|
||||
|
||||
/* MESH_EVENT_LINK: a transport (USB and TCP sessions included) connected or
|
||||
* disconnected. */
|
||||
* disconnected. The app-connected events stay transport-agnostic (they gate
|
||||
* buzzer, LED and unread handling); the mask says which transport it is. */
|
||||
static void process_link_change(void)
|
||||
{
|
||||
ui_set_link_transports(link_transports());
|
||||
if (atomic_set(&link_ups, 0) > 0) {
|
||||
ui_notify(UI_EVENT_BLE_CONNECTED);
|
||||
ui_notify(UI_EVENT_APP_CONNECTED);
|
||||
}
|
||||
if (atomic_set(&link_downs, 0) > 0 && !companion_serial.isConnected()) {
|
||||
companion_session_cleanup();
|
||||
ui_notify(UI_EVENT_BLE_DISCONNECTED);
|
||||
ui_notify(UI_EVENT_APP_DISCONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,6 +486,9 @@ static void mesh_event_loop(void)
|
||||
#endif
|
||||
|
||||
mesh_housekeeping_ui_refresh();
|
||||
#if IS_ENABLED(CONFIG_ZEPHCORE_COMPANION_WIFI) && defined(ZEPHCORE_LORA)
|
||||
companion_wifi_ui_refresh();
|
||||
#endif
|
||||
|
||||
if (companion_mesh_ptr) {
|
||||
companion_mesh_ptr->timeSyncTick();
|
||||
|
||||
Reference in new issue
Block a user