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 1949120dc867c7818511b5afec461dfc97d17eef58Marie Janssen#define LOG_TAG "bt_hci_inject" 2049120dc867c7818511b5afec461dfc97d17eef58Marie Janssen 2149a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include "hci_inject.h" 2249a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen 23f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He#include <base/logging.h> 2409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include <errno.h> 253e59b5b6f2ce1295e3e2711afcd2cdf0dd7e22b6Etan Cohen#include <string.h> 2609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 2709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include "bt_types.h" 28bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson#include "buffer_allocator.h" 29fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson#include "hci_layer.h" 30db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "osi/include/allocator.h" 310f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/list.h" 3244802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#include "osi/include/log.h" 33db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "osi/include/osi.h" 340f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/socket.h" 350f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/thread.h" 3609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 3709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatitypedef enum { 385ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson HCI_PACKET_COMMAND = 1, 3909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati HCI_PACKET_ACL_DATA = 2, 4009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati HCI_PACKET_SCO_DATA = 3, 415ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson HCI_PACKET_EVENT = 4, 4209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} hci_packet_t; 4309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 4409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatitypedef struct { 455ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson socket_t* socket; 4609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati uint8_t buffer[65536 + 3]; // 2 bytes length prefix, 1 byte type prefix. 4709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati size_t buffer_size; 4809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} client_t; 4909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 505ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic bool hci_inject_open(const hci_t* hci_interface); 51b2a292b5d8df2f359c38b0787bc01181225a9bc9Pavlin Radoslavovstatic void hci_inject_close(void); 52b2a292b5d8df2f359c38b0787bc01181225a9bc9Pavlin Radoslavovstatic int hci_packet_to_event(hci_packet_t packet); 535ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void accept_ready(socket_t* socket, void* context); 545ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void read_ready(socket_t* socket, void* context); 555ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void client_free(void* ptr); 56b2a292b5d8df2f359c38b0787bc01181225a9bc9Pavlin Radoslavov 5709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic const port_t LISTEN_PORT = 8873; 5809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 595ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic const hci_inject_t interface = {hci_inject_open, hci_inject_close}; 60b2a292b5d8df2f359c38b0787bc01181225a9bc9Pavlin Radoslavov 615ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic const hci_t* hci; 625ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic const allocator_t* buffer_allocator; 635ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic socket_t* listen_socket; 645ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic thread_t* thread; 655ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic list_t* clients; 6609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 675ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic bool hci_inject_open(const hci_t* hci_interface) { 68d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (BT_NET_DEBUG != TRUE) 695ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson return true; // Disable using network sockets for security reasons 704cac544da367d7458129631ddef6db4e3312cef7Pavlin Radoslavov#endif 714cac544da367d7458129631ddef6db4e3312cef7Pavlin Radoslavov 72f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(listen_socket == NULL); 73f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(thread == NULL); 74f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(clients == NULL); 75f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(hci_interface != NULL); 7609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 77fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson hci = hci_interface; 7809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 7909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati thread = thread_new("hci_inject"); 805ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson if (!thread) goto error; 8109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 82fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati clients = list_new(client_free); 835ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson if (!clients) goto error; 84fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati 8509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati listen_socket = socket_new(); 865ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson if (!listen_socket) goto error; 8709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 885ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson if (!socket_listen(listen_socket, LISTEN_PORT)) goto error; 8909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 905ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson socket_register(listen_socket, thread_get_reactor(thread), NULL, accept_ready, 915ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson NULL); 9209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return true; 9309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 9409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatierror:; 95fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson interface.close(); 9609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return false; 9709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 9809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 99b2a292b5d8df2f359c38b0787bc01181225a9bc9Pavlin Radoslavovstatic void hci_inject_close(void) { 100d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (BT_NET_DEBUG != TRUE) 1015ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson return; // Disable using network sockets for security reasons 1024cac544da367d7458129631ddef6db4e3312cef7Pavlin Radoslavov#endif 1034cac544da367d7458129631ddef6db4e3312cef7Pavlin Radoslavov 10409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati socket_free(listen_socket); 10509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati list_free(clients); 106fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati thread_free(thread); 10709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 10809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati listen_socket = NULL; 10909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati thread = NULL; 11009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati clients = NULL; 11109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 11209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 11309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic int hci_packet_to_event(hci_packet_t packet) { 11409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati switch (packet) { 11509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati case HCI_PACKET_COMMAND: 11609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return MSG_STACK_TO_HC_HCI_CMD; 11709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati case HCI_PACKET_ACL_DATA: 11809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return MSG_STACK_TO_HC_HCI_ACL; 11909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati case HCI_PACKET_SCO_DATA: 12009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return MSG_STACK_TO_HC_HCI_SCO; 12109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati default: 122db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_ERROR(LOG_TAG, "%s unsupported packet type: %d", __func__, packet); 12309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return -1; 12409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 12509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 12609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 1275ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void accept_ready(socket_t* socket, UNUSED_ATTR void* context) { 128f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(socket != NULL); 129f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(socket == listen_socket); 13009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 13109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati socket = socket_accept(socket); 1325ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson if (!socket) return; 13309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 1345ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson client_t* client = (client_t*)osi_calloc(sizeof(client_t)); 13509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 13609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client->socket = socket; 13709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 13809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (!list_append(clients, client)) { 139db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_ERROR(LOG_TAG, "%s unable to add client to list.", __func__); 14009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client_free(client); 14109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return; 14209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 14309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 144fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati socket_register(socket, thread_get_reactor(thread), client, read_ready, NULL); 14509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 14609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 1475ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void read_ready(UNUSED_ATTR socket_t* socket, void* context) { 148f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(socket != NULL); 149f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He CHECK(context != NULL); 15009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 1515ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson client_t* client = (client_t*)context; 15209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 1535ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson ssize_t ret = 1545ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson socket_read(client->socket, client->buffer + client->buffer_size, 1555ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson sizeof(client->buffer) - client->buffer_size); 15609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (ret == 0 || (ret == -1 && ret != EWOULDBLOCK && ret != EAGAIN)) { 15709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati list_remove(clients, client); 15809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati return; 15909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 16009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client->buffer_size += ret; 16109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 16209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati while (client->buffer_size > 3) { 1635ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson uint8_t* buffer = client->buffer; 16409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati hci_packet_t packet_type = (hci_packet_t)buffer[0]; 16509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati size_t packet_len = (buffer[2] << 8) | buffer[1]; 16609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati size_t frame_len = 3 + packet_len; 16709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 1685ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson if (client->buffer_size < frame_len) break; 16909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 17009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati // TODO(sharvil): validate incoming HCI messages. 17109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati // TODO(sharvil): once we have an HCI parser, we can eliminate 17209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati // the 2-byte size field since it will be contained in the packet. 17309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 1745ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson BT_HDR* buf = (BT_HDR*)buffer_allocator->alloc(BT_HDR_SIZE + packet_len); 17509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati if (buf) { 17609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati buf->event = hci_packet_to_event(packet_type); 17709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati buf->offset = 0; 17809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati buf->layer_specific = 0; 17909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati buf->len = packet_len; 18009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati memcpy(buf->data, buffer + 3, packet_len); 181fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson hci->transmit_downward(buf->event, buf); 18209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } else { 1835ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson LOG_ERROR(LOG_TAG, "%s dropping injected packet of length %zu", __func__, 1845ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson packet_len); 18509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 18609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 18709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati size_t remainder = client->buffer_size - frame_len; 18809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati memmove(buffer, buffer + frame_len, remainder); 18909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati client->buffer_size -= frame_len; 19009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati } 19109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 19209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 1935ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonstatic void client_free(void* ptr) { 1945ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson if (!ptr) return; 19509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati 1965ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watson client_t* client = (client_t*)ptr; 19709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati socket_free(client->socket); 1981e0ede7f5522a853fc39d4f183e508ed38f01636Zach Johnson osi_free(client); 19909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} 200fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson 2015ff20a23661695abb1cff6d01d71a8cad4cc7890Myles Watsonconst hci_inject_t* hci_inject_get_interface() { 202bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson buffer_allocator = buffer_allocator_get_interface(); 203fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson return &interface; 204fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson} 205