1//
2//  Copyright (C) 2016 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 <gtest/gtest.h>
18
19#include "service/common/android/bluetooth/advertise_data.h"
20#include "service/common/android/bluetooth/advertise_settings.h"
21#include "service/common/android/bluetooth/bluetooth_gatt_characteristic.h"
22#include "service/common/android/bluetooth/bluetooth_gatt_descriptor.h"
23#include "service/common/android/bluetooth/bluetooth_gatt_service.h"
24#include "service/common/android/bluetooth/scan_filter.h"
25#include "service/common/android/bluetooth/scan_result.h"
26#include "service/common/android/bluetooth/scan_settings.h"
27#include "service/common/android/bluetooth/uuid.h"
28#include "service/common/bluetooth/low_energy_constants.h"
29
30using android::Parcel;
31
32using bluetooth::AdvertiseData;
33using bluetooth::AdvertiseSettings;
34using bluetooth::Characteristic;
35using bluetooth::Descriptor;
36using bluetooth::ScanFilter;
37using bluetooth::ScanResult;
38using bluetooth::ScanSettings;
39using bluetooth::Service;
40using bluetooth::UUID;
41
42namespace bluetooth {
43namespace {
44
45template <class IN, class OUT>
46bool TestData(IN& in) {
47  Parcel parcel;
48
49  parcel.writeParcelable((OUT)in);
50  parcel.setDataPosition(0);
51  OUT out;
52  parcel.readParcelable(&out);
53  // in case of error this display nice log message
54  EXPECT_EQ(out, in);
55  return in == out;
56}
57
58TEST(ParcelableTest, NonEmptyAdvertiseData) {
59  std::vector<uint8_t> data{0x02, 0x02, 0x00};
60  AdvertiseData adv0(data);
61  bool result =
62      TestData<AdvertiseData, android::bluetooth::AdvertiseData>(adv0);
63  EXPECT_TRUE(result);
64}
65
66TEST(ParcelableTest, DefaultAdvertiseSettings) {
67  AdvertiseSettings settings;
68  bool result =
69      TestData<AdvertiseSettings, android::bluetooth::AdvertiseSettings>(
70          settings);
71  EXPECT_TRUE(result);
72}
73
74TEST(ParcelableTest, NonEmptyAdvertiseSettings) {
75  AdvertiseSettings settings(
76      AdvertiseSettings::MODE_BALANCED, base::TimeDelta::FromMilliseconds(150),
77      AdvertiseSettings::TX_POWER_LEVEL_HIGH, false /* connectable */);
78
79  bool result =
80      TestData<AdvertiseSettings, android::bluetooth::AdvertiseSettings>(
81          settings);
82  EXPECT_TRUE(result);
83}
84
85TEST(ParcelableTest, UUID) {
86  // Try a whole bunch of UUIDs.
87  for (int i = 0; i < 10; i++) {
88    UUID uuid = UUID::GetRandom();
89    TestData<UUID, android::bluetooth::UUID>(uuid);
90  }
91}
92
93TEST(ParcelableTest, ScanSettings) {
94  ScanSettings settings0;
95  ScanSettings settings1(
96      ScanSettings::MODE_BALANCED, ScanSettings::CALLBACK_TYPE_FIRST_MATCH,
97      ScanSettings::RESULT_TYPE_ABBREVIATED,
98      base::TimeDelta::FromMilliseconds(150), ScanSettings::MATCH_MODE_STICKY,
99      ScanSettings::MATCH_COUNT_FEW_ADVERTISEMENTS);
100
101  bool result =
102      TestData<ScanSettings, android::bluetooth::ScanSettings>(settings0);
103  EXPECT_TRUE(result);
104
105  result = TestData<ScanSettings, android::bluetooth::ScanSettings>(settings0);
106  EXPECT_TRUE(result);
107}
108
109TEST(ParcelableTest, ScanFilter) {
110  ScanFilter filter;
111
112  filter.set_device_name("Test Device Name");
113  ASSERT_TRUE(filter.SetDeviceAddress("01:02:04:AB:CD:EF"));
114
115  bool result = TestData<ScanFilter, android::bluetooth::ScanFilter>(filter);
116  EXPECT_TRUE(result);
117
118  UUID uuid = UUID::GetRandom();
119  filter.SetServiceUuid(uuid);
120
121  result = TestData<ScanFilter, android::bluetooth::ScanFilter>(filter);
122  EXPECT_TRUE(result);
123
124  UUID mask = UUID::GetRandom();
125  filter.SetServiceUuidWithMask(uuid, mask);
126  result = TestData<ScanFilter, android::bluetooth::ScanFilter>(filter);
127  EXPECT_TRUE(result);
128}
129
130TEST(ParcelableTest, ScanResult) {
131  const char kTestAddress[] = "01:02:03:AB:CD:EF";
132
133  const std::vector<uint8_t> kEmptyBytes;
134  const std::vector<uint8_t> kTestBytes{0x01, 0x02, 0x03};
135
136  const int kTestRssi = 127;
137
138  ScanResult result0(kTestAddress, kEmptyBytes, kTestRssi);
139  ScanResult result1(kTestAddress, kTestBytes, kTestRssi);
140
141  bool result = TestData<ScanResult, android::bluetooth::ScanResult>(result0);
142  EXPECT_TRUE(result);
143
144  result = TestData<ScanResult, android::bluetooth::ScanResult>(result1);
145  EXPECT_TRUE(result);
146}
147
148TEST(ParcelableTest, GattDescriptor) {
149  Descriptor s = Descriptor(0x0000, UUID::GetRandom(),
150                            bluetooth::kAttributePermissionRead);
151  Descriptor s2 = Descriptor(0xFFFE, UUID::GetRandom(),
152                             bluetooth::kAttributePermissionWrite);
153  Descriptor s3 = Descriptor(0x003D, UUID::GetRandom(),
154                             bluetooth::kAttributePermissionReadEncryptedMITM |
155                                 bluetooth::kAttributePermissionRead);
156
157  bool result =
158      TestData<Descriptor, android::bluetooth::BluetoothGattDescriptor>(s);
159  EXPECT_TRUE(result);
160
161  result =
162      TestData<Descriptor, android::bluetooth::BluetoothGattDescriptor>(s2);
163  EXPECT_TRUE(result);
164
165  result =
166      TestData<Descriptor, android::bluetooth::BluetoothGattDescriptor>(s3);
167  EXPECT_TRUE(result);
168}
169
170TEST(ParcelableTest, GattCharacteristic) {
171  Characteristic c = Characteristic(0x0004, UUID::GetRandom(), 0, 0,
172                                    {Descriptor(0x0005, UUID::GetRandom(), 0),
173                                     Descriptor(0x0007, UUID::GetRandom(), 0),
174                                     Descriptor(0x00A1, UUID::GetRandom(), 0)});
175
176  bool result =
177      TestData<Characteristic, android::bluetooth::BluetoothGattCharacteristic>(
178          c);
179  EXPECT_TRUE(result);
180}
181
182TEST(ParcelableTest, GattService) {
183  Service s =
184      Service(0x0001, true, UUID("CAFE"),
185              {Characteristic(0x0004, UUID::GetRandom(),
186                              bluetooth::kCharacteristicPropertyNotify,
187                              bluetooth::kAttributePermissionRead,
188                              {Descriptor(0x0005, UUID::GetRandom(), 0),
189                               Descriptor(0x0007, UUID::GetRandom(), 0),
190                               Descriptor(0x0009, UUID::GetRandom(), 0)}),
191               Characteristic(0x000D, UUID::GetRandom(),
192                              bluetooth::kCharacteristicPropertyWrite,
193                              bluetooth::kAttributePermissionWrite,
194                              {Descriptor(0x0010, UUID::GetRandom(), 0),
195                               Descriptor(0x0012, UUID::GetRandom(), 0)}),
196               Characteristic(0x0015, UUID::GetRandom(), 0, 0, {})},
197              {});
198
199  Parcel parcel;
200
201  parcel.writeParcelable((android::bluetooth::BluetoothGattService)s);
202  parcel.setDataPosition(0);
203  android::bluetooth::BluetoothGattService out;
204  parcel.readParcelable(&out);
205
206  bool result = TestData<Service, android::bluetooth::BluetoothGattService>(s);
207  EXPECT_TRUE(result);
208}
209
210}  // namespace
211}  // namespace bluetooth
212