diff --git a/include/libwebsockets.h b/include/libwebsockets.h index ac8e22fc4..4d60592ab 100644 --- a/include/libwebsockets.h +++ b/include/libwebsockets.h @@ -621,6 +621,7 @@ struct lws; #include #include #include +#include #ifdef __cplusplus } diff --git a/include/libwebsockets/lws-settings.h b/include/libwebsockets/lws-settings.h new file mode 100644 index 000000000..541c8c6d3 --- /dev/null +++ b/include/libwebsockets/lws-settings.h @@ -0,0 +1,72 @@ +/* + * Generic Settings storage + * + * Copyright (C) 2020 Andy Green + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * + * This is like an abstract class for non-volatile storage, whether in a file- + * system or flash-backed blocks, etc. Named blobs of variable size are stored + * in nonvolatile media of some sort. Typically, these are JSON objects under + * a naming scheme like, eg, "network". + * + * There's a platform-specific storage identifier opaque_plat provided when the + * storage object is instantiated, this describes eg the storage device or + * partition in instantiation-specific terms. + * + * Blobs have a further "filename" associated with them. + */ + +#defined LSOOPEN_FLAG_WRITEABLE (1 << 0) + +struct lws_settings_ops; + +typedef struct { + void *handle_plat; + const struct lws_settings_ops *so; + uint8_t refcount; + void *opaque_plat; +} lws_settings_instance_t; + +typedef struct lws_settings_ops { + int (*get)(lws_settings_instance_t *si, const char *name, + uint8_t *dest, size_t *max_actual); + /**< if dest is NULL, max_actual is set to the actual length without + * copying anything out */ + int (*set)(lws_settings_instance_t *si, const char *name, + const uint8_t *src, size_t len); +} lws_settings_ops_t; + +LWS_VISIBLE LWS_EXTERN int +lws_settings_plat_get(lws_settings_instance_t *si, const char *name, + uint8_t *dest, size_t *max_actual); +LWS_VISIBLE LWS_EXTERN int +lws_settings_plat_set(lws_settings_instance_t *si, const char *name, + const uint8_t *src, size_t len); + +#define lws_settings_ops_plat \ + .get = lws_settings_plat_get, \ + .set = lws_settings_plat_set, + +LWS_VISIBLE LWS_EXTERN lws_settings_instance_t * +lws_settings_init(lws_settings_ops_t *so, void *opaque_plat); + +LWS_VISIBLE LWS_EXTERN void +lws_settings_deinit(lws_settings_instance_t **si); diff --git a/lib/drivers/CMakeLists.txt b/lib/drivers/CMakeLists.txt index 1320d885d..7404aae11 100644 --- a/lib/drivers/CMakeLists.txt +++ b/lib/drivers/CMakeLists.txt @@ -10,6 +10,7 @@ list(APPEND SOURCES drivers/led/led-gpio.c drivers/led/led-seq.c drivers/pwm/pwm.c + drivers/settings/settings.c ) if (LWS_ESP_PLATFORM) diff --git a/lib/drivers/settings/settings.c b/lib/drivers/settings/settings.c new file mode 100644 index 000000000..139e765b2 --- /dev/null +++ b/lib/drivers/settings/settings.c @@ -0,0 +1,44 @@ +/* + * lws_settings + * + * Copyright (C) 2019 - 2020 Andy Green + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +lws_settings_instance_t * +lws_settings_init(lws_settings_ops_t *so, void *opaque_plat) +{ + lws_settings_instance_t *si = lws_zalloc(sizeof(*si), __func__); + + if (!si) + return NULL; + + si->so = so; + si->opaque_plat = opaque_plat; + + return si; +} + +void +lws_settings_deinit(lws_settings_instance_t **si) +{ + lws_free(*si); + *si = NULL; +} diff --git a/lib/plat/freertos/CMakeLists.txt b/lib/plat/freertos/CMakeLists.txt index 22b7e8d04..44fe8e13b 100644 --- a/lib/plat/freertos/CMakeLists.txt +++ b/lib/plat/freertos/CMakeLists.txt @@ -39,6 +39,10 @@ list(APPEND SOURCES plat/freertos/freertos-service.c plat/freertos/freertos-sockets.c misc/romfs.c) + +if (LWS_ESP_PLATFORM AND LWS_WITH_DRIVERS) + list(APPEND SOURCES plat/freertos/esp32/drivers/settings.c) +endif() if (LWS_WITH_ESP32_HELPER) list(APPEND SOURCES plat/freertos/esp32/esp32-helpers.c) endif() @@ -53,4 +57,4 @@ endif() # Keep explicit parent scope exports at end # -exports_to_parent_scope() \ No newline at end of file +exports_to_parent_scope() diff --git a/lib/plat/freertos/esp32/drivers/settings.c b/lib/plat/freertos/esp32/drivers/settings.c new file mode 100644 index 000000000..2eb9dc5b6 --- /dev/null +++ b/lib/plat/freertos/esp32/drivers/settings.c @@ -0,0 +1,71 @@ +/* + * esp32 / esp-idf NV settings shim + * + * Copyright (C) 2019 - 2020 Andy Green + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include + +int +lws_settings_plat_get(lws_settings_instance_t si, const char *name, + uint8_t *dest, size_t *max_actual) +{ + int n; + + n = nvs_flash_init_partition((const char *)si->opaque_plat); + + lwsl_notice("%s: init partition %d\n", __func__, n); + if (n == ESP_ERR_NOT_FOUND) + return 1; + + if (nvs_open_from_partition((const char *)si->opaque_plat, + "_lws_settings", NVS_READONLY, + (nvs_handle_t *)&si->handle_plat)) + return 1; + + n = nvs_get_blob((nvs_handle_t)si->handle_plat, + name, dest, max_actual); + + nvs_close((nvs_handle_t)si->handle_plat); + + return !!n; +} + +int +lws_settings_plat_set(lws_settings_instance_t si, const char *name, + const uint8_t *src, size_t len) +{ + n = nvs_flash_init_partition((const char *)si->opaque_plat); + + lwsl_notice("%s: init partition %d\n", __func__, n); + if (n == ESP_ERR_NOT_FOUND) + return 1; + + if (nvs_open_from_partition((const char *)si->opaque_plat, + "_lws_settings", NVS_READWRITE, + (nvs_handle_t *)&si->handle_plat)) + return 1; + + n = nvs_set_blob((nvs_handle_t)si->handle_plat, name, src, len); + + nvs_commit((nvs_handle_t)si->handle_plat); + nvs_close((nvs_handle_t)si->handle_plat); +}