示例#1
0
// @note emdi: unused..
ret_code_t pds_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
{
    ret_code_t        ret;
    fds_record_desc_t record_desc;

    NRF_PM_DEBUG_CHECK(m_module_initialized);

    VERIFY_PEER_ID_IN_RANGE(peer_id);
    VERIFY_PEER_DATA_ID_IN_RANGE(data_id);

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

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

    ret = fds_record_delete(&record_desc);

    switch (ret)
    {
        case FDS_SUCCESS:
            return NRF_SUCCESS;

        case FDS_ERR_NO_SPACE_IN_QUEUES:
            return NRF_ERROR_BUSY;

        default:
            return NRF_ERROR_INTERNAL;
    }
}
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;
    }
}
ret_code_t pds_peer_data_read(pm_peer_id_t        peer_id,
                              pm_peer_data_id_t   data_id,
                              pm_peer_data_t    * p_data,
                              uint16_t          * p_len_words)
{
    ret_code_t           retval;
    pm_peer_data_flash_t peer_data_flash;

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

    retval = pds_peer_data_read_ptr_get(peer_id, data_id, &peer_data_flash, NULL);
    if (retval != NRF_SUCCESS)
    {
        return retval;
    }

    if ((*p_len_words) == 0)
    {
        (*p_len_words) = peer_data_flash.length_words;
        return NRF_SUCCESS;
    }
    else if ((*p_len_words) < peer_data_flash.length_words)
    {
        return NRF_ERROR_NO_MEM;
    }

    VERIFY_PARAM_NOT_NULL(p_data->p_all_data);

    retval = peer_data_deserialize(&peer_data_flash, p_data);

    return retval;
}
示例#4
0
ret_code_t pds_peer_id_free(pm_peer_id_t peer_id)
{
    NRF_PM_DEBUG_CHECK(m_module_initialized);
    VERIFY_PEER_ID_IN_RANGE(peer_id);

    (void)peer_id_delete(peer_id);
    peer_data_delete();

    return NRF_SUCCESS;
}
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;
    }
}
ret_code_t pds_peer_id_free(pm_peer_id_t peer_id)
{
    VERIFY_MODULE_INITIALIZED();
    VERIFY_PEER_ID_IN_RANGE(peer_id);
    PEER_IDS_INITIALIZE();

    (void)peer_id_delete(peer_id);
    peer_data_clear();

    return NRF_SUCCESS;
}
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);
}
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;
}
示例#9
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;
    }
}
示例#10
0
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;
}