Enhance Gateway Network and Runtime Functionality

- Added a check in GatewayNetworkService::handleDaliRawFrame to ensure raw reporting is enabled for the gateway before processing the frame.
- Extended the JSON snapshot in GatewayNetworkService::gatewaySnapshotJson to include additional operation-related fields for each channel, providing more detailed status information.
- Updated GatewayRuntime::classifyCommandPriority to include new opcodes (0x66 and 0x67) in the control command classification, improving command handling.

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-06-13 20:13:33 +08:00
parent 530f0ecf12
commit fc4e9016cf
8 changed files with 1269 additions and 20 deletions
@@ -405,6 +405,9 @@ void GatewayBleBridge::handleDaliRawFrame(const DaliRawFrame& frame) {
if (!enabled_ || conn_handle_ == kInvalidConnectionHandle || frame.data.empty()) {
return;
}
if (!controller_.rawReportingEnabled(frame.gateway_id)) {
return;
}
notifyCharacteristic(frame.channel_index, LegacyRawPayload(frame.data));
}
@@ -52,6 +52,13 @@ struct GatewayChannelSnapshot {
uint8_t group_mask_high{0};
bool allocating{false};
int last_alloc_addr{0};
bool operation_active{false};
uint8_t operation_request_id{0};
uint16_t operation_id{0};
uint8_t operation_status{0};
uint8_t operation_progress{0};
uint8_t operation_target{0};
uint8_t operation_count{0};
};
struct GatewayControllerSnapshot {
@@ -109,8 +116,16 @@ class GatewayController {
bool bleEnabled() const;
bool wifiEnabled() const;
bool ipRouterEnabled() const;
bool rawReportingEnabled(uint8_t gateway_id) const;
GatewayControllerSnapshot snapshot();
struct ParsedTlv {
uint8_t type{0};
std::vector<uint8_t> value;
};
using ParsedTlvMap = std::map<uint8_t, ParsedTlv>;
private:
struct ReconciliationJob {
enum class Phase : uint8_t {
@@ -140,6 +155,30 @@ class GatewayController {
uint8_t short_address{0};
};
struct GatewayOperationRuntimeState {
bool active{false};
bool cancel_requested{false};
uint8_t request_id{0};
uint16_t operation_id{0};
uint8_t status{0};
uint8_t progress{0};
uint8_t target{0};
uint8_t count{0};
};
struct GatewayRawReportLease {
bool enabled{false};
TickType_t expires_at{0};
};
struct GatewayOperationTaskContext {
GatewayController* controller{nullptr};
uint8_t gateway_id{0};
uint8_t request_id{0};
uint16_t operation_id{0};
ParsedTlvMap fields;
};
struct TransactionWaiter {
uint8_t gateway_id{0};
uint8_t opcode{0};
@@ -150,7 +189,9 @@ class GatewayController {
};
static void TaskEntry(void* arg);
static void OperationTaskEntry(void* arg);
void taskLoop();
void runOperationTask(GatewayOperationTaskContext* context);
void dispatchCommand(const std::vector<uint8_t>& command);
void scheduleReconciliation(uint8_t gateway_id,
std::optional<GatewayCacheDaliTarget> target = std::nullopt);
@@ -171,6 +212,13 @@ class GatewayController {
void refreshRuntimeGatewayNames();
void publishPayload(uint8_t gateway_id, const std::vector<uint8_t>& payload);
void publishFrame(const std::vector<uint8_t>& frame);
void publishRawReportLeaseResponse(uint8_t gateway_id, uint8_t status);
void publishOperationEvent(uint8_t gateway_id, uint8_t request_id, uint16_t operation_id,
uint8_t event, uint8_t status, uint8_t progress,
uint8_t target, uint8_t count);
void publishOperationResultChunks(uint8_t gateway_id, uint8_t request_id,
uint16_t operation_id,
const std::vector<uint8_t>& tlv_payload);
bool transactionFrameMatches(const TransactionWaiter& waiter,
const std::vector<uint8_t>& frame) const;
void captureTransactionFrame(const std::vector<uint8_t>& frame);
@@ -219,6 +267,16 @@ class GatewayController {
bool gatewaySerialMatches(const std::vector<uint8_t>& command) const;
void handleGatewayIdentityCommand(uint8_t gateway_id, uint8_t op);
void handleAllocationCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
void handleRawReportLeaseCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
void handleGatewayOperationCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
bool operationActive(uint8_t gateway_id) const;
bool operationCancelRequested(uint8_t gateway_id, uint8_t request_id) const;
bool startOperation(uint8_t gateway_id, uint8_t request_id, uint16_t operation_id,
ParsedTlvMap fields);
void abortOperation(uint8_t gateway_id, uint8_t request_id);
void finishOperation(uint8_t gateway_id, uint8_t request_id, uint8_t status,
uint8_t progress, uint8_t target, uint8_t count);
ParsedTlvMap parseOperationTlvs(const uint8_t* data, size_t len, bool* ok) const;
void handleInternalSceneCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
void handleInternalGroupCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
void handleGatewayCacheCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
@@ -234,6 +292,7 @@ class GatewayController {
TaskHandle_t task_handle_{nullptr};
SemaphoreHandle_t maintenance_lock_{nullptr};
SemaphoreHandle_t transaction_lock_{nullptr};
SemaphoreHandle_t operation_lock_{nullptr};
std::vector<NotificationSink> notification_sinks_;
std::vector<BleStateSink> ble_state_sinks_;
std::vector<WifiStateSink> wifi_state_sinks_;
@@ -242,6 +301,8 @@ class GatewayController {
std::vector<TransactionWaiter*> transaction_waiters_;
std::map<uint8_t, ReconciliationJob> reconciliation_jobs_;
std::map<uint8_t, CacheRefreshJob> cache_refresh_jobs_;
std::map<uint8_t, GatewayOperationRuntimeState> operation_states_;
std::map<uint8_t, GatewayRawReportLease> raw_report_leases_;
std::atomic<int> maintenance_activity_gateway_{-1};
bool setup_mode_{false};
bool wireless_setup_mode_{false};
File diff suppressed because it is too large Load Diff
@@ -1298,6 +1298,9 @@ void GatewayNetworkService::handleDaliRawFrame(const DaliRawFrame& frame) {
if (!espnow_started_ || !espnow_connected_ || frame.data.empty()) {
return;
}
if (!controller_.rawReportingEnabled(frame.gateway_id)) {
return;
}
cJSON* payload = cJSON_CreateObject();
if (payload == nullptr) {
@@ -1606,6 +1609,13 @@ std::string GatewayNetworkService::gatewaySnapshotJson() {
cJSON_AddNumberToObject(item, "groupMaskHigh", channel.group_mask_high);
cJSON_AddBoolToObject(item, "isAllocAddr", channel.allocating);
cJSON_AddNumberToObject(item, "lastAllocAddr", channel.last_alloc_addr);
cJSON_AddBoolToObject(item, "operationActive", channel.operation_active);
cJSON_AddNumberToObject(item, "operationRequestId", channel.operation_request_id);
cJSON_AddNumberToObject(item, "operationId", channel.operation_id);
cJSON_AddNumberToObject(item, "operationStatus", channel.operation_status);
cJSON_AddNumberToObject(item, "operationProgress", channel.operation_progress);
cJSON_AddNumberToObject(item, "operationTarget", channel.operation_target);
cJSON_AddNumberToObject(item, "operationCount", channel.operation_count);
cJSON_AddItemToArray(channels, item);
}
cJSON_AddItemToObject(root, "channels", channels);
@@ -1757,4 +1767,4 @@ esp_err_t GatewayNetworkService::HandleJqJsGet(httpd_req_t* req) {
return httpd_resp_send_chunk(req, nullptr, 0);
}
} // namespace gateway
} // namespace gateway
@@ -370,7 +370,8 @@ GatewayRuntime::CommandPriority GatewayRuntime::classifyCommandPriority(
if (opcode == 0x00 || opcode == 0x01 || opcode == 0x03 || opcode == 0x04 || opcode == 0x07 ||
opcode == 0x08 || opcode == 0x10 || opcode == 0x11 || opcode == 0x12 || opcode == 0x13 ||
opcode == 0x0B || opcode == 0x17 || opcode == 0x18 || opcode == 0x37 || opcode == 0x38 ||
opcode == 0x60 || opcode == 0x61 || opcode == 0x62 || (opcode == 0x30 && addr == 0)) {
opcode == 0x60 || opcode == 0x61 || opcode == 0x62 || opcode == 0x66 || opcode == 0x67 ||
(opcode == 0x30 && addr == 0)) {
return CommandPriority::kControl;
}
return CommandPriority::kNormal;