1 /*
2 * Copyright 2022 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 #pragma once
18
19 #include <algorithm>
20 #include <cstdint>
21 #include <deque>
22 #include <memory>
23 #include <sstream>
24 #include <string>
25
26 #include "include/hardware/bluetooth.h"
27 #include "macros.h"
28 #include "types/bluetooth/uuid.h"
29
bt_property_type_text(const::bt_property_type_t type)30 inline std::string bt_property_type_text(const ::bt_property_type_t type) {
31 switch (type) {
32 CASE_RETURN_TEXT(BT_PROPERTY_BDNAME);
33 CASE_RETURN_TEXT(BT_PROPERTY_BDADDR);
34 CASE_RETURN_TEXT(BT_PROPERTY_UUIDS);
35 CASE_RETURN_TEXT(BT_PROPERTY_CLASS_OF_DEVICE);
36 CASE_RETURN_TEXT(BT_PROPERTY_TYPE_OF_DEVICE);
37 CASE_RETURN_TEXT(BT_PROPERTY_SERVICE_RECORD);
38 CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_BONDED_DEVICES);
39 CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT);
40 CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_FRIENDLY_NAME);
41 CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_RSSI);
42 CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_VERSION_INFO);
43 CASE_RETURN_TEXT(BT_PROPERTY_LOCAL_LE_FEATURES);
44 CASE_RETURN_TEXT(BT_PROPERTY_RESERVED_0E);
45 CASE_RETURN_TEXT(BT_PROPERTY_RESERVED_0F);
46 CASE_RETURN_TEXT(BT_PROPERTY_DYNAMIC_AUDIO_BUFFER);
47 CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER);
48 CASE_RETURN_TEXT(BT_PROPERTY_APPEARANCE);
49 CASE_RETURN_TEXT(BT_PROPERTY_VENDOR_PRODUCT_INFO);
50 CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_ASHA_CAPABILITY);
51 CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID);
52 CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_MODEL_NUM);
53 CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP);
54 CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_ADDR_TYPE);
55 CASE_RETURN_TEXT(BT_PROPERTY_RESERVED_0x14);
56 default:
57 RETURN_UNKNOWN_TYPE_STRING(::bt_property_type_t, type);
58 }
59 }
60
61 namespace bluetooth {
62 namespace test {
63 namespace headless {
64
65 struct bt_property_t {
Typebt_property_t66 ::bt_property_type_t Type() const { return type; }
67
68 virtual std::string ToString() const = 0;
69
70 // TODO verify this prints as expected
ToRawbt_property_t71 std::string ToRaw() {
72 std::ostringstream oss;
73 const uint8_t* p = data.get();
74 for (size_t i = 0; i < sizeof(bt_property_t); i++, p++) {
75 oss << "0x" << std::hex << *p << " ";
76 }
77 return oss.str();
78 }
79
80 protected:
bt_property_tbt_property_t81 bt_property_t(const uint8_t* data, const size_t len) {
82 this->len = len;
83 this->data = std::make_unique<uint8_t[]>(len);
84 std::copy(data, data + len, this->data.get());
85 }
86 virtual ~bt_property_t() = default;
87
88 std::unique_ptr<uint8_t[]> data;
89 size_t len;
90 ::bt_property_type_t type;
91 };
92
93 namespace property {
94
95 struct void_t : public bt_property_t {
void_tvoid_t96 void_t(const uint8_t* data, const size_t len, int type) : bt_property_t(data, len) {
97 this->type = (::bt_property_type_t)type;
98 }
99
100 public:
ToStringvoid_t101 virtual std::string ToString() const override {
102 return std::format("Unimplemented property type:{} name:{}", type, bt_property_type_text(type));
103 }
104 };
105
106 struct uuid_t : public bt_property_t {
107 public:
uuid_tuuid_t108 uuid_t(const uint8_t* data, const size_t len) : bt_property_t(data, len) {}
109
get_uuidsuuid_t110 std::deque<bluetooth::Uuid> get_uuids() const {
111 std::deque<bluetooth::Uuid> uuids;
112 bluetooth::Uuid* p_uuid = reinterpret_cast<bluetooth::Uuid*>(data.get());
113 for (size_t i = 0; i < num_uuid(); i++, p_uuid++) {
114 bluetooth::Uuid uuid =
115 bluetooth::Uuid::From128BitBE(reinterpret_cast<const uint8_t*>(p_uuid));
116 uuids.push_back(uuid);
117 }
118 return uuids;
119 }
120
ToStringuuid_t121 virtual std::string ToString() const override {
122 return std::format("Number of uuids:{}", get_uuids().size());
123 }
124
125 private:
num_uuiduuid_t126 size_t num_uuid() const { return len / sizeof(bluetooth::Uuid); }
127 };
128
129 struct name_t : public bt_property_t {
name_tname_t130 name_t(const uint8_t* data, const size_t len) : bt_property_t(data, len) {
131 type = BT_PROPERTY_BDNAME;
132 }
133
get_namename_t134 std::string get_name() const {
135 char* s = reinterpret_cast<char*>(data.get());
136 return std::string(s);
137 }
138
ToStringname_t139 virtual std::string ToString() const override { return std::format("Name:{}", get_name()); }
140 };
141
142 struct bdaddr_t : public bt_property_t {
bdaddr_tbdaddr_t143 bdaddr_t(const uint8_t* data, const size_t len) : bt_property_t(data, len) {
144 type = BT_PROPERTY_BDNAME;
145 }
146
get_addrbdaddr_t147 RawAddress get_addr() const {
148 uint8_t* s = reinterpret_cast<uint8_t*>(data.get());
149 // TODO This may need to be reversed
150 RawAddress bd_addr;
151 log::assert_that(6U == bd_addr.FromOctets(s), "Mac address is not 6 bytes");
152 return bd_addr;
153 }
154
ToStringbdaddr_t155 virtual std::string ToString() const override {
156 return std::format("bd_addr:{}", get_addr().ToString());
157 }
158 };
159
160 struct class_of_device_t : public bt_property_t {
class_of_device_tclass_of_device_t161 class_of_device_t(const uint8_t* data, const size_t len) : bt_property_t(data, len) {
162 type = BT_PROPERTY_CLASS_OF_DEVICE;
163 }
164
get_class_of_deviceclass_of_device_t165 uint32_t get_class_of_device() const {
166 uint32_t* cod = reinterpret_cast<uint32_t*>(data.get());
167 return *cod;
168 }
169
ToStringclass_of_device_t170 virtual std::string ToString() const override {
171 return std::format("cod:0x{:04x}", get_class_of_device());
172 }
173 };
174
175 struct type_of_device_t : public bt_property_t {
type_of_device_ttype_of_device_t176 type_of_device_t(const uint8_t* data, const size_t len) : bt_property_t(data, len) {
177 type = BT_PROPERTY_TYPE_OF_DEVICE;
178 }
179
get_type_of_devicetype_of_device_t180 uint32_t get_type_of_device() const {
181 uint32_t* tod = reinterpret_cast<uint32_t*>(data.get());
182 return *tod;
183 }
184
ToStringtype_of_device_t185 virtual std::string ToString() const override {
186 return std::format("tod:0x{:04x}", get_type_of_device());
187 }
188 };
189
190 } // namespace property
191
192 bluetooth::test::headless::bt_property_t* property_factory(const ::bt_property_t& bt_property);
193
194 template <typename T>
get_property_type(bluetooth::test::headless::bt_property_t * bt_property)195 T* get_property_type(bluetooth::test::headless::bt_property_t* bt_property) {
196 return static_cast<T*>(bt_property);
197 }
198
199 } // namespace headless
200 } // namespace test
201 } // namespace bluetooth
202