From 8edcc90e4524fe48dbc72f7020c50634271e3289 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Tue, 2 Apr 2019 19:21:14 +0200 Subject: [PATCH] Fix for GATT not returning disconnect callback. Before recent refactor GATT was using the L2CAP layer to start LE connections. Since the refactor, GATT talks directly to added connection_manager, just like L2CAP. L2CAP does have it's own timer for direct connections, that was returning conneciton failure after timeout. After switching to connection_manager, GATT no longer receives those callbacks. This patch makes the connection_manager send the on_connection_timed_out callback, and wire it to same handler that L2CAP layer was using before. Test: unit tests added Bug: 125553095 Change-Id: Iaf8be46fe8eed49f78ddbc6a2f3516bc8279e91f --- stack/gatt/connection_manager.cc | 2 ++ stack/gatt/connection_manager.h | 5 +++++ stack/gatt/gatt_main.cc | 6 ++++++ stack/test/gatt_connection_manager_test.cc | 6 ++++++ 4 files changed, 19 insertions(+) diff --git a/stack/gatt/connection_manager.cc b/stack/gatt/connection_manager.cc index bbbf10075..cfbb02eee 100644 --- a/stack/gatt/connection_manager.cc +++ b/stack/gatt/connection_manager.cc @@ -183,6 +183,8 @@ void reset(bool after_reset) { } void wl_direct_connect_timeout_cb(uint8_t app_id, const RawAddress& address) { + on_connection_timed_out(app_id, address); + // TODO: this would free the timer, from within the timer callback, which is // bad. direct_connect_remove(app_id, address); diff --git a/stack/gatt/connection_manager.h b/stack/gatt/connection_manager.h index 81abd8efa..4704c8fe0 100644 --- a/stack/gatt/connection_manager.h +++ b/stack/gatt/connection_manager.h @@ -53,4 +53,9 @@ extern bool direct_connect_add(tAPP_ID app_id, const RawAddress& address); extern bool direct_connect_remove(tAPP_ID app_id, const RawAddress& address); extern void dump(int fd); + +/* This callback will be executed when direct connect attempt fails due to + * timeout. It must be implemented by users of connection_manager */ +extern void on_connection_timed_out(uint8_t app_id, const RawAddress& address); + } // namespace connection_manager diff --git a/stack/gatt/gatt_main.cc b/stack/gatt/gatt_main.cc index 7bac5b44c..49e7da980 100644 --- a/stack/gatt/gatt_main.cc +++ b/stack/gatt/gatt_main.cc @@ -382,6 +382,12 @@ bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr, return true; } +namespace connection_manager { +void on_connection_timed_out(uint8_t app_id, const RawAddress& address) { + gatt_le_connect_cback(L2CAP_ATT_CID, address, false, 0xff, BT_TRANSPORT_LE); +} +} // namespace connection_manager + /** This callback function is called by L2CAP to indicate that the ATT fixed * channel for LE is connected (conn = true)/disconnected (conn = false). */ diff --git a/stack/test/gatt_connection_manager_test.cc b/stack/test/gatt_connection_manager_test.cc index a257f7a50..eed377698 100644 --- a/stack/test/gatt_connection_manager_test.cc +++ b/stack/test/gatt_connection_manager_test.cc @@ -26,6 +26,7 @@ class WhiteListMock { MOCK_METHOD0(WhiteListClear, void()); MOCK_METHOD0(SetLeConnectionModeToFast, bool()); MOCK_METHOD0(SetLeConnectionModeToSlow, void()); + MOCK_METHOD2(OnConnectionTimedOut, void(uint8_t, const RawAddress&)); }; std::unique_ptr localWhiteListMock; @@ -71,6 +72,10 @@ class BleConnectionManager : public testing::Test { } }; +void on_connection_timed_out(uint8_t app_id, const RawAddress& address) { + localWhiteListMock->OnConnectionTimedOut(app_id, address); +} + /** Verify that app can add a device to white list, it is returned as interested * app, and then can remove the device later. */ TEST_F(BleConnectionManager, test_background_connection_add_remove) { @@ -183,6 +188,7 @@ TEST_F(BleConnectionManager, test_direct_connect_timeout) { EXPECT_CALL(*localWhiteListMock, SetLeConnectionModeToSlow()).Times(1); EXPECT_CALL(*localWhiteListMock, WhiteListRemove(_)).Times(1); + EXPECT_CALL(*localWhiteListMock, OnConnectionTimedOut(CLIENT1, address1)).Times(1); EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1); // simulate timeout seconds passed, alarm executing -- 2.11.0