diff --git a/components/dali_domain/src/dali_domain.cpp b/components/dali_domain/src/dali_domain.cpp index 9d4ede5..413e753 100644 --- a/components/dali_domain/src/dali_domain.cpp +++ b/components/dali_domain/src/dali_domain.cpp @@ -10,6 +10,10 @@ #include #include +#ifndef CONFIG_DALI_QUERY_RESPONSE_TIMEOUT_MS +#define CONFIG_DALI_QUERY_RESPONSE_TIMEOUT_MS 25 +#endif + namespace gateway { namespace { @@ -17,6 +21,48 @@ namespace { constexpr const char* kTag = "dali_domain"; constexpr size_t kSerialRxPacketMaxBytes = 8; constexpr UBaseType_t kSerialRxQueueDepth = 8; +constexpr uint32_t kHardwareQueryRawSuppressMs = CONFIG_DALI_QUERY_RESPONSE_TIMEOUT_MS + 10; + +portMUX_TYPE s_query_raw_suppress_lock = portMUX_INITIALIZER_UNLOCKED; +TickType_t s_query_raw_suppress_until[DALI_PHY_COUNT] = {}; + +void BeginHardwareQueryRawSuppress(uint8_t bus_id) { + if (bus_id >= DALI_PHY_COUNT) { + return; + } + const TickType_t until = xTaskGetTickCount() + pdMS_TO_TICKS(kHardwareQueryRawSuppressMs); + portENTER_CRITICAL(&s_query_raw_suppress_lock); + s_query_raw_suppress_until[bus_id] = until; + portEXIT_CRITICAL(&s_query_raw_suppress_lock); +} + +bool TakeHardwareQueryRawSuppress(uint8_t bus_id) { + if (bus_id >= DALI_PHY_COUNT) { + return false; + } + + bool suppress = false; + const TickType_t now = xTaskGetTickCount(); + portENTER_CRITICAL(&s_query_raw_suppress_lock); + const TickType_t until = s_query_raw_suppress_until[bus_id]; + if (until != 0 && now <= until) { + suppress = true; + s_query_raw_suppress_until[bus_id] = 0; + } else if (until != 0) { + s_query_raw_suppress_until[bus_id] = 0; + } + portEXIT_CRITICAL(&s_query_raw_suppress_lock); + return suppress; +} + +void ClearHardwareQueryRawSuppress(uint8_t bus_id) { + if (bus_id >= DALI_PHY_COUNT) { + return; + } + portENTER_CRITICAL(&s_query_raw_suppress_lock); + s_query_raw_suppress_until[bus_id] = 0; + portEXIT_CRITICAL(&s_query_raw_suppress_lock); +} DaliDomainSnapshot MakeSnapshot(uint8_t gateway_id, int address, const char* kind) { DaliDomainSnapshot snapshot; @@ -113,12 +159,15 @@ std::vector TransactHardwareFrame(uint8_t bus_id, const uint8_t* data, Dali_msg_t tx = dali_msg_new(data[1], data[2]); tx.id = bus_id; Dali_msg_t rx = {}; + BeginHardwareQueryRawSuppress(bus_id); if (dali_query(&tx, &rx) == pdTRUE) { if (rx.status != DALI_FRAME_OK || rx.length != 8) { + ClearHardwareQueryRawSuppress(bus_id); return LegacyQueryResponse(0xFD); } return {0xFF, rx.data[0]}; } + ClearHardwareQueryRawSuppress(bus_id); return LegacyQueryResponse(0xFE); } default: @@ -1250,6 +1299,12 @@ void DaliDomainService::rawFrameTaskLoop() { if (byte_count > DALI_MAX_BYTES) { byte_count = DALI_MAX_BYTES; } + if (byte_count == 1 && TakeHardwareQueryRawSuppress(message.id)) { + continue; + } + if (byte_count != 1 && byte_count != 2 && byte_count != 3) { + continue; + } DaliRawFrame frame; frame.channel_index = channel->config.channel_index; frame.gateway_id = channel->config.gateway_id; diff --git a/components/gateway_ble/src/gateway_ble.cpp b/components/gateway_ble/src/gateway_ble.cpp index 1d7ecb5..a3a84fd 100644 --- a/components/gateway_ble/src/gateway_ble.cpp +++ b/components/gateway_ble/src/gateway_ble.cpp @@ -141,6 +141,13 @@ void RegisterGatt(struct ble_gatt_register_ctxt* ctxt, void* arg) { } } +std::vector LegacyRawPayload(const std::vector& data) { + if (data.size() == 1) { + return {0xBE, data[0]}; + } + return data; +} + const struct ble_gatt_svc_def kGattServices[] = { { .type = BLE_GATT_SVC_TYPE_PRIMARY, @@ -377,7 +384,7 @@ void GatewayBleBridge::handleDaliRawFrame(const DaliRawFrame& frame) { if (!enabled_ || conn_handle_ == kInvalidConnectionHandle || frame.data.empty()) { return; } - notifyCharacteristic(frame.channel_index, frame.data); + notifyCharacteristic(frame.channel_index, LegacyRawPayload(frame.data)); } void GatewayBleBridge::handleRawWrite(size_t channel_index, const std::vector& payload) { diff --git a/components/gateway_usb_setup/src/gateway_usb_setup.cpp b/components/gateway_usb_setup/src/gateway_usb_setup.cpp index 6245e0a..e2200fa 100644 --- a/components/gateway_usb_setup/src/gateway_usb_setup.cpp +++ b/components/gateway_usb_setup/src/gateway_usb_setup.cpp @@ -12,6 +12,13 @@ namespace gateway { namespace { constexpr const char* kTag = "gateway_usb"; constexpr size_t kCommandFrameMinLen = 7; + +std::vector LegacyRawPayload(const std::vector& data) { + if (data.size() == 1) { + return {0xBE, data[0]}; + } + return data; +} } GatewayUsbSetupBridge::GatewayUsbSetupBridge(GatewayController& controller, @@ -106,11 +113,12 @@ void GatewayUsbSetupBridge::handleRawFrame(const DaliRawFrame& frame) { return; } - const int written = usb_serial_jtag_write_bytes(frame.data.data(), frame.data.size(), + const auto payload = LegacyRawPayload(frame.data); + const int written = usb_serial_jtag_write_bytes(payload.data(), payload.size(), pdMS_TO_TICKS(config_.write_timeout_ms)); - if (written < 0 || static_cast(written) != frame.data.size()) { + if (written < 0 || static_cast(written) != payload.size()) { ESP_LOGW(kTag, "failed to forward USB raw setup frame channel=%u len=%u", frame.channel_index, - static_cast(frame.data.size())); + static_cast(payload.size())); } }