1//
2//  Copyright (C) 2015 Google, Inc.
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 <algorithm>
18#include <array>
19#include <stdint.h>
20
21#include <gtest/gtest.h>
22
23#include "service/common/bluetooth/uuid.h"
24
25using namespace bluetooth;
26
27namespace {
28
29const std::array<uint8_t, UUID::kNumBytes128> kBtSigBaseUUID = {
30    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
31      0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb, }
32};
33
34}  // namespace
35
36// Verify that an uninitialized UUID is equal
37// To the BT SIG Base UUID.
38TEST(UUIDTest, DefaultUUID) {
39  UUID uuid;
40  ASSERT_TRUE(uuid.is_valid());
41  ASSERT_TRUE(uuid.GetFullBigEndian() == kBtSigBaseUUID);
42}
43
44// Verify that we initialize a 16-bit UUID in a
45// way consistent with how we read it.
46TEST(UUIDTest, Init16Bit) {
47  auto my_uuid_16 = kBtSigBaseUUID;
48  my_uuid_16[2] = 0xde;
49  my_uuid_16[3] = 0xad;
50  UUID uuid(UUID::UUID16Bit({{ 0xde, 0xad }}));
51  ASSERT_TRUE(uuid.is_valid());
52  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_16);
53  ASSERT_TRUE(UUID::kNumBytes16 == uuid.GetShortestRepresentationSize());
54}
55
56// Verify that we initialize a 16-bit UUID in a
57// way consistent with how we read it.
58TEST(UUIDTest, Init16BitString) {
59  auto my_uuid_16 = kBtSigBaseUUID;
60  my_uuid_16[2] = 0xde;
61  my_uuid_16[3] = 0xad;
62  UUID uuid("dead");
63  ASSERT_TRUE(uuid.is_valid());
64  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_16);
65  ASSERT_TRUE(UUID::kNumBytes16 == uuid.GetShortestRepresentationSize());
66
67  uuid = UUID("0xdead");
68  ASSERT_TRUE(uuid.is_valid());
69  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_16);
70  ASSERT_TRUE(UUID::kNumBytes16 == uuid.GetShortestRepresentationSize());
71}
72
73
74// Verify that we initialize a 32-bit UUID in a
75// way consistent with how we read it.
76TEST(UUIDTest, Init32Bit) {
77  auto my_uuid_32 = kBtSigBaseUUID;
78  my_uuid_32[0] = 0xde;
79  my_uuid_32[1] = 0xad;
80  my_uuid_32[2] = 0xbe;
81  my_uuid_32[3] = 0xef;
82  UUID uuid(UUID::UUID32Bit({{ 0xde, 0xad, 0xbe, 0xef }}));
83  ASSERT_TRUE(uuid.is_valid());
84  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_32);
85  ASSERT_TRUE(UUID::kNumBytes32 == uuid.GetShortestRepresentationSize());
86}
87
88// Verify correct reading of a 32-bit UUID initialized from string.
89TEST(UUIDTest, Init32BitString) {
90  auto my_uuid_32 = kBtSigBaseUUID;
91  my_uuid_32[0] = 0xde;
92  my_uuid_32[1] = 0xad;
93  my_uuid_32[2] = 0xbe;
94  my_uuid_32[3] = 0xef;
95  UUID uuid("deadbeef");
96  ASSERT_TRUE(uuid.is_valid());
97  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_32);
98  ASSERT_TRUE(UUID::kNumBytes32 == uuid.GetShortestRepresentationSize());
99}
100
101// Verify that we initialize a 128-bit UUID in a
102// way consistent with how we read it.
103TEST(UUIDTest, Init128Bit) {
104  auto my_uuid_128 = kBtSigBaseUUID;
105  for (int i = 0; i < static_cast<int>(my_uuid_128.size()); ++i) {
106    my_uuid_128[i] = i;
107  }
108
109  UUID uuid(my_uuid_128);
110  ASSERT_TRUE(uuid.is_valid());
111  ASSERT_TRUE(uuid.GetFullBigEndian() == my_uuid_128);
112  ASSERT_TRUE(UUID::kNumBytes128 == uuid.GetShortestRepresentationSize());
113}
114
115// Verify that we initialize a 128-bit UUID in a
116// way consistent with how we read it as LE.
117TEST(UUIDTest, Init128BitLittleEndian) {
118  auto my_uuid_128 = kBtSigBaseUUID;
119  for (int i = 0; i < static_cast<int>(my_uuid_128.size()); ++i) {
120    my_uuid_128[i] = i;
121  }
122
123  UUID uuid(my_uuid_128);
124  std::reverse(my_uuid_128.begin(), my_uuid_128.end());
125  ASSERT_TRUE(uuid.is_valid());
126  ASSERT_TRUE(uuid.GetFullLittleEndian() == my_uuid_128);
127}
128
129// Verify that we initialize a 128-bit UUID in a
130// way consistent with how we read it.
131TEST(UUIDTest, Init128BitString) {
132  UUID::UUID128Bit my_uuid{
133    { 7, 1, 6, 8, 14, 255, 16, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
134  };
135  std::string my_uuid_string("07010608-0eff-1002-0304-05060708090a");
136
137  UUID uuid0(my_uuid);
138  UUID uuid1(my_uuid_string);
139
140  ASSERT_TRUE(uuid0.is_valid());
141  ASSERT_TRUE(uuid1.is_valid());
142  ASSERT_TRUE(uuid0 == uuid1);
143  ASSERT_TRUE(UUID::kNumBytes128 == uuid0.GetShortestRepresentationSize());
144}
145
146TEST(UUIDTest, InitInvalid) {
147  UUID uuid0("000102030405060708090A0B0C0D0E0F");
148  ASSERT_FALSE(uuid0.is_valid());
149
150  UUID uuid1("1*90");
151  ASSERT_FALSE(uuid1.is_valid());
152
153  UUID uuid2("109g");
154  ASSERT_FALSE(uuid1.is_valid());
155}
156
157TEST(UUIDTest, ToString) {
158  const UUID::UUID16Bit data{{ 0x18, 0x0d }};
159  UUID uuid(data);
160  std::string uuid_string = uuid.ToString();
161  EXPECT_EQ("0000180d-0000-1000-8000-00805f9b34fb", uuid_string);
162}
163