From f33ade65803e4bb72dc30b790afbe0bb4758f151 Mon Sep 17 00:00:00 2001
From: Jakub Pawlowski <jpawlowski@google.com>
Date: Mon, 23 Jan 2017 14:03:19 -0800
Subject: [PATCH] Add advertising handle zero quirk

Some controllers are strict about VSC handle mapping, and don't allow
using zero value.

Test: manual test
Change-Id: Ia2df17af16e0e4da375d6e7d5b5f882ced508ce9
---
 system/stack/btm/ble_advertiser_hci_interface.cc | 14 ++++++++++++++
 system/stack/btm/ble_advertiser_hci_interface.h  |  3 +++
 system/stack/btm/btm_ble_multi_adv.cc            |  6 ++++++
 3 files changed, 23 insertions(+)

diff --git a/system/stack/btm/ble_advertiser_hci_interface.cc b/system/stack/btm/ble_advertiser_hci_interface.cc
index 4b2d7632900..f430fe017f2 100644
--- a/system/stack/btm/ble_advertiser_hci_interface.cc
+++ b/system/stack/btm/ble_advertiser_hci_interface.cc
@@ -24,6 +24,7 @@
 #include <utility>
 #include "btm_api.h"
 #include "btm_ble_api.h"
+#include "btm_int_types.h"
 #include "device/include/controller.h"
 
 #define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8
@@ -203,6 +204,19 @@ class BleAdvertiserVscHciInterfaceImpl : public BleAdvertiserHciInterface {
                command_complete);
   }
 
+  bool QuirkAdvertiserZeroHandle() override {
+    // Android BT HCI Requirements version 0.96 and below specify that handle 0
+    // is equal to standard HCI interface, and should be accessed using non-VSC
+    // commands. Broadcom controllers are strict about this requirement, so
+    // don't use 0 handle.
+    if (BTM_IS_BRCM_CONTROLLER()) {
+      LOG(INFO) << "QuirkAdvertiserZeroHandle in use";
+      return true;
+    }
+
+    return false;
+  }
+
  public:
   static void VendorSpecificEventCback(uint8_t length, uint8_t* p) {
     VLOG(1) << __func__;
diff --git a/system/stack/btm/ble_advertiser_hci_interface.h b/system/stack/btm/ble_advertiser_hci_interface.h
index b429d880207..17abfa5719c 100644
--- a/system/stack/btm/ble_advertiser_hci_interface.h
+++ b/system/stack/btm/ble_advertiser_hci_interface.h
@@ -71,6 +71,9 @@ class BleAdvertiserHciInterface {
   virtual void Enable(uint8_t enable, uint8_t handle, uint16_t duration,
                       uint8_t max_extended_advertising_events,
                       status_cb command_complete) = 0;
+
+  // Some implementation don't behave well when handle value 0 is used.
+  virtual bool QuirkAdvertiserZeroHandle() { return 0; }
 };
 
 #endif  // BLE_ADVERTISER_HCI_INTERFACE_H
diff --git a/system/stack/btm/btm_ble_multi_adv.cc b/system/stack/btm/btm_ble_multi_adv.cc
index e2c08f440fb..d2655210d9b 100644
--- a/system/stack/btm/btm_ble_multi_adv.cc
+++ b/system/stack/btm/btm_ble_multi_adv.cc
@@ -67,6 +67,7 @@ void btm_ble_adv_raddr_timer_timeout(void* data);
 namespace {
 
 void DoNothing(uint8_t) {}
+void DoNothing2(uint8_t, uint8_t) {}
 
 std::queue<base::Callback<void(tBTM_RAND_ENC* p)>>* rand_gen_inst_id = nullptr;
 
@@ -511,6 +512,11 @@ void btm_ble_adv_init() {
   BleAdvertisingManager::Initialize(BleAdvertiserHciInterface::Get());
   BleAdvertiserHciInterface::Get()->SetAdvertisingEventObserver(
       (BleAdvertisingManagerImpl*)BleAdvertisingManager::Get());
+
+  if (BleAdvertiserHciInterface::Get()->QuirkAdvertiserZeroHandle()) {
+    // If handle 0 can't be used, register advertiser for it, but never use it.
+    BleAdvertisingManager::Get()->RegisterAdvertiser(Bind(DoNothing2));
+  }
 }
 
 /*******************************************************************************
-- 
GitLab