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