feat(gateway): add GatewayNetworkService and enhance runtime channel handling

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Tony
2026-04-29 23:54:33 +08:00
parent 4433fe97c7
commit 52aa2fc129
9 changed files with 661 additions and 12 deletions
@@ -10,6 +10,8 @@
#include <vector>
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "gateway_core.hpp"
#include "nvs.h"
@@ -80,6 +82,7 @@ class GatewayRuntime {
GatewayRuntime(BootProfile profile, GatewayRuntimeConfig config,
DaliDomainService* dali_domain);
~GatewayRuntime();
esp_err_t start();
@@ -126,6 +129,7 @@ class GatewayRuntime {
CommandDropReason last_enqueue_drop_reason_{CommandDropReason::kNone};
std::function<uint8_t(uint8_t gw, uint8_t raw_addr)> command_address_resolver_;
std::optional<WirelessInfo> wireless_info_;
SemaphoreHandle_t command_lock_{nullptr};
};
} // namespace gateway
@@ -25,6 +25,24 @@ constexpr uint8_t kCommandFramePrefix0 = 0x28;
constexpr uint8_t kCommandFramePrefix1 = 0x01;
constexpr uint8_t kNotifyFramePrefix = 0x22;
class LockGuard {
public:
explicit LockGuard(SemaphoreHandle_t lock) : lock_(lock) {
if (lock_ != nullptr) {
xSemaphoreTakeRecursive(lock_, portMAX_DELAY);
}
}
~LockGuard() {
if (lock_ != nullptr) {
xSemaphoreGiveRecursive(lock_);
}
}
private:
SemaphoreHandle_t lock_;
};
} // namespace
esp_err_t InitializeRuntimeNvs() {
@@ -158,7 +176,15 @@ GatewayRuntime::GatewayRuntime(BootProfile profile, GatewayRuntimeConfig config,
: profile_(profile),
config_(std::move(config)),
dali_domain_(dali_domain),
command_address_resolver_([](uint8_t, uint8_t raw_addr) { return raw_addr; }) {}
command_address_resolver_([](uint8_t, uint8_t raw_addr) { return raw_addr; }),
command_lock_(xSemaphoreCreateRecursiveMutex()) {}
GatewayRuntime::~GatewayRuntime() {
if (command_lock_ != nullptr) {
vSemaphoreDelete(command_lock_);
command_lock_ = nullptr;
}
}
esp_err_t GatewayRuntime::start() {
const esp_err_t err = settings_.open();
@@ -230,6 +256,7 @@ std::vector<uint8_t> GatewayRuntime::buildNotificationFrame(const std::vector<ui
}
bool GatewayRuntime::enqueueCommand(std::vector<uint8_t> command) {
LockGuard guard(command_lock_);
last_enqueue_drop_reason_ = CommandDropReason::kNone;
if (isQueryCommand(command) && hasPendingQueryCommand(command)) {
last_enqueue_drop_reason_ = CommandDropReason::kDuplicate;
@@ -246,6 +273,7 @@ bool GatewayRuntime::enqueueCommand(std::vector<uint8_t> command) {
}
std::optional<std::vector<uint8_t>> GatewayRuntime::popNextCommand() {
LockGuard guard(command_lock_);
if (pending_commands_.empty()) {
current_command_.reset();
return std::nullopt;
@@ -257,10 +285,12 @@ std::optional<std::vector<uint8_t>> GatewayRuntime::popNextCommand() {
}
void GatewayRuntime::completeCurrentCommand() {
LockGuard guard(command_lock_);
current_command_.reset();
}
bool GatewayRuntime::hasPendingQueryCommand(const std::vector<uint8_t>& command) const {
LockGuard guard(command_lock_);
const auto command_key = queryCommandKey(command);
if (!command_key.has_value()) {
return false;
@@ -277,6 +307,7 @@ bool GatewayRuntime::hasPendingQueryCommand(const std::vector<uint8_t>& command)
}
GatewayRuntime::CommandDropReason GatewayRuntime::lastEnqueueDropReason() const {
LockGuard guard(command_lock_);
return last_enqueue_drop_reason_;
}
@@ -293,6 +324,7 @@ void GatewayRuntime::setWirelessInfo(WirelessInfo info) {
void GatewayRuntime::setCommandAddressResolver(
std::function<uint8_t(uint8_t gw, uint8_t raw_addr)> resolver) {
LockGuard guard(command_lock_);
if (resolver) {
command_address_resolver_ = std::move(resolver);
return;