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