Merge branch 'master' of github.com:technyon/nuki_hub into ota

This commit is contained in:
technyon
2022-06-15 20:26:44 +02:00
10 changed files with 121 additions and 11 deletions

View File

@@ -9,6 +9,11 @@ project(nuki_hub CXX)
set(LOG_LEVEL ARDUHAL_LOG_LEVEL_NONE) set(LOG_LEVEL ARDUHAL_LOG_LEVEL_NONE)
# Length of char arrays to store certificates for MQTTS
add_compile_definitions(TLS_CA_MAX_SIZE=1500)
add_compile_definitions(TLS_CERT_MAX_SIZE=1500)
add_compile_definitions(TLS_KEY_MAX_SIZE=1800)
include_directories(${PROJECT_NAME} include_directories(${PROJECT_NAME}
PRIVATE PRIVATE
lib/Crc16 lib/Crc16
@@ -84,6 +89,7 @@ target_link_arduino_libraries(${PROJECT_NAME}
PRIVATE PRIVATE
core core
WiFi WiFi
WiFiClientSecure
Update Update
# WebServer # WebServer
DNSServer DNSServer

View File

@@ -42,11 +42,11 @@ void Network::setupDevice(const NetworkDeviceType hardware)
break; break;
case NetworkDeviceType::WiFi: case NetworkDeviceType::WiFi:
Serial.println(F("Network device: Builtin WiFi")); Serial.println(F("Network device: Builtin WiFi"));
_device = new WifiDevice(_hostname); _device = new WifiDevice(_hostname, _preferences);
break; break;
default: default:
Serial.println(F("Unknown network device type, defaulting to WiFi")); Serial.println(F("Unknown network device type, defaulting to WiFi"));
_device = new WifiDevice(_hostname); _device = new WifiDevice(_hostname, _preferences);
break; break;
} }
} }
@@ -161,6 +161,8 @@ bool Network::reconnect()
{ {
Serial.print(F("MQTT connect failed, rc=")); Serial.print(F("MQTT connect failed, rc="));
Serial.println(_device->mqttClient()->state()); Serial.println(_device->mqttClient()->state());
_device->printError();
_device->mqttClient()->disconnect();
_mqttConnected = false; _mqttConnected = false;
_nextReconnect = millis() + 5000; _nextReconnect = millis() + 5000;
} }

View File

@@ -10,6 +10,9 @@
#define preference_mqtt_lock_path "mqttpath" #define preference_mqtt_lock_path "mqttpath"
#define preference_opener_enabled "openerena" #define preference_opener_enabled "openerena"
#define preference_mqtt_opener_path "mqttoppath" #define preference_mqtt_opener_path "mqttoppath"
#define preference_mqtt_ca "mqttca"
#define preference_mqtt_crt "mqttcrt"
#define preference_mqtt_key "mqttkey"
#define preference_hostname "hostname" #define preference_hostname "hostname"
#define preference_network_timeout "nettmout" #define preference_network_timeout "nettmout"
#define preference_query_interval_lockstate "lockStInterval" #define preference_query_interval_lockstate "lockStInterval"

View File

