static void peer_ids_init()
{
    fds_record_desc_t  record_desc;
    fds_flash_record_t record;
    fds_find_token_t   find_tok = {0};

    uint16_t const record_key = peer_data_id_to_record_key(PM_PEER_DATA_ID_BONDING);

    if (!m_pds.peer_ids_initialized)
    {
        while(fds_record_find_by_key(record_key, &record_desc, &find_tok) == FDS_SUCCESS)
        {
            pm_peer_id_t peer_id;

            // It is safe to ignore the return value since we just obtained
            // this descriptor and also 'record' is different from NULL.
            (void)fds_record_open(&record_desc, &record);
            peer_id = file_id_to_peer_id(record.p_header->ic.file_id);
            (void)fds_record_close(&record_desc);

            (void)peer_id_allocate(peer_id);
        }

        m_pds.peer_ids_initialized = true;
    }
}
ret_code_t pds_peer_data_read_ptr_get(pm_peer_id_t            peer_id,
                                      pm_peer_data_id_t       data_id,
                                      pm_peer_data_flash_t  * p_data,
                                      pm_store_token_t      * p_token)
{
    ret_code_t retval;

    fds_flash_record_t record;
    fds_record_desc_t  record_desc;

    VERIFY_MODULE_INITIALIZED();
    VERIFY_PEER_ID_IN_RANGE(peer_id);
    VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
    VERIFY_PARAM_NOT_NULL(p_data);

    retval = find_fds_item(peer_id, data_id, &record_desc);
    if (retval != FDS_SUCCESS)
    {
        return NRF_ERROR_NOT_FOUND;
    }

    // Shouldn't fail, unless the record was deleted.
    (void)fds_record_open(&record_desc, &record);

    if (p_data != NULL)
    {
        p_data->data_id      = data_id;
        p_data->length_words = record.p_header->tl.length_words;
        p_data->p_all_data   = record.p_data;
    }

    if (p_token != NULL)
    {
        *p_token = (uint32_t)record.p_header->record_id;
    }

    // Shouldn't fail, unless the record was already closed.
    (void)fds_record_close(&record_desc);

    return NRF_SUCCESS;
}
bool pds_peer_data_iterate(pm_peer_data_id_t            data_id,
                           pm_peer_id_t         * const p_peer_id,
                           pm_peer_data_flash_t * const p_data)
{
    ret_code_t         ret;
    uint16_t           rec_key;
    fds_record_desc_t  rec_desc;
    fds_flash_record_t rec_flash;

    NRF_PM_DEBUG_CHECK(m_module_initialized);
    NRF_PM_DEBUG_CHECK(p_peer_id != NULL);
    NRF_PM_DEBUG_CHECK(p_data    != NULL);

    // @note emdi: should we check the data_id ?
    rec_key = peer_data_id_to_record_key(data_id);

    if (fds_record_find_by_key(rec_key, &rec_desc, &m_fds_ftok) != NRF_SUCCESS)
    {
        return false;
    }

    ret = fds_record_open(&rec_desc, &rec_flash);

    if (ret != NRF_SUCCESS)
    {
        // It can only happen if the record was deleted after the call to fds_record_find_by_key(),
        // before we could open it, or if CRC support was enabled in Flash Data Storage at compile
        // time and the CRC check failed.
        return false;
    }

    p_data->data_id      = data_id;
    p_data->length_words = rec_flash.p_header->tl.length_words;
    p_data->p_all_data   = rec_flash.p_data;

    *p_peer_id           = file_id_to_peer_id(rec_flash.p_header->ic.file_id);

    (void)fds_record_close(&rec_desc);

    return true;
}
static void peer_ids_load()
{
    fds_record_desc_t  record_desc;
    fds_flash_record_t record;
    fds_find_token_t   ftok;

    memset(&ftok, 0x00, sizeof(fds_find_token_t));

    uint16_t const record_key = peer_data_id_to_record_key(PM_PEER_DATA_ID_BONDING);

    while (fds_record_find_by_key(record_key, &record_desc, &ftok) == FDS_SUCCESS)
    {
        pm_peer_id_t peer_id;

        // It is safe to ignore the return value since the descriptor was
        // just obtained and also 'record' is different from NULL.
        (void)fds_record_open(&record_desc, &record);
        peer_id = file_id_to_peer_id(record.p_header->ic.file_id);
        (void)fds_record_close(&record_desc);

        (void)peer_id_allocate(peer_id);
    }
}
ret_code_t pds_peer_data_read(pm_peer_id_t                    peer_id,
                              pm_peer_data_id_t               data_id,
                              pm_peer_data_t          * const p_data,
                              uint32_t          const * const p_buf_len)
{
    ret_code_t         ret;
    fds_record_desc_t  rec_desc;
    fds_flash_record_t rec_flash;

    NRF_PM_DEBUG_CHECK(m_module_initialized);
    NRF_PM_DEBUG_CHECK(p_data != NULL);

    VERIFY_PEER_ID_IN_RANGE(peer_id);
    VERIFY_PEER_DATA_ID_IN_RANGE(data_id);

    ret = peer_data_find(peer_id, data_id, &rec_desc);

    if (ret != NRF_SUCCESS)
    {
        return NRF_ERROR_NOT_FOUND;
    }

    // Shouldn't fail, unless the record was deleted in the meanwhile or the CRC check has failed.
    ret = fds_record_open(&rec_desc, &rec_flash);

    if (ret != NRF_SUCCESS)
    {
        return NRF_ERROR_NOT_FOUND;
    }

    // @note emdi: could this actually be set by the caller and used instead
    // of an additional parameter (data_id) ?
    p_data->data_id      = data_id;
    p_data->length_words = rec_flash.p_header->tl.length_words;

    // If p_buf_len is NULL, provide a pointer to data in flash, otherwise,
    // check that the buffer is large enough and copy the data in flash into the buffer.
    if (p_buf_len != NULL)
    {
        uint32_t const data_len_bytes = (p_data->length_words * sizeof(uint32_t));

        if ((*p_buf_len) <= data_len_bytes)
        {
            memcpy(p_data->p_all_data, rec_flash.p_data, data_len_bytes);
        }
        else
        {
            return NRF_ERROR_NO_MEM;
        }
    }
    else
    {
        // The cast is necessary because if no buffer is provided, we just copy the pointer,
        // but it that case it should be considered a pointer to const data by the caller,
        // since it is a pointer to data in flash.
        p_data->p_all_data = (void*)rec_flash.p_data;
    }

    // Shouldn't fail unless the record was already closed, in which case it can be ignored.
    (void)fds_record_close(&rec_desc);

    return NRF_SUCCESS;
}