Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93136d9f authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Metrics: Log L2CAP and RFCOMM socket connection state changes to statsd"

parents 9551a5f2 7a98b40a
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@

#include <base/logging.h>

#include <frameworks/base/core/proto/android/bluetooth/enums.pb.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>

@@ -34,6 +35,7 @@
#include "btif_sock_thread.h"
#include "btif_uid.h"
#include "btif_util.h"
#include "common/metrics.h"
#include "device/include/controller.h"
#include "osi/include/thread.h"

@@ -138,6 +140,11 @@ static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
  bt_status_t status = BT_STATUS_FAIL;
  int original_channel = channel;

  bluetooth::common::LogSocketConnectionState(
      RawAddress::kEmpty, 0, type,
      android::bluetooth::SocketConnectionstateEnum::
          SOCKET_CONNECTION_STATE_LISTENING,
      0, 0, app_uid, channel, android::bluetooth::SOCKET_ROLE_LISTEN);
  switch (type) {
    case BTSOCK_RFCOMM:
      status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd,
@@ -174,6 +181,13 @@ static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
      status = BT_STATUS_UNSUPPORTED;
      break;
  }
  if (status != BT_STATUS_SUCCESS) {
    bluetooth::common::LogSocketConnectionState(
        RawAddress::kEmpty, 0, type,
        android::bluetooth::SocketConnectionstateEnum::
            SOCKET_CONNECTION_STATE_DISCONNECTED,
        0, 0, app_uid, channel, android::bluetooth::SOCKET_ROLE_LISTEN);
  }
  return status;
}

@@ -186,6 +200,11 @@ static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type,
  *sock_fd = INVALID_FD;
  bt_status_t status = BT_STATUS_FAIL;

  bluetooth::common::LogSocketConnectionState(
      *bd_addr, 0, type,
      android::bluetooth::SocketConnectionstateEnum::
          SOCKET_CONNECTION_STATE_CONNECTING,
      0, 0, app_uid, channel, android::bluetooth::SOCKET_ROLE_CONNECTION);
  switch (type) {
    case BTSOCK_RFCOMM:
      status =
@@ -213,6 +232,13 @@ static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type,
      status = BT_STATUS_UNSUPPORTED;
      break;
  }
  if (status != BT_STATUS_SUCCESS) {
    bluetooth::common::LogSocketConnectionState(
        *bd_addr, 0, type,
        android::bluetooth::SocketConnectionstateEnum::
            SOCKET_CONNECTION_STATE_DISCONNECTED,
        0, 0, app_uid, channel, android::bluetooth::SOCKET_ROLE_CONNECTION);
  }
  return status;
}

+71 −5
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

#include <mutex>

#include <frameworks/base/core/proto/android/bluetooth/enums.pb.h>
#include <hardware/bt_sock.h>

#include "osi/include/allocator.h"
@@ -46,6 +47,7 @@
#include "btm_api.h"
#include "btm_int.h"
#include "btu.h"
#include "common/metrics.h"
#include "hcimsgs.h"
#include "l2c_api.h"
#include "l2c_int.h"
@@ -84,6 +86,10 @@ typedef struct l2cap_socket {
  bool is_le_coc;                 // is le connection oriented channel?
  uint16_t rx_mtu;
  uint16_t tx_mtu;
  // Cumulative number of bytes transmitted on this socket
  int64_t tx_bytes;
  // Cumulative number of bytes received on this socket
  int64_t rx_bytes;
} l2cap_socket;

