4#include <zephyr/kernel.h>
7#include <zephyr/settings/settings.h>
14static const char *
const TAG =
"zephyr.preferences";
16#define ESPHOME_SETTINGS_KEY "esphome"
19static constexpr size_t KEY_BUFFER_SIZE = 20;
21class ZephyrPreferenceBackend :
public ESPPreferenceBackend {
23 ZephyrPreferenceBackend(uint32_t
type) { this->type_ =
type; }
24 ZephyrPreferenceBackend(uint32_t
type, std::vector<uint8_t> &&data) : data(std::move(data)) { this->type_ =
type; }
26 bool save(
const uint8_t *data,
size_t len)
override {
27 this->data.resize(
len);
28 std::memcpy(this->data.data(), data,
len);
29 ESP_LOGVV(TAG,
"save key: %u, len: %d", this->type_,
len);
33 bool load(uint8_t *data,
size_t len)
override {
34 if (
len != this->data.size()) {
35 char key_buf[KEY_BUFFER_SIZE];
36 this->format_key(key_buf,
sizeof(key_buf));
37 ESP_LOGE(TAG,
"size of setting key %s changed, from: %u, to: %u", key_buf, this->data.size(),
len);
40 std::memcpy(data, this->data.data(),
len);
41 ESP_LOGVV(TAG,
"load key: %u, len: %d", this->type_,
len);
45 uint32_t get_type()
const {
return this->type_; }
46 void format_key(
char *buf,
size_t size)
const { snprintf(buf,
size, ESPHOME_SETTINGS_KEY
"/%" PRIx32, this->type_); }
48 std::vector<uint8_t> data;
54class ZephyrPreferences :
public ESPPreferences {
57 int err = settings_subsys_init();
59 ESP_LOGE(TAG,
"Failed to initialize settings subsystem, err: %d", err);
63 static struct settings_handler settings_cb = {
64 .name = ESPHOME_SETTINGS_KEY,
65 .h_set = load_setting,
66 .h_export = export_settings,
69 err = settings_register(&settings_cb);
71 ESP_LOGE(TAG,
"setting_register failed, err, %d", err);
75 err = settings_load_subtree(ESPHOME_SETTINGS_KEY);
77 ESP_LOGE(TAG,
"Cannot load settings, err: %d", err);
80 ESP_LOGD(TAG,
"Loaded %u settings.", this->backends_.size());
83 ESPPreferenceObject make_preference(
size_t length, uint32_t
type,
bool in_flash)
override {
87 ESPPreferenceObject make_preference(
size_t length, uint32_t
type)
override {
88 for (
auto *backend : this->backends_) {
89 if (backend->get_type() ==
type) {
90 return ESPPreferenceObject(backend);
93 printf(
"type %u size %u\n",
type, this->backends_.size());
94 auto *pref =
new ZephyrPreferenceBackend(
type);
95 char key_buf[KEY_BUFFER_SIZE];
96 pref->format_key(key_buf,
sizeof(key_buf));
97 ESP_LOGD(TAG,
"Add new setting %s.", key_buf);
98 this->backends_.push_back(pref);
99 return ESPPreferenceObject(pref);
102 bool sync()
override {
103 ESP_LOGD(TAG,
"Save settings");
104 int err = settings_save();
106 ESP_LOGE(TAG,
"Cannot save settings, err: %d", err);
112 bool reset()
override {
113 ESP_LOGD(TAG,
"Reset settings");
114 for (
auto *backend : this->backends_) {
116 backend->data.clear();
123 std::vector<ZephyrPreferenceBackend *> backends_;
125 static int load_setting(
const char *name,
size_t len, settings_read_cb read_cb,
void *cb_arg) {
127 if (!
type.has_value()) {
128 std::string full_name(ESPHOME_SETTINGS_KEY);
132 settings_delete(full_name.c_str());
135 std::vector<uint8_t> data(
len);
136 int err = read_cb(cb_arg, data.data(),
len);
138 ESP_LOGD(TAG,
"load setting, name: %s(%u), len %u, err %u", name, *
type,
len, err);
139 auto *pref =
new ZephyrPreferenceBackend(*
type, std::move(data));
144 static int export_settings(
int (*cb)(
const char *name,
const void *value,
size_t val_len)) {
145 for (
auto *backend :
static_cast<ZephyrPreferences *
>(
global_preferences)->backends_) {
146 char name[KEY_BUFFER_SIZE];
147 backend->format_key(name,
sizeof(name));
148 int err =
cb(name, backend->data.data(), backend->data.size());
149 ESP_LOGD(TAG,
"save in flash, name %s, len %u, err %d", name, backend->data.size(), err);
155static ZephyrPreferences s_preferences;
159 s_preferences.open();
Providing packet encoding functions for exchanging data with a remote host.
size_t parse_hex(const char *str, size_t length, uint8_t *data, size_t count)
Parse bytes from a hex-encoded string into a byte array.
ESPPreferences * global_preferences