4#include <zephyr/kernel.h>
7#include <zephyr/settings/settings.h>
12static const char *
const TAG =
"zephyr.preferences";
14#define ESPHOME_SETTINGS_KEY "esphome"
16class ZephyrPreferenceBackend :
public ESPPreferenceBackend {
18 ZephyrPreferenceBackend(uint32_t
type) { this->type_ =
type; }
19 ZephyrPreferenceBackend(uint32_t
type, std::vector<uint8_t> &&data) : data(std::move(data)) { this->type_ =
type; }
21 bool save(
const uint8_t *data,
size_t len)
override {
22 this->data.resize(
len);
23 std::memcpy(this->data.data(), data,
len);
24 ESP_LOGVV(TAG,
"save key: %u, len: %d", this->type_,
len);
28 bool load(uint8_t *data,
size_t len)
override {
29 if (
len != this->data.size()) {
30 ESP_LOGE(TAG,
"size of setting key %s changed, from: %u, to: %u", get_key().c_str(), this->data.size(),
len);
33 std::memcpy(data, this->data.data(),
len);
34 ESP_LOGVV(TAG,
"load key: %u, len: %d", this->type_,
len);
38 uint32_t get_type()
const {
return this->type_; }
39 std::string get_key()
const {
return str_sprintf(ESPHOME_SETTINGS_KEY
"/%" PRIx32, this->type_); }
41 std::vector<uint8_t> data;
47class ZephyrPreferences :
public ESPPreferences {
50 int err = settings_subsys_init();
52 ESP_LOGE(TAG,
"Failed to initialize settings subsystem, err: %d", err);
56 static struct settings_handler settings_cb = {
57 .name = ESPHOME_SETTINGS_KEY,
58 .h_set = load_setting,
59 .h_export = export_settings,
62 err = settings_register(&settings_cb);
64 ESP_LOGE(TAG,
"setting_register failed, err, %d", err);
68 err = settings_load_subtree(ESPHOME_SETTINGS_KEY);
70 ESP_LOGE(TAG,
"Cannot load settings, err: %d", err);
73 ESP_LOGD(TAG,
"Loaded %u settings.", this->backends_.size());
76 ESPPreferenceObject make_preference(
size_t length, uint32_t
type,
bool in_flash)
override {
80 ESPPreferenceObject make_preference(
size_t length, uint32_t
type)
override {
81 for (
auto *backend : this->backends_) {
82 if (backend->get_type() ==
type) {
83 return ESPPreferenceObject(backend);
86 printf(
"type %u size %u\n",
type, this->backends_.size());
87 auto *pref =
new ZephyrPreferenceBackend(
type);
88 ESP_LOGD(TAG,
"Add new setting %s.", pref->get_key().c_str());
89 this->backends_.push_back(pref);
90 return ESPPreferenceObject(pref);
93 bool sync()
override {
94 ESP_LOGD(TAG,
"Save settings");
95 int err = settings_save();
97 ESP_LOGE(TAG,
"Cannot save settings, err: %d", err);
103 bool reset()
override {
104 ESP_LOGD(TAG,
"Reset settings");
105 for (
auto *backend : this->backends_) {
107 backend->data.clear();
114 std::vector<ZephyrPreferenceBackend *> backends_;
116 static int load_setting(
const char *name,
size_t len, settings_read_cb read_cb,
void *cb_arg) {
118 if (!
type.has_value()) {
119 std::string full_name(ESPHOME_SETTINGS_KEY);
123 settings_delete(full_name.c_str());
126 std::vector<uint8_t> data(
len);
127 int err = read_cb(cb_arg, data.data(),
len);
129 ESP_LOGD(TAG,
"load setting, name: %s(%u), len %u, err %u", name, *
type,
len, err);
130 auto *pref =
new ZephyrPreferenceBackend(*
type, std::move(data));
135 static int export_settings(
int (*cb)(
const char *name,
const void *value,
size_t val_len)) {
136 for (
auto *backend :
static_cast<ZephyrPreferences *
>(
global_preferences)->backends_) {
137 auto name = backend->get_key();
138 int err =
cb(name.c_str(), backend->data.data(), backend->data.size());
139 ESP_LOGD(TAG,
"save in flash, name %s, len %u, err %d", name.c_str(), backend->data.size(), err);
146 auto *prefs =
new ZephyrPreferences();
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
std::string str_sprintf(const char *fmt,...)