static void btsock_l2cap_server_listen(l2cap_socket* sock);
@@ -215,6 +221,14 @@ static void btsock_l2cap_free_l(l2cap_socket* sock) {
  if (!t) /* prever double-frees */
    return;

  // Whenever a socket is freed, the connection must be dropped
  bluetooth::common::LogSocketConnectionState(
      sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
      android::bluetooth::SOCKET_CONNECTION_STATE_DISCONNECTED, sock->tx_bytes,
      sock->rx_bytes, sock->app_uid, sock->channel,
      sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
                   : android::bluetooth::SOCKET_ROLE_CONNECTION);

  if (sock->next) sock->next->prev = sock->prev;

  if (sock->prev)
@@ -309,6 +323,8 @@ static l2cap_socket* btsock_l2cap_alloc_l(const char* name,
  sock->prev = NULL;
  if (socks) socks->prev = sock;
  sock->id = (socks ? socks->id : 0) + 1;
  sock->tx_bytes = 0;
  sock->rx_bytes = 0;
  socks = sock;
  /* paranoia cap on: verify no ID duplicates due to overflow and fix as needed
   */
@@ -396,6 +412,14 @@ static void on_srv_l2cap_listen_started(tBTA_JV_L2CAP_START* p_start,
  DVLOG(2) << __func__ << ": sock->handle: " << sock->handle
           << ", id: " << sock->id;

  bluetooth::common::LogSocketConnectionState(
      sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
      android::bluetooth::SocketConnectionstateEnum::
          SOCKET_CONNECTION_STATE_LISTENING,
      0, 0, sock->app_uid, sock->channel,
      sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
                   : android::bluetooth::SOCKET_ROLE_CONNECTION);

  if (!sock->server_psm_sent) {
    if (!send_app_psm_or_chan_l(sock)) {
      // closed
@@ -448,6 +472,14 @@ static void on_srv_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open,
  accept_rs->id = sock->id;
  sock->id = new_listen_id;

  bluetooth::common::LogSocketConnectionState(
      accept_rs->addr, accept_rs->id,
      accept_rs->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
      android::bluetooth::SOCKET_CONNECTION_STATE_CONNECTED, 0, 0,
      accept_rs->app_uid, accept_rs->channel,
      accept_rs->server ? android::bluetooth::SOCKET_ROLE_LISTEN
                        : android::bluetooth::SOCKET_ROLE_CONNECTION);

  // start monitor the socket
  btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP,
                       SOCK_THREAD_FD_EXCEPTION, sock->id);
@@ -489,6 +521,14 @@ static void on_srv_l2cap_le_connect_l(tBTA_JV_L2CAP_LE_OPEN* p_open,
  *(p_open->p_p_cback) = (void*)btsock_l2cap_cbk;
  *(p_open->p_user_data) = UINT_TO_PTR(accept_rs->id);

  bluetooth::common::LogSocketConnectionState(
      accept_rs->addr, accept_rs->id,
      accept_rs->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
      android::bluetooth::SOCKET_CONNECTION_STATE_CONNECTED, 0, 0,
      accept_rs->app_uid, accept_rs->channel,
      accept_rs->server ? android::bluetooth::SOCKET_ROLE_LISTEN
                        : android::bluetooth::SOCKET_ROLE_CONNECTION);

  // start monitor the socket
  btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP,
                       SOCK_THREAD_FD_EXCEPTION, sock->id);
@@ -518,6 +558,13 @@ static void on_cl_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open,
    return;
  }

  bluetooth::common::LogSocketConnectionState(
      sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
      android::bluetooth::SOCKET_CONNECTION_STATE_CONNECTED, 0, 0,
      sock->app_uid, sock->channel,
      sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
                   : android::bluetooth::SOCKET_ROLE_CONNECTION);

  // start monitoring the socketpair to get call back when app writing data
  DVLOG(2) << " connect signal sent, slot id: " << sock->id
           << ", chan: " << sock->channel << ", server: " << sock->server;
@@ -542,6 +589,13 @@ static void on_cl_l2cap_le_connect_l(tBTA_JV_L2CAP_LE_OPEN* p_open,
    return;
  }

  bluetooth::common::LogSocketConnectionState(
      sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
      android::bluetooth::SOCKET_CONNECTION_STATE_CONNECTED, 0, 0,
      sock->app_uid, sock->channel,
      sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
                   : android::bluetooth::SOCKET_ROLE_CONNECTION);

  // start monitoring the socketpair to get call back when app writing data
  DVLOG(2) << " connect signal sent, slot id: " << sock->id
           << ", chan: " << sock->channel << ", server: " << sock->server;
@@ -564,18 +618,21 @@ static void on_l2cap_connect(tBTA_JV* p_data, uint32_t id) {

  sock->tx_mtu = le_open->tx_mtu;
  if (sock->fixed_chan && le_open->status == BTA_JV_SUCCESS) {
    if (!sock->server)
    if (!sock->server) {
      on_cl_l2cap_le_connect_l(le_open, sock);
    else
    } else {
      on_srv_l2cap_le_connect_l(le_open, sock);
    }
  } else if (!sock->fixed_chan && psm_open->status == BTA_JV_SUCCESS) {
    if (!sock->server)
    if (!sock->server) {
      on_cl_l2cap_psm_connect_l(psm_open, sock);
    else
    } else {
      on_srv_l2cap_psm_connect_l(psm_open, sock);
  } else
    }
  } else {
    btsock_l2cap_free_l(sock);
  }
}

static void on_l2cap_close(tBTA_JV_L2CAP_CLOSE* p_close, uint32_t id) {
  l2cap_socket* sock;
@@ -584,6 +641,13 @@ static void on_l2cap_close(tBTA_JV_L2CAP_CLOSE* p_close, uint32_t id) {
  sock = btsock_l2cap_find_by_id_l(id);
  if (!sock) return;

  bluetooth::common::LogSocketConnectionState(
      sock->addr, sock->id, sock->is_le_coc ? BTSOCK_L2CAP_LE : BTSOCK_L2CAP,
      android::bluetooth::SOCKET_CONNECTION_STATE_DISCONNECTING, 0, 0,
      sock->app_uid, sock->channel,
      sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
                   : android::bluetooth::SOCKET_ROLE_CONNECTION);

  DVLOG(2) << __func__ << ": slot id: " << sock->id << ", fd: " << sock->our_fd
           << (sock->fixed_chan ? ", fixed_chan:" : ", PSM: ") << sock->channel
           << ", server:" << sock->server;
@@ -624,6 +688,7 @@ static void on_l2cap_write_done(uint16_t len, uint32_t id) {
                         sock->id);
  }

  sock->tx_bytes += len;
  uid_set_add_tx(uid_set, app_uid, len);
}

@@ -677,6 +742,7 @@ static void on_l2cap_data_ind(tBTA_JV* evt, uint32_t id) {
    }
  }

  sock->rx_bytes += bytes_read;
  uid_set_add_rx(uid_set, app_uid, bytes_read);
}

