Пример #1
0
ret_code_t pds_peer_data_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
{
    ret_code_t        retval;
    uint16_t          file_id;
    uint16_t          record_key;
    fds_record_desc_t record_desc;
    fds_find_token_t  find_tok = {0};

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

    file_id    = peer_id_to_file_id(peer_id);
    record_key = peer_data_id_to_record_key(data_id);

    retval = fds_record_find(file_id, record_key, &record_desc, &find_tok);
    if(retval != FDS_SUCCESS)
    {
        return NRF_ERROR_NOT_FOUND;
    }

    retval = fds_record_delete(&record_desc);

    switch (retval)
    {
        case FDS_SUCCESS:
            return NRF_SUCCESS;

        case FDS_ERR_NO_SPACE_IN_QUEUES:
            return NRF_ERROR_BUSY;

        default:
            return NRF_ERROR_INTERNAL;
    }
}
Пример #2
0
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;
    }
}
Пример #3
0
static ret_code_t peer_data_find(pm_peer_id_t              peer_id,
                                 pm_peer_data_id_t         data_id,
                                 fds_record_desc_t * const p_desc)
{
    ret_code_t       ret;
    fds_find_token_t ftok;

    NRF_PM_DEBUG_CHECK(peer_id < PM_PEER_ID_N_AVAILABLE_IDS);
    NRF_PM_DEBUG_CHECK(peer_data_id_is_valid(data_id));
    NRF_PM_DEBUG_CHECK(p_desc != NULL);

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

    uint16_t file_id    = peer_id_to_file_id(peer_id);
    uint16_t record_key = peer_data_id_to_record_key(data_id);

    ret = fds_record_find(file_id, record_key, p_desc, &ftok);

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

    return NRF_SUCCESS;
}
Пример #4
0
ret_code_t pds_peer_data_update(pm_peer_id_t                 peer_id,
                                pm_peer_data_const_t const * p_peer_data,
                                pm_store_token_t             old_token,
                                pm_store_token_t           * p_store_token)
{
    ret_code_t         retval;
    fds_record_t       record;
    fds_record_desc_t  record_desc;
    fds_record_chunk_t chunks[2];
    uint16_t           n_chunks;

    VERIFY_MODULE_INITIALIZED();
    VERIFY_PEER_ID_IN_RANGE(peer_id);
    VERIFY_PARAM_NOT_NULL(p_peer_data);
    VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id);

    // Create chunks.
    peer_data_parts_get(p_peer_data, chunks, &n_chunks);

    // Prepare the record to be written.
    record.file_id         = peer_id_to_file_id(peer_id);
    record.key             = peer_data_id_to_record_key(p_peer_data->data_id);
    record.data.p_chunks   = chunks;
    record.data.num_chunks = n_chunks;

    // Obtain the descriptor of the record to be updated.
    // It is safe to ignore the return value if record_desc is different from NULL.
    (void)fds_descriptor_from_rec_id(&record_desc, (uint32_t)old_token);

    retval = fds_record_update(&record_desc, &record);

    if ((retval == FDS_SUCCESS) && (p_store_token != NULL))
    {
        // If fds_record_update() returned sucessfully, it is safe
        // to ignore the return value from fds_record_id_from_desc() since
        // the descriptor is valid, and also p_store_token is different from NULL.
        (void)fds_record_id_from_desc(&record_desc, (uint32_t*)p_store_token);
    }

    switch (retval)
    {
        case FDS_SUCCESS:
            return NRF_SUCCESS;

        case FDS_ERR_BUSY:
        case FDS_ERR_NO_SPACE_IN_QUEUES:
            return NRF_ERROR_BUSY;

        case FDS_ERR_NO_SPACE_IN_FLASH:
            return NRF_ERROR_NO_MEM;

        default:
            return NRF_ERROR_INTERNAL;
    }
}
Пример #5
0
static ret_code_t find_fds_item(pm_peer_id_t              peer_id,
                                pm_peer_data_id_t         data_id,
                                fds_record_desc_t * const p_desc)
{
    fds_find_token_t find_tok = {0};

    VERIFY_PEER_ID_IN_RANGE(peer_id);
    VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
    // pp_record verified by caller.

    uint16_t file_id    = peer_id_to_file_id(peer_id);
    uint16_t record_key = peer_data_id_to_record_key(data_id);

    return fds_record_find(file_id, record_key, p_desc, &find_tok);
}
Пример #6
0
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;
}
Пример #7
0
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);
    }
}
Пример #8
0
ret_code_t pds_peer_data_store(pm_peer_id_t                 peer_id,
                               pm_peer_data_const_t const * p_peer_data,
                               pm_prepare_token_t           prepare_token,
                               pm_store_token_t           * p_store_token)
{
    ret_code_t         ret;
    fds_record_t       rec;
    fds_record_desc_t  rec_desc;
    fds_record_chunk_t rec_chunk;

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

    VERIFY_PEER_ID_IN_RANGE(peer_id);
    VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id);

    // Prepare chunk.
    rec_chunk.p_data       = p_peer_data->p_all_data;
    rec_chunk.length_words = p_peer_data->length_words;

    // Prepare the record to be stored in flash.
    rec.file_id         = peer_id_to_file_id(peer_id);
    rec.key             = peer_data_id_to_record_key(p_peer_data->data_id);
    rec.data.p_chunks   = &rec_chunk;
    rec.data.num_chunks = 1;

    ret = peer_data_find(peer_id, p_peer_data->data_id, &rec_desc);

    if (ret == NRF_ERROR_NOT_FOUND)
    {
        // No previous data exists in flash.
        if (prepare_token == PDS_PREPARE_TOKEN_INVALID)
        {
            // No space was previously reserved.
            ret = fds_record_write(&rec_desc, &rec);
        }
        else
        {
            // Space for this record was previously reserved.
            ret = fds_record_write_reserved(&rec_desc, &rec, (fds_reserve_token_t*)&prepare_token);
        }
    }
    else // NRF_SUCCESS
    {
        if (prepare_token != PDS_PREPARE_TOKEN_INVALID)
        {
            (void)fds_reserve_cancel((fds_reserve_token_t*)&prepare_token);
        }

        // Update existing record.
        ret = fds_record_update(&rec_desc, &rec);
    }

    switch (ret)
    {
        case FDS_SUCCESS:
            if (p_store_token != NULL)
            {
                // Update the store token.
                (void)fds_record_id_from_desc(&rec_desc, (uint32_t*)p_store_token);
            }
            return NRF_SUCCESS;

        case FDS_ERR_BUSY:
        case FDS_ERR_NO_SPACE_IN_QUEUES:
            return NRF_ERROR_BUSY;

        case FDS_ERR_NO_SPACE_IN_FLASH:
            return NRF_ERROR_STORAGE_FULL;

        default:
            return NRF_ERROR_INTERNAL;
    }
}