hci_inject.cc revision 09f31c121df79afe045163e0142dec5c09caa072
109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati/****************************************************************************** 209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * 309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * Copyright (C) 2014 Google, Inc. 409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * 509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * Licensed under the Apache License, Version 2.0 (the "License"); 609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * you may not use this file except in compliance with the License. 709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * You may obtain a copy of the License at: 809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * 909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * http://www.apache.org/licenses/LICENSE-2.0 1009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * 1109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * Unless required by applicable law or agreed to in writing, software 1209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * distributed under the License is distributed on an "AS IS" BASIS, 1309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * See the License for the specific language governing permissions and 1509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * limitations under the License. 1609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati * 1709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati ******************************************************************************/ 1809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 1909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#define LOG_TAG "bt_hci_inject" 2009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 2109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include <assert.h> 2209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include <errno.h> 2309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include <utils/Log.h> 2409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 2509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include "bt_hci_bdroid.h" 2609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include "bt_types.h" 2709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include "hci_inject.h" 2809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include "list.h" 2909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include "osi.h" 3009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include "socket.h" 3109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include "thread.h" 3209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 3309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatitypedef enum { 3409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati HCI_PACKET_COMMAND = 1, 3509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati HCI_PACKET_ACL_DATA = 2, 3609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati HCI_PACKET_SCO_DATA = 3, 3709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati HCI_PACKET_EVENT = 4, 3809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} hci_packet_t; 3909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 4009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatitypedef struct { 4109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati socket_t *socket; 4209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati uint8_t buffer[65536 + 3]; // 2 bytes length prefix, 1 byte type prefix. 4309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati size_t buffer_size; 4409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} client_t; 4509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 4609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic const port_t LISTEN_PORT = 8873; 4709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 4809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic const bt_hc_interface_t *hci; 4909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic socket_t *listen_socket; 5009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic thread_t *thread; 5109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic list_t *clients; 5209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 5309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic int hci_packet_to_event(hci_packet_t packet); 5409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void accept_ready(socket_t *socket, void *context); 5509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void read_ready(socket_t *socket, void *context); 5609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void client_free(void *ptr); 5709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 5809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatibool hci_inject_open(void) { 5909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati assert(listen_socket == NULL); 6009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati assert(thread == NULL); 6109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati assert(clients == NULL); 6209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 6309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati hci = bt_hc_get_interface(); 6409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 6509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati clients = list_new(client_free); 6609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (!clients) 6709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati goto error; 6809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 6909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati thread = thread_new("hci_inject"); 7009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (!thread) 7109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati goto error; 7209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 7309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati listen_socket = socket_new(); 7409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (!listen_socket) 7509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati goto error; 7609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 7709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (!socket_listen(listen_socket, LISTEN_PORT)) 7809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati goto error; 7909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 8009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati socket_register(listen_socket, thread_get_reactor(thread), accept_ready, NULL, NULL); 8109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return true; 8209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 8309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatierror:; 8409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati hci_inject_close(); 8509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return false; 8609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 8709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 8809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavativoid hci_inject_close(void) { 8909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati socket_free(listen_socket); 9009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati thread_free(thread); 9109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati list_free(clients); 9209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 9309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati listen_socket = NULL; 9409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati thread = NULL; 9509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati clients = NULL; 9609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 9709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 9809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic int hci_packet_to_event(hci_packet_t packet) { 9909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati switch (packet) { 10009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati case HCI_PACKET_COMMAND: 10109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return MSG_STACK_TO_HC_HCI_CMD; 10209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati case HCI_PACKET_ACL_DATA: 10309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return MSG_STACK_TO_HC_HCI_ACL; 10409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati case HCI_PACKET_SCO_DATA: 10509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return MSG_STACK_TO_HC_HCI_SCO; 10609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati default: 10709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati ALOGE("%s unsupported packet type: %d", __func__, packet); 10809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return -1; 10909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 11009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 11109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 11209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void accept_ready(socket_t *socket, UNUSED_ATTR void *context) { 11309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati assert(socket != NULL); 11409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati assert(socket == listen_socket); 11509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 11609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati socket = socket_accept(socket); 11709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (!socket) 11809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return; 11909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 12009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client_t *client = (client_t *)calloc(1, sizeof(client_t)); 12109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (!client) { 12209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati ALOGE("%s unable to allocate memory for client.", __func__); 12309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati socket_free(socket); 12409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return; 12509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 12609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 12709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client->socket = socket; 12809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 12909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (!list_append(clients, client)) { 13009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati ALOGE("%s unable to add client to list.", __func__); 13109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client_free(client); 13209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return; 13309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 13409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 13509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati socket_register(socket, thread_get_reactor(thread), read_ready, NULL, client); 13609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 13709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 13809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void read_ready(UNUSED_ATTR socket_t *socket, void *context) { 13909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati assert(bt_hc_cbacks != NULL); 14009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati assert(socket != NULL); 14109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati assert(context != NULL); 14209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 14309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client_t *client = (client_t *)context; 14409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 14509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati ssize_t ret = socket_read(client->socket, client->buffer + client->buffer_size, sizeof(client->buffer) - client->buffer_size); 14609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (ret == 0 || (ret == -1 && ret != EWOULDBLOCK && ret != EAGAIN)) { 14709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati list_remove(clients, client); 14809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return; 14909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 15009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client->buffer_size += ret; 15109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 15209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati while (client->buffer_size > 3) { 15309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati uint8_t *buffer = client->buffer; 15409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati hci_packet_t packet_type = (hci_packet_t)buffer[0]; 15509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati size_t packet_len = (buffer[2] << 8) | buffer[1]; 15609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati size_t frame_len = 3 + packet_len; 15709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 15809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (client->buffer_size < frame_len) 15909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati break; 16009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 16109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati // TODO(sharvil): validate incoming HCI messages. 16209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati // TODO(sharvil): once we have an HCI parser, we can eliminate 16309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati // the 2-byte size field since it will be contained in the packet. 16409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 16509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati BT_HDR *buf = (BT_HDR *)bt_hc_cbacks->alloc(packet_len); 16609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (buf) { 16709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati buf->event = hci_packet_to_event(packet_type); 16809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati buf->offset = 0; 16909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati buf->layer_specific = 0; 17009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati buf->len = packet_len; 17109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati memcpy(buf->data, buffer + 3, packet_len); 17209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati hci->transmit_buf(buf, NULL, 0); 17309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } else { 17409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati ALOGE("%s dropping injected packet of length %zu", __func__, packet_len); 17509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 17609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 17709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati size_t remainder = client->buffer_size - frame_len; 17809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati memmove(buffer, buffer + frame_len, remainder); 17909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client->buffer_size -= frame_len; 18009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 18109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 18209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 18309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void client_free(void *ptr) { 18409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (!ptr) 18509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return; 18609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 18709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client_t *client = (client_t *)ptr; 18809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati socket_free(client->socket); 18909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 190