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