@@ -189,6 +189,21 @@ bool WebCfgServer::processArgs(String& message)
_preferences->putString(preference_mqtt_opener_path, value); _preferences->putString(preference_mqtt_opener_path, value);
configChanged = true; configChanged = true;
} }
else if(key == "MQTTCA")
{
_preferences->putString(preference_mqtt_ca, value);
configChanged = true;
}
else if(key == "MQTTCRT")
{
_preferences->putString(preference_mqtt_crt, value);
configChanged = true;
}
else if(key == "MQTTKEY")
{
_preferences->putString(preference_mqtt_key, value);
configChanged = true;
}
else if(key == "HOSTNAME") else if(key == "HOSTNAME")
{ {
_preferences->putString(preference_hostname, value); _preferences->putString(preference_hostname, value);
@@ -481,6 +496,9 @@ void WebCfgServer::buildMqttConfigHtml(String &response)
printInputField(response, "MQTTPORT", "MQTT Broker port", _preferences->getInt(preference_mqtt_broker_port), 5); printInputField(response, "MQTTPORT", "MQTT Broker port", _preferences->getInt(preference_mqtt_broker_port), 5);
printInputField(response, "MQTTUSER", "MQTT User (# to clear)", _preferences->getString(preference_mqtt_user).c_str(), 30); printInputField(response, "MQTTUSER", "MQTT User (# to clear)", _preferences->getString(preference_mqtt_user).c_str(), 30);
printInputField(response, "MQTTPASS", "MQTT Password", "*", 30, true); printInputField(response, "MQTTPASS", "MQTT Password", "*", 30, true);
printTextarea(response, "MQTTCA", "MQTT SSL CA Certificate", _preferences->getString(preference_mqtt_ca).c_str(), TLS_CA_MAX_SIZE);
printTextarea(response, "MQTTCRT", "MQTT SSL Client Certificate", _preferences->getString(preference_mqtt_crt).c_str(), TLS_CERT_MAX_SIZE);
printTextarea(response, "MQTTKEY", "MQTT SSL Client Key", _preferences->getString(preference_mqtt_key).c_str(), TLS_KEY_MAX_SIZE);
printInputField(response, "NETTIMEOUT", "Network Timeout until restart (seconds; -1 to disable)", _preferences->getInt(preference_network_timeout), 5); printInputField(response, "NETTIMEOUT", "Network Timeout until restart (seconds; -1 to disable)", _preferences->getInt(preference_network_timeout), 5);
response.concat("</table>"); response.concat("</table>");
response.concat("<br><INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"Save\">"); response.concat("<br><INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"Save\">");
@@ -624,6 +642,32 @@ void WebCfgServer::printCheckBox(String &response, const char *token, const char
response.concat("/></td></tr>"); response.concat("/></td></tr>");
} }
void WebCfgServer::printTextarea(String& response,
const char *token,
const char *description,
const char *value,
const size_t maxLength)
{
char maxLengthStr[20];
itoa(maxLength, maxLengthStr, 10);
response.concat("<tr>");
response.concat("<td>");
response.concat(description);
response.concat("</td>");
response.concat("<td>");
response.concat(" <TEXTAREA NAME=\"");
response.concat(token);
response.concat("\" MAXLENGTH=\"");
response.concat(maxLengthStr);
response.concat("\\\">");
response.concat(value);
response.concat("</TEXTAREA>");
response.concat("</td>");
response.concat("</tr>");
}
void WebCfgServer::printParameter(String& response, const char *description, const char *value) void WebCfgServer::printParameter(String& response, const char *description, const char *value)
{ {
response.concat("<tr>"); response.concat("<tr>");

View File

@@ -43,6 +43,7 @@ private:
void printInputField(String& response, const char* token, const char* description, const char* value, const size_t maxLength, const bool isPassword = false); void printInputField(String& response, const char* token, const char* description, const char* value, const size_t maxLength, const bool isPassword = false);
void printInputField(String& response, const char* token, const char* description, const int value, size_t maxLength); void printInputField(String& response, const char* token, const char* description, const int value, size_t maxLength);
void printCheckBox(String& response, const char* token, const char* description, const bool value); void printCheckBox(String& response, const char* token, const char* description, const bool value);
void printTextarea(String& response, const char *token, const char *description, const char *value, const size_t maxLength);
void printParameter(String& response, const char* description, const char* value); void printParameter(String& response, const char* description, const char* value);

View File

@@ -14,6 +14,7 @@ public:
virtual void initialize() = 0; virtual void initialize() = 0;
virtual bool reconnect() = 0; virtual bool reconnect() = 0;
virtual void reconfigure() = 0; virtual void reconfigure() = 0;
virtual void printError() = 0;
virtual void update() = 0; virtual void update() = 0;

View File

@@ -117,6 +117,13 @@ void W5500Device::resetDevice()
nwDelay(1500); nwDelay(1500);
} }
void W5500Device::printError()
{
Serial.print(F("Free Heap: "));
Serial.println(ESP.getFreeHeap());
}
PubSubClient *W5500Device::mqttClient() PubSubClient *W5500Device::mqttClient()
{ {
return _mqttClient; return _mqttClient;

View File

@@ -13,6 +13,7 @@ public:
virtual void initialize(); virtual void initialize();
virtual bool reconnect(); virtual bool reconnect();
virtual void reconfigure(); virtual void reconfigure();
virtual void printError();
virtual void update(); virtual void update();

View File

@@ -1,15 +1,41 @@
#include <WiFi.h> #include <WiFi.h>
#include "WifiDevice.h" #include "WifiDevice.h"
#include "WiFiManager.h" #include "WiFiManager.h"
#include "../PreferencesKeys.h"
WifiDevice::WifiDevice(const String& hostname) WifiDevice::WifiDevice(const String& hostname, Preferences* _preferences)
: NetworkDevice(hostname), : NetworkDevice(hostname)
_mqttClient(_wifiClient) {
{} size_t caLength = _preferences->getString(preference_mqtt_ca,_ca,TLS_CA_MAX_SIZE);
size_t crtLength = _preferences->getString(preference_mqtt_crt,_cert,TLS_CERT_MAX_SIZE);
size_t keyLength = _preferences->getString(preference_mqtt_key,_key,TLS_KEY_MAX_SIZE);
if(caLength > 1) // length is 1 when empty
{
Serial.println(F("MQTT over TLS."));
Serial.println(_ca);
_wifiClientSecure = new WiFiClientSecure();
_wifiClientSecure->setCACert(_ca);
if(crtLength > 1 && keyLength > 1) // length is 1 when empty
{
Serial.println(F("MQTT with client certificate."));
Serial.println(_cert);
Serial.println(_key);
_wifiClientSecure->setCertificate(_cert);
_wifiClientSecure->setPrivateKey(_key);
}
_mqttClient = new PubSubClient(*_wifiClientSecure);
} else
{
Serial.println(F("MQTT without TLS."));
_wifiClient = new WiFiClient();
_mqttClient = new PubSubClient(*_wifiClient);
}
}
PubSubClient *WifiDevice::mqttClient() PubSubClient *WifiDevice::mqttClient()
{ {
return &_mqttClient; return _mqttClient;
} }
void WifiDevice::initialize() void WifiDevice::initialize()
@@ -48,7 +74,7 @@ void WifiDevice::initialize()
Serial.println(WiFi.localIP().toString()); Serial.println(WiFi.localIP().toString());
} }
_mqttClient.setBufferSize(_mqttMaxBufferSize); _mqttClient->setBufferSize(_mqttMaxBufferSize);
} }
void WifiDevice::reconfigure() void WifiDevice::reconfigure()
@@ -58,6 +84,18 @@ void WifiDevice::reconfigure()
ESP.restart(); ESP.restart();
} }
void WifiDevice::printError()
{
if(_wifiClientSecure != nullptr)
{
char lastError[100];
_wifiClientSecure->lastError(lastError,100);
Serial.println(lastError);
}
Serial.print(F("Free Heap: "));
Serial.println(ESP.getFreeHeap());
}
bool WifiDevice::isConnected() bool WifiDevice::isConnected()
{ {
return WiFi.isConnected(); return WiFi.isConnected();

View File

@@ -1,17 +1,20 @@
#pragma once #pragma once
#include <WiFiClient.h> #include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <Preferences.h>
#include "NetworkDevice.h" #include "NetworkDevice.h"
#include "../SpiffsCookie.h" #include "../SpiffsCookie.h"
class WifiDevice : public NetworkDevice class WifiDevice : public NetworkDevice
{ {
public: public:
WifiDevice(const String& hostname); WifiDevice(const String& hostname, Preferences* _preferences);
virtual void initialize(); virtual void initialize();
virtual void reconfigure(); virtual void reconfigure();
virtual bool reconnect(); virtual bool reconnect();
virtual void printError();
virtual void update(); virtual void update();
@@ -20,7 +23,11 @@ public:
virtual PubSubClient *mqttClient(); virtual PubSubClient *mqttClient();
private: private:
WiFiClient _wifiClient; WiFiClient* _wifiClient = nullptr;
PubSubClient _mqttClient; WiFiClientSecure* _wifiClientSecure = nullptr;
PubSubClient* _mqttClient = nullptr;
SpiffsCookie _cookie; SpiffsCookie _cookie;
char _ca[TLS_CA_MAX_SIZE];
char _cert[TLS_CERT_MAX_SIZE];
char _key[TLS_KEY_MAX_SIZE];
}; };