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