mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 22:02:17 +01:00
feat: settings ops, the WiFi and frequency scans, and reboot for socket protocol 2
Step 1d of the protocol 2 core (docs/SECURITY_PLAN.md). - getSettings/saveSettings by section: general, network, mqtt, security, radio. A save is the settings route's request, so loop() applies it with the settings' own fromJSON(). ProtoSettings checks every field first: kind, range, string length, IP addresses. - Secrets are only reported as has*. A security save replies with the client's new token and closes the other sockets; other saves send settingsChanged to the other clients. - scanWifi runs an async scan from ESPNetwork, kept apart from the roaming scan, and wifiNetworks goes to the clients that asked. - beginFrequencyScan, endFrequencyScan and reboot run at once on async_tcp, as their routes do: a scan's end mustn't wait in the loop queue behind an unpair that waits for the scan to end (new op kind 'a'). - e2e: test_settings.py and a --reboot flag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
97a4e98183
commit
2517f40709
22 changed files with 1221 additions and 49 deletions
50
src/ProtoSettings.h
Normal file
50
src/ProtoSettings.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef PROTO_SETTINGS_H
|
||||
#define PROTO_SETTINGS_H
|
||||
#include <stdint.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include "ProtoSchema.h"
|
||||
|
||||
// Socket protocol 2's settings ops (docs/PROTOCOL.md): the sections that
|
||||
// getSettings and saveSettings name, and what a save's payload becomes. A
|
||||
// save is the settings route's request: its payload, in full names, is what
|
||||
// loop() hands to the settings' own fromJSON(), so the rules stay in one
|
||||
// place. Kept free of the settings and the web server so it can be unit
|
||||
// tested on the PC (pio test -e native).
|
||||
|
||||
enum class settings_section_t : uint8_t {
|
||||
general, // hostname, SSDP and the clock
|
||||
network, // the connection, WiFi, Ethernet and the IP address
|
||||
mqtt,
|
||||
security,
|
||||
radio
|
||||
};
|
||||
// The settings each part of a section belongs to, which loop() saves only
|
||||
// when a field of it was sent.
|
||||
enum class settings_part_t : uint8_t {
|
||||
general, // ConfigSettings: hostname, ssdpBroadcast
|
||||
ntp, // NTPSettings
|
||||
conn, // ConfigSettings: connType
|
||||
wifi, // WifiSettings
|
||||
ethernet, // EthernetSettings
|
||||
ip, // IPSettings
|
||||
mqtt, // MQTTSettings
|
||||
security, // SecuritySettings
|
||||
radio // transceiver_config_t
|
||||
};
|
||||
const char *settingsSectionName(settings_section_t section);
|
||||
// The section that payload d names in section. nullptr when it is good;
|
||||
// otherwise what is wrong with it, for a bad request reply.
|
||||
const char *parseSettingsSection(JsonObjectConst d, settings_section_t §ion);
|
||||
// saveSettings: the section d names, and in doc its fields under the names
|
||||
// the route reads. Each is checked against its kind and its range or length,
|
||||
// so nothing is cut short or wraps. An address may be "" to clear it. As
|
||||
// with every op, only what was sent is in it; a field the section doesn't
|
||||
// save, such as hasPassword, is refused. Without hasEthernet the Ethernet
|
||||
// fields are refused too. nullptr when it is good; otherwise what is wrong.
|
||||
const char *expandSettingsPayload(JsonObjectConst d, bool hasEthernet, settings_section_t §ion, JsonDocument &doc);
|
||||
// The parts that a save's request (from expandSettingsPayload) sets, as bits
|
||||
// 1 << settings_part_t. A route name such as hostname means another setting
|
||||
// in another section, hence the section.
|
||||
uint16_t settingsParts(settings_section_t section, JsonObjectConst request);
|
||||
inline bool settingsSets(uint16_t parts, settings_part_t part) { return parts & (1u << static_cast<uint8_t>(part)); }
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue