1 /******************************************************************************
2 *
3 * Copyright 2022 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #define LOG_TAG "bt_btif_profile_storage"
19
20 #include "btif_profile_storage.h"
21
22 #include <alloca.h>
23 #include <bluetooth/log.h>
24 #include <com_android_bluetooth_flags.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>
28
29 #include <vector>
30
31 #include "bta_csis_api.h"
32 #include "bta_groups.h"
33 #include "bta_has_api.h"
34 #include "bta_hd_api.h"
35 #include "bta_hearing_aid_api.h"
36 #include "bta_hh_api.h"
37 #include "bta_le_audio_api.h"
38 #include "bta_vc_api.h"
39 #include "btif/include/btif_dm.h"
40 #include "btif/include/btif_jni_task.h"
41 #include "btif_config.h"
42 #include "btif_hh.h"
43 #include "btif_storage.h"
44 #include "stack/include/bt_uuid16.h"
45 #include "stack/include/main_thread.h"
46 #include "storage/config_keys.h"
47 #include "types/bluetooth/uuid.h"
48 #include "types/raw_address.h"
49
50 using base::Bind;
51 using bluetooth::Uuid;
52 using bluetooth::csis::CsisClient;
53 using bluetooth::groups::DeviceGroups;
54 using namespace bluetooth;
55
56 /*******************************************************************************
57 * Constants & Macros
58 ******************************************************************************/
59
60 #define STORAGE_HID_ATRR_MASK_SIZE (4)
61 #define STORAGE_HID_SUB_CLASS_SIZE (2)
62 #define STORAGE_HID_APP_ID_SIZE (2)
63 #define STORAGE_HID_VENDOR_ID_SIZE (4)
64 #define STORAGE_HID_PRODUCT_ID_SIZE (4)
65 #define STORAGE_HID_VERSION_SIZE (4)
66 #define STORAGE_HID_CTRY_CODE_SIZE (2)
67 #define STORAGE_HID_DESC_LEN_SIZE (4)
68 #define STORAGE_HID_DESC_MAX_SIZE (2 * 512)
69
70 /* <18 char bd addr> <space>LIST <attr_mask> <space> > <sub_class> <space>
71 <app_id> <space>
72 <vendor_id> <space> > <product_id> <space>
73 <version> <space>
74 <ctry_code> <space> > <desc_len> <space>
75 <desc_list> <space> */
76 #define BTIF_HID_INFO_ENTRY_SIZE_MAX \
77 (STORAGE_BDADDR_STRING_SZ + 1 + STORAGE_HID_ATRR_MASK_SIZE + 1 + \
78 STORAGE_HID_SUB_CLASS_SIZE + 1 + STORAGE_HID_APP_ID_SIZE + 1 + \
79 STORAGE_HID_VENDOR_ID_SIZE + 1 + STORAGE_HID_PRODUCT_ID_SIZE + 1 + \
80 STORAGE_HID_VERSION_SIZE + 1 + STORAGE_HID_CTRY_CODE_SIZE + 1 + \
81 STORAGE_HID_DESC_LEN_SIZE + 1 + STORAGE_HID_DESC_MAX_SIZE + 1)
82
83 #define STORAGE_HID_DB_VERSION (1)
84
btif_storage_hid_device_info(std::string bdstr,uint16_t attr_mask,uint8_t sub_class,uint8_t app_id,uint16_t vendor_id,uint16_t product_id,uint16_t version,uint8_t ctry_code,uint16_t ssr_max_latency,uint16_t ssr_min_tout,uint16_t dl_len,uint8_t * dsc_list)85 static void btif_storage_hid_device_info(
86 std::string bdstr, uint16_t attr_mask, uint8_t sub_class, uint8_t app_id,
87 uint16_t vendor_id, uint16_t product_id, uint16_t version,
88 uint8_t ctry_code, uint16_t ssr_max_latency, uint16_t ssr_min_tout,
89 uint16_t dl_len, uint8_t* dsc_list) {
90 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_ATTR_MASK, attr_mask);
91 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_SUB_CLASS, sub_class);
92 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_APP_ID, app_id);
93 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_VENDOR_ID, vendor_id);
94 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_PRODUCT_ID, product_id);
95 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_VERSION, version);
96 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_COUNTRY_CODE, ctry_code);
97 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_SSR_MAX_LATENCY,
98 ssr_max_latency);
99 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_SSR_MIN_TIMEOUT,
100 ssr_min_tout);
101 if (dl_len > 0)
102 btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_HID_DESCRIPTOR, dsc_list,
103 dl_len);
104 }
btif_storage_hogp_device_info(std::string bdstr,uint16_t attr_mask,uint8_t sub_class,uint8_t app_id,uint16_t vendor_id,uint16_t product_id,uint16_t version,uint8_t ctry_code,uint16_t dl_len,uint8_t * dsc_list)105 static void btif_storage_hogp_device_info(std::string bdstr, uint16_t attr_mask,
106 uint8_t sub_class, uint8_t app_id,
107 uint16_t vendor_id,
108 uint16_t product_id, uint16_t version,
109 uint8_t ctry_code, uint16_t dl_len,
110 uint8_t* dsc_list) {
111 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HOGP_ATTR_MASK, attr_mask);
112 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HOGP_SUB_CLASS, sub_class);
113 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HOGP_APP_ID, app_id);
114 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HOGP_VENDOR_ID, vendor_id);
115 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HOGP_PRODUCT_ID, product_id);
116 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HOGP_VERSION, version);
117 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HOGP_COUNTRY_CODE, ctry_code);
118 if (dl_len > 0)
119 btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_HOGP_DESCRIPTOR, dsc_list,
120 dl_len);
121 }
122 /*******************************************************************************
123 *
124 * Function btif_storage_add_hid_device_info
125 *
126 * Description BTIF storage API - Adds the hid information of bonded hid
127 * devices-to NVRAM
128 *
129 * Returns BT_STATUS_SUCCESS if the store was successful,
130 * BT_STATUS_FAIL otherwise
131 *
132 ******************************************************************************/
133
btif_storage_add_hid_device_info(const tAclLinkSpec & link_spec,uint16_t attr_mask,uint8_t sub_class,uint8_t app_id,uint16_t vendor_id,uint16_t product_id,uint16_t version,uint8_t ctry_code,uint16_t ssr_max_latency,uint16_t ssr_min_tout,uint16_t dl_len,uint8_t * dsc_list)134 bt_status_t btif_storage_add_hid_device_info(
135 const tAclLinkSpec& link_spec, uint16_t attr_mask, uint8_t sub_class,
136 uint8_t app_id, uint16_t vendor_id, uint16_t product_id, uint16_t version,
137 uint8_t ctry_code, uint16_t ssr_max_latency, uint16_t ssr_min_tout,
138 uint16_t dl_len, uint8_t* dsc_list) {
139 log::verbose("link spec: {}", link_spec.ToRedactedStringForLogging());
140 std::string bdstr = link_spec.addrt.bda.ToString();
141
142 if (!com::android::bluetooth::flags::allow_switching_hid_and_hogp()) {
143 btif_storage_hid_device_info(
144 bdstr, attr_mask, sub_class, app_id, vendor_id, product_id, version,
145 ctry_code, ssr_max_latency, ssr_min_tout, dl_len, dsc_list);
146 return BT_STATUS_SUCCESS;
147 }
148
149 if (link_spec.transport == BT_TRANSPORT_AUTO) {
150 log::error("Unexpected transport!");
151 return BT_STATUS_UNHANDLED;
152 }
153 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_DB_VERSION,
154 STORAGE_HID_DB_VERSION);
155 if (link_spec.transport == BT_TRANSPORT_BR_EDR) {
156 btif_storage_hid_device_info(
157 bdstr, attr_mask, sub_class, app_id, vendor_id, product_id, version,
158 ctry_code, ssr_max_latency, ssr_min_tout, dl_len, dsc_list);
159 } else {
160 btif_storage_hogp_device_info(bdstr, attr_mask, sub_class, app_id,
161 vendor_id, product_id, version, ctry_code,
162 dl_len, dsc_list);
163 }
164
165 return BT_STATUS_SUCCESS;
166 }
167
btif_storage_load_bonded_hid_device(const tAclLinkSpec link_spec)168 static void btif_storage_load_bonded_hid_device(const tAclLinkSpec link_spec) {
169 auto name = link_spec.addrt.bda.ToString();
170 int value;
171 bool reconnect_allowed = true;
172
173 if (!btif_config_get_int(name, BTIF_STORAGE_KEY_HID_ATTR_MASK, &value))
174 return;
175 uint16_t attr_mask = (uint16_t)value;
176
177 if (btif_in_fetch_bonded_device(name) != BT_STATUS_SUCCESS) {
178 btif_storage_remove_hid_info(link_spec);
179 return;
180 }
181
182 tBTA_HH_DEV_DSCP_INFO dscp_info = {};
183
184 btif_config_get_int(name, BTIF_STORAGE_KEY_HID_SUB_CLASS, &value);
185 uint8_t sub_class = (uint8_t)value;
186
187 btif_config_get_int(name, BTIF_STORAGE_KEY_HID_APP_ID, &value);
188 uint8_t app_id = (uint8_t)value;
189
190 btif_config_get_int(name, BTIF_STORAGE_KEY_HID_VENDOR_ID, &value);
191 dscp_info.vendor_id = (uint16_t)value;
192
193 btif_config_get_int(name, BTIF_STORAGE_KEY_HID_PRODUCT_ID, &value);
194 dscp_info.product_id = (uint16_t)value;
195
196 btif_config_get_int(name, BTIF_STORAGE_KEY_HID_VERSION, &value);
197 dscp_info.version = (uint16_t)value;
198
199 btif_config_get_int(name, BTIF_STORAGE_KEY_HID_COUNTRY_CODE, &value);
200 dscp_info.ctry_code = (uint8_t)value;
201
202 value = 0;
203 btif_config_get_int(name, BTIF_STORAGE_KEY_HID_SSR_MAX_LATENCY, &value);
204 dscp_info.ssr_max_latency = (uint16_t)value;
205
206 value = 0;
207 btif_config_get_int(name, BTIF_STORAGE_KEY_HID_SSR_MIN_TIMEOUT, &value);
208 dscp_info.ssr_min_tout = (uint16_t)value;
209
210 size_t len =
211 btif_config_get_bin_length(name, BTIF_STORAGE_KEY_HID_DESCRIPTOR);
212 if (len > 0) {
213 dscp_info.descriptor.dl_len = (uint16_t)len;
214 dscp_info.descriptor.dsc_list = (uint8_t*)alloca(len);
215 btif_config_get_bin(name, BTIF_STORAGE_KEY_HID_DESCRIPTOR,
216 (uint8_t*)dscp_info.descriptor.dsc_list, &len);
217 }
218
219 btif_storage_get_hid_connection_policy(link_spec, &reconnect_allowed);
220 // add extracted information to BTA HH
221 btif_hh_load_bonded_dev(link_spec, attr_mask, sub_class, app_id, dscp_info,
222 reconnect_allowed);
223 }
224
btif_storage_load_bonded_hogp_device(const tAclLinkSpec link_spec)225 static void btif_storage_load_bonded_hogp_device(const tAclLinkSpec link_spec) {
226 auto name = link_spec.addrt.bda.ToString();
227 int value;
228 bool reconnect_allowed = true;
229
230 if (!btif_config_get_int(name, BTIF_STORAGE_KEY_HOGP_ATTR_MASK, &value))
231 return;
232 uint16_t attr_mask = (uint16_t)value;
233
234 if (btif_in_fetch_bonded_device(name) != BT_STATUS_SUCCESS) {
235 btif_storage_remove_hid_info(link_spec);
236 return;
237 }
238
239 tBTA_HH_DEV_DSCP_INFO dscp_info = {};
240
241 btif_config_get_int(name, BTIF_STORAGE_KEY_HOGP_SUB_CLASS, &value);
242 uint8_t sub_class = (uint8_t)value;
243
244 btif_config_get_int(name, BTIF_STORAGE_KEY_HOGP_APP_ID, &value);
245 uint8_t app_id = (uint8_t)value;
246
247 btif_config_get_int(name, BTIF_STORAGE_KEY_HOGP_VENDOR_ID, &value);
248 dscp_info.vendor_id = (uint16_t)value;
249
250 btif_config_get_int(name, BTIF_STORAGE_KEY_HOGP_PRODUCT_ID, &value);
251 dscp_info.product_id = (uint16_t)value;
252
253 btif_config_get_int(name, BTIF_STORAGE_KEY_HOGP_VERSION, &value);
254 dscp_info.version = (uint16_t)value;
255
256 btif_config_get_int(name, BTIF_STORAGE_KEY_HOGP_COUNTRY_CODE, &value);
257 dscp_info.ctry_code = (uint8_t)value;
258
259 size_t len =
260 btif_config_get_bin_length(name, BTIF_STORAGE_KEY_HOGP_DESCRIPTOR);
261 if (len > 0) {
262 dscp_info.descriptor.dl_len = (uint16_t)len;
263 dscp_info.descriptor.dsc_list = (uint8_t*)alloca(len);
264 btif_config_get_bin(name, BTIF_STORAGE_KEY_HOGP_DESCRIPTOR,
265 (uint8_t*)dscp_info.descriptor.dsc_list, &len);
266 }
267
268 btif_storage_get_hid_connection_policy(link_spec, &reconnect_allowed);
269 // add extracted information to BTA HH
270 btif_hh_load_bonded_dev(link_spec, attr_mask, sub_class, app_id, dscp_info,
271 reconnect_allowed);
272 }
273 /*******************************************************************************
274 *
275 * Function btif_storage_load_bonded_hid_info
276 *
277 * Description BTIF storage API - Loads hid info for all the bonded devices
278 * from NVRAM and adds those devices to the BTA_HH.
279 *
280 * Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
281 *
282 ******************************************************************************/
btif_storage_load_bonded_hid_info(void)283 bt_status_t btif_storage_load_bonded_hid_info(void) {
284 for (const auto& bd_addr : btif_config_get_paired_devices()) {
285 auto name = bd_addr.ToString();
286 tAclLinkSpec link_spec = {};
287 link_spec.addrt.bda = bd_addr;
288 link_spec.addrt.type = BLE_ADDR_PUBLIC;
289 link_spec.transport = BT_TRANSPORT_AUTO;
290
291 int db_version = 0;
292 if (com::android::bluetooth::flags::allow_switching_hid_and_hogp()) {
293 btif_config_get_int(name, BTIF_STORAGE_KEY_HID_DB_VERSION, &db_version);
294 }
295
296 log::info("link spec: {}; db version: {}", link_spec, db_version);
297
298 if (db_version == 0) {
299 btif_storage_load_bonded_hid_device(link_spec);
300 } else {
301 link_spec.transport = BT_TRANSPORT_BR_EDR;
302 btif_storage_load_bonded_hid_device(link_spec);
303
304 link_spec.transport = BT_TRANSPORT_LE;
305 btif_storage_load_bonded_hogp_device(link_spec);
306 }
307 }
308 return BT_STATUS_SUCCESS;
309 }
310
311 /*******************************************************************************
312 *
313 * Function btif_storage_remove_hid_info
314 *
315 * Description BTIF storage API - Deletes the bonded hid device info from
316 * NVRAM
317 *
318 * Returns BT_STATUS_SUCCESS if the deletion was successful,
319 * BT_STATUS_FAIL otherwise
320 *
321 ******************************************************************************/
btif_storage_remove_hid_info(const tAclLinkSpec & link_spec)322 bt_status_t btif_storage_remove_hid_info(const tAclLinkSpec& link_spec) {
323 std::string bdstr = link_spec.addrt.bda.ToString();
324
325 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_ATTR_MASK);
326 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_SUB_CLASS);
327 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_APP_ID);
328 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_VENDOR_ID);
329 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_PRODUCT_ID);
330 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_VERSION);
331 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_COUNTRY_CODE);
332 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_SSR_MAX_LATENCY);
333 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_SSR_MIN_TIMEOUT);
334 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_DESCRIPTOR);
335 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_RECONNECT_ALLOWED);
336 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT);
337 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_REPORT_VERSION);
338
339 if (com::android::bluetooth::flags::allow_switching_hid_and_hogp()) {
340 int db_version = 0;
341 btif_config_get_int(bdstr, BTIF_STORAGE_KEY_HID_DB_VERSION, &db_version);
342 if (db_version == STORAGE_HID_DB_VERSION) {
343 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_ATTR_MASK);
344 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_SUB_CLASS);
345 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_APP_ID);
346 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_VENDOR_ID);
347 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_PRODUCT_ID);
348 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_VERSION);
349 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_COUNTRY_CODE);
350 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_DESCRIPTOR);
351 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HOGP_RECONNECT_ALLOWED);
352 }
353 btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_DB_VERSION);
354 }
355 return BT_STATUS_SUCCESS;
356 }
357
358 // Check if a given profile is supported.
btif_device_supports_profile(const std::string & device,const Uuid & profile)359 static bool btif_device_supports_profile(const std::string& device,
360 const Uuid& profile) {
361 int size = STORAGE_UUID_STRING_SIZE * BT_MAX_NUM_UUIDS;
362 char uuid_str[size];
363 if (btif_config_get_str(device, BTIF_STORAGE_KEY_REMOTE_SERVICE, uuid_str,
364 &size)) {
365 Uuid p_uuid[BT_MAX_NUM_UUIDS];
366 size_t num_uuids =
367 btif_split_uuids_string(uuid_str, p_uuid, BT_MAX_NUM_UUIDS);
368 for (size_t i = 0; i < num_uuids; i++) {
369 if (p_uuid[i] == profile) {
370 return true;
371 }
372 }
373 }
374
375 return false;
376 }
377
btif_device_supports_hogp(const std::string & device)378 static bool btif_device_supports_hogp(const std::string& device) {
379 return btif_device_supports_profile(device,
380 Uuid::From16Bit(UUID_SERVCLASS_LE_HID));
381 }
382
btif_device_supports_classic_hid(const std::string & device)383 static bool btif_device_supports_classic_hid(const std::string& device) {
384 return btif_device_supports_profile(
385 device, Uuid::From16Bit(UUID_SERVCLASS_HUMAN_INTERFACE));
386 }
387
388 /*******************************************************************************
389 *
390 * Function btif_storage_get_le_hid_devices
391 *
392 * Description BTIF storage API - Finds all bonded LE HID devices
393 *
394 * Returns std::vector of (RawAddress, AddressType)
395 *
396 ******************************************************************************/
397
398 bool btif_get_address_type(const RawAddress& bda, tBLE_ADDR_TYPE* p_addr_type);
399
btif_storage_get_le_hid_devices(void)400 std::vector<std::pair<RawAddress, uint8_t>> btif_storage_get_le_hid_devices(
401 void) {
402 std::vector<std::pair<RawAddress, uint8_t>> hid_addresses;
403 for (const auto& bd_addr : btif_config_get_paired_devices()) {
404 auto name = bd_addr.ToString();
405 if (btif_device_supports_hogp(name)) {
406 tBLE_ADDR_TYPE type = BLE_ADDR_PUBLIC;
407 btif_get_address_type(bd_addr, &type);
408
409 hid_addresses.push_back({bd_addr, type});
410 log::debug("Remote device: {}", bd_addr);
411 }
412 }
413
414 return hid_addresses;
415 }
416
btif_storage_get_wake_capable_classic_hid_devices(void)417 std::vector<RawAddress> btif_storage_get_wake_capable_classic_hid_devices(
418 void) {
419 std::vector<RawAddress> hid_addresses;
420 for (const auto& bd_addr : btif_config_get_paired_devices()) {
421 auto name = bd_addr.ToString();
422 if (btif_device_supports_classic_hid(name)) {
423 // Filter out devices that aren't keyboards or pointing devices.
424 // 0x500 = HID Major
425 // 0x080 = Pointing device
426 // 0x040 = Keyboard
427 constexpr int kHidMask = COD_HID_MAJOR;
428 constexpr int kKeyboardMouseMask = COD_HID_COMBO & ~COD_HID_MAJOR;
429 int cod_value;
430 if (!btif_config_get_int(name, BTIF_STORAGE_KEY_DEV_CLASS, &cod_value) ||
431 (cod_value & kHidMask) != kHidMask ||
432 (cod_value & kKeyboardMouseMask) == 0) {
433 continue;
434 }
435
436 hid_addresses.push_back(bd_addr);
437 log::debug("Remote device: {}", bd_addr);
438 }
439 }
440
441 return hid_addresses;
442 }
443
btif_storage_add_hearing_aid(const HearingDevice & dev_info)444 void btif_storage_add_hearing_aid(const HearingDevice& dev_info) {
445 do_in_jni_thread(
446 Bind(
447 [](const HearingDevice& dev_info) {
448 std::string bdstr = dev_info.address.ToString();
449 log::verbose("saving hearing aid device: {}", dev_info.address);
450 btif_config_set_int(
451 bdstr, BTIF_STORAGE_KEY_HEARING_AID_SERVICE_CHANGED_CCC_HANDLE,
452 dev_info.service_changed_ccc_handle);
453 btif_config_set_int(bdstr,
454 BTIF_STORAGE_KEY_HEARING_AID_READ_PSM_HANDLE,
455 dev_info.read_psm_handle);
456 btif_config_set_int(bdstr,
457 BTIF_STORAGE_KEY_HEARING_AID_CAPABILITIES,
458 dev_info.capabilities);
459 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HEARING_AID_CODECS,
460 dev_info.codecs);
461 btif_config_set_int(
462 bdstr, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_CONTROL_POINT,
463 dev_info.audio_control_point_handle);
464 btif_config_set_int(bdstr,
465 BTIF_STORAGE_KEY_HEARING_AID_VOLUME_HANDLE,
466 dev_info.volume_handle);
467 btif_config_set_int(
468 bdstr, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_HANDLE,
469 dev_info.audio_status_handle);
470 btif_config_set_int(
471 bdstr, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_CCC_HANDLE,
472 dev_info.audio_status_ccc_handle);
473 btif_config_set_uint64(bdstr, BTIF_STORAGE_KEY_HEARING_AID_SYNC_ID,
474 dev_info.hi_sync_id);
475 btif_config_set_int(bdstr,
476 BTIF_STORAGE_KEY_HEARING_AID_RENDER_DELAY,
477 dev_info.render_delay);
478 btif_config_set_int(bdstr,
479 BTIF_STORAGE_KEY_HEARING_AID_PREPARATION_DELAY,
480 dev_info.preparation_delay);
481 btif_config_set_int(
482 bdstr, BTIF_STORAGE_KEY_HEARING_AID_IS_ACCEPTLISTED, true);
483 },
484 dev_info));
485 }
486
487 /** Loads information about bonded hearing aid devices */
btif_storage_load_bonded_hearing_aids()488 void btif_storage_load_bonded_hearing_aids() {
489 for (const auto& bd_addr : btif_config_get_paired_devices()) {
490 const std::string& name = bd_addr.ToString();
491
492 int size = STORAGE_UUID_STRING_SIZE * BT_MAX_NUM_UUIDS;
493 char uuid_str[size];
494 bool isHearingaidDevice = false;
495 if (btif_config_get_str(name, BTIF_STORAGE_KEY_REMOTE_SERVICE, uuid_str,
496 &size)) {
497 Uuid p_uuid[BT_MAX_NUM_UUIDS];
498 size_t num_uuids =
499 btif_split_uuids_string(uuid_str, p_uuid, BT_MAX_NUM_UUIDS);
500 for (size_t i = 0; i < num_uuids; i++) {
501 if (p_uuid[i] == Uuid::FromString("FDF0")) {
502 isHearingaidDevice = true;
503 break;
504 }
505 }
506 }
507 if (!isHearingaidDevice) {
508 continue;
509 }
510
511 log::verbose("Remote device:{}", bd_addr);
512
513 if (btif_in_fetch_bonded_device(name) != BT_STATUS_SUCCESS) {
514 btif_storage_remove_hearing_aid(bd_addr);
515 continue;
516 }
517
518 int value;
519 uint8_t capabilities = 0;
520 if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_CAPABILITIES,
521 &value))
522 capabilities = value;
523
524 uint16_t codecs = 0;
525 if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_CODECS, &value))
526 codecs = value;
527
528 uint16_t audio_control_point_handle = 0;
529 if (btif_config_get_int(
530 name, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_CONTROL_POINT, &value))
531 audio_control_point_handle = value;
532
533 uint16_t audio_status_handle = 0;
534 if (btif_config_get_int(
535 name, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_HANDLE, &value))
536 audio_status_handle = value;
537
538 uint16_t audio_status_ccc_handle = 0;
539 if (btif_config_get_int(
540 name, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_CCC_HANDLE, &value))
541 audio_status_ccc_handle = value;
542
543 uint16_t service_changed_ccc_handle = 0;
544 if (btif_config_get_int(
545 name, BTIF_STORAGE_KEY_HEARING_AID_SERVICE_CHANGED_CCC_HANDLE,
546 &value))
547 service_changed_ccc_handle = value;
548
549 uint16_t volume_handle = 0;
550 if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_VOLUME_HANDLE,
551 &value))
552 volume_handle = value;
553
554 uint16_t read_psm_handle = 0;
555 if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_READ_PSM_HANDLE,
556 &value))
557 read_psm_handle = value;
558
559 uint64_t lvalue;
560 uint64_t hi_sync_id = 0;
561 if (btif_config_get_uint64(name, BTIF_STORAGE_KEY_HEARING_AID_SYNC_ID,
562 &lvalue))
563 hi_sync_id = lvalue;
564
565 uint16_t render_delay = 0;
566 if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_RENDER_DELAY,
567 &value))
568 render_delay = value;
569
570 uint16_t preparation_delay = 0;
571 if (btif_config_get_int(
572 name, BTIF_STORAGE_KEY_HEARING_AID_PREPARATION_DELAY, &value))
573 preparation_delay = value;
574
575 bool is_acceptlisted = false;
576 if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_IS_ACCEPTLISTED,
577 &value))
578 is_acceptlisted = value;
579
580 // add extracted information to BTA Hearing Aid
581 do_in_main_thread(
582 FROM_HERE,
583 Bind(&HearingAid::AddFromStorage,
584 HearingDevice(bd_addr, capabilities, codecs,
585 audio_control_point_handle, audio_status_handle,
586 audio_status_ccc_handle, service_changed_ccc_handle,
587 volume_handle, read_psm_handle, hi_sync_id,
588 render_delay, preparation_delay),
589 is_acceptlisted));
590 }
591 }
592
593 /** Deletes the bonded hearing aid device info from NVRAM */
btif_storage_remove_hearing_aid(const RawAddress & address)594 void btif_storage_remove_hearing_aid(const RawAddress& address) {
595 std::string addrstr = address.ToString();
596 btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_READ_PSM_HANDLE);
597 btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_CAPABILITIES);
598 btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_CODECS);
599 btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_CONTROL_POINT);
600 btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_VOLUME_HANDLE);
601 btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_HANDLE);
602 btif_config_remove(addrstr,
603 BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_CCC_HANDLE);
604 btif_config_remove(addrstr,
605 BTIF_STORAGE_KEY_HEARING_AID_SERVICE_CHANGED_CCC_HANDLE);
606 btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_SYNC_ID);
607 btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_RENDER_DELAY);
608 btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_PREPARATION_DELAY);
609 btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_IS_ACCEPTLISTED);
610 }
611
612 /** Set/Unset the hearing aid device HEARING_AID_IS_ACCEPTLISTED flag. */
btif_storage_set_hearing_aid_acceptlist(const RawAddress & address,bool add_to_acceptlist)613 void btif_storage_set_hearing_aid_acceptlist(const RawAddress& address,
614 bool add_to_acceptlist) {
615 std::string addrstr = address.ToString();
616
617 btif_config_set_int(addrstr, BTIF_STORAGE_KEY_HEARING_AID_IS_ACCEPTLISTED,
618 add_to_acceptlist);
619 }
620
621 /** Get the hearing aid device properties. */
btif_storage_get_hearing_aid_prop(const RawAddress & address,uint8_t * capabilities,uint64_t * hi_sync_id,uint16_t * render_delay,uint16_t * preparation_delay,uint16_t * codecs)622 bool btif_storage_get_hearing_aid_prop(
623 const RawAddress& address, uint8_t* capabilities, uint64_t* hi_sync_id,
624 uint16_t* render_delay, uint16_t* preparation_delay, uint16_t* codecs) {
625 std::string addrstr = address.ToString();
626
627 int value;
628 if (btif_config_get_int(addrstr, BTIF_STORAGE_KEY_HEARING_AID_CAPABILITIES,
629 &value)) {
630 *capabilities = value;
631 } else {
632 return false;
633 }
634
635 if (btif_config_get_int(addrstr, BTIF_STORAGE_KEY_HEARING_AID_CODECS,
636 &value)) {
637 *codecs = value;
638 } else {
639 return false;
640 }
641
642 if (btif_config_get_int(addrstr, BTIF_STORAGE_KEY_HEARING_AID_RENDER_DELAY,
643 &value)) {
644 *render_delay = value;
645 } else {
646 return false;
647 }
648
649 if (btif_config_get_int(
650 addrstr, BTIF_STORAGE_KEY_HEARING_AID_PREPARATION_DELAY, &value)) {
651 *preparation_delay = value;
652 } else {
653 return false;
654 }
655
656 uint64_t lvalue;
657 if (btif_config_get_uint64(addrstr, BTIF_STORAGE_KEY_HEARING_AID_SYNC_ID,
658 &lvalue)) {
659 *hi_sync_id = lvalue;
660 } else {
661 return false;
662 }
663
664 return true;
665 }
666
667 /** Set autoconnect information for LeAudio device */
btif_storage_set_leaudio_autoconnect(const RawAddress & addr,bool autoconnect)668 void btif_storage_set_leaudio_autoconnect(const RawAddress& addr,
669 bool autoconnect) {
670 do_in_jni_thread(Bind(
671 [](const RawAddress& addr, bool autoconnect) {
672 std::string bdstr = addr.ToString();
673 log::verbose("saving le audio device: {}", addr);
674 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_LEAUDIO_AUTOCONNECT,
675 autoconnect);
676 },
677 addr, autoconnect));
678 }
679
680 /** Store ASEs information */
btif_storage_leaudio_update_handles_bin(const RawAddress & addr)681 void btif_storage_leaudio_update_handles_bin(const RawAddress& addr) {
682 std::vector<uint8_t> handles;
683
684 if (LeAudioClient::GetHandlesForStorage(addr, handles)) {
685 do_in_jni_thread(Bind(
686 [](const RawAddress& bd_addr, std::vector<uint8_t> handles) {
687 auto bdstr = bd_addr.ToString();
688 btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_LEAUDIO_HANDLES_BIN,
689 handles.data(), handles.size());
690 },
691 addr, std::move(handles)));
692 }
693 }
694
695 /** Store PACs information */
btif_storage_leaudio_update_pacs_bin(const RawAddress & addr)696 void btif_storage_leaudio_update_pacs_bin(const RawAddress& addr) {
697 std::vector<uint8_t> sink_pacs;
698
699 if (LeAudioClient::GetSinkPacsForStorage(addr, sink_pacs)) {
700 do_in_jni_thread(Bind(
701 [](const RawAddress& bd_addr, std::vector<uint8_t> sink_pacs) {
702 auto bdstr = bd_addr.ToString();
703 btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_LEAUDIO_SINK_PACS_BIN,
704 sink_pacs.data(), sink_pacs.size());
705 },
706 addr, std::move(sink_pacs)));
707 }
708
709 std::vector<uint8_t> source_pacs;
710 if (LeAudioClient::GetSourcePacsForStorage(addr, source_pacs)) {
711 do_in_jni_thread(Bind(
712 [](const RawAddress& bd_addr, std::vector<uint8_t> source_pacs) {
713 auto bdstr = bd_addr.ToString();
714 btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_PACS_BIN,
715 source_pacs.data(), source_pacs.size());
716 },
717 addr, std::move(source_pacs)));
718 }
719 }
720
721 /** Store ASEs information */
btif_storage_leaudio_update_ase_bin(const RawAddress & addr)722 void btif_storage_leaudio_update_ase_bin(const RawAddress& addr) {
723 std::vector<uint8_t> ases;
724
725 if (LeAudioClient::GetAsesForStorage(addr, ases)) {
726 do_in_jni_thread(Bind(
727 [](const RawAddress& bd_addr, std::vector<uint8_t> ases) {
728 auto bdstr = bd_addr.ToString();
729 btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_LEAUDIO_ASES_BIN,
730 ases.data(), ases.size());
731 },
732 addr, std::move(ases)));
733 }
734 }
735
736 /** Store Le Audio device audio locations */
btif_storage_set_leaudio_audio_location(const RawAddress & addr,uint32_t sink_location,uint32_t source_location)737 void btif_storage_set_leaudio_audio_location(const RawAddress& addr,
738 uint32_t sink_location,
739 uint32_t source_location) {
740 do_in_jni_thread(
741 Bind(
742 [](const RawAddress& addr, int sink_location, int source_location) {
743 std::string bdstr = addr.ToString();
744 log::debug("saving le audio device: {}", addr);
745 btif_config_set_int(bdstr,
746 BTIF_STORAGE_KEY_LEAUDIO_SINK_AUDIOLOCATION,
747 sink_location);
748 btif_config_set_int(bdstr,
749 BTIF_STORAGE_KEY_LEAUDIO_SOURCE_AUDIOLOCATION,
750 source_location);
751 },
752 addr, sink_location, source_location));
753 }
754
755 /** Store Le Audio device context types */
btif_storage_set_leaudio_supported_context_types(const RawAddress & addr,uint16_t sink_supported_context_type,uint16_t source_supported_context_type)756 void btif_storage_set_leaudio_supported_context_types(
757 const RawAddress& addr, uint16_t sink_supported_context_type,
758 uint16_t source_supported_context_type) {
759 do_in_jni_thread(
760 Bind(
761 [](const RawAddress& addr, int sink_supported_context_type,
762 int source_supported_context_type) {
763 std::string bdstr = addr.ToString();
764 log::debug("saving le audio device: {}", addr);
765 btif_config_set_int(
766 bdstr, BTIF_STORAGE_KEY_LEAUDIO_SINK_SUPPORTED_CONTEXT_TYPE,
767 sink_supported_context_type);
768 btif_config_set_int(
769 bdstr, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_SUPPORTED_CONTEXT_TYPE,
770 source_supported_context_type);
771 },
772 addr, sink_supported_context_type, source_supported_context_type));
773 }
774
775 /** Loads information about bonded Le Audio devices */
btif_storage_load_bonded_leaudio()776 void btif_storage_load_bonded_leaudio() {
777 for (const auto& bd_addr : btif_config_get_paired_devices()) {
778 auto name = bd_addr.ToString();
779
780 int size = STORAGE_UUID_STRING_SIZE * BT_MAX_NUM_UUIDS;
781 char uuid_str[size];
782 bool isLeAudioDevice = false;
783 if (btif_config_get_str(name, BTIF_STORAGE_KEY_REMOTE_SERVICE, uuid_str,
784 &size)) {
785 Uuid p_uuid[BT_MAX_NUM_UUIDS];
786 size_t num_uuids =
787 btif_split_uuids_string(uuid_str, p_uuid, BT_MAX_NUM_UUIDS);
788 for (size_t i = 0; i < num_uuids; i++) {
789 if (p_uuid[i] == Uuid::FromString("184E")) {
790 isLeAudioDevice = true;
791 break;
792 }
793 }
794 }
795 if (!isLeAudioDevice) {
796 continue;
797 }
798
799 log::verbose("Remote device:{}", bd_addr);
800
801 int value;
802 bool autoconnect = false;
803 if (btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_AUTOCONNECT, &value))
804 autoconnect = !!value;
805
806 int sink_audio_location = 0;
807 if (btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_SINK_AUDIOLOCATION,
808 &value))
809 sink_audio_location = value;
810
811 int source_audio_location = 0;
812 if (btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_AUDIOLOCATION,
813 &value))
814 source_audio_location = value;
815
816 int sink_supported_context_type = 0;
817 if (btif_config_get_int(
818 name, BTIF_STORAGE_KEY_LEAUDIO_SINK_SUPPORTED_CONTEXT_TYPE, &value))
819 sink_supported_context_type = value;
820
821 int source_supported_context_type = 0;
822 if (btif_config_get_int(
823 name, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_SUPPORTED_CONTEXT_TYPE,
824 &value))
825 source_supported_context_type = value;
826
827 size_t buffer_size =
828 btif_config_get_bin_length(name, BTIF_STORAGE_KEY_LEAUDIO_HANDLES_BIN);
829 std::vector<uint8_t> handles(buffer_size);
830 if (buffer_size > 0) {
831 btif_config_get_bin(name, BTIF_STORAGE_KEY_LEAUDIO_HANDLES_BIN,
832 handles.data(), &buffer_size);
833 }
834
835 buffer_size = btif_config_get_bin_length(
836 name, BTIF_STORAGE_KEY_LEAUDIO_SINK_PACS_BIN);
837 std::vector<uint8_t> sink_pacs(buffer_size);
838 if (buffer_size > 0) {
839 btif_config_get_bin(name, BTIF_STORAGE_KEY_LEAUDIO_SINK_PACS_BIN,
840 sink_pacs.data(), &buffer_size);
841 }
842
843 buffer_size = btif_config_get_bin_length(
844 name, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_PACS_BIN);
845 std::vector<uint8_t> source_pacs(buffer_size);
846 if (buffer_size > 0) {
847 btif_config_get_bin(name, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_PACS_BIN,
848 source_pacs.data(), &buffer_size);
849 }
850
851 buffer_size =
852 btif_config_get_bin_length(name, BTIF_STORAGE_KEY_LEAUDIO_ASES_BIN);
853 std::vector<uint8_t> ases(buffer_size);
854 if (buffer_size > 0) {
855 btif_config_get_bin(name, BTIF_STORAGE_KEY_LEAUDIO_ASES_BIN, ases.data(),
856 &buffer_size);
857 }
858
859 do_in_main_thread(
860 FROM_HERE,
861 Bind(&LeAudioClient::AddFromStorage, bd_addr, autoconnect,
862 sink_audio_location, source_audio_location,
863 sink_supported_context_type, source_supported_context_type,
864 std::move(handles), std::move(sink_pacs), std::move(source_pacs),
865 std::move(ases)));
866 }
867 }
868
btif_storage_leaudio_clear_service_data(const RawAddress & address)869 void btif_storage_leaudio_clear_service_data(const RawAddress& address) {
870 auto bdstr = address.ToString();
871 btif_config_remove(bdstr, BTIF_STORAGE_KEY_LEAUDIO_HANDLES_BIN);
872 btif_config_remove(bdstr, BTIF_STORAGE_KEY_LEAUDIO_SINK_PACS_BIN);
873 btif_config_remove(bdstr, BTIF_STORAGE_KEY_LEAUDIO_ASES_BIN);
874 }
875
876 /** Remove the Le Audio device from storage */
btif_storage_remove_leaudio(const RawAddress & address)877 void btif_storage_remove_leaudio(const RawAddress& address) {
878 std::string addrstr = address.ToString();
879 btif_config_set_int(addrstr, BTIF_STORAGE_KEY_LEAUDIO_AUTOCONNECT, false);
880 }
881
btif_storage_add_leaudio_has_device(const RawAddress & address,std::vector<uint8_t> presets_bin,uint8_t features,uint8_t active_preset)882 void btif_storage_add_leaudio_has_device(const RawAddress& address,
883 std::vector<uint8_t> presets_bin,
884 uint8_t features,
885 uint8_t active_preset) {
886 do_in_jni_thread(
887 Bind(
888 [](const RawAddress& address, std::vector<uint8_t> presets_bin,
889 uint8_t features, uint8_t active_preset) {
890 const std::string& name = address.ToString();
891
892 btif_config_set_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS,
893 features);
894 btif_config_set_int(name,
895 BTIF_STORAGE_KEY_LEAUDIO_HAS_ACTIVE_PRESET,
896 active_preset);
897 btif_config_set_bin(name,
898 BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS,
899 presets_bin.data(), presets_bin.size());
900
901 btif_config_set_int(
902 name, BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED, true);
903 },
904 address, std::move(presets_bin), features, active_preset));
905 }
906
btif_storage_set_leaudio_has_active_preset(const RawAddress & address,uint8_t active_preset)907 void btif_storage_set_leaudio_has_active_preset(const RawAddress& address,
908 uint8_t active_preset) {
909 do_in_jni_thread(Bind(
910 [](const RawAddress& address, uint8_t active_preset) {
911 const std::string& name = address.ToString();
912
913 btif_config_set_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_ACTIVE_PRESET,
914 active_preset);
915 },
916 address, active_preset));
917 }
918
btif_storage_get_leaudio_has_features(const RawAddress & address,uint8_t & features)919 bool btif_storage_get_leaudio_has_features(const RawAddress& address,
920 uint8_t& features) {
921 std::string name = address.ToString();
922
923 int value;
924 if (!btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS, &value))
925 return false;
926
927 features = value;
928 return true;
929 }
930
btif_storage_set_leaudio_has_features(const RawAddress & address,uint8_t features)931 void btif_storage_set_leaudio_has_features(const RawAddress& address,
932 uint8_t features) {
933 do_in_jni_thread(Bind(
934 [](const RawAddress& address, uint8_t features) {
935 const std::string& name = address.ToString();
936
937 btif_config_set_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS, features);
938 },
939 address, features));
940 }
941
btif_storage_load_bonded_leaudio_has_devices()942 void btif_storage_load_bonded_leaudio_has_devices() {
943 for (const auto& bd_addr : btif_config_get_paired_devices()) {
944 const std::string& name = bd_addr.ToString();
945
946 if (!btif_config_exist(name,
947 BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED) &&
948 !btif_config_exist(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS))
949 continue;
950
951 #ifndef TARGET_FLOSS
952 int value;
953 uint16_t is_acceptlisted = 0;
954 if (btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED,
955 &value))
956 is_acceptlisted = value;
957
958 uint8_t features = 0;
959 if (btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS, &value))
960 features = value;
961
962 do_in_main_thread(FROM_HERE,
963 Bind(&bluetooth::le_audio::has::HasClient::AddFromStorage,
964 bd_addr, features, is_acceptlisted));
965 #else
966 log::fatal("TODO - Fix LE audio build.");
967 #endif
968 }
969 }
970
btif_storage_remove_leaudio_has(const RawAddress & address)971 void btif_storage_remove_leaudio_has(const RawAddress& address) {
972 std::string addrstr = address.ToString();
973 btif_config_remove(addrstr, BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED);
974 btif_config_remove(addrstr, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS);
975 btif_config_remove(addrstr, BTIF_STORAGE_KEY_LEAUDIO_HAS_ACTIVE_PRESET);
976 btif_config_remove(addrstr, BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS);
977 }
978
btif_storage_set_leaudio_has_acceptlist(const RawAddress & address,bool add_to_acceptlist)979 void btif_storage_set_leaudio_has_acceptlist(const RawAddress& address,
980 bool add_to_acceptlist) {
981 std::string addrstr = address.ToString();
982
983 btif_config_set_int(addrstr, BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED,
984 add_to_acceptlist);
985 }
986
btif_storage_set_leaudio_has_presets(const RawAddress & address,std::vector<uint8_t> presets_bin)987 void btif_storage_set_leaudio_has_presets(const RawAddress& address,
988 std::vector<uint8_t> presets_bin) {
989 do_in_jni_thread(
990 Bind(
991 [](const RawAddress& address, std::vector<uint8_t> presets_bin) {
992 const std::string& name = address.ToString();
993
994 btif_config_set_bin(name,
995 BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS,
996 presets_bin.data(), presets_bin.size());
997 },
998 address, std::move(presets_bin)));
999 }
1000
btif_storage_get_leaudio_has_presets(const RawAddress & address,std::vector<uint8_t> & presets_bin,uint8_t & active_preset)1001 bool btif_storage_get_leaudio_has_presets(const RawAddress& address,
1002 std::vector<uint8_t>& presets_bin,
1003 uint8_t& active_preset) {
1004 std::string name = address.ToString();
1005
1006 int value;
1007 if (!btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_ACTIVE_PRESET,
1008 &value))
1009 return false;
1010 active_preset = value;
1011
1012 auto bin_sz = btif_config_get_bin_length(
1013 name, BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS);
1014 presets_bin.resize(bin_sz);
1015 if (!btif_config_get_bin(name,
1016 BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS,
1017 presets_bin.data(), &bin_sz))
1018 return false;
1019
1020 return true;
1021 }
1022
1023 /** Adds the bonded Le Audio device grouping info into the NVRAM */
btif_storage_add_groups(const RawAddress & addr)1024 void btif_storage_add_groups(const RawAddress& addr) {
1025 std::vector<uint8_t> group_info;
1026 auto not_empty = DeviceGroups::GetForStorage(addr, group_info);
1027
1028 if (not_empty)
1029 do_in_jni_thread(Bind(
1030 [](const RawAddress& bd_addr, std::vector<uint8_t> group_info) {
1031 auto bdstr = bd_addr.ToString();
1032 btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_DEVICE_GROUP_BIN,
1033 group_info.data(), group_info.size());
1034 },
1035 addr, std::move(group_info)));
1036 }
1037
1038 /** Deletes the bonded Le Audio device grouping info from the NVRAM */
btif_storage_remove_groups(const RawAddress & address)1039 void btif_storage_remove_groups(const RawAddress& address) {
1040 std::string addrstr = address.ToString();
1041 btif_config_remove(addrstr, BTIF_STORAGE_KEY_DEVICE_GROUP_BIN);
1042 }
1043
1044 /** Loads information about bonded group devices */
btif_storage_load_bonded_groups(void)1045 void btif_storage_load_bonded_groups(void) {
1046 for (const auto& bd_addr : btif_config_get_paired_devices()) {
1047 auto name = bd_addr.ToString();
1048 size_t buffer_size =
1049 btif_config_get_bin_length(name, BTIF_STORAGE_KEY_DEVICE_GROUP_BIN);
1050 if (buffer_size == 0) continue;
1051
1052 log::verbose("Grouped device:{}", bd_addr);
1053
1054 std::vector<uint8_t> in(buffer_size);
1055 if (btif_config_get_bin(name, BTIF_STORAGE_KEY_DEVICE_GROUP_BIN, in.data(),
1056 &buffer_size)) {
1057 do_in_main_thread(FROM_HERE, Bind(&DeviceGroups::AddFromStorage, bd_addr,
1058 std::move(in)));
1059 }
1060 }
1061 }
1062
1063 /** Loads information about bonded group devices */
btif_storage_load_bonded_volume_control_devices(void)1064 void btif_storage_load_bonded_volume_control_devices(void) {
1065 for (const auto& bd_addr : btif_config_get_paired_devices()) {
1066 auto device = bd_addr.ToString();
1067 if (btif_device_supports_profile(
1068 device, Uuid::From16Bit(UUID_SERVCLASS_VOLUME_CONTROL_SERVER))) {
1069 do_in_main_thread(FROM_HERE,
1070 Bind(&VolumeControl::AddFromStorage, bd_addr));
1071 }
1072 }
1073 }
1074
1075 /** Stores information about the bonded CSIS device */
btif_storage_update_csis_info(const RawAddress & addr)1076 void btif_storage_update_csis_info(const RawAddress& addr) {
1077 std::vector<uint8_t> set_info;
1078 auto not_empty = CsisClient::GetForStorage(addr, set_info);
1079
1080 if (not_empty)
1081 do_in_jni_thread(Bind(
1082 [](const RawAddress& bd_addr, std::vector<uint8_t> set_info) {
1083 auto bdstr = bd_addr.ToString();
1084 btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_CSIS_SET_INFO_BIN,
1085 set_info.data(), set_info.size());
1086 },
1087 addr, std::move(set_info)));
1088 }
1089
1090 /** Loads information about the bonded CSIS device */
btif_storage_load_bonded_csis_devices(void)1091 void btif_storage_load_bonded_csis_devices(void) {
1092 for (const auto& bd_addr : btif_config_get_paired_devices()) {
1093 auto name = bd_addr.ToString();
1094
1095 log::verbose("Loading CSIS device:{}", bd_addr);
1096
1097 size_t buffer_size =
1098 btif_config_get_bin_length(name, BTIF_STORAGE_KEY_CSIS_SET_INFO_BIN);
1099 std::vector<uint8_t> in(buffer_size);
1100 if (buffer_size != 0)
1101 btif_config_get_bin(name, BTIF_STORAGE_KEY_CSIS_SET_INFO_BIN, in.data(),
1102 &buffer_size);
1103
1104 if (buffer_size != 0)
1105 do_in_main_thread(
1106 FROM_HERE, Bind(&CsisClient::AddFromStorage, bd_addr, std::move(in)));
1107 }
1108 }
1109
1110 /** Removes information about the bonded CSIS device */
btif_storage_remove_csis_device(const RawAddress & address)1111 void btif_storage_remove_csis_device(const RawAddress& address) {
1112 std::string addrstr = address.ToString();
1113 btif_config_remove(addrstr, BTIF_STORAGE_KEY_CSIS_AUTOCONNECT);
1114 btif_config_remove(addrstr, BTIF_STORAGE_KEY_CSIS_SET_INFO_BIN);
1115 }
1116
1117 /*******************************************************************************
1118 * Function btif_storage_load_hidd
1119 *
1120 * Description Loads hidd bonded device and "plugs" it into hidd
1121 *
1122 * Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
1123 *
1124 ******************************************************************************/
btif_storage_load_hidd(void)1125 bt_status_t btif_storage_load_hidd(void) {
1126 for (const auto& bd_addr : btif_config_get_paired_devices()) {
1127 auto name = bd_addr.ToString();
1128
1129 log::verbose("Remote device:{}", bd_addr);
1130 int value;
1131 if (btif_in_fetch_bonded_device(name) == BT_STATUS_SUCCESS) {
1132 if (btif_config_get_int(name, BTIF_STORAGE_KEY_HID_DEVICE_CABLED,
1133 &value)) {
1134 BTA_HdAddDevice(bd_addr);
1135 break;
1136 }
1137 }
1138 }
1139
1140 return BT_STATUS_SUCCESS;
1141 }
1142
1143 /*******************************************************************************
1144 *
1145 * Function btif_storage_set_hidd
1146 *
1147 * Description Stores currently used HIDD device info in nvram and remove
1148 * the "HidDeviceCabled" flag from unused devices
1149 *
1150 * Returns BT_STATUS_SUCCESS
1151 *
1152 ******************************************************************************/
btif_storage_set_hidd(const RawAddress & remote_bd_addr)1153 bt_status_t btif_storage_set_hidd(const RawAddress& remote_bd_addr) {
1154 std::string remote_device_address_string = remote_bd_addr.ToString();
1155 for (const auto& bd_addr : btif_config_get_paired_devices()) {
1156 auto name = bd_addr.ToString();
1157 if (bd_addr == remote_bd_addr) continue;
1158 if (btif_in_fetch_bonded_device(name) == BT_STATUS_SUCCESS) {
1159 btif_config_remove(name, BTIF_STORAGE_KEY_HID_DEVICE_CABLED);
1160 }
1161 }
1162
1163 btif_config_set_int(remote_device_address_string,
1164 BTIF_STORAGE_KEY_HID_DEVICE_CABLED, 1);
1165 return BT_STATUS_SUCCESS;
1166 }
1167
1168 /*******************************************************************************
1169 *
1170 * Function btif_storage_remove_hidd
1171 *
1172 * Description Removes hidd bonded device info from nvram
1173 *
1174 * Returns BT_STATUS_SUCCESS
1175 *
1176 ******************************************************************************/
btif_storage_remove_hidd(RawAddress * remote_bd_addr)1177 bt_status_t btif_storage_remove_hidd(RawAddress* remote_bd_addr) {
1178 btif_config_remove(remote_bd_addr->ToString(),
1179 BTIF_STORAGE_KEY_HID_DEVICE_CABLED);
1180
1181 return BT_STATUS_SUCCESS;
1182 }
1183
1184 /*******************************************************************************
1185 *
1186 * Function btif_storage_set_hid_connection_policy
1187 *
1188 * Description Stores connection policy info in nvram
1189 *
1190 * Returns BT_STATUS_SUCCESS
1191 *
1192 ******************************************************************************/
btif_storage_set_hid_connection_policy(const tAclLinkSpec & link_spec,bool reconnect_allowed)1193 bt_status_t btif_storage_set_hid_connection_policy(
1194 const tAclLinkSpec& link_spec, bool reconnect_allowed) {
1195 std::string bdstr = link_spec.addrt.bda.ToString();
1196
1197 if (link_spec.transport == BT_TRANSPORT_LE) {
1198 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HOGP_RECONNECT_ALLOWED,
1199 reconnect_allowed);
1200 } else if (link_spec.transport == BT_TRANSPORT_BR_EDR) {
1201 btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_RECONNECT_ALLOWED,
1202 reconnect_allowed);
1203 } else {
1204 log::error("Unexpected!");
1205 }
1206
1207 return BT_STATUS_SUCCESS;
1208 }
1209
1210 /*******************************************************************************
1211 *
1212 * Function btif_storage_get_hid_connection_policy
1213 *
1214 * Description get connection policy info from nvram
1215 *
1216 * Returns BT_STATUS_SUCCESS
1217 *
1218 ******************************************************************************/
btif_storage_get_hid_connection_policy(const tAclLinkSpec & link_spec,bool * reconnect_allowed)1219 bt_status_t btif_storage_get_hid_connection_policy(
1220 const tAclLinkSpec& link_spec, bool* reconnect_allowed) {
1221 std::string bdstr = link_spec.addrt.bda.ToString();
1222
1223 int value = 0;
1224 if (link_spec.transport == BT_TRANSPORT_LE) {
1225 btif_config_get_int(bdstr, BTIF_STORAGE_KEY_HOGP_RECONNECT_ALLOWED, &value);
1226 } else if (link_spec.transport == BT_TRANSPORT_BR_EDR) {
1227 btif_config_get_int(bdstr, BTIF_STORAGE_KEY_HID_RECONNECT_ALLOWED, &value);
1228 } else {
1229 log::error("Un expected!");
1230 }
1231 *reconnect_allowed = value ? true : false;
1232
1233 return BT_STATUS_SUCCESS;
1234 }
1235
1236 /*******************************************************************************
1237 *
1238 *Function : btif_storage_set_pce_profile_version
1239 *
1240 * Description :
1241 * This function store remote PCE profile version in config file
1242 *
1243 ******************************************************************************/
btif_storage_set_pce_profile_version(const RawAddress & remote_bd_addr,uint16_t peer_pce_version)1244 void btif_storage_set_pce_profile_version(const RawAddress& remote_bd_addr,
1245 uint16_t peer_pce_version) {
1246 log::verbose("peer_pce_version : 0x{:x}", peer_pce_version);
1247
1248 if (btif_config_set_bin(
1249 remote_bd_addr.ToString(), BTIF_STORAGE_KEY_PBAP_PCE_VERSION,
1250 (const uint8_t*)&peer_pce_version, sizeof(peer_pce_version))) {
1251 } else {
1252 log::warn("Failed to store peer_pce_version for {}", remote_bd_addr);
1253 }
1254 }
1255
1256 /*******************************************************************************
1257 *
1258 * Function btif_storage_is_pce_version_102
1259 *
1260 * Description checks if remote supports PBAP 1.2
1261 *
1262 * Returns true/false depending on remote PBAP version support found in
1263 *file.
1264 *
1265 ******************************************************************************/
btif_storage_is_pce_version_102(const RawAddress & remote_bd_addr)1266 bool btif_storage_is_pce_version_102(const RawAddress& remote_bd_addr) {
1267 bool entry_found = false;
1268 // Read and restore the PBAP PCE version from local storage
1269 uint16_t pce_version = 0;
1270 size_t version_value_size = sizeof(pce_version);
1271 if (!btif_config_get_bin(remote_bd_addr.ToString(),
1272 BTIF_STORAGE_KEY_PBAP_PCE_VERSION,
1273 (uint8_t*)&pce_version, &version_value_size)) {
1274 log::verbose("Failed to read cached peer PCE version for {}",
1275 remote_bd_addr);
1276 return entry_found;
1277 }
1278
1279 if (pce_version == 0x0102) {
1280 entry_found = true;
1281 }
1282
1283 log::verbose("read cached peer PCE version 0x{:04x} for {}", pce_version,
1284 remote_bd_addr);
1285
1286 return entry_found;
1287 }
1288