1 #include "stack/connection_manager/connection_manager.h"
2 
3 #include <base/bind_helpers.h>
4 #include <base/functional/bind.h>
5 #include <base/functional/callback.h>
6 #include <base/location.h>
7 #include <gmock/gmock.h>
8 #include <gtest/gtest.h>
9 
10 #include <memory>
11 
12 #include "osi/include/alarm.h"
13 #include "osi/test/alarm_mock.h"
14 #include "security_device_record.h"
15 #include "stack/btm/neighbor_inquiry.h"
16 
17 // TODO(b/369381361) Enfore -Wmissing-prototypes
18 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
19 
20 using testing::_;
21 using testing::DoAll;
22 using testing::Mock;
23 using testing::Return;
24 using testing::SaveArg;
25 
26 using connection_manager::tAPP_ID;
27 
28 namespace {
29 // convenience mock, for verifying acceptlist operations on lower layer are
30 // actually scheduled
31 class AcceptlistMock {
32 public:
33   MOCK_METHOD2(AcceptlistAdd, bool(const RawAddress&, bool is_direct));
34   MOCK_METHOD1(AcceptlistRemove, void(const RawAddress&));
35   MOCK_METHOD0(AcceptlistClear, void());
36   MOCK_METHOD2(OnConnectionTimedOut, void(uint8_t, const RawAddress&));
37 
38   /* Not really accept list related, btui still BTM - just for testing put it
39    * here. */
40   MOCK_METHOD2(EnableTargetedAnnouncements, void(bool, tBTM_INQ_RESULTS_CB*));
41 };
42 
43 std::unique_ptr<AcceptlistMock> localAcceptlistMock;
44 }  // namespace
45 
46 RawAddress address1{{0x01, 0x01, 0x01, 0x01, 0x01, 0x01}};
47 RawAddress address2{{0x22, 0x22, 0x02, 0x22, 0x33, 0x22}};
48 
49 constexpr tAPP_ID CLIENT1 = 1;
50 constexpr tAPP_ID CLIENT2 = 2;
51 constexpr tAPP_ID CLIENT3 = 3;
52 constexpr tAPP_ID CLIENT10 = 10;
53 
BTM_Sec_GetAddressWithType(const RawAddress & bd_addr)54 const tBLE_BD_ADDR BTM_Sec_GetAddressWithType(const RawAddress& bd_addr) {
55   return tBLE_BD_ADDR{.type = BLE_ADDR_PUBLIC, .bda = bd_addr};
56 }
57 
btm_find_dev(const RawAddress &)58 tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& /* bd_addr */) { return nullptr; }
59 
60 namespace bluetooth {
61 namespace shim {
62 
ACL_AcceptLeConnectionFrom(const tBLE_BD_ADDR & address,bool is_direct)63 bool ACL_AcceptLeConnectionFrom(const tBLE_BD_ADDR& address, bool is_direct) {
64   return localAcceptlistMock->AcceptlistAdd(address.bda, is_direct);
65 }
ACL_IgnoreLeConnectionFrom(const tBLE_BD_ADDR & address)66 void ACL_IgnoreLeConnectionFrom(const tBLE_BD_ADDR& address) {
67   return localAcceptlistMock->AcceptlistRemove(address.bda);
68 }
69 
ACL_IgnoreAllLeConnections()70 void ACL_IgnoreAllLeConnections() { return localAcceptlistMock->AcceptlistClear(); }
71 
72 }  // namespace shim
73 }  // namespace bluetooth
74 
BTM_BleTargetAnnouncementObserve(bool enable,tBTM_INQ_RESULTS_CB * p_results_cb)75 void BTM_BleTargetAnnouncementObserve(bool enable, tBTM_INQ_RESULTS_CB* p_results_cb) {
76   localAcceptlistMock->EnableTargetedAnnouncements(enable, p_results_cb);
77 }
78 
BTM_LogHistory(const std::string &,const RawAddress &,const std::string &)79 void BTM_LogHistory(const std::string& /*tag*/, const RawAddress& /*bd_addr*/,
80                     const std::string& /*msg*/) {}
81 
82 namespace bluetooth {
83 namespace shim {
set_target_announcements_filter(bool)84 void set_target_announcements_filter(bool /*enable*/) {}
85 }  // namespace shim
86 }  // namespace bluetooth
87 
L2CA_ConnectFixedChnl(uint16_t,const RawAddress &)88 bool L2CA_ConnectFixedChnl(uint16_t /*fixed_cid*/, const RawAddress& /*bd_addr*/) { return false; }
BTM_GetHCIConnHandle(RawAddress const &,unsigned char)89 uint16_t BTM_GetHCIConnHandle(RawAddress const&, unsigned char) { return 0xFFFF; }
90 
91 namespace connection_manager {
92 class BleConnectionManager : public testing::Test {
SetUp()93   void SetUp() override {
94     localAcceptlistMock = std::make_unique<AcceptlistMock>();
95     auto alarm_mock = AlarmMock::Get();
96     ON_CALL(*alarm_mock, AlarmNew(_)).WillByDefault(testing::Invoke([](const char* /*name*/) {
97       // We must return something from alarm_new in tests, if we just return
98       // null, unique_ptr will misbehave.
99       return (alarm_t*)new uint8_t[30];
100     }));
101     ON_CALL(*alarm_mock, AlarmFree(_)).WillByDefault(testing::Invoke([](alarm_t* alarm) {
102       if (alarm) {
103         uint8_t* ptr = (uint8_t*)alarm;
104         delete[] ptr;
105       }
106     }));
107   }
108 
TearDown()109   void TearDown() override {
110     connection_manager::reset(true);
111     AlarmMock::Reset();
112     localAcceptlistMock.reset();
113   }
114 };
115 
on_connection_timed_out(uint8_t app_id,const RawAddress & address)116 void on_connection_timed_out(uint8_t app_id, const RawAddress& address) {
117   localAcceptlistMock->OnConnectionTimedOut(app_id, address);
118 }
119 
120 /** Verify that app can add a device to acceptlist, it is returned as interested
121  * app, and then can remove the device later. */
TEST_F(BleConnectionManager,test_background_connection_add_remove)122 TEST_F(BleConnectionManager, test_background_connection_add_remove) {
123   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, false)).WillOnce(Return(true));
124   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(0);
125 
126   EXPECT_TRUE(background_connect_add(CLIENT1, address1));
127 
128   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
129 
130   std::set<tAPP_ID> apps = get_apps_connecting_to(address1);
131   EXPECT_EQ(apps.size(), 1UL);
132   EXPECT_EQ(apps.count(CLIENT1), 1UL);
133 
134   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(_, _)).Times(0);
135   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(address1)).Times(1);
136 
137   EXPECT_TRUE(background_connect_remove(CLIENT1, address1));
138 
139   EXPECT_EQ(get_apps_connecting_to(address1).size(), 0UL);
140 
141   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
142 }
143 
144 /** Verify that multiple clients adding same device multiple times, result in
145  * device being added to whtie list only once, also, that device is removed only
146  * after last client removes it. */
TEST_F(BleConnectionManager,test_background_connection_multiple_clients)147 TEST_F(BleConnectionManager, test_background_connection_multiple_clients) {
148   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, false)).WillOnce(Return(true));
149   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(0);
150   EXPECT_TRUE(background_connect_add(CLIENT1, address1));
151   EXPECT_TRUE(background_connect_add(CLIENT1, address1));
152   EXPECT_TRUE(background_connect_add(CLIENT2, address1));
153   EXPECT_TRUE(background_connect_add(CLIENT3, address1));
154 
155   EXPECT_EQ(get_apps_connecting_to(address1).size(), 3UL);
156 
157   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
158 
159   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(_, _)).Times(0);
160 
161   // removing from nonexisting client, should fail
162   EXPECT_FALSE(background_connect_remove(CLIENT10, address1));
163 
164   EXPECT_TRUE(background_connect_remove(CLIENT1, address1));
165   // already removed,  removing from same client twice should return false;
166   EXPECT_FALSE(background_connect_remove(CLIENT1, address1));
167   EXPECT_TRUE(background_connect_remove(CLIENT2, address1));
168 
169   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(address1)).Times(1);
170   EXPECT_TRUE(background_connect_remove(CLIENT3, address1));
171 
172   EXPECT_EQ(get_apps_connecting_to(address1).size(), 0UL);
173 
174   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
175 }
176 
177 /** Verify adding/removing device to direct connection. */
TEST_F(BleConnectionManager,test_direct_connection_client)178 TEST_F(BleConnectionManager, test_direct_connection_client) {
179   // Direct connect attempt: use faster scan parameters, add to acceptlist,
180   // start 30 timeout
181   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, true)).WillOnce(Return(true));
182   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(0);
183   EXPECT_CALL(*AlarmMock::Get(), AlarmNew(_)).Times(1);
184   EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _)).Times(1);
185   EXPECT_TRUE(direct_connect_add(CLIENT1, address1));
186 
187   // App already doing a direct connection, attempt to re-add result in failure
188   EXPECT_FALSE(direct_connect_add(CLIENT1, address1));
189 
190   // Client that don't do direct connection should fail attempt to stop it
191   EXPECT_FALSE(direct_connect_remove(CLIENT2, address1));
192 
193   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
194 
195   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(1);
196   EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1);
197 
198   // Removal should lower the connection parameters, and free the alarm.
199   // Even though we call AcceptlistRemove, it won't be executed over HCI until
200   // acceptlist is in use, i.e. next connection attempt
201   EXPECT_TRUE(direct_connect_remove(CLIENT1, address1));
202 
203   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
204 }
205 
206 /** Verify direct connection timeout does remove device from acceptlist, and
207  * lower the connection scan parameters */
TEST_F(BleConnectionManager,test_direct_connect_timeout)208 TEST_F(BleConnectionManager, test_direct_connect_timeout) {
209   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, true)).WillOnce(Return(true));
210   EXPECT_CALL(*AlarmMock::Get(), AlarmNew(_)).Times(1);
211   alarm_callback_t alarm_callback = nullptr;
212   void* alarm_data = nullptr;
213 
214   EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _))
215           .Times(1)
216           .WillOnce(DoAll(SaveArg<2>(&alarm_callback), SaveArg<3>(&alarm_data)));
217 
218   // Start direct connect attempt...
219   EXPECT_TRUE(direct_connect_add(CLIENT1, address1));
220 
221   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
222 
223   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(1);
224   EXPECT_CALL(*localAcceptlistMock, OnConnectionTimedOut(CLIENT1, address1)).Times(1);
225   EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1);
226 
227   // simulate timeout seconds passed, alarm executing
228   alarm_callback(alarm_data);
229 
230   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
231 }
232 
233 /** Verify that we properly handle successfull direct connection */
TEST_F(BleConnectionManager,test_direct_connection_success)234 TEST_F(BleConnectionManager, test_direct_connection_success) {
235   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, true)).WillOnce(Return(true));
236   EXPECT_CALL(*AlarmMock::Get(), AlarmNew(_)).Times(1);
237   EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _)).Times(1);
238 
239   // Start direct connect attempt...
240   EXPECT_TRUE(direct_connect_add(CLIENT1, address1));
241 
242   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
243 
244   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(address1)).Times(1);
245   EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1);
246   // simulate event from lower layers - connections was established
247   // successfully.
248   on_connection_complete(address1);
249 }
250 
251 /** Verify that we properly handle application unregistration */
TEST_F(BleConnectionManager,test_app_unregister)252 TEST_F(BleConnectionManager, test_app_unregister) {
253   /* Test scenario:
254    * - Client 1 connecting to address1 and address2.
255    * - Client 2 connecting to address2
256    * - unregistration of Client1 should trigger address1 removal from acceptlist
257    * - unregistration of Client2 should trigger address2 removal
258    */
259 
260   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, true)).WillOnce(Return(true));
261   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address2, false)).WillOnce(Return(true));
262   EXPECT_TRUE(direct_connect_add(CLIENT1, address1));
263   EXPECT_TRUE(background_connect_add(CLIENT1, address2));
264   EXPECT_TRUE(direct_connect_add(CLIENT2, address2));
265   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
266 
267   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(address1)).Times(1);
268   on_app_deregistered(CLIENT1);
269   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
270 
271   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(address2)).Times(1);
272   on_app_deregistered(CLIENT2);
273 }
274 
275 /** Verify adding device to both direct connection and background connection. */
TEST_F(BleConnectionManager,test_direct_and_background_connect)276 TEST_F(BleConnectionManager, test_direct_and_background_connect) {
277   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, true)).WillOnce(Return(true));
278   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(0);
279   EXPECT_CALL(*AlarmMock::Get(), AlarmNew(_)).Times(1);
280   EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _)).Times(1);
281   // add device as both direct and background connection
282   EXPECT_TRUE(direct_connect_add(CLIENT1, address1));
283   EXPECT_TRUE(background_connect_add(CLIENT1, address1));
284 
285   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
286 
287   EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1);
288   // not removing from acceptlist yet, as the background connection is still
289   // pending.
290   EXPECT_TRUE(direct_connect_remove(CLIENT1, address1));
291 
292   // remove from acceptlist, because no more interest in device.
293   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(1);
294   EXPECT_TRUE(background_connect_remove(CLIENT1, address1));
295 
296   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
297 }
298 
TEST_F(BleConnectionManager,test_target_announement_connect)299 TEST_F(BleConnectionManager, test_target_announement_connect) {
300   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(0);
301   EXPECT_TRUE(background_connect_targeted_announcement_add(CLIENT1, address1));
302   EXPECT_TRUE(background_connect_targeted_announcement_add(CLIENT1, address1));
303 }
304 
TEST_F(BleConnectionManager,test_add_targeted_announement_when_allow_list_used)305 TEST_F(BleConnectionManager, test_add_targeted_announement_when_allow_list_used) {
306   /* Accept adding to allow list */
307   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, false)).WillOnce(Return(true));
308 
309   /* This shall be called when registering announcements */
310   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(1);
311   EXPECT_TRUE(background_connect_add(CLIENT1, address1));
312   EXPECT_TRUE(background_connect_targeted_announcement_add(CLIENT2, address1));
313 
314   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
315 }
316 
TEST_F(BleConnectionManager,test_add_background_connect_when_targeted_announcement_are_enabled)317 TEST_F(BleConnectionManager, test_add_background_connect_when_targeted_announcement_are_enabled) {
318   /* Accept adding to allow list */
319   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, false)).Times(0);
320 
321   /* This shall be called when registering announcements */
322   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(0);
323 
324   EXPECT_TRUE(background_connect_targeted_announcement_add(CLIENT2, address1));
325 
326   EXPECT_TRUE(background_connect_add(CLIENT1, address1));
327   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
328 }
329 
TEST_F(BleConnectionManager,test_re_add_background_connect_to_allow_list)330 TEST_F(BleConnectionManager, test_re_add_background_connect_to_allow_list) {
331   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, false)).Times(0);
332   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(0);
333 
334   EXPECT_TRUE(background_connect_targeted_announcement_add(CLIENT2, address1));
335 
336   EXPECT_TRUE(background_connect_add(CLIENT1, address1));
337   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
338 
339   /* Now remove app using targeted announcement and expect device
340    * to be added to white list
341    */
342 
343   /* Accept adding to allow list */
344   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, false)).WillOnce(Return(true));
345 
346   EXPECT_TRUE(background_connect_remove(CLIENT2, address1));
347   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
348 
349   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(1);
350   EXPECT_TRUE(background_connect_remove(CLIENT1, address1));
351   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
352 }
353 
TEST_F(BleConnectionManager,test_re_add_to_allow_list_after_timeout_with_multiple_clients)354 TEST_F(BleConnectionManager, test_re_add_to_allow_list_after_timeout_with_multiple_clients) {
355   EXPECT_CALL(*AlarmMock::Get(), AlarmNew(_)).Times(1);
356   alarm_callback_t alarm_callback = nullptr;
357   void* alarm_data = nullptr;
358 
359   /* Accept adding to allow list */
360   ON_CALL(*localAcceptlistMock, AcceptlistAdd(address1, _)).WillByDefault(Return(true));
361 
362   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, false)).Times(1);
363   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(0);
364 
365   EXPECT_TRUE(background_connect_add(CLIENT1, address1));
366 
367   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
368 
369   EXPECT_CALL(*AlarmMock::Get(), AlarmSetOnMloop(_, _, _, _))
370           .Times(1)
371           .WillOnce(DoAll(SaveArg<2>(&alarm_callback), SaveArg<3>(&alarm_data)));
372   // Start direct connect attempt...
373   EXPECT_TRUE(direct_connect_add(CLIENT2, address1));
374 
375   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
376 
377   // simulate timeout seconds passed, alarm executing
378   EXPECT_CALL(*localAcceptlistMock, OnConnectionTimedOut(CLIENT2, address1)).Times(1);
379   EXPECT_CALL(*localAcceptlistMock, AcceptlistRemove(_)).Times(0);
380   EXPECT_CALL(*localAcceptlistMock, AcceptlistAdd(address1, false)).Times(1);
381   EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1);
382   alarm_callback(alarm_data);
383 
384   Mock::VerifyAndClearExpectations(localAcceptlistMock.get());
385 }
386 
387 }  // namespace connection_manager
388