OSDN Git Service

OOB: Start advertising when OOB data is generated.
authorMartin Brabham <optedoblivion@google.com>
Thu, 20 May 2021 21:30:09 +0000 (14:30 -0700)
committerMartin Brabham <optedoblivion@google.com>
Tue, 29 Jun 2021 19:33:26 +0000 (12:33 -0700)
This affords the stack the capability to provide the proper
random address and address type to the user via the OobDataCallback.

Previous to this commit, the data defaults to the public address.

This advertisement will time out, and will clear OOB data upon timeout.

Bug: 192084169
Test: Manual, test app.
Test: m bt_host_test_bta
Test: m net_test_btif_stack
Tag: #feature
Change-Id: Ia24c10e7209027b8b070b9196caba7e394ee6dcb
Merged-In: Ia24c10e7209027b8b070b9196caba7e394ee6dcb

btif/include/btif_common.h
btif/include/btif_gatt.h
btif/src/bluetooth.cc
btif/src/btif_dm.cc
stack/include/smp_api.h
stack/smp/smp_api.cc
stack/smp/smp_int.h
stack/smp/smp_keys.cc
test/mock/mock_stack_smp_api.cc

index 51effde..3ce8db6 100644 (file)
@@ -208,7 +208,8 @@ void invoke_ssp_request_cb(RawAddress bd_addr, bt_bdname_t bd_name,
                            uint32_t cod, bt_ssp_variant_t pairing_variant,
                            uint32_t pass_key);
 void invoke_oob_data_request_cb(tBT_TRANSPORT t, bool valid, Octet16 c,
-                                Octet16 r, RawAddress raw_address);
+                                Octet16 r, RawAddress raw_address,
+                                uint8_t address_type);
 void invoke_bond_state_changed_cb(bt_status_t status, RawAddress bd_addr,
                                   bt_bond_state_t state);
 void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr,
index 88f18a7..7391e6d 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef BTIF_GATT_H
 #define BTIF_GATT_H
 
+#include "include/hardware/bt_gatt.h"
+
 extern const btgatt_client_interface_t btgattClientInterface;
 extern const btgatt_server_interface_t btgattServerInterface;
 
index 7a267a3..e071a70 100644 (file)
@@ -739,7 +739,8 @@ void invoke_ssp_request_cb(RawAddress bd_addr, bt_bdname_t bd_name,
 }
 
 void invoke_oob_data_request_cb(tBT_TRANSPORT t, bool valid, Octet16 c,
-                                Octet16 r, RawAddress raw_address) {
+                                Octet16 r, RawAddress raw_address,
+                                uint8_t address_type) {
   LOG_INFO("%s", __func__);
   bt_oob_data_t oob_data = {};
 
@@ -749,8 +750,7 @@ void invoke_oob_data_request_cb(tBT_TRANSPORT t, bool valid, Octet16 c,
     oob_data.address[i] = raw_address.address[j];
     j--;
   }
-  // Set type always public
-  oob_data.address[6] = 0;
+  oob_data.address[6] = address_type;
 
   // Each value (for C and R) is 16 octets in length
   bool c_empty = true;
index a888a20..5cda4d3 100644 (file)
@@ -54,6 +54,7 @@
 #include "btif_bqr.h"
 #include "btif_config.h"
 #include "btif_dm.h"
+#include "btif_gatt.h"
 #include "btif_hd.h"
 #include "btif_hf.h"
 #include "btif_hh.h"
@@ -1334,16 +1335,16 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event,
             p_data->disc_res.num_uuids == 0) {
           LOG_INFO("SDP failed, send empty UUID to unblock bonding %s",
                    bd_addr.ToString().c_str());
-          bt_property_t prop;
+          bt_property_t prop_uuids;
           Uuid uuid = {};
 
-          prop.type = BT_PROPERTY_UUIDS;
-          prop.val = &uuid;
-          prop.len = Uuid::kNumBytes128;
+          prop_uuids.type = BT_PROPERTY_UUIDS;
+          prop_uuids.val = &uuid;
+          prop_uuids.len = Uuid::kNumBytes128;
 
           /* Send the event to the BTIF */
           invoke_remote_device_properties_cb(BT_STATUS_SUCCESS, bd_addr, 1,
-                                             &prop);
+                                             &prop_uuids);
           break;
         }
       }
