コード例 #1
0
ファイル: pm_buffer.c プロジェクト: CarrieTung/mbed
uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks)
{
    if (!BUFFER_IS_VALID(p_buffer))
    {
        return ( BUFFER_INVALID_ID );
    }

    uint8_t first_locked_mutex = BUFFER_INVALID_ID;

    for (uint8_t i = 0; i < p_buffer->n_blocks; i++)
    {
        if (pm_mutex_lock(p_buffer->p_mutex, i))
        {
            if (first_locked_mutex == BUFFER_INVALID_ID)
            {
                first_locked_mutex = i;
            }
            if ((i - first_locked_mutex + 1) == n_blocks)
            {
                return first_locked_mutex;
            }
        }
        else if (first_locked_mutex != BUFFER_INVALID_ID)
        {
            for (uint8_t j = first_locked_mutex; j < i; j++)
            {
                pm_buffer_release(p_buffer, j);
            }
            first_locked_mutex = BUFFER_INVALID_ID;
        }
    }

    return ( BUFFER_INVALID_ID );
}
コード例 #2
0
ファイル: peer_database.c プロジェクト: BLEHexapod/nrf_sdk
/**@brief Function for gracefully deactivating a write buffer record.
 *
 * @details This function will first release any buffers, then invalidate the record.
 *
 * @param[inout] p_write_buffer_record  The record to release.
 *
 * @return  A pointer to the matching record, or NULL if none was found.
 */
static void write_buffer_record_release(pdb_buffer_record_t * p_write_buffer_record)
{
    for (int i = 0; i < p_write_buffer_record->n_bufs; i++)
    {
        pm_buffer_release(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id + i);
    }

    write_buffer_record_invalidate(p_write_buffer_record);
}
コード例 #3
0
ファイル: peer_database.c プロジェクト: BLEHexapod/nrf_sdk
ret_code_t pdb_write_buf_get(pm_peer_id_t       peer_id,
                             pm_peer_data_id_t  data_id,
                             uint32_t           n_bufs,
                             pm_peer_data_t   * p_peer_data)
{
    VERIFY_MODULE_INITIALIZED();
    VERIFY_PARAM_NOT_NULL(p_peer_data);
    if (   !PM_PEER_DATA_ID_IS_VALID(data_id)
        || (n_bufs == 0)
        || (n_bufs > N_WRITE_BUFFERS)
        || !pds_peer_id_is_allocated(peer_id))
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    pdb_buffer_record_t * write_buffer_record;
    uint8_t             * p_buffer_memory;

    write_buffer_record = write_buffer_record_find(peer_id, data_id);

    if ((write_buffer_record != NULL) && (write_buffer_record->n_bufs < n_bufs))
    {
        // @TODO: Copy?
        // Existing buffer is too small.
        for (uint8_t i = 0; i < write_buffer_record->n_bufs; i++)
        {
            pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i);
        }
        write_buffer_record_invalidate(write_buffer_record);
        write_buffer_record = NULL;
    }
    else if ((write_buffer_record != NULL) && write_buffer_record->n_bufs > n_bufs)
    {
        // Release excess blocks.
        for (uint8_t i = n_bufs; i < write_buffer_record->n_bufs; i++)
        {
            pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i);
        }
    }

    if (write_buffer_record == NULL)
    {
        write_buffer_record_get(&write_buffer_record, peer_id, data_id);
        if (write_buffer_record == NULL)
        {
            return NRF_ERROR_BUSY;
        }
    }

    if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID)
    {
        write_buffer_record->buffer_block_id = pm_buffer_block_acquire(&m_pdb.write_buffer, n_bufs);

        if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID)
        {
            write_buffer_record_invalidate(write_buffer_record);
            return NRF_ERROR_BUSY;
        }
    }

    write_buffer_record->n_bufs = n_bufs;

    p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, write_buffer_record->buffer_block_id);

    if (p_buffer_memory == NULL)
    {
        return NRF_ERROR_INTERNAL;
    }

    peer_data_point_to_buffer(p_peer_data, data_id, p_buffer_memory, n_bufs);
    switch(data_id)
    {
        case PM_PEER_DATA_ID_BONDING:
            /* No action needed. */
            break;
        case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
            /* No action needed. */
            break;
        case PM_PEER_DATA_ID_GATT_LOCAL:
        {
            uint32_t size_offset = sizeof(pm_peer_data_local_gatt_db_t);
            p_peer_data->data.p_local_gatt_db->p_data = &p_buffer_memory[size_offset];
            p_peer_data->data.p_local_gatt_db->len    = (PDB_WRITE_BUF_SIZE*n_bufs)-size_offset;
        }
            break;
        case PM_PEER_DATA_ID_GATT_REMOTE:
        {
            uint32_t size_offset = sizeof(pm_peer_data_remote_gatt_db_t);
            p_peer_data->data.p_remote_gatt_db->p_data = (ble_gatt_db_srv_t*)&(p_buffer_memory[size_offset]);
            p_peer_data->data.p_remote_gatt_db->service_count
                            = ((PDB_WRITE_BUF_SIZE*n_bufs)-size_offset)/sizeof(ble_gatt_db_srv_t);
        }
            break;
        case PM_PEER_DATA_ID_APPLICATION:
        {
            p_peer_data->data.p_application_data = p_buffer_memory;
        }
            break;
        default:
            // Invalid data_id. This should have been picked up earlier.
            return NRF_ERROR_INTERNAL;
    }

    return NRF_SUCCESS;
}