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