Skip to content

Commit

Permalink
Properly support HTTPS/TLS
Browse files Browse the repository at this point in the history
  • Loading branch information
Johboh committed Dec 9, 2023
1 parent b87fea0 commit 414d839
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 22 deletions.
4 changes: 3 additions & 1 deletion examples/Node/Node.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <EspNowCrypt.h>
#include <EspNowNode.h>
#include <EspNowPreferences.h>
#include <esp_crt_bundle.h>

#define SLEEP_TIME_US (1000LL * 1000LL * 60LL * 1LL) // 1 minute

Expand Down Expand Up @@ -66,7 +67,8 @@ EspNowNode::OnLog _on_log = [](const std::string message, const esp_log_level_t

EspNowPreferences _esp_now_preferences;
EspNowCrypt _esp_now_crypt(esp_now_encryption_key, esp_now_encryption_secret);
EspNowNode _esp_now_node(_esp_now_crypt, _esp_now_preferences, FIRMWARE_VERSION, _on_log);
EspNowNode _esp_now_node(_esp_now_crypt, _esp_now_preferences, FIRMWARE_VERSION, _on_log,
arduino_esp_crt_bundle_attach);

void setup() {
Serial.begin(115200);
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{
"name": "Johan Böhlin"
},
"version": "0.3.2",
"version": "0.3.3",
"license": "MIT",
"repository":
{
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=EspNowNetwork
version=0.3.2
version=0.3.3
author=Johan Böhlin <[email protected]>
maintainer=Johan Böhlin <[email protected]>
sentence=Arduino/ESP-IDF library for setting up a network of ESP NOW nodes
Expand Down
18 changes: 17 additions & 1 deletion src/EspNowNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define __ESP_NOW_NODE_H__

#include "Preferences.h"
#include "impl/EspNowOta.h"
#include <EspNowCrypt.h>
#include <esp_log.h>
#include <esp_netif.h>
Expand Down Expand Up @@ -37,15 +38,29 @@ class EspNowNode {
*/
typedef std::function<void(const std::string message, const esp_log_level_t log_level)> OnLog;

/**
* @brief CRT Bundle Attach for Ardunio or ESP-IDF from MDTLS, to support TLS/HTTPS firmware URIs.
*
* Include esp_crt_bundle.h and pass the following when using respective framework:
* for Arduino: arduino_esp_crt_bundle_attach
* for ESP-IDF: esp_crt_bundle_attach
*
* C style function.
*/
typedef EspNowOta::CrtBundleAttach CrtBundleAttach;

/**
* @brief Construct a new EspNowNode.
*
* @param crypt the EspNowCrypt to use for encrypting/decrypting messages.
* @param preferences the EspNowNetwork::Preferences to use for storing/reading preferences.
* @param firmware_version the (incremental) firmware version that this node is currently running.
* @param on_log callback when the host want to log something.
* @param crt_bundle_attach crt_bundle_attach for either Ardunio (arduino_esp_crt_bundle_attach) or ESP-IDF
* (esp_crt_bundle_attach).
*/
EspNowNode(EspNowCrypt &crypt, EspNowNetwork::Preferences &preferences, uint32_t firmware_version, OnLog on_log = {});
EspNowNode(EspNowCrypt &crypt, EspNowNetwork::Preferences &preferences, uint32_t firmware_version, OnLog on_log = {},
CrtBundleAttach crt_bundle_attach = nullptr);

public:
/**
Expand Down Expand Up @@ -119,6 +134,7 @@ class EspNowNode {
uint32_t _firmware_version;
bool _setup_successful = false;
uint8_t _esp_now_host_address[6];
CrtBundleAttach _crt_bundle_attach;
EspNowNetwork::Preferences &_preferences;
};

Expand Down
8 changes: 5 additions & 3 deletions src/impl/EspNowNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ void esp_now_on_data_callback(const esp_now_recv_info_t *esp_now_info, const uin
#endif

EspNowNode::EspNowNode(EspNowCrypt &crypt, EspNowNetwork::Preferences &preferences, uint32_t firmware_version,
OnLog on_log)
: _on_log(on_log), _crypt(crypt), _firmware_version(firmware_version), _preferences(preferences) {}
OnLog on_log, CrtBundleAttach crt_bundle_attach)
: _on_log(on_log), _crypt(crypt), _firmware_version(firmware_version), _crt_bundle_attach(crt_bundle_attach),
_preferences(preferences) {}

bool EspNowNode::setup() {
if (_setup_successful) {
Expand Down Expand Up @@ -378,7 +379,8 @@ void EspNowNode::handleFirmwareUpdate(char *wifi_ssid, char *wifi_password, char

// Connect to wifi.
EspNowOta _esp_now_ota(
[&](const std::string message, const esp_log_level_t log_level) { log("EspNowOta: " + message, log_level); });
[&](const std::string message, const esp_log_level_t log_level) { log("EspNowOta: " + message, log_level); },
_crt_bundle_attach);

uint16_t retries = 2;
unsigned long connect_timeout_ms = 15000;
Expand Down
27 changes: 14 additions & 13 deletions src/impl/EspNowOta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include "EspNowMD5Builder.h"
#include <esp_app_format.h>
#include <esp_crt_bundle.h>
#include <esp_flash_partitions.h>
#include <esp_log.h>
#include <esp_mac.h>
Expand Down Expand Up @@ -31,7 +30,10 @@
#define SPI_SECTORS_PER_BLOCK 16 // usually large erase block is 32k/64k
#define SPI_FLASH_BLOCK_SIZE (SPI_SECTORS_PER_BLOCK * SPI_FLASH_SEC_SIZE)

EspNowOta::EspNowOta(OnLog on_log) : _on_log(on_log) { _wifi_event_group = xEventGroupCreate(); }
EspNowOta::EspNowOta(OnLog on_log, CrtBundleAttach crt_bundle_attach)
: _on_log(on_log), _crt_bundle_attach(crt_bundle_attach) {
_wifi_event_group = xEventGroupCreate();
}

void EspNowOta::wifiEventHandler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
EspNowOta *wrapper = (EspNowOta *)arg;
Expand Down Expand Up @@ -108,22 +110,22 @@ bool EspNowOta::connectToWiFi(const char *ssid, const char *password, unsigned l
return false;
}

bool EspNowOta::updateFrom(std::string &url, std::string md5hash) {
bool EspNowOta::updateFrom(std::string &url, std::string md5_hash) {
auto *partition = esp_ota_get_next_update_partition(NULL);
if (!partition) {
log("Unable to find OTA partition", ESP_LOG_ERROR);
return false;
}
log("Found partition " + std::string(partition->label), ESP_LOG_INFO);

if (!md5hash.empty() && md5hash.length() != 32) {
if (!md5_hash.empty() && md5_hash.length() != 32) {
log("MD5 is not correct length. Leave empty for no MD5 checksum verification. Expected length: 32, got " +
std::to_string(md5hash.length()),
std::to_string(md5_hash.length()),
ESP_LOG_ERROR);
return false;
}

return downloadAndWriteToPartition(partition, url, md5hash);
return downloadAndWriteToPartition(partition, url, md5_hash);
}

esp_err_t EspNowOta::httpEventHandler(esp_http_client_event_t *evt) {
Expand Down Expand Up @@ -172,13 +174,12 @@ bool EspNowOta::downloadAndWriteToPartition(const esp_partition_t *partition, st
config.user_data = this;
config.event_handler = httpEventHandler;
config.buffer_size = SPI_FLASH_SEC_SIZE;
/*#if PIOFRAMEWORK == "arduino"
config.crt_bundle_attach = arduino_esp_crt_bundle_attach;
#elif PIOFRAMEWORK == "espidf"
config.crt_bundle_attach = esp_crt_bundle_attach;
#else
#error "PIOFRAMEWORK is either not defined in platformio.ini or framework is not supported."
#endif*/
if (_crt_bundle_attach) {
config.crt_bundle_attach = _crt_bundle_attach;
log("With TLS/HTTPS support", ESP_LOG_INFO);
} else {
log("Without TLS/HTTPS support", ESP_LOG_INFO);
}
esp_http_client_handle_t client = esp_http_client_init(&config);

log("Using URL " + url, ESP_LOG_INFO);
Expand Down
19 changes: 17 additions & 2 deletions src/impl/EspNowOta.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,18 @@ class EspNowOta {
*/
typedef std::function<void(const std::string message, const esp_log_level_t log_level)> OnLog;

EspNowOta(OnLog on_log = {});
/**
* @brief CRT Bundle Attach for Ardunio or ESP-IDF from MDTLS, to support TLS/HTTPS firmware URIs.
*
* Include esp_crt_bundle.h and pass the following when using respective framework:
* for Arduino: arduino_esp_crt_bundle_attach
* for ESP-IDF: esp_crt_bundle_attach
*
* C style function.
*/
typedef esp_err_t (*CrtBundleAttach)(void *conf);

EspNowOta(OnLog on_log = {}, CrtBundleAttach crt_bundle_attach = nullptr);

/**
* @brief Connect to wifi.
Expand All @@ -37,8 +48,11 @@ class EspNowOta {
/**
* @brief Try to update firmware from the given URL.
* WiFi needs to be established first.
*
* @param url url to update from.
* @param md5_hash 32 string character MD5 hash to validate written firmware against. Empty to not validate.
*/
bool updateFrom(std::string &url, std::string md5hash = "");
bool updateFrom(std::string &url, std::string md5_hash = "");

private:
int fillBuffer(esp_http_client_handle_t client, char *buffer, size_t buffer_size);
Expand All @@ -62,6 +76,7 @@ class EspNowOta {
esp_ip4_addr_t _ip_addr;
uint16_t _wifi_num_retries = 0;
uint16_t _wifi_retry_number = 0;
CrtBundleAttach _crt_bundle_attach;
EventGroupHandle_t _wifi_event_group;

private:
Expand Down

0 comments on commit 414d839

Please sign in to comment.