1 /****************************************************************************** 2 * 3 * Copyright 2014 Google, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #define LOG_TAG "bt_hci_inject" 20 21 #include "hci_inject.h" 22 23 #include <base/logging.h> 24 #include <errno.h> 25 #include <string.h> 26 27 #include "bt_types.h" 28 #include "buffer_allocator.h" 29 #include "hci_layer.h" 30 #include "osi/include/allocator.h" 31 #include "osi/include/list.h" 32 #include "osi/include/log.h" 33 #include "osi/include/osi.h" 34 #include "osi/include/socket.h" 35 #include "osi/include/thread.h" 36 37 typedef enum { 38 HCI_PACKET_COMMAND = 1, 39 HCI_PACKET_ACL_DATA = 2, 40 HCI_PACKET_SCO_DATA = 3, 41 HCI_PACKET_EVENT = 4, 42 } hci_packet_t; 43 44 typedef struct { 45 socket_t* socket; 46 uint8_t buffer[65536 + 3]; // 2 bytes length prefix, 1 byte type prefix. 47 size_t buffer_size; 48 } client_t; 49 50 static bool hci_inject_open(const hci_t* hci_interface); 51 static void hci_inject_close(void); 52 static int hci_packet_to_event(hci_packet_t packet); 53 static void accept_ready(socket_t* socket, void* context); 54 static void read_ready(socket_t* socket, void* context); 55 static void client_free(void* ptr); 56 57 static const port_t LISTEN_PORT = 8873; 58 59 static const hci_inject_t interface = {hci_inject_open, hci_inject_close}; 60 61 static const hci_t* hci; 62 static const allocator_t* buffer_allocator; 63 static socket_t* listen_socket; 64 static thread_t* thread; 65 static list_t* clients; 66 67 static bool hci_inject_open(const hci_t* hci_interface) { 68 #if (BT_NET_DEBUG != TRUE) 69 return true; // Disable using network sockets for security reasons 70 #endif 71 72 CHECK(listen_socket == NULL); 73 CHECK(thread == NULL); 74 CHECK(clients == NULL); 75 CHECK(hci_interface != NULL); 76 77 hci = hci_interface; 78 79 thread = thread_new("hci_inject"); 80 if (!thread) goto error; 81 82 clients = list_new(client_free); 83 if (!clients) goto error; 84 85 listen_socket = socket_new(); 86 if (!listen_socket) goto error; 87 88 if (!socket_listen(listen_socket, LISTEN_PORT)) goto error; 89 90 socket_register(listen_socket, thread_get_reactor(thread), NULL, accept_ready, 91 NULL); 92 return true; 93 94 error:; 95 interface.close(); 96 return false; 97 } 98 99 static void hci_inject_close(void) { 100 #if (BT_NET_DEBUG != TRUE) 101 return; // Disable using network sockets for security reasons 102 #endif 103 104 socket_free(listen_socket); 105 list_free(clients); 106 thread_free(thread); 107 108 listen_socket = NULL; 109 thread = NULL; 110 clients = NULL; 111 } 112 113 static int hci_packet_to_event(hci_packet_t packet) { 114 switch (packet) { 115 case HCI_PACKET_COMMAND: 116 return MSG_STACK_TO_HC_HCI_CMD; 117 case HCI_PACKET_ACL_DATA: 118 return MSG_STACK_TO_HC_HCI_ACL; 119 case HCI_PACKET_SCO_DATA: 120 return MSG_STACK_TO_HC_HCI_SCO; 121 default: 122 LOG_ERROR(LOG_TAG, "%s unsupported packet type: %d", __func__, packet); 123 return -1; 124 } 125 } 126 127 static void accept_ready(socket_t* socket, UNUSED_ATTR void* context) { 128 CHECK(socket != NULL); 129 CHECK(socket == listen_socket); 130 131 socket = socket_accept(socket); 132 if (!socket) return; 133 134 client_t* client = (client_t*)osi_calloc(sizeof(client_t)); 135 136 client->socket = socket; 137 138 if (!list_append(clients, client)) { 139 LOG_ERROR(LOG_TAG, "%s unable to add client to list.", __func__); 140 client_free(client); 141 return; 142 } 143 144 socket_register(socket, thread_get_reactor(thread), client, read_ready, NULL); 145 } 146 147 static void read_ready(UNUSED_ATTR socket_t* socket, void* context) { 148 CHECK(socket != NULL); 149 CHECK(context != NULL); 150 151 client_t* client = (client_t*)context; 152 153 ssize_t ret = 154 socket_read(client->socket, client->buffer + client->buffer_size, 155 sizeof(client->buffer) - client->buffer_size); 156 if (ret == 0 || (ret == -1 && ret != EWOULDBLOCK && ret != EAGAIN)) { 157 list_remove(clients, client); 158 return; 159 } 160 client->buffer_size += ret; 161 162 while (client->buffer_size > 3) { 163 uint8_t* buffer = client->buffer; 164 hci_packet_t packet_type = (hci_packet_t)buffer[0]; 165 size_t packet_len = (buffer[2] << 8) | buffer[1]; 166 size_t frame_len = 3 + packet_len; 167 168 if (client->buffer_size < frame_len) break; 169 170 // TODO(sharvil): validate incoming HCI messages. 171 // TODO(sharvil): once we have an HCI parser, we can eliminate 172 // the 2-byte size field since it will be contained in the packet. 173 174 BT_HDR* buf = (BT_HDR*)buffer_allocator->alloc(BT_HDR_SIZE + packet_len); 175 if (buf) { 176 buf->event = hci_packet_to_event(packet_type); 177 buf->offset = 0; 178 buf->layer_specific = 0; 179 buf->len = packet_len; 180 memcpy(buf->data, buffer + 3, packet_len); 181 hci->transmit_downward(buf->event, buf); 182 } else { 183 LOG_ERROR(LOG_TAG, "%s dropping injected packet of length %zu", __func__, 184 packet_len); 185 } 186 187 size_t remainder = client->buffer_size - frame_len; 188 memmove(buffer, buffer + frame_len, remainder); 189 client->buffer_size -= frame_len; 190 } 191 } 192 193 static void client_free(void* ptr) { 194 if (!ptr) return; 195 196 client_t* client = (client_t*)ptr; 197 socket_free(client->socket); 198 osi_free(client); 199 } 200 201 const hci_inject_t* hci_inject_get_interface() { 202 buffer_allocator = buffer_allocator_get_interface(); 203 return &interface; 204 } 205