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