1 /*
2  * Copyright 2024 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 "discovery/device/bt_property.h"
18 
19 #include <base/strings/stringprintf.h>
20 
21 #include <string>
22 
23 #include "include/hardware/bluetooth.h"
24 #include "os/log.h"
25 #include "stack/include/bt_name.h"
26 #include "types/bluetooth/uuid.h"
27 
bt_property_type_text(const bt_property_type_t & type)28 std::string bt_property_type_text(const bt_property_type_t& type) {
29   switch (type) {
30     CASE_RETURN_TEXT(BT_PROPERTY_BDNAME);
31     CASE_RETURN_TEXT(BT_PROPERTY_BDADDR);
32     CASE_RETURN_TEXT(BT_PROPERTY_UUIDS);
33     CASE_RETURN_TEXT(BT_PROPERTY_CLASS_OF_DEVICE);
34     CASE_RETURN_TEXT(BT_PROPERTY_TYPE_OF_DEVICE);
35     CASE_RETURN_TEXT(BT_PROPERTY_SERVICE_RECORD);
36     CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_SCAN_MODE);
37     CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_BONDED_DEVICES);
38     CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT);
39     CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_FRIENDLY_NAME);
40     CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_RSSI);
41     CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_VERSION_INFO);
42     CASE_RETURN_TEXT(BT_PROPERTY_LOCAL_LE_FEATURES);
43     CASE_RETURN_TEXT(BT_PROPERTY_RESERVED_0E);
44     CASE_RETURN_TEXT(BT_PROPERTY_RESERVED_0F);
45     CASE_RETURN_TEXT(BT_PROPERTY_DYNAMIC_AUDIO_BUFFER);
46     CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER);
47     CASE_RETURN_TEXT(BT_PROPERTY_APPEARANCE);
48     CASE_RETURN_TEXT(BT_PROPERTY_VENDOR_PRODUCT_INFO);
49     CASE_RETURN_TEXT(BT_PROPERTY_RESERVED_0x14);
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_ADDR_TYPE);
54     CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP);
55     CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED);
56     CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE);
57   }
58   return base::StringPrintf("Unknown [%d]", (int)type);
59 }
60 
bt_property_text(const bt_property_t & property)61 std::string bt_property_text(const bt_property_t& property) {
62   switch (property.type) {
63     case BT_PROPERTY_BDNAME:
64       return base::StringPrintf(
65           "type:%s name:%s",
66           bt_property_type_text(property.type).c_str(),
67           (const char*)property.val);
68     case BT_PROPERTY_BDADDR:
69       return base::StringPrintf(
70           "type:%s addr:%s",
71           bt_property_type_text(property.type).c_str(),
72           ((const RawAddress*)property.val)->ToString().c_str());
73     case BT_PROPERTY_UUIDS: {
74       std::ostringstream oss;
75       const bluetooth::Uuid* it = (const bluetooth::Uuid*)property.val;
76       for (size_t i = 0; i < (size_t)property.len; i += sizeof(bluetooth::Uuid), it++) {
77         (i == 0) ? oss << *it : oss << " " << *it;
78       }
79       return base::StringPrintf(
80           "type:%s uuids:%s", bt_property_type_text(property.type).c_str(), oss.str().c_str());
81     }
82     case BT_PROPERTY_CLASS_OF_DEVICE:
83       return base::StringPrintf(
84           "type:%s cod:0x%x",
85           bt_property_type_text(property.type).c_str(),
86           *(uint32_t*)(property.val));
87 
88     case BT_PROPERTY_TYPE_OF_DEVICE:
89       return base::StringPrintf(
90           "type:%s type_of_device:%d",
91           bt_property_type_text(property.type).c_str(),
92           *(uint32_t*)(property.val));
93 
94     case BT_PROPERTY_SERVICE_RECORD:
95       return base::StringPrintf(
96           "type:%s uuid:%s channel:%u name:\"%s\"",
97           bt_property_type_text(property.type).c_str(),
98           (((bt_service_record_t*)property.val)->uuid).ToString().c_str(),
99           (((bt_service_record_t*)property.val)->channel),
100           (((bt_service_record_t*)property.val)->name));
101 
102     case BT_PROPERTY_ADAPTER_SCAN_MODE:
103       return base::StringPrintf(
104           "type:%s scan_mode:%u",
105           bt_property_type_text(property.type).c_str(),
106           *((bt_scan_mode_t*)property.val));
107 
108     case BT_PROPERTY_ADAPTER_BONDED_DEVICES: {
109       std::ostringstream oss;
110       const RawAddress* it = (const RawAddress*)property.val;
111       for (size_t i = 0; i < (size_t)property.len; i += sizeof(RawAddress), it++) {
112         (i == 0) ? oss << *it : oss << " " << *it;
113       }
114       return base::StringPrintf(
115           "type:%s addrs:%s", bt_property_type_text(property.type).c_str(), oss.str().c_str());
116     }
117     case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT:
118       return base::StringPrintf(
119           "type:%s discoverable_timeout:%u",
120           bt_property_type_text(property.type).c_str(),
121           *((uint32_t*)property.val));
122 
123     case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
124       return base::StringPrintf(
125           "type:%s remote_friendly_name:%s",
126           bt_property_type_text(property.type).c_str(),
127           (uint8_t*)property.val);
128 
129     case BT_PROPERTY_REMOTE_RSSI:
130       return base::StringPrintf(
131           "type:%s rssi:%hhd",
132           bt_property_type_text(property.type).c_str(),
133           *(int8_t*)property.val);
134 
135     case BT_PROPERTY_REMOTE_VERSION_INFO:
136       return base::StringPrintf(
137           "type:%s version:%d sub:%d mfr:%d",
138           bt_property_type_text(property.type).c_str(),
139           ((bt_remote_version_t*)property.val)->version,
140           ((bt_remote_version_t*)property.val)->sub_ver,
141           ((bt_remote_version_t*)property.val)->manufacturer);
142 
143     case BT_PROPERTY_LOCAL_LE_FEATURES:
144       return base::StringPrintf(
145           "type:%s version_supported:%d local_privacy_enabled:%d"
146           " max_adv_instance:%d rpa_offload_supported:%d max_irk_list_size:%d"
147           " max_adv_filter_supported:%d activity_energy_info_supported:%d"
148           " scan_result_storage_size:%d total_trackable_advertisers:%d"
149           " extended_scan_support:%d debug_logging_supported:%d le_2m_phy_supported:%d"
150           " le_coded_phy_supported:%d le_extended_advertising_supported:%d"
151           " le_periodic_advertising_supported:%d le_maximum_advertising_data_length:%d"
152           " dynamic_audio_buffer_supported:%d "
153           "le_periodic_advertising_sync_transfer_sender_supported:%d"
154           " le_connected_isochronous_stream_central_supported:%d "
155           "le_isochronous_broadcast_supported:%d"
156           " le_periodic_advertising_sync_transfer_recipient_supported:%d "
157           "adv_filter_extended_features_mask:%d"
158           "le_channel_sounding_supported:%d ",
159           bt_property_type_text(property.type).c_str(),
160           ((bt_local_le_features_t*)property.val)->version_supported,
161           ((bt_local_le_features_t*)property.val)->local_privacy_enabled,
162           ((bt_local_le_features_t*)property.val)->max_adv_instance,
163           ((bt_local_le_features_t*)property.val)->rpa_offload_supported,
164           ((bt_local_le_features_t*)property.val)->max_irk_list_size,
165           ((bt_local_le_features_t*)property.val)->max_adv_filter_supported,
166           ((bt_local_le_features_t*)property.val)->activity_energy_info_supported,
167           ((bt_local_le_features_t*)property.val)->scan_result_storage_size,
168           ((bt_local_le_features_t*)property.val)->total_trackable_advertisers,
169           ((bt_local_le_features_t*)property.val)->extended_scan_support,
170           ((bt_local_le_features_t*)property.val)->debug_logging_supported,
171           ((bt_local_le_features_t*)property.val)->le_2m_phy_supported,
172           ((bt_local_le_features_t*)property.val)->le_coded_phy_supported,
173           ((bt_local_le_features_t*)property.val)->le_extended_advertising_supported,
174           ((bt_local_le_features_t*)property.val)->le_periodic_advertising_supported,
175           ((bt_local_le_features_t*)property.val)->le_maximum_advertising_data_length,
176           ((bt_local_le_features_t*)property.val)->dynamic_audio_buffer_supported,
177           ((bt_local_le_features_t*)property.val)
178               ->le_periodic_advertising_sync_transfer_sender_supported,
179           ((bt_local_le_features_t*)property.val)
180               ->le_connected_isochronous_stream_central_supported,
181           ((bt_local_le_features_t*)property.val)->le_isochronous_broadcast_supported,
182           ((bt_local_le_features_t*)property.val)
183               ->le_periodic_advertising_sync_transfer_recipient_supported,
184           ((bt_local_le_features_t*)property.val)->adv_filter_extended_features_mask,
185           ((bt_local_le_features_t*)property.val)->le_channel_sounding_supported);
186 
187     case BT_PROPERTY_RESERVED_0E:
188       return base::StringPrintf("type:%s", bt_property_type_text(property.type).c_str());
189 
190     case BT_PROPERTY_RESERVED_0F:
191       return base::StringPrintf("type:%s", bt_property_type_text(property.type).c_str());
192 
193     case BT_PROPERTY_DYNAMIC_AUDIO_BUFFER:
194       return base::StringPrintf("type:%s", bt_property_type_text(property.type).c_str());
195 
196     case BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER:
197       return base::StringPrintf(
198           "type:%s is_coordinated_set_member:%s",
199           bt_property_type_text(property.type).c_str(),
200           (*(bool*)property.val) ? "true" : "false");
201 
202     case BT_PROPERTY_APPEARANCE:
203       return base::StringPrintf(
204           "type:%s appearance:0x%x",
205           bt_property_type_text(property.type).c_str(),
206           (*(uint16_t*)property.val));
207 
208     case BT_PROPERTY_VENDOR_PRODUCT_INFO:
209       return base::StringPrintf(
210           "type:%s vendor_id_src:%hhu vendor_id:%hu product_id:%hu version:%hu",
211           bt_property_type_text(property.type).c_str(),
212           ((bt_vendor_product_info_t*)property.val)->vendor_id_src,
213           ((bt_vendor_product_info_t*)property.val)->vendor_id,
214           ((bt_vendor_product_info_t*)property.val)->product_id,
215           ((bt_vendor_product_info_t*)property.val)->version);
216 
217     case BT_PROPERTY_RESERVED_0x14:
218       return base::StringPrintf("type:%s", bt_property_type_text(property.type).c_str());
219 
220     case BT_PROPERTY_REMOTE_ASHA_CAPABILITY:
221       return base::StringPrintf(
222           "type:%s remote_asha_capability:%hd",
223           bt_property_type_text(property.type).c_str(),
224           (*(int16_t*)property.val));
225 
226     case BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID:
227       return base::StringPrintf(
228           "type:%s remote_asha_truncated_hisyncid:%u",
229           bt_property_type_text(property.type).c_str(),
230           (*(uint32_t*)property.val));
231 
232     case BT_PROPERTY_REMOTE_MODEL_NUM:
233       return base::StringPrintf(
234           "type:%s remote_model_num:%s",
235           bt_property_type_text(property.type).c_str(),
236           (char*)property.val);
237 
238     case BT_PROPERTY_REMOTE_ADDR_TYPE:
239       return base::StringPrintf(
240           "type:%s remote_asha_truncated_hisyncid:0x%x",
241           bt_property_type_text(property.type).c_str(),
242           (*(uint8_t*)property.val));
243 
244     case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
245       return base::StringPrintf("type:%s", bt_property_type_text(property.type).c_str());
246 
247     case BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED:
248       return base::StringPrintf(
249           "type:%s remote secure connections supported:%hhd",
250           bt_property_type_text(property.type).c_str(),
251           (*(uint8_t*)property.val));
252 
253     case BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE:
254       return base::StringPrintf(
255           "type:%s remote max session key size:%hhd",
256           bt_property_type_text(property.type).c_str(),
257           (*(uint8_t*)property.val));
258   }
259   return std::string("Unknown");
260 }
261 
262 namespace bluetooth::property {
263 
BtPropertyLegacy(const std::vector<std::shared_ptr<BtProperty>> & bt_properties)264 BtPropertyLegacy::BtPropertyLegacy(const std::vector<std::shared_ptr<BtProperty>>& bt_properties)
265     : bt_properties_(bt_properties) {
266   properties_.resize(bt_properties.size());
267   std::vector<bt_property_t>::iterator it = properties_.begin();
268   for (const auto& p : bt_properties) {
269     *it++ = {
270         .type = p->Type(),
271         .len = (int)p->Size(),
272         .val = (void*)p->Val(),
273     };
274   }
275 }
276 
Export(bt_property_t * bt_properties,size_t size)277 void BtPropertyLegacy::Export(bt_property_t* bt_properties, size_t size) {
278   log::assert_that(bt_properties != nullptr, "assert failed: bt_properties != nullptr");
279   log::assert_that(size >= properties_.size(), "assert failed: size >= properties_.size()");
280 
281   for (const auto& p : bt_properties_) {
282     *bt_properties++ = {
283         .type = p->Type(),
284         .len = (int)p->Size(),
285         .val = (void*)p->Val(),
286     };
287   }
288 }
289 
NumProperties() const290 size_t BtPropertyLegacy::NumProperties() const {
291   return properties_.size();
292 }
293 
Properties() const294 const std::vector<bt_property_t>& BtPropertyLegacy::Properties() const {
295   return properties_;
296 }
297 
Create(const BD_NAME bd_name)298 std::shared_ptr<BdName> BdName::Create(const BD_NAME bd_name) {
299   return std::make_shared<BdName>(BdName(bd_name));
300 }
Create(const RawAddress & bd_addr)301 std::shared_ptr<BdAddr> BdAddr::Create(const RawAddress& bd_addr) {
302   return std::make_shared<BdAddr>(BdAddr(bd_addr));
303 }
Create(const std::vector<bluetooth::Uuid> & uuids)304 std::shared_ptr<Uuids> Uuids::Create(const std::vector<bluetooth::Uuid>& uuids) {
305   return std::make_shared<Uuids>(Uuids(uuids));
306 }
Create(const uint32_t & cod)307 std::shared_ptr<ClassOfDevice> ClassOfDevice::Create(const uint32_t& cod) {
308   return std::make_shared<ClassOfDevice>(ClassOfDevice(cod));
309 }
Create(const bt_device_type_t & type)310 std::shared_ptr<TypeOfDevice> TypeOfDevice::Create(const bt_device_type_t& type) {
311   return std::make_shared<TypeOfDevice>(TypeOfDevice(type));
312 }
Create(const bt_service_record_t & record)313 std::shared_ptr<ServiceRecord> ServiceRecord::Create(const bt_service_record_t& record) {
314   return std::make_shared<ServiceRecord>(ServiceRecord(record));
315 }
Create(const bt_scan_mode_t & mode)316 std::shared_ptr<AdapterScanMode> AdapterScanMode::Create(const bt_scan_mode_t& mode) {
317   return std::make_shared<AdapterScanMode>(AdapterScanMode(mode));
318 }
Create(const RawAddress * bd_addr,size_t len)319 std::shared_ptr<AdapterBondedDevices> AdapterBondedDevices::Create(
320     const RawAddress* bd_addr, size_t len) {
321   log::assert_that(bd_addr != nullptr, "assert failed: bd_addr != nullptr");
322   return std::make_shared<AdapterBondedDevices>(AdapterBondedDevices(bd_addr, len));
323 }
Create(const uint32_t & timeout)324 std::shared_ptr<AdapterDiscoverableTimeout> AdapterDiscoverableTimeout::Create(
325     const uint32_t& timeout) {
326   return std::make_shared<AdapterDiscoverableTimeout>(AdapterDiscoverableTimeout(timeout));
327 }
Create(const uint8_t bd_name[],size_t len)328 std::shared_ptr<RemoteFriendlyName> RemoteFriendlyName::Create(
329     const uint8_t bd_name[], size_t len) {
330   return std::make_shared<RemoteFriendlyName>(RemoteFriendlyName(bd_name, len));
331 }
Create(const int8_t & rssi)332 std::shared_ptr<RemoteRSSI> RemoteRSSI::Create(const int8_t& rssi) {
333   return std::make_shared<RemoteRSSI>(RemoteRSSI(rssi));
334 }
Create(const bt_remote_version_t & info)335 std::shared_ptr<RemoteVersionInfo> RemoteVersionInfo::Create(const bt_remote_version_t& info) {
336   return std::make_shared<RemoteVersionInfo>(RemoteVersionInfo(info));
337 }
Create(const bt_local_le_features_t & features)338 std::shared_ptr<LocalLeFeatures> LocalLeFeatures::Create(const bt_local_le_features_t& features) {
339   return std::make_shared<LocalLeFeatures>(LocalLeFeatures(features));
340 }
Create(const bool & is_set_member)341 std::shared_ptr<RemoteIsCoordinatedSetMember> RemoteIsCoordinatedSetMember::Create(
342     const bool& is_set_member) {
343   return std::make_shared<RemoteIsCoordinatedSetMember>(
344       RemoteIsCoordinatedSetMember(is_set_member));
345 }
Create(const uint16_t & appearance)346 std::shared_ptr<Appearance> Appearance::Create(const uint16_t& appearance) {
347   return std::make_shared<Appearance>(Appearance(appearance));
348 }
Create(const bt_vendor_product_info_t & info)349 std::shared_ptr<VendorProductInfo> VendorProductInfo::Create(const bt_vendor_product_info_t& info) {
350   return std::make_shared<VendorProductInfo>(VendorProductInfo(info));
351 }
Create(const int16_t & capability)352 std::shared_ptr<RemoteASHACapability> RemoteASHACapability::Create(const int16_t& capability) {
353   return std::make_shared<RemoteASHACapability>(RemoteASHACapability(capability));
354 }
Create(const uint32_t & id)355 std::shared_ptr<RemoteASHATruncatedHiSyncId> RemoteASHATruncatedHiSyncId::Create(
356     const uint32_t& id) {
357   return std::make_shared<RemoteASHATruncatedHiSyncId>(RemoteASHATruncatedHiSyncId(id));
358 }
Create(const bt_bdname_t & name)359 std::shared_ptr<RemoteModelNum> RemoteModelNum::Create(const bt_bdname_t& name) {
360   return std::make_shared<RemoteModelNum>(RemoteModelNum(name));
361 }
Create(const uint8_t & addr)362 std::shared_ptr<RemoteAddrType> RemoteAddrType::Create(const uint8_t& addr) {
363   return std::make_shared<RemoteAddrType>(RemoteAddrType(addr));
364 }
Create(const int & timestamp)365 std::shared_ptr<RemoteDeviceTimestamp> RemoteDeviceTimestamp::Create(const int& timestamp) {
366   return std::make_shared<RemoteDeviceTimestamp>(RemoteDeviceTimestamp(timestamp));
367 }
368 
369 }  // namespace bluetooth::property
370