Refactor KNX DALI Gateway Configuration and Update Device Parameters
- Introduced configuration macros for OEM manufacturer ID, application number, and application version in knxprod.h. - Updated product identity definitions to use the new configuration macros. - Modified device type enumeration to include additional device types. - Adjusted color space enumeration values for consistency. - Defined generated group object layout constants for memory offsets and block sizes. - Enhanced knx_dali_gw.cpp to utilize the new configuration macros for manufacturer ID and program version. - Updated the device initialization logic to reflect the new hardware and program version structures. - Removed obsolete knx_dali_gw subproject and updated related submodules. Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -9,11 +9,14 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace gateway::openknx {
|
||||
|
||||
class TpuartUartInterface;
|
||||
|
||||
class EtsDeviceRuntime {
|
||||
public:
|
||||
using CemiFrameSender = std::function<void(const uint8_t* data, size_t len)>;
|
||||
@@ -25,7 +28,8 @@ class EtsDeviceRuntime {
|
||||
|
||||
EtsDeviceRuntime(std::string nvs_namespace,
|
||||
uint16_t fallback_individual_address,
|
||||
uint16_t tunnel_client_address = 0);
|
||||
uint16_t tunnel_client_address = 0,
|
||||
std::unique_ptr<TpuartUartInterface> tp_uart_interface = nullptr);
|
||||
~EtsDeviceRuntime();
|
||||
|
||||
uint16_t individualAddress() const;
|
||||
@@ -43,7 +47,12 @@ class EtsDeviceRuntime {
|
||||
void setFunctionPropertyHandlers(FunctionPropertyHandler command_handler,
|
||||
FunctionPropertyHandler state_handler);
|
||||
void setGroupWriteHandler(GroupWriteHandler handler);
|
||||
void setBusFrameSender(CemiFrameSender sender);
|
||||
void setNetworkInterface(esp_netif_t* netif);
|
||||
bool hasTpUart() const;
|
||||
bool enableTpUart(bool enabled = true);
|
||||
bool tpUartOnline() const;
|
||||
bool transmitTpFrame(const uint8_t* data, size_t len);
|
||||
|
||||
bool handleTunnelFrame(const uint8_t* data, size_t len, CemiFrameSender sender);
|
||||
bool handleBusFrame(const uint8_t* data, size_t len);
|
||||
@@ -70,9 +79,11 @@ class EtsDeviceRuntime {
|
||||
bool shouldConsumeBusFrame(CemiFrame& frame) const;
|
||||
|
||||
std::string nvs_namespace_;
|
||||
std::unique_ptr<TpuartUartInterface> tp_uart_interface_;
|
||||
EspIdfPlatform platform_;
|
||||
Bau07B0 device_;
|
||||
CemiFrameSender sender_;
|
||||
CemiFrameSender bus_frame_sender_;
|
||||
GroupWriteHandler group_write_handler_;
|
||||
FunctionPropertyHandler command_handler_;
|
||||
FunctionPropertyHandler state_handler_;
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace gateway {
|
||||
|
||||
namespace openknx {
|
||||
class EtsDeviceRuntime;
|
||||
class TpuartUartInterface;
|
||||
}
|
||||
|
||||
constexpr uint16_t kGatewayKnxDefaultUdpPort = 3671;
|
||||
@@ -143,9 +144,7 @@ class GatewayKnxBridge {
|
||||
size_t etsBindingCount() const;
|
||||
|
||||
std::vector<GatewayKnxDaliBinding> describeDaliBindings() const;
|
||||
bool matchesCemiFrame(const uint8_t* data, size_t len) const;
|
||||
bool matchesGroupAddress(uint16_t group_address) const;
|
||||
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,
|
||||
@@ -198,12 +197,11 @@ class GatewayKnxBridge {
|
||||
|
||||
class GatewayKnxTpIpRouter {
|
||||
public:
|
||||
using CemiFrameHandler = std::function<DaliBridgeResult(const uint8_t* data, size_t len)>;
|
||||
using GroupWriteHandler = std::function<DaliBridgeResult(uint16_t group_address,
|
||||
const uint8_t* data,
|
||||
size_t len)>;
|
||||
|
||||
GatewayKnxTpIpRouter(GatewayKnxBridge& bridge, CemiFrameHandler handler,
|
||||
GatewayKnxTpIpRouter(GatewayKnxBridge& bridge,
|
||||
std::string openknx_namespace = "openknx");
|
||||
~GatewayKnxTpIpRouter();
|
||||
|
||||
@@ -256,22 +254,23 @@ class GatewayKnxTpIpRouter {
|
||||
void handleTcpAccept();
|
||||
void handleTcpClient(TcpClient& client);
|
||||
void closeTcpClient(TcpClient& client);
|
||||
std::unique_ptr<openknx::TpuartUartInterface> createOpenKnxTpUartInterface();
|
||||
bool configureTpUart();
|
||||
bool initializeTpUart();
|
||||
bool configureProgrammingGpio();
|
||||
void refreshNetworkInterfaces(bool force_log = false);
|
||||
void handleUdpDatagram(const uint8_t* data, size_t len, const ::sockaddr_in& remote);
|
||||
void handleSearchRequest(const uint8_t* data, size_t len, const ::sockaddr_in& remote);
|
||||
void handleDescriptionRequest(const uint8_t* data, size_t len,
|
||||
void handleSearchRequest(uint16_t service, const uint8_t* packet_data, size_t len,
|
||||
const ::sockaddr_in& remote);
|
||||
void handleDescriptionRequest(const uint8_t* packet_data, size_t len,
|
||||
const ::sockaddr_in& remote);
|
||||
void handleRoutingIndication(const uint8_t* body, size_t len);
|
||||
void handleTunnellingRequest(const uint8_t* body, size_t len, const ::sockaddr_in& remote);
|
||||
void handleDeviceConfigurationRequest(const uint8_t* body, size_t len,
|
||||
void handleRoutingIndication(const uint8_t* packet_data, size_t len);
|
||||
void handleTunnellingRequest(const uint8_t* packet_data, size_t len, const ::sockaddr_in& remote);
|
||||
void handleDeviceConfigurationRequest(const uint8_t* packet_data, size_t len,
|
||||
const ::sockaddr_in& remote);
|
||||
void handleConnectRequest(const uint8_t* body, size_t len, const ::sockaddr_in& remote);
|
||||
void handleConnectionStateRequest(const uint8_t* body, size_t len,
|
||||
void handleConnectRequest(const uint8_t* packet_data, size_t len, const ::sockaddr_in& remote);
|
||||
void handleConnectionStateRequest(const uint8_t* packet_data, size_t len,
|
||||
const ::sockaddr_in& remote);
|
||||
void handleDisconnectRequest(const uint8_t* body, size_t len, const ::sockaddr_in& remote);
|
||||
void handleDisconnectRequest(const uint8_t* packet_data, size_t len, const ::sockaddr_in& remote);
|
||||
void handleSecureService(uint16_t service, const uint8_t* body, size_t len,
|
||||
const ::sockaddr_in& remote);
|
||||
void sendTunnellingAck(uint8_t channel_id, uint8_t sequence, uint8_t status,
|
||||
@@ -283,6 +282,8 @@ class GatewayKnxTpIpRouter {
|
||||
void sendSecureSessionStatus(uint8_t status, const ::sockaddr_in& remote);
|
||||
void sendTunnelIndication(const uint8_t* data, size_t len);
|
||||
void sendTunnelIndicationToClient(TunnelClient& client, const uint8_t* data, size_t len);
|
||||
void sendCemiFrameToClient(TunnelClient& client, uint16_t service,
|
||||
const uint8_t* data, size_t len);
|
||||
void sendConnectionStateResponse(uint8_t channel_id, uint8_t status,
|
||||
const ::sockaddr_in& remote);
|
||||
void sendDisconnectResponse(uint8_t channel_id, uint8_t status,
|
||||
@@ -319,9 +320,11 @@ class GatewayKnxTpIpRouter {
|
||||
uint16_t effectiveTunnelAddressForSlot(size_t slot) const;
|
||||
void pruneStaleTunnelClients();
|
||||
bool handleOpenKnxTunnelFrame(const uint8_t* data, size_t len,
|
||||
TunnelClient* response_client);
|
||||
TunnelClient* response_client, uint16_t response_service);
|
||||
bool handleOpenKnxBusFrame(const uint8_t* data, size_t len);
|
||||
bool transmitOpenKnxTpFrame(const uint8_t* data, size_t len);
|
||||
void selectOpenKnxNetworkInterface(const ::sockaddr_in& remote);
|
||||
bool routeOpenKnxGroupWrite(const uint8_t* data, size_t len, const char* context);
|
||||
bool emitOpenKnxGroupValue(uint16_t group_object_number, const uint8_t* data, size_t len);
|
||||
bool shouldRouteDaliApplicationFrames() const;
|
||||
uint8_t advertisedMedium() const;
|
||||
@@ -329,16 +332,11 @@ class GatewayKnxTpIpRouter {
|
||||
uint16_t effectiveIpInterfaceIndividualAddress() const;
|
||||
uint16_t effectiveKnxDeviceIndividualAddress() const;
|
||||
uint16_t effectiveTunnelAddress() const;
|
||||
void pollTpUart();
|
||||
void pollProgrammingButton();
|
||||
void updateProgrammingLed();
|
||||
void setProgrammingLed(bool on);
|
||||
void handleTpUartControlByte(uint8_t byte);
|
||||
void handleTpTelegram(const uint8_t* data, size_t len);
|
||||
void forwardCemiToTp(const uint8_t* data, size_t len);
|
||||
|
||||
GatewayKnxBridge& bridge_;
|
||||
CemiFrameHandler handler_;
|
||||
GroupWriteHandler group_write_handler_;
|
||||
std::string openknx_namespace_;
|
||||
GatewayKnxConfig config_;
|
||||
@@ -361,10 +359,6 @@ class GatewayKnxTpIpRouter {
|
||||
std::array<TunnelClient, kMaxTunnelClients> tunnel_clients_{};
|
||||
std::unique_ptr<IpParameterObject> knx_ip_parameters_;
|
||||
uint8_t last_tunnel_channel_id_{0};
|
||||
std::vector<uint8_t> tp_rx_frame_;
|
||||
std::vector<uint8_t> tp_last_sent_telegram_;
|
||||
TickType_t tp_uart_last_byte_tick_{0};
|
||||
bool tp_uart_extended_frame_{false};
|
||||
bool tp_uart_online_{false};
|
||||
bool commissioning_only_{false};
|
||||
std::atomic_bool openknx_configured_{false};
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
// Internal header shared between gateway_knx.cpp and gateway_knx_router.cpp.
|
||||
// Internal helpers and product identity shared by gateway_knx component sources.
|
||||
|
||||
#include "driver/uart.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/uart_periph.h"
|
||||
|
||||
#include <cstdint>
|
||||
@@ -15,6 +16,46 @@ namespace knx_internal {
|
||||
|
||||
constexpr const char* kTag = "gateway_knx";
|
||||
|
||||
#ifndef CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID
|
||||
#define CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID 0x00A4
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_GATEWAY_KNX_OEM_APPLICATION_NUMBER
|
||||
#define CONFIG_GATEWAY_KNX_OEM_APPLICATION_NUMBER 0x0001
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_GATEWAY_KNX_OEM_APPLICATION_VERSION
|
||||
#define CONFIG_GATEWAY_KNX_OEM_APPLICATION_VERSION 0x08
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_GATEWAY_KNX_OEM_HARDWARE_ID
|
||||
#define CONFIG_GATEWAY_KNX_OEM_HARDWARE_ID 0xA401
|
||||
#endif
|
||||
|
||||
inline constexpr uint16_t kReg1DaliManufacturerId =
|
||||
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID);
|
||||
inline constexpr uint16_t kReg1DaliHardwareId =
|
||||
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OEM_HARDWARE_ID);
|
||||
inline constexpr uint16_t kReg1DaliApplicationNumber =
|
||||
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OEM_APPLICATION_NUMBER);
|
||||
inline constexpr uint8_t kReg1DaliApplicationVersion =
|
||||
static_cast<uint8_t>(CONFIG_GATEWAY_KNX_OEM_APPLICATION_VERSION);
|
||||
inline constexpr uint8_t kReg1DaliHardwareType[6] = {
|
||||
0x00,
|
||||
0x00,
|
||||
static_cast<uint8_t>((kReg1DaliHardwareId >> 8) & 0xff),
|
||||
static_cast<uint8_t>(kReg1DaliHardwareId & 0xff),
|
||||
kReg1DaliApplicationVersion,
|
||||
0x00};
|
||||
inline constexpr uint8_t kReg1DaliOrderNumber[10] = {
|
||||
'R', 'E', 'G', '1', '-', 'D', 'a', 'l', 'i', 0};
|
||||
inline constexpr uint8_t kReg1DaliProgramVersion[5] = {
|
||||
static_cast<uint8_t>((kReg1DaliManufacturerId >> 8) & 0xff),
|
||||
static_cast<uint8_t>(kReg1DaliManufacturerId & 0xff),
|
||||
static_cast<uint8_t>((kReg1DaliApplicationNumber >> 8) & 0xff),
|
||||
static_cast<uint8_t>(kReg1DaliApplicationNumber & 0xff),
|
||||
kReg1DaliApplicationVersion};
|
||||
|
||||
// RAII semaphore guard.
|
||||
class SemaphoreGuard {
|
||||
public:
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
#include "ets_device_runtime.h"
|
||||
|
||||
#include "gateway_knx_internal.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "knx/cemi_server.h"
|
||||
#include "knx/secure_application_layer.h"
|
||||
#include "knx/property.h"
|
||||
#include "tpuart_uart_interface.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -29,53 +35,97 @@ class ActiveFunctionPropertyRuntimeScope {
|
||||
|
||||
constexpr uint16_t kInvalidIndividualAddress = 0xffff;
|
||||
constexpr uint16_t kKnxUnconfiguredBroadcastAddress = 0xffff; // KNX broadcast IA for unconfigured devices
|
||||
constexpr uint16_t kReg1DaliManufacturerId = 0x00a4;
|
||||
constexpr uint8_t kReg1DaliApplicationNumber = 0x01;
|
||||
constexpr uint8_t kReg1DaliApplicationVersion = 0x05;
|
||||
constexpr uint8_t kReg1DaliOrderNumber[10] = {'R', 'E', 'G', '1', '-', 'D', 'a', 'l', 'i', 0};
|
||||
|
||||
bool IsUsableIndividualAddress(uint16_t address) {
|
||||
return address != 0 && address != kInvalidIndividualAddress;
|
||||
}
|
||||
|
||||
bool IsErasedMemory(const uint8_t* data, size_t size) {
|
||||
if (data == nullptr || size == 0) {
|
||||
return true;
|
||||
std::string HexBytesString(const uint8_t* data, size_t length) {
|
||||
if (data == nullptr || length == 0) {
|
||||
return {};
|
||||
}
|
||||
return std::all_of(data, data + size, [](uint8_t value) { return value == 0xff; });
|
||||
|
||||
std::string out;
|
||||
out.reserve(length * 3);
|
||||
char buffer[4] = {0};
|
||||
for (size_t index = 0; index < length; ++index) {
|
||||
std::snprintf(buffer, sizeof(buffer), "%02X", data[index]);
|
||||
out += buffer;
|
||||
if (index + 1 < length) {
|
||||
out.push_back(' ');
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string PrintableOrderNumber(const uint8_t* data, size_t length) {
|
||||
if (data == nullptr || length == 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string out;
|
||||
out.reserve(length);
|
||||
for (size_t index = 0; index < length; ++index) {
|
||||
if (data[index] == 0) {
|
||||
break;
|
||||
}
|
||||
out.push_back(static_cast<char>(data[index]));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void LogReg1DaliIdentity(const std::string& nvs_namespace, Bau07B0& device) {
|
||||
uint8_t program_version[5] = {0};
|
||||
if (auto* property = device.parameters().property(PID_PROG_VERSION); property != nullptr) {
|
||||
property->read(program_version);
|
||||
}
|
||||
|
||||
const std::string hardware_type =
|
||||
HexBytesString(device.deviceObject().hardwareType(), LEN_HARDWARE_TYPE);
|
||||
const std::string program_version_hex =
|
||||
HexBytesString(program_version, sizeof(program_version));
|
||||
const std::string order_number =
|
||||
PrintableOrderNumber(device.deviceObject().orderNumber(),
|
||||
sizeof(knx_internal::kReg1DaliOrderNumber));
|
||||
|
||||
ESP_LOGI("gateway_knx",
|
||||
"OpenKNX identity namespace=%s manufacturer=0x%04x mask=0x%04x deviceVersion=0x%04x hardwareType=%s progVersion=%s order=%s",
|
||||
nvs_namespace.c_str(), device.deviceObject().manufacturerId(),
|
||||
device.deviceObject().maskVersion(), device.deviceObject().version(),
|
||||
hardware_type.c_str(), program_version_hex.c_str(), order_number.c_str());
|
||||
}
|
||||
|
||||
void ApplyReg1DaliIdentity(Bau07B0& device, EspIdfPlatform& platform) {
|
||||
device.deviceObject().manufacturerId(kReg1DaliManufacturerId);
|
||||
device.deviceObject().manufacturerId(knx_internal::kReg1DaliManufacturerId);
|
||||
device.deviceObject().bauNumber(platform.uniqueSerialNumber());
|
||||
device.deviceObject().orderNumber(kReg1DaliOrderNumber);
|
||||
const uint8_t program_version[5] = {0x00, 0xa4, 0x00, kReg1DaliApplicationNumber,
|
||||
kReg1DaliApplicationVersion};
|
||||
device.parameters().property(PID_PROG_VERSION)->write(program_version);
|
||||
device.deviceObject().hardwareType(knx_internal::kReg1DaliHardwareType);
|
||||
device.deviceObject().orderNumber(knx_internal::kReg1DaliOrderNumber);
|
||||
device.parameters().property(PID_PROG_VERSION)->write(
|
||||
knx_internal::kReg1DaliProgramVersion);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EtsDeviceRuntime::EtsDeviceRuntime(std::string nvs_namespace,
|
||||
uint16_t fallback_individual_address,
|
||||
uint16_t tunnel_client_address)
|
||||
uint16_t tunnel_client_address,
|
||||
std::unique_ptr<TpuartUartInterface> tp_uart_interface)
|
||||
: nvs_namespace_(std::move(nvs_namespace)),
|
||||
platform_(nullptr, nvs_namespace_.c_str()),
|
||||
tp_uart_interface_(std::move(tp_uart_interface)),
|
||||
platform_(tp_uart_interface_.get(), nvs_namespace_.c_str()),
|
||||
device_(platform_) {
|
||||
platform_.outboundCemiFrameCallback(&EtsDeviceRuntime::HandleOutboundCemiFrame, this);
|
||||
ApplyReg1DaliIdentity(device_, platform_);
|
||||
if (IsUsableIndividualAddress(fallback_individual_address)) {
|
||||
device_.deviceObject().individualAddress(fallback_individual_address);
|
||||
}
|
||||
const uint8_t* memory = platform_.getNonVolatileMemoryStart();
|
||||
const size_t memory_size = platform_.getNonVolatileMemorySize();
|
||||
if (!IsErasedMemory(memory, memory_size)) {
|
||||
device_.readMemory();
|
||||
}
|
||||
ESP_LOGI("gateway_knx", "OpenKNX loading memory namespace=%s", nvs_namespace_.c_str());
|
||||
device_.readMemory();
|
||||
if (!IsUsableIndividualAddress(device_.deviceObject().individualAddress()) &&
|
||||
IsUsableIndividualAddress(fallback_individual_address)) {
|
||||
device_.deviceObject().individualAddress(fallback_individual_address);
|
||||
}
|
||||
LogReg1DaliIdentity(nvs_namespace_, device_);
|
||||
if (auto* server = device_.getCemiServer()) {
|
||||
server->clientAddress(IsUsableIndividualAddress(tunnel_client_address)
|
||||
? tunnel_client_address
|
||||
@@ -92,6 +142,9 @@ EtsDeviceRuntime::EtsDeviceRuntime(std::string nvs_namespace,
|
||||
}
|
||||
|
||||
EtsDeviceRuntime::~EtsDeviceRuntime() {
|
||||
if (tp_uart_interface_ != nullptr) {
|
||||
device_.enabled(false);
|
||||
}
|
||||
platform_.outboundCemiFrameCallback(nullptr, nullptr);
|
||||
#ifdef USE_DATASECURE
|
||||
device_.secureGroupWriteCallback(nullptr, nullptr);
|
||||
@@ -170,10 +223,43 @@ void EtsDeviceRuntime::setGroupWriteHandler(GroupWriteHandler handler) {
|
||||
group_write_handler_ = std::move(handler);
|
||||
}
|
||||
|
||||
void EtsDeviceRuntime::setBusFrameSender(CemiFrameSender sender) {
|
||||
bus_frame_sender_ = std::move(sender);
|
||||
}
|
||||
|
||||
void EtsDeviceRuntime::setNetworkInterface(esp_netif_t* netif) {
|
||||
platform_.networkInterface(netif);
|
||||
}
|
||||
|
||||
bool EtsDeviceRuntime::hasTpUart() const { return tp_uart_interface_ != nullptr; }
|
||||
|
||||
bool EtsDeviceRuntime::enableTpUart(bool enabled) {
|
||||
if (tp_uart_interface_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
device_.enabled(enabled);
|
||||
loop();
|
||||
return !enabled || device_.enabled();
|
||||
}
|
||||
|
||||
bool EtsDeviceRuntime::tpUartOnline() const {
|
||||
return tp_uart_interface_ != nullptr && const_cast<Bau07B0&>(device_).enabled();
|
||||
}
|
||||
|
||||
bool EtsDeviceRuntime::transmitTpFrame(const uint8_t* data, size_t len) {
|
||||
auto* data_link_layer = device_.getDataLinkLayer();
|
||||
if (tp_uart_interface_ == nullptr || data_link_layer == nullptr || data == nullptr || len < 2 ||
|
||||
!data_link_layer->enabled()) {
|
||||
return false;
|
||||
}
|
||||
std::vector<uint8_t> frame_data(data, data + len);
|
||||
CemiFrame frame(frame_data.data(), static_cast<uint16_t>(frame_data.size()));
|
||||
if (!frame.valid()) {
|
||||
return false;
|
||||
}
|
||||
return data_link_layer->transmitFrame(frame);
|
||||
}
|
||||
|
||||
bool EtsDeviceRuntime::handleTunnelFrame(const uint8_t* data, size_t len,
|
||||
CemiFrameSender sender) {
|
||||
auto* server = device_.getCemiServer();
|
||||
@@ -248,10 +334,16 @@ bool EtsDeviceRuntime::HandleOutboundCemiFrame(CemiFrame& frame, void* context)
|
||||
|
||||
void EtsDeviceRuntime::EmitTunnelFrame(CemiFrame& frame, void* context) {
|
||||
auto* self = static_cast<EtsDeviceRuntime*>(context);
|
||||
if (self == nullptr || !self->sender_) {
|
||||
if (self == nullptr) {
|
||||
return;
|
||||
}
|
||||
self->sender_(frame.data(), frame.dataLength());
|
||||
if (self->sender_) {
|
||||
self->sender_(frame.data(), frame.dataLength());
|
||||
return;
|
||||
}
|
||||
if (self->bus_frame_sender_) {
|
||||
self->bus_frame_sender_(frame.data(), frame.dataLength());
|
||||
}
|
||||
}
|
||||
|
||||
void EtsDeviceRuntime::HandleSecureGroupWrite(uint16_t group_address, const uint8_t* data,
|
||||
@@ -324,6 +416,9 @@ bool EtsDeviceRuntime::shouldConsumeTunnelFrame(CemiFrame& frame) const {
|
||||
case M_FuncPropStateRead_req:
|
||||
return true;
|
||||
case L_data_req: {
|
||||
if (tpUartOnline()) {
|
||||
return true;
|
||||
}
|
||||
// In commissioning / programming mode ETS may address the device via its
|
||||
// individual address, the cEMI-client tunnel address (device+1), or the
|
||||
// unconfigured broadcast address 0xFFFF. Consume only those; let all
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "ets_memory_loader.h"
|
||||
|
||||
#include "esp_idf_platform.h"
|
||||
#include "gateway_knx_internal.h"
|
||||
|
||||
#include "knx/bau07B0.h"
|
||||
#include "knx/property.h"
|
||||
@@ -28,18 +29,13 @@ bool IsErasedMemory(const uint8_t* data, size_t size) {
|
||||
return std::all_of(data, data + size, [](uint8_t value) { return value == 0xff; });
|
||||
}
|
||||
|
||||
constexpr uint16_t kReg1DaliManufacturerId = 0x00a4;
|
||||
constexpr uint8_t kReg1DaliApplicationNumber = 0x01;
|
||||
constexpr uint8_t kReg1DaliApplicationVersion = 0x05;
|
||||
constexpr uint8_t kReg1DaliOrderNumber[10] = {'R', 'E', 'G', '1', '-', 'D', 'a', 'l', 'i', 0};
|
||||
|
||||
void ApplyReg1DaliIdentity(Bau07B0& device, EspIdfPlatform& platform) {
|
||||
device.deviceObject().manufacturerId(kReg1DaliManufacturerId);
|
||||
device.deviceObject().manufacturerId(knx_internal::kReg1DaliManufacturerId);
|
||||
device.deviceObject().bauNumber(platform.uniqueSerialNumber());
|
||||
device.deviceObject().orderNumber(kReg1DaliOrderNumber);
|
||||
const uint8_t program_version[5] = {0x00, 0xa4, 0x00, kReg1DaliApplicationNumber,
|
||||
kReg1DaliApplicationVersion};
|
||||
device.parameters().property(PID_PROG_VERSION)->write(program_version);
|
||||
device.deviceObject().hardwareType(knx_internal::kReg1DaliHardwareType);
|
||||
device.deviceObject().orderNumber(knx_internal::kReg1DaliOrderNumber);
|
||||
device.parameters().property(PID_PROG_VERSION)->write(
|
||||
knx_internal::kReg1DaliProgramVersion);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user