• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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