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, ¶ms);
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