Example #1
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;
}
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;
    }
}
Example #3
0
// Function for deleting all data beloning to a peer.
// These operations will be sent to FDS one at a time.
static void peer_data_delete()
{
    ret_code_t        ret;
    pm_peer_id_t      peer_id;
    uint16_t          file_id;
    fds_record_desc_t desc;
    fds_find_token_t  ftok;

    memset(&ftok, 0x00, sizeof(fds_find_token_t));
    peer_id = peer_id_get_next_deleted(PM_PEER_ID_INVALID);

    while (    (peer_id != PM_PEER_ID_INVALID)
            && (fds_record_find_in_file(peer_id_to_file_id(peer_id), &desc, &ftok)
            == FDS_ERR_NOT_FOUND))
    {
        peer_id_free(peer_id);
        peer_id = peer_id_get_next_deleted(peer_id);
    }

    if (!m_peer_delete_ongoing && (peer_id != PM_PEER_ID_INVALID))
    {
        m_peer_delete_ongoing = true;

        file_id = peer_id_to_file_id(peer_id);
        ret     = fds_file_delete(file_id);

        if (ret == FDS_ERR_NO_SPACE_IN_QUEUES)
        {
            m_peer_delete_queued = true;
        }
        else if (ret != NRF_SUCCESS)
        {
            m_peer_delete_ongoing = false;

            pds_evt_t pds_evt;

            pds_evt.evt_id      = PDS_EVT_ERROR_UNEXPECTED;
            pds_evt.peer_id     = peer_id;
            pds_evt.data_id     = PM_PEER_DATA_ID_INVALID;
            pds_evt.store_token = PM_STORE_TOKEN_INVALID;
            pds_evt.result      = ret;

            pds_evt_send(&pds_evt);
        }
    }
}
// Function for clearing all peer data of one peer.
// These operations will be sent to FDS one at a time.
static void peer_data_clear()
{
    ret_code_t        retval;
    uint16_t          file_id;
    fds_record_desc_t desc;
    fds_find_token_t  token   = {0};
    pm_peer_id_t      peer_id = peer_id_get_next_deleted(PM_PEER_ID_INVALID);

    while (    (peer_id != PM_PEER_ID_INVALID)
            && (fds_record_find_in_file(peer_id_to_file_id(peer_id), &desc, &token)
            == FDS_ERR_NOT_FOUND))
    {
        peer_id_free(peer_id);
        peer_id = peer_id_get_next_deleted(peer_id);
    }

    if (!m_pds.clearing && (peer_id != PM_PEER_ID_INVALID))
    {
        file_id = peer_id_to_file_id(peer_id);
        retval  = fds_file_delete(file_id);

        if (retval == FDS_SUCCESS)
        {
            m_pds.clearing = true;
        }
        else if (retval == FDS_ERR_NO_SPACE_IN_QUEUES)
        {
            m_pds.clear_queued = true;
        }
        else
        {
            pds_evt_t pds_evt;

            pds_evt.evt_id      = PDS_EVT_ERROR_UNEXPECTED;
            pds_evt.peer_id     = peer_id;
            pds_evt.data_id     = PM_PEER_DATA_ID_INVALID;
            pds_evt.store_token = PM_STORE_TOKEN_INVALID;
            pds_evt.result      = retval;

            pds_evt_send(&pds_evt);
        }
    }
}
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;
    }
}
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);
}
Example #7
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;
    }
}