CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
host_api_nvs.cpp
Go to the documentation of this file.
1
9
12#include "cdc_core/Raii.h"
13#include "nvs.h"
14#include "nvs_flash.h"
15
16#include <cstring>
17#include <string>
18
19extern "C" void* plg_get_active_plugin(void);
20extern "C" void plg_log_warn(const char* msg);
21
22namespace {
23
24std::string activeNamespace()
25{
26 auto* plugin = static_cast<cdc::plugin_manager::Plugin*>(plg_get_active_plugin());
27 if (!plugin) return {};
28 const auto& cap = plugin->manifest().capabilities;
29 if (!cap.nvs_namespace.empty()) return cap.nvs_namespace;
30 return std::string("plugin_") + plugin->id();
31}
32
33bool namespaceOk(const std::string& ns)
34{
35 constexpr size_t NVS_MAX = 15;
36 if (ns.empty() || ns.size() > NVS_MAX) return false;
37 if (ns.rfind("plg_", 0) != 0 && ns.rfind("plugin_", 0) != 0) return false;
38 for (char c : ns) {
39 bool ok = (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_';
40 if (!ok) return false;
41 }
42 return true;
43}
44
45int openScope(bool write, ::cdc::core::NvsScope& out)
46{
47 std::string ns = activeNamespace();
48 if (!namespaceOk(ns)) return HOST_ERR_NO_CAPABILITY;
49 out = ::cdc::core::NvsScope(ns.c_str(), write ? NVS_READWRITE : NVS_READONLY);
50 if (!out) {
51 return (out.status() == ESP_ERR_NVS_NOT_FOUND) ? HOST_ERR_NOT_FOUND
53 }
54 return HOST_OK;
55}
56
57int translateErr(esp_err_t err)
58{
59 switch (err) {
60 case ESP_OK: return HOST_OK;
61 case ESP_ERR_NVS_NOT_FOUND: return HOST_ERR_NOT_FOUND;
62 case ESP_ERR_NVS_INVALID_LENGTH: return HOST_ERR_NO_MEMORY;
63 default: return HOST_ERR_GENERIC;
64 }
65}
66
67int writeAndCommit(::cdc::core::NvsScope& h, esp_err_t writeErr)
68{
69 if (writeErr == ESP_OK) writeErr = h.commit();
70 return translateErr(writeErr);
71}
72
73} // namespace
74
75extern "C" {
76
77int host_nvs_get_blob(const char* key, uint8_t* buf, size_t* len)
78{
79 if (!key || !len) return HOST_ERR_INVALID_ARG;
81 int rc = openScope(false, h);
82 if (rc != HOST_OK) return rc;
83 return translateErr(nvs_get_blob(h, key, buf, len));
84}
85
86int host_nvs_set_blob(const char* key, const uint8_t* buf, size_t len)
87{
88 if (!key || (!buf && len > 0)) return HOST_ERR_INVALID_ARG;
90 int rc = openScope(true, h);
91 if (rc != HOST_OK) return rc;
92 return writeAndCommit(h, nvs_set_blob(h, key, buf, len));
93}
94
95int host_nvs_get_u32(const char* key, uint32_t* out)
96{
97 if (!key || !out) return HOST_ERR_INVALID_ARG;
99 int rc = openScope(false, h);
100 if (rc != HOST_OK) return rc;
101 return translateErr(nvs_get_u32(h, key, out));
102}
103
104int host_nvs_set_u32(const char* key, uint32_t value)
105{
106 if (!key) return HOST_ERR_INVALID_ARG;
108 int rc = openScope(true, h);
109 if (rc != HOST_OK) return rc;
110 return writeAndCommit(h, nvs_set_u32(h, key, value));
111}
112
113int host_nvs_get_str(const char* key, char* buf, size_t buf_size)
114{
115 if (!key || !buf || buf_size == 0) return HOST_ERR_INVALID_ARG;
117 int rc = openScope(false, h);
118 if (rc != HOST_OK) return rc;
119 size_t n = buf_size;
120 return translateErr(nvs_get_str(h, key, buf, &n));
121}
122
123int host_nvs_set_str(const char* key, const char* value)
124{
125 if (!key || !value) return HOST_ERR_INVALID_ARG;
127 int rc = openScope(true, h);
128 if (rc != HOST_OK) return rc;
129 return writeAndCommit(h, nvs_set_str(h, key, value));
130}
131
132int host_nvs_erase(const char* key)
133{
134 if (!key) return HOST_ERR_INVALID_ARG;
136 int rc = openScope(true, h);
137 if (rc != HOST_OK) return rc;
138 return writeAndCommit(h, nvs_erase_key(h, key));
139}
140
142{
144 int rc = openScope(true, h);
145 if (rc != HOST_OK) return rc;
146 return writeAndCommit(h, nvs_erase_all(h));
147}
148
149int host_nvs_list_keys(char* out, size_t* out_len)
150{
151 if (!out_len) return HOST_ERR_INVALID_ARG;
152 std::string ns = activeNamespace();
153 if (!namespaceOk(ns)) return HOST_ERR_NO_CAPABILITY;
154
155 nvs_iterator_t it = nullptr;
156 esp_err_t err = nvs_entry_find(NVS_DEFAULT_PART_NAME, ns.c_str(), NVS_TYPE_ANY, &it);
157 size_t written = 0;
158 const size_t max = (out ? *out_len : 0);
159 while (err == ESP_OK && it) {
160 nvs_entry_info_t info;
161 nvs_entry_info(it, &info);
162 size_t need = std::strlen(info.key) + 1;
163 if (out && (written + need) <= max) {
164 std::memcpy(out + written, info.key, need - 1);
165 out[written + need - 1] = '\n';
166 }
167 written += need;
168 err = nvs_entry_next(&it);
169 }
170 nvs_release_iterator(it);
171 *out_len = written;
172 return HOST_OK;
173}
174
175} // extern "C"
Owned WAMR module instance + per-plugin state.
Shared RAII wrappers for firmware resources.
RAII wrapper for an NVS handle.
Definition Raii.h:106
esp_err_t commit() noexcept
Commit pending writes. Caller checks the return value if needed.
Definition Raii.h:153
esp_err_t status() const noexcept
esp_err_t result of the original nvs_open call.
Definition Raii.h:150
const PluginManifest & manifest() const noexcept
Definition Plugin.h:88
int host_nvs_list_keys(char *out, size_t *out_len)
Enumerate the keys in the plugin's namespace.
int host_nvs_erase(const char *key)
Delete a single key.
int host_nvs_set_u32(const char *key, uint32_t value)
Write a uint32 value.
int host_nvs_get_blob(const char *key, uint8_t *buf, size_t *len)
Read a binary blob from NVS.
int host_nvs_get_str(const char *key, char *buf, size_t buf_size)
Read a NUL-terminated string.
int host_nvs_get_u32(const char *key, uint32_t *out)
Read a uint32 value.
int host_nvs_erase_all(void)
Erase every key in the plugin's namespace.
int host_nvs_set_blob(const char *key, const uint8_t *buf, size_t len)
Write a binary blob to NVS.
int host_nvs_set_str(const char *key, const char *value)
Write a NUL-terminated string.
CDC Badge OS plugin host API - canonical C ABI contract.
#define HOST_ERR_NO_CAPABILITY
Definition host_api.h:40
#define HOST_OK
Definition host_api.h:37
#define HOST_ERR_INVALID_ARG
Definition host_api.h:39
#define HOST_ERR_NO_MEMORY
Definition host_api.h:43
#define HOST_ERR_NOT_FOUND
Definition host_api.h:41
#define HOST_ERR_GENERIC
Definition host_api.h:38
void plg_log_warn(const char *msg)
void * plg_get_active_plugin(void)