+53 −4
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

#include <mutex>

#include <frameworks/base/core/proto/android/bluetooth/enums.pb.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>

@@ -47,6 +48,7 @@
#include "btm_api.h"
#include "btm_int.h"
#include "btu.h"
#include "common/metrics.h"
#include "hcimsgs.h"
#include "osi/include/compat.h"
#include "osi/include/list.h"
@@ -97,6 +99,10 @@ typedef struct {
  int rfc_port_handle;
  int role;
  list_t* incoming_queue;
  // Cumulative number of bytes transmitted on this socket
  int64_t tx_bytes;
  // Cumulative number of bytes received on this socket
  int64_t rx_bytes;
} rfc_slot_t;

static rfc_slot_t rfc_slots[MAX_RFC_CHANNEL];
@@ -225,11 +231,15 @@ static rfc_slot_t* alloc_rfc_slot(const RawAddress* addr, const char* name,
  } else {
    memset(slot->service_name, 0, sizeof(slot->service_name));
  }
  if (addr) slot->addr = *addr;

  if (addr) {
    slot->addr = *addr;
  } else {
    slot->addr = RawAddress::kEmpty;
  }
  slot->id = rfc_slot_id;
  slot->f.server = server;

  slot->tx_bytes = 0;
  slot->rx_bytes = 0;
  return slot;
}

