1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "discovery/device/eir_data.h"
18 
19 #include <bluetooth/log.h>
20 
21 #include "discovery/device/eir_test_data_packets.h"
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "hci/hci_packets.h"
25 #include "os/log.h"
26 
27 using namespace bluetooth;
28 using bluetooth::discovery::device::EirData;
29 
30 namespace {
31 constexpr uint8_t kPartialUuid16Data[] = {
32     0x2, static_cast<uint8_t>(hci::GapDataType::COMPLETE_LIST_16_BIT_UUIDS), 0x34};
33 constexpr uint8_t kOneUuid16Data[] = {
34     0x3, static_cast<uint8_t>(hci::GapDataType::COMPLETE_LIST_16_BIT_UUIDS), 0x34, 0x12};
35 constexpr char kAudiMmi9962[] = "Audi_MMI_9962";
36 constexpr char kChromeBoxForMeetings[] = "Chromebox for Meetings";
37 
38 }  // namespace
39 
40 namespace debug {
LogUuids16(const std::vector<uint16_t> & uuids16)41 void LogUuids16(const std::vector<uint16_t>& uuids16) {
42   for (const auto& uuid : uuids16) {
43     log::info("uuid:0x{:x}", uuid);
44   }
45 }
46 
LogUuids128(const std::vector<hci::Uuid> & uuids128)47 void LogUuids128(const std::vector<hci::Uuid>& uuids128) {
48   for (const auto& uuid : uuids128) {
49     log::info("uuid:{}", uuid.ToString());
50   }
51 }
52 }  // namespace debug
53 
TEST(EirDataTest,partial_uuid16)54 TEST(EirDataTest, partial_uuid16) {
55   const EirData eir_data(
56       std::vector<uint8_t>(kPartialUuid16Data, kPartialUuid16Data + sizeof(kPartialUuid16Data)));
57 
58   std::vector<uint16_t> uuids;
59   ASSERT_FALSE(eir_data.GetUuids16(uuids));
60 }
61 
TEST(EirDataTest,one_uuid16)62 TEST(EirDataTest, one_uuid16) {
63   const EirData eir_data(
64       std::vector<uint8_t>(kOneUuid16Data, kOneUuid16Data + sizeof(kOneUuid16Data)));
65 
66   std::vector<uint16_t> uuids;
67   ASSERT_TRUE(eir_data.GetUuids16(uuids));
68   ASSERT_EQ(1U, uuids.size());
69   ASSERT_EQ(0x1234, uuids[0]);
70 }
71 
TEST(EirDataTest,test_data_packets__data_type)72 TEST(EirDataTest, test_data_packets__data_type) {
73   ASSERT_EQ(1U, selected_packets.count("pkt34639"));
74   const auto& pkt = selected_packets["pkt34639"];
75   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
76 
77   std::vector<hci::GapDataType> gap_data_types = eir_data.GetDataTypes();
78   ASSERT_EQ(6U, gap_data_types.size());
79 }
80 
TEST(EirDataTest,test_data_packets__complete_name)81 TEST(EirDataTest, test_data_packets__complete_name) {
82   ASSERT_EQ(1U, selected_packets.count("pkt34639"));
83   const auto& pkt = selected_packets["pkt34639"];
84   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
85 
86   std::vector<std::array<uint8_t, kEirSize>> names;
87   ASSERT_TRUE(eir_data.GetCompleteNames(names));
88   ASSERT_EQ(1U, names.size());
89   std::string name(names[0].begin(), names[0].end());
90   ASSERT_STREQ(kAudiMmi9962, name.c_str());
91 }
92 
TEST(EirDataTest,test_data_packets__uuids16)93 TEST(EirDataTest, test_data_packets__uuids16) {
94   ASSERT_EQ(1U, selected_packets.count("pkt34639"));
95   const auto& pkt = selected_packets["pkt34639"];
96   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
97 
98   std::vector<uint16_t> uuids16;
99   ASSERT_TRUE(eir_data.GetUuids16(uuids16));
100   ASSERT_EQ(14U, uuids16.size());
101   ASSERT_EQ(0x112e, uuids16[0]);
102   ASSERT_EQ(0x180a, uuids16[13]);
103 }
104 
TEST(EirDataTest,test_data_packets__uuids16_incomplete)105 TEST(EirDataTest, test_data_packets__uuids16_incomplete) {
106   ASSERT_EQ(1U, selected_packets.count("pkt19200"));
107   const auto& pkt = selected_packets["pkt19200"];
108   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
109 
110   std::vector<uint16_t> uuids16;
111   ASSERT_TRUE(eir_data.GetUuidsIncomplete16(uuids16));
112   ASSERT_EQ(7U, uuids16.size());
113   ASSERT_EQ(0x110d, uuids16[0]);
114   ASSERT_EQ(0x1131, uuids16[6]);
115 }
116 
TEST(EirDataTest,test_data_packets__device_id)117 TEST(EirDataTest, test_data_packets__device_id) {
118   ASSERT_EQ(1U, selected_packets.count("pkt2062"));
119   const auto& pkt = selected_packets["pkt2062"];
120   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
121 
122   std::vector<std::vector<uint8_t>> device_ids;
123   ASSERT_TRUE(eir_data.GetDeviceId(device_ids));
124   ASSERT_EQ(1U, device_ids.size());
125   ASSERT_EQ(0x01, device_ids[0][0]);
126 }
127 
TEST(EirDataTest,test_data_packets__manufacturer_data)128 TEST(EirDataTest, test_data_packets__manufacturer_data) {
129   ASSERT_EQ(1U, selected_packets.count("pkt26171"));
130   const auto& pkt = selected_packets["pkt26171"];
131   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
132 
133   std::vector<std::vector<uint8_t>> mfr_data;
134   ASSERT_TRUE(eir_data.GetManufacturerSpecificData(mfr_data));
135   ASSERT_EQ(1U, mfr_data.size());
136   ASSERT_EQ(0, mfr_data[0][0]);
137 }
138 
TEST(EirDataTest,test_data_packets__security_manager_oob_flags)139 TEST(EirDataTest, test_data_packets__security_manager_oob_flags) {
140   ASSERT_EQ(1U, selected_packets.count("pkt26171"));
141   const auto& pkt = selected_packets["pkt26171"];
142   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
143 
144   std::vector<std::vector<uint8_t>> oob_flags;
145   ASSERT_TRUE(eir_data.GetManufacturerSpecificData(oob_flags));
146   ASSERT_EQ(1U, oob_flags.size());
147   ASSERT_EQ(0, oob_flags[0][0]);
148 }
149 
TEST(EirDataTest,test_data_packets__service_uuids16)150 TEST(EirDataTest, test_data_packets__service_uuids16) {
151   ASSERT_EQ(1U, selected_packets.count("pktAsha"));
152   const auto& pkt = selected_packets["pktAsha"];
153   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
154 
155   std::vector<discovery::device::service_uuid16_t> service_uuids16;
156   ASSERT_TRUE(eir_data.GetServiceUuuids16(service_uuids16));
157   ASSERT_EQ(1U, service_uuids16.size());
158   ASSERT_EQ(0xfdf0, service_uuids16[0].uuid);
159 }
160 
TEST(EirDataTest,test_data_packets__service_uuids32)161 TEST(EirDataTest, test_data_packets__service_uuids32) {
162   for (const auto& pkt : data_packets) {
163     const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
164     std::vector<discovery::device::service_uuid32_t> service_uuids32;
165     ASSERT_FALSE(eir_data.GetServiceUuuids32(service_uuids32));
166   }
167 }
168 
TEST(EirDataTest,test_data_packets__tx_power_level)169 TEST(EirDataTest, test_data_packets__tx_power_level) {
170   ASSERT_EQ(1U, selected_packets.count("pkt34639"));
171   const auto& pkt = selected_packets["pkt34639"];
172   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
173 
174   std::vector<int8_t> levels;
175   ASSERT_TRUE(eir_data.GetTxPowerLevel(levels));
176   ASSERT_EQ(1U, levels.size());
177   ASSERT_EQ(4, levels[0]);
178 }
179 
TEST(EirDataTest,test_select_packets__pktAsha)180 TEST(EirDataTest, test_select_packets__pktAsha) {
181   ASSERT_EQ(1U, selected_packets.count("pktAsha"));
182   const auto& pkt = selected_packets["pktAsha"];
183   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
184 
185   std::vector<std::array<uint8_t, kEirSize>> names;
186   ASSERT_TRUE(eir_data.GetCompleteNames(names));
187   std::string name(names[0].begin(), names[0].end());
188   ASSERT_STREQ(kChromeBoxForMeetings, name.c_str());
189 
190   std::vector<int8_t> tx_power_level;
191   ASSERT_TRUE(eir_data.GetTxPowerLevel(tx_power_level));
192   ASSERT_EQ(10, tx_power_level[0]);
193 
194   const std::vector<uint8_t> v1 =
195       std::vector<uint8_t>({0x01, 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00});
196   std::vector<std::vector<uint8_t>> device_ids;
197   ASSERT_TRUE(eir_data.GetDeviceId(device_ids));
198   ASSERT_EQ(v1.size(), device_ids[0].size());
199   ASSERT_THAT(v1, testing::ContainerEq(device_ids[0]));
200 
201   const std::vector<uint16_t> v2 =
202       std::vector<uint16_t>({0x1800, 0x1801, 0x180a, 0x110e, 0x110c, 0x111f, 0x110a});
203   std::vector<uint16_t> uuids16;
204   ASSERT_TRUE(eir_data.GetUuids16(uuids16));
205   ASSERT_EQ(v2.size(), uuids16.size());
206   ASSERT_THAT(v2, testing::ContainerEq(uuids16));
207 
208   std::vector<discovery::device::service_uuid16_t> service_uuids16;
209   ASSERT_TRUE(eir_data.GetServiceUuuids16(service_uuids16));
210   ASSERT_EQ(1U, service_uuids16.size());
211   ASSERT_EQ(0xfdf0, service_uuids16[0].uuid);
212 }
213 
TEST(EirDataTest,test_select_packets__pkt34639)214 TEST(EirDataTest, test_select_packets__pkt34639) {
215   ASSERT_EQ(1U, selected_packets.count("pkt34639"));
216   const auto& pkt = selected_packets["pkt34639"];
217   const EirData eir_data(std::vector<uint8_t>(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize));
218 
219   std::vector<uint16_t> uuids16;
220   ASSERT_TRUE(eir_data.GetUuids16(uuids16));
221   ASSERT_EQ(14U, uuids16.size());
222   ASSERT_EQ(0x112e, uuids16[0]);
223   ASSERT_EQ(0x180a, uuids16[13]);
224 
225   std::vector<uint32_t> uuids32;
226   ASSERT_FALSE(eir_data.GetUuids32(uuids32));
227   ASSERT_EQ(0U, uuids32.size());
228 
229   std::vector<hci::Uuid> uuids128;
230   ASSERT_TRUE(eir_data.GetUuids128(uuids128));
231 
232   ASSERT_EQ(hci::Uuid::FromString("00000000-deca-fade-deca-deafdecacaff"), uuids128[0]);
233 
234   std::vector<int8_t> tx_power_level;
235   ASSERT_TRUE(eir_data.GetTxPowerLevel(tx_power_level));
236   ASSERT_EQ(4, tx_power_level[0]);
237 
238   std::vector<std::array<uint8_t, 240>> names;
239   ASSERT_TRUE(eir_data.GetCompleteNames(names));
240   ASSERT_STREQ("Audi_MMI_9962", std::string(names[0].begin(), names[0].end()).data());
241 }
242