1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_bluetooth_sapphire/internal/host/common/device_class.h"
16
17 #include "pw_unit_test/framework.h"
18
19 namespace bt {
20 namespace {
21
22 struct TestPayload {
23 uint8_t arg0;
24 DeviceClass class_of_device;
25 } __attribute__((packed));
26
TEST(DeviceClassTest,CastFromBytes)27 TEST(DeviceClassTest, CastFromBytes) {
28 std::array<uint8_t, 4> bytes{{10, 0x06, 0x02, 0x02}};
29 EXPECT_EQ(bytes.size(), sizeof(TestPayload));
30
31 auto* test_payload = reinterpret_cast<TestPayload*>(bytes.data());
32 EXPECT_EQ(10, test_payload->arg0);
33 EXPECT_EQ(DeviceClass::MajorClass::kPhone,
34 test_payload->class_of_device.major_class());
35 std::unordered_set<DeviceClass::ServiceClass> srvs_expected = {
36 DeviceClass::ServiceClass::kNetworking};
37 EXPECT_EQ(srvs_expected, test_payload->class_of_device.GetServiceClasses());
38
39 // Computer -- Laptop with no Serivces.
40 std::array<uint8_t, 4> no_srv_bytes{{0xBA, 0x0C, 0x01, 0x00}};
41 EXPECT_EQ(no_srv_bytes.size(), sizeof(TestPayload));
42
43 test_payload = reinterpret_cast<TestPayload*>(no_srv_bytes.data());
44 EXPECT_EQ(0xBA, test_payload->arg0);
45 EXPECT_EQ(DeviceClass::MajorClass::kComputer,
46 test_payload->class_of_device.major_class());
47 srvs_expected = {};
48 EXPECT_EQ(srvs_expected, test_payload->class_of_device.GetServiceClasses());
49
50 // Wearable -- watch with Location and Audio services
51 std::array<uint8_t, 4> two_srv_bytes{{0xA0, 0x04, 0x07, 0x21}};
52 EXPECT_EQ(two_srv_bytes.size(), sizeof(TestPayload));
53
54 test_payload = reinterpret_cast<TestPayload*>(two_srv_bytes.data());
55 EXPECT_EQ(0xA0, test_payload->arg0);
56 EXPECT_EQ(DeviceClass::MajorClass::kWearable,
57 test_payload->class_of_device.major_class());
58 srvs_expected = {DeviceClass::ServiceClass::kAudio,
59 DeviceClass::ServiceClass::kPositioning};
60 EXPECT_EQ(srvs_expected, test_payload->class_of_device.GetServiceClasses());
61 }
62
TEST(DeviceClassTest,ConstructFromUInt32)63 TEST(DeviceClassTest, ConstructFromUInt32) {
64 // AudioVideo -- headset with Rendering and Audio services
65 DeviceClass class_of_device(0x240404);
66
67 EXPECT_EQ(DeviceClass::MajorClass::kAudioVideo,
68 class_of_device.major_class());
69
70 const uint8_t WEARABLE_HEADSET_DEVICE_MINOR_CLASS = 1;
71 EXPECT_EQ(WEARABLE_HEADSET_DEVICE_MINOR_CLASS, class_of_device.minor_class());
72
73 std::unordered_set<DeviceClass::ServiceClass> srvs_expected = {
74 DeviceClass::ServiceClass::kAudio, DeviceClass::ServiceClass::kRendering};
75 EXPECT_EQ(srvs_expected, class_of_device.GetServiceClasses());
76 }
77
TEST(DeviceClassTest,ConvertToUInt32)78 TEST(DeviceClassTest, ConvertToUInt32) {
79 uint32_t raw = 0x240304;
80 DeviceClass class_of_device(raw);
81 EXPECT_EQ(class_of_device.to_int(), raw);
82 }
83
TEST(DeviceClassTest,GetBytes)84 TEST(DeviceClassTest, GetBytes) {
85 DeviceClass class_of_device(0x240404);
86 EXPECT_EQ(class_of_device.bytes(), (DeviceClass::Bytes{{0x04, 0x04, 0x24}}));
87 }
88
TEST(DeviceClassTest,ToString)89 TEST(DeviceClassTest, ToString) {
90 DeviceClass device;
91 EXPECT_EQ("Unspecified", device.ToString());
92
93 device = DeviceClass({0x06, 0x02, 0x02});
94 EXPECT_EQ("Phone (Networking)", device.ToString());
95
96 device = DeviceClass({0x06, 0x02, 0x60});
97 EXPECT_EQ("Phone (Telephony, Audio)", device.ToString());
98 }
99
TEST(DeviceClassTest,Comparison)100 TEST(DeviceClassTest, Comparison) {
101 DeviceClass class1(DeviceClass::MajorClass::kPhone);
102 DeviceClass class2(DeviceClass::MajorClass::kPhone);
103 DeviceClass class3(DeviceClass::MajorClass::kComputer);
104 EXPECT_EQ(class1, class2);
105 EXPECT_NE(class2, class3);
106 }
107
108 } // namespace
109 } // namespace bt
110