3#include <zephyr/kernel.h>
6#include <zephyr/settings/settings.h>
11static const char *
const TAG =
"zephyr.preferences";
13#define ESPHOME_SETTINGS_KEY "esphome"
15class ZephyrPreferenceBackend :
public ESPPreferenceBackend {
17 ZephyrPreferenceBackend(uint32_t
type) { this->type_ =
type; }
18 ZephyrPreferenceBackend(uint32_t
type, std::vector<uint8_t> &&data) : data(std::move(data)) { this->type_ =
type; }
20 bool save(
const uint8_t *data,
size_t len)
override {
21 this->data.resize(
len);
22 std::memcpy(this->data.data(), data,
len);
23 ESP_LOGVV(TAG,
"save key: %u, len: %d", this->type_,
len);
27 bool load(uint8_t *data,
size_t len)
override {
28 if (
len != this->data.size()) {
29 ESP_LOGE(TAG,
"size of setting key %s changed, from: %u, to: %u", get_key().c_str(), this->data.size(),
len);
32 std::memcpy(data, this->data.data(),
len);
33 ESP_LOGVV(TAG,
"load key: %u, len: %d", this->type_,
len);
37 uint32_t get_type()
const {
return this->type_; }
38 std::string get_key()
const {
return str_sprintf(ESPHOME_SETTINGS_KEY
"/%" PRIx32, this->type_); }
40 std::vector<uint8_t> data;
46class ZephyrPreferences :
public ESPPreferences {
49 int err = settings_subsys_init();
51 ESP_LOGE(TAG,
"Failed to initialize settings subsystem, err: %d", err);
55 static struct settings_handler settings_cb = {
56 .name = ESPHOME_SETTINGS_KEY,
57 .h_set = load_setting,
58 .h_export = export_settings,
61 err = settings_register(&settings_cb);
63 ESP_LOGE(TAG,
"setting_register failed, err, %d", err);
67 err = settings_load_subtree(ESPHOME_SETTINGS_KEY);
69 ESP_LOGE(TAG,
"Cannot load settings, err: %d", err);
72 ESP_LOGD(TAG,
"Loaded %u settings.", this->backends_.size());
75 ESPPreferenceObject make_preference(
size_t length, uint32_t
type,
bool in_flash)
override {
79 ESPPreferenceObject make_preference(
size_t length, uint32_t
type)
override {
80 for (
auto *backend : this->backends_) {
81 if (backend->get_type() ==
type) {
82 return ESPPreferenceObject(backend);
85 printf(
"type %u size %u\n",
type, this->backends_.size());
86 auto *pref =
new ZephyrPreferenceBackend(
type);
87 ESP_LOGD(TAG,
"Add new setting %s.", pref->get_key().c_str());
88 this->backends_.push_back(pref);
89 return ESPPreferenceObject(pref);
92 bool sync()
override {
93 ESP_LOGD(TAG,
"Save settings");
94 int err = settings_save();
96 ESP_LOGE(TAG,
"Cannot save settings, err: %d", err);
102 bool reset()
override {
103 ESP_LOGD(TAG,
"Reset settings");
104 for (
auto *backend : this->backends_) {
106 backend->data.clear();
113 std::vector<ZephyrPreferenceBackend *> backends_;
115 static int load_setting(
const char *name,
size_t len, settings_read_cb read_cb,
void *cb_arg) {
117 if (!
type.has_value()) {
118 std::string full_name(ESPHOME_SETTINGS_KEY);
122 settings_delete(full_name.c_str());
125 std::vector<uint8_t> data(
len);
126 int err = read_cb(cb_arg, data.data(),
len);
128 ESP_LOGD(TAG,
"load setting, name: %s(%u), len %u, err %u", name, *
type,
len, err);
129 auto *pref =
new ZephyrPreferenceBackend(*
type, std::move(data));
134 static int export_settings(
int (*cb)(
const char *name,
const void *value,
size_t val_len)) {
135 for (
auto *backend :
static_cast<ZephyrPreferences *
>(
global_preferences)->backends_) {
136 auto name = backend->get_key();
137 int err =
cb(name.c_str(), backend->data.data(), backend->data.size());
138 ESP_LOGD(TAG,
"save in flash, name %s, len %u, err %d", name.c_str(), backend->data.size(), err);
145 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,...)