1 /*
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 #define SETTINGS_MAX_DIR_DEPTH	8	/* max depth of settings tree */
38 #define SETTINGS_MAX_NAME_LEN	(8 * SETTINGS_MAX_DIR_DEPTH)
39 #define SETTINGS_MAX_VAL_LEN	256
40 #define SETTINGS_NAME_SEPARATOR	'/'
41 #define SETTINGS_NAME_END '='
42 
43 /* place for settings additions:
44  * up to 7 separators, '=', '\0'
45  */
46 #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 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 struct settings_handler {
69 
70 	const char *name;
71 	/**< Name of subtree. */
72 
73 	int cprio;
74 	/**< Priority of commit, lower value is higher priority */
75 
76 	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 	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 	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 	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 	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 struct settings_handler_static {
138 
139 	const char *name;
140 	/**< Name of subtree. */
141 
142 	int cprio;
143 	/**< Priority of commit, lower value is higher priority */
144 
145 	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 	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 	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 	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 						  _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 				       _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 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 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 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 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 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 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 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 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 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 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 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 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 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 struct settings_store {
407 	sys_snode_t cs_next;
408 	/**< Linked list node info for internal usage. */
409 
410 	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 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 	const char *subtree;
425 	/**
426 	 * @brief Pointer to the callback function.
427 	 *
428 	 * If NULL then matching registered function would be used.
429 	 */
430 	settings_load_direct_cb cb;
431 	/**
432 	 * @brief Parameter for callback function
433 	 *
434 	 * Parameter to be passed to the callback function.
435 	 */
436 	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 struct settings_store_itf {
445 	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 	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 	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 	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 	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 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 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 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 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 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 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 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 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 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 int settings_storage_get(void **storage);
648 
649 #ifdef __cplusplus
650 }
651 #endif
652 
653 #endif /* ZEPHYR_INCLUDE_SETTINGS_SETTINGS_H_ */
654