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