From 900b436856bdfe88a998baa65d2eb4bef77d7f35 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Sat, 27 Jul 2024 15:31:17 +0200 Subject: [PATCH] Generate device name --- esp32_device/.vscode/settings.json | 9 ++++- esp32_device/main/CMakeLists.txt | 3 +- esp32_device/main/constants.h | 6 ++++ esp32_device/main/dev_name.c | 40 ++++++++++++++++++++++ esp32_device/main/dev_name.h | 33 ++++++++++++++++++ esp32_device/main/main.c | 22 +++++++++++- esp32_device/main/random.c | 31 +++++++++++++++++ esp32_device/main/random.h | 21 ++++++++++++ esp32_device/main/storage.c | 55 ++++++++++++++++++++++++++++++ esp32_device/main/storage.h | 32 +++++++++++++++++ 10 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 esp32_device/main/constants.h create mode 100644 esp32_device/main/dev_name.c create mode 100644 esp32_device/main/dev_name.h create mode 100644 esp32_device/main/random.c create mode 100644 esp32_device/main/random.h create mode 100644 esp32_device/main/storage.c create mode 100644 esp32_device/main/storage.h diff --git a/esp32_device/.vscode/settings.json b/esp32_device/.vscode/settings.json index b169c6b..4691b44 100644 --- a/esp32_device/.vscode/settings.json +++ b/esp32_device/.vscode/settings.json @@ -6,5 +6,12 @@ "idf.openOcdConfigs": [ "interface/ftdi/esp32_devkitj_v1.cfg", "target/esp32.cfg" - ] + ], + "files.associations": { + "dev_name.h": "c", + "stdio.h": "c", + "storage.h": "c", + "cstdlib": "c", + "cstring": "c" + } } diff --git a/esp32_device/main/CMakeLists.txt b/esp32_device/main/CMakeLists.txt index cf2c455..6936930 100755 --- a/esp32_device/main/CMakeLists.txt +++ b/esp32_device/main/CMakeLists.txt @@ -1,2 +1,3 @@ -idf_component_register(SRCS "main.c" +idf_component_register(SRCS "random.c" "storage.c" "main.c" + "dev_name.c" INCLUDE_DIRS ".") diff --git a/esp32_device/main/constants.h b/esp32_device/main/constants.h new file mode 100644 index 0000000..dcbfeee --- /dev/null +++ b/esp32_device/main/constants.h @@ -0,0 +1,6 @@ +#pragma once + +/** + * Device name len + */ +#define DEV_NAME_LEN 10 \ No newline at end of file diff --git a/esp32_device/main/dev_name.c b/esp32_device/main/dev_name.c new file mode 100644 index 0000000..b341b86 --- /dev/null +++ b/esp32_device/main/dev_name.c @@ -0,0 +1,40 @@ +#include "stddef.h" +#include "dev_name.h" +#include "storage.h" +#include "stdio.h" +#include "random.h" +#include "constants.h" +#include "string.h" + +#define DEV_PREFIX "ESP32 " + +bool dev_generate_name_if_required() +{ + // Check if a device name has already been defined + if (storage_get_dev_name(NULL) > 0) + return false; + + // Generate random device name + char name[DEV_NAME_LEN]; + rand_str(DEV_NAME_LEN - 1, name); + storage_set_dev_name(name); + + return true; +} + +char *dev_name() +{ + size_t len = storage_get_dev_name(NULL); + + char *dev = malloc(len + strlen(DEV_PREFIX) + 1); + if (dev == NULL) + { + printf("Failed to allocate memory to store dev name!\n"); + return NULL; + } + + strcpy(dev, DEV_PREFIX); + storage_get_dev_name(dev + strlen(DEV_PREFIX)); + + return dev; +} \ No newline at end of file diff --git a/esp32_device/main/dev_name.h b/esp32_device/main/dev_name.h new file mode 100644 index 0000000..0fb9b54 --- /dev/null +++ b/esp32_device/main/dev_name.h @@ -0,0 +1,33 @@ +/** + * Device name management + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * Generate random device name, if not existent + */ + bool dev_generate_name_if_required(); + + /** + * Clear device name + */ + void dev_remove_name(); + + /** + * Get current device name. This value MUST be freed after usage + * + * @return NULL if no name was already defined. + */ + char *dev_name(); + +#ifdef __cplusplus +} +#endif diff --git a/esp32_device/main/main.c b/esp32_device/main/main.c index 02017d3..5b01812 100755 --- a/esp32_device/main/main.c +++ b/esp32_device/main/main.c @@ -1,9 +1,29 @@ #include #include "esp_system.h" +#include "dev_name.h" +#include "storage.h" + void app_main(void) { - printf("\n\n\nhello world and bye\n\n\n"); + printf("\n"); + + if (storage_init() == false) + { + printf("Failed to init storage!\n"); + fflush(stdout); + esp_restart(); + } + + if (dev_generate_name_if_required()) + { + printf("Generated a new device name\n"); + } + + char *name = dev_name(); + printf("Dev name: %s\n", name); + free(name); + fflush(stdout); esp_restart(); } diff --git a/esp32_device/main/random.c b/esp32_device/main/random.c new file mode 100644 index 0000000..e775821 --- /dev/null +++ b/esp32_device/main/random.c @@ -0,0 +1,31 @@ +#include "random.h" +#include "esp_random.h" + +void rand_str(size_t len, char *dest) +{ + for (size_t i = 0; i < len; i++) + { + uint32_t v = esp_random() % (26 * 2 + 10); + + // Upper case letter + if (v < 26) + { + dest[i] = 65 + v; + continue; + } + v -= 26; + + // Lower case letter + if (v < 26) + { + dest[i] = 97 + v; + continue; + } + v -= 26; + + // Digit + dest[i] = 48 + (v % 10); + } + + dest[len] = '\0'; +} \ No newline at end of file diff --git a/esp32_device/main/random.h b/esp32_device/main/random.h new file mode 100644 index 0000000..6011e21 --- /dev/null +++ b/esp32_device/main/random.h @@ -0,0 +1,21 @@ +/** + * Random utilities + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * Generate random string of given size + */ + void rand_str(size_t len, char *dest); + +#ifdef __cplusplus +} +#endif diff --git a/esp32_device/main/storage.c b/esp32_device/main/storage.c new file mode 100644 index 0000000..1fdb4f3 --- /dev/null +++ b/esp32_device/main/storage.c @@ -0,0 +1,55 @@ +#include "constants.h" +#include "storage.h" +#include "nvs_flash.h" +#include "nvs.h" +#include + +#define STORAGE_NAMESPACE "storage" + +#define DEV_NAME_KEY "dev_name" + +bool storage_init() +{ + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) + { + printf("Need to reset storage\n"); + + // NVS partition was truncated and needs to be erased + // Retry nvs_flash_init + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + + return err == ESP_OK; +} + +void storage_set_dev_name(const char *name) +{ + nvs_handle_t my_handle; + + ESP_ERROR_CHECK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle)); + + ESP_ERROR_CHECK(nvs_set_blob(my_handle, DEV_NAME_KEY, name, strlen(name))); + + nvs_close(my_handle); +} + +size_t storage_get_dev_name(char *dest) +{ + nvs_handle_t my_handle; + + ESP_ERROR_CHECK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle)); + + size_t len = (dest == NULL ? 0 : DEV_NAME_LEN); + esp_err_t res = nvs_get_blob(my_handle, DEV_NAME_KEY, dest, &len); + + nvs_close(my_handle); + + if (res == ESP_ERR_NVS_NOT_FOUND || len == 0) + return 0; + + ESP_ERROR_CHECK(res); + + return len; +} \ No newline at end of file diff --git a/esp32_device/main/storage.h b/esp32_device/main/storage.h new file mode 100644 index 0000000..5df1487 --- /dev/null +++ b/esp32_device/main/storage.h @@ -0,0 +1,32 @@ +/** + * Storage management + */ + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * Initialize storage + */ + bool storage_init(); + + /** + * Write device name + */ + void storage_set_dev_name(const char *name); + + /** + * Get current device name + */ + size_t storage_get_dev_name(char *dest); + +#ifdef __cplusplus +} +#endif