Remove Solo1 support + validate HTTPS certs on HTTPS requests (#443)

* Use esp_crt_bundle for HTTPS requests

* Remove Solo1 support
This commit is contained in:
iranl
2024-08-08 12:29:48 +02:00
committed by GitHub
parent 1a7baca5da
commit 1f4e85a09e
30 changed files with 1532 additions and 1755 deletions

View File

@@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
board: [esp32dev, esp32-s3, esp32-c3, esp32-c6, esp32solo1]
board: [esp32dev, esp32-s3, esp32-c3, esp32-c6]
build: [release]
env:
BOARD: ${{ matrix.board }}

View File

@@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
board: [esp32dev, esp32-s3, esp32-c3, esp32-c6, esp32solo1]
board: [esp32dev, esp32-s3, esp32-c3, esp32-c6]
build: [release, debug]
env:
BOARD: ${{ matrix.board }}

View File

@@ -29,7 +29,7 @@ jobs:
strategy:
fail-fast: false
matrix:
board: [esp32dev, esp32-s3, esp32-c3, esp32-c6, esp32solo1]
board: [esp32dev, esp32-s3, esp32-c3, esp32-c6]
build: [release]
env:
BOARD: ${{ matrix.board }}

View File

@@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
board: [esp32dev, esp32-s3, esp32-c3, esp32-c6, esp32solo1]
board: [esp32dev, esp32-s3, esp32-c3, esp32-c6]
build: [release, debug]
env:
BOARD: ${{ matrix.board }}

View File

@@ -15,12 +15,12 @@ Feel free to join us on Discord: https://discord.gg/9nPq85bP4p
## Supported devices
<b>Supported ESP32 devices:</b>
- Nuki Hub is compiled against all ESP32 models with Wi-Fi and Bluetooh Low Energy (BLE) which are supported by ESP-IDF 5.1.4 and Arduino Core 3.0.1.
- Nuki Hub is compiled against all ESP32 models with Wi-Fi and Bluetooh Low Energy (BLE) which are supported by ESP-IDF 5.1.4 and Arduino Core 3.0.2.
- Tested stable builds are provided for the ESP32, ESP32-S3 and ESP32-C3.
- Support for the ESP32-C6 is experimental. There could be more frequent crashes than on other ESP32 devices and connections with the Nuki device could be slower than on other ESP32 devices.
- The ESP32-Solo1 is not supported by ESP-IDF 5.1 and as such can't be build using Arduino Core 3 and ESP-IDF 5.1. Untested builds against Arduino Core 2.0.14 and ESP-IDF 4.4 are provided.
<b>Not supported ESP32 devices:</b>
- The ESP32-Solo1 is not supported by ESP-IDF 5.1 and as such can't be build using Arduino Core 3 and ESP-IDF 5.1. Release 9.0 was the last (untested) release for the Solo1 which for the Solo1 is built against Arduino Core 2.0.14 and ESP-IDF 4.4.
- The ESP32-S2 has no BLE and as such can't run Nuki Hub.
- The ESP32-H2 has no Wi-FI and Nuki Hub is not compiled against this target because of this (at this time).

View File

@@ -14,42 +14,29 @@
#include <NetworkClientSecure.h>
// This is GandiStandardSSLCA2.pem, the root Certificate Authority that signed
// the server certificate for the demo server https://jigsaw.w3.org in this
// example. This certificate is valid until Sep 11 23:59:59 2024 GMT
// This is a Baltimore CyberTrust cert, the root Certificate Authority that
// signed the server certificate for the demo server https://jigsaw.w3.org in this
// example. This certificate is valid until Mon, 12 May 2025 23:59:00 GMT
const char *rootCACertificate = "-----BEGIN CERTIFICATE-----\n"
"MIIF6TCCA9GgAwIBAgIQBeTcO5Q4qzuFl8umoZhQ4zANBgkqhkiG9w0BAQwFADCB\n"
"iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n"
"cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n"
"BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQw\n"
"OTEyMDAwMDAwWhcNMjQwOTExMjM1OTU5WjBfMQswCQYDVQQGEwJGUjEOMAwGA1UE\n"
"CBMFUGFyaXMxDjAMBgNVBAcTBVBhcmlzMQ4wDAYDVQQKEwVHYW5kaTEgMB4GA1UE\n"
"AxMXR2FuZGkgU3RhbmRhcmQgU1NMIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n"
"DwAwggEKAoIBAQCUBC2meZV0/9UAPPWu2JSxKXzAjwsLibmCg5duNyj1ohrP0pIL\n"
"m6jTh5RzhBCf3DXLwi2SrCG5yzv8QMHBgyHwv/j2nPqcghDA0I5O5Q1MsJFckLSk\n"
"QFEW2uSEEi0FXKEfFxkkUap66uEHG4aNAXLy59SDIzme4OFMH2sio7QQZrDtgpbX\n"
"bmq08j+1QvzdirWrui0dOnWbMdw+naxb00ENbLAb9Tr1eeohovj0M1JLJC0epJmx\n"
"bUi8uBL+cnB89/sCdfSN3tbawKAyGlLfOGsuRTg/PwSWAP2h9KK71RfWJ3wbWFmV\n"
"XooS/ZyrgT5SKEhRhWvzkbKGPym1bgNi7tYFAgMBAAGjggF1MIIBcTAfBgNVHSME\n"
"GDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQUs5Cn2MmvTs1hPJ98\n"
"rV1/Qf1pMOowDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYD\n"
"VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMCIGA1UdIAQbMBkwDQYLKwYBBAGy\n"
"MQECAhowCAYGZ4EMAQIBMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNl\n"
"cnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNy\n"
"bDB2BggrBgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRy\n"
"dXN0LmNvbS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZ\n"
"aHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAWGf9\n"
"crJq13xhlhl+2UNG0SZ9yFP6ZrBrLafTqlb3OojQO3LJUP33WbKqaPWMcwO7lWUX\n"
"zi8c3ZgTopHJ7qFAbjyY1lzzsiI8Le4bpOHeICQW8owRc5E69vrOJAKHypPstLbI\n"
"FhfFcvwnQPYT/pOmnVHvPCvYd1ebjGU6NSU2t7WKY28HJ5OxYI2A25bUeo8tqxyI\n"
"yW5+1mUfr13KFj8oRtygNeX56eXVlogMT8a3d2dIhCe2H7Bo26y/d7CQuKLJHDJd\n"
"ArolQ4FCR7vY4Y8MDEZf7kYzawMUgtN+zY+vkNaOJH1AQrRqahfGlZfh8jjNp+20\n"
"J0CT33KpuMZmYzc4ZCIwojvxuch7yPspOqsactIGEk72gtQjbz7Dk+XYtsDe3CMW\n"
"1hMwt6CaDixVBgBwAc/qOR2A24j3pSC4W/0xJmmPLQphgzpHphNULB7j7UTKvGof\n"
"KA5R2d4On3XNDgOVyvnFqSot/kGkoUeuDcL5OWYzSlvhhChZbH2UF3bkRYKtcCD9\n"
"0m9jqNf6oDP6N8v3smWe2lBvP+Sn845dWDKXcCMu5/3EFZucJ48y7RetWIExKREa\n"
"m9T8bJUox04FB6b9HbwZ4ui3uRGKLXASUoWNjDNKD/yZkuBjcNqllEdjB+dYxzFf\n"
"BT02Vf6Dsuimrdfp5gJ0iHRc2jTbkNJtUQoj1iM=\n"
"MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\n"
"RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\n"
"VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\n"
"DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\n"
"ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\n"
"VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\n"
"mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\n"
"IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\n"
"mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\n"
"XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\n"
"dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\n"
"jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\n"
"BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\n"
"DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\n"
"9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\n"
"jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\n"
"Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\n"
"ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\n"
"R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n"
"-----END CERTIFICATE-----\n";
// Not sure if NetworkClientSecure checks the validity date of the certificate.

View File

@@ -1,5 +1,5 @@
name=HTTPClient
version=2.0.0
version=3.0.3
author=Markus Sattler
maintainer=Markus Sattler
sentence=HTTP Client for ESP32

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,8 @@
*
* Copyright (c) 2015 Markus Sattler. All rights reserved.
* This file is part of the HTTPClient for Arduino.
* Port to ESP32 by Evandro Luis Copercini (2017),
* changed fingerprints to CA verification.
* Port to ESP32 by Evandro Luis Copercini (2017),
* changed fingerprints to CA verification.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -33,12 +33,10 @@
#include <memory>
#include <Arduino.h>
#include <WiFiClient.h>
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
#include <WiFiClientSecure.h>
#else
#include <NetworkClient.h>
#ifndef HTTPCLIENT_NOSECURE
#include <NetworkClientSecure.h>
#endif
#endif // HTTPCLIENT_NOSECURE
/// Cookie jar support
#include <vector>
@@ -59,73 +57,74 @@
#define HTTPC_ERROR_READ_TIMEOUT (-11)
/// size for the stream handling
#define HTTP_TCP_BUFFER_SIZE (1460)
#define HTTP_TCP_RX_BUFFER_SIZE (4096)
#define HTTP_TCP_TX_BUFFER_SIZE (1460)
/// HTTP codes see RFC7231
typedef enum {
HTTP_CODE_CONTINUE = 100,
HTTP_CODE_SWITCHING_PROTOCOLS = 101,
HTTP_CODE_PROCESSING = 102,
HTTP_CODE_OK = 200,
HTTP_CODE_CREATED = 201,
HTTP_CODE_ACCEPTED = 202,
HTTP_CODE_NON_AUTHORITATIVE_INFORMATION = 203,
HTTP_CODE_NO_CONTENT = 204,
HTTP_CODE_RESET_CONTENT = 205,
HTTP_CODE_PARTIAL_CONTENT = 206,
HTTP_CODE_MULTI_STATUS = 207,
HTTP_CODE_ALREADY_REPORTED = 208,
HTTP_CODE_IM_USED = 226,
HTTP_CODE_MULTIPLE_CHOICES = 300,
HTTP_CODE_MOVED_PERMANENTLY = 301,
HTTP_CODE_FOUND = 302,
HTTP_CODE_SEE_OTHER = 303,
HTTP_CODE_NOT_MODIFIED = 304,
HTTP_CODE_USE_PROXY = 305,
HTTP_CODE_TEMPORARY_REDIRECT = 307,
HTTP_CODE_PERMANENT_REDIRECT = 308,
HTTP_CODE_BAD_REQUEST = 400,
HTTP_CODE_UNAUTHORIZED = 401,
HTTP_CODE_PAYMENT_REQUIRED = 402,
HTTP_CODE_FORBIDDEN = 403,
HTTP_CODE_NOT_FOUND = 404,
HTTP_CODE_METHOD_NOT_ALLOWED = 405,
HTTP_CODE_NOT_ACCEPTABLE = 406,
HTTP_CODE_PROXY_AUTHENTICATION_REQUIRED = 407,
HTTP_CODE_REQUEST_TIMEOUT = 408,
HTTP_CODE_CONFLICT = 409,
HTTP_CODE_GONE = 410,
HTTP_CODE_LENGTH_REQUIRED = 411,
HTTP_CODE_PRECONDITION_FAILED = 412,
HTTP_CODE_PAYLOAD_TOO_LARGE = 413,
HTTP_CODE_URI_TOO_LONG = 414,
HTTP_CODE_UNSUPPORTED_MEDIA_TYPE = 415,
HTTP_CODE_RANGE_NOT_SATISFIABLE = 416,
HTTP_CODE_EXPECTATION_FAILED = 417,
HTTP_CODE_MISDIRECTED_REQUEST = 421,
HTTP_CODE_UNPROCESSABLE_ENTITY = 422,
HTTP_CODE_LOCKED = 423,
HTTP_CODE_FAILED_DEPENDENCY = 424,
HTTP_CODE_UPGRADE_REQUIRED = 426,
HTTP_CODE_PRECONDITION_REQUIRED = 428,
HTTP_CODE_TOO_MANY_REQUESTS = 429,
HTTP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
HTTP_CODE_INTERNAL_SERVER_ERROR = 500,
HTTP_CODE_NOT_IMPLEMENTED = 501,
HTTP_CODE_BAD_GATEWAY = 502,
HTTP_CODE_SERVICE_UNAVAILABLE = 503,
HTTP_CODE_GATEWAY_TIMEOUT = 504,
HTTP_CODE_HTTP_VERSION_NOT_SUPPORTED = 505,
HTTP_CODE_VARIANT_ALSO_NEGOTIATES = 506,
HTTP_CODE_INSUFFICIENT_STORAGE = 507,
HTTP_CODE_LOOP_DETECTED = 508,
HTTP_CODE_NOT_EXTENDED = 510,
HTTP_CODE_NETWORK_AUTHENTICATION_REQUIRED = 511
HTTP_CODE_CONTINUE = 100,
HTTP_CODE_SWITCHING_PROTOCOLS = 101,
HTTP_CODE_PROCESSING = 102,
HTTP_CODE_OK = 200,
HTTP_CODE_CREATED = 201,
HTTP_CODE_ACCEPTED = 202,
HTTP_CODE_NON_AUTHORITATIVE_INFORMATION = 203,
HTTP_CODE_NO_CONTENT = 204,
HTTP_CODE_RESET_CONTENT = 205,
HTTP_CODE_PARTIAL_CONTENT = 206,
HTTP_CODE_MULTI_STATUS = 207,
HTTP_CODE_ALREADY_REPORTED = 208,
HTTP_CODE_IM_USED = 226,
HTTP_CODE_MULTIPLE_CHOICES = 300,
HTTP_CODE_MOVED_PERMANENTLY = 301,
HTTP_CODE_FOUND = 302,
HTTP_CODE_SEE_OTHER = 303,
HTTP_CODE_NOT_MODIFIED = 304,
HTTP_CODE_USE_PROXY = 305,
HTTP_CODE_TEMPORARY_REDIRECT = 307,
HTTP_CODE_PERMANENT_REDIRECT = 308,
HTTP_CODE_BAD_REQUEST = 400,
HTTP_CODE_UNAUTHORIZED = 401,
HTTP_CODE_PAYMENT_REQUIRED = 402,
HTTP_CODE_FORBIDDEN = 403,
HTTP_CODE_NOT_FOUND = 404,
HTTP_CODE_METHOD_NOT_ALLOWED = 405,
HTTP_CODE_NOT_ACCEPTABLE = 406,
HTTP_CODE_PROXY_AUTHENTICATION_REQUIRED = 407,
HTTP_CODE_REQUEST_TIMEOUT = 408,
HTTP_CODE_CONFLICT = 409,
HTTP_CODE_GONE = 410,
HTTP_CODE_LENGTH_REQUIRED = 411,
HTTP_CODE_PRECONDITION_FAILED = 412,
HTTP_CODE_PAYLOAD_TOO_LARGE = 413,
HTTP_CODE_URI_TOO_LONG = 414,
HTTP_CODE_UNSUPPORTED_MEDIA_TYPE = 415,
HTTP_CODE_RANGE_NOT_SATISFIABLE = 416,
HTTP_CODE_EXPECTATION_FAILED = 417,
HTTP_CODE_MISDIRECTED_REQUEST = 421,
HTTP_CODE_UNPROCESSABLE_ENTITY = 422,
HTTP_CODE_LOCKED = 423,
HTTP_CODE_FAILED_DEPENDENCY = 424,
HTTP_CODE_UPGRADE_REQUIRED = 426,
HTTP_CODE_PRECONDITION_REQUIRED = 428,
HTTP_CODE_TOO_MANY_REQUESTS = 429,
HTTP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
HTTP_CODE_INTERNAL_SERVER_ERROR = 500,
HTTP_CODE_NOT_IMPLEMENTED = 501,
HTTP_CODE_BAD_GATEWAY = 502,
HTTP_CODE_SERVICE_UNAVAILABLE = 503,
HTTP_CODE_GATEWAY_TIMEOUT = 504,
HTTP_CODE_HTTP_VERSION_NOT_SUPPORTED = 505,
HTTP_CODE_VARIANT_ALSO_NEGOTIATES = 506,
HTTP_CODE_INSUFFICIENT_STORAGE = 507,
HTTP_CODE_LOOP_DETECTED = 508,
HTTP_CODE_NOT_EXTENDED = 510,
HTTP_CODE_NETWORK_AUTHENTICATION_REQUIRED = 511
} t_http_codes;
typedef enum {
HTTPC_TE_IDENTITY,
HTTPC_TE_CHUNKED
HTTPC_TE_IDENTITY,
HTTPC_TE_CHUNKED
} transferEncoding_t;
/**
@@ -140,176 +139,184 @@ typedef enum {
* In the sense of the RFC, it's just like every redirection is confirmed.
*/
typedef enum {
HTTPC_DISABLE_FOLLOW_REDIRECTS,
HTTPC_STRICT_FOLLOW_REDIRECTS,
HTTPC_FORCE_FOLLOW_REDIRECTS
HTTPC_DISABLE_FOLLOW_REDIRECTS,
HTTPC_STRICT_FOLLOW_REDIRECTS,
HTTPC_FORCE_FOLLOW_REDIRECTS
} followRedirects_t;
#ifdef HTTPCLIENT_1_1_COMPATIBLE
class TransportTraits;
typedef std::unique_ptr<TransportTraits> TransportTraitsPtr;
#endif
// cookie jar support
typedef struct {
String host; // host which tries to set the cookie
time_t date; // timestamp of the response that set the cookie
String name;
String value;
String domain;
String path = "";
struct {
time_t date = 0;
bool valid = false;
} expires;
struct {
time_t duration = 0;
bool valid = false;
} max_age;
bool http_only = false;
bool secure = false;
typedef struct {
String host; // host which tries to set the cookie
time_t date; // timestamp of the response that set the cookie
String name;
String value;
String domain;
String path = "";
struct {
time_t date = 0;
bool valid = false;
} expires;
struct {
time_t duration = 0;
bool valid = false;
} max_age;
bool http_only = false;
bool secure = false;
} Cookie;
typedef std::vector<Cookie> CookieJar;
class HTTPClient
{
class HTTPClient {
public:
HTTPClient();
~HTTPClient();
HTTPClient();
~HTTPClient();
/*
* Since both begin() functions take a reference to client as a parameter, you need to
/*
* Since both begin() functions take a reference to client as a parameter, you need to
* ensure the client object lives the entire time of the HTTPClient
*/
bool begin(WiFiClient &client, String url);
bool begin(WiFiClient &client, String host, uint16_t port, String uri = "/", bool https = false);
bool begin(NetworkClient &client, String url);
bool begin(NetworkClient &client, String host, uint16_t port, String uri = "/", bool https = false);
#ifdef HTTPCLIENT_1_1_COMPATIBLE
bool begin(String url);
bool begin(String url, const char* CAcert);
bool begin(String host, uint16_t port, String uri = "/");
bool begin(String host, uint16_t port, String uri, const char* CAcert);
bool begin(String host, uint16_t port, String uri, const char* CAcert, const char* cli_cert, const char* cli_key);
bool begin(String url);
bool begin(String host, uint16_t port, String uri = "/");
#ifndef HTTPCLIENT_NOSECURE
bool begin(String url, const char *CAcert);
bool begin(String host, uint16_t port, String uri, const char *CAcert);
bool begin(String host, uint16_t port, String uri, const char *CAcert, const char *cli_cert, const char *cli_key);
#else
bool begin(String url, const char *CAcert) {
return false;
};
bool begin(String host, uint16_t port, String uri, const char *CAcert) {
return false;
};
bool begin(String host, uint16_t port, String uri, const char *CAcert, const char *cli_cert, const char *cli_key) {
return false;
};
#endif // HTTPCLIENT_NOSECURE
#endif
void end(void);
void end(void);
bool connected(void);
bool connected(void);
void setReuse(bool reuse); /// keep-alive
void setUserAgent(const String& userAgent);
void setAuthorization(const char * user, const char * password);
void setAuthorization(const char * auth);
void setAuthorizationType(const char * authType);
void setConnectTimeout(int32_t connectTimeout);
void setTimeout(uint16_t timeout);
void setReuse(bool reuse); /// keep-alive
void setUserAgent(const String &userAgent);
void setAcceptEncoding(const String &acceptEncoding);
void setAuthorization(const char *user, const char *password);
void setAuthorization(const char *auth);
void setAuthorizationType(const char *authType);
void setConnectTimeout(int32_t connectTimeout);
void setTimeout(uint16_t timeout);
// Redirections
void setFollowRedirects(followRedirects_t follow);
void setRedirectLimit(uint16_t limit); // max redirects to follow for a single request
// Redirections
void setFollowRedirects(followRedirects_t follow);
void setRedirectLimit(uint16_t limit); // max redirects to follow for a single request
bool setURL(const String &url);
void useHTTP10(bool usehttp10 = true);
bool setURL(const String &url);
void useHTTP10(bool usehttp10 = true);
/// request handling
int GET();
int PATCH(uint8_t * payload, size_t size);
int PATCH(String payload);
int POST(uint8_t * payload, size_t size);
int POST(String payload);
int PUT(uint8_t * payload, size_t size);
int PUT(String payload);
int sendRequest(const char * type, String payload);
int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0);
int sendRequest(const char * type, Stream * stream, size_t size = 0);
/// request handling
int GET();
int PATCH(uint8_t *payload, size_t size);
int PATCH(String payload);
int POST(uint8_t *payload, size_t size);
int POST(String payload);
int PUT(uint8_t *payload, size_t size);
int PUT(String payload);
int sendRequest(const char *type, String payload);
int sendRequest(const char *type, uint8_t *payload = NULL, size_t size = 0);
int sendRequest(const char *type, Stream *stream, size_t size = 0);
void addHeader(const String& name, const String& value, bool first = false, bool replace = true);
void addHeader(const String &name, const String &value, bool first = false, bool replace = true);
/// Response handling
void collectHeaders(const char* headerKeys[], const size_t headerKeysCount);
String header(const char* name); // get request header value by name
String header(size_t i); // get request header value by number
String headerName(size_t i); // get request header name by number
int headers(); // get header count
bool hasHeader(const char* name); // check if header exists
/// Response handling
void collectHeaders(const char *headerKeys[], const size_t headerKeysCount);
String header(const char *name); // get request header value by name
String header(size_t i); // get request header value by number
String headerName(size_t i); // get request header name by number
int headers(); // get header count
bool hasHeader(const char *name); // check if header exists
int getSize(void);
const String &getLocation(void);
int getSize(void);
const String &getLocation(void);
NetworkClient &getStream(void);
NetworkClient *getStreamPtr(void);
int writeToStream(Stream *stream);
String getString(void);
WiFiClient& getStream(void);
WiFiClient* getStreamPtr(void);
int writeToStream(Stream* stream);
String getString(void);
static String errorToString(int error);
static String errorToString(int error);
/// Cookie jar support
void setCookieJar(CookieJar* cookieJar);
void resetCookieJar();
void clearAllCookies();
/// Cookie jar support
void setCookieJar(CookieJar *cookieJar);
void resetCookieJar();
void clearAllCookies();
protected:
struct RequestArgument {
String key;
String value;
};
struct RequestArgument {
String key;
String value;
};
bool beginInternal(String url, const char* expectedProtocol);
void disconnect(bool preserveClient = false);
void clear();
int returnError(int error);
bool connect(void);
bool sendHeader(const char * type);
int handleHeaderResponse();
int writeToStreamDataBlock(Stream * stream, int len);
bool beginInternal(String url, const char *expectedProtocol);
void disconnect(bool preserveClient = false);
void clear();
int returnError(int error);
bool connect(void);
bool sendHeader(const char *type);
int handleHeaderResponse();
int writeToStreamDataBlock(Stream *stream, int len);
/// Cookie jar support
void setCookie(String date, String headerValue);
bool generateCookieString(String *cookieString);
/// Cookie jar support
void setCookie(String date, String headerValue);
bool generateCookieString(String *cookieString);
#ifdef HTTPCLIENT_1_1_COMPATIBLE
TransportTraitsPtr _transportTraits;
std::unique_ptr<WiFiClient> _tcpDeprecated;
TransportTraitsPtr _transportTraits;
std::unique_ptr<NetworkClient> _tcpDeprecated;
#endif
WiFiClient* _client = nullptr;
NetworkClient *_client = nullptr;
/// request handling
String _host;
uint16_t _port = 0;
int32_t _connectTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT;
bool _reuse = true;
uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT;
bool _useHTTP10 = false;
bool _secure = false;
/// request handling
String _host;
uint16_t _port = 0;
int32_t _connectTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT;
bool _reuse = true;
uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT;
bool _useHTTP10 = false;
bool _secure = false;
String _uri;
String _protocol;
String _headers;
String _userAgent = "ESP32HTTPClient";
String _base64Authorization;
String _authorizationType = "Basic";
String _uri;
String _protocol;
String _headers;
String _userAgent = "ESP32HTTPClient";
String _base64Authorization;
String _authorizationType = "Basic";
String _acceptEncoding = "identity;q=1,chunked;q=0.1,*;q=0";
/// Response handling
RequestArgument* _currentHeaders = nullptr;
size_t _headerKeysCount = 0;
/// Response handling
RequestArgument *_currentHeaders = nullptr;
size_t _headerKeysCount = 0;
int _returnCode = 0;
int _size = -1;
bool _canReuse = false;
followRedirects_t _followRedirects = HTTPC_DISABLE_FOLLOW_REDIRECTS;
uint16_t _redirectLimit = 10;
String _location;
transferEncoding_t _transferEncoding = HTTPC_TE_IDENTITY;
/// Cookie jar support
CookieJar* _cookieJar = nullptr;
int _returnCode = 0;
int _size = -1;
bool _canReuse = false;
followRedirects_t _followRedirects = HTTPC_DISABLE_FOLLOW_REDIRECTS;
uint16_t _redirectLimit = 10;
String _location;
transferEncoding_t _transferEncoding = HTTPC_TE_IDENTITY;
/// Cookie jar support
CookieJar *_cookieJar = nullptr;
};
#endif /* HTTPClient_H_ */
#endif /* HTTPClient_H_ */

View File

@@ -18,27 +18,37 @@ const char *server = "www.howsmyssl.com"; // Server URL
// change it to your server root CA
// SHA1 fingerprint is broken now!
const char *test_root_ca = "-----BEGIN CERTIFICATE-----\n"
"MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/\n"
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n"
"DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow\n"
"PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD\n"
"Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n"
"AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O\n"
"rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq\n"
"OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b\n"
"xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw\n"
"7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD\n"
"aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\n"
"HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG\n"
"SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69\n"
"ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr\n"
"AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz\n"
"R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5\n"
"JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo\n"
"Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ\n"
"-----END CERTIFICATE-----\n";
const char *test_root_ca = R"literal(
-----BEGIN CERTIFICATE-----
MIIFBTCCAu2gAwIBAgIQS6hSk/eaL6JzBkuoBI110DANBgkqhkiG9w0BAQsFADBP
MQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFy
Y2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMTAeFw0yNDAzMTMwMDAwMDBa
Fw0yNzAzMTIyMzU5NTlaMDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBF
bmNyeXB0MQwwCgYDVQQDEwNSMTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDPV+XmxFQS7bRH/sknWHZGUCiMHT6I3wWd1bUYKb3dtVq/+vbOo76vACFL
YlpaPAEvxVgD9on/jhFD68G14BQHlo9vH9fnuoE5CXVlt8KvGFs3Jijno/QHK20a
/6tYvJWuQP/py1fEtVt/eA0YYbwX51TGu0mRzW4Y0YCF7qZlNrx06rxQTOr8IfM4
FpOUurDTazgGzRYSespSdcitdrLCnF2YRVxvYXvGLe48E1KGAdlX5jgc3421H5KR
mudKHMxFqHJV8LDmowfs/acbZp4/SItxhHFYyTr6717yW0QrPHTnj7JHwQdqzZq3
DZb3EoEmUVQK7GH29/Xi8orIlQ2NAgMBAAGjgfgwgfUwDgYDVR0PAQH/BAQDAgGG
MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATASBgNVHRMBAf8ECDAGAQH/
AgEAMB0GA1UdDgQWBBS7vMNHpeS8qcbDpHIMEI2iNeHI6DAfBgNVHSMEGDAWgBR5
tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAKG
Fmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0gBAwwCjAIBgZngQwBAgEwJwYD
VR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVuY3Iub3JnLzANBgkqhkiG9w0B
AQsFAAOCAgEAkrHnQTfreZ2B5s3iJeE6IOmQRJWjgVzPw139vaBw1bGWKCIL0vIo
zwzn1OZDjCQiHcFCktEJr59L9MhwTyAWsVrdAfYf+B9haxQnsHKNY67u4s5Lzzfd
u6PUzeetUK29v+PsPmI2cJkxp+iN3epi4hKu9ZzUPSwMqtCceb7qPVxEbpYxY1p9
1n5PJKBLBX9eb9LU6l8zSxPWV7bK3lG4XaMJgnT9x3ies7msFtpKK5bDtotij/l0
GaKeA97pb5uwD9KgWvaFXMIEt8jVTjLEvwRdvCn294GPDF08U8lAkIv7tghluaQh
1QnlE4SEN4LOECj8dsIGJXpGUk3aU3KkJz9icKy+aUgA+2cP21uh6NcDIS3XyfaZ
QjmDQ993ChII8SXWupQZVBiIpcWO4RqZk3lr7Bz5MUCwzDIA359e57SSq5CCkY0N
4B6Vulk7LktfwrdGNVI5BsC9qqxSwSKgRJeZ9wygIaehbHFHFhcBaMDKpiZlBHyz
rsnnlFXCb5s8HKn5LsUgGvB24L7sGNZP2CX7dhHov+YhD+jozLW2p9W4959Bz2Ei
RmqDtmiXLnzqTpXbI+suyCsohKRg6Un0RC47+cpiVwHiXZAW+cn8eiNIjqbVgXLx
KPpdzvvtTnOPlC7SQZSYmdunr3Bf9b77AiC/ZidstK36dRILKz7OA54=
-----END CERTIFICATE-----
)literal";
// You can use x.509 client certificates if you want
//const char* test_client_key = ""; //to verify the client
//const char* test_client_cert = ""; //to verify the client

View File

@@ -1,5 +1,5 @@
name=NetworkClientSecure
version=2.0.0
version=3.0.3
author=Evandro Luis Copercini
maintainer=Github Community
sentence=Enables secure network connection (local and Internet) using the ESP32 built-in WiFi.

View File

@@ -305,9 +305,11 @@ int NetworkClientSecure::available() {
res = data_to_read(sslclient.get());
if (res < 0 && !_stillinPlainStart) {
log_e("Closing connection on failed available check");
if (res != MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
log_e("Closing connection on failed available check");
}
stop();
return peeked ? peeked : res;
return peeked;
}
return res + peeked;
}
@@ -337,9 +339,9 @@ void NetworkClientSecure::setCACert(const char *rootCA) {
_use_insecure = false;
}
void NetworkClientSecure::setCACertBundle(const uint8_t *bundle) {
if (bundle != NULL) {
esp_crt_bundle_set(bundle, sizeof(bundle));
void NetworkClientSecure::setCACertBundle(const uint8_t *bundle, size_t size) {
if (bundle != NULL && size > 0) {
esp_crt_bundle_set(bundle, size);
attach_ssl_certificate_bundle(sslclient.get(), true);
_use_ca_bundle = true;
} else {
@@ -349,6 +351,11 @@ void NetworkClientSecure::setCACertBundle(const uint8_t *bundle) {
}
}
void NetworkClientSecure::setDefaultCACertBundle() {
attach_ssl_certificate_bundle(sslclient.get(), true);
_use_ca_bundle = true;
}
void NetworkClientSecure::setCertificate(const char *client_ca) {
if (_cert_free && _cert) {
free((void *)_cert);

View File

@@ -73,7 +73,8 @@ public:
void setCertificate(const char *client_ca);
void setPrivateKey(const char *private_key);
bool loadCACert(Stream &stream, size_t size);
void setCACertBundle(const uint8_t *bundle);
void setCACertBundle(const uint8_t *bundle, size_t size);
void setDefaultCACertBundle();
bool loadCertificate(Stream &stream, size_t size);
bool loadPrivateKey(Stream &stream, size_t size);
bool verify(const char *fingerprint, const char *domain_name);

View File

@@ -1,3 +1,3 @@
#pragma once
#include "NetworkClientSecure.h"
#define WiFiClientSecure NetworkClientSecure
typedef NetworkClientSecure WiFiClientSecure;

View File

@@ -27,7 +27,7 @@
const char *pers = "esp32-tls";
static int _handle_error(int err, const char *function, int line) {
if (err == -30848) {
if (err == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
return err;
}
#ifdef MBEDTLS_ERROR_C

View File

@@ -7,8 +7,6 @@ from pathlib import Path
def get_board_name(env):
board = env.get('BOARD_MCU')
if env.get('BOARD') == 'esp32-solo1':
board = env.get('BOARD').replace('-', '')
return board
def create_target_dir(env):
@@ -37,9 +35,6 @@ def merge_bin(source, target, env):
#if not env.get('BUILD_TYPE') in ['release']:
# return
if env.get('BOARD') in ['esp32-solo1']:
return
board = get_board_name(env)
chip = env.get('BOARD_MCU')
target_dir = create_target_dir(env)

View File

@@ -59,7 +59,7 @@ monitor_filters =
[env:esp32dev]
board = esp32dev
extra_scripts =
extra_scripts =
pre:pio_package_pre.py
post:pio_package.py
build_flags =
@@ -86,29 +86,6 @@ board = nuki-esp32-s3
extends = env:esp32dev
board = esp32-c6-devkitm-1
[env:esp32solo1]
platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32-2023.10.03.zip
framework = arduino
board = esp32-solo1
extra_scripts =
pre:pio_package_pre.py
post:pio_package.py
build_flags =
${env.build_flags}
-DFRAMEWORK_ARDUINO_SOLO1
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=0
-DCONFIG_BT_NIMBLE_LOG_LEVEL=0
-DNUKI_ALT_CONNECT
-DNUKI_64BIT_TIME
lib_deps =
BleScanner=symlink://lib/BleScanner
lib_ignore =
esp-nimble-cpp
NetworkClientSecure
ESPAsyncTCP-esphome
AsyncTCP_RP2040W
[env:esp32dev_dbg]
extends = env:esp32dev
custom_build = debug
@@ -195,22 +172,4 @@ build_flags =
-DDEBUG_NUKI_CONNECT
-DDEBUG_NUKI_COMMUNICATION
;-DDEBUG_NUKI_HEX_DATA
-DDEBUG_NUKI_READABLE_DATA
[env:esp32solo1_dbg]
extends = env:esp32solo1
custom_build = debug
build_flags =
${env.build_flags}
-DFRAMEWORK_ARDUINO_SOLO1
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=0
-DNUKI_ALT_CONNECT
-DNUKI_64BIT_TIME
-DDEBUG_NUKIHUB
-DDEBUG_SENSE_NUKI
-DDEBUG_NUKI_COMMAND
-DDEBUG_NUKI_CONNECT
-DDEBUG_NUKI_COMMUNICATION
;-DDEBUG_NUKI_HEX_DATA
-DDEBUG_NUKI_READABLE_DATA

View File

@@ -15,8 +15,6 @@ Howto flash (Webflash)
-Click on "Next"
-Click on "Install"
NOTE: Webflash is not available for the ESP32-Solo1
Howto flash (Espressif Flash Download Tools)
--
@@ -52,13 +50,6 @@ e000 boot_app0.bin
10000 nuki_hub_esp32c6.bin
280000 nuki_hub_updater_esp32c6.bin
ESP32SOLO1
e000 boot_app0.bin
1000 bootloader.bin
8000 nuki_hub.partitions.bin
10000 nuki_hub_esp32solo1.bin
280000 nuki_hub_updater_esp32solo1.bin
Make sure the checkmarks for all files are enabled.
- Select the COM-Port the ESP device is connected to
@@ -87,8 +78,4 @@ esptool.py --chip esp32c3 --port /dev/ttyUSB0 --baud 921600 --before default_res
esptool.py --chip esp32c6 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq keep --flash_size detect 0xe000 boot_app0.bin 0x0 bootloader.bin 0x10000 nuki_hub_esp32c6.bin 0x280000 nuki_hub_updater_esp32c6.bin 0x8000 nuki_hub.partitions.bin
## ESP32SOLO1
esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq keep --flash_size detect 0xe000 boot_app0.bin 0x1000 bootloader.bin 0x10000 nuki_hub_esp32solo1.bin 0x280000 nuki_hub_updater_esp32solo1.bin 0x8000 nuki_hub.partitions.bin
Adjust the serial device and path to the binaries if necessary.

View File

@@ -7,7 +7,6 @@
#define NUKI_HUB_DATE "unknownbuilddate"
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
#define GITHUB_LATEST_RELEASE_API_URL (char*)"https://api.github.com/repos/technyon/nuki_hub/releases/latest"
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"
#if defined(CONFIG_IDF_TARGET_ESP32C3)
@@ -32,14 +31,6 @@
#define GITHUB_MASTER_RELEASE_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/master/nuki_hub_esp32c6.bin"
#define GITHUB_MASTER_UPDATER_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/master/nuki_hub_updater_esp32c6.bin"
#else
#if defined(FRAMEWORK_ARDUINO_SOLO1)
#define GITHUB_LATEST_RELEASE_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_esp32solo1.bin"
#define GITHUB_LATEST_UPDATER_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_updater_esp32solo1.bin"
#define GITHUB_BETA_RELEASE_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/beta/nuki_hub_esp32solo1.bin"
#define GITHUB_BETA_UPDATER_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/beta/nuki_hub_updater_esp32solo1.bin"
#define GITHUB_MASTER_RELEASE_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/master/nuki_hub_esp32solo1.bin"
#define GITHUB_MASTER_UPDATER_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/master/nuki_hub_updater_esp32solo1.bin"
#else
#define GITHUB_LATEST_RELEASE_BINARY_URL "https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_esp32.bin"
#define GITHUB_LATEST_UPDATER_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_updater_esp32.bin"
#define GITHUB_BETA_RELEASE_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/beta/nuki_hub_esp32.bin"
@@ -47,7 +38,6 @@
#define GITHUB_MASTER_RELEASE_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/master/nuki_hub_esp32.bin"
#define GITHUB_MASTER_UPDATER_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/master/nuki_hub_updater_esp32.bin"
#endif
#endif
#ifndef NUKI_HUB_UPDATER
#define MQTT_QOS_LEVEL 1

View File

@@ -5,6 +5,8 @@
#include "Logger.h"
#include "Config.h"
#include "RestartReason.h"
#include <HTTPClient.h>
#include <NetworkClientSecure.h>
#if defined(CONFIG_IDF_TARGET_ESP32)
#include "networkDevices/EthLan8720Device.h"
#endif
@@ -484,30 +486,38 @@ bool NukiNetwork::update()
{
_lastUpdateCheckTs = ts;
https.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
https.useHTTP10(true);
https.begin(GITHUB_OTA_MANIFEST_URL);
int httpResponseCode = https.GET();
if (httpResponseCode == HTTP_CODE_OK || httpResponseCode == HTTP_CODE_MOVED_PERMANENTLY)
{
JsonDocument doc;
DeserializationError jsonError = deserializeJson(doc, https.getStream());
if (!jsonError)
NetworkClientSecure *client = new NetworkClientSecure;
if (client) {
client->setDefaultCACertBundle();
{
_latestVersion = doc["release"]["version"];
publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion, true);
HTTPClient https;
https.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
https.useHTTP10(true);
if (_latestVersion != _preferences->getString(preference_latest_version).c_str())
{
_preferences->putString(preference_latest_version, _latestVersion);
}
if (https.begin(*client, GITHUB_OTA_MANIFEST_URL)) {
int httpResponseCode = https.GET();
if (httpResponseCode == HTTP_CODE_OK || httpResponseCode == HTTP_CODE_MOVED_PERMANENTLY)
{
JsonDocument doc;
DeserializationError jsonError = deserializeJson(doc, https.getStream());
if (!jsonError)
{
_latestVersion = doc["release"]["version"];
publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_latest, _latestVersion, true);
if (_latestVersion != _preferences->getString(preference_latest_version).c_str())
{
_preferences->putString(preference_latest_version, _latestVersion);
}
}
}
}
https.end();
}
delete client;
}
https.end();
}
}

View File

@@ -5,7 +5,6 @@
#include <map>
#include "networkDevices/NetworkDevice.h"
#include "networkDevices/IPConfiguration.h"
#include <HTTPClient.h>
#ifndef NUKI_HUB_UPDATER
#include "MqttReceiver.h"
@@ -112,7 +111,6 @@ private:
static NukiNetwork* _inst;
const char* _latestVersion;
HTTPClient https;
Preferences* _preferences;
IPConfiguration* _ipConfiguration = nullptr;

View File

@@ -71,10 +71,8 @@ void NukiNetworkLock::initialize()
if(_preferences->getBool(preference_update_from_mqtt, false))
{
#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0))
_network->subscribe(_mqttPath, mqtt_topic_update);
_network->initTopic(_mqttPath, mqtt_topic_update, "0");
#endif
}
_network->subscribe(_mqttPath, mqtt_topic_webserver_action);
@@ -195,7 +193,6 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
delay(200);
restartEsp(RestartReason::RequestedViaMqtt);
}
#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0))
else if(comparePrefixedPath(topic, mqtt_topic_update) && strcmp(value, "1") == 0 && _preferences->getBool(preference_update_from_mqtt, false))
{
Log->println(F("Update requested via MQTT."));
@@ -204,7 +201,6 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
delay(200);
restartEsp(RestartReason::OTAReboot);
}
#endif
else if(comparePrefixedPath(topic, mqtt_topic_webserver_action))
{
if(strcmp(value, "") == 0 ||

View File

@@ -10,6 +10,7 @@
#ifndef NUKI_HUB_UPDATER
#include <HTTPClient.h>
#include <NetworkClientSecure.h>
#include "ArduinoJson.h"
WebCfgServer::WebCfgServer(NukiWrapper* nuki, NukiOpenerWrapper* nukiOpener, NukiNetwork* network, Gpio* gpio, EthServer* ethServer, Preferences* preferences, bool allowRestartToPortal, uint8_t partitionType)
@@ -318,7 +319,6 @@ void WebCfgServer::initialize()
esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL));
restartEsp(RestartReason::OTAReboot);
});
#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0))
_server.on("/autoupdate", [&]() {
if (_hasCredentials && !_server.authenticate(_credUser, _credPassword)) {
return _server.requestAuthentication();
@@ -347,7 +347,6 @@ void WebCfgServer::initialize()
waitAndProcess(true, 1000);
restartEsp(RestartReason::OTAReboot);
});
#endif
_server.on("/uploadota", HTTP_POST, [&]() {
if (_hasCredentials && !_server.authenticate(_credUser, _credPassword)) {
return _server.requestAuthentication();
@@ -415,7 +414,6 @@ void WebCfgServer::buildOtaHtml(String &response, bool errored)
response.concat("<div id=\"msgdiv\" style=\"visibility:hidden\">Initiating Over-the-air update. This will take about two minutes, please be patient.<br>You will be forwarded automatically when the update is complete.</div>");
#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0))
response.concat("<div id=\"autoupdform\"><h4>Update Nuki Hub</h4>");
response.concat("Click on the button to reboot and automatically update Nuki Hub and the Nuki Hub updater to the latest versions from GitHub");
response.concat("<div style=\"clear: both\"></div>");
@@ -433,53 +431,58 @@ void WebCfgServer::buildOtaHtml(String &response, bool errored)
response.concat("<br>");
#ifndef NUKI_HUB_UPDATER
HTTPClient https;
https.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
https.setTimeout(2500);
https.useHTTP10(true);
https.begin(GITHUB_OTA_MANIFEST_URL);
int httpResponseCode = https.GET();
if (httpResponseCode == HTTP_CODE_OK || httpResponseCode == HTTP_CODE_MOVED_PERMANENTLY)
{
JsonDocument doc;
DeserializationError jsonError = deserializeJson(doc, https.getStream());
if (!jsonError)
NetworkClientSecure *client = new NetworkClientSecure;
if (client) {
client->setDefaultCACertBundle();
{
response.concat("<b>Latest release version: </b>");
response.concat(doc["release"]["fullversion"].as<const char*>());
response.concat(" (");
response.concat(doc["release"]["build"].as<const char*>());
response.concat("), ");
response.concat(doc["release"]["time"].as<const char*>());
response.concat("<br>");
response.concat("<b>Latest beta version: </b>");
response.concat(doc["beta"]["fullversion"].as<const char*>());
if(doc["beta"]["fullversion"] != "No beta available")
{
response.concat(" (");
response.concat(doc["beta"]["build"].as<const char*>());
response.concat("), ");
response.concat(doc["beta"]["time"].as<const char*>());
HTTPClient https;
https.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
https.setTimeout(2500);
https.useHTTP10(true);
if (https.begin(*client, GITHUB_OTA_MANIFEST_URL)) {
int httpResponseCode = https.GET();
if (httpResponseCode == HTTP_CODE_OK || httpResponseCode == HTTP_CODE_MOVED_PERMANENTLY)
{
JsonDocument doc;
DeserializationError jsonError = deserializeJson(doc, https.getStream());
if (!jsonError)
{
response.concat("<b>Latest release version: </b>");
response.concat(doc["release"]["fullversion"].as<const char*>());
response.concat(" (");
response.concat(doc["release"]["build"].as<const char*>());
response.concat("), ");
response.concat(doc["release"]["time"].as<const char*>());
response.concat("<br>");
response.concat("<b>Latest beta version: </b>");
response.concat(doc["beta"]["fullversion"].as<const char*>());
if(doc["beta"]["fullversion"] != "No beta available")
{
response.concat(" (");
response.concat(doc["beta"]["build"].as<const char*>());
response.concat("), ");
response.concat(doc["beta"]["time"].as<const char*>());
}
response.concat("<br>");
response.concat("<b>Latest development version: </b>");
response.concat(doc["master"]["fullversion"].as<const char*>());
response.concat(" (");
response.concat(doc["master"]["build"].as<const char*>());
response.concat("), ");
response.concat(doc["master"]["time"].as<const char*>());
response.concat("<br>");
}
}
https.end();
}
response.concat("<br>");
response.concat("<b>Latest development version: </b>");
response.concat(doc["master"]["fullversion"].as<const char*>());
response.concat(" (");
response.concat(doc["master"]["build"].as<const char*>());
response.concat("), ");
response.concat(doc["master"]["time"].as<const char*>());
response.concat("<br>");
}
delete client;
}
https.end();
#endif
response.concat("<br></div>");
#endif
if(_partitionType == 1)
{
@@ -612,16 +615,12 @@ void WebCfgServer::handleOtaUpload()
filename = "/" + filename;
}
_otaStartTs = esp_timer_get_time() / 1000;
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
esp_task_wdt_init(30, false);
#else
esp_task_wdt_config_t twdt_config = {
.timeout_ms = 30000,
.idle_core_mask = 0,
.trigger_panic = false,
};
esp_task_wdt_reconfigure(&twdt_config);
#endif
#ifndef NUKI_HUB_UPDATER
_network->disableAutoRestarts();
@@ -2539,7 +2538,7 @@ void WebCfgServer::buildNukiConfigHtml(String &response)
#endif
printInputField(response, "RSBC", "Restart if bluetooth beacons not received (seconds; -1 to disable)", _preferences->getInt(preference_restart_ble_beacon_lost), 10, "");
printInputField(response, "TXPWR", "BLE transmit power in dB (minimum -12, maximum 9)", _preferences->getInt(preference_ble_tx_power, 9), 10, "");
response.concat("</table>");
response.concat("<br><input type=\"submit\" name=\"submit\" value=\"Save\">");
response.concat("</form>");

View File

@@ -244,16 +244,13 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
case HTTP_EVENT_DISCONNECTED:
Log->println("HTTP_EVENT_DISCONNECTED");
break;
#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0))
case HTTP_EVENT_REDIRECT:
Log->println("HTTP_EVENT_REDIRECT");
break;
#endif
}
return ESP_OK;
}
#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0))
void otaTask(void *pvParameter)
{
uint8_t partitionType = checkPartition();
@@ -297,36 +294,21 @@ void otaTask(void *pvParameter)
esp_task_wdt_reset();
}
#endif
void setupTasks(bool ota)
{
// configMAX_PRIORITIES is 25
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
esp_task_wdt_init(300, true);
#else
esp_task_wdt_config_t twdt_config = {
.timeout_ms = 300000,
.idle_core_mask = 0,
.trigger_panic = true,
};
esp_task_wdt_reconfigure(&twdt_config);
#endif
if(ota)
{
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
xTaskCreatePinnedToCore(networkTask, "ntw", preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), NULL, 3, &networkTaskHandle, 1);
esp_task_wdt_add(networkTaskHandle);
#ifndef NUKI_HUB_UPDATER
xTaskCreatePinnedToCore(nukiTask, "nuki", preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), NULL, 2, &nukiTaskHandle, 1);
esp_task_wdt_add(nukiTaskHandle);
#endif
#else
xTaskCreatePinnedToCore(otaTask, "ota", 8192, NULL, 2, &otaTaskHandle, 1);
esp_task_wdt_add(otaTaskHandle);
#endif
}
else
{

View File

@@ -76,13 +76,11 @@ void EthLan8720Device::initialize()
WiFi.setHostname(_hostname.c_str());
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
_hardwareInitialized = ETH.begin(_phy_addr, _power, _mdc, _mdio, _type, _clock_mode, _use_mac_from_efuse);
#elif CONFIG_IDF_TARGET_ESP32
#if CONFIG_IDF_TARGET_ESP32
_hardwareInitialized = ETH.begin(_type, _phy_addr, _mdc, _mdio, _power, _clock_mode);
#else
#else
_hardwareInitialized = false;
#endif
#endif
ETH.setHostname(_hostname.c_str());
if(!_ipConfiguration->dhcpEnabled())

View File

@@ -1,33 +1,26 @@
#pragma once
#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0))
#ifndef CONFIG_IDF_TARGET_ESP32
typedef enum {
ETH_CLOCK_GPIO0_IN = 0,
ETH_CLOCK_GPIO16_OUT = 2,
ETH_CLOCK_GPIO17_OUT = 3
} eth_clock_mode_t;
#ifndef CONFIG_IDF_TARGET_ESP32
typedef enum {
ETH_CLOCK_GPIO0_IN = 0,
ETH_CLOCK_GPIO16_OUT = 2,
ETH_CLOCK_GPIO17_OUT = 3
} eth_clock_mode_t;
#define ETH_PHY_TYPE ETH_PHY_MAX
#else
#define ETH_PHY_TYPE ETH_PHY_LAN8720
#endif
#define ETH_PHY_TYPE ETH_PHY_MAX
#else
#define ETH_PHY_TYPE ETH_PHY_LAN8720
#endif
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
#define ETH_PHY_ADDR 0
#define ETH_PHY_MDC 23
#define ETH_PHY_MDIO 18
#define ETH_PHY_POWER -1
#define ETH_RESET_PIN 1
#endif
#include <WiFiClient.h>
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
#include <WiFiClientSecure.h>
#else
#include <NetworkClientSecure.h>
#endif
#include <Preferences.h>
#include "NetworkDevice.h"
#ifndef NUKI_HUB_UPDATER

View File

@@ -1,11 +1,7 @@
#pragma once
#include <WiFiClient.h>
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
#include <WiFiClientSecure.h>
#else
#include <NetworkClientSecure.h>
#endif
#include <Preferences.h>
#include "NetworkDevice.h"
#include "WiFiManager.h"

View File

@@ -8,8 +8,6 @@ from pathlib import Path
def get_board_name(env):
board = env.get('BOARD_MCU')
if env.get('BOARD') == 'esp32-solo1':
board = env.get('BOARD').replace('-', '')
return board
def create_target_dir(env):

View File

@@ -1,42 +0,0 @@
import re, shutil, os
from datetime import datetime, timezone
if not os.path.exists('src/networkDevices/'):
os.mkdir('src/networkDevices')
shutil.copy("../src/main.cpp", "src/main.cpp")
shutil.copy("../src/Config.h", "src/Config.h")
shutil.copy("../src/Logger.h", "src/Logger.h")
shutil.copy("../src/NukiNetwork.h", "src/NukiNetwork.h")
shutil.copy("../src/Ota.h", "src/Ota.h")
shutil.copy("../src/PreferencesKeys.h", "src/PreferencesKeys.h")
shutil.copy("../src/RestartReason.h", "src/RestartReason.h")
shutil.copy("../src/WebCfgServer.h", "src/WebCfgServer.h")
shutil.copy("../src/WebCfgServerConstants.h", "src/WebCfgServerConstants.h")
shutil.copy("../src/Logger.cpp", "src/Logger.cpp")
shutil.copy("../src/NukiNetwork.cpp", "src/NukiNetwork.cpp")
shutil.copy("../src/Ota.cpp", "src/Ota.cpp")
shutil.copy("../src/WebCfgServer.cpp", "src/WebCfgServer.cpp")
shutil.copy("../src/networkDevices/EthLan8720Device.h", "src/networkDevices/EthLan8720Device.h")
shutil.copy("../src/networkDevices/IPConfiguration.h", "src/networkDevices/IPConfiguration.h")
shutil.copy("../src/networkDevices/NetworkDevice.h", "src/networkDevices/NetworkDevice.h")
shutil.copy("../src/networkDevices/W5500Device.h", "src/networkDevices/W5500Device.h")
shutil.copy("../src/networkDevices/WifiDevice.h", "src/networkDevices/WifiDevice.h")
shutil.copy("../src/networkDevices/EthLan8720Device.cpp", "src/networkDevices/EthLan8720Device.cpp")
shutil.copy("../src/networkDevices/IPConfiguration.cpp", "src/networkDevices/IPConfiguration.cpp")
shutil.copy("../src/networkDevices/NetworkDevice.cpp", "src/networkDevices/NetworkDevice.cpp")
shutil.copy("../src/networkDevices/W5500Device.cpp", "src/networkDevices/W5500Device.cpp")
shutil.copy("../src/networkDevices/WifiDevice.cpp", "src/networkDevices/WifiDevice.cpp")
regex = r"\#define NUKI_HUB_DATE \"(.*)\""
content_new = ""
with open ('src/Config.h', 'r' ) as readfile:
file_content = readfile.read()
content_new = re.sub(regex, "#define NUKI_HUB_DATE \"" + datetime.now(timezone.utc).strftime("%Y-%m-%d") + "\"", file_content, flags = re.M)
with open('src/Config.h', 'w') as writefile:
writefile.write(content_new)

View File

@@ -63,23 +63,4 @@ board = nuki-esp32-s3
[env:updater_esp32-c6]
extends = env:updater_esp32dev
board = esp32-c6-devkitm-1
[env:updater_esp32solo1]
platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32-2023.10.03.zip
framework = arduino
board = esp32-solo1
extra_scripts =
pre:pio_package_pre_solo1.py
post:pio_package.py
build_flags =
${env.build_flags}
-DFRAMEWORK_ARDUINO_SOLO1
lib_deps =
AsyncTCP=symlink://../lib/AsyncTCP
Ethernet=symlink://../lib/Ethernet
HTTPClient=symlink://../lib/HTTPClient
WebServer=symlink://../lib/WebServer
WiFiManager=symlink://../lib/WiFiManager
lib_ignore =
NetworkClientSecure
board = esp32-c6-devkitm-1