blob: 833769574a1dbef864b13bc3d9c17b0c30afdc8d [file] [log] [blame]
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#include <string.h>
#include "hci_hal.h"
#include "hci_internals.h"
#include "bt_utils.h"
#if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
#include <assert.h>
#include "osi/include/eager_reader.h"
#include "osi/include/osi.h"
#include "osi/include/log.h"
#endif
bt_soc_type soc_type;
const hci_hal_t *hci_hal_get_interface() {
soc_type = get_soc_type();
if (soc_type == BT_SOC_ROME || soc_type == BT_SOC_CHEROKEE) {
return hci_hal_h4_get_interface();
} else {
return hci_hal_mct_get_interface();
}
}
#if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
void hci_reader_free(hci_reader_t *reader) {
if (!reader)
return;
// Only unregister from the input if we actually did register
if (reader->inbound_read_object)
reactor_unregister(reader->inbound_read_object);
// Free the current buffer, because it's not in the queue
// and won't be freed below
if (reader->data_buffer)
osi_free(reader->data_buffer);
osi_free(reader);
}
hci_reader_t *hci_reader_new(
int fd_to_read,
size_t buffer_size,
size_t max_buffer_count,
thread_t *thread,
hci_reader_cb read_cb
) {
assert(fd_to_read != INVALID_FD);
assert(buffer_size > 0);
assert(max_buffer_count > 0);
hci_reader_t *ret = osi_calloc(sizeof(hci_reader_t));
if (!ret) {
LOG_ERROR("%s unable to allocate memory for new hci_reader.", __func__);
goto error;
}
ret->inbound_fd = fd_to_read;
ret->data_buffer = osi_calloc(buffer_size);
ret->buffer_size = buffer_size;
ret->rd_ptr = 0;
ret->wr_ptr = 0;
ret->inbound_read_thread = thread;
if (!ret->inbound_read_thread) {
LOG_ERROR("%s unable to make reading thread.", __func__);
goto error;
}
ret->inbound_read_object = reactor_register(
thread_get_reactor(ret->inbound_read_thread),
fd_to_read,
ret,
read_cb,
NULL
);
return ret;
error:;
hci_reader_free(ret);
return NULL;
}
size_t hci_reader_read(hci_reader_t *reader, uint8_t *buffer, size_t req_size) {
int bytes_read = 0;
assert(reader != NULL);
assert(buffer != NULL);
// If the caller wants nonblocking behavior, poll to see if we have
// any bytes available before reading.
if (reader->rd_ptr < reader->wr_ptr) {
bytes_read = reader->wr_ptr - reader->rd_ptr;
if ((size_t) bytes_read > req_size)
bytes_read = req_size;
memcpy(buffer, reader->data_buffer+reader->rd_ptr, bytes_read);
reader->rd_ptr += bytes_read;
} else {
bytes_read = read(reader->inbound_fd, buffer, req_size);
if(bytes_read == -1)
bytes_read = 0;
}
return bytes_read;
}
#endif