feat(gateway): enable full IP forwarding for KNX TP and enhance group value write handling
Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -699,7 +699,7 @@ CONFIG_GATEWAY_KNX_TP_RX_PIN=-1
|
||||
CONFIG_GATEWAY_KNX_TP_BAUDRATE=19200
|
||||
CONFIG_GATEWAY_KNX_TP_STARTUP_TIMEOUT_MS=2000
|
||||
CONFIG_GATEWAY_KNX_TP_UART_9BIT_MODE=y
|
||||
# CONFIG_GATEWAY_KNX_TP_FULL_IP_FORWARD is not set
|
||||
CONFIG_GATEWAY_KNX_TP_FULL_IP_FORWARD=y
|
||||
CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE=12288
|
||||
CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY=5
|
||||
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
||||
|
||||
@@ -550,6 +550,10 @@ std::optional<DecodedGroupWrite> DecodeOpenKnxGroupWrite(const uint8_t* data, si
|
||||
return out;
|
||||
}
|
||||
|
||||
bool IsOpenKnxGroupValueWrite(const uint8_t* data, size_t len) {
|
||||
return DecodeOpenKnxGroupWrite(data, len).has_value();
|
||||
}
|
||||
|
||||
uint8_t Reg1PercentToArc(uint8_t value) {
|
||||
if (value == 0 || value == 0xff) {
|
||||
return value;
|
||||
@@ -3430,9 +3434,10 @@ void GatewayKnxTpIpRouter::handleTunnellingRequest(const uint8_t* packet_data, s
|
||||
const uint8_t* cemi = frame.data();
|
||||
const size_t cemi_len = frame.dataLength();
|
||||
const std::vector<uint8_t> current_cemi(cemi, cemi + cemi_len);
|
||||
const bool is_group_value_write = IsOpenKnxGroupValueWrite(cemi, cemi_len);
|
||||
const bool duplicate_sequence = sequence == client->received_sequence;
|
||||
const bool duplicate_payload = duplicate_sequence && client->last_received_cemi == current_cemi;
|
||||
if (duplicate_payload) {
|
||||
if (duplicate_payload && !is_group_value_write) {
|
||||
ESP_LOGD(kTag, "duplicate KNXnet/IP tunnelling request channel=%u seq=%u",
|
||||
static_cast<unsigned>(channel_id), static_cast<unsigned>(sequence));
|
||||
sendTunnellingAck(channel_id, sequence, kKnxNoError, client->data_remote);
|
||||
@@ -3453,7 +3458,11 @@ void GatewayKnxTpIpRouter::handleTunnellingRequest(const uint8_t* packet_data, s
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (duplicate_sequence) {
|
||||
if (duplicate_payload) {
|
||||
ESP_LOGI(kTag,
|
||||
"reprocessing duplicate KNXnet/IP GroupValueWrite channel=%u seq=%u without cached confirmation replay",
|
||||
static_cast<unsigned>(channel_id), static_cast<unsigned>(sequence));
|
||||
} else if (duplicate_sequence) {
|
||||
ESP_LOGW(kTag,
|
||||
"accept KNXnet/IP tunnelling request channel=%u with repeated seq=%u because cEMI payload changed",
|
||||
static_cast<unsigned>(channel_id), static_cast<unsigned>(sequence));
|
||||
@@ -4019,8 +4028,13 @@ bool GatewayKnxTpIpRouter::sendCemiFrameToClient(TunnelClient& client, uint16_t
|
||||
}
|
||||
if (service == kServiceTunnellingRequest && message_code.has_value() &&
|
||||
message_code.value() == L_data_con) {
|
||||
client.last_tunnel_confirmation_sequence = send_sequence;
|
||||
client.last_tunnel_confirmation_packet = packet;
|
||||
if (IsOpenKnxGroupValueWrite(data, len)) {
|
||||
client.last_tunnel_confirmation_sequence = 0;
|
||||
client.last_tunnel_confirmation_packet.clear();
|
||||
} else {
|
||||
client.last_tunnel_confirmation_sequence = send_sequence;
|
||||
client.last_tunnel_confirmation_packet = packet;
|
||||
}
|
||||
}
|
||||
ESP_LOGI(kTag, "sent KNXnet/IP cEMI service=0x%04x channel=%u seq=%u cemi=0x%02x len=%u to %s",
|
||||
static_cast<unsigned>(service), static_cast<unsigned>(client.channel_id),
|
||||
|
||||
Reference in New Issue
Block a user