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