hci_inject.cc revision 3e59b5b6f2ce1295e3e2711afcd2cdf0dd7e22b6
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>
233e59b5b6f2ce1295e3e2711afcd2cdf0dd7e22b6Etan Cohen#include <string.h>
2409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
250f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/allocator.h"
2609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include "bt_types.h"
27bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson#include "buffer_allocator.h"
2809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati#include "hci_inject.h"
29fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson#include "hci_layer.h"
300f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/list.h"
310f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/osi.h"
3244802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#include "osi/include/log.h"
330f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/socket.h"
340f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/thread.h"
3509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
3609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatitypedef enum {
3709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  HCI_PACKET_COMMAND  = 1,
3809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  HCI_PACKET_ACL_DATA = 2,
3909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  HCI_PACKET_SCO_DATA = 3,
4009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  HCI_PACKET_EVENT    = 4,
4109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} hci_packet_t;
4209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
4309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatitypedef struct {
4409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  socket_t *socket;
4509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  uint8_t buffer[65536 + 3];  // 2 bytes length prefix, 1 byte type prefix.
4609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  size_t buffer_size;
4709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati} client_t;
4809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
4909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic const port_t LISTEN_PORT = 8873;
5009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
51bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonstatic const hci_inject_t interface;
52bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonstatic const hci_t *hci;
53bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonstatic const allocator_t *buffer_allocator;
5409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic socket_t *listen_socket;
5509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic thread_t *thread;
5609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic list_t *clients;
5709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
5809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic int hci_packet_to_event(hci_packet_t packet);
5909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void accept_ready(socket_t *socket, void *context);
6009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void read_ready(socket_t *socket, void *context);
6109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void client_free(void *ptr);
6209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
63bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonbool hci_inject_open(const hci_t *hci_interface) {
6409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  assert(listen_socket == NULL);
6509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  assert(thread == NULL);
6609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  assert(clients == NULL);
67fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson  assert(hci_interface != NULL);
6809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
69fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson  hci = hci_interface;
7009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
7109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  thread = thread_new("hci_inject");
7209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  if (!thread)
7309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    goto error;
7409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
75fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati  clients = list_new(client_free);
76fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati  if (!clients)
77fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati    goto error;
78fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati
7909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  listen_socket = socket_new();
8009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  if (!listen_socket)
8109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    goto error;
8209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
8309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  if (!socket_listen(listen_socket, LISTEN_PORT))
8409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    goto error;
8509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
86fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati  socket_register(listen_socket, thread_get_reactor(thread), NULL, accept_ready, NULL);
8709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  return true;
8809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
8909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatierror:;
90fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson  interface.close();
9109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  return false;
9209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati}
9309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
9409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavativoid hci_inject_close(void) {
9509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  socket_free(listen_socket);
9609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  list_free(clients);
97fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati  thread_free(thread);
9809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
9909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  listen_socket = NULL;
10009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  thread = NULL;
10109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  clients = NULL;
10209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati}
10309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
10409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic int hci_packet_to_event(hci_packet_t packet) {
10509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  switch (packet) {
10609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    case HCI_PACKET_COMMAND:
10709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati      return MSG_STACK_TO_HC_HCI_CMD;
10809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    case HCI_PACKET_ACL_DATA:
10909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati      return MSG_STACK_TO_HC_HCI_ACL;
11009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    case HCI_PACKET_SCO_DATA:
11109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati      return MSG_STACK_TO_HC_HCI_SCO;
11209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    default:
11344802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati      LOG_ERROR("%s unsupported packet type: %d", __func__, packet);
11409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati      return -1;
11509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  }
11609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati}
11709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
11809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void accept_ready(socket_t *socket, UNUSED_ATTR void *context) {
11909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  assert(socket != NULL);
12009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  assert(socket == listen_socket);
12109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
12209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  socket = socket_accept(socket);
12309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  if (!socket)
12409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    return;
12509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
1261e0ede7f5522a853fc39d4f183e508ed38f01636Zach Johnson  client_t *client = (client_t *)osi_calloc(sizeof(client_t));
12709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  if (!client) {
12844802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati    LOG_ERROR("%s unable to allocate memory for client.", __func__);
12909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    socket_free(socket);
13009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    return;
13109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  }
13209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
13309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  client->socket = socket;
13409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
13509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  if (!list_append(clients, client)) {
13644802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati    LOG_ERROR("%s unable to add client to list.", __func__);
13709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    client_free(client);
13809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    return;
13909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  }
14009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
141fbf89085bf308a98b00da77d1538539f6dd58604Sharvil Nanavati  socket_register(socket, thread_get_reactor(thread), client, read_ready, NULL);
14209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati}
14309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
14409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void read_ready(UNUSED_ATTR socket_t *socket, void *context) {
14509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  assert(socket != NULL);
14609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  assert(context != NULL);
14709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
14809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  client_t *client = (client_t *)context;
14909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
15009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  ssize_t ret = socket_read(client->socket, client->buffer + client->buffer_size, sizeof(client->buffer) - client->buffer_size);
15109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  if (ret == 0 || (ret == -1 && ret != EWOULDBLOCK && ret != EAGAIN)) {
15209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    list_remove(clients, client);
15309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    return;
15409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  }
15509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  client->buffer_size += ret;
15609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
15709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  while (client->buffer_size > 3) {
15809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    uint8_t *buffer = client->buffer;
15909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    hci_packet_t packet_type = (hci_packet_t)buffer[0];
16009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    size_t packet_len = (buffer[2] << 8) | buffer[1];
16109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    size_t frame_len = 3 + packet_len;
16209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
16309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    if (client->buffer_size < frame_len)
16409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati      break;
16509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
16609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    // TODO(sharvil): validate incoming HCI messages.
16709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    // TODO(sharvil): once we have an HCI parser, we can eliminate
16809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    //   the 2-byte size field since it will be contained in the packet.
16909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
170bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson    BT_HDR *buf = (BT_HDR *)buffer_allocator->alloc(packet_len);
17109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    if (buf) {
17209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati      buf->event = hci_packet_to_event(packet_type);
17309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati      buf->offset = 0;
17409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati      buf->layer_specific = 0;
17509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati      buf->len = packet_len;
17609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati      memcpy(buf->data, buffer + 3, packet_len);
177fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson      hci->transmit_downward(buf->event, buf);
17809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    } else {
17944802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati      LOG_ERROR("%s dropping injected packet of length %zu", __func__, packet_len);
18009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    }
18109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
18209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    size_t remainder = client->buffer_size - frame_len;
18309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    memmove(buffer, buffer + frame_len, remainder);
18409f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    client->buffer_size -= frame_len;
18509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  }
18609f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati}
18709f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
18809f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavatistatic void client_free(void *ptr) {
18909f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  if (!ptr)
19009f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati    return;
19109f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati
19209f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  client_t *client = (client_t *)ptr;
19309f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati  socket_free(client->socket);
1941e0ede7f5522a853fc39d4f183e508ed38f01636Zach Johnson  osi_free(client);
19509f31c121df79afe045163e0142dec5c09caa072Sharvil Nanavati}
196fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson
197bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonstatic const hci_inject_t interface = {
198fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson  hci_inject_open,
199fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson  hci_inject_close
200fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson};
201fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson
202bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnsonconst hci_inject_t *hci_inject_get_interface() {
203bf8193bc81cc077e3acd245cacbe8e3789c4b9ffZach Johnson  buffer_allocator = buffer_allocator_get_interface();
204fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson  return &interface;
205fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson}
206