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_BAUDRATE=19200
|
||||||
CONFIG_GATEWAY_KNX_TP_STARTUP_TIMEOUT_MS=2000
|
CONFIG_GATEWAY_KNX_TP_STARTUP_TIMEOUT_MS=2000
|
||||||
CONFIG_GATEWAY_KNX_TP_UART_9BIT_MODE=y
|
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_STACK_SIZE=12288
|
||||||
CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY=5
|
CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY=5
|
||||||
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
||||||
|
|||||||
@@ -550,6 +550,10 @@ std::optional<DecodedGroupWrite> DecodeOpenKnxGroupWrite(const uint8_t* data, si
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsOpenKnxGroupValueWrite(const uint8_t* data, size_t len) {
|
||||||
|
return DecodeOpenKnxGroupWrite(data, len).has_value();
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t Reg1PercentToArc(uint8_t value) {
|
uint8_t Reg1PercentToArc(uint8_t value) {
|
||||||
if (value == 0 || value == 0xff) {
|
if (value == 0 || value == 0xff) {
|
||||||
return value;
|
return value;
|
||||||
@@ -3430,9 +3434,10 @@ void GatewayKnxTpIpRouter::handleTunnellingRequest(const uint8_t* packet_data, s
|
|||||||
const uint8_t* cemi = frame.data();
|
const uint8_t* cemi = frame.data();
|
||||||
const size_t cemi_len = frame.dataLength();
|
const size_t cemi_len = frame.dataLength();
|
||||||
const std::vector<uint8_t> current_cemi(cemi, cemi + cemi_len);
|
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_sequence = sequence == client->received_sequence;
|
||||||
const bool duplicate_payload = duplicate_sequence && client->last_received_cemi == current_cemi;
|
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",
|
ESP_LOGD(kTag, "duplicate KNXnet/IP tunnelling request channel=%u seq=%u",
|
||||||
static_cast<unsigned>(channel_id), static_cast<unsigned>(sequence));
|
static_cast<unsigned>(channel_id), static_cast<unsigned>(sequence));
|
||||||
sendTunnellingAck(channel_id, sequence, kKnxNoError, client->data_remote);
|
sendTunnellingAck(channel_id, sequence, kKnxNoError, client->data_remote);
|
||||||
@@ -3453,7 +3458,11 @@ void GatewayKnxTpIpRouter::handleTunnellingRequest(const uint8_t* packet_data, s
|
|||||||
}
|
}
|
||||||
return;
|
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,
|
ESP_LOGW(kTag,
|
||||||
"accept KNXnet/IP tunnelling request channel=%u with repeated seq=%u because cEMI payload changed",
|
"accept KNXnet/IP tunnelling request channel=%u with repeated seq=%u because cEMI payload changed",
|
||||||
static_cast<unsigned>(channel_id), static_cast<unsigned>(sequence));
|
static_cast<unsigned>(channel_id), static_cast<unsigned>(sequence));
|
||||||
@@ -4019,9 +4028,14 @@ bool GatewayKnxTpIpRouter::sendCemiFrameToClient(TunnelClient& client, uint16_t
|
|||||||
}
|
}
|
||||||
if (service == kServiceTunnellingRequest && message_code.has_value() &&
|
if (service == kServiceTunnellingRequest && message_code.has_value() &&
|
||||||
message_code.value() == L_data_con) {
|
message_code.value() == L_data_con) {
|
||||||
|
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_sequence = send_sequence;
|
||||||
client.last_tunnel_confirmation_packet = packet;
|
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",
|
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),
|
static_cast<unsigned>(service), static_cast<unsigned>(client.channel_id),
|
||||||
static_cast<unsigned>(request.connectionHeader().sequenceCounter()), static_cast<unsigned>(data[0]),
|
static_cast<unsigned>(request.connectionHeader().sequenceCounter()), static_cast<unsigned>(data[0]),
|
||||||
|
|||||||
Reference in New Issue
Block a user