@@ -2374,14 +2375,92 @@ void btif_dm_generate_local_oob_data(tBT_TRANSPORT transport) {
   if (transport == BT_TRANSPORT_BR_EDR) {
     BTM_ReadLocalOobData();
   } else if (transport == BT_TRANSPORT_LE) {
-    SMP_CrLocScOobData(base::BindOnce(&btif_dm_proc_loc_oob));
+    // Call create data first, so we don't have to hold on to the address for
+    // the state machine lifecycle.  Rather, lets create the data, then start
+    // advertising then request the address.
+    SMP_CrLocScOobData();
   }
 }
 
+// Step Four: CallBack from Step Three
+static void get_address_callback(tBT_TRANSPORT transport, bool is_valid,
+                                 const Octet16& c, const Octet16& r,
+                                 uint8_t address_type, RawAddress address) {
+  invoke_oob_data_request_cb(transport, is_valid, c, r, address, address_type);
+}
+
+// Step Three: CallBack from Step Two, advertise and get address
+static void start_advertising_callback(uint8_t id, tBT_TRANSPORT transport,
+                                       bool is_valid, const Octet16& c,
+                                       const Octet16& r, uint8_t status) {
+  if (status != 0) {
+    LOG_INFO("OOB get advertiser ID failed with status %hhd", status);
+    invoke_oob_data_request_cb(transport, false, c, r, RawAddress{}, 0x00);
+    SMP_ClearLocScOobData();
+    return;
+  }
+  LOG_DEBUG("OOB advertiser with id %hhd", id);
+  auto advertiser = get_ble_advertiser_instance();
+  advertiser->GetOwnAddress(
+      id, base::Bind(&get_address_callback, transport, is_valid, c, r));
+}
+
+static void timeout_cb(uint8_t id, uint8_t status) {
+  LOG_INFO("OOB advertiser with id %hhd timed out with status %hhd", id,
+           status);
+  auto advertiser = get_ble_advertiser_instance();
+  advertiser->Unregister(id);
+  SMP_ClearLocScOobData();
+}
+
+// Step Two: CallBack from Step One, advertise and get address
+static void id_status_callback(tBT_TRANSPORT transport, bool is_valid,
+                               const Octet16& c, const Octet16& r, uint8_t id,
+                               uint8_t status) {
+  if (status != 0) {
+    LOG_INFO("OOB get advertiser ID failed with status %hhd", status);
+    invoke_oob_data_request_cb(transport, false, c, r, RawAddress{}, 0x00);
+    SMP_ClearLocScOobData();
+    return;
+  }
+
+  auto advertiser = get_ble_advertiser_instance();
+  AdvertiseParameters parameters;
+  parameters.advertising_event_properties = 0x0041 /* connectable, tx power */;
+  parameters.min_interval = 0xa0;   // 100 ms
+  parameters.max_interval = 0x500;  // 800 ms
+  parameters.channel_map = 0x7;     // Use all the channels
+  parameters.tx_power = 0;          // 0 dBm
+  parameters.primary_advertising_phy = 1;
+  parameters.secondary_advertising_phy = 2;
+  parameters.scan_request_notification_enable = 0;
+
+  std::vector<uint8_t> advertisement{0x02, 0x01 /* Flags */,
+                                     0x02 /* Connectable */};
+  std::vector<uint8_t> scan_data{};
+
+  advertiser->StartAdvertising(
+      id,
+      base::Bind(&start_advertising_callback, id, transport, is_valid, c, r),
+      parameters, advertisement, scan_data, 3600 /* timeout_s */,
+      base::Bind(&timeout_cb, id));
+}
+
+// Step One: Start the advertiser
+static void start_oob_advertiser(tBT_TRANSPORT transport, bool is_valid,
+                                 const Octet16& c, const Octet16& r) {
+  auto advertiser = get_ble_advertiser_instance();
+  advertiser->RegisterAdvertiser(
+      base::Bind(&id_status_callback, transport, is_valid, c, r));
+}
+
 void btif_dm_proc_loc_oob(tBT_TRANSPORT transport, bool is_valid,
                           const Octet16& c, const Octet16& r) {
-  invoke_oob_data_request_cb(transport, is_valid, c, r,
-                             *controller_get_interface()->get_address());
+  // is_valid is important for deciding which OobDataCallback function to use
+  if (!is_valid)
+    invoke_oob_data_request_cb(transport, false, c, r, RawAddress{}, 0x00);
+  // Now that we have the data, lets start advertising and get the address.
+  start_oob_advertiser(transport, is_valid, c, r);
 }
 
 /*******************************************************************************
index bc4060c..9787bd8 100644 (file)
@@ -182,14 +182,17 @@ extern void SMP_SecureConnectionOobDataReply(uint8_t* p_data);
  * Description      This function is called to generate a public key to be
  *                  passed to a remote device via an Out of Band transport
  *
- * Parameters:      callback - receive the data
+ ******************************************************************************/
+extern void SMP_CrLocScOobData();
+
+/*******************************************************************************
+ *
+ * Function         SMP_ClearLocScOobData
+ *
+ * Description      This function is called to clear out the OOB stored locally.
  *
  ******************************************************************************/
