ret_code_t pds_peer_data_write(pm_peer_id_t                 peer_id,
                               pm_peer_data_const_t const * p_peer_data,
                               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;

    retval = fds_record_write(&record_desc, &record);

    if ((retval == FDS_SUCCESS) && (p_store_token != NULL))
    {
        // If fds_record_write() 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;
    }
}
Example #2
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;
    }
}