feat(gateway): enhance DALI and KNX handling with broadcast management support and configurable task stack size
Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -19,14 +19,98 @@ bool GatewayKnxTpIpRouter::handleOpenKnxTunnelFrame(const uint8_t* data, size_t
|
||||
const uint8_t* suppress_routing_echo,
|
||||
size_t suppress_routing_echo_len) {
|
||||
bool route_to_oam = response_client != nullptr && response_client->oam_router_persona;
|
||||
if (!route_to_oam && data != nullptr && len >= 2) {
|
||||
bool route_to_all_internal_instances = false;
|
||||
if (data != nullptr && len >= 2) {
|
||||
std::vector<uint8_t> frame_data(data, data + len);
|
||||
CemiFrame frame(frame_data.data(), static_cast<uint16_t>(frame_data.size()));
|
||||
if (frame.valid() && oam_router_ != nullptr &&
|
||||
MatchesOamRouterLocalIndividualAddress(frame, *oam_router_)) {
|
||||
route_to_oam = true;
|
||||
if (frame.valid()) {
|
||||
route_to_all_internal_instances = IsKnxBroadcastManagementRequest(frame);
|
||||
if (!route_to_oam && oam_router_ != nullptr &&
|
||||
MatchesOamRouterLocalIndividualAddress(frame, *oam_router_)) {
|
||||
route_to_oam = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (route_to_all_internal_instances) {
|
||||
SemaphoreGuard guard(openknx_lock_);
|
||||
if (ets_device_ == nullptr && oam_router_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
std::vector<uint8_t> tunnel_confirmation;
|
||||
const bool needs_tunnel_confirmation =
|
||||
response_client != nullptr && response_client->connected &&
|
||||
response_service == kServiceTunnellingRequest &&
|
||||
BuildTunnelConfirmationFrame(data, len, &tunnel_confirmation);
|
||||
bool sent_tunnel_confirmation = false;
|
||||
const auto send_response =
|
||||
[this, response_client, response_service, needs_tunnel_confirmation,
|
||||
&tunnel_confirmation, &sent_tunnel_confirmation, suppress_routing_echo,
|
||||
suppress_routing_echo_len](const uint8_t* response, size_t response_len) {
|
||||
if (response == nullptr || response_len == 0) {
|
||||
return;
|
||||
}
|
||||
publishCloudCemiFrame(response, response_len);
|
||||
const bool routing_context =
|
||||
response_client == nullptr && response_service == kServiceRoutingIndication;
|
||||
const auto message_code = CemiMessageCode(response, response_len);
|
||||
if (routing_context && suppress_routing_echo != nullptr &&
|
||||
IsLocalRoutingEchoIndication(response, response_len, suppress_routing_echo,
|
||||
suppress_routing_echo_len)) {
|
||||
return;
|
||||
}
|
||||
if (needs_tunnel_confirmation && !sent_tunnel_confirmation &&
|
||||
message_code.has_value() && message_code.value() != L_data_con) {
|
||||
sent_tunnel_confirmation = sendCemiFrameToClient(
|
||||
*response_client, kServiceTunnellingRequest,
|
||||
tunnel_confirmation.data(), tunnel_confirmation.size());
|
||||
}
|
||||
|
||||
const uint16_t service = KnxIpServiceForCemi(response, response_len, response_service);
|
||||
if (service == kServiceDeviceConfigurationRequest) {
|
||||
if (response_client != nullptr && response_client->connected) {
|
||||
sendCemiFrameToClient(*response_client, service, response, response_len);
|
||||
} else if (routing_context) {
|
||||
sendRoutingIndication(response, response_len);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (message_code.has_value() && message_code.value() == L_data_con) {
|
||||
if (routing_context) {
|
||||
return;
|
||||
}
|
||||
if (response_client != nullptr && response_client->connected) {
|
||||
sent_tunnel_confirmation =
|
||||
sendCemiFrameToClient(*response_client, service, response, response_len) ||
|
||||
sent_tunnel_confirmation;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (routing_context) {
|
||||
sendRoutingIndication(response, response_len);
|
||||
return;
|
||||
}
|
||||
if (response_client != nullptr && response_client->connected) {
|
||||
sendCemiFrameToClient(*response_client, service, response, response_len);
|
||||
return;
|
||||
}
|
||||
sendTunnelIndication(response, response_len);
|
||||
};
|
||||
bool consumed = false;
|
||||
if (ets_device_ != nullptr) {
|
||||
consumed = ets_device_->handleLocalBroadcastManagementFrame(data, len, send_response) ||
|
||||
consumed;
|
||||
}
|
||||
if (oam_router_ != nullptr) {
|
||||
consumed = oam_router_->handleLocalBroadcastManagementFrame(data, len, send_response) ||
|
||||
consumed;
|
||||
}
|
||||
if (needs_tunnel_confirmation && consumed && !sent_tunnel_confirmation) {
|
||||
sendCemiFrameToClient(*response_client, kServiceTunnellingRequest,
|
||||
tunnel_confirmation.data(), tunnel_confirmation.size());
|
||||
}
|
||||
syncOpenKnxConfigFromDevice();
|
||||
return consumed;
|
||||
}
|
||||
if (route_to_oam) {
|
||||
return handleOamRouterTunnelFrame(data, len, response_client, response_service,
|
||||
suppress_routing_echo, suppress_routing_echo_len);
|
||||
|
||||
Reference in New Issue
Block a user