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

Commit 6fb1e4fc authored by Michael Sun's avatar Michael Sun Committed by Mingguang Xu
Browse files

btaa: HCI LE and special event process

Implementation the HCI process for LE and special (events that contains
more than one device information) events.

Tag: #feature
Bug: 177230507
Test: verified locally BTAA can process LE and special events.
BYPASS_LONG_LINES_REASON: consist with gd format

Change-Id: If30069673bd6164b22af926ca17ea9830f891a8a
parent 4cc57fc4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ struct CmdEvtActivityClassification {

CmdEvtActivityClassification lookup_cmd(hci::OpCode opcode);
CmdEvtActivityClassification lookup_event(hci::EventCode event_code);
CmdEvtActivityClassification lookup_le_event(hci::SubeventCode subevent_code);

}  // namespace activity_attribution
}  // namespace bluetooth
+64 −0
Original line number Diff line number Diff line
@@ -397,5 +397,69 @@ CmdEvtActivityClassification lookup_event(hci::EventCode event_code) {
  return classification;
}

CmdEvtActivityClassification lookup_le_event(hci::SubeventCode subevent_code) {
  CmdEvtActivityClassification classification = {};
  switch (subevent_code) {
    case hci::SubeventCode::CONNECTION_COMPLETE:
    case hci::SubeventCode::ENHANCED_CONNECTION_COMPLETE:
      classification = {.activity = Activity::CONNECT, .connection_handle_pos = 4, .address_pos = 7};
      break;

    case hci::SubeventCode::CONNECTION_UPDATE_COMPLETE:
    case hci::SubeventCode::READ_REMOTE_FEATURES_COMPLETE:
    case hci::SubeventCode::PHY_UPDATE_COMPLETE:
    case hci::SubeventCode::CTE_REQUEST_FAILED:
    case hci::SubeventCode::TRANSMIT_POWER_REPORTING:
      classification = {.activity = Activity::CONNECT, .connection_handle_pos = 4, .address_pos = 0};
      break;

    case hci::SubeventCode::LONG_TERM_KEY_REQUEST:
    case hci::SubeventCode::REMOTE_CONNECTION_PARAMETER_REQUEST:
    case hci::SubeventCode::DATA_LENGTH_CHANGE:
    case hci::SubeventCode::CHANNEL_SELECTION_ALGORITHM:
    case hci::SubeventCode::CONNECTION_IQ_REPORT:
    case hci::SubeventCode::PATH_LOSS_THRESHOLD:
      classification = {.activity = Activity::CONNECT, .connection_handle_pos = 3, .address_pos = 0};
      break;

    case hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE:
    case hci::SubeventCode::GENERATE_DHKEY_COMPLETE:
      classification = {.activity = Activity::CONTROL, .connection_handle_pos = 0, .address_pos = 0};
      break;

    case hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED:
    case hci::SubeventCode::PERIODIC_ADVERTISING_REPORT:
    case hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST:
    case hci::SubeventCode::ADVERTISING_SET_TERMINATED:
      classification = {.activity = Activity::ADVERTISE, .connection_handle_pos = 0, .address_pos = 0};
      break;

    case hci::SubeventCode::SCAN_TIMEOUT:
    case hci::SubeventCode::BIG_INFO_ADVERTISING_REPORT:
    case hci::SubeventCode::CONNECTIONLESS_IQ_REPORT:
    case hci::SubeventCode::CREATE_BIG_COMPLETE:
    case hci::SubeventCode::TERMINATE_BIG_COMPLETE:
    case hci::SubeventCode::BIG_SYNC_ESTABLISHED:
    case hci::SubeventCode::BIG_SYNC_LOST:
    case hci::SubeventCode::REQUEST_PEER_SCA_COMPLETE:
      classification = {.activity = Activity::SCAN, .connection_handle_pos = 0, .address_pos = 0};
      break;

    case hci::SubeventCode::SCAN_REQUEST_RECEIVED:
      classification = {.activity = Activity::ADVERTISE, .connection_handle_pos = 0, .address_pos = 5};
      break;

    case hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED:
    case hci::SubeventCode::CIS_ESTABLISHED:
    case hci::SubeventCode::CIS_REQUEST:
      classification = {.activity = Activity::SCAN, .connection_handle_pos = 4, .address_pos = 0};
      break;

    default:
      classification = {.activity = Activity::UNKNOWN, .connection_handle_pos = 0, .address_pos = 0};
  }
  return classification;
}

}  // namespace activity_attribution
}  // namespace bluetooth
+82 −0
Original line number Diff line number Diff line
@@ -46,6 +46,86 @@ struct PendingCommand {
static DeviceParser device_parser;
static PendingCommand pending_command;

static void process_le_event(std::vector<BtaaHciPacket>& btaa_hci_packets, int16_t byte_count, hci::EventView& event) {
  uint16_t connection_handle_value = 0;
  hci::Address address_value;

  auto le_packet_view = hci::LeMetaEventView::Create(event);
  if (!le_packet_view.IsValid()) {
    return;
  }

  auto subevent_code = le_packet_view.GetSubeventCode();
  auto le_event_info = lookup_le_event(subevent_code);

  if (le_event_info.activity != Activity::UNKNOWN) {
    // lookup_le_event returns all simple classic event which does not require additional processing.
    if (le_event_info.connection_handle_pos) {
      auto connection_handle_it = event.begin() + le_event_info.connection_handle_pos;
      connection_handle_value = connection_handle_it.extract<uint16_t>();
    }
    if (le_event_info.address_pos) {
      auto address_value_it = event.begin() + le_event_info.address_pos;
      address_value = address_value_it.extract<hci::Address>();
    }
    device_parser.match_handle_with_address(connection_handle_value, address_value);
    btaa_hci_packets.push_back(BtaaHciPacket(le_event_info.activity, address_value, byte_count));
  }
}

static void process_special_event(
    std::vector<BtaaHciPacket>& btaa_hci_packets,
    hci::EventCode event_code,
    uint16_t byte_count,
    hci::EventView& event) {
  uint16_t avg_byte_count;
  hci::Address address_value;

  switch (event_code) {
    case hci::EventCode::INQUIRY_RESULT:
    case hci::EventCode::INQUIRY_RESULT_WITH_RSSI: {
      auto packet_view = hci::InquiryResultView::Create(event);
      if (!packet_view.IsValid()) {
        return;
      }
      auto inquiry_results = packet_view.GetInquiryResults();
      avg_byte_count = byte_count / inquiry_results.size();
      for (auto& inquiry_result : inquiry_results) {
        btaa_hci_packets.push_back(BtaaHciPacket(Activity::SCAN, inquiry_result.bd_addr_, avg_byte_count));
      }
    } break;

    case hci::EventCode::NUMBER_OF_COMPLETED_PACKETS: {
      auto packet_view = hci::NumberOfCompletedPacketsView::Create(event);
      if (!packet_view.IsValid()) {
        return;
      }
      auto completed_packets = packet_view.GetCompletedPackets();
      avg_byte_count = byte_count / completed_packets.size();
      for (auto& completed_packet : completed_packets) {
        device_parser.match_handle_with_address(completed_packet.connection_handle_, address_value);
        btaa_hci_packets.push_back(BtaaHciPacket(Activity::CONNECT, address_value, avg_byte_count));
      }
    } break;

    case hci::EventCode::RETURN_LINK_KEYS: {
      auto packet_view = hci::ReturnLinkKeysView::Create(event);
      if (!packet_view.IsValid()) {
        return;
      }
      auto keys_and_addresses = packet_view.GetKeys();
      avg_byte_count = byte_count / keys_and_addresses.size();
      for (auto& key_and_address : keys_and_addresses) {
        btaa_hci_packets.push_back(BtaaHciPacket(Activity::CONNECT, key_and_address.address_, avg_byte_count));
      }
    } break;

    default: {
      btaa_hci_packets.push_back(BtaaHciPacket(Activity::UNKNOWN, address_value, byte_count));
    } break;
  }
}

static void process_command(
    std::vector<BtaaHciPacket>& btaa_hci_packets,
    packet::PacketView<packet::kLittleEndian>& packet_view,
@@ -123,11 +203,13 @@ static void process_event(
        break;
      }
      case hci::EventCode::LE_META_EVENT:
        process_le_event(btaa_hci_packets, byte_count, event);
        break;
      case hci::EventCode::VENDOR_SPECIFIC:
        btaa_hci_packets.push_back(BtaaHciPacket(Activity::VENDOR, address_value, byte_count));
        break;
      default:
        process_special_event(btaa_hci_packets, event_code, byte_count, event);
        break;
    }
  }