feat(gateway): enhance GatewayNetworkService with HTTP and UDP support, add status LED control

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Tony
2026-04-30 00:54:53 +08:00
parent 52aa2fc129
commit 3d8d00c3dd
10 changed files with 599 additions and 30 deletions
@@ -31,10 +31,34 @@ struct GatewayControllerConfig {
bool internal_group_supported{true};
};
struct GatewayChannelSnapshot {
uint8_t channel_index{0};
uint8_t gateway_id{0};
std::string name;
std::string phy;
uint8_t scene_mask_low{0};
uint8_t scene_mask_high{0};
uint8_t group_mask_low{0};
uint8_t group_mask_high{0};
bool allocating{false};
int last_alloc_addr{0};
};
struct GatewayControllerSnapshot {
bool setup_mode{false};
bool ble_enabled{false};
bool wifi_enabled{false};
bool ip_router_enabled{false};
bool internal_scene_supported{false};
bool internal_group_supported{false};
std::vector<GatewayChannelSnapshot> channels;
};
class GatewayController {
public:
using NotificationSink = std::function<void(const std::vector<uint8_t>& frame)>;
using BleStateSink = std::function<void(bool enabled)>;
using WifiStateSink = std::function<void(uint8_t mode)>;
using GatewayNameSink = std::function<void(uint8_t gateway_id)>;
GatewayController(GatewayRuntime& runtime, DaliDomainService& dali_domain,
@@ -45,12 +69,14 @@ class GatewayController {
bool enqueueCommandFrame(const std::vector<uint8_t>& frame);
void addNotificationSink(NotificationSink sink);
void addBleStateSink(BleStateSink sink);
void addWifiStateSink(WifiStateSink sink);
void addGatewayNameSink(GatewayNameSink sink);
bool setupMode() const;
bool bleEnabled() const;
bool wifiEnabled() const;
bool ipRouterEnabled() const;
GatewayControllerSnapshot snapshot();
private:
struct InternalScene {
@@ -143,6 +169,7 @@ class GatewayController {
nvs_handle_t storage_{0};
std::vector<NotificationSink> notification_sinks_;
std::vector<BleStateSink> ble_state_sinks_;
std::vector<WifiStateSink> wifi_state_sinks_;
std::vector<GatewayNameSink> gateway_name_sinks_;
std::map<uint8_t, SceneStore> scenes_;
std::map<uint8_t, GroupStore> groups_;
@@ -80,6 +80,18 @@ void AppendPaddedName(std::vector<uint8_t>& out, std::string_view name) {
}
}
const char* PhyKindToString(DaliPhyKind phy_kind) {
switch (phy_kind) {
case DaliPhyKind::kNativeHardware:
return "native";
case DaliPhyKind::kSerialUart:
return "serial";
case DaliPhyKind::kCustom:
default:
return "custom";
}
}
} // namespace
GatewayController::GatewayController(GatewayRuntime& runtime, DaliDomainService& dali_domain,
@@ -157,6 +169,12 @@ void GatewayController::addBleStateSink(BleStateSink sink) {
}
}
void GatewayController::addWifiStateSink(WifiStateSink sink) {
if (sink) {
wifi_state_sinks_.push_back(std::move(sink));
}
}
void GatewayController::addGatewayNameSink(GatewayNameSink sink) {
if (sink) {
gateway_name_sinks_.push_back(std::move(sink));
@@ -179,6 +197,36 @@ bool GatewayController::ipRouterEnabled() const {
return ip_router_enabled_;
}
GatewayControllerSnapshot GatewayController::snapshot() {
GatewayControllerSnapshot out;
out.setup_mode = setup_mode_;
out.ble_enabled = ble_enabled_;
out.wifi_enabled = wifi_enabled_;
out.ip_router_enabled = ip_router_enabled_;
out.internal_scene_supported = config_.internal_scene_supported;
out.internal_group_supported = config_.internal_group_supported;
const auto channels = dali_domain_.channelInfo();
out.channels.reserve(channels.size());
for (const auto& channel : channels) {
const auto [scene_low, scene_high] = sceneMask(channel.gateway_id);
const auto [group_low, group_high] = groupMask(channel.gateway_id);
GatewayChannelSnapshot channel_snapshot;
channel_snapshot.channel_index = channel.channel_index;
channel_snapshot.gateway_id = channel.gateway_id;
channel_snapshot.name = channel.name;
channel_snapshot.phy = PhyKindToString(channel.phy_kind);
channel_snapshot.scene_mask_low = scene_low;
channel_snapshot.scene_mask_high = scene_high;
channel_snapshot.group_mask_low = group_low;
channel_snapshot.group_mask_high = group_high;
channel_snapshot.allocating = dali_domain_.isAllocAddr(channel.gateway_id);
channel_snapshot.last_alloc_addr = dali_domain_.lastAllocAddr(channel.gateway_id);
out.channels.push_back(std::move(channel_snapshot));
}
return out;
}
void GatewayController::TaskEntry(void* arg) {
static_cast<GatewayController*>(arg)->taskLoop();
}
@@ -257,6 +305,9 @@ void GatewayController::dispatchCommand(const std::vector<uint8_t>& command) {
} else if (addr == 1 || addr == 101) {
wifi_enabled_ = true;
}
for (const auto& sink : wifi_state_sinks_) {
sink(addr);
}
break;
case 0x05:
handleGatewayNameCommand(gateway_id, command);