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