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

Commit d4246efc authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Use LE Extended Advertising Report Event when available

Bug: 30622771
Test: sl4a ConcurrentBleAdvertisingTest
Change-Id: Id85504922c21f15bc36ac8bb5e4ab962ee356e3d
parent 0f64422f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@
#include "stack/include/btm_ble_api.h"

const bt_event_mask_t BLE_EVENT_MASK = {
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x7f}};
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x16, 0x7f}};

const bt_event_mask_t CLASSIC_EVENT_MASK = {HCI_DUMO_EVENT_MASK_EXT};

+116 −37
Original line number Diff line number Diff line
@@ -1980,20 +1980,121 @@ void btm_clear_all_pending_le_entry(void) {
  }
}

/*******************************************************************************
 *
 * Function         btm_ble_process_adv_pkt
 *
 * Description      This function is called when adv packet report events are
 *                  received from the device. It updates the inquiry database.
 *                  If the inquiry database is full, the oldest entry is
void btm_ble_process_adv_addr(BD_ADDR bda, uint8_t addr_type) {
#if (BLE_PRIVACY_SPT == TRUE)
  /* map address to security record */
  bool match = btm_identity_addr_to_random_pseudo(bda, &addr_type, false);

  BTM_TRACE_DEBUG("%s: bda= %0x:%0x:%0x:%0x:%0x:%0x", __func__, bda[0], bda[1],
                  bda[2], bda[3], bda[4], bda[5]);
  /* always do RRA resolution on host */
  if (!match && BTM_BLE_IS_RESOLVE_BDA(bda)) {
    tBTM_SEC_DEV_REC* match_rec = btm_ble_resolve_random_addr(bda);
    if (match_rec) {
      match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
      memcpy(match_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);

      if (btm_ble_init_pseudo_addr(match_rec, bda)) {
        memcpy(bda, match_rec->bd_addr, BD_ADDR_LEN);
      } else {
        // Assign the original address to be the current report address
        memcpy(bda, match_rec->ble.pseudo_addr, BD_ADDR_LEN);
      }
    }
  }
#endif
}

/**
 * This function is called when extended advertising report event is received .
 * It updates the inquiry database. If the inquiry database is full, the oldest
 * entry is discarded.
 */
void btm_ble_process_ext_adv_pkt(uint8_t data_len, uint8_t* data) {
  BD_ADDR bda, direct_address;
  uint8_t* p = data;
  uint8_t addr_type, num_reports, pkt_data_len, primary_phy, secondary_phy,
      advertising_sid;
  int8_t rssi, tx_power;
  uint16_t event_type, periodic_adv_int, direct_address_type;

  /* Only process the results if the inquiry is still active */
  if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) return;

  /* Extract the number of reports in this event. */
  STREAM_TO_UINT8(num_reports, p);

  while (num_reports--) {
    if (p > data + data_len) {
      // TODO(jpawlowski): we should crash the stack here
      BTM_TRACE_ERROR(
          "Malformed LE Extended Advertising Report Event from controller - "
          "can't loop the data");
      return;
    }

    /* Extract inquiry results */
    STREAM_TO_UINT16(event_type, p);
    STREAM_TO_UINT8(addr_type, p);
    STREAM_TO_BDADDR(bda, p);
    STREAM_TO_UINT8(primary_phy, p);
    STREAM_TO_UINT8(secondary_phy, p);
    STREAM_TO_UINT8(advertising_sid, p);
    STREAM_TO_INT8(tx_power, p);
    STREAM_TO_INT8(rssi, p);
    STREAM_TO_UINT16(periodic_adv_int, p);
    STREAM_TO_UINT8(direct_address_type, p);
    STREAM_TO_BDADDR(direct_address, p);
    STREAM_TO_UINT8(pkt_data_len, p);

    uint8_t* pkt_data = p;
    p += pkt_data_len; /* Advance to the the next packet*/

    if (rssi >= 21 && rssi <= 126) {
      BTM_TRACE_ERROR("%s: bad rssi value in advertising report: ", __func__,
                      pkt_data_len, rssi);
    }

    // we parse legacy packets only for now.
    if ((event_type & 0x0010) == 0) {
      continue;
    }

    // TODO(jpawlowski): event type should be passed to
    // btm_ble_process_adv_pkt_cont. Legacy values should be transformed to new
    // value in btm_ble_process_adv_pkt
    uint8_t legacy_evt_type;
    if (event_type == 0x0013) {
      legacy_evt_type = 0x00;  // ADV_IND;
    } else if (event_type == 0x0015) {
      legacy_evt_type = 0x01;  // ADV_DIRECT_IND;
    } else if (event_type == 0x0012) {
      legacy_evt_type = 0x02;  // ADV_SCAN_IND;
    } else if (event_type == 0x0010) {
      legacy_evt_type = 0x03;  // ADV_NONCONN_IND;
    } else if (event_type == 0x001B) {
      legacy_evt_type = 0x02;  // SCAN_RSP;
    } else if (event_type == 0x001A) {
      legacy_evt_type = 0x02;  // SCAN_RSP;
    } else {
      BTM_TRACE_ERROR(
          "Malformed LE Advertising Report Event from controller - unsupported "
          "legacy event_type 0x%04x",
          event_type);
      return;
    }

    btm_ble_process_adv_addr(bda, addr_type);
    btm_ble_process_adv_pkt_cont(bda, addr_type, legacy_evt_type, pkt_data_len,
                                 pkt_data, rssi);
  }
}

