Merge "L2CAP: Delete callbacks from queue after use"
diff --git a/gd/shim/Android.bp b/gd/shim/Android.bp
index 4ef329d..ae85b94 100644
--- a/gd/shim/Android.bp
+++ b/gd/shim/Android.bp
@@ -1,6 +1,7 @@
filegroup {
name: "BluetoothShimSources",
srcs: [
+ "advertising.cc",
"controller.cc",
"connectability.cc",
"discoverability.cc",
diff --git a/gd/shim/advertising.cc b/gd/shim/advertising.cc
new file mode 100644
index 0000000..b7e0b4e
--- /dev/null
+++ b/gd/shim/advertising.cc
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "bt_gd_shim"
+
+#include <functional>
+#include <memory>
+
+#include "hci/address.h"
+#include "hci/hci_packets.h"
+#include "hci/le_advertising_manager.h"
+#include "module.h"
+#include "os/handler.h"
+#include "os/log.h"
+#include "shim/advertising.h"
+
+namespace bluetooth {
+namespace shim {
+
+struct Advertising::impl {
+ hci::LeAdvertisingManager* module_{nullptr};
+
+ impl(hci::LeAdvertisingManager* module);
+ ~impl();
+};
+
+const ModuleFactory Advertising::Factory = ModuleFactory([]() { return new Advertising(); });
+
+Advertising::impl::impl(hci::LeAdvertisingManager* advertising_manager) : module_(advertising_manager) {}
+
+Advertising::impl::~impl() {}
+
+/**
+ * Module methods
+ */
+void Advertising::ListDependencies(ModuleList* list) {
+ list->add<hci::LeAdvertisingManager>();
+}
+
+void Advertising::Start() {
+ pimpl_ = std::make_unique<impl>(GetDependency<hci::LeAdvertisingManager>());
+}
+
+void Advertising::Stop() {
+ pimpl_.reset();
+}
+
+} // namespace shim
+} // namespace bluetooth
diff --git a/gd/shim/advertising.h b/gd/shim/advertising.h
new file mode 100644
index 0000000..17c094a
--- /dev/null
+++ b/gd/shim/advertising.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "module.h"
+#include "shim/iadvertising.h"
+
+namespace bluetooth {
+namespace shim {
+
+class Advertising : public bluetooth::Module, public bluetooth::shim::IAdvertising {
+ public:
+ Advertising() = default;
+ ~Advertising() = default;
+
+ static const ModuleFactory Factory;
+
+ protected:
+ void ListDependencies(ModuleList* list) override; // Module
+ void Start() override; // Module
+ void Stop() override; // Module
+
+ private:
+ struct impl;
+ std::unique_ptr<impl> pimpl_;
+ DISALLOW_COPY_AND_ASSIGN(Advertising);
+};
+
+} // namespace shim
+} // namespace bluetooth
diff --git a/gd/shim/iadvertising.h b/gd/shim/iadvertising.h
new file mode 100644
index 0000000..85a75c6
--- /dev/null
+++ b/gd/shim/iadvertising.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+/**
+ * The gd API exported to the legacy api
+ */
+namespace bluetooth {
+namespace shim {
+
+struct IAdvertising {
+ virtual ~IAdvertising() {}
+};
+
+} // namespace shim
+} // namespace bluetooth
diff --git a/gd/shim/istack.h b/gd/shim/istack.h
index af2b62d..37751a1 100644
--- a/gd/shim/istack.h
+++ b/gd/shim/istack.h
@@ -23,6 +23,7 @@
namespace bluetooth {
namespace shim {
+struct IAdvertising;
struct IController;
struct IConnectability;
struct IDiscoverability;
@@ -35,6 +36,7 @@
virtual void Start() = 0;
virtual void Stop() = 0;
+ virtual IAdvertising* GetAdvertising() = 0;
virtual IController* GetController() = 0;
virtual IConnectability* GetConnectability() = 0;
virtual IDiscoverability* GetDiscoverability() = 0;
diff --git a/gd/shim/only_include_this_file_into_legacy_stack___ever.h b/gd/shim/only_include_this_file_into_legacy_stack___ever.h
index bce2a66..3b07cfc 100644
--- a/gd/shim/only_include_this_file_into_legacy_stack___ever.h
+++ b/gd/shim/only_include_this_file_into_legacy_stack___ever.h
@@ -24,6 +24,7 @@
* Only common data structures should be used to pass data between the stacks.
*
*/
+#include "gd/shim/iadvertising.h"
#include "gd/shim/iconnectability.h"
#include "gd/shim/icontroller.h"
#include "gd/shim/idiscoverability.h"
diff --git a/gd/shim/stack.cc b/gd/shim/stack.cc
index 8b02e6b..db0b774 100644
--- a/gd/shim/stack.cc
+++ b/gd/shim/stack.cc
@@ -20,6 +20,7 @@
#include "hal/hci_hal.h"
#include "hci/acl_manager.h"
#include "hci/classic_security_manager.h"
+#include "hci/le_advertising_manager.h"
#include "l2cap/classic/l2cap_classic_module.h"
#include "l2cap/le/l2cap_le_module.h"
#include "neighbor/connectability.h"
@@ -30,6 +31,7 @@
#include "os/log.h"
#include "os/thread.h"
#include "security/security_module.h"
+#include "shim/advertising.h"
#include "shim/connectability.h"
#include "shim/controller.h"
#include "shim/discoverability.h"
@@ -52,6 +54,7 @@
ModuleList modules;
modules.add<::bluetooth::hal::HciHal>();
modules.add<::bluetooth::hci::AclManager>();
+ modules.add<::bluetooth::hci::LeAdvertisingManager>();
modules.add<::bluetooth::l2cap::classic::L2capClassicModule>();
modules.add<::bluetooth::l2cap::le::L2capLeModule>();
modules.add<::bluetooth::neighbor::ConnectabilityModule>();
@@ -62,6 +65,7 @@
modules.add<::bluetooth::shim::Controller>();
modules.add<::bluetooth::shim::HciLayer>();
modules.add<::bluetooth::security::SecurityModule>();
+ modules.add<::bluetooth::shim::Advertising>();
modules.add<::bluetooth::shim::Connectability>();
modules.add<::bluetooth::shim::Discoverability>();
modules.add<::bluetooth::shim::Inquiry>();
@@ -88,6 +92,10 @@
LOG_INFO("%s Successfully shut down Gd stack", __func__);
}
+ IAdvertising* GetAdvertising() {
+ return stack_manager_.GetInstance<bluetooth::shim::Advertising>();
+ }
+
IController* GetController() {
return stack_manager_.GetInstance<bluetooth::shim::Controller>();
}
@@ -135,6 +143,10 @@
pimpl_->Stop();
}
+bluetooth::shim::IAdvertising* bluetooth::shim::Stack::GetAdvertising() {
+ return pimpl_->GetAdvertising();
+}
+
bluetooth::shim::IConnectability* bluetooth::shim::Stack::GetConnectability() {
return pimpl_->GetConnectability();
}
diff --git a/gd/shim/stack.h b/gd/shim/stack.h
index f56852a..dc35780 100644
--- a/gd/shim/stack.h
+++ b/gd/shim/stack.h
@@ -18,6 +18,7 @@
#include <memory>
+#include "shim/iadvertising.h"
#include "shim/iconnectability.h"
#include "shim/icontroller.h"
#include "shim/idiscoverability.h"
@@ -41,6 +42,7 @@
void Start() override; // IStack
void Stop() override; // IStack
+ IAdvertising* GetAdvertising() override; // IStack
IController* GetController() override; // IStack
IConnectability* GetConnectability() override; // IStack
IHciLayer* GetHciLayer() override; // IStack
diff --git a/main/shim/l2cap.cc b/main/shim/l2cap.cc
index fb4dd02..98db9cb 100644
--- a/main/shim/l2cap.cc
+++ b/main/shim/l2cap.cc
@@ -26,6 +26,7 @@
constexpr size_t kBtHdrSize = sizeof(BT_HDR);
constexpr uint16_t kInvalidConnectionInterfaceDescriptor = 0;
constexpr bool kDisconnectResponseRequired = false;
+constexpr uint16_t kConnectionSuccess = 0;
bool bluetooth::legacy::shim::PsmData::IsPsmAllocated(uint16_t psm) const {
return psm_to_callback_map_.find(psm) != psm_to_callback_map_.end();
@@ -159,14 +160,34 @@
auto completed = register_completed.get_future();
bluetooth::shim::GetL2cap()->RegisterService(
psm,
- std::bind(&bluetooth::legacy::shim::L2cap::OnConnectionReady, this,
- std::placeholders::_1, std::placeholders::_2,
- std::placeholders::_3),
+ std::bind(
+ &bluetooth::legacy::shim::L2cap::OnRemoteInitiatedConnectionCreated,
+ this, std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3),
std::move(register_completed));
completed.wait();
LOG_DEBUG(LOG_TAG, "Successfully registered service on psm:%hd", psm);
}
+void bluetooth::legacy::shim::L2cap::OnRemoteInitiatedConnectionCreated(
+ std::string string_address, uint16_t psm, uint16_t cid) {
+ RawAddress raw_address;
+ RawAddress::FromString(string_address, raw_address);
+
+ LOG_DEBUG(LOG_TAG,
+ "Sending connection indicator to upper stack from device:%s "
+ "psm:%hd cid:%hd",
+ string_address.c_str(), psm, cid);
+
+ CHECK(!ConnectionExists(cid));
+ cid_to_psm_map_[cid] = psm;
+ SetCallbacks(cid, Classic().Callbacks(psm));
+ const tL2CAP_APPL_INFO* callbacks = Classic().Callbacks(psm);
+ CHECK(callbacks != nullptr);
+ callbacks->pL2CA_ConnectInd_Cb(raw_address, cid, psm /* UNUSED */,
+ 0 /* UNUSED */);
+}
+
void bluetooth::legacy::shim::L2cap::UnregisterService(uint16_t psm) {
if (!Classic().IsPsmRegistered(psm)) {
LOG_WARN(LOG_TAG,
@@ -182,9 +203,6 @@
uint16_t bluetooth::legacy::shim::L2cap::CreateConnection(
uint16_t psm, const RawAddress& raw_address) {
- LOG_DEBUG(LOG_TAG, "Requesting connection to psm:%hd address:%s", psm,
- raw_address.ToString().c_str());
-
if (!Classic().IsPsmRegistered(psm)) {
LOG_WARN(LOG_TAG, "Service must be registered in order to connect psm:%hd",
psm);
@@ -193,12 +211,18 @@
std::promise<uint16_t> connect_completed;
auto completed = connect_completed.get_future();
+ LOG_DEBUG(LOG_TAG,
+ "Starting local initiated connection to psm:%hd address:%s", psm,
+ raw_address.ToString().c_str());
+
bluetooth::shim::GetL2cap()->CreateConnection(
psm, raw_address.ToString(),
- std::bind(&bluetooth::legacy::shim::L2cap::OnConnectionReady, this,
- std::placeholders::_1, std::placeholders::_2,
- std::placeholders::_3),
+ std::bind(
+ &bluetooth::legacy::shim::L2cap::OnLocalInitiatedConnectionCreated,
+ this, std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3),
std::move(connect_completed));
+
uint16_t cid = completed.get();
if (cid == kInvalidConnectionInterfaceDescriptor) {
LOG_WARN(LOG_TAG,
@@ -209,33 +233,32 @@
"Successfully started connection to psm:%hd address:%s"
" connection_interface_descriptor:%hd",
psm, raw_address.ToString().c_str(), cid);
- CHECK(cid_to_psm_map_.find(cid) == cid_to_psm_map_.end());
+ CHECK(!ConnectionExists(cid));
cid_to_psm_map_[cid] = psm;
SetCallbacks(cid, Classic().Callbacks(psm));
- const tL2CAP_APPL_INFO* callbacks = Classic().Callbacks(psm);
- CHECK(callbacks != nullptr);
}
return cid;
}
-void bluetooth::legacy::shim::L2cap::OnConnectionReady(
- std::string address_string, uint16_t psm, uint16_t cid) {
- LOG_DEBUG(
- LOG_TAG,
- "l2cap got new connection psm:%hd connection_interface_descriptor:%hd",
- psm, cid);
+void bluetooth::legacy::shim::L2cap::OnLocalInitiatedConnectionCreated(
+ std::string string_address, uint16_t psm, uint16_t cid) {
+ LOG_DEBUG(LOG_TAG,
+ "Sending connection confirm to the upper stack but really "
+ "a connection to %s has already been done cid:%hd",
+ string_address.c_str(), cid);
+ // TODO(cmanton) Make sure the device is correct for locally initiated
const tL2CAP_APPL_INFO* callbacks = Classic().Callbacks(psm);
- if (callbacks == nullptr) {
- return;
- }
- LOG_DEBUG(LOG_TAG, "%s Setting postable map for cid:%d", __func__, cid);
-}
+ CHECK(callbacks != nullptr);
+ callbacks->pL2CA_ConnectCfm_Cb(cid, kConnectionSuccess);
+};
bool bluetooth::legacy::shim::L2cap::Write(uint16_t cid, BT_HDR* bt_hdr) {
- CHECK(ConnectionExists(cid));
CHECK(bt_hdr != nullptr);
const uint8_t* data = bt_hdr->data + bt_hdr->offset;
size_t len = bt_hdr->len;
+ if (!ConnectionExists(cid) || len == 0) {
+ return false;
+ }
LOG_DEBUG(LOG_TAG, "Writing data cid:%hd len:%zd", cid, len);
bluetooth::shim::GetL2cap()->Write(cid, data, len);
return true;
@@ -243,20 +266,24 @@
bool bluetooth::legacy::shim::L2cap::WriteFlushable(uint16_t cid,
BT_HDR* bt_hdr) {
- CHECK(ConnectionExists(cid));
CHECK(bt_hdr != nullptr);
const uint8_t* data = bt_hdr->data + bt_hdr->offset;
size_t len = bt_hdr->len;
+ if (!ConnectionExists(cid) || len == 0) {
+ return false;
+ }
bluetooth::shim::GetL2cap()->WriteFlushable(cid, data, len);
return true;
}
bool bluetooth::legacy::shim::L2cap::WriteNonFlushable(uint16_t cid,
BT_HDR* bt_hdr) {
- CHECK(ConnectionExists(cid));
CHECK(bt_hdr != nullptr);
const uint8_t* data = bt_hdr->data + bt_hdr->offset;
size_t len = bt_hdr->len;
+ if (!ConnectionExists(cid) || len == 0) {
+ return false;
+ }
bluetooth::shim::GetL2cap()->WriteNonFlushable(cid, data, len);
return true;
}
@@ -278,6 +305,7 @@
static_cast<BT_HDR*>(osi_calloc(data.size() + kBtHdrSize));
std::copy(data.begin(), data.end(), bt_hdr->data);
bt_hdr->len = data.size();
+ CHECK(cid_to_callback_map_.find(cid) != cid_to_callback_map_.end());
cid_to_callback_map_[cid]->pL2CA_DataInd_Cb(cid, bt_hdr);
});
@@ -307,14 +335,12 @@
bool bluetooth::legacy::shim::L2cap::ConfigRequest(
uint16_t cid, const tL2CAP_CFG_INFO* config_info) {
CHECK(ConnectionExists(cid));
- LOG_INFO(LOG_TAG, "Received config request from upper layer");
- CHECK(cid_to_psm_map_.find(cid) != cid_to_psm_map_.end());
- const tL2CAP_APPL_INFO* callbacks = Classic().Callbacks(cid_to_psm_map_[cid]);
- CHECK(callbacks != nullptr);
- CHECK(cid_to_postable_map_.count(cid) == 1);
+ LOG_INFO(LOG_TAG, "Received config request from upper layer cid:%hd", cid);
- auto func = cid_to_postable_map_[cid];
- func([&cid, &callbacks](uint16_t cid2) {
+ bluetooth::shim::GetL2cap()->SendLoopbackResponse([this, cid]() {
+ CHECK(ConnectionExists(cid));
+ const tL2CAP_APPL_INFO* callbacks = cid_to_callback_map_[cid];
+ CHECK(callbacks != nullptr);
tL2CAP_CFG_INFO cfg_info{
.result = L2CAP_CFG_OK,
.mtu_present = false,
@@ -325,7 +351,6 @@
.ext_flow_spec_present = false,
.flags = 0,
};
- LOG_INFO(LOG_TAG, "Config request lambda");
callbacks->pL2CA_ConfigCfm_Cb(cid, &cfg_info);
callbacks->pL2CA_ConfigInd_Cb(cid, &cfg_info);
});
@@ -344,8 +369,8 @@
bool bluetooth::legacy::shim::L2cap::DisconnectRequest(uint16_t cid) {
CHECK(ConnectionExists(cid));
- bluetooth::shim::GetL2cap()->CloseConnection(cid);
cid_to_callback_map_.erase(cid);
+ bluetooth::shim::GetL2cap()->CloseConnection(cid);
return true;
}
diff --git a/main/shim/l2cap.h b/main/shim/l2cap.h
index e0828d6..2fbe0d6 100644
--- a/main/shim/l2cap.h
+++ b/main/shim/l2cap.h
@@ -53,14 +53,18 @@
void RegisterService(uint16_t psm, const tL2CAP_APPL_INFO* callbacks,
bool enable_snoop);
void UnregisterService(uint16_t psm);
+
uint16_t CreateConnection(uint16_t psm, const RawAddress& raw_address);
- void OnConnectionReady(std::string address_string, uint16_t psm,
- uint16_t cid);
bool Write(uint16_t cid, BT_HDR* bt_hdr);
bool WriteFlushable(uint16_t cid, BT_HDR* bt_hdr);
bool WriteNonFlushable(uint16_t cid, BT_HDR* bt_hdr);
+ void OnLocalInitiatedConnectionCreated(std::string string_address,
+ uint16_t psm, uint16_t cid);
+ void OnRemoteInitiatedConnectionCreated(std::string string_addresss,
+ uint16_t psm, uint16_t cid);
+
uint16_t GetNextDynamicClassicPsm();
uint16_t GetNextDynamicLePsm();
@@ -78,9 +82,6 @@
bool DisconnectRequest(uint16_t cid);
bool DisconnectResponse(uint16_t cid);
- void Test(void* context);
- void Test2();
-
L2cap();
PsmData& Classic();
diff --git a/main/shim/l2cap_test.cc b/main/shim/l2cap_test.cc
index a7dddde..bf28f3c 100644
--- a/main/shim/l2cap_test.cc
+++ b/main/shim/l2cap_test.cc
@@ -233,7 +233,9 @@
CHECK(cid != 0);
// Simulate a successful connection response
- l2cap_->OnConnectionReady("11:22:33:44:55:66", kPsm, kCid);
+ l2cap_->OnLocalInitiatedConnectionCreated("11:22:33:44:55:66", kPsm, kCid);
+ CHECK(cnt_.L2caConnectCfmCb == 1);
+
CHECK(l2cap_->ConfigRequest(cid, nullptr));
}
@@ -248,7 +250,9 @@
CHECK(cid != 0);
// Simulate a successful connection response
- l2cap_->OnConnectionReady("11:22:33:44:55:66", kPsm, kCid);
+ l2cap_->OnLocalInitiatedConnectionCreated("11:22:33:44:55:66", kPsm, kCid);
+ CHECK(cnt_.L2caConnectCfmCb == 1);
+
CHECK(l2cap_->ConfigResponse(cid, nullptr));
}
@@ -263,7 +267,9 @@
CHECK(cid != 0);
// Simulate a successful connection response
- l2cap_->OnConnectionReady("11:22:33:44:55:66", kPsm, kCid);
+ l2cap_->OnLocalInitiatedConnectionCreated("11:22:33:44:55:66", kPsm, kCid);
+ CHECK(cnt_.L2caConnectCfmCb == 1);
+
CHECK(l2cap_->DisconnectRequest(cid));
}
@@ -278,7 +284,9 @@
CHECK(cid != 0);
// Simulate a successful connection response
- l2cap_->OnConnectionReady("11:22:33:44:55:66", kPsm, kCid);
+ l2cap_->OnLocalInitiatedConnectionCreated("11:22:33:44:55:66", kPsm, kCid);
+ CHECK(cnt_.L2caConnectCfmCb == 1);
+
CHECK(l2cap_->DisconnectResponse(cid));
}
@@ -293,11 +301,12 @@
CHECK(cid != 0);
// Simulate a successful connection response
- l2cap_->OnConnectionReady("11:22:33:44:55:66", kPsm, kCid);
+ l2cap_->OnLocalInitiatedConnectionCreated("11:22:33:44:55:66", kPsm, kCid);
CHECK(cnt_.L2caConnectCfmCb == 1);
CHECK(l2cap_->ConfigRequest(cid, nullptr) == true);
CHECK(cnt_.L2caConfigCfmCb == 1);
+ CHECK(cnt_.L2caConfigIndCb == 1);
BT_HDR* bt_hdr = (BT_HDR*)bt_hdr_data;
diff --git a/main/shim/test_stack.cc b/main/shim/test_stack.cc
index 5d4ede5..7baad68 100644
--- a/main/shim/test_stack.cc
+++ b/main/shim/test_stack.cc
@@ -66,12 +66,16 @@
void TestGdShimL2cap::WriteNonFlushable(uint16_t cid, const uint8_t* data,
size_t len) {}
-void TestGdShimL2cap::SendLoopbackResponse(std::function<void()>) {}
+void TestGdShimL2cap::SendLoopbackResponse(std::function<void()> function) {
+ function();
+}
void TestStack::Start() {}
void TestStack::Stop() {}
+bluetooth::shim::IAdvertising* TestStack::GetAdvertising() { return nullptr; }
+
bluetooth::shim::IController* TestStack::GetController() { return nullptr; }
bluetooth::shim::IConnectability* TestStack::GetConnectability() {
diff --git a/main/shim/test_stack.h b/main/shim/test_stack.h
index ee0986a..23b90cd 100644
--- a/main/shim/test_stack.h
+++ b/main/shim/test_stack.h
@@ -54,6 +54,7 @@
public:
TestStack() = default;
+ bluetooth::shim::IAdvertising* GetAdvertising();
bluetooth::shim::IController* GetController();
bluetooth::shim::IConnectability* GetConnectability();
bluetooth::shim::IDiscoverability* GetDiscoverability();