-extern void SMP_CrLocScOobData(
-    base::OnceCallback<void(tBT_TRANSPORT, bool,
-                            const std::array<unsigned char, 16>&,
-                            const std::array<unsigned char, 16>&)>
-        callback);
+extern void SMP_ClearLocScOobData();
 
 // Called when LTK request is received from controller.
 extern bool smp_proc_ltk_request(const RawAddress& bda);
index 452e68f..164971d 100644 (file)
@@ -557,16 +557,19 @@ void SMP_SecureConnectionOobDataReply(uint8_t* p_data) {
  * Function         SMP_CrLocScOobData
  *
  * Description      This function is called to generate a public key to be
- *                  passed to a remote device via Out of Band transport
- *
- * Parameters:      callback - receive the data
+ *                  passed to a remote device via Out of Band transport.
  *
  ******************************************************************************/
-void SMP_CrLocScOobData(
-    base::OnceCallback<void(tBT_TRANSPORT, bool,
-                            const std::array<unsigned char, 16>&,
-                            const std::array<unsigned char, 16>&)>
-        callback) {
+void SMP_CrLocScOobData() {
   tSMP_INT_DATA smp_int_data;
   smp_sm_event(&smp_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, &smp_int_data);
 }
+
+/*******************************************************************************
+ *
+ * Function         SMP_ClearLocScOobData
+ *
+ * Description      This function is called to clear out the OOB stored locally.
+ *
+ ******************************************************************************/
+void SMP_ClearLocScOobData() { smp_clear_local_oob_data(); }
index 88f125c..54fdfdf 100644 (file)
@@ -464,5 +464,6 @@ extern void smp_xor_128(Octet16* a, const Octet16& b);
 /* Save the p_cb->sc_oob_data.loc_oob_data for later, since the p_cb gets
  * cleaned up */
 extern void smp_save_local_oob_data(tSMP_CB* p_cb);
+extern void smp_clear_local_oob_data();
 
 #endif /* SMP_INT_H */
index 2bddd0d..50b9245 100644 (file)
@@ -63,6 +63,8 @@ void smp_save_local_oob_data(tSMP_CB* p_cb) {
   saved_local_oob_data = p_cb->sc_oob_data.loc_oob_data;
 }
 
+void smp_clear_local_oob_data() { saved_local_oob_data = {}; }
+
 static bool is_empty(tSMP_LOC_OOB_DATA* data) {
   tSMP_LOC_OOB_DATA empty_data = {};
   return memcmp(data, &empty_data, sizeof(tSMP_LOC_OOB_DATA)) == 0;
index ae48e42..6d6335a 100644 (file)
@@ -79,10 +79,6 @@ void SMP_SecurityGrant(const RawAddress& bd_addr, tSMP_STATUS res) {
   mock_function_count_map[__func__]++;
 }
 
-void SMP_CrLocScOobData(
-    base::OnceCallback<void(tBT_TRANSPORT, bool,
-                            const std::array<unsigned char, 16>&,
-                            const std::array<unsigned char, 16>&)>
-        callback) {
-  mock_function_count_map[__func__]++;
-}
+void SMP_CrLocScOobData() { mock_function_count_map[__func__]++; }
+
+void SMP_ClearLocScOobData() { mock_function_count_map[__func__]++; }