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