summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/screen/screen.c7
-rw-r--r--components/sntp/CMakeLists.txt3
-rw-r--r--components/sntp/time_sntp.c36
-rw-r--r--components/sntp/time_sntp.h18
-rw-r--r--components/wifi/CMakeLists.txt4
-rw-r--r--components/wifi/dpp_wifi.c214
-rw-r--r--components/wifi/dpp_wifi.h47
-rw-r--r--components/wifi/idf_component.yml2
8 files changed, 329 insertions, 2 deletions
diff --git a/components/screen/screen.c b/components/screen/screen.c
index c6de3c7..45f89f7 100644
--- a/components/screen/screen.c
+++ b/components/screen/screen.c
@@ -179,7 +179,10 @@ void test_screen(struct Screen* screen)
void display(struct Screen* screen, char digits[4])
{
for (uint8_t i = 0; i < 4; ++i) {
- screen->nixies[i].digit = digits[i] - '0';
- set_digit(screen->mcp, &(screen->nixies[i])); // Call set_digit function
+ uint8_t digit = digits[i] - '0';
+ if (screen->nixies[i].digit != digit){
+ screen->nixies[i].digit = digit;
+ set_digit(screen->mcp, &(screen->nixies[i])); // Call set_digit function
+ }
}
} \ No newline at end of file
diff --git a/components/sntp/CMakeLists.txt b/components/sntp/CMakeLists.txt
new file mode 100644
index 0000000..fc734f5
--- /dev/null
+++ b/components/sntp/CMakeLists.txt
@@ -0,0 +1,3 @@
+idf_component_register(SRCS "time_sntp.c"
+ INCLUDE_DIRS "."
+ PRIV_REQUIRES esp_system esp_netif esp_event)
diff --git a/components/sntp/time_sntp.c b/components/sntp/time_sntp.c
new file mode 100644
index 0000000..90cc1d1
--- /dev/null
+++ b/components/sntp/time_sntp.c
@@ -0,0 +1,36 @@
+#include "time_sntp.h"
+
+void set_tz(char* tz){
+ setenv("TZ", tz, 1); // Zürich tz
+ tzset();
+}
+
+void obtain_time(char t[4])
+{
+ time_t now;
+ struct tm timeinfo;
+ time(&now); // Get the current time
+ localtime_r(&now, &timeinfo);
+ strftime(t, sizeof(t)+sizeof(char), "%H%M", &timeinfo); // Seems to require +1 char size to do it correctly
+ ESP_LOGI(SNTP_TAG, "The local time is: %s", t);
+}
+
+void sync_time(void)
+{
+ ESP_ERROR_CHECK(esp_netif_init());
+
+ ESP_LOGI(SNTP_TAG, "Initializing and starting SNTP");
+ /*
+ * This is the basic default config with one server and starting the service
+ */
+ esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG(CONFIG_SNTP_TIME_SERVER);
+
+ esp_netif_sntp_init(&config);
+ // wait for time to be set
+ int retry = 0;
+ const int retry_count = 15;
+ while (esp_netif_sntp_sync_wait(2000 / portTICK_PERIOD_MS) == ESP_ERR_TIMEOUT && ++retry < retry_count) {
+ ESP_LOGI(SNTP_TAG, "Waiting for system time to be synched... (%d/%d)", retry, retry_count);
+ }
+ esp_netif_sntp_deinit();
+}
diff --git a/components/sntp/time_sntp.h b/components/sntp/time_sntp.h
new file mode 100644
index 0000000..a8a894e
--- /dev/null
+++ b/components/sntp/time_sntp.h
@@ -0,0 +1,18 @@
+#ifndef SNTP_H
+#define SNTP_H
+
+#include <time.h>
+#include <sys/time.h>
+#include "esp_system.h"
+#include "esp_event.h"
+#include "esp_log.h"
+#include "esp_netif.h"
+#include "esp_netif_sntp.h"
+#include "esp_sntp.h"
+
+static const char *SNTP_TAG = "SNTP";
+
+void set_tz(char* tz);
+void obtain_time(char t[4]);
+void sync_time(void);
+#endif \ No newline at end of file
diff --git a/components/wifi/CMakeLists.txt b/components/wifi/CMakeLists.txt
new file mode 100644
index 0000000..97a03bb
--- /dev/null
+++ b/components/wifi/CMakeLists.txt
@@ -0,0 +1,4 @@
+idf_component_register(SRCS "dpp_wifi.c"
+ INCLUDE_DIRS "."
+ PRIV_REQUIRES esp_system esp_wifi esp_event wpa_supplicant log nvs_flash)
+ \ No newline at end of file
diff --git a/components/wifi/dpp_wifi.c b/components/wifi/dpp_wifi.c
new file mode 100644
index 0000000..495361c
--- /dev/null
+++ b/components/wifi/dpp_wifi.c
@@ -0,0 +1,214 @@
+#include "dpp_wifi.h"
+
+static void event_handler(void *arg, esp_event_base_t event_base,
+ int32_t event_id, void *event_data)
+{
+ if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
+ ESP_ERROR_CHECK(esp_supp_dpp_start_listen());
+ ESP_LOGI(WIFI_TAG, "Started listening for DPP Authentication");
+ } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
+ if (s_retry_num < WIFI_MAX_RETRY_NUM) {
+ esp_wifi_connect();
+ s_retry_num++;
+ ESP_LOGI(WIFI_TAG, "retry to connect to the AP");
+ } else {
+ xEventGroupSetBits(s_dpp_event_group, DPP_CONNECT_FAIL_BIT);
+ }
+ ESP_LOGI(WIFI_TAG, "connect to the AP fail");
+ } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
+ ESP_LOGI(WIFI_TAG, "Successfully connected to the AP ssid : %s ", s_dpp_wifi_configuration.sta.ssid);
+ } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
+ ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
+ ESP_LOGI(WIFI_TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
+ s_retry_num = 0;
+ xEventGroupSetBits(s_dpp_event_group, DPP_CONNECTED_BIT);
+ }
+}
+
+void dpp_enrollee_event_cb(esp_supp_dpp_event_t event, void *data)
+{
+ switch (event) {
+ case ESP_SUPP_DPP_URI_READY:
+ if (data != NULL) {
+ esp_qrcode_config_t cfg = ESP_QRCODE_CONFIG_DEFAULT();
+
+ ESP_LOGI(WIFI_TAG, "Scan below QR Code to configure the enrollee:");
+ esp_qrcode_generate(&cfg, (const char *)data);
+ }
+ break;
+ case ESP_SUPP_DPP_CFG_RECVD:
+ memcpy(&s_dpp_wifi_configuration, data, sizeof(s_dpp_wifi_configuration));
+ s_retry_num = 0;
+ esp_wifi_set_config(ESP_IF_WIFI_STA, &s_dpp_wifi_configuration);
+ esp_wifi_connect();
+ break;
+ case ESP_SUPP_DPP_FAIL:
+ if (s_retry_num < 5) {
+ ESP_LOGI(WIFI_TAG, "DPP Auth failed (Reason: %s), retry...", esp_err_to_name((int)data));
+ ESP_ERROR_CHECK(esp_supp_dpp_start_listen());
+ s_retry_num++;
+ } else {
+ xEventGroupSetBits(s_dpp_event_group, DPP_AUTH_FAIL_BIT);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+esp_err_t dpp_enrollee_bootstrap(void)
+{
+ esp_err_t ret;
+ size_t pkey_len = strlen(EXAMPLE_DPP_BOOTSTRAPPING_KEY);
+ char *key = NULL;
+
+ if (pkey_len) {
+ /* Currently only NIST P-256 curve is supported, add prefix/postfix accordingly */
+ char prefix[] = "30310201010420";
+ char postfix[] = "a00a06082a8648ce3d030107";
+
+ if (pkey_len != CURVE_SEC256R1_PKEY_HEX_DIGITS) {
+ ESP_LOGI(WIFI_TAG, "Invalid key length! Private key needs to be 32 bytes (or 64 hex digits) long");
+ return ESP_FAIL;
+ }
+
+ key = malloc(sizeof(prefix) + pkey_len + sizeof(postfix));
+ if (!key) {
+ ESP_LOGI(WIFI_TAG, "Failed to allocate for bootstrapping key");
+ return ESP_ERR_NO_MEM;
+ }
+ sprintf(key, "%s%s%s", prefix, EXAMPLE_DPP_BOOTSTRAPPING_KEY, postfix);
+ }
+
+ /* Currently only supported method is QR Code */
+ ret = esp_supp_dpp_bootstrap_gen(EXAMPLE_DPP_LISTEN_CHANNEL_LIST, DPP_BOOTSTRAP_QR_CODE,
+ key, EXAMPLE_DPP_DEVICE_INFO);
+
+ if (key)
+ free(key);
+
+ return ret;
+}
+
+void save_wifi_configuration(const uint8_t *ssid, const uint8_t *psk) {
+ nvs_handle_t handle;
+ ESP_ERROR_CHECK(nvs_open("wifi_creds", NVS_READWRITE, &handle));
+
+ // Save SSID
+ ESP_ERROR_CHECK(nvs_set_str(handle, "ssid", (const char *)ssid));
+
+ // Save PSK
+ ESP_ERROR_CHECK(nvs_set_str(handle, "psk", (const char *)psk));
+
+ // Commit the changes
+ ESP_ERROR_CHECK(nvs_commit(handle));
+
+ // Close the handle
+ nvs_close(handle);
+}
+
+bool load_wifi_configuration() {
+ nvs_handle_t handle;
+ esp_err_t err = nvs_open("wifi_creds", NVS_READONLY, &handle);
+ if (err != ESP_OK) {
+ // Handle error opening NVS
+ return false; // Indicates failure to load credentials
+ }
+
+ // Initialize ssid and psk fields in the struct
+ memset(&s_dpp_wifi_configuration, 0, sizeof(s_dpp_wifi_configuration));
+
+ // Read SSID
+ size_t ssid_size = sizeof(s_dpp_wifi_configuration.sta.ssid);
+ if (nvs_get_str(handle, "ssid", (char *)s_dpp_wifi_configuration.sta.ssid, &ssid_size) != ESP_OK || strlen((char *)s_dpp_wifi_configuration.sta.ssid) == 0) {
+ nvs_close(handle);
+ return false; // Indicates no valid SSID stored
+ }
+
+ // Read PSK
+ size_t psk_size = sizeof(s_dpp_wifi_configuration.sta.password);
+ if (nvs_get_str(handle, "psk", (char *)s_dpp_wifi_configuration.sta.password, &psk_size) != ESP_OK || strlen((char *)s_dpp_wifi_configuration.sta.password) == 0) {
+ nvs_close(handle);
+ return false; // Indicates no valid PSK stored
+ }
+
+ // Close the handle
+ nvs_close(handle);
+ return true; // Indicates valid credentials loaded
+}
+
+void dpp_enrollee_init(void)
+{
+ s_dpp_event_group = xEventGroupCreate();
+
+ ESP_ERROR_CHECK(esp_netif_init());
+
+ ESP_ERROR_CHECK(esp_event_loop_create_default());
+ esp_netif_create_default_wifi_sta();
+
+ ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
+ ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
+
+ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+ ESP_ERROR_CHECK(esp_wifi_init(&cfg));
+
+ ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
+ ESP_ERROR_CHECK(esp_supp_dpp_init(dpp_enrollee_event_cb));
+ ESP_ERROR_CHECK(dpp_enrollee_bootstrap());
+ ESP_ERROR_CHECK(esp_wifi_start());
+
+ /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
+ * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
+ EventBits_t bits = xEventGroupWaitBits(s_dpp_event_group,
+ DPP_CONNECTED_BIT | DPP_CONNECT_FAIL_BIT | DPP_AUTH_FAIL_BIT,
+ pdFALSE,
+ pdFALSE,
+ portMAX_DELAY);
+
+ /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
+ * happened. */
+ if (bits & DPP_CONNECTED_BIT) {
+ ESP_LOGI(WIFI_TAG, "connected to ap SSID:%s",
+ s_dpp_wifi_configuration.sta.ssid);
+ save_wifi_configuration(s_dpp_wifi_configuration.sta.ssid, s_dpp_wifi_configuration.sta.password);
+ } else if (bits & DPP_CONNECT_FAIL_BIT) {
+ ESP_LOGI(WIFI_TAG, "Failed to connect to SSID:%s",
+ s_dpp_wifi_configuration.sta.ssid);
+ } else if (bits & DPP_AUTH_FAIL_BIT) {
+ ESP_LOGI(WIFI_TAG, "DPP Authentication failed after %d retries", s_retry_num);
+ } else {
+ ESP_LOGE(WIFI_TAG, "UNEXPECTED EVENT");
+ }
+
+ esp_supp_dpp_deinit();
+ ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler));
+ //ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler));
+ vEventGroupDelete(s_dpp_event_group);
+}
+
+void launch_dpp(void)
+{
+ if (load_wifi_configuration()) {
+ ESP_ERROR_CHECK(esp_netif_init());
+ ESP_ERROR_CHECK(esp_event_loop_create_default());
+ esp_netif_create_default_wifi_sta();
+ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+ ESP_ERROR_CHECK(esp_wifi_init(&cfg));
+ ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
+ ESP_ERROR_CHECK(esp_wifi_start());
+ // Use the configuration to connect to Wi-Fi
+ ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
+ esp_wifi_set_config(ESP_IF_WIFI_STA, &s_dpp_wifi_configuration);
+ if(esp_wifi_connect() != ESP_OK) // Connect to the network
+ {
+ ESP_LOGI(WIFI_TAG, "No valid Wi-Fi credentials stored.");
+ ESP_LOGI(WIFI_TAG, "Initiating dpp...");
+ dpp_enrollee_init();
+ }
+ } else {
+ // No valid Wi-Fi credentials found
+ ESP_LOGI(WIFI_TAG, "No valid Wi-Fi credentials stored.");
+ ESP_LOGI(WIFI_TAG, "Initiating dpp...");
+ dpp_enrollee_init();
+ }
+}
diff --git a/components/wifi/dpp_wifi.h b/components/wifi/dpp_wifi.h
new file mode 100644
index 0000000..e8a2519
--- /dev/null
+++ b/components/wifi/dpp_wifi.h
@@ -0,0 +1,47 @@
+#ifndef DPP_H
+#define DPP_H
+
+#include <string.h>
+#include "esp_system.h"
+#include "esp_wifi.h"
+#include "esp_event.h"
+#include "esp_dpp.h"
+#include "esp_log.h"
+#include "nvs_flash.h"
+#include "qrcode.h"
+
+#ifdef CONFIG_ESP_DPP_LISTEN_CHANNEL_LIST
+#define EXAMPLE_DPP_LISTEN_CHANNEL_LIST CONFIG_ESP_DPP_LISTEN_CHANNEL_LIST
+#else
+#define EXAMPLE_DPP_LISTEN_CHANNEL_LIST "6"
+#endif
+
+#ifdef CONFIG_ESP_DPP_BOOTSTRAPPING_KEY
+#define EXAMPLE_DPP_BOOTSTRAPPING_KEY CONFIG_ESP_DPP_BOOTSTRAPPING_KEY
+#else
+#define EXAMPLE_DPP_BOOTSTRAPPING_KEY 0
+#endif
+
+#ifdef CONFIG_ESP_DPP_DEVICE_INFO
+#define EXAMPLE_DPP_DEVICE_INFO CONFIG_ESP_DPP_DEVICE_INFO
+#else
+#define EXAMPLE_DPP_DEVICE_INFO 0
+#endif
+
+#define CURVE_SEC256R1_PKEY_HEX_DIGITS 64
+
+static const char *WIFI_TAG = "wifi dpp-enrollee";
+
+static wifi_config_t s_dpp_wifi_configuration;
+static int s_retry_num = 0;
+
+/* FreeRTOS event group to signal when we are connected*/
+static EventGroupHandle_t s_dpp_event_group;
+
+#define DPP_CONNECTED_BIT BIT0
+#define DPP_CONNECT_FAIL_BIT BIT1
+#define DPP_AUTH_FAIL_BIT BIT2
+#define WIFI_MAX_RETRY_NUM 3
+
+void launch_dpp(void);
+#endif \ No newline at end of file
diff --git a/components/wifi/idf_component.yml b/components/wifi/idf_component.yml
new file mode 100644
index 0000000..15aa094
--- /dev/null
+++ b/components/wifi/idf_component.yml
@@ -0,0 +1,2 @@
+dependencies:
+ qrcode: "^0.1.0"