1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
|
/*
* Copyright (c) Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef FDS_H__
#define FDS_H__
/**
* @defgroup flash_data_storage Flash Data Storage
* @ingroup app_common
* @{
* @brief Flash Data Storage (FDS).
*
* @details Flash Data Storage (FDS) is a minimalistic filesystem for the on-chip flash.
* It can be used to manipulate @e records, which consist of a piece of data, made up
* of one or more chunks, and an associated key pair.
*/
#include <stdint.h>
#include <stdbool.h>
#include "sdk_errors.h"
/**@brief */
#define SIZEOF_WORDS(val) (sizeof(val) / 4)
/**@brief Reserved type key used to flag cleared records.
* May not be used as a record key by the application. */
#define FDS_TYPE_ID_INVALID (0x0000)
/**@brief Reserved instance key used to check for missing or corrupted metadata.
* May not be used as a record key by the application. */
#define FDS_INSTANCE_ID_INVALID (0xFFFF)
typedef uint32_t fds_record_id_t;
typedef uint16_t fds_type_id_t;
typedef uint16_t fds_length_t;
typedef uint16_t fds_instance_id_t;
typedef uint16_t fds_checksum_t;
/**@brief A piece of a record metadata, keeping information about one of its keys (type) and its
* lenght, expressed in 4 byte words. */
typedef struct
{
fds_type_id_t type; /**< The record type ID. */
fds_length_t length_words; /**< Length of the record's data, in 4 byte words. */
} fds_tl_t;
/**@brief A piece of a record metadata, keeping information about one of its keys (instance) and
* its checksum. */
typedef struct
{
fds_instance_id_t instance; /**< The record instance ID. */
fds_checksum_t checksum; /**< Checksum of the entire record, including the metadata. */
} fds_ic_t;
/**@brief The record metadata. */
typedef struct
{
fds_tl_t tl; /**< See @ref fds_tl_t. */
fds_ic_t ic; /**< See @ref fds_ic_t. */
fds_record_id_t id; /**< The unique record ID (32 bits). */
} fds_header_t;
typedef fds_header_t fds_record_header_t;
/**@brief The record descriptor structure, used to manipulate a record.
* @note This structure is meant to be opaque to the user, who does not need to access
* any of its fields.
* @note This structure does not need special initialization.
* @warning Do not reuse the same descriptor for different records. If you do, be sure to set
* its fields to zero. */
typedef struct
{
uint32_t record_id; /**< The unique record ID. */
uint32_t const * p_rec; /**< The last known record address in flash. */
uint16_t vpage_id; /**< The virtual page ID in which the record is stored. */
uint16_t gc_magic; /**< Number of times the GC algorithm has been run. */
uint16_t ptr_magic; /**< Used to verify the validity of p_rec. */
} fds_record_desc_t;
/**@brief The record key, used to lookup records.
* @note The uniqueness of either field is not enforced by the system. */
typedef struct
{
uint16_t type;
uint16_t instance;
} fds_record_key_t;
/**@brief Structure used for reading a record back from flash memory. */
typedef struct
{
// TODO: the header should be a pointer.
fds_header_t header; /**< The record header (metadata), as stored in flash. */
uint32_t const * p_data; /**< The record data. */
} fds_record_t;
/**@brief A record chunk, containing a piece of data to be stored in a record.
*
* @note p_data must be aligned on a (4 bytes) word boundary.
*/
typedef struct
{
void const * p_data; /**< Pointer to the data to store. Must be word aligned. */
fds_length_t length_words; /**< Length of data pointed by p_data, in 4 byte words. */
} fds_record_chunk_t;
/**@brief A token to a reserved space in flash, created by @ref fds_reserve.
* Use @ref fds_write_reserved to write the record in the reserved space,
* or @ref fds_reserve_cancel to cancel the reservation.
*/
typedef struct
{
uint16_t vpage_id; /**< The virtual ID of the page where space was reserved. */
fds_length_t length_words; /**< The amount of space reserved, in 4 byte words. */
} fds_write_token_t;
/**@brief A token to keep information about the progress of @ref fds_find, @ref fds_find_by_type
* and @ref fds_find_by_instance operations.
* @note This structure is meant to be opaque to the user, who does not need to access any of its
* fields.
* @note The token does not need special initialization.
* @warning Do not reuse the same token to search for different records. If you do, be sure to set
* its fields to zero. */
typedef struct
{
uint32_t const * p_addr;
uint32_t magic;
uint16_t vpage_id;
} fds_find_token_t;
typedef enum
{
FDS_CMD_NONE, /**< No command. */
FDS_CMD_INIT, /**< Module initialization commnad. Used in @ref fds_init */
FDS_CMD_WRITE, /**< Write command. Used in @ref fds_write and @ref fds_write_reserved. */
FDS_CMD_UPDATE, /**< Update command. Used in @ref fds_update. */
FDS_CMD_CLEAR, /**< Clear record command. Used in @ref fds_clear and @ref fds_update. */
FDS_CMD_CLEAR_INST, /**< Clear instance command. Used in @ref fds_clear_by_instance. */
FDS_CMD_GC /**< Garbage collection. Used in @ref fds_gc. */
} fds_cmd_id_t;
/**@brief Flash data storage callback function.
*
* @param result Result of the command.
* @param cmd The command associated with the callback.
* @param record_id The unique ID of the record associated with the callback.
* @param record_key The key pair of the record associated with the callback.
*/
typedef void (*fds_cb_t)(ret_code_t result,
fds_cmd_id_t cmd,
fds_record_id_t record_id,
fds_record_key_t record_key);
/**@brief Function to register a callback for the module events.
* @details The maximum amount of callback which can be registered can be configured by
* changing the FDS_MAX_USERS macro in fds_config.h.
*
* @param[in] cb The callback function.
*
*
* @retval NRF_SUCCESS Success.
* @retval NRF_ERROR_NO_MEM Error. Maximum number of registered callbacks reached.
*/
ret_code_t fds_register(fds_cb_t cb);
/**@brief Function to initialize the module.
*
* @details This function initializes the module and installs the filesystem, if it is not
* installed yet.
*
* @note This function is asynchronous. Completion is reported with a callback through the
* registered event handler. To be able to receive such callback, be sure to call
* @ref fds_register before calling @ref fds_init.
*
* @retval NRF_SUCCESS Success. The command was queued.
* @retval NRF_ERROR_INVALID_STATE Error. The module is currently undergoing initialization.
* @retval NRF_ERROR_NO_MEM Error. Insufficient space to install the filesystem, or
* insufficient resources to perform the installation.
*/
ret_code_t fds_init(void);
/**@brief Function to write a record to flash.
*
* @details This function can be used to write a record to flash. A record data consists of
* multiple chunks and is supplied to the function as an array of fds_record_chunk_t
* structures. The maximum lenght of a record data may not exceed the size of one flash
* page minus FDS_HEADER_SIZE words.
*
* @note This function is asynchronous, therefore, completion is reported with a callback
* through the registered event handler.
*
* @note The record data must be aligned on a 4 byte boundary, and because it is not buffered
* internally, it must be kept in memory by the application until the callback for the
* command has been received, i.e., the command completed.
*
* @param[out] p_desc The record descriptor. It may be NULL.
* @param[in] key The record key pair.
* @param[in] num_chunks The number of elements in the chunks array.
* @param[in] chunks An array of chunks making up the record data.
*
* @retval NRF_SUCCESS Success. The command was queued.
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
* @retval NRF_ERROR_INVALID_DATA Error. The key contains an invalid type or instance.
* @retval NRF_ERROR_INVALID_ADDR Error. The record data is not aligned on a 4 byte boundary.
* @retval NRF_ERROR_INVALID_LENGTH Error. The record length exceeds the maximum lenght.
* @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation.
* @retval NRF_ERROR_NO_MEM Error. No flash space available to store the record.
*/
ret_code_t fds_write(fds_record_desc_t * const p_desc,
fds_record_key_t key,
uint8_t num_chunks,
fds_record_chunk_t chunks[]);
/**@brief Function to reserve space for a record.
*
* @details This function can be used to reserve flash space to store a record, which can be
* later written down using @ref fds_write_reserved. It is possible to cancel a
* reservation by using @ref fds_reserve_cancel.
*
* @param[out] p_tok A token which can be used to write a record in the reserved space
* using @ref fds_write_reserved.
* @param[in] length_words The lenght of the record data, in 4 byte words.
*
* @retval NRF_SUCCESS Success. Flash space was successfully reserved.
* @retval NRF_ERROR_NULL Error. p_tok is NULL.
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
* @retval NRF_ERROR_NO_MEM Error. Insufficient space.
*/
ret_code_t fds_reserve(fds_write_token_t * const p_tok, uint16_t length_words);
/**@brief Function to cancel a space reservation.
*
* @param[in] p_tok The token produced by @ref fds_reserve, identifying the reservation to cancel.
*
* @retval NRF_SUCCESS Success. The reservation was canceled.
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
* @retval NRF_ERROR_NULL Error. p_tok is NULL.
* @retval NRF_ERROR_INVALID_DATA Error. p_tok contains invalid data.
*/
ret_code_t fds_reserve_cancel(fds_write_token_t * const p_tok);
/**@brief Function to write a record to flash, the space for which has been previously reserved
* using @ref fds_reserve.
*
* @details This function behaves similarly to @ref fds_write, with the exception that it never
* fails with NRF_ERROR_NO_MEM.
*
* @note This function is asynchronous, therefore, completion is reported with a callback
* through the registered event handler.
*
* @note The record data must be aligned on a 4 byte boundary, and because it is not buffered
* internally, it must be kept in memory by the application until the callback for the
* command has been received, i.e., the command completed.
*
* @param[in] p_tok The token return by @ref fds_reserve.
* @param[out] p_desc The record descriptor. It may be NULL.
* @param[in] key The record key pair.
* @param[in] num_chunks The number of elements in the chunks array.
* @param[in] chunks An array of chunks making up the record data.
*
* @retval NRF_SUCCESS Success. The command was queued.
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
* @retval NRF_ERROR_INVALID_DATA Error. The key contains an invalid type or instance.
* @retval NRF_ERROR_INVALID_ADDR Error. The record data is not aligned on a 4 byte boundary.
* @retval NRF_ERROR_INVALID_LENGTH Error. The record length exceeds the maximum lenght.
* @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation.
*/
ret_code_t fds_write_reserved(fds_write_token_t const * const p_tok,
fds_record_desc_t * const p_desc,
fds_record_key_t key,
uint8_t num_chunks,
fds_record_chunk_t chunks[]);
/**@brief Function to clear a record.
*
* @details Clearing a record has the effect of preventing the system from retrieving the record
* descriptor using the @ref fds_find, @ref fds_find_by_type and @ref fds_find_by_instance
* functions. Additionally, @ref fds_open calls shall fail when supplied a descritpor for
* a record which has been cleared. Clearing a record does not free the space it occupies
* in flash. The reclaim flash space used by cleared records, use @ref fds_gc.
*
* @note This function is asynchronous, therefore, completion is reported with a callback
* through the registered event handler.
*
* @param[in] p_desc The descriptor of the record to clear.
*
* @retval NRF_SUCCESS Success. The command was queued.
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
* @retval NRF_ERROR_NULL Error. p_desc is NULL.
* @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation.
*/
ret_code_t fds_clear(fds_record_desc_t * const p_desc);
/**@brief Function to clear all records with a given instance.
*
* @details Clearing a record has the effect of preventing the system from retrieving the record
* descriptor using the @ref fds_find, @ref fds_find_by_type and @ref fds_find_by_instance
* functions. Additionally, @ref fds_open calls shall fail when supplied a descritpor for
* a record which has been cleared. Clearing a record does not free the space it occupies
* in flash. The reclaim flash space used by cleared records, use @ref fds_gc.
*
* @note This function is asynchronous, therefore, completion is reported with a callback
* through the registered event handler. Only one callback will be issued. The record
* instance ID in the key parameter of the callback will contain the instance ID passed as
* parameter to this function. The record ID parameter will be zero, and the type ID equal
* to FDS_TYPE_ID_INVALID.
*
* @param[in] instance The instance ID of the records to clear.
*
* @retval NRF_SUCCESS Success. The command was queued.
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
* @retval NRF_ERROR_NULL Error. p_desc is NULL.
* @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation.
*/
ret_code_t fds_clear_by_instance(fds_instance_id_t instance);
/**@brief Function to update an existing record.
*
* @details Updating a record writes a new record with the given key and data in flash, and then
* clears the old record.
*
* @note This function is asynchronous, therefore, completion is reported with a callback
* through the registered event handler. Two callbacks will be issued, one to signal that
* the updated record has been written down, and another to signal that the old one has been
* cleared.
*
* @note The record data must be aligned on a 4 byte boundary, and because it is not buffered
* internally, it must be kept in memory by the application until the callback for the
* command has been received, i.e., the command completed.
*
* @param[in, out] p_desc The descriptor of the record to update. The descriptor of the updated
* record, after the function has returned with NRF_SUCCESS.
* @param[in] key The record new key pair.
* @param[in] num_chunks The number of elements in the chunks array.
* @param[in] chunks An array of chunks making up the record new data.
*
* @retval NRF_SUCCESS Success. The command was queued.
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
* @retval NRF_ERROR_INVALID_DATA Error. The key contains an invalid type or instance.
* @retval NRF_ERROR_INVALID_ADDR Error. The record data is not aligned on a 4 byte boundary.
* @retval NRF_ERROR_INVALID_LENGTH Error. The record length exceeds the maximum lenght.
* @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation.
* @retval NRF_ERROR_NO_MEM Error. No flash space available to store the record.
*/
ret_code_t fds_update(fds_record_desc_t * const p_desc,
fds_record_key_t key,
uint8_t num_chunks,
fds_record_chunk_t chunks[]);
/**@brief Function to search for records with a given key pair.
*
* @details Because types are not unique, to search for the next record with the given key call
* the function again and supply the same fds_find_token_t structure to resume searching
* from the last record found.
*
* @param[in] type The record type ID.
* @param[in] instance The record instance ID.
* @param[out] p_desc The descriptor of the record found.
* @param[out] p_token A token containing information about the progress of the operation.
*
* @retval NRF_SUCCESS Success. A record was found.
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
* @retval NRF_ERROR_NULL Error. Either p_desc or p_token are NULL.
* @retval NRF_ERROR_NOT_FOUND Error. No record with the given key pair was found.
*/
ret_code_t fds_find(fds_type_id_t type,
fds_instance_id_t instance,
fds_record_desc_t * const p_desc,
fds_find_token_t * const p_token);
/**@brief Function to search for records with a given type.
*
* @details Because types are not unique, to search for the next record with the given key call
* the function again and supply the same fds_find_token_t structure to resume searching
* from the last record found.
*
* @param[in] type The type ID in the record key.
* @param[out] p_desc The descriptor of the record found.
* @param[out] p_token A token containing information about the progress of the operation.
*
* @retval NRF_SUCCESS Success. A record was found.
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
* @retval NRF_ERROR_NULL Error. Either p_desc or p_token are NULL.
* @retval NRF_ERROR_NOT_FOUND Error. No record with the given type was found.
*/
ret_code_t fds_find_by_type(fds_type_id_t type,
fds_record_desc_t * const p_desc,
fds_find_token_t * const p_token);
/**@brief Function to search for records with a given instance.
*
* @details Because types are not unique, to search for the next record with the given key call
* the function again and supply the same fds_find_token_t structure to resume searching
* from the last record found.
*
* @param[in] instance The instance ID in the record key.
* @param[out] p_desc The descriptor of the record found.
* @param[out] p_token A token containing information about the progress of the operation.
*
* @retval NRF_SUCCESS Success. A record was found.
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
* @retval NRF_ERROR_NULL Error. Either p_desc or p_token are NULL.
* @retval NRF_ERROR_NOT_FOUND Error. No record with the given instance was found.
*/
ret_code_t fds_find_by_instance(fds_instance_id_t instance,
fds_record_desc_t * const p_desc,
fds_find_token_t * const p_token);
/**@brief Function to open a record for reading.
*
* @details Function to read a record which has been written to flash. This function initializes
* a fds_record_t structure which can be used to access the record data as well as
* its associated metadata. The pointers provided in the fds_record_t structure are
* pointers to flash memory. Opening a record with @ref fds_open prevents the garbage
* collection to run on the flash page in which record is stored, therefore the contents
* of the memory pointed by the fds_record_t p_data field is guaranteed to remain
* unmodified, as long as the record is kept open.
*
* @note When you are done reading a record, close it using @ref fds_close so that successive
* garbage collections can reclaim space on the page where the record is stored, if necessary.
*
* @param[in] p_desc The descriptor of the record to open.
* @param[out] p_record The record data and metadata, as stored in flash.
*
* @retval NRF_SUCCESS Success. The record was opened.
* @retval NRF_ERROR_NOT_FOUND Error. The record was not found. It may have been cleared, or it
* may have not been written yet.
* @retval NRF_ERROR_INVALID_DATA Error. The descriptor contains invalid data.
* @retval NRF_ERROR_NULL Error. Either p_desc or p_record are NULL.
*/
ret_code_t fds_open(fds_record_desc_t * const p_desc,
fds_record_t * const p_record);
/**@brief Function to close a record, after its contents have been read.
*
* @details Closing a record allows garbage collection to be run on the page in which the
* record being closed is stored (if no other records remain open on that page).
*
* @note Closing a record, does NOT invalidate its descriptor, which can be safely supplied to
* all functions which accept a descriptor as a parameter.
*
* @param[in] p_desc The descriptor of the record to close.
*
* @retval NRF_SUCCESS Success. The record was closed.
* @retval NRF_ERROR_NULL Error. p_desc is NULL.
* @retval NRF_ERROR_INVALID_DATA Error. The descriptor contains invalid data.
*/
ret_code_t fds_close(fds_record_desc_t const * const p_desc);
/**@brief Function to perform a garbage collection.
*
* @details Garbage collection reclaims the flash space occupied by records which have been cleared
* using @ref fds_clear.
*
* @note This function is asynchronous, therefore, completion is reported with a callback
* through the registered event handler.
*/
ret_code_t fds_gc(void);
/**@brief Function to compare two record descriptors.
*
* @param[in] p_desc_one First descriptor.
* @param[in] p_desc_two Second descriptor.
*
* @retval true If the descriptors identify the same record.
* @retval false Otherwise.
*/
bool fds_descriptor_match(fds_record_desc_t const * const p_desc_one,
fds_record_desc_t const * const p_desc_two);
/**@brief Function to obtain a descriptor from a record ID.
*
* @details This function can be used to reconstruct a descriptor from a record ID, such as the
* one passed to the callback function.
*
* @warning This function does not check if a record with the given record ID exists or not. If a
* non-existing record ID is supplied, the resulting descriptor will cause other functions
* to fail when used as parameter.
*
* @param[out] p_desc The descriptor of the record with given record ID.
* @param[in] record_id The record ID for which to provide a descriptor.
*
* @retval NRF_SUCCESS Success.
* @retval NRF_ERROR_NULL Error. p_desc is NULL.
*/
ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc,
fds_record_id_t record_id);
/**@brief Function to obtain a record ID from a record descriptor.
*
* @details This function can be used to extract a record ID from a descriptor. It may be used
* in the callback function to determine which record the callback is associated to, if
* you have its descriptor.
*
* @warning This function does not check the record descriptor sanity. If the descriptor is
* uninitialized, or has been tampered with, the resulting record ID may be invalid.
*
* @param[in] p_desc The descriptor from which to extract the record ID.
* @param[out] p_record_id The record ID contained in the given descriptor.
*
* @retval NRF_SUCCESS Success.
* @retval NRF_ERROR_NULL Error. Either p_desc is NULL or p_record_id is NULL.
*/
ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc,
fds_record_id_t * const p_record_id);
/** @} */
#endif // FDS_H__
|