feat(gateway): add KNX Data Secure support and related configurations
Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "gateway_modbus.hpp"
|
||||
#include "gateway_provisioning.hpp"
|
||||
#include "openknx_idf/ets_memory_loader.h"
|
||||
#include "openknx_idf/security_storage.h"
|
||||
|
||||
#include "cJSON.h"
|
||||
#include "driver/uart.h"
|
||||
@@ -121,6 +122,25 @@ GatewayBridgeHttpResponse ErrorResponse(esp_err_t err, const char* message) {
|
||||
return GatewayBridgeHttpResponse{err, body};
|
||||
}
|
||||
|
||||
cJSON* FactoryFdskInfoToCjson(const openknx::FactoryFdskInfo& fdsk_info,
|
||||
bool include_secret_strings) {
|
||||
cJSON* root = cJSON_CreateObject();
|
||||
if (root == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
cJSON_AddBoolToObject(root, "available", fdsk_info.available);
|
||||
if (fdsk_info.available) {
|
||||
cJSON_AddStringToObject(root, "serialNumber", fdsk_info.serialNumber.c_str());
|
||||
cJSON_AddNumberToObject(root, "labelLength", static_cast<double>(fdsk_info.label.size()));
|
||||
cJSON_AddNumberToObject(root, "qrCodeLength", static_cast<double>(fdsk_info.qrCode.size()));
|
||||
if (include_secret_strings) {
|
||||
cJSON_AddStringToObject(root, "label", fdsk_info.label.c_str());
|
||||
cJSON_AddStringToObject(root, "qrCode", fdsk_info.qrCode.c_str());
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
const char* JsonString(const cJSON* parent, const char* name) {
|
||||
const cJSON* item = cJSON_GetObjectItemCaseSensitive(parent, name);
|
||||
return cJSON_IsString(item) && item->valuestring != nullptr ? item->valuestring : nullptr;
|
||||
@@ -2041,6 +2061,40 @@ struct GatewayBridgeService::ChannelRuntime {
|
||||
cJSON_AddStringToObject(knx_json, "lastError",
|
||||
knx_last_error.empty() ? router_error.c_str()
|
||||
: knx_last_error.c_str());
|
||||
cJSON* security_json = cJSON_CreateObject();
|
||||
if (security_json != nullptr) {
|
||||
#if defined(CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED)
|
||||
cJSON_AddBoolToObject(security_json, "dataSecureCompiled", true);
|
||||
#else
|
||||
cJSON_AddBoolToObject(security_json, "dataSecureCompiled", false);
|
||||
#endif
|
||||
#if defined(CONFIG_GATEWAY_KNX_IP_SECURE_SUPPORTED)
|
||||
cJSON_AddBoolToObject(security_json, "knxnetIpSecureCompiled", true);
|
||||
#else
|
||||
cJSON_AddBoolToObject(security_json, "knxnetIpSecureCompiled", false);
|
||||
#endif
|
||||
cJSON_AddBoolToObject(security_json, "knxnetIpSecureImplemented", false);
|
||||
#if defined(CONFIG_GATEWAY_KNX_SECURITY_DEV_ENDPOINTS)
|
||||
cJSON_AddBoolToObject(security_json, "developmentEndpointsEnabled", true);
|
||||
#else
|
||||
cJSON_AddBoolToObject(security_json, "developmentEndpointsEnabled", false);
|
||||
#endif
|
||||
#if defined(CONFIG_GATEWAY_KNX_SECURITY_PLAIN_NVS)
|
||||
cJSON_AddBoolToObject(security_json, "plainNvsStorage", true);
|
||||
cJSON_AddStringToObject(security_json, "storage", "plain_nvs_development");
|
||||
#else
|
||||
cJSON_AddBoolToObject(security_json, "plainNvsStorage", false);
|
||||
cJSON_AddStringToObject(security_json, "storage", "none");
|
||||
#endif
|
||||
#if defined(CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED)
|
||||
const auto fdsk_info = openknx::LoadFactoryFdskInfo();
|
||||
cJSON* fdsk_json = FactoryFdskInfoToCjson(fdsk_info, false);
|
||||
if (fdsk_json != nullptr) {
|
||||
cJSON_AddItemToObject(security_json, "factorySetupKey", fdsk_json);
|
||||
}
|
||||
#endif
|
||||
cJSON_AddItemToObject(knx_json, "security", security_json);
|
||||
}
|
||||
if (effective_knx.has_value()) {
|
||||
cJSON_AddBoolToObject(knx_json, "daliRouterEnabled", effective_knx->dali_router_enabled);
|
||||
cJSON_AddBoolToObject(knx_json, "ipRouterEnabled", effective_knx->ip_router_enabled);
|
||||
@@ -4008,6 +4062,36 @@ GatewayBridgeHttpResponse GatewayBridgeService::handlePost(
|
||||
}
|
||||
return handleGet("knx", gateway_id.value());
|
||||
}
|
||||
if (action == "knx_security_read_factory_key") {
|
||||
#if defined(CONFIG_GATEWAY_KNX_SECURITY_DEV_ENDPOINTS) && \
|
||||
defined(CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED)
|
||||
cJSON* body_root = body.empty() ? nullptr : cJSON_ParseWithLength(body.data(), body.size());
|
||||
if (body_root == nullptr) {
|
||||
return ErrorResponse(ESP_ERR_INVALID_ARG, "confirmation JSON is required");
|
||||
}
|
||||
const char* confirm = JsonString(body_root, "confirm");
|
||||
const bool confirmed = confirm != nullptr &&
|
||||
std::string_view(confirm) == "read-factory-setup-key";
|
||||
cJSON_Delete(body_root);
|
||||
if (!confirmed) {
|
||||
return ErrorResponse(ESP_ERR_INVALID_ARG, "factory setup key read confirmation is required");
|
||||
}
|
||||
cJSON* response = cJSON_CreateObject();
|
||||
if (response == nullptr) {
|
||||
return ErrorResponse(ESP_ERR_NO_MEM, "failed to allocate security response");
|
||||
}
|
||||
cJSON* fdsk_json = FactoryFdskInfoToCjson(openknx::LoadFactoryFdskInfo(), true);
|
||||
if (fdsk_json == nullptr) {
|
||||
cJSON_Delete(response);
|
||||
return ErrorResponse(ESP_ERR_NO_MEM, "failed to allocate factory setup key response");
|
||||
}
|
||||
cJSON_AddItemToObject(response, "factorySetupKey", fdsk_json);
|
||||
return JsonOk(response);
|
||||
#else
|
||||
return ErrorResponse(ESP_ERR_NOT_SUPPORTED,
|
||||
"KNX security development endpoints are disabled");
|
||||
#endif
|
||||
}
|
||||
if (action == "bacnet_start") {
|
||||
const esp_err_t err = runtime->startBacnet();
|
||||
if (err != ESP_OK) {
|
||||
|
||||
Reference in New Issue
Block a user