137 lines
5.4 KiB
C++
137 lines
5.4 KiB
C++
#include "NetworkConfig.hpp"
|
|
#include "Hardware/Eth.hpp"
|
|
#include "Wifi.hpp"
|
|
#include "knx_facade.h"
|
|
#include "esp_log.h"
|
|
#include <cstring>
|
|
|
|
static const char* TAG = "NetworkConfig";
|
|
|
|
// Parameter offsets within the NW module's parameter block.
|
|
// These must match the offsets generated by OpenKNXproducer for the NW module.
|
|
// The producer assigns a base offset; these are relative offsets within Network.share.xml.
|
|
// After running the producer, update NW_PARAM_BASE to the assigned base offset.
|
|
|
|
static constexpr uint16_t NW_PARAM_BASE = 0; // Will be set by producer
|
|
|
|
// Byte 0: Flags
|
|
static constexpr uint16_t NW_FLAGS = NW_PARAM_BASE + 0;
|
|
static constexpr uint8_t NW_LAN_ENABLE_MASK = 0x80; // Bit 7
|
|
static constexpr uint8_t NW_LAN_STATIC_MASK = 0x40; // Bit 6
|
|
static constexpr uint8_t NW_WLAN_ENABLE_MASK = 0x20; // Bit 5
|
|
static constexpr uint8_t NW_WLAN_STATIC_MASK = 0x10; // Bit 4
|
|
|
|
// LAN IP config: bytes 1-16
|
|
static constexpr uint16_t NW_LAN_IP = NW_PARAM_BASE + 1;
|
|
static constexpr uint16_t NW_LAN_SUBNET = NW_PARAM_BASE + 5;
|
|
static constexpr uint16_t NW_LAN_GATEWAY = NW_PARAM_BASE + 9;
|
|
static constexpr uint16_t NW_LAN_DNS = NW_PARAM_BASE + 13;
|
|
|
|
// WLAN IP config: bytes 17-32
|
|
static constexpr uint16_t NW_WLAN_IP = NW_PARAM_BASE + 17;
|
|
static constexpr uint16_t NW_WLAN_SUBNET = NW_PARAM_BASE + 21;
|
|
static constexpr uint16_t NW_WLAN_GATEWAY = NW_PARAM_BASE + 25;
|
|
static constexpr uint16_t NW_WLAN_DNS = NW_PARAM_BASE + 29;
|
|
|
|
// WLAN credentials: bytes 33-129
|
|
static constexpr uint16_t NW_WLAN_WPA = NW_PARAM_BASE + 33;
|
|
static constexpr uint16_t NW_WLAN_SSID = NW_PARAM_BASE + 34;
|
|
static constexpr uint16_t NW_WLAN_PASS = NW_PARAM_BASE + 66;
|
|
static constexpr uint16_t NW_WLAN_SSID_LEN = 32;
|
|
static constexpr uint16_t NW_WLAN_PASS_LEN = 64;
|
|
|
|
extern KnxFacade<Esp32IdfPlatform, Bau07B0> knx;
|
|
|
|
static void readIpOctets(uint16_t offset, uint8_t out[4]) {
|
|
for (int i = 0; i < 4; i++) {
|
|
out[i] = knx.paramByte(offset + i);
|
|
}
|
|
}
|
|
|
|
static std::string readParamString(uint16_t offset, uint16_t maxLen) {
|
|
char buf[128] = {};
|
|
uint16_t len = (maxLen < sizeof(buf) - 1) ? maxLen : sizeof(buf) - 1;
|
|
for (uint16_t i = 0; i < len; i++) {
|
|
buf[i] = (char)knx.paramByte(offset + i);
|
|
if (buf[i] == '\0') break;
|
|
}
|
|
buf[len] = '\0';
|
|
return std::string(buf);
|
|
}
|
|
|
|
static wifi_auth_mode_t wpaVersionToAuthMode(uint8_t wpaVersion) {
|
|
switch (wpaVersion) {
|
|
case 1: return WIFI_AUTH_WPA3_PSK;
|
|
case 2: return WIFI_AUTH_WPA2_WPA3_PSK;
|
|
default: return WIFI_AUTH_WPA2_PSK;
|
|
}
|
|
}
|
|
|
|
void NetworkConfig::applyFromKnx() {
|
|
if (!knx.configured()) {
|
|
ESP_LOGW(TAG, "KNX not configured, using default network settings");
|
|
return;
|
|
}
|
|
|
|
uint8_t flags = knx.paramByte(NW_FLAGS);
|
|
bool lanEnabled = (flags & NW_LAN_ENABLE_MASK) != 0;
|
|
bool lanStatic = (flags & NW_LAN_STATIC_MASK) != 0;
|
|
bool wlanEnabled = (flags & NW_WLAN_ENABLE_MASK) != 0;
|
|
bool wlanStatic = (flags & NW_WLAN_STATIC_MASK) != 0;
|
|
|
|
ESP_LOGI(TAG, "Network config: LAN=%s(%s) WLAN=%s(%s)",
|
|
lanEnabled ? "on" : "off", lanStatic ? "static" : "dhcp",
|
|
wlanEnabled ? "on" : "off", wlanStatic ? "static" : "dhcp");
|
|
|
|
// Apply LAN static IP if configured
|
|
if (lanEnabled && lanStatic) {
|
|
StaticIpConfig cfg = {};
|
|
readIpOctets(NW_LAN_IP, cfg.ip);
|
|
readIpOctets(NW_LAN_SUBNET, cfg.subnet);
|
|
readIpOctets(NW_LAN_GATEWAY, cfg.gateway);
|
|
readIpOctets(NW_LAN_DNS, cfg.dns);
|
|
|
|
ESP_LOGI(TAG, "LAN static: %d.%d.%d.%d/%d.%d.%d.%d gw %d.%d.%d.%d dns %d.%d.%d.%d",
|
|
cfg.ip[0], cfg.ip[1], cfg.ip[2], cfg.ip[3],
|
|
cfg.subnet[0], cfg.subnet[1], cfg.subnet[2], cfg.subnet[3],
|
|
cfg.gateway[0], cfg.gateway[1], cfg.gateway[2], cfg.gateway[3],
|
|
cfg.dns[0], cfg.dns[1], cfg.dns[2], cfg.dns[3]);
|
|
|
|
Eth::instance().applyStaticIp(cfg);
|
|
}
|
|
|
|
// Initialize WLAN if enabled
|
|
if (wlanEnabled) {
|
|
Wifi::instance().init();
|
|
|
|
if (wlanStatic) {
|
|
StaticIpConfig cfg = {};
|
|
readIpOctets(NW_WLAN_IP, cfg.ip);
|
|
readIpOctets(NW_WLAN_SUBNET, cfg.subnet);
|
|
readIpOctets(NW_WLAN_GATEWAY, cfg.gateway);
|
|
readIpOctets(NW_WLAN_DNS, cfg.dns);
|
|
|
|
ESP_LOGI(TAG, "WLAN static: %d.%d.%d.%d/%d.%d.%d.%d gw %d.%d.%d.%d dns %d.%d.%d.%d",
|
|
cfg.ip[0], cfg.ip[1], cfg.ip[2], cfg.ip[3],
|
|
cfg.subnet[0], cfg.subnet[1], cfg.subnet[2], cfg.subnet[3],
|
|
cfg.gateway[0], cfg.gateway[1], cfg.gateway[2], cfg.gateway[3],
|
|
cfg.dns[0], cfg.dns[1], cfg.dns[2], cfg.dns[3]);
|
|
|
|
Wifi::instance().applyStaticIp(cfg);
|
|
}
|
|
|
|
// Read WLAN credentials from KNX parameters
|
|
std::string ssid = readParamString(NW_WLAN_SSID, NW_WLAN_SSID_LEN);
|
|
std::string password = readParamString(NW_WLAN_PASS, NW_WLAN_PASS_LEN);
|
|
uint8_t wpaVersion = knx.paramByte(NW_WLAN_WPA);
|
|
wifi_auth_mode_t authMode = wpaVersionToAuthMode(wpaVersion);
|
|
|
|
if (!ssid.empty()) {
|
|
ESP_LOGI(TAG, "WLAN connecting to SSID: %s (WPA=%d)", ssid.c_str(), wpaVersion);
|
|
Wifi::instance().connect(ssid.c_str(), password.c_str(), authMode);
|
|
} else {
|
|
ESP_LOGW(TAG, "WLAN enabled but no SSID configured");
|
|
}
|
|
}
|
|
}
|