@@ -411,6 +421,12 @@ static void cleanup_rfc_slot(rfc_slot_t* slot) {
  if (slot->fd != INVALID_FD) {
    shutdown(slot->fd, SHUT_RDWR);
    close(slot->fd);
    bluetooth::common::LogSocketConnectionState(
        slot->addr, slot->id, BTSOCK_RFCOMM,
        android::bluetooth::SOCKET_CONNECTION_STATE_DISCONNECTED,
        slot->tx_bytes, slot->rx_bytes, slot->app_uid, slot->scn,
        slot->f.server ? android::bluetooth::SOCKET_ROLE_LISTEN
                       : android::bluetooth::SOCKET_ROLE_CONNECTION);
    slot->fd = INVALID_FD;
  }

@@ -436,6 +452,8 @@ static void cleanup_rfc_slot(rfc_slot_t* slot) {
  memset(&slot->f, 0, sizeof(slot->f));
  slot->id = 0;
  slot->scn_notified = false;
  slot->tx_bytes = 0;
  slot->rx_bytes = 0;
}

static bool send_app_scn(rfc_slot_t* slot) {
@@ -484,6 +502,13 @@ static void on_srv_rfc_listen_started(tBTA_JV_RFCOMM_START* p_start,

  if (p_start->status == BTA_JV_SUCCESS) {
    slot->rfc_handle = p_start->handle;
    bluetooth::common::LogSocketConnectionState(
        slot->addr, slot->id, BTSOCK_RFCOMM,
        android::bluetooth::SocketConnectionstateEnum::
            SOCKET_CONNECTION_STATE_LISTENING,
        0, 0, slot->app_uid, slot->scn,
        slot->f.server ? android::bluetooth::SOCKET_ROLE_LISTEN
                       : android::bluetooth::SOCKET_ROLE_CONNECTION);
  } else {
    cleanup_rfc_slot(slot);
  }
@@ -500,6 +525,13 @@ static uint32_t on_srv_rfc_connect(tBTA_JV_RFCOMM_SRV_OPEN* p_open,
      srv_rs, &p_open->rem_bda, p_open->handle, p_open->new_listen_handle);
  if (!accept_rs) return 0;

  bluetooth::common::LogSocketConnectionState(
      accept_rs->addr, accept_rs->id, BTSOCK_RFCOMM,
      android::bluetooth::SOCKET_CONNECTION_STATE_CONNECTED, 0, 0,
      accept_rs->app_uid, accept_rs->scn,
      accept_rs->f.server ? android::bluetooth::SOCKET_ROLE_LISTEN
                          : android::bluetooth::SOCKET_ROLE_CONNECTION);

  // Start monitoring the socket.
  btsock_thread_add_fd(pth, srv_rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_EXCEPTION,
                       srv_rs->id);
@@ -525,6 +557,13 @@ static void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN* p_open, uint32_t id) {
  slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_open->handle);
  slot->addr = p_open->rem_bda;

  bluetooth::common::LogSocketConnectionState(
      slot->addr, slot->id, BTSOCK_RFCOMM,
      android::bluetooth::SOCKET_CONNECTION_STATE_CONNECTED, 0, 0,
      slot->app_uid, slot->scn,
      slot->f.server ? android::bluetooth::SOCKET_ROLE_LISTEN
                     : android::bluetooth::SOCKET_ROLE_CONNECTION);

  if (send_app_connect_signal(slot->fd, &slot->addr, slot->scn, 0, -1)) {
    slot->f.connected = true;
  } else {
@@ -539,7 +578,15 @@ static void on_rfc_close(UNUSED_ATTR tBTA_JV_RFCOMM_CLOSE* p_close,

  // rfc_handle already closed when receiving rfcomm close event from stack.
  rfc_slot_t* slot = find_rfc_slot_by_id(id);
  if (slot) cleanup_rfc_slot(slot);
  if (slot) {
    bluetooth::common::LogSocketConnectionState(
        slot->addr, slot->id, BTSOCK_RFCOMM,
        android::bluetooth::SOCKET_CONNECTION_STATE_DISCONNECTING, 0, 0,
        slot->app_uid, slot->scn,
        slot->f.server ? android::bluetooth::SOCKET_ROLE_LISTEN
                       : android::bluetooth::SOCKET_ROLE_CONNECTION);
    cleanup_rfc_slot(slot);
  }
}

static void on_rfc_write_done(tBTA_JV_RFCOMM_WRITE* p, uint32_t id) {
@@ -559,6 +606,7 @@ static void on_rfc_write_done(tBTA_JV_RFCOMM_WRITE* p, uint32_t id) {
      btsock_thread_add_fd(pth, slot->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD,
                           slot->id);
    }
    slot->tx_bytes += p->len;
  }

  uid_set_add_tx(uid_set, app_uid, p->len);
@@ -877,6 +925,7 @@ int bta_co_rfc_data_incoming(uint32_t id, BT_HDR* p_buf) {
    list_append(slot->incoming_queue, p_buf);
  }

  slot->rx_bytes += bytes_rx;
  uid_set_add_rx(uid_set, app_uid, bytes_rx);

  return ret;  // Return 0 to disable data flow.
+35 −9
Original line number Diff line number Diff line
@@ -572,9 +572,9 @@ void BluetoothMetricsLogger::Reset() {
void LogLinkLayerConnectionEvent(const RawAddress* address,
                                 uint32_t connection_handle,
                                 android::bluetooth::DirectionEnum direction,
                                 uint32_t link_type, uint32_t hci_cmd,
                                 uint32_t hci_event, uint32_t hci_ble_event,
                                 uint32_t cmd_status, uint32_t reason_code) {
                                 uint16_t link_type, uint32_t hci_cmd,
                                 uint16_t hci_event, uint16_t hci_ble_event,
                                 uint16_t cmd_status, uint16_t reason_code) {
  std::string obfuscated_id;
  if (address != nullptr) {
    obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(*address);
@@ -588,12 +588,12 @@ void LogLinkLayerConnectionEvent(const RawAddress* address,
      connection_handle, direction, link_type, hci_cmd, hci_event,
      hci_ble_event, cmd_status, reason_code);
  if (ret < 0) {
    LOG(WARNING) << __func__ << ": failed to log status 0x"
                 << loghex(cmd_status) << ", reason 0x" << loghex(reason_code)
                 << " from cmd 0x" << loghex(hci_cmd) << ", event 0x"
                 << loghex(hci_event) << ", ble_event 0x"
                 << loghex(hci_ble_event) << " for " << address << ", handle "
                 << connection_handle << ", error " << ret;
    LOG(WARNING) << __func__ << ": failed to log status " << loghex(cmd_status)
                 << ", reason " << loghex(reason_code) << " from cmd "
                 << loghex(hci_cmd) << ", event " << loghex(hci_event)
                 << ", ble_event " << loghex(hci_ble_event) << " for "
                 << address << ", handle " << connection_handle << ", type "
                 << loghex(link_type) << ", error " << ret;
  }
}

@@ -801,6 +801,32 @@ void LogSdpAttribute(const RawAddress& address, uint16_t protocol_uuid,
  }
}

void LogSocketConnectionState(
    const RawAddress& address, int port, int type,
    android::bluetooth::SocketConnectionstateEnum connection_state,
    int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
    android::bluetooth::SocketRoleEnum socket_role) {
  std::string obfuscated_id;
  if (!address.IsEmpty()) {
    obfuscated_id = AddressObfuscator::GetInstance()->Obfuscate(address);
  }
  // nullptr and size 0 represent missing value for obfuscated_id
  android::util::BytesField obfuscated_id_field(
      address.IsEmpty() ? nullptr : obfuscated_id.c_str(),
      address.IsEmpty() ? 0 : obfuscated_id.size());
  int ret = android::util::stats_write(
      android::util::BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED,
      obfuscated_id_field, port, type, connection_state, tx_bytes, rx_bytes,
      uid, server_port, socket_role);
  if (ret < 0) {
    LOG(WARNING) << __func__ << ": failed for " << address << ", port " << port
                 << ", type " << type << ", state " << connection_state
                 << ", tx_bytes " << tx_bytes << ", rx_bytes " << rx_bytes
                 << ", uid " << uid << ", server_port " << server_port
                 << ", socket_role " << socket_role << ", error " << ret;
  }
}

}  // namespace common

}  // namespace bluetooth
+24 −3
Original line number Diff line number Diff line
@@ -301,9 +301,9 @@ static const uint32_t kUnknownConnectionHandle = 0xFFFF;
void LogLinkLayerConnectionEvent(const RawAddress* address,
                                 uint32_t connection_handle,
                                 android::bluetooth::DirectionEnum direction,
                                 uint32_t link_type, uint32_t hci_cmd,
                                 uint32_t hci_event, uint32_t hci_ble_event,
                                 uint32_t cmd_status, uint32_t reason_code);
                                 uint16_t link_type, uint32_t hci_cmd,
                                 uint16_t hci_event, uint16_t hci_ble_event,
                                 uint16_t cmd_status, uint16_t reason_code);

/**
 * Logs when Bluetooth controller failed to reply with command status within
@@ -439,6 +439,27 @@ void LogClassicPairingEvent(const RawAddress& address, uint16_t handle,
void LogSdpAttribute(const RawAddress& address, uint16_t protocol_uuid,
                     uint16_t attribute_id, size_t attribute_size,
                     const char* attribute_value);

/**
 * Logs when there is a change in Bluetooth socket connection state
 *
 * @param address address of associated device, empty if this is a server port
 * @param port port of this socket connection
 * @param type type of socket
 * @param connection_state socket connection state
 * @param tx_bytes number of bytes transmitted
 * @param rx_bytes number of bytes received
 * @param server_port server port of this socket, if any. When both
 *        |server_port| and |port| fields are populated, |port| must be spawned
 *        by |server_port|
 * @param socket_role role of this socket, server or connection
 * @param uid socket owner's uid
 */
void LogSocketConnectionState(
    const RawAddress& address, int port, int type,
    android::bluetooth::SocketConnectionstateEnum connection_state,
    int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port,
    android::bluetooth::SocketRoleEnum socket_role);
}  // namespace common

}  // namespace bluetooth