1 /******************************************************************************
2  *
3  *  Copyright 2009-2014 Broadcom Corporation
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 /*******************************************************************************
20  *
21  *  Filename:      btif_gatt_client.c
22  *
23  *  Description:   GATT client implementation
24  *
25  ******************************************************************************/
26 
27 #define LOG_TAG "bt_btif_gattc"
28 
29 #include <base/at_exit.h>
30 #include <base/functional/bind.h>
31 #include <base/threading/thread.h>
32 #include <bluetooth/log.h>
33 #include <com_android_bluetooth_flags.h>
34 #include <hardware/bluetooth.h>
35 #include <hardware/bt_gatt.h>
36 #include <hardware/bt_gatt_types.h>
37 
38 #include <cstdlib>
39 #include <string>
40 
41 #include "bta/include/bta_api.h"
42 #include "bta/include/bta_gatt_api.h"
43 #include "bta/include/bta_sec_api.h"
44 #include "btif/include/btif_common.h"
45 #include "btif/include/btif_config.h"
46 #include "btif/include/btif_dm.h"
47 #include "btif/include/btif_gatt.h"
48 #include "btif/include/btif_gatt_util.h"
49 #include "hci/controller_interface.h"
50 #include "internal_include/bte_appl.h"
51 #include "main/shim/entry.h"
52 #include "osi/include/allocator.h"
53 #include "stack/include/acl_api.h"
54 #include "stack/include/acl_api_types.h"
55 #include "stack/include/btm_ble_sec_api.h"
56 #include "stack/include/btm_client_interface.h"
57 #include "stack/include/gatt_api.h"
58 #include "stack/include/main_thread.h"
59 #include "storage/config_keys.h"
60 #include "types/ble_address_with_type.h"
61 #include "types/bluetooth/uuid.h"
62 #include "types/bt_transport.h"
63 #include "types/raw_address.h"
64 
65 using base::Bind;
66 using base::Owned;
67 using bluetooth::Uuid;
68 
69 using namespace bluetooth;
70 using std::vector;
71 
72 static bt_status_t btif_gattc_test_command_impl(int command, const btgatt_test_params_t* params);
73 extern const btgatt_callbacks_t* bt_gatt_callbacks;
74 
75 typedef struct {
76   tGATT_IF gatt_if;
77   tCONN_ID conn_id;
78 } btif_test_cb_t;
79 
80 static const char* disc_name[GATT_DISC_MAX] = {
81         "Unknown",        "GATT_DISC_SRVC_ALL",  "GATT_DISC_SRVC_BY_UUID", "GATT_DISC_INC_SRVC",
82         "GATT_DISC_CHAR", "GATT_DISC_CHAR_DSCPT"};
83 
84 static btif_test_cb_t test_cb;
85 
86 /*******************************************************************************
87  *  Constants & Macros
88  ******************************************************************************/
89 #define CLI_CBACK_WRAP_IN_JNI(P_CBACK, P_CBACK_WRAP)               \
90   do {                                                             \
91     auto callbacks = bt_gatt_callbacks;                            \
92     if (callbacks && callbacks->client->P_CBACK) {                 \
93       log::verbose("HAL bt_gatt_callbacks->client->{}", #P_CBACK); \
94       do_in_jni_thread(P_CBACK_WRAP);                              \
95     } else {                                                       \
96       ASSERTC(0, "Callback is NULL", 0);                           \
97     }                                                              \
98   } while (0)
99 
100 #define CLI_CBACK_IN_JNI(P_CBACK, ...)                                 \
101   do {                                                                 \
102     auto callbacks = bt_gatt_callbacks;                                \
103     if (callbacks && callbacks->client->P_CBACK) {                     \
104       log::verbose("HAL bt_gatt_callbacks->client->{}", #P_CBACK);     \
105       do_in_jni_thread(Bind(callbacks->client->P_CBACK, __VA_ARGS__)); \
106     } else {                                                           \
107       ASSERTC(0, "Callback is NULL", 0);                               \
108     }                                                                  \
109   } while (0)
110 
111 #define CHECK_BTGATT_INIT()                \
112   do {                                     \
113     if (bt_gatt_callbacks == NULL) {       \
114       log::warn("BTGATT not initialized"); \
115       return BT_STATUS_NOT_READY;          \
116     } else {                               \
117       log::debug("");                      \
118     }                                      \
119   } while (0)
120 
121 namespace {
122 
to_bt_transport(int val)123 tBT_TRANSPORT to_bt_transport(int val) {
124   switch (val) {
125     case 0:
126       return BT_TRANSPORT_AUTO;
127     case 1:
128       return BT_TRANSPORT_BR_EDR;
129     case 2:
130       return BT_TRANSPORT_LE;
131     default:
132       break;
133   }
134   log::warn("Passed unexpected transport value:{}", val);
135   return BT_TRANSPORT_AUTO;
136 }
137 
138 uint8_t rssi_request_client_if;
139 
btif_gattc_upstreams_evt(uint16_t event,char * p_param)140 static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) {
141   log::debug("Event {} [{}]", gatt_client_event_text(static_cast<tBTA_GATTC_EVT>(event)), event);
142 
143   auto callbacks = bt_gatt_callbacks;
144   tBTA_GATTC* p_data = (tBTA_GATTC*)p_param;
145   switch (event) {
146     case BTA_GATTC_EXEC_EVT: {
147       HAL_CBACK(callbacks, client->execute_write_cb, static_cast<int>(p_data->exec_cmpl.conn_id),
148                 p_data->exec_cmpl.status);
149       break;
150     }
151 
152     case BTA_GATTC_SEARCH_CMPL_EVT: {
153       HAL_CBACK(callbacks, client->search_complete_cb,
154                 static_cast<int>(p_data->search_cmpl.conn_id), p_data->search_cmpl.status);
155       break;
156     }
157 
158     case BTA_GATTC_NOTIF_EVT: {
159       btgatt_notify_params_t data;
160 
161       data.bda = p_data->notify.bda;
162       memcpy(data.value, p_data->notify.value, p_data->notify.len);
163 
164       data.handle = p_data->notify.handle;
165       data.is_notify = p_data->notify.is_notify;
166       data.len = p_data->notify.len;
167 
168       HAL_CBACK(callbacks, client->notify_cb, static_cast<int>(p_data->notify.conn_id), data);
169 
170       if (!p_data->notify.is_notify) {
171         BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, p_data->notify.cid);
172       }
173 
174       break;
175     }
176 
177     case BTA_GATTC_OPEN_EVT: {
178       log::debug("BTA_GATTC_OPEN_EVT {}", p_data->open.remote_bda);
179       HAL_CBACK(callbacks, client->open_cb, static_cast<int>(p_data->open.conn_id),
180                 p_data->open.status, p_data->open.client_if, p_data->open.remote_bda);
181 
182       if (GATT_DEF_BLE_MTU_SIZE != p_data->open.mtu && p_data->open.mtu) {
183         HAL_CBACK(callbacks, client->configure_mtu_cb, static_cast<int>(p_data->open.conn_id),
184                   p_data->open.status, p_data->open.mtu);
185       }
186 
187       if (p_data->open.status == GATT_SUCCESS) {
188         btif_gatt_check_encrypted_link(p_data->open.remote_bda, p_data->open.transport);
189       }
190       break;
191     }
192 
193     case BTA_GATTC_CLOSE_EVT: {
194       log::debug("BTA_GATTC_CLOSE_EVT {}", p_data->close.remote_bda);
195       HAL_CBACK(callbacks, client->close_cb, static_cast<int>(p_data->close.conn_id),
196                 p_data->close.status, p_data->close.client_if, p_data->close.remote_bda);
197       break;
198     }
199 
200     case BTA_GATTC_DEREG_EVT:
201     case BTA_GATTC_SEARCH_RES_EVT:
202     case BTA_GATTC_CANCEL_OPEN_EVT:
203     case BTA_GATTC_SRVC_DISC_DONE_EVT:
204       log::debug("Ignoring event ({})", event);
205       break;
206 
207     case BTA_GATTC_CFG_MTU_EVT: {
208       HAL_CBACK(callbacks, client->configure_mtu_cb, static_cast<int>(p_data->cfg_mtu.conn_id),
209                 p_data->cfg_mtu.status, p_data->cfg_mtu.mtu);
210       break;
211     }
212 
213     case BTA_GATTC_CONGEST_EVT:
214       HAL_CBACK(callbacks, client->congestion_cb, static_cast<int>(p_data->congest.conn_id),
215                 p_data->congest.congested);
216       break;
217 
218     case BTA_GATTC_PHY_UPDATE_EVT:
219       HAL_CBACK(callbacks, client->phy_updated_cb, static_cast<int>(p_data->phy_update.conn_id),
220                 p_data->phy_update.tx_phy, p_data->phy_update.rx_phy, p_data->phy_update.status);
221       break;
222 
223     case BTA_GATTC_CONN_UPDATE_EVT:
224       HAL_CBACK(callbacks, client->conn_updated_cb, static_cast<int>(p_data->conn_update.conn_id),
225                 p_data->conn_update.interval, p_data->conn_update.latency,
226                 p_data->conn_update.timeout, p_data->conn_update.status);
227       break;
228 
229     case BTA_GATTC_SRVC_CHG_EVT:
230       HAL_CBACK(callbacks, client->service_changed_cb,
231                 static_cast<int>(p_data->service_changed.conn_id));
232       break;
233 
234     case BTA_GATTC_SUBRATE_CHG_EVT:
235       HAL_CBACK(callbacks, client->subrate_chg_cb, static_cast<int>(p_data->subrate_chg.conn_id),
236                 p_data->subrate_chg.subrate_factor, p_data->subrate_chg.latency,
237                 p_data->subrate_chg.cont_num, p_data->subrate_chg.timeout,
238                 p_data->subrate_chg.status);
239       break;
240 
241     default:
242       log::error("Unhandled event ({})!", event);
243       break;
244   }
245 }
246 
bta_gattc_cback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)247 static void bta_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
248   log::debug("gatt client callback event:{} [{}]", gatt_client_event_text(event), event);
249   bt_status_t status = btif_transfer_context(btif_gattc_upstreams_evt, (uint16_t)event,
250                                              (char*)p_data, sizeof(tBTA_GATTC), NULL);
251   ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
252 }
253 
btm_read_rssi_cb(void * p_void)254 void btm_read_rssi_cb(void* p_void) {
255   tBTM_RSSI_RESULT* p_result = (tBTM_RSSI_RESULT*)p_void;
256 
257   if (!p_result) {
258     return;
259   }
260 
261   CLI_CBACK_IN_JNI(read_remote_rssi_cb, rssi_request_client_if, p_result->rem_bda, p_result->rssi,
262                    static_cast<uint8_t>(p_result->status));
263 }
264 
265 /*******************************************************************************
266  *  Client API Functions
267  ******************************************************************************/
268 
btif_gattc_register_app(const Uuid & uuid,bool eatt_support)269 static bt_status_t btif_gattc_register_app(const Uuid& uuid, bool eatt_support) {
270   CHECK_BTGATT_INIT();
271 
272   return do_in_jni_thread(Bind(
273           [](const Uuid& uuid, bool eatt_support) {
274             BTA_GATTC_AppRegister(
275                     bta_gattc_cback,
276                     base::Bind(
277                             [](const Uuid& uuid, uint8_t client_id, uint8_t status) {
278                               do_in_jni_thread(Bind(
279                                       [](const Uuid& uuid, uint8_t client_id, uint8_t status) {
280                                         auto callbacks = bt_gatt_callbacks;
281                                         HAL_CBACK(callbacks, client->register_client_cb, status,
282                                                   client_id, uuid);
283                                       },
284                                       uuid, client_id, status));
285                             },
286                             uuid),
287                     eatt_support);
288           },
289           uuid, eatt_support));
290 }
291 
btif_gattc_unregister_app_impl(int client_if)292 static void btif_gattc_unregister_app_impl(int client_if) { BTA_GATTC_AppDeregister(client_if); }
293 
btif_gattc_unregister_app(int client_if)294 static bt_status_t btif_gattc_unregister_app(int client_if) {
295   CHECK_BTGATT_INIT();
296   return do_in_jni_thread(Bind(&btif_gattc_unregister_app_impl, client_if));
297 }
298 
btif_gattc_open_impl(int client_if,RawAddress address,tBLE_ADDR_TYPE addr_type,bool is_direct,tBT_TRANSPORT transport,bool opportunistic,int initiating_phys,int preferred_mtu)299 void btif_gattc_open_impl(int client_if, RawAddress address, tBLE_ADDR_TYPE addr_type,
300                           bool is_direct, tBT_TRANSPORT transport, bool opportunistic,
301                           int initiating_phys, int preferred_mtu) {
302   int device_type = BT_DEVICE_TYPE_UNKNOWN;
303 
304   if (addr_type == BLE_ADDR_RANDOM) {
305     device_type = BT_DEVICE_TYPE_BLE;
306     BTA_DmAddBleDevice(address, addr_type, device_type);
307   } else {
308     // Ensure device is in inquiry database
309     addr_type = BLE_ADDR_PUBLIC;
310     if (btif_get_address_type(address, &addr_type) && btif_get_device_type(address, &device_type) &&
311         device_type != BT_DEVICE_TYPE_BREDR) {
312       BTA_DmAddBleDevice(address, addr_type, device_type);
313     }
314   }
315 
316   // Check for background connections
317   if (!is_direct) {
318     // Check for privacy 1.0 and 1.1 controller and do not start background
319     // connection if RPA offloading is not supported, since it will not
320     // connect after change of random address
321     if (!bluetooth::shim::GetController()->SupportsBlePrivacy() && (addr_type == BLE_ADDR_RANDOM) &&
322         BTM_BLE_IS_RESOLVE_BDA(address)) {
323       tBTM_BLE_VSC_CB vnd_capabilities;
324       BTM_BleGetVendorCapabilities(&vnd_capabilities);
325       if (!vnd_capabilities.rpa_offloading) {
326         auto callbacks = bt_gatt_callbacks;
327         HAL_CBACK(callbacks, client->open_cb, 0, BT_STATUS_UNSUPPORTED, client_if, address);
328         return;
329       }
330     }
331   }
332 
333   // Determine transport
334   if (transport == BT_TRANSPORT_AUTO) {
335     if (com::android::bluetooth::flags::default_gatt_transport()) {
336       // Prefer LE transport when LE is supported
337       transport = (device_type == BT_DEVICE_TYPE_BREDR) ? BT_TRANSPORT_BR_EDR : BT_TRANSPORT_LE;
338     } else {
339       switch (device_type) {
340         case BT_DEVICE_TYPE_BREDR:
341           transport = BT_TRANSPORT_BR_EDR;
342           break;
343 
344         case BT_DEVICE_TYPE_BLE:
345           transport = BT_TRANSPORT_LE;
346           break;
347 
348         case BT_DEVICE_TYPE_DUMO:
349           transport = (addr_type == BLE_ADDR_RANDOM) ? BT_TRANSPORT_LE : BT_TRANSPORT_BR_EDR;
350           break;
351 
352         default:
353           log::error("Unknown device type {}", DeviceTypeText(device_type));
354           // transport must not be AUTO for finding control blocks. Use LE for backward
355           // compatibility.
356           transport = BT_TRANSPORT_LE;
357           break;
358       }
359     }
360   }
361 
362   // Connect!
363   log::info("Transport={}, device type={}, address={}, address type={}, phy={}",
364             bt_transport_text(transport), DeviceTypeText(device_type),
365             address, addr_type, initiating_phys);
366   tBTM_BLE_CONN_TYPE type = is_direct ? BTM_BLE_DIRECT_CONNECTION : BTM_BLE_BKG_CONNECT_ALLOW_LIST;
367   BTA_GATTC_Open(client_if, address, addr_type, type, transport, opportunistic, initiating_phys,
368                  preferred_mtu);
369 }
370 
btif_gattc_open(int client_if,const RawAddress & bd_addr,uint8_t addr_type,bool is_direct,int transport,bool opportunistic,int initiating_phys,int preferred_mtu)371 static bt_status_t btif_gattc_open(int client_if, const RawAddress& bd_addr, uint8_t addr_type,
372                                    bool is_direct, int transport, bool opportunistic,
373                                    int initiating_phys, int preferred_mtu) {
374   CHECK_BTGATT_INIT();
375   // Closure will own this value and free it.
376   return do_in_jni_thread(Bind(&btif_gattc_open_impl, client_if, bd_addr, addr_type, is_direct,
377                                to_bt_transport(transport), opportunistic, initiating_phys,
378                                preferred_mtu));
379 }
380 
btif_gattc_close_impl(int client_if,RawAddress address,int conn_id)381 void btif_gattc_close_impl(int client_if, RawAddress address, int conn_id) {
382   log::info("client_if={}, conn_id={}, address={}", client_if, conn_id, address);
383   // Disconnect established connections
384   if (conn_id != 0) {
385     BTA_GATTC_Close(static_cast<tCONN_ID>(conn_id));
386   } else {
387     BTA_GATTC_CancelOpen(client_if, address, true);
388   }
389 
390   // Cancel pending background connections (remove from acceptlist)
391   BTA_GATTC_CancelOpen(client_if, address, false);
392 }
393 
btif_gattc_close(int client_if,const RawAddress & bd_addr,int conn_id)394 static bt_status_t btif_gattc_close(int client_if, const RawAddress& bd_addr, int conn_id) {
395   CHECK_BTGATT_INIT();
396   return do_in_jni_thread(Bind(&btif_gattc_close_impl, client_if, bd_addr, conn_id));
397 }
398 
btif_gattc_refresh(int,const RawAddress & bd_addr)399 static bt_status_t btif_gattc_refresh(int /* client_if */, const RawAddress& bd_addr) {
400   CHECK_BTGATT_INIT();
401   return do_in_jni_thread(Bind(&BTA_GATTC_Refresh, bd_addr));
402 }
403 
btif_gattc_search_service(int conn_id,const Uuid * filter_uuid)404 static bt_status_t btif_gattc_search_service(int conn_id, const Uuid* filter_uuid) {
405   CHECK_BTGATT_INIT();
406 
407   if (filter_uuid) {
408     return do_in_jni_thread(
409             Bind(&BTA_GATTC_ServiceSearchRequest, static_cast<tCONN_ID>(conn_id), *filter_uuid));
410   } else {
411     return do_in_jni_thread(
412             Bind(&BTA_GATTC_ServiceSearchAllRequest, static_cast<tCONN_ID>(conn_id)));
413   }
414 }
415 
btif_gattc_discover_service_by_uuid(int conn_id,const Uuid & uuid)416 static void btif_gattc_discover_service_by_uuid(int conn_id, const Uuid& uuid) {
417   do_in_jni_thread(Bind(&BTA_GATTC_DiscoverServiceByUuid, static_cast<tCONN_ID>(conn_id), uuid));
418 }
419 
btif_gattc_get_gatt_db_impl(int conn_id)420 void btif_gattc_get_gatt_db_impl(int conn_id) {
421   btgatt_db_element_t* db = NULL;
422   int count = 0;
423   BTA_GATTC_GetGattDb(static_cast<tCONN_ID>(conn_id), 0x0000, 0xFFFF, &db, &count);
424 
425   auto callbacks = bt_gatt_callbacks;
426   HAL_CBACK(callbacks, client->get_gatt_db_cb, conn_id, db, count);
427   osi_free(db);
428 }
429 
btif_gattc_get_gatt_db(int conn_id)430 static bt_status_t btif_gattc_get_gatt_db(int conn_id) {
431   CHECK_BTGATT_INIT();
432   return do_in_jni_thread(Bind(&btif_gattc_get_gatt_db_impl, conn_id));
433 }
434 
read_char_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void *)435 void read_char_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
436                   uint8_t* value, void* /* data */) {
437   btgatt_read_params_t params = {
438           .handle = handle,
439           .value.len = len,
440           .value_type = 0x00, /* GATTC_READ_VALUE_TYPE_VALUE */
441           .status = status,
442   };
443   log::assert_that(len <= GATT_MAX_ATTR_LEN, "assert failed: len <= GATT_MAX_ATTR_LEN");
444   if (len > 0) {
445     memcpy(params.value.value, value, len);
446   }
447 
448   CLI_CBACK_IN_JNI(read_characteristic_cb, conn_id, status, params);
449 }
450 
btif_gattc_read_char(int conn_id,uint16_t handle,int auth_req)451 static bt_status_t btif_gattc_read_char(int conn_id, uint16_t handle, int auth_req) {
452   CHECK_BTGATT_INIT();
453   return do_in_jni_thread(Bind(&BTA_GATTC_ReadCharacteristic, static_cast<tCONN_ID>(conn_id),
454                                handle, auth_req, read_char_cb, nullptr));
455 }
456 
read_using_char_uuid_cb(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void *)457 void read_using_char_uuid_cb(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
458                              uint8_t* value, void* /* data */) {
459   btgatt_read_params_t params = {
460           .handle = handle,
461           .value.len = len,
462           .value_type = 0x00, /* GATTC_READ_VALUE_TYPE_VALUE */
463           .status = status,
464   };
465   log::assert_that(len <= GATT_MAX_ATTR_LEN, "assert failed: len <= GATT_MAX_ATTR_LEN");
466   if (len > 0) {
467     memcpy(params.value.value, value, len);
468   }
469 
470   CLI_CBACK_IN_JNI(read_characteristic_cb, static_cast<int>(conn_id), status, params);
471 }
472 
btif_gattc_read_using_char_uuid(int conn_id,const Uuid & uuid,uint16_t s_handle,uint16_t e_handle,int auth_req)473 static bt_status_t btif_gattc_read_using_char_uuid(int conn_id, const Uuid& uuid, uint16_t s_handle,
474                                                    uint16_t e_handle, int auth_req) {
475   CHECK_BTGATT_INIT();
476   return do_in_jni_thread(Bind(&BTA_GATTC_ReadUsingCharUuid, static_cast<tCONN_ID>(conn_id), uuid,
477                                s_handle, e_handle, auth_req, read_using_char_uuid_cb, nullptr));
478 }
479 
read_desc_cb(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void *)480 void read_desc_cb(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
481                   uint8_t* value, void* /* data */) {
482   btgatt_read_params_t params;
483   params.value_type = 0x00 /* GATTC_READ_VALUE_TYPE_VALUE */;
484   params.status = status;
485   params.handle = handle;
486   params.value.len = len;
487   log::assert_that(len <= GATT_MAX_ATTR_LEN, "assert failed: len <= GATT_MAX_ATTR_LEN");
488   if (len > 0) {
489     memcpy(params.value.value, value, len);
490   }
491   CLI_CBACK_IN_JNI(read_descriptor_cb, static_cast<int>(conn_id), status, params);
492 }
493 
btif_gattc_read_char_descr(int conn_id,uint16_t handle,int auth_req)494 static bt_status_t btif_gattc_read_char_descr(int conn_id, uint16_t handle, int auth_req) {
495   CHECK_BTGATT_INIT();
496   return do_in_jni_thread(Bind(&BTA_GATTC_ReadCharDescr, static_cast<tCONN_ID>(conn_id), handle,
497                                auth_req, read_desc_cb, nullptr));
498 }
499 
write_char_cb(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,void *)500 void write_char_cb(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
501                    const uint8_t* value, void* /* data */) {
502   std::vector<uint8_t> val(value, value + len);
503   CLI_CBACK_WRAP_IN_JNI(
504           write_characteristic_cb,
505           base::BindOnce(
506                   [](write_characteristic_callback cb, tCONN_ID conn_id, tGATT_STATUS status,
507                      uint16_t handle, std::vector<uint8_t> moved_value) {
508                     cb(static_cast<int>(conn_id), status, handle, moved_value.size(),
509                        moved_value.data());
510                   },
511                   bt_gatt_callbacks->client->write_characteristic_cb, conn_id, status, handle,
512                   std::move(val)));
513 }
514 
btif_gattc_write_char(int conn_id,uint16_t handle,int write_type,int auth_req,const uint8_t * val,size_t len)515 static bt_status_t btif_gattc_write_char(int conn_id, uint16_t handle, int write_type, int auth_req,
516                                          const uint8_t* val, size_t len) {
517   CHECK_BTGATT_INIT();
518 
519   std::vector<uint8_t> value(val, val + len);
520 
521   if (value.size() > GATT_MAX_ATTR_LEN) {
522     value.resize(GATT_MAX_ATTR_LEN);
523   }
524 
525   return do_in_jni_thread(Bind(&BTA_GATTC_WriteCharValue, static_cast<tCONN_ID>(conn_id), handle,
526                                write_type, std::move(value), auth_req, write_char_cb, nullptr));
527 }
528 
write_descr_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,void *)529 void write_descr_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
530                     const uint8_t* value, void* /* data */) {
531   std::vector<uint8_t> val(value, value + len);
532 
533   CLI_CBACK_WRAP_IN_JNI(
534           write_descriptor_cb,
535           base::BindOnce(
536                   [](write_descriptor_callback cb, uint16_t conn_id, tGATT_STATUS status,
537                      uint16_t handle, std::vector<uint8_t> moved_value) {
538                     cb(conn_id, status, handle, moved_value.size(), moved_value.data());
539                   },
540                   bt_gatt_callbacks->client->write_descriptor_cb, conn_id, status, handle,
541                   std::move(val)));
542 }
543 
btif_gattc_write_char_descr(int conn_id,uint16_t handle,int auth_req,const uint8_t * val,size_t len)544 static bt_status_t btif_gattc_write_char_descr(int conn_id, uint16_t handle, int auth_req,
545                                                const uint8_t* val, size_t len) {
546   CHECK_BTGATT_INIT();
547 
548   std::vector<uint8_t> value(val, val + len);
549 
550   if (value.size() > GATT_MAX_ATTR_LEN) {
551     value.resize(GATT_MAX_ATTR_LEN);
552   }
553 
554   return do_in_jni_thread(Bind(&BTA_GATTC_WriteCharDescr, static_cast<tCONN_ID>(conn_id), handle,
555                                std::move(value), auth_req, write_descr_cb, nullptr));
556 }
557 
btif_gattc_execute_write(int conn_id,int execute)558 static bt_status_t btif_gattc_execute_write(int conn_id, int execute) {
559   CHECK_BTGATT_INIT();
560   return do_in_jni_thread(
561           Bind(&BTA_GATTC_ExecuteWrite, static_cast<tCONN_ID>(conn_id), (uint8_t)execute));
562 }
563 
btif_gattc_reg_for_notification_impl(tGATT_IF client_if,const RawAddress & bda,uint16_t handle)564 static void btif_gattc_reg_for_notification_impl(tGATT_IF client_if, const RawAddress& bda,
565                                                  uint16_t handle) {
566   tGATT_STATUS status = BTA_GATTC_RegisterForNotifications(client_if, bda, handle);
567 
568   // TODO(jpawlowski): conn_id is currently unused
569   auto callbacks = bt_gatt_callbacks;
570   HAL_CBACK(callbacks, client->register_for_notification_cb,
571             /* conn_id */ 0, 1, status, handle);
572 }
573 
btif_gattc_reg_for_notification(int client_if,const RawAddress & bd_addr,uint16_t handle)574 bt_status_t btif_gattc_reg_for_notification(int client_if, const RawAddress& bd_addr,
575                                             uint16_t handle) {
576   CHECK_BTGATT_INIT();
577 
578   return do_in_jni_thread(Bind(base::IgnoreResult(&btif_gattc_reg_for_notification_impl), client_if,
579                                bd_addr, handle));
580 }
581 
btif_gattc_dereg_for_notification_impl(tGATT_IF client_if,const RawAddress & bda,uint16_t handle)582 static void btif_gattc_dereg_for_notification_impl(tGATT_IF client_if, const RawAddress& bda,
583                                                    uint16_t handle) {
584   tGATT_STATUS status = BTA_GATTC_DeregisterForNotifications(client_if, bda, handle);
585 
586   // TODO(jpawlowski): conn_id is currently unused
587   auto callbacks = bt_gatt_callbacks;
588   HAL_CBACK(callbacks, client->register_for_notification_cb,
589             /* conn_id */ 0, 0, status, handle);
590 }
591 
btif_gattc_dereg_for_notification(int client_if,const RawAddress & bd_addr,uint16_t handle)592 bt_status_t btif_gattc_dereg_for_notification(int client_if, const RawAddress& bd_addr,
593                                               uint16_t handle) {
594   CHECK_BTGATT_INIT();
595 
596   return do_in_jni_thread(Bind(base::IgnoreResult(&btif_gattc_dereg_for_notification_impl),
597                                client_if, bd_addr, handle));
598 }
599 
btif_gattc_read_remote_rssi(int client_if,const RawAddress & bd_addr)600 static bt_status_t btif_gattc_read_remote_rssi(int client_if, const RawAddress& bd_addr) {
601   CHECK_BTGATT_INIT();
602   rssi_request_client_if = client_if;
603 
604   return do_in_jni_thread(base::Bind(
605           [](int client_if, const RawAddress& bd_addr) {
606             if (get_btm_client_interface().link_controller.BTM_ReadRSSI(
607                         bd_addr, btm_read_rssi_cb) != tBTM_STATUS::BTM_CMD_STARTED) {
608               log::warn("Unable to read RSSI peer:{} client_if:{}", bd_addr, client_if);
609             }
610           },
611           client_if, bd_addr));
612 }
613 
btif_gattc_configure_mtu(int conn_id,int mtu)614 static bt_status_t btif_gattc_configure_mtu(int conn_id, int mtu) {
615   CHECK_BTGATT_INIT();
616   return do_in_jni_thread(Bind(
617           base::IgnoreResult(static_cast<void (*)(tCONN_ID, uint16_t)>(&BTA_GATTC_ConfigureMTU)),
618           static_cast<tCONN_ID>(conn_id), mtu));
619 }
620 
btif_gattc_conn_parameter_update_impl(RawAddress addr,int min_interval,int max_interval,int latency,int timeout,uint16_t min_ce_len,uint16_t max_ce_len)621 static void btif_gattc_conn_parameter_update_impl(RawAddress addr, int min_interval,
622                                                   int max_interval, int latency, int timeout,
623                                                   uint16_t min_ce_len, uint16_t max_ce_len) {
624   if (BTA_DmGetConnectionState(addr)) {
625     BTA_DmBleUpdateConnectionParams(addr, min_interval, max_interval, latency, timeout, min_ce_len,
626                                     max_ce_len);
627   } else {
628     BTA_DmSetBlePrefConnParams(addr, min_interval, max_interval, latency, timeout);
629   }
630 }
631 
btif_gattc_conn_parameter_update(const RawAddress & bd_addr,int min_interval,int max_interval,int latency,int timeout,uint16_t min_ce_len,uint16_t max_ce_len)632 bt_status_t btif_gattc_conn_parameter_update(const RawAddress& bd_addr, int min_interval,
633                                              int max_interval, int latency, int timeout,
634                                              uint16_t min_ce_len, uint16_t max_ce_len) {
635   CHECK_BTGATT_INIT();
636   return do_in_jni_thread(Bind(base::IgnoreResult(&btif_gattc_conn_parameter_update_impl), bd_addr,
637                                min_interval, max_interval, latency, timeout, min_ce_len,
638                                max_ce_len));
639 }
640 
btif_gattc_set_preferred_phy(const RawAddress & bd_addr,uint8_t tx_phy,uint8_t rx_phy,uint16_t phy_options)641 static bt_status_t btif_gattc_set_preferred_phy(const RawAddress& bd_addr, uint8_t tx_phy,
642                                                 uint8_t rx_phy, uint16_t phy_options) {
643   CHECK_BTGATT_INIT();
644   do_in_main_thread(Bind(
645           [](const RawAddress& bd_addr, uint8_t tx_phy, uint8_t rx_phy, uint16_t phy_options) {
646             get_btm_client_interface().ble.BTM_BleSetPhy(bd_addr, tx_phy, rx_phy, phy_options);
647           },
648           bd_addr, tx_phy, rx_phy, phy_options));
649   return BT_STATUS_SUCCESS;
650 }
651 
btif_gattc_read_phy(const RawAddress & bd_addr,base::Callback<void (uint8_t tx_phy,uint8_t rx_phy,uint8_t status)> cb)652 static bt_status_t btif_gattc_read_phy(
653         const RawAddress& bd_addr,
654         base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
655   CHECK_BTGATT_INIT();
656   do_in_main_thread(Bind(&BTM_BleReadPhy, bd_addr, jni_thread_wrapper(cb)));
657   return BT_STATUS_SUCCESS;
658 }
659 
btif_gattc_get_device_type(const RawAddress & bd_addr)660 static int btif_gattc_get_device_type(const RawAddress& bd_addr) {
661   int device_type = 0;
662 
663   if (btif_config_get_int(bd_addr.ToString().c_str(), BTIF_STORAGE_KEY_DEV_TYPE, &device_type)) {
664     return device_type;
665   }
666   return 0;
667 }
668 
btif_gattc_test_command(int command,const btgatt_test_params_t & params)669 static bt_status_t btif_gattc_test_command(int command, const btgatt_test_params_t& params) {
670   return btif_gattc_test_command_impl(command, &params);
671 }
672 
btif_gattc_subrate_request_impl(RawAddress addr,int subrate_min,int subrate_max,int max_latency,int cont_num,int sup_timeout)673 static void btif_gattc_subrate_request_impl(RawAddress addr, int subrate_min, int subrate_max,
674                                             int max_latency, int cont_num, int sup_timeout) {
675   if (BTA_DmGetConnectionState(addr)) {
676     BTA_DmBleSubrateRequest(addr, subrate_min, subrate_max, max_latency, cont_num, sup_timeout);
677   }
678 }
679 
btif_gattc_subrate_request(const RawAddress & bd_addr,int subrate_min,int subrate_max,int max_latency,int cont_num,int sup_timeout)680 static bt_status_t btif_gattc_subrate_request(const RawAddress& bd_addr, int subrate_min,
681                                               int subrate_max, int max_latency, int cont_num,
682                                               int sup_timeout) {
683   CHECK_BTGATT_INIT();
684   return do_in_jni_thread(Bind(base::IgnoreResult(&btif_gattc_subrate_request_impl), bd_addr,
685                                subrate_min, subrate_max, max_latency, cont_num, sup_timeout));
686 }
687 
btif_test_connect_cback(tGATT_IF,const RawAddress &,tCONN_ID conn_id,bool connected,tGATT_DISCONN_REASON,tBT_TRANSPORT)688 static void btif_test_connect_cback(tGATT_IF, const RawAddress&, tCONN_ID conn_id, bool connected,
689                                     tGATT_DISCONN_REASON, tBT_TRANSPORT) {
690   log::info("conn_id={}, connected={}", conn_id, connected);
691   test_cb.conn_id = connected ? conn_id : 0;
692 }
693 
btif_test_command_complete_cback(tCONN_ID conn_id,tGATTC_OPTYPE op,tGATT_STATUS status,tGATT_CL_COMPLETE * p_data)694 static void btif_test_command_complete_cback(tCONN_ID conn_id, tGATTC_OPTYPE op,
695                                              tGATT_STATUS status, tGATT_CL_COMPLETE* p_data) {
696   log::info("op_code=0x{:02x}, conn_id=0x{:x}. status=0x{:x}", op, conn_id, status);
697 
698   switch (op) {
699     case GATTC_OPTYPE_READ:
700     case GATTC_OPTYPE_WRITE:
701     case GATTC_OPTYPE_CONFIG:
702     case GATTC_OPTYPE_EXE_WRITE:
703     case GATTC_OPTYPE_NOTIFICATION:
704       break;
705 
706     case GATTC_OPTYPE_INDICATION:
707       if (GATTC_SendHandleValueConfirm(conn_id, p_data->cid) != GATT_SUCCESS) {
708         log::error(
709                 "Unable to send handle value confirmation conn_id:0x{:x} "
710                 "cid:0x{:04x}",
711                 conn_id, p_data->cid);
712       }
713       break;
714 
715     default:
716       log::info("Unknown op_code (0x{:02x})", op);
717       break;
718   }
719 }
720 
btif_test_discovery_result_cback(tCONN_ID,tGATT_DISC_TYPE disc_type,tGATT_DISC_RES * p_data)721 static void btif_test_discovery_result_cback(tCONN_ID /* conn_id */, tGATT_DISC_TYPE disc_type,
722                                              tGATT_DISC_RES* p_data) {
723   log::info("------ GATT Discovery result {:<22s} -------", disc_name[disc_type]);
724   log::info("Attribute handle: 0x{:04x} ({})", p_data->handle, p_data->handle);
725 
726   if (disc_type != GATT_DISC_CHAR_DSCPT) {
727     log::info("Attribute type: {}", p_data->type.ToString());
728   }
729 
730   switch (disc_type) {
731     case GATT_DISC_SRVC_ALL:
732       log::info("Handle range: 0x{:04x} ~ 0x{:04x} ({} ~ {})", p_data->handle,
733                 p_data->value.group_value.e_handle, p_data->handle,
734                 p_data->value.group_value.e_handle);
735       log::info("Service UUID: {}", p_data->value.group_value.service_type.ToString());
736       break;
737 
738     case GATT_DISC_SRVC_BY_UUID:
739       log::info("Handle range: 0x{:04x} ~ 0x{:04x} ({} ~ {})", p_data->handle, p_data->value.handle,
740                 p_data->handle, p_data->value.handle);
741       break;
742 
743     case GATT_DISC_INC_SRVC:
744       log::info("Handle range: 0x{:04x} ~ 0x{:04x} ({} ~ {})", p_data->value.incl_service.s_handle,
745                 p_data->value.incl_service.e_handle, p_data->value.incl_service.s_handle,
746                 p_data->value.incl_service.e_handle);
747       log::info("Service UUID: {}", p_data->value.incl_service.service_type.ToString());
748       break;
749 
750     case GATT_DISC_CHAR:
751       log::info("Properties: 0x{:02x}", p_data->value.dclr_value.char_prop);
752       log::info("Characteristic UUID: {}", p_data->value.dclr_value.char_uuid.ToString());
753       break;
754 
755     case GATT_DISC_CHAR_DSCPT:
756       log::info("Descriptor UUID: {}", p_data->type.ToString());
757       break;
758     case GATT_DISC_MAX:
759       log::error("Unknown discovery item");
760       break;
761   }
762 
763   log::info("-----------------------------------------------------------");
764 }
765 
btif_test_discovery_complete_cback(tCONN_ID,tGATT_DISC_TYPE,tGATT_STATUS status)766 static void btif_test_discovery_complete_cback(tCONN_ID /* conn_id */,
767                                                tGATT_DISC_TYPE /* disc_type */,
768                                                tGATT_STATUS status) {
769   log::info("status={}", status);
770 }
771 
772 static tGATT_CBACK btif_test_callbacks = {
773         btif_test_connect_cback,
774         btif_test_command_complete_cback,
775         btif_test_discovery_result_cback,
776         btif_test_discovery_complete_cback,
777         NULL,
778         NULL,
779         NULL,
780         NULL,
781         NULL,
782         NULL,
783 };
784 
785 }  // namespace
786 
btif_gattc_test_command_impl(int command,const btgatt_test_params_t * params)787 static bt_status_t btif_gattc_test_command_impl(int command, const btgatt_test_params_t* params) {
788   switch (command) {
789     case 0x01: /* Enable */
790     {
791       log::info("ENABLE - enable={}", params->u1);
792       if (params->u1) {
793         std::array<uint8_t, Uuid::kNumBytes128> tmp;
794         tmp.fill(0xAE);
795         test_cb.gatt_if = GATT_Register(bluetooth::Uuid::From128BitBE(tmp), std::string("GattTest"),
796                                         &btif_test_callbacks, false);
797         GATT_StartIf(test_cb.gatt_if);
798       } else {
799         GATT_Deregister(test_cb.gatt_if);
800         test_cb.gatt_if = 0;
801       }
802       break;
803     }
804 
805     case 0x02: /* Connect */
806     {
807       log::info("CONNECT - device={} (dev_type={}, addr_type={})", *params->bda1, params->u1,
808                 params->u2);
809 
810       if (params->u1 == BT_DEVICE_TYPE_BLE) {
811         BTM_SecAddBleDevice(*params->bda1, BT_DEVICE_TYPE_BLE,
812                             static_cast<tBLE_ADDR_TYPE>(params->u2));
813       }
814 
815       if (!GATT_Connect(test_cb.gatt_if, *params->bda1, BTM_BLE_DIRECT_CONNECTION, BT_TRANSPORT_LE,
816                         false)) {
817         log::error("GATT_Connect failed!");
818       }
819       break;
820     }
821 
822     case 0x03: /* Disconnect */
823     {
824       log::info("DISCONNECT - conn_id={}", test_cb.conn_id);
825       if (GATT_Disconnect(test_cb.conn_id) != GATT_SUCCESS) {
826         log::error("Unable to disconnect");
827       }
828       break;
829     }
830 
831     case 0x04: /* Discover */
832     {
833       if (params->u1 >= GATT_DISC_MAX) {
834         log::error("DISCOVER - Invalid type ({})!", params->u1);
835         return (bt_status_t)0;
836       }
837 
838       log::info("DISCOVER ({}), conn_id={}, uuid={}, handles=0x{:04x}-0x{:04x}",
839                 disc_name[params->u1], test_cb.conn_id, params->uuid1->ToString(), params->u2,
840                 params->u3);
841       if (GATTC_Discover(test_cb.conn_id, static_cast<tGATT_DISC_TYPE>(params->u1), params->u2,
842                          params->u3, *params->uuid1) != GATT_SUCCESS) {
843         log::error("Unable to discover");
844       }
845       break;
846     }
847 
848     case 0xF0: /* Pairing configuration */
849       log::info("Setting pairing config auth={}, iocaps={}, keys={}/{}/{}", params->u1, params->u2,
850                 params->u3, params->u4, params->u5);
851 
852       bte_appl_cfg.ble_auth_req = params->u1;
853       bte_appl_cfg.ble_io_cap = params->u2;
854       bte_appl_cfg.ble_init_key = params->u3;
855       bte_appl_cfg.ble_resp_key = params->u4;
856       bte_appl_cfg.ble_max_key_size = params->u5;
857       break;
858 
859     default:
860       log::error("UNKNOWN TEST COMMAND 0x{:02x}", command);
861       break;
862   }
863   return (bt_status_t)0;
864 }
865 
866 const btgatt_client_interface_t btgattClientInterface = {
867         btif_gattc_register_app,
868         btif_gattc_unregister_app,
869         btif_gattc_open,
870         btif_gattc_close,
871         btif_gattc_refresh,
872         btif_gattc_search_service,
873         btif_gattc_discover_service_by_uuid,
874         btif_gattc_read_char,
875         btif_gattc_read_using_char_uuid,
876         btif_gattc_write_char,
877         btif_gattc_read_char_descr,
878         btif_gattc_write_char_descr,
879         btif_gattc_execute_write,
880         btif_gattc_reg_for_notification,
881         btif_gattc_dereg_for_notification,
882         btif_gattc_read_remote_rssi,
883         btif_gattc_get_device_type,
884         btif_gattc_configure_mtu,
885         btif_gattc_conn_parameter_update,
886         btif_gattc_set_preferred_phy,
887         btif_gattc_read_phy,
888         btif_gattc_test_command,
889         btif_gattc_get_gatt_db,
890         btif_gattc_subrate_request,
891 };
892