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