1 /******************************************************************************
2 *
3 * Copyright (C) 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/bind.h>
31 #include <base/threading/thread.h>
32 #include <errno.h>
33 #include <hardware/bluetooth.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "device/include/controller.h"
37
38 #include "btcore/include/bdaddr.h"
39 #include "btif_common.h"
40 #include "btif_util.h"
41
42 #include <hardware/bt_gatt.h>
43
44 #include "bta_api.h"
45 #include "bta_closure_api.h"
46 #include "bta_gatt_api.h"
47 #include "btif_config.h"
48 #include "btif_dm.h"
49 #include "btif_gatt.h"
50 #include "btif_gatt_util.h"
51 #include "btif_storage.h"
52 #include "osi/include/log.h"
53 #include "vendor_api.h"
54
55 using base::Bind;
56 using base::Owned;
57 using std::vector;
58
59 extern bt_status_t btif_gattc_test_command_impl(int command,
60 btgatt_test_params_t* params);
61 extern const btgatt_callbacks_t* bt_gatt_callbacks;
62
63 /*******************************************************************************
64 * Constants & Macros
65 ******************************************************************************/
66
67 #define CLI_CBACK_IN_JNI(P_CBACK, ...) \
68 do { \
69 if (bt_gatt_callbacks && bt_gatt_callbacks->client->P_CBACK) { \
70 BTIF_TRACE_API("HAL bt_gatt_callbacks->client->%s", #P_CBACK); \
71 do_in_jni_thread(Bind(bt_gatt_callbacks->client->P_CBACK, __VA_ARGS__)); \
72 } else { \
73 ASSERTC(0, "Callback is NULL", 0); \
74 } \
75 } while (0)
76
77 #define CHECK_BTGATT_INIT() \
78 do { \
79 if (bt_gatt_callbacks == NULL) { \
80 LOG_WARN(LOG_TAG, "%s: BTGATT not initialized", __func__); \
81 return BT_STATUS_NOT_READY; \
82 } else { \
83 LOG_VERBOSE(LOG_TAG, "%s", __func__); \
84 } \
85 } while (0)
86
87 #define BLE_RESOLVE_ADDR_MSB \
88 0x40 /* bit7, bit6 is 01 to be resolvable random \
89 */
90 #define BLE_RESOLVE_ADDR_MASK 0xc0 /* bit 6, and bit7 */
91 #define BTM_BLE_IS_RESOLVE_BDA(x) \
92 (((x)[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB)
93
94 namespace {
95
96 uint8_t rssi_request_client_if;
97
btif_gattc_upstreams_evt(uint16_t event,char * p_param)98 void btif_gattc_upstreams_evt(uint16_t event, char* p_param) {
99 LOG_VERBOSE(LOG_TAG, "%s: Event %d", __func__, event);
100
101 tBTA_GATTC* p_data = (tBTA_GATTC*)p_param;
102 switch (event) {
103 case BTA_GATTC_DEREG_EVT:
104 break;
105
106 case BTA_GATTC_EXEC_EVT: {
107 HAL_CBACK(bt_gatt_callbacks, client->execute_write_cb,
108 p_data->exec_cmpl.conn_id, p_data->exec_cmpl.status);
109 break;
110 }
111
112 case BTA_GATTC_SEARCH_CMPL_EVT: {
113 HAL_CBACK(bt_gatt_callbacks, client->search_complete_cb,
114 p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
115 break;
116 }
117
118 case BTA_GATTC_NOTIF_EVT: {
119 btgatt_notify_params_t data;
120
121 bdcpy(data.bda.address, p_data->notify.bda);
122 memcpy(data.value, p_data->notify.value, p_data->notify.len);
123
124 data.handle = p_data->notify.handle;
125 data.is_notify = p_data->notify.is_notify;
126 data.len = p_data->notify.len;
127
128 HAL_CBACK(bt_gatt_callbacks, client->notify_cb, p_data->notify.conn_id,
129 &data);
130
131 if (p_data->notify.is_notify == false)
132 BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, p_data->notify.handle);
133
134 break;
135 }
136
137 case BTA_GATTC_OPEN_EVT: {
138 bt_bdaddr_t bda;
139 bdcpy(bda.address, p_data->open.remote_bda);
140
141 HAL_CBACK(bt_gatt_callbacks, client->open_cb, p_data->open.conn_id,
142 p_data->open.status, p_data->open.client_if, &bda);
143
144 if (GATT_DEF_BLE_MTU_SIZE != p_data->open.mtu && p_data->open.mtu) {
145 HAL_CBACK(bt_gatt_callbacks, client->configure_mtu_cb,
146 p_data->open.conn_id, p_data->open.status, p_data->open.mtu);
147 }
148
149 if (p_data->open.status == BTA_GATT_OK)
150 btif_gatt_check_encrypted_link(p_data->open.remote_bda,
151 p_data->open.transport);
152 break;
153 }
154
155 case BTA_GATTC_CLOSE_EVT: {
156 bt_bdaddr_t bda;
157 bdcpy(bda.address, p_data->close.remote_bda);
158 HAL_CBACK(bt_gatt_callbacks, client->close_cb, p_data->close.conn_id,
159 p_data->status, p_data->close.client_if, &bda);
160 break;
161 }
162
163 case BTA_GATTC_ACL_EVT:
164 LOG_DEBUG(LOG_TAG, "BTA_GATTC_ACL_EVT: status = %d", p_data->status);
165 /* Ignore for now */
166 break;
167
168 case BTA_GATTC_CANCEL_OPEN_EVT:
169 break;
170
171 case BTA_GATTC_CFG_MTU_EVT: {
172 HAL_CBACK(bt_gatt_callbacks, client->configure_mtu_cb,
173 p_data->cfg_mtu.conn_id, p_data->cfg_mtu.status,
174 p_data->cfg_mtu.mtu);
175 break;
176 }
177
178 case BTA_GATTC_CONGEST_EVT:
179 HAL_CBACK(bt_gatt_callbacks, client->congestion_cb,
180 p_data->congest.conn_id, p_data->congest.congested);
181 break;
182
183 case BTA_GATTC_PHY_UPDATE_EVT:
184 HAL_CBACK(bt_gatt_callbacks, client->phy_updated_cb,
185 p_data->phy_update.conn_id, p_data->phy_update.tx_phy,
186 p_data->phy_update.rx_phy, p_data->phy_update.status);
187 break;
188
189 case BTA_GATTC_CONN_UPDATE_EVT:
190 HAL_CBACK(bt_gatt_callbacks, client->conn_updated_cb,
191 p_data->conn_update.conn_id, p_data->conn_update.interval,
192 p_data->conn_update.latency, p_data->conn_update.timeout,
193 p_data->conn_update.status);
194 break;
195
196 default:
197 LOG_ERROR(LOG_TAG, "%s: Unhandled event (%d)!", __func__, event);
198 break;
199 }
200 }
201
bta_gattc_cback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)202 void bta_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
203 bt_status_t status =
204 btif_transfer_context(btif_gattc_upstreams_evt, (uint16_t)event,
205 (char*)p_data, sizeof(tBTA_GATTC), NULL);
206 ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
207 }
208
btm_read_rssi_cb(tBTM_RSSI_RESULTS * p_result)209 void btm_read_rssi_cb(tBTM_RSSI_RESULTS* p_result) {
210 if (!p_result) return;
211
212 bt_bdaddr_t* addr = new bt_bdaddr_t;
213 bdcpy(addr->address, p_result->rem_bda);
214 CLI_CBACK_IN_JNI(read_remote_rssi_cb, rssi_request_client_if,
215 base::Owned(addr), p_result->rssi, p_result->status);
216 }
217
218 /*******************************************************************************
219 * Client API Functions
220 ******************************************************************************/
221
btif_gattc_register_app(bt_uuid_t * uuid)222 bt_status_t btif_gattc_register_app(bt_uuid_t* uuid) {
223 CHECK_BTGATT_INIT();
224
225 tBT_UUID bt_uuid;
226 btif_to_bta_uuid(&bt_uuid, uuid);
227
228 return do_in_jni_thread(Bind(
229 [](tBT_UUID bt_uuid) {
230 BTA_GATTC_AppRegister(
231 bta_gattc_cback,
232 base::Bind(
233 [](tBT_UUID bt_uuid, uint8_t client_id, uint8_t status) {
234 do_in_jni_thread(Bind(
235 [](tBT_UUID bt_uuid, uint8_t client_id, uint8_t status) {
236 bt_uuid_t app_uuid;
237 bta_to_btif_uuid(&app_uuid, &bt_uuid);
238 HAL_CBACK(bt_gatt_callbacks, client->register_client_cb,
239 status, client_id, &app_uuid);
240 },
241 bt_uuid, client_id, status));
242 },
243 bt_uuid));
244 },
245 bt_uuid));
246 }
247
btif_gattc_unregister_app_impl(int client_if)248 void btif_gattc_unregister_app_impl(int client_if) {
249 BTA_GATTC_AppDeregister(client_if);
250 }
251
btif_gattc_unregister_app(int client_if)252 bt_status_t btif_gattc_unregister_app(int client_if) {
253 CHECK_BTGATT_INIT();
254 return do_in_jni_thread(Bind(&btif_gattc_unregister_app_impl, client_if));
255 }
256
btif_gattc_open_impl(int client_if,BD_ADDR address,bool is_direct,int transport_p,int initiating_phys)257 void btif_gattc_open_impl(int client_if, BD_ADDR address, bool is_direct,
258 int transport_p, int initiating_phys) {
259 // Ensure device is in inquiry database
260 int addr_type = 0;
261 int device_type = 0;
262 tBTA_GATT_TRANSPORT transport = (tBTA_GATT_TRANSPORT)BTA_GATT_TRANSPORT_LE;
263
264 if (btif_get_address_type(address, &addr_type) &&
265 btif_get_device_type(address, &device_type) &&
266 device_type != BT_DEVICE_TYPE_BREDR) {
267 BTA_DmAddBleDevice(address, addr_type, device_type);
268 }
269
270 // Check for background connections
271 if (!is_direct) {
272 // Check for privacy 1.0 and 1.1 controller and do not start background
273 // connection if RPA offloading is not supported, since it will not
274 // connect after change of random address
275 if (!controller_get_interface()->supports_ble_privacy() &&
276 (addr_type == BLE_ADDR_RANDOM) && BTM_BLE_IS_RESOLVE_BDA(address)) {
277 tBTM_BLE_VSC_CB vnd_capabilities;
278 BTM_BleGetVendorCapabilities(&vnd_capabilities);
279 if (!vnd_capabilities.rpa_offloading) {
280 HAL_CBACK(bt_gatt_callbacks, client->open_cb, 0, BT_STATUS_UNSUPPORTED,
281 client_if, (bt_bdaddr_t*)&address);
282 return;
283 }
284 }
285 BTA_DmBleStartAutoConn();
286 }
287
288 // Determine transport
289 if (transport_p != GATT_TRANSPORT_AUTO) {
290 transport = transport_p;
291 } else {
292 switch (device_type) {
293 case BT_DEVICE_TYPE_BREDR:
294 transport = BTA_GATT_TRANSPORT_BR_EDR;
295 break;
296
297 case BT_DEVICE_TYPE_BLE:
298 transport = BTA_GATT_TRANSPORT_LE;
299 break;
300
301 case BT_DEVICE_TYPE_DUMO:
302 if (transport_p == GATT_TRANSPORT_LE)
303 transport = BTA_GATT_TRANSPORT_LE;
304 else
305 transport = BTA_GATT_TRANSPORT_BR_EDR;
306 break;
307 }
308 }
309
310 // Connect!
311 BTIF_TRACE_DEBUG("%s Transport=%d, device type=%d, phy=%d", __func__,
312 transport, device_type, initiating_phys);
313 BTA_GATTC_Open(client_if, address, is_direct, transport, false,
314 initiating_phys);
315 }
316
btif_gattc_open(int client_if,const bt_bdaddr_t * bd_addr,bool is_direct,int transport,int initiating_phys)317 bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t* bd_addr,
318 bool is_direct, int transport,
319 int initiating_phys) {
320 CHECK_BTGATT_INIT();
321 // Closure will own this value and free it.
322 uint8_t* address = new BD_ADDR;
323 bdcpy(address, bd_addr->address);
324 return do_in_jni_thread(Bind(&btif_gattc_open_impl, client_if,
325 base::Owned(address), is_direct, transport,
326 initiating_phys));
327 }
328
btif_gattc_close_impl(int client_if,BD_ADDR address,int conn_id)329 void btif_gattc_close_impl(int client_if, BD_ADDR address, int conn_id) {
330 // Disconnect established connections
331 if (conn_id != 0)
332 BTA_GATTC_Close(conn_id);
333 else
334 BTA_GATTC_CancelOpen(client_if, address, true);
335
336 // Cancel pending background connections (remove from whitelist)
337 BTA_GATTC_CancelOpen(client_if, address, false);
338 }
339
btif_gattc_close(int client_if,const bt_bdaddr_t * bd_addr,int conn_id)340 bt_status_t btif_gattc_close(int client_if, const bt_bdaddr_t* bd_addr,
341 int conn_id) {
342 CHECK_BTGATT_INIT();
343 // Closure will own this value and free it.
344 uint8_t* address = new BD_ADDR;
345 bdcpy(address, bd_addr->address);
346 return do_in_jni_thread(
347 Bind(&btif_gattc_close_impl, client_if, base::Owned(address), conn_id));
348 }
349
btif_gattc_refresh(int client_if,const bt_bdaddr_t * bd_addr)350 bt_status_t btif_gattc_refresh(int client_if, const bt_bdaddr_t* bd_addr) {
351 CHECK_BTGATT_INIT();
352 // Closure will own this value and free it.
353 uint8_t* address = new BD_ADDR;
354 bdcpy(address, bd_addr->address);
355 return do_in_jni_thread(Bind(&BTA_GATTC_Refresh, base::Owned(address)));
356 }
357
btif_gattc_search_service(int conn_id,bt_uuid_t * filter_uuid)358 bt_status_t btif_gattc_search_service(int conn_id, bt_uuid_t* filter_uuid) {
359 CHECK_BTGATT_INIT();
360
361 if (filter_uuid) {
362 tBT_UUID* uuid = new tBT_UUID;
363 btif_to_bta_uuid(uuid, filter_uuid);
364 return do_in_jni_thread(
365 Bind(&BTA_GATTC_ServiceSearchRequest, conn_id, base::Owned(uuid)));
366 } else {
367 return do_in_jni_thread(
368 Bind(&BTA_GATTC_ServiceSearchRequest, conn_id, nullptr));
369 }
370 }
371
btif_gattc_discover_service_by_uuid(int conn_id,bt_uuid_t * p_uuid)372 void btif_gattc_discover_service_by_uuid(int conn_id, bt_uuid_t* p_uuid) {
373 LOG_ASSERT(p_uuid);
374
375 tBT_UUID* uuid = new tBT_UUID;
376 btif_to_bta_uuid(uuid, p_uuid);
377 do_in_jni_thread(
378 Bind(&BTA_GATTC_DiscoverServiceByUuid, conn_id, base::Owned(uuid)));
379 }
380
btif_gattc_get_gatt_db_impl(int conn_id)381 void btif_gattc_get_gatt_db_impl(int conn_id) {
382 btgatt_db_element_t* db = NULL;
383 int count = 0;
384 BTA_GATTC_GetGattDb(conn_id, 0x0000, 0xFFFF, &db, &count);
385
386 HAL_CBACK(bt_gatt_callbacks, client->get_gatt_db_cb, conn_id, db, count);
387 osi_free(db);
388 }
389
btif_gattc_get_gatt_db(int conn_id)390 bt_status_t btif_gattc_get_gatt_db(int conn_id) {
391 CHECK_BTGATT_INIT();
392 return do_in_jni_thread(Bind(&btif_gattc_get_gatt_db_impl, conn_id));
393 }
394
read_char_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)395 void read_char_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
396 uint16_t len, uint8_t* value, void* data) {
397 btgatt_read_params_t* params = new btgatt_read_params_t;
398 params->value_type = 0x00 /* GATTC_READ_VALUE_TYPE_VALUE */;
399 params->status = status;
400 params->handle = handle;
401 params->value.len = len;
402 CHECK(len <= BTGATT_MAX_ATTR_LEN);
403 if (len > 0) memcpy(params->value.value, value, len);
404
405 CLI_CBACK_IN_JNI(read_characteristic_cb, conn_id, status,
406 base::Owned(params));
407 }
408
btif_gattc_read_char(int conn_id,uint16_t handle,int auth_req)409 bt_status_t btif_gattc_read_char(int conn_id, uint16_t handle, int auth_req) {
410 CHECK_BTGATT_INIT();
411 return do_in_jni_thread(Bind(&BTA_GATTC_ReadCharacteristic, conn_id, handle,
412 auth_req, read_char_cb, nullptr));
413 }
414
read_using_char_uuid_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)415 void read_using_char_uuid_cb(uint16_t conn_id, tGATT_STATUS status,
416 uint16_t handle, uint16_t len, uint8_t* value,
417 void* data) {
418 btgatt_read_params_t* params = new btgatt_read_params_t;
419 params->value_type = 0x00 /* GATTC_READ_VALUE_TYPE_VALUE */;
420 params->status = status;
421 params->handle = handle;
422 params->value.len = len;
423 CHECK(len <= BTGATT_MAX_ATTR_LEN);
424 if (len > 0) memcpy(params->value.value, value, len);
425
426 CLI_CBACK_IN_JNI(read_characteristic_cb, conn_id, status,
427 base::Owned(params));
428 }
429
btif_gattc_read_using_char_uuid(int conn_id,bt_uuid_t * uuid,uint16_t s_handle,uint16_t e_handle,int auth_req)430 bt_status_t btif_gattc_read_using_char_uuid(int conn_id, bt_uuid_t* uuid,
431 uint16_t s_handle,
432 uint16_t e_handle, int auth_req) {
433 CHECK_BTGATT_INIT();
434 tBT_UUID bt_uuid;
435 btif_to_bta_uuid(&bt_uuid, uuid);
436 return do_in_jni_thread(Bind(&BTA_GATTC_ReadUsingCharUuid, conn_id, bt_uuid,
437 s_handle, e_handle, auth_req,
438 read_using_char_uuid_cb, nullptr));
439 }
440
read_desc_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)441 void read_desc_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
442 uint16_t len, uint8_t* value, void* data) {
443 btgatt_read_params_t* params = new btgatt_read_params_t;
444 params->value_type = 0x00 /* GATTC_READ_VALUE_TYPE_VALUE */;
445 params->status = status;
446 params->handle = handle;
447 params->value.len = len;
448 CHECK(len <= BTGATT_MAX_ATTR_LEN);
449 if (len > 0) memcpy(params->value.value, value, len);
450
451 CLI_CBACK_IN_JNI(read_descriptor_cb, conn_id, status, base::Owned(params));
452 }
453
btif_gattc_read_char_descr(int conn_id,uint16_t handle,int auth_req)454 bt_status_t btif_gattc_read_char_descr(int conn_id, uint16_t handle,
455 int auth_req) {
456 CHECK_BTGATT_INIT();
457 return do_in_jni_thread(Bind(&BTA_GATTC_ReadCharDescr, conn_id, handle,
458 auth_req, read_desc_cb, nullptr));
459 }
460
write_char_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,void * data)461 void write_char_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
462 void* data) {
463 CLI_CBACK_IN_JNI(write_characteristic_cb, conn_id, status, handle);
464 }
465
btif_gattc_write_char(int conn_id,uint16_t handle,int write_type,int auth_req,vector<uint8_t> value)466 bt_status_t btif_gattc_write_char(int conn_id, uint16_t handle, int write_type,
467 int auth_req, vector<uint8_t> value) {
468 CHECK_BTGATT_INIT();
469
470 if (value.size() > BTGATT_MAX_ATTR_LEN) value.resize(BTGATT_MAX_ATTR_LEN);
471
472 return do_in_jni_thread(Bind(&BTA_GATTC_WriteCharValue, conn_id, handle,
473 write_type, std::move(value), auth_req,
474 write_char_cb, nullptr));
475 }
476
write_descr_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,void * data)477 void write_descr_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
478 void* data) {
479 CLI_CBACK_IN_JNI(write_descriptor_cb, conn_id, status, handle);
480 }
481
btif_gattc_write_char_descr(int conn_id,uint16_t handle,int auth_req,vector<uint8_t> value)482 bt_status_t btif_gattc_write_char_descr(int conn_id, uint16_t handle,
483 int auth_req, vector<uint8_t> value) {
484 CHECK_BTGATT_INIT();
485
486 if (value.size() > BTGATT_MAX_ATTR_LEN) value.resize(BTGATT_MAX_ATTR_LEN);
487
488 return do_in_jni_thread(Bind(&BTA_GATTC_WriteCharDescr, conn_id, handle,
489 std::move(value), auth_req, write_descr_cb,
490 nullptr));
491 }
492
btif_gattc_execute_write(int conn_id,int execute)493 bt_status_t btif_gattc_execute_write(int conn_id, int execute) {
494 CHECK_BTGATT_INIT();
495 return do_in_jni_thread(
496 Bind(&BTA_GATTC_ExecuteWrite, conn_id, (uint8_t)execute));
497 }
498
btif_gattc_reg_for_notification_impl(tBTA_GATTC_IF client_if,const BD_ADDR bda,uint16_t handle)499 void btif_gattc_reg_for_notification_impl(tBTA_GATTC_IF client_if,
500 const BD_ADDR bda, uint16_t handle) {
501 tBTA_GATT_STATUS status = BTA_GATTC_RegisterForNotifications(
502 client_if, const_cast<uint8_t*>(bda), handle);
503
504 // TODO(jpawlowski): conn_id is currently unused
505 HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
506 /* conn_id */ 0, 1, status, handle);
507 }
508
btif_gattc_reg_for_notification(int client_if,const bt_bdaddr_t * bd_addr,uint16_t handle)509 bt_status_t btif_gattc_reg_for_notification(int client_if,
510 const bt_bdaddr_t* bd_addr,
511 uint16_t handle) {
512 CHECK_BTGATT_INIT();
513
514 uint8_t* address = new BD_ADDR;
515 bdcpy(address, bd_addr->address);
516 return do_in_jni_thread(
517 Bind(base::IgnoreResult(&btif_gattc_reg_for_notification_impl), client_if,
518 base::Owned(address), handle));
519 }
520
btif_gattc_dereg_for_notification_impl(tBTA_GATTC_IF client_if,const BD_ADDR bda,uint16_t handle)521 void btif_gattc_dereg_for_notification_impl(tBTA_GATTC_IF client_if,
522 const BD_ADDR bda,
523 uint16_t handle) {
524 tBTA_GATT_STATUS status = BTA_GATTC_DeregisterForNotifications(
525 client_if, const_cast<uint8_t*>(bda), handle);
526
527 // TODO(jpawlowski): conn_id is currently unused
528 HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
529 /* conn_id */ 0, 0, status, handle);
530 }
531
btif_gattc_dereg_for_notification(int client_if,const bt_bdaddr_t * bd_addr,uint16_t handle)532 bt_status_t btif_gattc_dereg_for_notification(int client_if,
533 const bt_bdaddr_t* bd_addr,
534 uint16_t handle) {
535 CHECK_BTGATT_INIT();
536
537 uint8_t* address = new BD_ADDR;
538 bdcpy(address, bd_addr->address);
539 return do_in_jni_thread(
540 Bind(base::IgnoreResult(&btif_gattc_dereg_for_notification_impl),
541 client_if, base::Owned(address), handle));
542 }
543
btif_gattc_read_remote_rssi(int client_if,const bt_bdaddr_t * bd_addr)544 bt_status_t btif_gattc_read_remote_rssi(int client_if,
545 const bt_bdaddr_t* bd_addr) {
546 CHECK_BTGATT_INIT();
547 rssi_request_client_if = client_if;
548 // Closure will own this value and free it.
549 uint8_t* address = new BD_ADDR;
550 bdcpy(address, bd_addr->address);
551 return do_in_jni_thread(Bind(base::IgnoreResult(&BTM_ReadRSSI),
552 base::Owned(address),
553 (tBTM_CMPL_CB*)btm_read_rssi_cb));
554 }
555
btif_gattc_configure_mtu(int conn_id,int mtu)556 bt_status_t btif_gattc_configure_mtu(int conn_id, int mtu) {
557 CHECK_BTGATT_INIT();
558 return do_in_jni_thread(
559 Bind(base::IgnoreResult(&BTA_GATTC_ConfigureMTU), conn_id, mtu));
560 }
561
btif_gattc_conn_parameter_update_impl(bt_bdaddr_t addr,int min_interval,int max_interval,int latency,int timeout)562 void btif_gattc_conn_parameter_update_impl(bt_bdaddr_t addr, int min_interval,
563 int max_interval, int latency,
564 int timeout) {
565 if (BTA_DmGetConnectionState(addr.address))
566 BTA_DmBleUpdateConnectionParams(addr.address, min_interval, max_interval,
567 latency, timeout);
568 else
569 BTA_DmSetBlePrefConnParams(addr.address, min_interval, max_interval,
570 latency, timeout);
571 }
572
btif_gattc_conn_parameter_update(const bt_bdaddr_t * bd_addr,int min_interval,int max_interval,int latency,int timeout)573 bt_status_t btif_gattc_conn_parameter_update(const bt_bdaddr_t* bd_addr,
574 int min_interval, int max_interval,
575 int latency, int timeout) {
576 CHECK_BTGATT_INIT();
577 return do_in_jni_thread(
578 Bind(base::IgnoreResult(&btif_gattc_conn_parameter_update_impl), *bd_addr,
579 min_interval, max_interval, latency, timeout));
580 }
581
btif_gattc_set_preferred_phy(int conn_id,uint8_t tx_phy,uint8_t rx_phy,uint16_t phy_options)582 bt_status_t btif_gattc_set_preferred_phy(int conn_id, uint8_t tx_phy,
583 uint8_t rx_phy, uint16_t phy_options) {
584 CHECK_BTGATT_INIT();
585 do_in_bta_thread(FROM_HERE, Bind(&GATTC_SetPreferredPHY, conn_id, tx_phy,
586 rx_phy, phy_options));
587 return BT_STATUS_SUCCESS;
588 }
589
btif_gattc_read_phy(int conn_id,base::Callback<void (uint8_t tx_phy,uint8_t rx_phy,uint8_t status)> cb)590 bt_status_t btif_gattc_read_phy(
591 int conn_id,
592 base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
593 CHECK_BTGATT_INIT();
594 do_in_bta_thread(FROM_HERE, Bind(&GATTC_ReadPHY, conn_id,
595 jni_thread_wrapper(FROM_HERE, cb)));
596 return BT_STATUS_SUCCESS;
597 }
598
btif_gattc_get_device_type(const bt_bdaddr_t * bd_addr)599 int btif_gattc_get_device_type(const bt_bdaddr_t* bd_addr) {
600 int device_type = 0;
601 char bd_addr_str[18] = {0};
602
603 bdaddr_to_string(bd_addr, bd_addr_str, sizeof(bd_addr_str));
604 if (btif_config_get_int(bd_addr_str, "DevType", &device_type))
605 return device_type;
606 return 0;
607 }
608
btif_gattc_test_command(int command,btgatt_test_params_t * params)609 bt_status_t btif_gattc_test_command(int command, btgatt_test_params_t* params) {
610 return btif_gattc_test_command_impl(command, params);
611 }
612
613 } // namespace
614
615 const btgatt_client_interface_t btgattClientInterface = {
616 btif_gattc_register_app,
617 btif_gattc_unregister_app,
618 btif_gattc_open,
619 btif_gattc_close,
620 btif_gattc_refresh,
621 btif_gattc_search_service,
622 btif_gattc_discover_service_by_uuid,
623 btif_gattc_read_char,
624 btif_gattc_read_using_char_uuid,
625 btif_gattc_write_char,
626 btif_gattc_read_char_descr,
627 btif_gattc_write_char_descr,
628 btif_gattc_execute_write,
629 btif_gattc_reg_for_notification,
630 btif_gattc_dereg_for_notification,
631 btif_gattc_read_remote_rssi,
632 btif_gattc_get_device_type,
633 btif_gattc_configure_mtu,
634 btif_gattc_conn_parameter_update,
635 btif_gattc_set_preferred_phy,
636 btif_gattc_read_phy,
637 btif_gattc_test_command,
638 btif_gattc_get_gatt_db};
639