1 /*
2  * Copyright 2020 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 "hci/uuid.h"
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 namespace testing {
23 
24 using bluetooth::hci::Uuid;
25 
26 static const Uuid ONES =
27         Uuid::From128BitBE(Uuid::UUID128Bit{{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
28                                              0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}});
29 
30 static const Uuid SEQUENTIAL =
31         Uuid::From128BitBE(Uuid::UUID128Bit{{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xab,
32                                              0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89}});
33 
34 static const Uuid kBase =
35         Uuid::From128BitBE(Uuid::UUID128Bit{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80,
36                                              0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb}});
37 
38 static const Uuid kBaseLe =
39         Uuid::From128BitLE(Uuid::UUID128Bit{{0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00,
40                                              0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}});
41 
TEST(UuidTest,IsEmpty)42 TEST(UuidTest, IsEmpty) {
43   ASSERT_TRUE(Uuid::kEmpty.IsEmpty());
44   ASSERT_FALSE(kBase.IsEmpty());
45 }
46 
TEST(UuidTest,GetShortestRepresentationSize)47 TEST(UuidTest, GetShortestRepresentationSize) {
48   ASSERT_EQ(Uuid::kNumBytes16, kBase.GetShortestRepresentationSize());
49   ASSERT_EQ(Uuid::kNumBytes32, Uuid::From32Bit(0x01234567).GetShortestRepresentationSize());
50   ASSERT_EQ(Uuid::kNumBytes128, Uuid::kEmpty.GetShortestRepresentationSize());
51 }
52 
TEST(UuidTest,As16Bit)53 TEST(UuidTest, As16Bit) {
54   // Even though this is is not 16bit UUID, we should be able to get proper bits
55   ASSERT_EQ((uint16_t)0x1111, ONES.As16Bit());
56   ASSERT_EQ((uint16_t)0x4567, SEQUENTIAL.As16Bit());
57   ASSERT_EQ((uint16_t)0x0000, kBase.As16Bit());
58 }
59 
TEST(UuidTest,As32Bit)60 TEST(UuidTest, As32Bit) {
61   // Even though this is is not 32bit UUID, we should be able to get proper bits
62   ASSERT_EQ((uint32_t)0x11111111, ONES.As32Bit());
63   ASSERT_EQ((uint32_t)0x01234567, SEQUENTIAL.As32Bit());
64   ASSERT_EQ((uint32_t)0x00000000, kBase.As32Bit());
65   ASSERT_EQ((uint32_t)0x12345678, Uuid::From32Bit(0x12345678).As32Bit());
66 }
67 
TEST(UuidTest,Is16Bit)68 TEST(UuidTest, Is16Bit) {
69   ASSERT_FALSE(ONES.Is16Bit());
70   ASSERT_FALSE(SEQUENTIAL.Is16Bit());
71   ASSERT_TRUE(kBase.Is16Bit());
72   auto uuid = Uuid::FromString("1ae8");
73   ASSERT_TRUE(uuid);
74   ASSERT_TRUE(uuid->Is16Bit());
75 }
76 
TEST(UuidTest,From16Bit)77 TEST(UuidTest, From16Bit) {
78   ASSERT_EQ(Uuid::From16Bit(0x0000), kBase);
79 
80   const uint8_t u2[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00,
81                         0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
82   Uuid uuid = Uuid::From16Bit(0x0001);
83   ASSERT_EQ(0, memcmp(uuid.data(), u2, sizeof(u2)));
84 
85   const uint8_t u3[] = {0x00, 0x00, 0x55, 0x3e, 0x00, 0x00, 0x10, 0x00,
86                         0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
87   uuid = Uuid::From16Bit(0x553e);
88   ASSERT_EQ(0, memcmp(uuid.data(), u3, sizeof(u3)));
89 
90   const uint8_t u4[] = {0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x10, 0x00,
91                         0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
92   uuid = Uuid::From16Bit(0xffff);
93   ASSERT_EQ(0, memcmp(uuid.data(), u4, sizeof(u4)));
94 }
95 
TEST(UuidTest,From32Bit)96 TEST(UuidTest, From32Bit) {
97   ASSERT_EQ(Uuid::From32Bit(0x00000000), kBase);
98 
99   const uint8_t u2[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00,
100                         0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
101   Uuid uuid = Uuid::From32Bit(0x00000001);
102   ASSERT_EQ(0, memcmp(uuid.data(), u2, sizeof(u2)));
103 
104   const uint8_t u3[] = {0x33, 0x44, 0x55, 0x3e, 0x00, 0x00, 0x10, 0x00,
105                         0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
106   uuid = Uuid::From32Bit(0x3344553e);
107   ASSERT_EQ(0, memcmp(uuid.data(), u3, sizeof(u3)));
108 
109   const uint8_t u4[] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x10, 0x00,
110                         0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
111   uuid = Uuid::From32Bit(0xffffffff);
112   ASSERT_EQ(0, memcmp(uuid.data(), u4, sizeof(u4)));
113 }
114 
TEST(UuidTest,ToString)115 TEST(UuidTest, ToString) {
116   const std::string UUID_BASE_STR = "00000000-0000-1000-8000-00805f9b34fb";
117   const std::string UUID_EMP_STR = "00000000-0000-0000-0000-000000000000";
118   const std::string UUID_ONES_STR = "11111111-1111-1111-1111-111111111111";
119   const std::string UUID_SEQ_STR = "01234567-89ab-cdef-abcd-ef0123456789";
120 
121   ASSERT_EQ(UUID_BASE_STR, kBase.ToString());
122   ASSERT_EQ(UUID_EMP_STR, Uuid::kEmpty.ToString());
123   ASSERT_EQ(UUID_ONES_STR, ONES.ToString());
124   ASSERT_EQ(UUID_SEQ_STR, SEQUENTIAL.ToString());
125 
126   Uuid uuid = Uuid::From32Bit(0x12345678);
127   ASSERT_EQ("12345678-0000-1000-8000-00805f9b34fb", uuid.ToString());
128 }
129 
TEST(UuidTest,test_string_to_uuid)130 TEST(UuidTest, test_string_to_uuid) {
131   const uint8_t u1[] = {0xe3, 0x9c, 0x62, 0x85, 0x86, 0x7f, 0x4b, 0x1d,
132                         0x9d, 0xb0, 0x35, 0xfb, 0xd9, 0xae, 0xbf, 0x22};
133   auto uuid = Uuid::FromString("e39c6285-867f-4b1d-9db0-35fbd9aebf22");
134   ASSERT_TRUE(uuid);
135   ASSERT_EQ(0, memcmp(uuid->data(), u1, sizeof(u1)));
136 
137   const uint8_t u2[] = {0x00, 0x00, 0x1a, 0xe8, 0x00, 0x00, 0x10, 0x00,
138                         0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
139   uuid = Uuid::FromString("1Ae8");
140   ASSERT_TRUE(uuid);
141   ASSERT_EQ(0, memcmp(uuid->data(), u2, sizeof(u2)));
142 
143   const uint8_t u3[] = {0x12, 0x34, 0x11, 0x28, 0x00, 0x00, 0x10, 0x00,
144                         0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
145   uuid = Uuid::FromString("12341128");
146   ASSERT_TRUE(uuid);
147   ASSERT_EQ(0, memcmp(uuid->data(), u3, sizeof(u3)));
148 }
149 
TEST(UuidTest,legacy)150 TEST(UuidTest, legacy) {
151   const std::string UUID_BASE_STR = "e39c6285-867f-4b1d-9db0-35fbd9aebf22";
152   auto uuid = Uuid::FromString("e39c6285-867f-4b1d-9db0-35fbd9aebf22");
153   ASSERT_EQ(UUID_BASE_STR, uuid->ToLegacyConfigString());
154   ASSERT_EQ(uuid, Uuid::FromLegacyConfigString(UUID_BASE_STR));
155 }
156 
TEST(UuidTest,inequalities)157 TEST(UuidTest, inequalities) {
158   auto uuid1 = Uuid::kEmpty;
159   auto uuid2 = Uuid::FromString("11111111-1111-1111-1111-111111111111");
160 
161   ASSERT_TRUE(uuid1 < uuid2);
162   ASSERT_TRUE(uuid1 != uuid2);
163 }
164 
TEST(UuidTest,endianness)165 TEST(UuidTest, endianness) {
166   Uuid uuidBe = kBase;
167   Uuid uuidLe = kBaseLe;
168   ASSERT_EQ(kBase, kBaseLe);
169 }
170 
TEST(UuidTest,test_string_to_uuid_invalid)171 TEST(UuidTest, test_string_to_uuid_invalid) {
172   ASSERT_FALSE(Uuid::FromString("This is not a UUID"));
173   ASSERT_FALSE(Uuid::FromString("11212"));
174   ASSERT_FALSE(Uuid::FromString("1121 "));
175   ASSERT_FALSE(Uuid::FromString("AGFE"));
176   ASSERT_FALSE(Uuid::FromString("ABFG"));
177   ASSERT_FALSE(Uuid::FromString("e39c6285867f14b1d9db035fbd9aebf22"));
178   ASSERT_FALSE(Uuid::FromString("12234567-89ab-cdef-abcd-ef01234567ZZ"));
179   ASSERT_FALSE(Uuid::FromString(std::string()));
180   ASSERT_FALSE(Uuid::FromString("e39c6285 867f 4b1d 9db0 35fbd9aebf22"));
181   ASSERT_FALSE(Uuid::FromString("ab34xx78"));
182 }
183 
184 }  // namespace testing
185