ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
config_store.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file config_store.h
6 * @brief Typed NVS configuration store (PROTOCORE_ENABLE_CONFIG_STORE).
7 *
8 * A small typed key/value API for core device settings - WiFi credentials, IP
9 * configuration, feature toggles - that routes them into the ESP32's native
10 * Non-Volatile Storage (NVS) partition as binary entries, rather than a JSON
11 * text file on the filesystem. NVS is wear-levelled and independent of the
12 * LittleFS/SPIFFS partition, so configuration survives a filesystem corruption
13 * and credentials live in the storage area meant for them.
14 *
15 * Three value types: null-terminated strings, `uint32_t`, and raw blobs - each
16 * with a default returned when the key is absent. On ESP32 the backend is the
17 * Arduino `Preferences` NVS wrapper; on host builds it is a fixed in-memory table
18 * (`PROTOCORE_CONFIG_MAX_ENTRIES` x `PROTOCORE_CONFIG_VAL_MAX`) so the typed contract is
19 * unit-testable without flash.
20 *
21 * Writes hit NVS, so call the setters at provisioning / config time, not in the
22 * request hot path. Keys are limited to 15 chars (NVS), plus null.
23 *
24 * @author Douglas Quigg (dstroy0)
25 * @date 2026
26 */
27
28#ifndef PROTOCORE_CONFIG_STORE_H
29#define PROTOCORE_CONFIG_STORE_H
30
31#include "protocore_config.h" // the entry point: protocore_types.h for the widths
32
33#if PROTOCORE_ENABLE_CONFIG_STORE
34
36
37// PROTOCORE_CONFIG_STORE_BORROW - the bytes this module runs out of - is stated in protocore_config.h, which sums it
38// into its arena. A caller takes them once and passes the pointer to every call. How they are
39// carved is this module's and is never named here.
40
41/** @brief What begin takes. */
42typedef struct
43{
44 const char *ns;
45} ConfigStoreBeginArgs;
46
47/** @brief What set_str takes. */
48typedef struct
49{
50 const char *key;
51 const char *val;
52} ConfigStoreSetStrArgs;
53
54/** @brief What get_str takes. */
55typedef struct
56{
57 const char *key;
58 char *out;
59 size_t out_cap;
60 const char *def;
61} ConfigStoreGetStrArgs;
62
63/** @brief What set_u32 takes. */
64typedef struct
65{
66 const char *key;
67 uint32_t val;
68} ConfigStoreSetU32Args;
69
70/** @brief What get_u32 takes. */
71typedef struct
72{
73 const char *key;
74 uint32_t def;
75} ConfigStoreGetU32Args;
76
77/** @brief What set_blob takes. */
78typedef struct
79{
80 const char *key;
81 const void *data;
82 size_t len;
83} ConfigStoreSetBlobArgs;
84
85/** @brief What get_blob takes. */
86typedef struct
87{
88 const char *key;
89 void *out;
90 size_t out_cap;
91} ConfigStoreGetBlobArgs;
92
93/** @brief What erase takes. */
94typedef struct
95{
96 const char *key;
97} ConfigStoreEraseArgs;
98typedef struct
99{
100 ConfigStoreBeginArgs begin_args;
101 ConfigStoreSetStrArgs set_str_args;
102 ConfigStoreGetStrArgs get_str_args;
103 ConfigStoreSetU32Args set_u32_args;
104 ConfigStoreGetU32Args get_u32_args;
105 ConfigStoreSetBlobArgs set_blob_args;
106 ConfigStoreGetBlobArgs get_blob_args;
107 ConfigStoreEraseArgs erase_args;
108 proto_bool ok;
109 int n;
110 uint32_t ms;
111} ConfigStoreVars;
112
113/** @brief The operands and the outcome. */
114extern ConfigStoreVars ConfigStoreV;
115
116/** @brief The entries. */
117typedef struct
118{
119 void (*const begin)(uint8_t *work);
120 void (*const set_str)(uint8_t *work);
121 void (*const get_str)(uint8_t *work);
122 void (*const set_u32)(uint8_t *work);
123 void (*const get_u32)(uint8_t *work);
124 void (*const set_blob)(uint8_t *work);
125 void (*const get_blob)(uint8_t *work);
126 void (*const erase)(uint8_t *work);
127 void (*const clear)(uint8_t *work);
128} ConfigStoreNs;
129
130// What the table binds, defined once in the .c and taking one parameter each: everything
131// else an entry needs is an operand in ConfigStoreV or a region of the borrow at a fixed offset.
132void protocore_config_store_begin(uint8_t *work);
133void protocore_config_store_set_str(uint8_t *work);
134void protocore_config_store_get_str(uint8_t *work);
135void protocore_config_store_set_u32(uint8_t *work);
136void protocore_config_store_get_u32(uint8_t *work);
137void protocore_config_store_set_blob(uint8_t *work);
138void protocore_config_store_get_blob(uint8_t *work);
139void protocore_config_store_erase(uint8_t *work);
140void protocore_config_store_clear(uint8_t *work);
141
142// `static const`, initialised HERE rather than `extern` against a definition in the .c: a
143// const object whose initializer every translation unit can see is a COMPILE-TIME FACT, so
144// `ConfigStore.begin(work)` resolves to a named function and becomes a DIRECT call. An extern table
145// leaves the call indirect and the symbol live at every level, -O2 -flto included.
146static const ConfigStoreNs ConfigStore __attribute__((unused)) = {
147 .begin = protocore_config_store_begin,
148 .set_str = protocore_config_store_set_str,
149 .get_str = protocore_config_store_get_str,
150 .set_u32 = protocore_config_store_set_u32,
151 .get_u32 = protocore_config_store_get_u32,
152 .set_blob = protocore_config_store_set_blob,
153 .get_blob = protocore_config_store_get_blob,
154 .erase = protocore_config_store_erase,
155 .clear = protocore_config_store_clear,
156};
157
158/**
159 * @brief The PROTOCORE_CONFIG_STORE_BORROW bytes this module's state lives in.
160 *
161 * Stated beside the namespace rather than on it: an entry takes a borrow, and this is where
162 * that borrow comes from. Taken once from the end of the pool, which no mark and no release
163 * walks, so the state lasts the life of the program.
164 *
165 * @return the span.
166 */
167uint8_t *protocore_config_store_span(void);
168
170
171#endif // PROTOCORE_ENABLE_CONFIG_STORE
172
173#endif // PROTOCORE_CONFIG_STORE_H
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97