Add EtsDeviceRuntime class for handling KNX device runtime operations

- Introduced EtsDeviceRuntime class to manage device runtime functionalities including handling tunnel frames and function property commands.
- Added support for individual address management and memory snapshot retrieval.
- Updated EtsMemorySnapshot structure to include individual address.
- Implemented identity application for DALI devices in the memory loader.
- Enhanced CMakeLists.txt to include new source files and compile definitions.
- Updated header files to include new dependencies and declarations.
- Refactored existing memory loading logic to accommodate new device runtime features.

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-05-12 05:19:14 +08:00
parent d231460612
commit 36d10702da
14 changed files with 1034 additions and 41 deletions
+52 -1
View File
@@ -13,12 +13,17 @@
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
namespace gateway {
namespace openknx {
class EtsDeviceRuntime;
}
constexpr uint16_t kGatewayKnxDefaultUdpPort = 3671;
constexpr const char* kGatewayKnxDefaultMulticastAddress = "224.0.23.12";
constexpr uint32_t kGatewayKnxDefaultTpBaudrate = 19200;
@@ -96,6 +101,13 @@ struct GatewayKnxDaliBinding {
GatewayKnxDaliTarget target;
};
struct GatewayKnxCommissioningBallast {
uint8_t high{0};
uint8_t middle{0};
uint8_t low{0};
uint8_t short_address{0xff};
};
std::optional<GatewayKnxConfig> GatewayKnxConfigFromValue(const DaliValue* value);
DaliValue GatewayKnxConfigToValue(const GatewayKnxConfig& config);
@@ -122,6 +134,12 @@ class GatewayKnxBridge {
DaliBridgeResult handleCemiFrame(const uint8_t* data, size_t len);
DaliBridgeResult handleGroupWrite(uint16_t group_address, const uint8_t* data,
size_t len);
bool handleFunctionPropertyCommand(uint8_t object_index, uint8_t property_id,
const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleFunctionPropertyState(uint8_t object_index, uint8_t property_id,
const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
private:
DaliBridgeResult executeForDecodedWrite(uint16_t group_address,
@@ -133,16 +151,43 @@ class GatewayKnxBridge {
const uint8_t* data, size_t len);
void rebuildEtsBindings();
bool handleReg1TypeCommand(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleReg1ScanCommand(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleReg1AssignCommand(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleReg1EvgWriteCommand(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleReg1EvgReadCommand(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleReg1SetSceneCommand(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleReg1GetSceneCommand(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleReg1IdentifyCommand(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleReg1ScanState(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleReg1AssignState(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
bool handleReg1FoundEvgsState(const uint8_t* data, size_t len,
std::vector<uint8_t>* response);
DaliBridgeEngine& engine_;
GatewayKnxConfig config_;
std::map<uint16_t, std::vector<GatewayKnxDaliBinding>> ets_bindings_by_group_address_;
bool commissioning_scan_done_{true};
bool commissioning_assign_done_{true};
std::vector<GatewayKnxCommissioningBallast> commissioning_found_ballasts_;
};
class GatewayKnxTpIpRouter {
public:
using CemiFrameHandler = std::function<DaliBridgeResult(const uint8_t* data, size_t len)>;
GatewayKnxTpIpRouter(GatewayKnxBridge& bridge, CemiFrameHandler handler);
GatewayKnxTpIpRouter(GatewayKnxBridge& bridge, CemiFrameHandler handler,
std::string openknx_namespace = "openknx");
~GatewayKnxTpIpRouter();
void setConfig(const GatewayKnxConfig& config);
@@ -179,6 +224,10 @@ class GatewayKnxTpIpRouter {
void sendConnectResponse(uint8_t channel_id, uint8_t status,
const ::sockaddr_in& remote);
void sendRoutingIndication(const uint8_t* data, size_t len);
bool handleOpenKnxTunnelFrame(const uint8_t* data, size_t len);
void syncOpenKnxConfigFromDevice();
uint16_t effectiveIndividualAddress() const;
uint16_t effectiveTunnelAddress() const;
void pollTpUart();
void handleTpUartControlByte(uint8_t byte);
void handleTpTelegram(const uint8_t* data, size_t len);
@@ -186,7 +235,9 @@ class GatewayKnxTpIpRouter {
GatewayKnxBridge& bridge_;
CemiFrameHandler handler_;
std::string openknx_namespace_;
GatewayKnxConfig config_;
std::unique_ptr<openknx::EtsDeviceRuntime> ets_device_;
TaskHandle_t task_handle_{nullptr};
std::atomic_bool stop_requested_{false};
std::atomic_bool started_{false};