1 /****************************************************************************** 2 * 3 * Copyright (C) 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 <assert.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 const port_t LISTEN_PORT = 8873; 51 52 static const hci_inject_t interface; 53 static const hci_t *hci; 54 static const allocator_t *buffer_allocator; 55 static socket_t *listen_socket; 56 static thread_t *thread; 57 static list_t *clients; 58 59 static int hci_packet_to_event(hci_packet_t packet); 60 static void accept_ready(socket_t *socket, void *context); 61 static void read_ready(socket_t *socket, void *context); 62 static void client_free(void *ptr); 63 64 bool hci_inject_open(const hci_t *hci_interface) { 65 #if (!defined(BT_NET_DEBUG) || (BT_NET_DEBUG != TRUE)) 66 return true; // Disable using network sockets for security reasons 67 #endif 68 69 assert(listen_socket == NULL); 70 assert(thread == NULL); 71 assert(clients == NULL); 72 assert(hci_interface != NULL); 73 74 hci = hci_interface; 75 76 thread = thread_new("hci_inject"); 77 if (!thread) 78 goto error; 79 80 clients = list_new(client_free); 81 if (!clients) 82 goto error; 83 84 listen_socket = socket_new(); 85 if (!listen_socket) 86 goto error; 87 88 if (!socket_listen(listen_socket, LISTEN_PORT)) 89 goto error; 90 91 socket_register(listen_socket, thread_get_reactor(thread), NULL, accept_ready, NULL); 92 return true; 93 94 error:; 95 interface.close(); 96 return false; 97 } 98 99 void hci_inject_close(void) { 100 #if (!defined(BT_NET_DEBUG) || (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 assert(socket != NULL); 129 assert(socket == listen_socket); 130 131 socket = socket_accept(socket); 132 if (!socket) 133 return; 134 135 client_t *client = (client_t *)osi_calloc(sizeof(client_t)); 136 137 client->socket = socket; 138 139 if (!list_append(clients, client)) { 140 LOG_ERROR(LOG_TAG, "%s unable to add client to list.", __func__); 141 client_free(client); 142 return; 143 } 144 145 socket_register(socket, thread_get_reactor(thread), client, read_ready, NULL); 146 } 147 148 static void read_ready(UNUSED_ATTR socket_t *socket, void *context) { 149 assert(socket != NULL); 150 assert(context != NULL); 151 152 client_t *client = (client_t *)context; 153 154 ssize_t ret = socket_read(client->socket, client->buffer + client->buffer_size, sizeof(client->buffer) - client->buffer_size); 155 if (ret == 0 || (ret == -1 && ret != EWOULDBLOCK && ret != EAGAIN)) { 156 list_remove(clients, client); 157 return; 158 } 159 client->buffer_size += ret; 160 161 while (client->buffer_size > 3) { 162 uint8_t *buffer = client->buffer; 163 hci_packet_t packet_type = (hci_packet_t)buffer[0]; 164 size_t packet_len = (buffer[2] << 8) | buffer[1]; 165 size_t frame_len = 3 + packet_len; 166 167 if (client->buffer_size < frame_len) 168 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__, packet_len); 184 } 185 186 size_t remainder = client->buffer_size - frame_len; 187 memmove(buffer, buffer + frame_len, remainder); 188 client->buffer_size -= frame_len; 189 } 190 } 191 192 static void client_free(void *ptr) { 193 if (!ptr) 194 return; 195 196 client_t *client = (client_t *)ptr; 197 socket_free(client->socket); 198 osi_free(client); 199 } 200 201 static const hci_inject_t interface = { 202 hci_inject_open, 203 hci_inject_close 204 }; 205 206 const hci_inject_t *hci_inject_get_interface() { 207 buffer_allocator = buffer_allocator_get_interface(); 208 return &interface; 209 } 210