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