Updated all wifi endpoints to use protobufs
This commit is contained in:
@@ -17,37 +17,6 @@ export enum MessageTopic {
|
|||||||
rssi = 'rssi'
|
rssi = 'rssi'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WifiStatus = {
|
|
||||||
status: number
|
|
||||||
local_ip: number
|
|
||||||
mac_address: string
|
|
||||||
rssi: number
|
|
||||||
ssid: string
|
|
||||||
bssid: string
|
|
||||||
channel: number
|
|
||||||
subnet_mask: number
|
|
||||||
gateway_ip: number
|
|
||||||
dns_ip_1: number
|
|
||||||
dns_ip_2?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type KnownNetworkItem = {
|
|
||||||
ssid: string
|
|
||||||
password: string
|
|
||||||
static_ip_config: boolean
|
|
||||||
local_ip?: number
|
|
||||||
subnet_mask?: number
|
|
||||||
gateway_ip?: number
|
|
||||||
dns_ip_1?: number
|
|
||||||
dns_ip_2?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type WifiSettings = {
|
|
||||||
hostname: string
|
|
||||||
priority_RSSI: boolean
|
|
||||||
wifi_networks: KnownNetworkItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type vector = { x: number; y: number }
|
export type vector = { x: number; y: number }
|
||||||
|
|
||||||
export type GithubRelease = {
|
export type GithubRelease = {
|
||||||
@@ -59,18 +28,6 @@ export type GithubRelease = {
|
|||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type NetworkList = {
|
|
||||||
networks: NetworkItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NetworkItem = {
|
|
||||||
rssi: number
|
|
||||||
ssid: string
|
|
||||||
bssid: string
|
|
||||||
channel: number
|
|
||||||
encryption_type: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Rssi = {
|
export type Rssi = {
|
||||||
rssi: number
|
rssi: number
|
||||||
ssid: string
|
ssid: string
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
import { fly } from 'svelte/transition'
|
import { fly } from 'svelte/transition'
|
||||||
import { onMount, onDestroy } from 'svelte'
|
import { onMount, onDestroy } from 'svelte'
|
||||||
import RssiIndicator from '$lib/components/statusbar/RSSIIndicator.svelte'
|
import RssiIndicator from '$lib/components/statusbar/RSSIIndicator.svelte'
|
||||||
import type { NetworkItem, NetworkList } from '$lib/types/models'
|
import { type WifiNetworkScan, type Response as ProtoResponse } from '$lib/platform_shared/api'
|
||||||
import { api } from '$lib/api'
|
import { api } from '$lib/api'
|
||||||
import { AP, Network, Reload, Cancel } from '$lib/components/icons'
|
import { AP, Network, Reload, Cancel } from '$lib/components/icons'
|
||||||
import { modals, exitBeforeEnter, type ModalProps } from 'svelte-modals'
|
import { modals, exitBeforeEnter, type ModalProps } from 'svelte-modals'
|
||||||
|
|
||||||
let { isOpen, storeNetwork }: ModalProps = $props()
|
let { isOpen, storeNetwork }: ModalProps = $props()
|
||||||
|
|
||||||
const encryptionType = [
|
const encryptionTypes = [
|
||||||
'Open',
|
'Open',
|
||||||
'WEP',
|
'WEP',
|
||||||
'WPA PSK',
|
'WPA PSK',
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
'WAPI PSK'
|
'WAPI PSK'
|
||||||
]
|
]
|
||||||
|
|
||||||
let listOfNetworks: NetworkItem[] = $state([])
|
let listOfNetworks = $state<WifiNetworkScan[]>([])
|
||||||
|
|
||||||
let scanActive = $state(false)
|
let scanActive = $state(false)
|
||||||
|
|
||||||
@@ -38,13 +38,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function pollingResults() {
|
async function pollingResults() {
|
||||||
const result = await api.get<NetworkList>('/api/wifi/networks')
|
const result = await api.get<ProtoResponse>('/api/wifi/networks')
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
console.error(`Error occurred while fetching: `, result.inner)
|
console.error(`Error occurred while fetching: `, result.inner)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
let response = result.inner
|
if (result.inner.wifiNetworkList) {
|
||||||
listOfNetworks = response.networks
|
listOfNetworks = result.inner.wifiNetworkList.networks
|
||||||
|
}
|
||||||
scanActive = false
|
scanActive = false
|
||||||
if (listOfNetworks.length) {
|
if (listOfNetworks.length) {
|
||||||
clearInterval(pollingId)
|
clearInterval(pollingId)
|
||||||
@@ -106,7 +107,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="font-bold">{network.ssid}</div>
|
<div class="font-bold">{network.ssid}</div>
|
||||||
<div class="text-sm opacity-75">
|
<div class="text-sm opacity-75">
|
||||||
Security: {encryptionType[network.encryption_type]},
|
Security: {encryptionTypes[network.encryptionType]},
|
||||||
Channel: {network.channel}
|
Channel: {network.channel}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,8 +10,13 @@
|
|||||||
import ScanNetworks from './Scan.svelte'
|
import ScanNetworks from './Scan.svelte'
|
||||||
import Spinner from '$lib/components/Spinner.svelte'
|
import Spinner from '$lib/components/Spinner.svelte'
|
||||||
import InfoDialog from '$lib/components/InfoDialog.svelte'
|
import InfoDialog from '$lib/components/InfoDialog.svelte'
|
||||||
import { type WifiStatus } from '$lib/types/models'
|
import {
|
||||||
import { WifiSettings, WifiNetwork, Response, Request } from '$lib/platform_shared/api'
|
type WifiStatus,
|
||||||
|
type WifiSettings,
|
||||||
|
type WifiNetwork,
|
||||||
|
type Response as ProtoResponse,
|
||||||
|
Request
|
||||||
|
} from '$lib/platform_shared/api'
|
||||||
import { api } from '$lib/api'
|
import { api } from '$lib/api'
|
||||||
import { ipToUint32, uint32ToIp, isValidIpString } from '$lib/utilities'
|
import { ipToUint32, uint32ToIp, isValidIpString } from '$lib/utilities'
|
||||||
import {
|
import {
|
||||||
@@ -80,17 +85,19 @@
|
|||||||
let formErrorhostname = $state(false)
|
let formErrorhostname = $state(false)
|
||||||
|
|
||||||
async function getWifiStatus() {
|
async function getWifiStatus() {
|
||||||
const result = await api.get<WifiStatus>('/api/wifi/sta/status')
|
const result = await api.get<ProtoResponse>('/api/wifi/sta/status')
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
console.error(`Error occurred while fetching: `, result.inner)
|
console.error(`Error occurred while fetching: `, result.inner)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wifiStatus = result.inner
|
if (result.inner.wifiStatus) {
|
||||||
|
wifiStatus = result.inner.wifiStatus
|
||||||
|
}
|
||||||
return wifiStatus
|
return wifiStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getWifiSettings() {
|
async function getWifiSettings() {
|
||||||
const result = await api.get<Response>('/api/wifi/sta/settings')
|
const result = await api.get<ProtoResponse>('/api/wifi/sta/settings')
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
console.error(`Error occurred while fetching: `, result.inner)
|
console.error(`Error occurred while fetching: `, result.inner)
|
||||||
return
|
return
|
||||||
@@ -101,7 +108,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function postWiFiSettings(data: WifiSettings) {
|
async function postWiFiSettings(data: WifiSettings) {
|
||||||
const result = await api.post_proto<Response>('/api/wifi/sta/settings', Request.create({ wifiSettings: data }))
|
const result = await api.post_proto<ProtoResponse>('/api/wifi/sta/settings', Request.create({ wifiSettings: data }))
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
console.error(`Error occurred while fetching: `, result.inner)
|
console.error(`Error occurred while fetching: `, result.inner)
|
||||||
notifications.error('User not authorized.', 3000)
|
notifications.error('User not authorized.', 3000)
|
||||||
@@ -330,7 +337,7 @@
|
|||||||
<StatusItem
|
<StatusItem
|
||||||
icon={Home}
|
icon={Home}
|
||||||
title="IP Address"
|
title="IP Address"
|
||||||
description={uint32ToIp(wifiStatus.local_ip)}
|
description={uint32ToIp(wifiStatus.localIp)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatusItem icon={WiFi} title="RSSI" description={`${wifiStatus.rssi} dBm`}>
|
<StatusItem icon={WiFi} title="RSSI" description={`${wifiStatus.rssi} dBm`}>
|
||||||
@@ -361,7 +368,7 @@
|
|||||||
<StatusItem
|
<StatusItem
|
||||||
icon={MAC}
|
icon={MAC}
|
||||||
title="MAC Address"
|
title="MAC Address"
|
||||||
description={wifiStatus.mac_address}
|
description={wifiStatus.macAddress}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatusItem
|
<StatusItem
|
||||||
@@ -373,19 +380,19 @@
|
|||||||
<StatusItem
|
<StatusItem
|
||||||
icon={Gateway}
|
icon={Gateway}
|
||||||
title="Gateway IP"
|
title="Gateway IP"
|
||||||
description={uint32ToIp(wifiStatus.gateway_ip)}
|
description={uint32ToIp(wifiStatus.gatewayIp)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatusItem
|
<StatusItem
|
||||||
icon={Subnet}
|
icon={Subnet}
|
||||||
title="Subnet Mask"
|
title="Subnet Mask"
|
||||||
description={uint32ToIp(wifiStatus.subnet_mask)}
|
description={uint32ToIp(wifiStatus.subnetMask)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatusItem
|
<StatusItem
|
||||||
icon={DNS}
|
icon={DNS}
|
||||||
title="DNS"
|
title="DNS"
|
||||||
description={uint32ToIp(wifiStatus.dns_ip_1)}
|
description={uint32ToIp(wifiStatus.dnsIp1)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <esp_http_server.h>
|
#include <esp_http_server.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <ArduinoJson.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <filesystem.h>
|
#include <filesystem.h>
|
||||||
@@ -17,8 +16,6 @@
|
|||||||
|
|
||||||
class WiFiService : public StatefulService<WiFiSettings> {
|
class WiFiService : public StatefulService<WiFiSettings> {
|
||||||
private:
|
private:
|
||||||
static void getNetworks(JsonObject &root);
|
|
||||||
static void getNetworkStatus(JsonObject &root);
|
|
||||||
void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
|
void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||||
void onStationModeStop(WiFiEvent_t event, WiFiEventInfo_t info);
|
void onStationModeStop(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||||
static void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
|
static void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
|
||||||
|
|||||||
+35
-34
@@ -60,10 +60,23 @@ esp_err_t WiFiService::getNetworks(httpd_req_t *request) {
|
|||||||
return handleScan(request);
|
return handleScan(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonDocument doc;
|
api_Response response = api_Response_init_zero;
|
||||||
JsonObject root = doc.to<JsonObject>();
|
response.which_payload = api_Response_wifi_network_list_tag;
|
||||||
getNetworks(root);
|
api_WifiNetworkList &networkList = response.payload.wifi_network_list;
|
||||||
return WebServer::sendJson(request, 200, doc);
|
|
||||||
|
// Limit to max_count from options file (20)
|
||||||
|
size_t count = (numNetworks > 20) ? 20 : static_cast<size_t>(numNetworks);
|
||||||
|
networkList.networks_count = count;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
networkList.networks[i].rssi = WiFi.RSSI(i);
|
||||||
|
strncpy(networkList.networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networkList.networks[i].ssid) - 1);
|
||||||
|
strncpy(networkList.networks[i].bssid, WiFi.BSSIDstr(i).c_str(), sizeof(networkList.networks[i].bssid) - 1);
|
||||||
|
networkList.networks[i].channel = WiFi.channel(i);
|
||||||
|
networkList.networks[i].encryption_type = static_cast<uint32_t>(WiFi.encryptionType(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return WebServer::sendProto(request, 200, api_Response_fields, &response, api_Response_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiService::setupMDNS(const char *hostname) {
|
void WiFiService::setupMDNS(const char *hostname) {
|
||||||
@@ -74,47 +87,35 @@ void WiFiService::setupMDNS(const char *hostname) {
|
|||||||
MDNS.addServiceTxt("http", "tcp", "Firmware Version", APP_VERSION);
|
MDNS.addServiceTxt("http", "tcp", "Firmware Version", APP_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiService::getNetworks(JsonObject &root) {
|
|
||||||
JsonArray networks = root["networks"].to<JsonArray>();
|
|
||||||
int numNetworks = WiFi.scanComplete();
|
|
||||||
for (int i = 0; i < numNetworks; i++) {
|
|
||||||
JsonObject network = networks.add<JsonObject>();
|
|
||||||
network["rssi"] = WiFi.RSSI(i);
|
|
||||||
network["ssid"] = WiFi.SSID(i);
|
|
||||||
network["bssid"] = WiFi.BSSIDstr(i);
|
|
||||||
network["channel"] = WiFi.channel(i);
|
|
||||||
network["encryption_type"] = (uint8_t)WiFi.encryptionType(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t WiFiService::getNetworkStatus(httpd_req_t *request) {
|
esp_err_t WiFiService::getNetworkStatus(httpd_req_t *request) {
|
||||||
JsonDocument doc;
|
api_Response response = api_Response_init_zero;
|
||||||
JsonObject root = doc.to<JsonObject>();
|
response.which_payload = api_Response_wifi_status_tag;
|
||||||
getNetworkStatus(root);
|
api_WifiStatus &wifiStatus = response.payload.wifi_status;
|
||||||
return WebServer::sendJson(request, 200, doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiFiService::getNetworkStatus(JsonObject &root) {
|
|
||||||
wl_status_t status = WiFi.status();
|
wl_status_t status = WiFi.status();
|
||||||
root["status"] = (uint8_t)status;
|
wifiStatus.status = static_cast<uint32_t>(status);
|
||||||
|
|
||||||
if (status == WL_CONNECTED) {
|
if (status == WL_CONNECTED) {
|
||||||
root["local_ip"] = (uint32_t)(WiFi.localIP());
|
wifiStatus.local_ip = static_cast<uint32_t>(WiFi.localIP());
|
||||||
root["mac_address"] = WiFi.macAddress();
|
strncpy(wifiStatus.mac_address, WiFi.macAddress().c_str(), sizeof(wifiStatus.mac_address) - 1);
|
||||||
root["rssi"] = WiFi.RSSI();
|
wifiStatus.rssi = WiFi.RSSI();
|
||||||
root["ssid"] = WiFi.SSID();
|
strncpy(wifiStatus.ssid, WiFi.SSID().c_str(), sizeof(wifiStatus.ssid) - 1);
|
||||||
root["bssid"] = WiFi.BSSIDstr();
|
strncpy(wifiStatus.bssid, WiFi.BSSIDstr().c_str(), sizeof(wifiStatus.bssid) - 1);
|
||||||
root["channel"] = WiFi.channel();
|
wifiStatus.channel = WiFi.channel();
|
||||||
root["subnet_mask"] = (uint32_t)(WiFi.subnetMask());
|
wifiStatus.subnet_mask = static_cast<uint32_t>(WiFi.subnetMask());
|
||||||
root["gateway_ip"] = (uint32_t)(WiFi.gatewayIP());
|
wifiStatus.gateway_ip = static_cast<uint32_t>(WiFi.gatewayIP());
|
||||||
|
|
||||||
IPAddress dnsIP1 = WiFi.dnsIP(0);
|
IPAddress dnsIP1 = WiFi.dnsIP(0);
|
||||||
IPAddress dnsIP2 = WiFi.dnsIP(1);
|
IPAddress dnsIP2 = WiFi.dnsIP(1);
|
||||||
if (dnsIP1 != IPAddress(0, 0, 0, 0)) {
|
if (dnsIP1 != IPAddress(0, 0, 0, 0)) {
|
||||||
root["dns_ip_1"] = (uint32_t)(dnsIP1);
|
wifiStatus.dns_ip_1 = static_cast<uint32_t>(dnsIP1);
|
||||||
}
|
}
|
||||||
if (dnsIP2 != IPAddress(0, 0, 0, 0)) {
|
if (dnsIP2 != IPAddress(0, 0, 0, 0)) {
|
||||||
root["dns_ip_2"] = (uint32_t)(dnsIP2);
|
wifiStatus.dns_ip_2 = static_cast<uint32_t>(dnsIP2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return WebServer::sendProto(request, 200, api_Response_fields, &response, api_Response_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiService::manageSTA() {
|
void WiFiService::manageSTA() {
|
||||||
|
|||||||
@@ -24,6 +24,14 @@ api.WifiNetwork.password max_size:65
|
|||||||
api.WifiSettings.hostname max_size:33
|
api.WifiSettings.hostname max_size:33
|
||||||
api.WifiSettings.wifi_networks max_count:5
|
api.WifiSettings.wifi_networks max_count:5
|
||||||
|
|
||||||
|
api.WifiNetworkScan.ssid max_size:33
|
||||||
|
api.WifiNetworkScan.bssid max_size:18
|
||||||
|
api.WifiNetworkList.networks max_count:20
|
||||||
|
|
||||||
|
api.WifiStatus.mac_address max_size:18
|
||||||
|
api.WifiStatus.ssid max_size:33
|
||||||
|
api.WifiStatus.bssid max_size:18
|
||||||
|
|
||||||
api.MDNSTxtRecord.key max_size:32
|
api.MDNSTxtRecord.key max_size:32
|
||||||
api.MDNSTxtRecord.value max_size:64
|
api.MDNSTxtRecord.value max_size:64
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,35 @@ message WifiSettings {
|
|||||||
|
|
||||||
message WifiSettingsRequest {}
|
message WifiSettingsRequest {}
|
||||||
|
|
||||||
|
// WiFi scan result - single network found during scan
|
||||||
|
message WifiNetworkScan {
|
||||||
|
int32 rssi = 1;
|
||||||
|
string ssid = 2;
|
||||||
|
string bssid = 3;
|
||||||
|
uint32 channel = 4;
|
||||||
|
uint32 encryption_type = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response for /api/wifi/networks endpoint
|
||||||
|
message WifiNetworkList {
|
||||||
|
repeated WifiNetworkScan networks = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response for /api/wifi/sta/status endpoint
|
||||||
|
message WifiStatus {
|
||||||
|
uint32 status = 1;
|
||||||
|
uint32 local_ip = 2;
|
||||||
|
string mac_address = 3;
|
||||||
|
int32 rssi = 4;
|
||||||
|
string ssid = 5;
|
||||||
|
string bssid = 6;
|
||||||
|
uint32 channel = 7;
|
||||||
|
uint32 subnet_mask = 8;
|
||||||
|
uint32 gateway_ip = 9;
|
||||||
|
uint32 dns_ip_1 = 10;
|
||||||
|
uint32 dns_ip_2 = 11;
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Camera Settings - shared data types
|
// Camera Settings - shared data types
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -265,6 +294,8 @@ message Response {
|
|||||||
ServoSettings servo_settings = 20;
|
ServoSettings servo_settings = 20;
|
||||||
FileList file_list = 30;
|
FileList file_list = 30;
|
||||||
WifiSettings wifi_settings = 40;
|
WifiSettings wifi_settings = 40;
|
||||||
|
WifiNetworkList wifi_network_list = 41;
|
||||||
|
WifiStatus wifi_status = 42;
|
||||||
CameraSettings camera_settings = 50;
|
CameraSettings camera_settings = 50;
|
||||||
MDNSSettings mdns_settings = 60;
|
MDNSSettings mdns_settings = 60;
|
||||||
MDNSStatus mdns_status = 61;
|
MDNSStatus mdns_status = 61;
|
||||||
|
|||||||
Reference in New Issue
Block a user