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