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