1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include "devices.h"
19 
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 
23 #include <map>
24 
25 #include "bta_gatt_api_mock.h"
26 #include "bta_gatt_queue_mock.h"
27 #include "btm_api_mock.h"
28 #include "gatt/database_builder.h"
29 
30 namespace bluetooth {
31 namespace vc {
32 namespace internal {
33 
34 using ::testing::_;
35 using ::testing::DoAll;
36 using ::testing::Invoke;
37 using ::testing::Mock;
38 using ::testing::Return;
39 using ::testing::SetArgPointee;
40 using ::testing::Test;
41 
GetTestAddress(int index)42 RawAddress GetTestAddress(int index) {
43   CHECK_LT(index, UINT8_MAX);
44   RawAddress result = {
45       {0xC0, 0xDE, 0xC0, 0xDE, 0x00, static_cast<uint8_t>(index)}};
46   return result;
47 }
48 
49 class VolumeControlDevicesTest : public ::testing::Test {
50  protected:
SetUp()51   void SetUp() override {
52     devices_ = new VolumeControlDevices();
53     gatt::SetMockBtaGattInterface(&gatt_interface);
54     gatt::SetMockBtaGattQueue(&gatt_queue);
55   }
56 
TearDown()57   void TearDown() override {
58     gatt::SetMockBtaGattQueue(nullptr);
59     gatt::SetMockBtaGattInterface(nullptr);
60     delete devices_;
61   }
62 
63   VolumeControlDevices* devices_ = nullptr;
64   gatt::MockBtaGattInterface gatt_interface;
65   gatt::MockBtaGattQueue gatt_queue;
66 };
67 
TEST_F(VolumeControlDevicesTest,test_add)68 TEST_F(VolumeControlDevicesTest, test_add) {
69   RawAddress test_address_0 = GetTestAddress(0);
70   ASSERT_EQ((size_t)0, devices_->Size());
71   devices_->Add(test_address_0, true);
72   ASSERT_EQ((size_t)1, devices_->Size());
73 }
74 
TEST_F(VolumeControlDevicesTest,test_add_twice)75 TEST_F(VolumeControlDevicesTest, test_add_twice) {
76   RawAddress test_address_0 = GetTestAddress(0);
77   ASSERT_EQ((size_t)0, devices_->Size());
78   devices_->Add(test_address_0, true);
79   devices_->Add(test_address_0, true);
80   ASSERT_EQ((size_t)1, devices_->Size());
81 }
82 
TEST_F(VolumeControlDevicesTest,test_remove)83 TEST_F(VolumeControlDevicesTest, test_remove) {
84   RawAddress test_address_0 = GetTestAddress(0);
85   RawAddress test_address_1 = GetTestAddress(1);
86   devices_->Add(test_address_0, true);
87   devices_->Add(test_address_1, true);
88   ASSERT_EQ((size_t)2, devices_->Size());
89   devices_->Remove(test_address_0);
90   ASSERT_EQ((size_t)1, devices_->Size());
91 }
92 
TEST_F(VolumeControlDevicesTest,test_clear)93 TEST_F(VolumeControlDevicesTest, test_clear) {
94   RawAddress test_address_0 = GetTestAddress(0);
95   ASSERT_EQ((size_t)0, devices_->Size());
96   devices_->Add(test_address_0, true);
97   ASSERT_EQ((size_t)1, devices_->Size());
98   devices_->Clear();
99   ASSERT_EQ((size_t)0, devices_->Size());
100 }
101 
TEST_F(VolumeControlDevicesTest,test_find_by_address)102 TEST_F(VolumeControlDevicesTest, test_find_by_address) {
103   RawAddress test_address_0 = GetTestAddress(0);
104   RawAddress test_address_1 = GetTestAddress(1);
105   RawAddress test_address_2 = GetTestAddress(2);
106   devices_->Add(test_address_0, true);
107   devices_->Add(test_address_1, false);
108   devices_->Add(test_address_2, true);
109   VolumeControlDevice* device = devices_->FindByAddress(test_address_1);
110   ASSERT_NE(nullptr, device);
111   ASSERT_EQ(test_address_1, device->address);
112 }
113 
TEST_F(VolumeControlDevicesTest,test_find_by_conn_id)114 TEST_F(VolumeControlDevicesTest, test_find_by_conn_id) {
115   RawAddress test_address_0 = GetTestAddress(0);
116   devices_->Add(test_address_0, true);
117   VolumeControlDevice* test_device = devices_->FindByAddress(test_address_0);
118   test_device->connection_id = 0x0005;
119   ASSERT_NE(nullptr, devices_->FindByConnId(test_device->connection_id));
120 }
121 
TEST_F(VolumeControlDevicesTest,test_disconnect)122 TEST_F(VolumeControlDevicesTest, test_disconnect) {
123   RawAddress test_address_0 = GetTestAddress(0);
124   RawAddress test_address_1 = GetTestAddress(1);
125   devices_->Add(test_address_0, true);
126   devices_->Add(test_address_1, true);
127   VolumeControlDevice* test_device_0 = devices_->FindByAddress(test_address_0);
128   test_device_0->connection_id = 0x0005;
129   tGATT_IF gatt_if = 8;
130   EXPECT_CALL(gatt_interface, Close(test_device_0->connection_id));
131   EXPECT_CALL(gatt_interface, CancelOpen(gatt_if, test_address_1, _));
132   devices_->Disconnect(gatt_if);
133 }
134 
TEST_F(VolumeControlDevicesTest,test_control_point_operation)135 TEST_F(VolumeControlDevicesTest, test_control_point_operation) {
136   uint8_t opcode = 50;
137   std::vector<RawAddress> devices;
138 
139   for (int i = 5; i > 0; i--) {
140     RawAddress test_address = GetTestAddress(i);
141     devices.push_back(test_address);
142     uint8_t change_counter = 10 * i;
143     uint16_t control_point_handle = 0x0020 + i;
144     uint16_t connection_id = i;
145     devices_->Add(test_address, true);
146     VolumeControlDevice* device = devices_->FindByAddress(test_address);
147     device->connection_id = connection_id;
148     device->change_counter = change_counter;
149     device->volume_control_point_handle = control_point_handle;
150     std::vector<uint8_t> data_expected({opcode, change_counter});
151 
152     EXPECT_CALL(gatt_queue,
153                 WriteCharacteristic(connection_id, control_point_handle,
154                                     data_expected, GATT_WRITE, _, _));
155   }
156 
157   const std::vector<uint8_t>* arg = nullptr;
158   GATT_WRITE_OP_CB cb = nullptr;
159   void* cb_data = nullptr;
160   devices_->ControlPointOperation(devices, opcode, arg, cb, cb_data);
161 }
162 
TEST_F(VolumeControlDevicesTest,test_control_point_operation_args)163 TEST_F(VolumeControlDevicesTest, test_control_point_operation_args) {
164   uint8_t opcode = 60;
165   uint8_t arg_1 = 0x02;
166   uint8_t arg_2 = 0x05;
167   std::vector<RawAddress> devices;
168 
169   for (int i = 5; i > 0; i--) {
170     RawAddress test_address = GetTestAddress(i);
171     devices.push_back(test_address);
172     uint8_t change_counter = 10 * i;
173     uint16_t control_point_handle = 0x0020 + i;
174     uint16_t connection_id = i;
175     devices_->Add(test_address, true);
176     VolumeControlDevice* device = devices_->FindByAddress(test_address);
177     device->connection_id = connection_id;
178     device->change_counter = change_counter;
179     device->volume_control_point_handle = control_point_handle;
180     std::vector<uint8_t> data_expected({opcode, change_counter, arg_1, arg_2});
181 
182     EXPECT_CALL(gatt_queue,
183                 WriteCharacteristic(connection_id, control_point_handle,
184                                     data_expected, GATT_WRITE, _, _));
185   }
186 
187   std::vector<uint8_t> arg({arg_1, arg_2});
188   GATT_WRITE_OP_CB cb = nullptr;
189   void* cb_data = nullptr;
190   devices_->ControlPointOperation(devices, opcode, &arg, cb, cb_data);
191 }
192 
TEST_F(VolumeControlDevicesTest,test_control_point_skip_not_connected)193 TEST_F(VolumeControlDevicesTest, test_control_point_skip_not_connected) {
194   RawAddress test_address = GetTestAddress(1);
195   devices_->Add(test_address, true);
196   VolumeControlDevice* device = devices_->FindByAddress(test_address);
197   device->connection_id = GATT_INVALID_CONN_ID;
198   uint16_t control_point_handle = 0x0020;
199   device->volume_control_point_handle = control_point_handle;
200 
201   EXPECT_CALL(gatt_queue,
202               WriteCharacteristic(_, control_point_handle, _, _, _, _))
203       .Times(0);
204 
205   uint8_t opcode = 5;
206   std::vector<RawAddress> devices = {test_address};
207   const std::vector<uint8_t>* arg = nullptr;
208   GATT_WRITE_OP_CB cb = nullptr;
209   void* cb_data = nullptr;
210   devices_->ControlPointOperation(devices, opcode, arg, cb, cb_data);
211 }
212 
213 class VolumeControlDeviceTest : public ::testing::Test {
214  protected:
SetUp()215   void SetUp() override {
216     device = new VolumeControlDevice(GetTestAddress(1), true);
217     gatt::SetMockBtaGattInterface(&gatt_interface);
218     gatt::SetMockBtaGattQueue(&gatt_queue);
219     bluetooth::manager::SetMockBtmInterface(&btm_interface);
220 
221     ON_CALL(gatt_interface, GetCharacteristic(_, _))
222         .WillByDefault(
223             Invoke([&](uint16_t conn_id,
224                        uint16_t handle) -> const gatt::Characteristic* {
225               for (auto const& service : services) {
226                 for (auto const& characteristic : service.characteristics) {
227                   if (characteristic.value_handle == handle) {
228                     return &characteristic;
229                   }
230                 }
231               }
232 
233               return nullptr;
234             }));
235 
236     ON_CALL(gatt_interface, GetOwningService(_, _))
237         .WillByDefault(Invoke(
238             [&](uint16_t conn_id, uint16_t handle) -> const gatt::Service* {
239               for (auto const& service : services) {
240                 if (service.handle <= handle && service.end_handle >= handle) {
241                   return &service;
242                 }
243               }
244 
245               return nullptr;
246             }));
247 
248     ON_CALL(gatt_interface, GetServices(_)).WillByDefault(Return(&services));
249   }
250 
TearDown()251   void TearDown() override {
252     bluetooth::manager::SetMockBtmInterface(nullptr);
253     gatt::SetMockBtaGattQueue(nullptr);
254     gatt::SetMockBtaGattInterface(nullptr);
255     delete device;
256   }
257 
258   /* sample database 1xVCS, 2xAICS, 2xVOCS */
SetSampleDatabase1(void)259   void SetSampleDatabase1(void) {
260     gatt::DatabaseBuilder builder;
261     builder.AddService(0x0001, 0x0016, kVolumeControlUuid, true);
262     builder.AddCharacteristic(
263         0x0010, 0x0011, kVolumeControlStateUuid,
264         GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
265     builder.AddDescriptor(0x0012,
266                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
267     builder.AddCharacteristic(0x0013, 0x0014, kVolumeControlPointUuid,
268                               GATT_CHAR_PROP_BIT_WRITE);
269     builder.AddCharacteristic(0x0015, 0x0016, kVolumeFlagsUuid,
270                               GATT_CHAR_PROP_BIT_READ);
271     builder.AddService(0x00a0, 0x00a3,
272                        Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER), true);
273     builder.AddCharacteristic(0x00a1, 0x00a2,
274                               Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD),
275                               GATT_CHAR_PROP_BIT_NOTIFY);
276     builder.AddDescriptor(0x00a3,
277                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
278     services = builder.Build().Services();
279     ASSERT_EQ(true, device->UpdateHandles());
280   }
281 
282   /* sample database no VCS */
SetSampleDatabase2(void)283   void SetSampleDatabase2(void) {
284     gatt::DatabaseBuilder builder;
285     builder.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
286     builder.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00),
287                               GATT_CHAR_PROP_BIT_READ);
288     services = builder.Build().Services();
289     ASSERT_EQ(false, device->UpdateHandles());
290   }
291 
292   VolumeControlDevice* device = nullptr;
293   gatt::MockBtaGattInterface gatt_interface;
294   gatt::MockBtaGattQueue gatt_queue;
295   bluetooth::manager::MockBtmInterface btm_interface;
296   std::list<gatt::Service> services;
297 };
298 
TEST_F(VolumeControlDeviceTest,test_service_volume_control_not_found)299 TEST_F(VolumeControlDeviceTest, test_service_volume_control_not_found) {
300   SetSampleDatabase2();
301   ASSERT_EQ(false, device->HasHandles());
302 }
303 
TEST_F(VolumeControlDeviceTest,test_service_volume_control_incomplete)304 TEST_F(VolumeControlDeviceTest, test_service_volume_control_incomplete) {
305   gatt::DatabaseBuilder builder;
306   builder.AddService(0x0001, 0x0006, kVolumeControlUuid, true);
307   builder.AddCharacteristic(
308       0x0002, 0x0003, kVolumeControlStateUuid,
309       GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
310   builder.AddDescriptor(0x0004, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
311   builder.AddCharacteristic(0x0005, 0x0006, kVolumeControlPointUuid,
312                             GATT_CHAR_PROP_BIT_WRITE);
313   /* no Volume Control Flags characteristic */
314   services = builder.Build().Services();
315   ASSERT_EQ(false, device->UpdateHandles());
316   ASSERT_EQ(0x0000, device->volume_state_handle);
317   ASSERT_EQ(0x0000, device->volume_state_ccc_handle);
318   ASSERT_EQ(0x0000, device->volume_control_point_handle);
319   ASSERT_EQ(0x0000, device->volume_flags_handle);
320   ASSERT_EQ(0x0000, device->volume_flags_ccc_handle);
321   ASSERT_EQ(false, device->HasHandles());
322 }
323 
TEST_F(VolumeControlDeviceTest,test_services_changed)324 TEST_F(VolumeControlDeviceTest, test_services_changed) {
325   SetSampleDatabase1();
326   ASSERT_NE(0, device->volume_state_handle);
327   ASSERT_NE(0, device->volume_control_point_handle);
328   ASSERT_NE(0, device->volume_flags_handle);
329   ASSERT_EQ(true, device->HasHandles());
330   SetSampleDatabase2();
331   ASSERT_EQ(0, device->volume_state_handle);
332   ASSERT_EQ(0, device->volume_control_point_handle);
333   ASSERT_EQ(0, device->volume_flags_handle);
334   ASSERT_EQ(false, device->HasHandles());
335 }
336 
TEST_F(VolumeControlDeviceTest,test_enqueue_initial_requests)337 TEST_F(VolumeControlDeviceTest, test_enqueue_initial_requests) {
338   SetSampleDatabase1();
339 
340   tGATT_IF gatt_if = 0x0001;
341   std::vector<uint8_t> register_for_notification_data({0x01, 0x00});
342 
343   std::map<uint16_t, uint16_t> expected_to_read_write{
344       {0x0011, 0x0012} /* volume control state */};
345 
346   for (auto const& handle_pair : expected_to_read_write) {
347     EXPECT_CALL(gatt_queue, ReadCharacteristic(_, handle_pair.first, _, _));
348     EXPECT_CALL(gatt_queue, WriteDescriptor(_, handle_pair.second,
349                                             register_for_notification_data,
350                                             GATT_WRITE, _, _));
351     EXPECT_CALL(gatt_interface,
352                 RegisterForNotifications(gatt_if, _, handle_pair.first));
353   }
354 
355   auto chrc_read_cb = [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
356                          uint16_t len, uint8_t* value, void* data) {};
357   auto cccd_write_cb = [](uint16_t conn_id, tGATT_STATUS status,
358                           uint16_t handle, void* data) {};
359   ASSERT_EQ(true, device->EnqueueInitialRequests(gatt_if, chrc_read_cb,
360                                                  cccd_write_cb));
361 };
362 
TEST_F(VolumeControlDeviceTest,test_device_ready)363 TEST_F(VolumeControlDeviceTest, test_device_ready) {
364   SetSampleDatabase1();
365 
366   // grab all the handles requested
367   std::vector<uint16_t> requested_handles;
368   ON_CALL(gatt_queue, WriteDescriptor(_, _, _, _, _, _))
369       .WillByDefault(Invoke(
370           [&requested_handles](
371               uint16_t conn_id, uint16_t handle, std::vector<uint8_t> value,
372               tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb,
373               void* cb_data) -> void { requested_handles.push_back(handle); }));
374   ON_CALL(gatt_queue, ReadCharacteristic(_, _, _, _))
375       .WillByDefault(Invoke(
376           [&requested_handles](uint16_t conn_id, uint16_t handle,
377                                GATT_READ_OP_CB cb, void* cb_data) -> void {
378             requested_handles.push_back(handle);
379           }));
380 
381   auto chrc_read_cb = [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
382                          uint16_t len, uint8_t* value, void* data) {};
383   auto cccd_write_cb = [](uint16_t conn_id, tGATT_STATUS status,
384                           uint16_t handle, void* data) {};
385   ASSERT_EQ(true, device->EnqueueInitialRequests(0x0001, chrc_read_cb,
386                                                  cccd_write_cb));
387   ASSERT_NE((size_t)0, requested_handles.size());
388 
389   // indicate non-pending requests
390   ASSERT_EQ(false, device->device_ready);
391   device->VerifyReady(0xffff);
392 
393   for (uint16_t handle : requested_handles) {
394     ASSERT_EQ(false, device->device_ready);
395     device->VerifyReady(handle);
396   }
397 
398   ASSERT_EQ(true, device->device_ready);
399 }
400 
TEST_F(VolumeControlDeviceTest,test_enqueue_remaining_requests)401 TEST_F(VolumeControlDeviceTest, test_enqueue_remaining_requests) {
402   SetSampleDatabase1();
403 
404   tGATT_IF gatt_if = 0x0001;
405   std::vector<uint8_t> register_for_notification_data({0x01, 0x00});
406 
407   std::vector<uint16_t> expected_to_read{0x0016 /* volume flags */};
408 
409   std::map<uint16_t, uint16_t> expected_to_write_value_ccc_handle_map{};
410 
411   for (uint16_t handle : expected_to_read) {
412     EXPECT_CALL(gatt_queue, ReadCharacteristic(_, handle, _, _));
413   }
414 
415   for (auto const& handle_pair : expected_to_write_value_ccc_handle_map) {
416     EXPECT_CALL(gatt_queue, WriteDescriptor(_, handle_pair.second,
417                                             register_for_notification_data,
418                                             GATT_WRITE, _, _));
419     EXPECT_CALL(gatt_interface,
420                 RegisterForNotifications(gatt_if, _, handle_pair.first));
421   }
422 
423   auto chrc_read_cb = [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
424                          uint16_t len, uint8_t* value, void* data) {};
425   auto cccd_write_cb = [](uint16_t conn_id, tGATT_STATUS status,
426                           uint16_t handle, void* data) {};
427   device->EnqueueRemainingRequests(gatt_if, chrc_read_cb, cccd_write_cb);
428 }
429 
TEST_F(VolumeControlDeviceTest,test_check_link_encrypted)430 TEST_F(VolumeControlDeviceTest, test_check_link_encrypted) {
431   ON_CALL(btm_interface, GetSecurityFlagsByTransport(_, _, _))
432       .WillByDefault(
433           DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(true)));
434   ASSERT_EQ(true, device->IsEncryptionEnabled());
435 
436   ON_CALL(btm_interface, GetSecurityFlagsByTransport(_, _, _))
437       .WillByDefault(DoAll(SetArgPointee<1>(0), Return(false)));
438   ASSERT_NE(true, device->IsEncryptionEnabled());
439 
440   ON_CALL(btm_interface, GetSecurityFlagsByTransport(_, _, _))
441       .WillByDefault(DoAll(SetArgPointee<1>(0), Return(true)));
442   ASSERT_NE(true, device->IsEncryptionEnabled());
443 }
444 
TEST_F(VolumeControlDeviceTest,test_control_point_operation)445 TEST_F(VolumeControlDeviceTest, test_control_point_operation) {
446   GATT_WRITE_OP_CB write_cb = [](uint16_t conn_id, tGATT_STATUS status,
447                                  uint16_t handle, void* data) {};
448   SetSampleDatabase1();
449   device->change_counter = 0x01;
450   std::vector<uint8_t> expected_data({0x03, 0x01});
451   EXPECT_CALL(gatt_queue, WriteCharacteristic(_, 0x0014, expected_data,
452                                               GATT_WRITE, write_cb, nullptr));
453   device->ControlPointOperation(0x03, nullptr, write_cb, nullptr);
454 }
455 
TEST_F(VolumeControlDeviceTest,test_control_point_operation_arg)456 TEST_F(VolumeControlDeviceTest, test_control_point_operation_arg) {
457   GATT_WRITE_OP_CB write_cb = [](uint16_t conn_id, tGATT_STATUS status,
458                                  uint16_t handle, void* data) {};
459   SetSampleDatabase1();
460   device->change_counter = 0x55;
461   std::vector<uint8_t> expected_data({0x01, 0x55, 0x02, 0x03});
462   EXPECT_CALL(gatt_queue, WriteCharacteristic(_, 0x0014, expected_data,
463                                               GATT_WRITE, write_cb, nullptr));
464   std::vector<uint8_t> arg({0x02, 0x03});
465   device->ControlPointOperation(0x01, &arg, write_cb, nullptr);
466 }
467 
468 }  // namespace internal
469 }  // namespace vc
470 }  // namespace bluetooth
471