/**
 * This function is called when advertising report event is received. It updates
 * the inquiry database. If the inquiry database is full, the oldest entry is
 * discarded.
 *
 * Parameters
 *
 * Returns          void
 *
 ******************************************************************************/
 */
void btm_ble_process_adv_pkt(uint8_t data_len, uint8_t* data) {
  BD_ADDR bda;
  uint8_t* p = data;
@@ -2029,29 +2130,7 @@ void btm_ble_process_adv_pkt(uint8_t data_len, uint8_t* data) {
                      pkt_data_len, rssi);
    }

#if (BLE_PRIVACY_SPT == TRUE)
    /* map address to security record */
    bool match = btm_identity_addr_to_random_pseudo(bda, &addr_type, false);

    BTM_TRACE_DEBUG("%s: bda= %0x:%0x:%0x:%0x:%0x:%0x", __func__, bda[0],
                    bda[1], bda[2], bda[3], bda[4], bda[5]);
    /* always do RRA resolution on host */
    if (!match && BTM_BLE_IS_RESOLVE_BDA(bda)) {
      tBTM_SEC_DEV_REC* match_rec = btm_ble_resolve_random_addr(bda);
      if (match_rec) {
        BTM_TRACE_DEBUG("Random match");
        match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
        memcpy(match_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);

        if (btm_ble_init_pseudo_addr(match_rec, bda)) {
          memcpy(bda, match_rec->bd_addr, BD_ADDR_LEN);
        } else {
          // Assign the original address to be the current report address
          memcpy(bda, match_rec->ble.pseudo_addr, BD_ADDR_LEN);
        }
      }
    }
#endif
    btm_ble_process_adv_addr(bda, addr_type);

    btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, pkt_data_len,
                                 pkt_data, rssi);
+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@

extern void btm_ble_refresh_raddr_timer_timeout(void* data);
extern void btm_ble_process_adv_pkt(uint8_t len, uint8_t* p);
extern void btm_ble_process_ext_adv_pkt(uint8_t len, uint8_t* p);
extern void btm_ble_proc_scan_rsp_rpt(uint8_t* p);
extern tBTM_STATUS btm_ble_read_remote_name(BD_ADDR remote_bda,
                                            tBTM_INQ_INFO* p_cur,
+5 −0
Original line number Diff line number Diff line
@@ -327,6 +327,11 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, BT_HDR* p_msg) {
          btu_ble_data_length_change_evt(p, hci_evt_len);
          break;

        case HCI_LE_EXTENDED_ADVERTISING_REPORT_EVT:
          HCI_TRACE_EVENT("HCI_LE_EXTENDED_ADVERTISING_REPORT_EVT");
          btm_ble_process_ext_adv_pkt(hci_evt_len, p);
          break;

        case HCI_LE_ADVERTISING_SET_TERMINATED_EVT:
          btm_le_on_advertising_set_terminated(p, hci_evt_len);
          break;
+1 −0
Original line number Diff line number Diff line
@@ -829,6 +829,7 @@
#define HCI_BLE_DATA_LENGTH_CHANGE_EVT 0x07
#define HCI_BLE_ENHANCED_CONN_COMPLETE_EVT 0x0a
#define HCI_BLE_DIRECT_ADV_EVT 0x0b
#define HCI_LE_EXTENDED_ADVERTISING_REPORT_EVT 0x0D
#define HCI_LE_ADVERTISING_SET_TERMINATED_EVT 0x12

/* Definitions for LE Channel Map */