Add secure transport and OAM router runtime implementations

- Implement secure transport mechanisms in `gateway_knx_secure_transport.cpp` for handling secure sessions, including AES encryption, session key generation, and secure packet wrapping and unwrapping.
- Introduce `OamRouterRuntime` in `oam_router_runtime.cpp` to manage OAM router identity, individual addresses, and tunnel frame handling.
- Enhance secure session management with functions for session allocation, authentication, and secure packet processing.
- Ensure compatibility with existing KNXnet/IP protocols while adding support for secure communications.

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-05-25 08:18:01 +08:00
parent 0467179f70
commit 2b779d5532
22 changed files with 2665 additions and 77 deletions
+119
View File
@@ -2,6 +2,115 @@
namespace gateway {
namespace {
GatewayKnxCloudRemoteConfig GatewayKnxCloudRemoteConfigFromValue(const DaliValue* value) {
GatewayKnxCloudRemoteConfig config;
if (value == nullptr || value->asObject() == nullptr) {
return config;
}
const auto& object = *value->asObject();
config.enabled = ObjectBoolAny(object, {"enabled", "cloudRemoteEnabled",
"cloud_remote_enabled"})
.value_or(config.enabled);
config.mode = ObjectStringAny(object, {"mode", "remoteMode", "remote_mode"})
.value_or(config.mode);
config.relay_endpoint = ObjectStringAny(object, {"relayEndpoint", "relay_endpoint",
"endpoint"})
.value_or(config.relay_endpoint);
config.mqtt_topic_prefix = ObjectStringAny(object, {"mqttTopicPrefix", "mqtt_topic_prefix",
"topicPrefix", "topic_prefix"})
.value_or(config.mqtt_topic_prefix);
config.auth_token_ref = ObjectStringAny(object, {"authTokenRef", "auth_token_ref",
"tokenRef", "token_ref"})
.value_or(config.auth_token_ref);
config.require_secure_tunnel = ObjectBoolAny(object, {"requireSecureTunnel",
"require_secure_tunnel"})
.value_or(config.require_secure_tunnel);
config.udp_punch_enabled = ObjectBoolAny(object, {"udpPunchEnabled", "udp_punch_enabled"})
.value_or(config.udp_punch_enabled);
return config;
}
DaliValue GatewayKnxCloudRemoteConfigToValue(const GatewayKnxCloudRemoteConfig& config) {
DaliValue::Object out;
out["enabled"] = config.enabled;
out["mode"] = config.mode;
out["relayEndpoint"] = config.relay_endpoint;
out["mqttTopicPrefix"] = config.mqtt_topic_prefix;
out["authTokenRef"] = config.auth_token_ref;
out["requireSecureTunnel"] = config.require_secure_tunnel;
out["udpPunchEnabled"] = config.udp_punch_enabled;
return DaliValue(std::move(out));
}
} // namespace
std::optional<GatewayKnxOamRouterConfig> GatewayKnxOamRouterConfigFromValue(
const DaliValue* value) {
if (value == nullptr || value->asObject() == nullptr) {
return std::nullopt;
}
const auto& object = *value->asObject();
GatewayKnxOamRouterConfig config;
config.enabled = ObjectBoolAny(object, {"enabled", "oamRouterEnabled",
"oam_router_enabled"})
.value_or(config.enabled);
config.ets_database_enabled = ObjectBoolAny(object, {"etsDatabaseEnabled",
"ets_database_enabled"})
.value_or(config.ets_database_enabled);
config.secure_tunnel_enabled = ObjectBoolAny(object, {"secureTunnelEnabled",
"secure_tunnel_enabled"})
.value_or(config.secure_tunnel_enabled);
config.secure_routing_enabled = ObjectBoolAny(object, {"secureRoutingEnabled",
"secure_routing_enabled"})
.value_or(config.secure_routing_enabled);
config.individual_address = static_cast<uint16_t>(std::clamp(
ObjectIntAny(object, {"individualAddress", "individual_address", "routerAddress",
"router_address"})
.value_or(config.individual_address),
0, 0xffff));
config.tunnel_address_base = static_cast<uint16_t>(std::clamp(
ObjectIntAny(object, {"tunnelAddressBase", "tunnel_address_base",
"tunnelBaseAddress", "tunnel_base_address"})
.value_or(config.tunnel_address_base),
0, 0xffff));
config.programming_button_gpio = std::clamp(
ObjectIntAny(object, {"programmingButtonGpio", "programming_button_gpio"})
.value_or(config.programming_button_gpio),
-1, 48);
config.programming_button_active_low =
ObjectBoolAny(object, {"programmingButtonActiveLow", "programming_button_active_low"})
.value_or(config.programming_button_active_low);
config.programming_led_gpio = std::clamp(
ObjectIntAny(object, {"programmingLedGpio", "programming_led_gpio"})
.value_or(config.programming_led_gpio),
-1, 48);
config.programming_led_active_high =
ObjectBoolAny(object, {"programmingLedActiveHigh", "programming_led_active_high"})
.value_or(config.programming_led_active_high);
config.cloud_remote = GatewayKnxCloudRemoteConfigFromValue(
ObjectValueAny(object, {"cloudRemote", "cloud_remote", "remoteAccess",
"remote_access"}));
return config;
}
DaliValue GatewayKnxOamRouterConfigToValue(const GatewayKnxOamRouterConfig& config) {
DaliValue::Object out;
out["enabled"] = config.enabled;
out["etsDatabaseEnabled"] = config.ets_database_enabled;
out["secureTunnelEnabled"] = config.secure_tunnel_enabled;
out["secureRoutingEnabled"] = config.secure_routing_enabled;
out["individualAddress"] = static_cast<int>(config.individual_address);
out["tunnelAddressBase"] = static_cast<int>(config.tunnel_address_base);
out["programmingButtonGpio"] = config.programming_button_gpio;
out["programmingButtonActiveLow"] = config.programming_button_active_low;
out["programmingLedGpio"] = config.programming_led_gpio;
out["programmingLedActiveHigh"] = config.programming_led_active_high;
out["cloudRemote"] = GatewayKnxCloudRemoteConfigToValue(config.cloud_remote);
return DaliValue(std::move(out));
}
std::optional<GatewayKnxConfig> GatewayKnxConfigFromValue(const DaliValue* value) {
if (value == nullptr || value->asObject() == nullptr) {
return std::nullopt;
@@ -65,6 +174,15 @@ std::optional<GatewayKnxConfig> GatewayKnxConfigFromValue(const DaliValue* value
config.programming_led_active_high =
ObjectBoolAny(object, {"programmingLedActiveHigh", "programming_led_active_high"})
.value_or(config.programming_led_active_high);
if (const auto oam_router = GatewayKnxOamRouterConfigFromValue(
ObjectValueAny(object, {"oamRouter", "oam_router", "routerApplication",
"router_application"}))) {
config.oam_router = oam_router.value();
} else {
config.oam_router.enabled = ObjectBoolAny(object, {"oamRouterEnabled",
"oam_router_enabled"})
.value_or(config.oam_router.enabled);
}
const auto* tp_uart = getObjectValue(object, "tpUart");
if (tp_uart == nullptr) {
@@ -117,6 +235,7 @@ DaliValue GatewayKnxConfigToValue(const GatewayKnxConfig& config) {
out["programmingButtonActiveLow"] = config.programming_button_active_low;
out["programmingLedGpio"] = config.programming_led_gpio;
out["programmingLedActiveHigh"] = config.programming_led_active_high;
out["oamRouter"] = GatewayKnxOamRouterConfigToValue(config.oam_router);
DaliValue::Object serial;
serial["uartPort"] = config.tp_uart.uart_port;
serial["txPin"] = config.tp_uart.tx_pin;