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