Line data Source code
1 0 : /*
2 : * Copyright (c) 2018 Nordic Semiconductor ASA
3 : * Copyright (c) 2015 Runtime Inc
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 :
8 : #ifndef ZEPHYR_INCLUDE_SETTINGS_SETTINGS_H_
9 : #define ZEPHYR_INCLUDE_SETTINGS_SETTINGS_H_
10 :
11 : #include <sys/types.h>
12 : #include <zephyr/sys/util.h>
13 : #include <zephyr/sys/slist.h>
14 : #include <zephyr/sys/iterable_sections.h>
15 : #include <stdint.h>
16 :
17 : #ifdef __cplusplus
18 : extern "C" {
19 : #endif
20 :
21 :
22 : /**
23 : * @defgroup file_system_storage File System Storage
24 : * @ingroup os_services
25 : * @{
26 : * @}
27 : */
28 :
29 : /**
30 : * @defgroup settings Settings
31 : * @since 1.12
32 : * @version 1.0.0
33 : * @ingroup file_system_storage
34 : * @{
35 : */
36 :
37 0 : #define SETTINGS_MAX_DIR_DEPTH 8 /* max depth of settings tree */
38 0 : #define SETTINGS_MAX_NAME_LEN (8 * SETTINGS_MAX_DIR_DEPTH)
39 0 : #define SETTINGS_MAX_VAL_LEN 256
40 0 : #define SETTINGS_NAME_SEPARATOR '/'
41 0 : #define SETTINGS_NAME_END '='
42 :
43 : /* place for settings additions:
44 : * up to 7 separators, '=', '\0'
45 : */
46 0 : #define SETTINGS_EXTRA_LEN ((SETTINGS_MAX_DIR_DEPTH - 1) + 2)
47 :
48 : /**
49 : * Function used to read the data from the settings storage in
50 : * h_set handler implementations.
51 : *
52 : * @param[in] cb_arg arguments for the read function. Appropriate cb_arg is
53 : * transferred to h_set handler implementation by
54 : * the backend.
55 : * @param[out] data the destination buffer
56 : * @param[in] len length of read
57 : *
58 : * @return positive: Number of bytes read, 0: key-value pair is deleted.
59 : * On error returns -ERRNO code.
60 : */
61 1 : typedef ssize_t (*settings_read_cb)(void *cb_arg, void *data, size_t len);
62 :
63 : /**
64 : * @struct settings_handler
65 : * Config handlers for subtree implement a set of handler functions.
66 : * These are registered using a call to @ref settings_register.
67 : */
68 1 : struct settings_handler {
69 :
70 1 : const char *name;
71 : /**< Name of subtree. */
72 :
73 1 : int cprio;
74 : /**< Priority of commit, lower value is higher priority */
75 :
76 1 : int (*h_get)(const char *key, char *val, int val_len_max);
77 : /**< Get values handler of settings items identified by keyword names.
78 : *
79 : * Parameters:
80 : * - key[in] the name with skipped part that was used as name in
81 : * handler registration
82 : * - val[out] buffer to receive value.
83 : * - val_len_max[in] size of that buffer.
84 : *
85 : * Return: length of data read on success, negative on failure.
86 : */
87 :
88 1 : int (*h_set)(const char *key, size_t len, settings_read_cb read_cb,
89 : void *cb_arg);
90 : /**< Set value handler of settings items identified by keyword names.
91 : *
92 : * Parameters:
93 : * - key[in] the name with skipped part that was used as name in
94 : * handler registration
95 : * - len[in] the size of the data found in the backend.
96 : * - read_cb[in] function provided to read the data from the backend.
97 : * - cb_arg[in] arguments for the read function provided by the
98 : * backend.
99 : *
100 : * Return: 0 on success, non-zero on failure.
101 : */
102 :
103 1 : int (*h_commit)(void);
104 : /**< This handler gets called after settings has been loaded in full.
105 : * User might use it to apply setting to the application.
106 : *
107 : * Return: 0 on success, non-zero on failure.
108 : */
109 :
110 1 : int (*h_export)(int (*export_func)(const char *name, const void *val,
111 : size_t val_len));
112 : /**< This gets called to dump all current settings items.
113 : *
114 : * This happens when @ref settings_save tries to save the settings.
115 : * Parameters:
116 : * - export_func: the pointer to the internal function which appends
117 : * a single key-value pair to persisted settings. Don't store
118 : * duplicated value. The name is subtree/key string, val is the string
119 : * with value.
120 : *
121 : * @remarks The User might limit a implementations of handler to serving
122 : * only one keyword at one call - what will impose limit to get/set
123 : * values using full subtree/key name.
124 : *
125 : * Return: 0 on success, non-zero on failure.
126 : */
127 :
128 1 : sys_snode_t node;
129 : /**< Linked list node info for module internal usage. */
130 : };
131 :
132 : /**
133 : * @struct settings_handler_static
134 : * Config handlers without the node element, used for static handlers.
135 : * These are registered using a call to SETTINGS_STATIC_HANDLER_DEFINE().
136 : */
137 1 : struct settings_handler_static {
138 :
139 1 : const char *name;
140 : /**< Name of subtree. */
141 :
142 1 : int cprio;
143 : /**< Priority of commit, lower value is higher priority */
144 :
145 1 : int (*h_get)(const char *key, char *val, int val_len_max);
146 : /**< Get values handler of settings items identified by keyword names.
147 : *
148 : * Parameters:
149 : * - key[in] the name with skipped part that was used as name in
150 : * handler registration
151 : * - val[out] buffer to receive value.
152 : * - val_len_max[in] size of that buffer.
153 : *
154 : * Return: length of data read on success, negative on failure.
155 : */
156 :
157 1 : int (*h_set)(const char *key, size_t len, settings_read_cb read_cb,
158 : void *cb_arg);
159 : /**< Set value handler of settings items identified by keyword names.
160 : *
161 : * Parameters:
162 : * - key[in] the name with skipped part that was used as name in
163 : * handler registration
164 : * - len[in] the size of the data found in the backend.
165 : * - read_cb[in] function provided to read the data from the backend.
166 : * - cb_arg[in] arguments for the read function provided by the
167 : * backend.
168 : *
169 : * Return: 0 on success, non-zero on failure.
170 : */
171 :
172 1 : int (*h_commit)(void);
173 : /**< This handler gets called after settings has been loaded in full.
174 : * User might use it to apply setting to the application.
175 : */
176 :
177 1 : int (*h_export)(int (*export_func)(const char *name, const void *val,
178 : size_t val_len));
179 : /**< This gets called to dump all current settings items.
180 : *
181 : * This happens when @ref settings_save tries to save the settings.
182 : * Parameters:
183 : * - export_func: the pointer to the internal function which appends
184 : * a single key-value pair to persisted settings. Don't store
185 : * duplicated value. The name is subtree/key string, val is the string
186 : * with value.
187 : *
188 : * @remarks The User might limit a implementations of handler to serving
189 : * only one keyword at one call - what will impose limit to get/set
190 : * values using full subtree/key name.
191 : *
192 : * Return: 0 on success, non-zero on failure.
193 : */
194 : };
195 :
196 : /**
197 : * Define a static handler for settings items
198 : *
199 : * @param _hname handler name
200 : * @param _tree subtree name
201 : * @param _get get routine (can be NULL)
202 : * @param _set set routine (can be NULL)
203 : * @param _commit commit routine (can be NULL)
204 : * @param _export export routine (can be NULL)
205 : * @param _cprio commit priority (lower value is higher priority)
206 : *
207 : * This creates a variable _hname prepended by settings_handler_.
208 : *
209 : */
210 :
211 : #define SETTINGS_STATIC_HANDLER_DEFINE_WITH_CPRIO(_hname, _tree, _get, _set, \
212 1 : _commit, _export, _cprio) \
213 : const STRUCT_SECTION_ITERABLE(settings_handler_static, \
214 : settings_handler_ ## _hname) = { \
215 : .name = _tree, \
216 : .cprio = _cprio, \
217 : .h_get = _get, \
218 : .h_set = _set, \
219 : .h_commit = _commit, \
220 : .h_export = _export, \
221 : }
222 :
223 : /* Handlers without commit priority are set to priority O */
224 : #define SETTINGS_STATIC_HANDLER_DEFINE(_hname, _tree, _get, _set, _commit, \
225 0 : _export) \
226 : SETTINGS_STATIC_HANDLER_DEFINE_WITH_CPRIO(_hname, _tree, _get, _set, \
227 : _commit, _export, 0)
228 :
229 : /**
230 : * Initialization of settings and backend
231 : *
232 : * Can be called at application startup.
233 : * In case the backend is a FS Remember to call it after the FS was mounted.
234 : * For FCB backend it can be called without such a restriction.
235 : *
236 : * @return 0 on success, non-zero on failure.
237 : */
238 1 : int settings_subsys_init(void);
239 :
240 : /**
241 : * Register a handler for settings items stored in RAM with
242 : * commit priority.
243 : *
244 : * @param cf Structure containing registration info.
245 : * @param cprio Commit priority (lower value is higher priority).
246 : *
247 : * @return 0 on success, non-zero on failure.
248 : */
249 1 : int settings_register_with_cprio(struct settings_handler *cf,
250 : int cprio);
251 :
252 : /**
253 : * Register a handler for settings items stored in RAM with
254 : * commit priority set to default.
255 : *
256 : * @param cf Structure containing registration info.
257 : *
258 : * @return 0 on success, non-zero on failure.
259 : */
260 1 : int settings_register(struct settings_handler *cf);
261 :
262 : /**
263 : * Load serialized items from registered persistence sources. Handlers for
264 : * serialized item subtrees registered earlier will be called for encountered
265 : * values.
266 : *
267 : * @return 0 on success, non-zero on failure.
268 : */
269 1 : int settings_load(void);
270 :
271 : /**
272 : * Load limited set of serialized items from registered persistence sources.
273 : * Handlers for serialized item subtrees registered earlier will be called for
274 : * encountered values that belong to the subtree.
275 : *
276 : * @param[in] subtree name of the subtree to be loaded.
277 : * @return 0 on success, non-zero on failure.
278 : */
279 1 : int settings_load_subtree(const char *subtree);
280 :
281 : /**
282 : * Callback function used for direct loading.
283 : * Used by @ref settings_load_subtree_direct function.
284 : *
285 : * @param[in] key the name with skipped part that was used as name in
286 : * handler registration
287 : * @param[in] len the size of the data found in the backend.
288 : * @param[in] read_cb function provided to read the data from the backend.
289 : * @param[in,out] cb_arg arguments for the read function provided by the
290 : * backend.
291 : * @param[in,out] param parameter given to the
292 : * @ref settings_load_subtree_direct function.
293 : *
294 : * @return When nonzero value is returned, further subtree searching is stopped.
295 : */
296 1 : typedef int (*settings_load_direct_cb)(
297 : const char *key,
298 : size_t len,
299 : settings_read_cb read_cb,
300 : void *cb_arg,
301 : void *param);
302 :
303 : /**
304 : * Load limited set of serialized items using given callback.
305 : *
306 : * This function bypasses the normal data workflow in settings module.
307 : * All the settings values that are found are passed to the given callback.
308 : *
309 : * @note
310 : * This function does not call commit function.
311 : * It works as a blocking function, so it is up to the user to call
312 : * any kind of commit function when this operation ends.
313 : *
314 : * @param[in] subtree subtree name of the subtree to be loaded.
315 : * @param[in] cb pointer to the callback function.
316 : * @param[in,out] param parameter to be passed when callback
317 : * function is called.
318 : * @return 0 on success, non-zero on failure.
319 : */
320 1 : int settings_load_subtree_direct(
321 : const char *subtree,
322 : settings_load_direct_cb cb,
323 : void *param);
324 :
325 : /**
326 : * Save currently running serialized items. All serialized items which are
327 : * different from currently persisted values will be saved.
328 : *
329 : * @return 0 on success, non-zero on failure.
330 : */
331 1 : int settings_save(void);
332 :
333 : /**
334 : * Save limited set of currently running serialized items. All serialized items
335 : * that belong to subtree and which are different from currently persisted
336 : * values will be saved.
337 : *
338 : * @param[in] subtree name of the subtree to be loaded.
339 : * @return 0 on success, non-zero on failure.
340 : */
341 1 : int settings_save_subtree(const char *subtree);
342 :
343 : /**
344 : * Write a single serialized value to persisted storage (if it has
345 : * changed value).
346 : *
347 : * @param name Name/key of the settings item.
348 : * @param value Pointer to the value of the settings item. This value will
349 : * be transferred to the @ref settings_handler::h_export handler implementation.
350 : * @param val_len Length of the value.
351 : *
352 : * @return 0 on success, non-zero on failure.
353 : */
354 1 : int settings_save_one(const char *name, const void *value, size_t val_len);
355 :
356 : /**
357 : * Delete a single serialized in persisted storage.
358 : *
359 : * Deleting an existing key-value pair in the settings mean
360 : * to set its value to NULL.
361 : *
362 : * @param name Name/key of the settings item.
363 : *
364 : * @return 0 on success, non-zero on failure.
365 : */
366 1 : int settings_delete(const char *name);
367 :
368 : /**
369 : * Call commit for all settings handler. This should apply all
370 : * settings which has been set, but not applied yet.
371 : *
372 : * @return 0 on success, non-zero on failure.
373 : */
374 1 : int settings_commit(void);
375 :
376 : /**
377 : * Call commit for settings handler that belong to subtree.
378 : * This should apply all settings which has been set, but not applied yet.
379 : *
380 : * @param[in] subtree name of the subtree to be committed.
381 : *
382 : * @return 0 on success, non-zero on failure.
383 : */
384 1 : int settings_commit_subtree(const char *subtree);
385 :
386 : /**
387 : * @} settings
388 : */
389 :
390 :
391 : /**
392 : * @defgroup settings_backend Settings backend interface
393 : * @ingroup settings
394 : * @{
395 : */
396 :
397 : /*
398 : * API for config storage
399 : */
400 :
401 : struct settings_store_itf;
402 :
403 : /**
404 : * Backend handler node for storage handling.
405 : */
406 1 : struct settings_store {
407 1 : sys_snode_t cs_next;
408 : /**< Linked list node info for internal usage. */
409 :
410 1 : const struct settings_store_itf *cs_itf;
411 : /**< Backend handler structure. */
412 : };
413 :
414 : /**
415 : * Arguments for data loading.
416 : * Holds all parameters that changes the way data should be loaded from backend.
417 : */
418 1 : struct settings_load_arg {
419 : /**
420 : * @brief Name of the subtree to be loaded
421 : *
422 : * If NULL, all values would be loaded.
423 : */
424 1 : const char *subtree;
425 : /**
426 : * @brief Pointer to the callback function.
427 : *
428 : * If NULL then matching registered function would be used.
429 : */
430 1 : settings_load_direct_cb cb;
431 : /**
432 : * @brief Parameter for callback function
433 : *
434 : * Parameter to be passed to the callback function.
435 : */
436 1 : void *param;
437 : };
438 :
439 : /**
440 : * Backend handler functions.
441 : * Sources are registered using a call to @ref settings_src_register.
442 : * Destinations are registered using a call to @ref settings_dst_register.
443 : */
444 1 : struct settings_store_itf {
445 1 : int (*csi_load)(struct settings_store *cs,
446 : const struct settings_load_arg *arg);
447 : /**< Loads values from storage limited to subtree defined by subtree.
448 : *
449 : * Parameters:
450 : * - cs - Corresponding backend handler node,
451 : * - arg - Structure that holds additional data for data loading.
452 : *
453 : * @note
454 : * Backend is expected not to provide duplicates of the entities.
455 : * It means that if the backend does not contain any functionality to
456 : * really delete old keys, it has to filter out old entities and call
457 : * load callback only on the final entity.
458 : */
459 :
460 1 : int (*csi_save_start)(struct settings_store *cs);
461 : /**< Handler called before an export operation.
462 : *
463 : * Parameters:
464 : * - cs - Corresponding backend handler node
465 : */
466 :
467 1 : int (*csi_save)(struct settings_store *cs, const char *name,
468 : const char *value, size_t val_len);
469 : /**< Save a single key-value pair to storage.
470 : *
471 : * Parameters:
472 : * - cs - Corresponding backend handler node
473 : * - name - Key in string format
474 : * - value - Binary value
475 : * - val_len - Length of value in bytes.
476 : */
477 :
478 1 : int (*csi_save_end)(struct settings_store *cs);
479 : /**< Handler called after an export operation.
480 : *
481 : * Parameters:
482 : * - cs - Corresponding backend handler node
483 : */
484 :
485 : /**< Get pointer to the storage instance used by the backend.
486 : *
487 : * Parameters:
488 : * - cs - Corresponding backend handler node
489 : */
490 0 : void *(*csi_storage_get)(struct settings_store *cs);
491 : };
492 :
493 : /**
494 : * Register a backend handler acting as source.
495 : *
496 : * @param cs Backend handler node containing handler information.
497 : *
498 : */
499 1 : void settings_src_register(struct settings_store *cs);
500 :
501 : /**
502 : * Register a backend handler acting as destination.
503 : *
504 : * @param cs Backend handler node containing handler information.
505 : *
506 : */
507 1 : void settings_dst_register(struct settings_store *cs);
508 :
509 :
510 : /*
511 : * API for handler lookup
512 : */
513 :
514 : /**
515 : * Parses a key to an array of elements and locate corresponding module handler.
516 : *
517 : * @param[in] name in string format
518 : * @param[out] next remaining of name after matched handler
519 : *
520 : * @return settings_handler_static on success, NULL on failure.
521 : */
522 1 : struct settings_handler_static *settings_parse_and_lookup(const char *name,
523 : const char **next);
524 :
525 : /**
526 : * Calls settings handler.
527 : *
528 : * @param[in] name The name of the data found in the backend.
529 : * @param[in] len The size of the data found in the backend.
530 : * @param[in] read_cb Function provided to read the data from
531 : * the backend.
532 : * @param[in,out] read_cb_arg Arguments for the read function provided by
533 : * the backend.
534 : * @param[in,out] load_arg Arguments for data loading.
535 : *
536 : * @return 0 or negative error code
537 : */
538 1 : int settings_call_set_handler(const char *name,
539 : size_t len,
540 : settings_read_cb read_cb,
541 : void *read_cb_arg,
542 : const struct settings_load_arg *load_arg);
543 : /**
544 : * @}
545 : */
546 :
547 : /**
548 : * @defgroup settings_name_proc Settings name processing
549 : * @brief API for const name processing
550 : * @ingroup settings
551 : * @{
552 : */
553 :
554 : /**
555 : * Compares the start of name with a key
556 : *
557 : * @param[in] name in string format
558 : * @param[in] key comparison string
559 : * @param[out] next pointer to remaining of name, when the remaining part
560 : * starts with a separator the separator is removed from next
561 : *
562 : * Some examples:
563 : * settings_name_steq("bt/btmesh/iv", "b", &next) returns 1, next="t/btmesh/iv"
564 : * settings_name_steq("bt/btmesh/iv", "bt", &next) returns 1, next="btmesh/iv"
565 : * settings_name_steq("bt/btmesh/iv", "bt/", &next) returns 0, next=NULL
566 : * settings_name_steq("bt/btmesh/iv", "bta", &next) returns 0, next=NULL
567 : *
568 : * REMARK: This routine could be simplified if the settings_handler names
569 : * would include a separator at the end.
570 : *
571 : * @return 0: no match
572 : * 1: match, next can be used to check if match is full
573 : */
574 1 : int settings_name_steq(const char *name, const char *key, const char **next);
575 :
576 : /**
577 : * determine the number of characters before the first separator
578 : *
579 : * @param[in] name in string format
580 : * @param[out] next pointer to remaining of name (excluding separator)
581 : *
582 : * @return index of the first separator, in case no separator was found this
583 : * is the size of name
584 : *
585 : */
586 1 : int settings_name_next(const char *name, const char **next);
587 : /**
588 : * @}
589 : */
590 :
591 : #ifdef CONFIG_SETTINGS_RUNTIME
592 :
593 : /**
594 : * @defgroup settings_rt Settings subsystem runtime
595 : * @brief API for runtime settings
596 : * @ingroup settings
597 : * @{
598 : */
599 :
600 : /**
601 : * Set a value with a specific key to a module handler.
602 : *
603 : * @param name Key in string format.
604 : * @param data Binary value.
605 : * @param len Value length in bytes.
606 : *
607 : * @return 0 on success, non-zero on failure.
608 : */
609 1 : int settings_runtime_set(const char *name, const void *data, size_t len);
610 :
611 : /**
612 : * Get a value corresponding to a key from a module handler.
613 : *
614 : * @param name Key in string format.
615 : * @param data Returned binary value.
616 : * @param len requested value length in bytes.
617 : *
618 : * @return length of data read on success, negative on failure.
619 : */
620 1 : int settings_runtime_get(const char *name, void *data, size_t len);
621 :
622 : /**
623 : * Apply settings in a module handler.
624 : *
625 : * @param name Key in string format.
626 : *
627 : * @return 0 on success, non-zero on failure.
628 : */
629 1 : int settings_runtime_commit(const char *name);
630 : /**
631 : * @}
632 : */
633 :
634 : #endif /* CONFIG_SETTINGS_RUNTIME */
635 :
636 : /**
637 : * Get the storage instance used by zephyr.
638 : *
639 : * The type of storage object instance depends on the settings backend used.
640 : * It might pointer to: `struct nvs_fs`, `struct fcb` or string witch file name
641 : * depends on settings backend type used.
642 : *
643 : * @retval Pointer to which reference to the storage object can be stored.
644 : *
645 : * @retval 0 on success, negative error code on failure.
646 : */
647 1 : int settings_storage_get(void **storage);
648 :
649 : #ifdef __cplusplus
650 : }
651 : #endif
652 :
653 : #endif /* ZEPHYR_INCLUDE_SETTINGS_SETTINGS_H_ */
|