1 /******************************************************************************
2 *
3 * Copyright (C) 2003-2012 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 * This file contains the GATT client action functions for the state
22 * machine.
23 *
24 ******************************************************************************/
25
26 #define LOG_TAG "bt_bta_gattc"
27
28 #include <string.h>
29
30 #include <base/callback.h>
31 #include "bt_common.h"
32 #include "bt_target.h"
33 #include "bta_gattc_int.h"
34 #include "bta_sys.h"
35 #include "btif/include/btif_debug_conn.h"
36 #include "l2c_api.h"
37 #include "osi/include/log.h"
38 #include "osi/include/osi.h"
39 #include "stack/l2cap/l2c_int.h"
40 #include "utl.h"
41
42 #if (BTA_HH_LE_INCLUDED == TRUE)
43 #include "bta_hh_int.h"
44 #endif
45
46 /*****************************************************************************
47 * Constants
48 ****************************************************************************/
49 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda,
50 uint16_t conn_id, bool connected,
51 tGATT_DISCONN_REASON reason,
52 tBT_TRANSPORT transport);
53
54 static void bta_gattc_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op,
55 tGATT_STATUS status,
56 tGATT_CL_COMPLETE* p_data);
57 static void bta_gattc_cmpl_sendmsg(uint16_t conn_id, tGATTC_OPTYPE op,
58 tBTA_GATT_STATUS status,
59 tGATT_CL_COMPLETE* p_data);
60
61 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB* p_clreg);
62 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
63 static void bta_gattc_cong_cback(uint16_t conn_id, bool congested);
64 static void bta_gattc_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
65 uint8_t tx_phy, uint8_t rx_phy,
66 uint8_t status);
67 static void bta_gattc_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
68 uint16_t interval, uint16_t latency,
69 uint16_t timeout, uint8_t status);
70
71 static tGATT_CBACK bta_gattc_cl_cback = {bta_gattc_conn_cback,
72 bta_gattc_cmpl_cback,
73 bta_gattc_disc_res_cback,
74 bta_gattc_disc_cmpl_cback,
75 NULL,
76 bta_gattc_enc_cmpl_cback,
77 bta_gattc_cong_cback,
78 bta_gattc_phy_update_cback,
79 bta_gattc_conn_update_cback};
80
81 /* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
82 static uint16_t bta_gattc_opcode_to_int_evt[] = {
83 BTA_GATTC_API_READ_EVT, BTA_GATTC_API_WRITE_EVT, BTA_GATTC_API_EXEC_EVT,
84 BTA_GATTC_API_CFG_MTU_EVT};
85
86 static const char* bta_gattc_op_code_name[] = {
87 "Unknown", "Discovery", "Read", "Write",
88 "Exec", "Config", "Notification", "Indication"};
89 /*****************************************************************************
90 * Action Functions
91 ****************************************************************************/
92
93 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb,
94 tBTA_GATT_STATUS status);
95
96 /*******************************************************************************
97 *
98 * Function bta_gattc_enable
99 *
100 * Description Enables GATTC module
101 *
102 *
103 * Returns void
104 *
105 ******************************************************************************/
bta_gattc_enable()106 static void bta_gattc_enable() {
107 APPL_TRACE_DEBUG("bta_gattc_enable");
108
109 if (bta_gattc_cb.state == BTA_GATTC_STATE_DISABLED) {
110 /* initialize control block */
111 memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
112 bta_gattc_cb.state = BTA_GATTC_STATE_ENABLED;
113 } else {
114 APPL_TRACE_DEBUG("GATTC is arelady enabled");
115 }
116 }
117
118 /*******************************************************************************
119 *
120 * Function bta_gattc_disable
121 *
122 * Description Disable GATTC module by cleaning up all active connections
123 * and deregister all application.
124 *
125 * Returns void
126 *
127 ******************************************************************************/
bta_gattc_disable()128 void bta_gattc_disable() {
129 uint8_t i;
130
131 APPL_TRACE_DEBUG("bta_gattc_disable");
132
133 if (bta_gattc_cb.state != BTA_GATTC_STATE_ENABLED) {
134 APPL_TRACE_ERROR("not enabled or disable in pogress");
135 return;
136 }
137
138 for (i = 0; i < BTA_GATTC_CL_MAX; i++) {
139 if (bta_gattc_cb.cl_rcb[i].in_use) {
140 bta_gattc_cb.state = BTA_GATTC_STATE_DISABLING;
141 /* don't deregister HH GATT IF */
142 /* HH GATT IF will be deregistered by bta_hh_le_deregister when disable HH */
143 #if (BTA_HH_LE_INCLUDED == TRUE)
144 if (!bta_hh_le_is_hh_gatt_if(bta_gattc_cb.cl_rcb[i].client_if)) {
145 #endif
146 bta_gattc_deregister(&bta_gattc_cb.cl_rcb[i]);
147 #if (BTA_HH_LE_INCLUDED == TRUE)
148 }
149 #endif
150 }
151 }
152
153 /* no registered apps, indicate disable completed */
154 if (bta_gattc_cb.state != BTA_GATTC_STATE_DISABLING) {
155 memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
156 bta_gattc_cb.state = BTA_GATTC_STATE_DISABLED;
157 }
158 }
159
160 /*******************************************************************************
161 *
162 * Function bta_gattc_register
163 *
164 * Description Register a GATT client application with BTA.
165 *
166 * Returns void
167 *
168 ******************************************************************************/
bta_gattc_register(tBT_UUID * p_app_uuid,tBTA_GATTC_CBACK * p_cback,BtaAppRegisterCallback cb)169 void bta_gattc_register(tBT_UUID* p_app_uuid, tBTA_GATTC_CBACK* p_cback,
170 BtaAppRegisterCallback cb) {
171 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
172 uint8_t client_if = 0;
173 APPL_TRACE_DEBUG("bta_gattc_register state %d", bta_gattc_cb.state);
174
175 /* check if GATTC module is already enabled . Else enable */
176 if (bta_gattc_cb.state == BTA_GATTC_STATE_DISABLED) {
177 bta_gattc_enable();
178 }
179 /* todo need to check duplicate uuid */
180 for (uint8_t i = 0; i < BTA_GATTC_CL_MAX; i++) {
181 if (!bta_gattc_cb.cl_rcb[i].in_use) {
182 if ((p_app_uuid == NULL) ||
183 (bta_gattc_cb.cl_rcb[i].client_if =
184 GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0) {
185 APPL_TRACE_ERROR("Register with GATT stack failed.");
186 status = BTA_GATT_ERROR;
187 } else {
188 bta_gattc_cb.cl_rcb[i].in_use = true;
189 bta_gattc_cb.cl_rcb[i].p_cback = p_cback;
190 memcpy(&bta_gattc_cb.cl_rcb[i].app_uuid, p_app_uuid, sizeof(tBT_UUID));
191
192 /* BTA use the same client interface as BTE GATT statck */
193 client_if = bta_gattc_cb.cl_rcb[i].client_if;
194
195 tBTA_GATTC_INT_START_IF* p_buf = (tBTA_GATTC_INT_START_IF*)osi_malloc(
196 sizeof(tBTA_GATTC_INT_START_IF));
197 p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT;
198 p_buf->client_if = bta_gattc_cb.cl_rcb[i].client_if;
199
200 bta_sys_sendmsg(p_buf);
201 status = BTA_GATT_OK;
202 break;
203 }
204 }
205 }
206
207 if (!cb.is_null()) cb.Run(client_if, status);
208 }
209 /*******************************************************************************
210 *
211 * Function bta_gattc_start_if
212 *
213 * Description start an application interface.
214 *
215 * Returns none.
216 *
217 ******************************************************************************/
bta_gattc_start_if(tBTA_GATTC_DATA * p_msg)218 void bta_gattc_start_if(tBTA_GATTC_DATA* p_msg) {
219 if (bta_gattc_cl_get_regcb(p_msg->int_start_if.client_if) != NULL) {
220 GATT_StartIf(p_msg->int_start_if.client_if);
221 } else {
222 APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
223 p_msg->int_start_if.client_if);
224 }
225 }
226 /*******************************************************************************
227 *
228 * Function bta_gattc_deregister
229 *
230 * Description De-Register a GATT client application with BTA.
231 *
232 * Returns void
233 *
234 ******************************************************************************/
bta_gattc_deregister(tBTA_GATTC_RCB * p_clreg)235 void bta_gattc_deregister(tBTA_GATTC_RCB* p_clreg) {
236 uint8_t i;
237 BT_HDR buf;
238
239 if (p_clreg != NULL) {
240 /* remove bg connection associated with this rcb */
241 for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i++) {
242 if (bta_gattc_cb.bg_track[i].in_use) {
243 if (bta_gattc_cb.bg_track[i].cif_mask &
244 (1 << (p_clreg->client_if - 1))) {
245 bta_gattc_mark_bg_conn(p_clreg->client_if,
246 bta_gattc_cb.bg_track[i].remote_bda, false);
247 GATT_CancelConnect(p_clreg->client_if,
248 bta_gattc_cb.bg_track[i].remote_bda, false);
249 }
250 }
251 }
252
253 if (p_clreg->num_clcb > 0) {
254 /* close all CLCB related to this app */
255 for (i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
256 if (bta_gattc_cb.clcb[i].in_use &&
257 (bta_gattc_cb.clcb[i].p_rcb == p_clreg)) {
258 p_clreg->dereg_pending = true;
259
260 buf.event = BTA_GATTC_API_CLOSE_EVT;
261 buf.layer_specific = bta_gattc_cb.clcb[i].bta_conn_id;
262 bta_gattc_close(&bta_gattc_cb.clcb[i], (tBTA_GATTC_DATA*)&buf);
263 }
264 }
265 } else
266 bta_gattc_deregister_cmpl(p_clreg);
267 } else {
268 APPL_TRACE_ERROR("%s: Deregister Failed unknown client cif", __func__);
269 bta_hh_cleanup_disable(BTA_HH_OK);
270 }
271 }
272 /*******************************************************************************
273 *
274 * Function bta_gattc_process_api_open
275 *
276 * Description process connect API request.
277 *
278 * Returns void
279 *
280 ******************************************************************************/
bta_gattc_process_api_open(tBTA_GATTC_DATA * p_msg)281 void bta_gattc_process_api_open(tBTA_GATTC_DATA* p_msg) {
282 uint16_t event = ((BT_HDR*)p_msg)->event;
283 tBTA_GATTC_CLCB* p_clcb = NULL;
284 tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if);
285
286 if (p_clreg != NULL) {
287 if (p_msg->api_conn.is_direct) {
288 p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
289 p_msg->api_conn.remote_bda,
290 p_msg->api_conn.transport);
291 if (p_clcb != NULL) {
292 bta_gattc_sm_execute(p_clcb, event, p_msg);
293 } else {
294 APPL_TRACE_ERROR("No resources to open a new connection.");
295
296 bta_gattc_send_open_cback(
297 p_clreg, BTA_GATT_NO_RESOURCES, p_msg->api_conn.remote_bda,
298 BTA_GATT_INVALID_CONN_ID, p_msg->api_conn.transport, 0);
299 }
300 } else {
301 bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);
302 }
303 } else {
304 APPL_TRACE_ERROR("bta_gattc_process_api_open Failed, unknown client_if: %d",
305 p_msg->api_conn.client_if);
306 }
307 }
308 /*******************************************************************************
309 *
310 * Function bta_gattc_process_api_open_cancel
311 *
312 * Description process connect API request.
313 *
314 * Returns void
315 *
316 ******************************************************************************/
bta_gattc_process_api_open_cancel(tBTA_GATTC_DATA * p_msg)317 void bta_gattc_process_api_open_cancel(tBTA_GATTC_DATA* p_msg) {
318 uint16_t event = ((BT_HDR*)p_msg)->event;
319 tBTA_GATTC_CLCB* p_clcb = NULL;
320 tBTA_GATTC_RCB* p_clreg;
321 tBTA_GATTC cb_data;
322
323 if (p_msg->api_cancel_conn.is_direct) {
324 p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
325 p_msg->api_cancel_conn.remote_bda,
326 BTA_GATT_TRANSPORT_LE);
327 if (p_clcb != NULL) {
328 bta_gattc_sm_execute(p_clcb, event, p_msg);
329 } else {
330 APPL_TRACE_ERROR("No such connection need to be cancelled");
331
332 p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if);
333
334 if (p_clreg && p_clreg->p_cback) {
335 cb_data.status = BTA_GATT_ERROR;
336 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
337 }
338 }
339 } else {
340 bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn);
341 }
342 }
343
344 /*******************************************************************************
345 *
346 * Function bta_gattc_process_enc_cmpl
347 *
348 * Description process encryption complete message.
349 *
350 * Returns void
351 *
352 ******************************************************************************/
bta_gattc_process_enc_cmpl(tBTA_GATTC_DATA * p_msg)353 void bta_gattc_process_enc_cmpl(tBTA_GATTC_DATA* p_msg) {
354 tBTA_GATTC_RCB* p_clreg;
355 tBTA_GATTC cb_data;
356
357 p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if);
358
359 if (p_clreg && p_clreg->p_cback) {
360 memset(&cb_data, 0, sizeof(tBTA_GATTC));
361
362 cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if;
363 bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda);
364
365 (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
366 }
367 }
368
369 /*******************************************************************************
370 *
371 * Function bta_gattc_cancel_open_error
372 *
373 * Description
374 *
375 * Returns void
376 *
377 ******************************************************************************/
bta_gattc_cancel_open_error(tBTA_GATTC_CLCB * p_clcb,UNUSED_ATTR tBTA_GATTC_DATA * p_data)378 void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB* p_clcb,
379 UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
380 tBTA_GATTC cb_data;
381
382 cb_data.status = BTA_GATT_ERROR;
383
384 if (p_clcb && p_clcb->p_rcb && p_clcb->p_rcb->p_cback)
385 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
386 }
387
388 /*******************************************************************************
389 *
390 * Function bta_gattc_open_error
391 *
392 * Description
393 *
394 * Returns void
395 *
396 ******************************************************************************/
bta_gattc_open_error(tBTA_GATTC_CLCB * p_clcb,UNUSED_ATTR tBTA_GATTC_DATA * p_data)397 void bta_gattc_open_error(tBTA_GATTC_CLCB* p_clcb,
398 UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
399 APPL_TRACE_ERROR("Connection already opened. wrong state");
400
401 bta_gattc_send_open_cback(p_clcb->p_rcb, BTA_GATT_OK, p_clcb->bda,
402 p_clcb->bta_conn_id, p_clcb->transport, 0);
403 }
404 /*******************************************************************************
405 *
406 * Function bta_gattc_open_fail
407 *
408 * Description
409 *
410 * Returns void
411 *
412 ******************************************************************************/
bta_gattc_open_fail(tBTA_GATTC_CLCB * p_clcb,UNUSED_ATTR tBTA_GATTC_DATA * p_data)413 void bta_gattc_open_fail(tBTA_GATTC_CLCB* p_clcb,
414 UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
415 bta_gattc_send_open_cback(p_clcb->p_rcb, BTA_GATT_ERROR, p_clcb->bda,
416 p_clcb->bta_conn_id, p_clcb->transport, 0);
417 /* open failure, remove clcb */
418 bta_gattc_clcb_dealloc(p_clcb);
419 }
420
421 /*******************************************************************************
422 *
423 * Function bta_gattc_open
424 *
425 * Description Process API connection function.
426 *
427 * Returns void
428 *
429 ******************************************************************************/
bta_gattc_open(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)430 void bta_gattc_open(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
431 tBTA_GATTC_DATA gattc_data;
432
433 /* open/hold a connection */
434 if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, true,
435 p_data->api_conn.transport, p_data->api_conn.opportunistic,
436 p_data->api_conn.initiating_phys)) {
437 APPL_TRACE_ERROR("Connection open failure");
438
439 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
440 } else {
441 /* a connected remote device */
442 if (GATT_GetConnIdIfConnected(
443 p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda,
444 &p_clcb->bta_conn_id, p_data->api_conn.transport)) {
445 gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
446
447 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
448 }
449 /* else wait for the callback event */
450 }
451 }
452 /*******************************************************************************
453 *
454 * Function bta_gattc_init_bk_conn
455 *
456 * Description Process API Open for a background connection
457 *
458 * Returns void
459 *
460 ******************************************************************************/
bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN * p_data,tBTA_GATTC_RCB * p_clreg)461 void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN* p_data,
462 tBTA_GATTC_RCB* p_clreg) {
463 tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
464 uint16_t conn_id;
465 tBTA_GATTC_CLCB* p_clcb;
466 tBTA_GATTC_DATA gattc_data;
467
468 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, true)) {
469 /* always call open to hold a connection */
470 if (!GATT_Connect(p_data->client_if, p_data->remote_bda, false,
471 p_data->transport, false)) {
472 uint8_t* bda = (uint8_t*)p_data->remote_bda;
473 status = BTA_GATT_ERROR;
474 APPL_TRACE_ERROR(
475 "%s unable to connect to remote "
476 "bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
477 __func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
478
479 } else {
480 status = BTA_GATT_OK;
481
482 /* if is a connected remote device */
483 if (GATT_GetConnIdIfConnected(p_data->client_if, p_data->remote_bda,
484 &conn_id, p_data->transport)) {
485 p_clcb = bta_gattc_find_alloc_clcb(
486 p_data->client_if, p_data->remote_bda, BTA_GATT_TRANSPORT_LE);
487 if (p_clcb != NULL) {
488 gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
489
490 /* open connection */
491 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, &gattc_data);
492 status = BTA_GATT_OK;
493 }
494 }
495 }
496 }
497
498 /* open failure, report OPEN_EVT */
499 if (status != BTA_GATT_OK) {
500 bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda,
501 BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE,
502 0);
503 }
504 }
505 /*******************************************************************************
506 *
507 * Function bta_gattc_cancel_bk_conn
508 *
509 * Description Process API Cancel Open for a background connection
510 *
511 * Returns void
512 *
513 ******************************************************************************/
bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN * p_data)514 void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN* p_data) {
515 tBTA_GATTC_RCB* p_clreg;
516 tBTA_GATTC cb_data;
517 cb_data.status = BTA_GATT_ERROR;
518
519 /* remove the device from the bg connection mask */
520 if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, false)) {
521 if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, false)) {
522 cb_data.status = BTA_GATT_OK;
523 } else {
524 APPL_TRACE_ERROR("bta_gattc_cancel_bk_conn failed");
525 }
526 }
527 p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
528
529 if (p_clreg && p_clreg->p_cback) {
530 (*p_clreg->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
531 }
532 }
533 /*******************************************************************************
534 *
535 * Function bta_gattc_int_cancel_open_ok
536 *
537 * Description
538 *
539 * Returns void
540 *
541 ******************************************************************************/
bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB * p_clcb,UNUSED_ATTR tBTA_GATTC_DATA * p_data)542 void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB* p_clcb,
543 UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
544 tBTA_GATTC cb_data;
545
546 if (p_clcb->p_rcb->p_cback) {
547 cb_data.status = BTA_GATT_OK;
548 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
549 }
550
551 bta_gattc_clcb_dealloc(p_clcb);
552 }
553 /*******************************************************************************
554 *
555 * Function bta_gattc_cancel_open
556 *
557 * Description
558 *
559 * Returns void
560 *
561 ******************************************************************************/
bta_gattc_cancel_open(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)562 void bta_gattc_cancel_open(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
563 tBTA_GATTC cb_data;
564
565 if (GATT_CancelConnect(p_clcb->p_rcb->client_if,
566 p_data->api_cancel_conn.remote_bda, true)) {
567 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CANCEL_OPEN_OK_EVT, p_data);
568 } else {
569 if (p_clcb->p_rcb->p_cback) {
570 cb_data.status = BTA_GATT_ERROR;
571 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CANCEL_OPEN_EVT, &cb_data);
572 }
573 }
574 }
575 /*******************************************************************************
576 *
577 * Function bta_gattc_conn
578 *
579 * Description receive connection callback from stack
580 *
581 * Returns void
582 *
583 ******************************************************************************/
bta_gattc_conn(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)584 void bta_gattc_conn(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
585 tBTA_GATTC_IF gatt_if;
586 APPL_TRACE_DEBUG("bta_gattc_conn server cache state=%d",
587 p_clcb->p_srcb->state);
588
589 if (p_data != NULL) {
590 APPL_TRACE_DEBUG("bta_gattc_conn conn_id=%d", p_data->hdr.layer_specific);
591 p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific;
592
593 GATT_GetConnectionInfor(p_data->hdr.layer_specific, &gatt_if, p_clcb->bda,
594 &p_clcb->transport);
595 }
596
597 p_clcb->p_srcb->connected = true;
598
599 if (p_clcb->p_srcb->mtu == 0) p_clcb->p_srcb->mtu = GATT_DEF_BLE_MTU_SIZE;
600
601 /* start database cache if needed */
602 if (p_clcb->p_srcb->p_srvc_cache == NULL ||
603 p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
604 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
605 p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
606 if (bta_gattc_cache_load(p_clcb)) {
607 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
608 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
609 } else {
610 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
611 /* cache load failure, start discovery */
612 bta_gattc_start_discover(p_clcb, NULL);
613 }
614 } else /* cache is building */
615 p_clcb->state = BTA_GATTC_DISCOVER_ST;
616 }
617
618 else {
619 /* a pending service handle change indication */
620 if (p_clcb->p_srcb->srvc_hdl_chg) {
621 p_clcb->p_srcb->srvc_hdl_chg = false;
622 /* start discovery */
623 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
624 }
625 }
626
627 if (p_clcb->p_rcb) {
628 /* there is no RM for GATT */
629 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
630 bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
631
632 bta_gattc_send_open_cback(p_clcb->p_rcb, BTA_GATT_OK, p_clcb->bda,
633 p_clcb->bta_conn_id, p_clcb->transport,
634 p_clcb->p_srcb->mtu);
635 }
636 }
637 /*******************************************************************************
638 *
639 * Function bta_gattc_close_fail
640 *
641 * Description close a connection.
642 *
643 * Returns void
644 *
645 ******************************************************************************/
bta_gattc_close_fail(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)646 void bta_gattc_close_fail(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
647 tBTA_GATTC cb_data;
648
649 if (p_clcb->p_rcb->p_cback) {
650 memset(&cb_data, 0, sizeof(tBTA_GATTC));
651 cb_data.close.client_if = p_clcb->p_rcb->client_if;
652 cb_data.close.conn_id = p_data->hdr.layer_specific;
653 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
654 cb_data.close.status = BTA_GATT_ERROR;
655 cb_data.close.reason = BTA_GATT_CONN_NONE;
656
657 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
658 }
659 }
660 /*******************************************************************************
661 *
662 * Function bta_gattc_api_close
663 *
664 * Description close a GATTC connection.
665 *
666 * Returns void
667 *
668 ******************************************************************************/
bta_gattc_close(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)669 void bta_gattc_close(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
670 tBTA_GATTC_CBACK* p_cback = p_clcb->p_rcb->p_cback;
671 tBTA_GATTC_RCB* p_clreg = p_clcb->p_rcb;
672 tBTA_GATTC cb_data;
673
674 APPL_TRACE_DEBUG("bta_gattc_close conn_id=%d", p_clcb->bta_conn_id);
675
676 cb_data.close.client_if = p_clcb->p_rcb->client_if;
677 cb_data.close.conn_id = p_clcb->bta_conn_id;
678 cb_data.close.reason = p_clcb->reason;
679 cb_data.close.status = p_clcb->status;
680 bdcpy(cb_data.close.remote_bda, p_clcb->bda);
681
682 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
683 bta_sys_conn_close(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
684
685 bta_gattc_clcb_dealloc(p_clcb);
686
687 if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) {
688 cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
689 } else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT) {
690 cb_data.close.status = p_data->int_conn.reason;
691 cb_data.close.reason = p_data->int_conn.reason;
692 }
693
694 if (p_cback) (*p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&cb_data);
695
696 if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
697 bta_gattc_deregister_cmpl(p_clreg);
698 }
699 }
700 /*******************************************************************************
701 *
702 * Function bta_gattc_reset_discover_st
703 *
704 * Description when a SRCB finished discovery, tell all related clcb.
705 *
706 * Returns None.
707 *
708 ******************************************************************************/
bta_gattc_reset_discover_st(tBTA_GATTC_SERV * p_srcb,tBTA_GATT_STATUS status)709 void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb,
710 tBTA_GATT_STATUS status) {
711 uint8_t i;
712
713 for (i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
714 if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) {
715 bta_gattc_cb.clcb[i].status = status;
716 bta_gattc_sm_execute(&bta_gattc_cb.clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT,
717 NULL);
718 }
719 }
720 }
721 /*******************************************************************************
722 *
723 * Function bta_gattc_disc_close
724 *
725 * Description close a GATTC connection while in discovery state.
726 *
727 * Returns void
728 *
729 ******************************************************************************/
bta_gattc_disc_close(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)730 void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
731 APPL_TRACE_DEBUG("%s: Discovery cancel conn_id=%d", __func__,
732 p_clcb->bta_conn_id);
733
734 if (p_clcb->disc_active)
735 bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
736 else
737 p_clcb->state = BTA_GATTC_CONN_ST;
738
739 // This function only gets called as the result of a BTA_GATTC_API_CLOSE_EVT
740 // while in the BTA_GATTC_DISCOVER_ST state. Once the state changes, the
741 // connection itself still needs to be closed to resolve the original event.
742 if (p_clcb->state == BTA_GATTC_CONN_ST) {
743 APPL_TRACE_DEBUG(
744 "State is back to BTA_GATTC_CONN_ST. "
745 "Trigger connection close");
746 bta_gattc_close(p_clcb, p_data);
747 }
748 }
749 /*******************************************************************************
750 *
751 * Function bta_gattc_set_discover_st
752 *
753 * Description when a SRCB start discovery, tell all related clcb and set
754 * the state.
755 *
756 * Returns None.
757 *
758 ******************************************************************************/
bta_gattc_set_discover_st(tBTA_GATTC_SERV * p_srcb)759 void bta_gattc_set_discover_st(tBTA_GATTC_SERV* p_srcb) {
760 uint8_t i;
761
762 L2CA_EnableUpdateBleConnParams(p_srcb->server_bda, false);
763 for (i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
764 if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) {
765 bta_gattc_cb.clcb[i].status = BTA_GATT_OK;
766 bta_gattc_cb.clcb[i].state = BTA_GATTC_DISCOVER_ST;
767 }
768 }
769 }
770 /*******************************************************************************
771 *
772 * Function bta_gattc_restart_discover
773 *
774 * Description process service change in discovery state, mark up the auto
775 * update flag and set status to be discovery cancel for
776 * current discovery.
777 *
778 * Returns None.
779 *
780 ******************************************************************************/
bta_gattc_restart_discover(tBTA_GATTC_CLCB * p_clcb,UNUSED_ATTR tBTA_GATTC_DATA * p_data)781 void bta_gattc_restart_discover(tBTA_GATTC_CLCB* p_clcb,
782 UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
783 p_clcb->status = BTA_GATT_CANCEL;
784 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
785 }
786
787 /*******************************************************************************
788 *
789 * Function bta_gattc_cfg_mtu
790 *
791 * Description Configure MTU size on the GATT connection.
792 *
793 * Returns None.
794 *
795 ******************************************************************************/
bta_gattc_cfg_mtu(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)796 void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
797 tBTA_GATT_STATUS status;
798
799 if (bta_gattc_enqueue(p_clcb, p_data)) {
800 status = GATTC_ConfigureMTU(p_clcb->bta_conn_id, p_data->api_mtu.mtu);
801
802 /* if failed, return callback here */
803 if (status != GATT_SUCCESS && status != GATT_CMD_STARTED) {
804 /* Dequeue the data, if it was enqueued */
805 if (p_clcb->p_q_cmd == p_data) p_clcb->p_q_cmd = NULL;
806
807 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status,
808 NULL);
809 }
810 }
811 }
812 /*******************************************************************************
813 *
814 * Function bta_gattc_start_discover
815 *
816 * Description Start a discovery on server.
817 *
818 * Returns None.
819 *
820 ******************************************************************************/
bta_gattc_start_discover(tBTA_GATTC_CLCB * p_clcb,UNUSED_ATTR tBTA_GATTC_DATA * p_data)821 void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb,
822 UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
823 APPL_TRACE_DEBUG(
824 "bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
825 p_clcb->bta_conn_id, p_clcb->p_srcb->state);
826
827 if (((p_clcb->p_q_cmd == NULL ||
828 p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
829 p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) ||
830 p_clcb->p_srcb->state == BTA_GATTC_SERV_DISC)
831 /* no pending operation, start discovery right away */
832 {
833 p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;
834
835 if (p_clcb->p_srcb != NULL) {
836 /* clear the service change mask */
837 p_clcb->p_srcb->srvc_hdl_chg = false;
838 p_clcb->p_srcb->update_count = 0;
839 p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
840
841 if (p_clcb->transport == BTA_TRANSPORT_LE)
842 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, false);
843
844 /* set all srcb related clcb into discovery ST */
845 bta_gattc_set_discover_st(p_clcb->p_srcb);
846
847 p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb);
848 if (p_clcb->status == BTA_GATT_OK) {
849 p_clcb->status = bta_gattc_discover_pri_service(
850 p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
851 }
852 if (p_clcb->status != BTA_GATT_OK) {
853 APPL_TRACE_ERROR("discovery on server failed");
854 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
855 } else
856 p_clcb->disc_active = true;
857 } else {
858 APPL_TRACE_ERROR("unknown device, can not start discovery");
859 }
860 }
861 /* pending operation, wait until it finishes */
862 else {
863 p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
864
865 if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE)
866 p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */
867 }
868 }
869 /*******************************************************************************
870 *
871 * Function bta_gattc_disc_cmpl
872 *
873 * Description discovery on server is finished
874 *
875 * Returns None.
876 *
877 ******************************************************************************/
bta_gattc_disc_cmpl(tBTA_GATTC_CLCB * p_clcb,UNUSED_ATTR tBTA_GATTC_DATA * p_data)878 void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb,
879 UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
880 tBTA_GATTC_DATA* p_q_cmd = p_clcb->p_q_cmd;
881
882 APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d", p_clcb->bta_conn_id);
883
884 if (p_clcb->transport == BTA_TRANSPORT_LE)
885 L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, true);
886 p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
887 p_clcb->disc_active = false;
888
889 if (p_clcb->status != GATT_SUCCESS) {
890 /* clean up cache */
891 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
892 list_free(p_clcb->p_srcb->p_srvc_cache);
893 p_clcb->p_srcb->p_srvc_cache = NULL;
894 }
895
896 /* used to reset cache in application */
897 bta_gattc_cache_reset(p_clcb->p_srcb->server_bda);
898 }
899 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_list) {
900 /* release pending attribute list buffer */
901 osi_free_and_reset((void**)&p_clcb->p_srcb->p_srvc_list);
902 }
903
904 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
905 /* start discovery again */
906 p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
907 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
908 }
909 /* get any queued command to proceed */
910 else if (p_q_cmd != NULL) {
911 p_clcb->p_q_cmd = NULL;
912 /* execute pending operation of link block still present */
913 if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) !=
914 NULL) {
915 bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
916 }
917 /* if the command executed requeued the cmd, we don't
918 * want to free the underlying buffer that's being
919 * referenced by p_clcb->p_q_cmd
920 */
921 if (p_q_cmd != p_clcb->p_q_cmd) osi_free_and_reset((void**)&p_q_cmd);
922 }
923 }
924 /*******************************************************************************
925 *
926 * Function bta_gattc_read
927 *
928 * Description Read an attribute
929 *
930 * Returns None.
931 *
932 ******************************************************************************/
bta_gattc_read(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)933 void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
934 if (!bta_gattc_enqueue(p_clcb, p_data)) return;
935
936 tBTA_GATT_STATUS status;
937 if (p_data->api_read.handle != 0) {
938 tGATT_READ_PARAM read_param;
939 memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
940 read_param.by_handle.handle = p_data->api_read.handle;
941 read_param.by_handle.auth_req = p_data->api_read.auth_req;
942 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
943 } else {
944 tGATT_READ_PARAM read_param;
945 memset(&read_param, 0, sizeof(tGATT_READ_BY_TYPE));
946
947 read_param.char_type.s_handle = p_data->api_read.s_handle;
948 read_param.char_type.e_handle = p_data->api_read.e_handle;
949 read_param.char_type.uuid = p_data->api_read.uuid;
950 read_param.char_type.auth_req = p_data->api_read.auth_req;
951 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_TYPE, &read_param);
952 }
953
954 /* read fail */
955 if (status != BTA_GATT_OK) {
956 /* Dequeue the data, if it was enqueued */
957 if (p_clcb->p_q_cmd == p_data) p_clcb->p_q_cmd = NULL;
958
959 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status,
960 NULL);
961 }
962 }
963 /*******************************************************************************
964 *
965 * Function bta_gattc_read_multi
966 *
967 * Description read multiple
968 *
969 * Returns None.
970 ******************************************************************************/
bta_gattc_read_multi(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)971 void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
972 tBTA_GATT_STATUS status = BTA_GATT_OK;
973 tGATT_READ_PARAM read_param;
974
975 if (bta_gattc_enqueue(p_clcb, p_data)) {
976 memset(&read_param, 0, sizeof(tGATT_READ_PARAM));
977
978 if (status == BTA_GATT_OK) {
979 read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr;
980 read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req;
981 memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles,
982 sizeof(uint16_t) * p_data->api_read_multi.num_attr);
983
984 status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE, &read_param);
985 }
986
987 /* read fail */
988 if (status != BTA_GATT_OK) {
989 /* Dequeue the data, if it was enqueued */
990 if (p_clcb->p_q_cmd == p_data) p_clcb->p_q_cmd = NULL;
991
992 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status,
993 NULL);
994 }
995 }
996 }
997 /*******************************************************************************
998 *
999 * Function bta_gattc_write
1000 *
1001 * Description Write an attribute
1002 *
1003 * Returns None.
1004 *
1005 ******************************************************************************/
bta_gattc_write(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1006 void bta_gattc_write(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
1007 if (!bta_gattc_enqueue(p_clcb, p_data)) return;
1008
1009 tBTA_GATT_STATUS status = BTA_GATT_OK;
1010 tGATT_VALUE attr;
1011
1012 attr.conn_id = p_clcb->bta_conn_id;
1013 attr.handle = p_data->api_write.handle;
1014 attr.offset = p_data->api_write.offset;
1015 attr.len = p_data->api_write.len;
1016 attr.auth_req = p_data->api_write.auth_req;
1017
1018 if (p_data->api_write.p_value)
1019 memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
1020
1021 status =
1022 GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
1023
1024 /* write fail */
1025 if (status != BTA_GATT_OK) {
1026 /* Dequeue the data, if it was enqueued */
1027 if (p_clcb->p_q_cmd == p_data) p_clcb->p_q_cmd = NULL;
1028
1029 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status,
1030 NULL);
1031 }
1032 }
1033 /*******************************************************************************
1034 *
1035 * Function bta_gattc_execute
1036 *
1037 * Description send execute write
1038 *
1039 * Returns None.
1040 ******************************************************************************/
bta_gattc_execute(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1041 void bta_gattc_execute(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
1042 tBTA_GATT_STATUS status;
1043
1044 if (bta_gattc_enqueue(p_clcb, p_data)) {
1045 status =
1046 GATTC_ExecuteWrite(p_clcb->bta_conn_id, p_data->api_exec.is_execute);
1047
1048 if (status != BTA_GATT_OK) {
1049 /* Dequeue the data, if it was enqueued */
1050 if (p_clcb->p_q_cmd == p_data) p_clcb->p_q_cmd = NULL;
1051
1052 bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE,
1053 status, NULL);
1054 }
1055 }
1056 }
1057 /*******************************************************************************
1058 *
1059 * Function bta_gattc_confirm
1060 *
1061 * Description send handle value confirmation
1062 *
1063 * Returns None.
1064 *
1065 ******************************************************************************/
bta_gattc_confirm(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1066 void bta_gattc_confirm(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
1067 uint16_t handle = p_data->api_confirm.handle;
1068
1069 if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific,
1070 handle) != GATT_SUCCESS) {
1071 APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
1072 } else {
1073 /* if over BR_EDR, inform PM for mode change */
1074 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
1075 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1076 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1077 }
1078 }
1079 }
1080 /*******************************************************************************
1081 *
1082 * Function bta_gattc_read_cmpl
1083 *
1084 * Description read complete
1085 *
1086 * Returns None.
1087 *
1088 ******************************************************************************/
bta_gattc_read_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1089 void bta_gattc_read_cmpl(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_OP_CMPL* p_data) {
1090 GATT_READ_OP_CB cb = p_clcb->p_q_cmd->api_read.read_cb;
1091 void* my_cb_data = p_clcb->p_q_cmd->api_read.read_cb_data;
1092
1093 // if it was read by handle, return the handle requested, if read by UUID, use
1094 // handle returned from remote
1095 uint16_t handle = p_clcb->p_q_cmd->api_read.handle;
1096 if (handle == 0) handle = p_data->p_cmpl->att_value.handle;
1097
1098 osi_free_and_reset((void**)&p_clcb->p_q_cmd);
1099
1100 if (cb) {
1101 cb(p_clcb->bta_conn_id, p_data->status, handle,
1102 p_data->p_cmpl->att_value.len, p_data->p_cmpl->att_value.value,
1103 my_cb_data);
1104 }
1105 }
1106 /*******************************************************************************
1107 *
1108 * Function bta_gattc_write_cmpl
1109 *
1110 * Description write complete
1111 *
1112 * Returns None.
1113 *
1114 ******************************************************************************/
bta_gattc_write_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1115 void bta_gattc_write_cmpl(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_OP_CMPL* p_data) {
1116 GATT_WRITE_OP_CB cb = p_clcb->p_q_cmd->api_write.write_cb;
1117 void* my_cb_data = p_clcb->p_q_cmd->api_write.write_cb_data;
1118
1119 osi_free_and_reset((void**)&p_clcb->p_q_cmd);
1120
1121 if (cb) {
1122 cb(p_clcb->bta_conn_id, p_data->status, p_data->p_cmpl->att_value.handle,
1123 my_cb_data);
1124 }
1125 }
1126 /*******************************************************************************
1127 *
1128 * Function bta_gattc_exec_cmpl
1129 *
1130 * Description execute write complete
1131 *
1132 * Returns None.
1133 *
1134 ******************************************************************************/
bta_gattc_exec_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1135 void bta_gattc_exec_cmpl(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_OP_CMPL* p_data) {
1136 tBTA_GATTC cb_data;
1137
1138 osi_free_and_reset((void**)&p_clcb->p_q_cmd);
1139 p_clcb->status = BTA_GATT_OK;
1140
1141 /* execute complete, callback */
1142 cb_data.exec_cmpl.conn_id = p_clcb->bta_conn_id;
1143 cb_data.exec_cmpl.status = p_data->status;
1144
1145 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_EXEC_EVT, &cb_data);
1146 }
1147
1148 /*******************************************************************************
1149 *
1150 * Function bta_gattc_cfg_mtu_cmpl
1151 *
1152 * Description configure MTU operation complete
1153 *
1154 * Returns None.
1155 *
1156 ******************************************************************************/
bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_OP_CMPL * p_data)1157 void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB* p_clcb,
1158 tBTA_GATTC_OP_CMPL* p_data) {
1159 tBTA_GATTC cb_data;
1160
1161 osi_free_and_reset((void**)&p_clcb->p_q_cmd);
1162
1163 if (p_data->p_cmpl && p_data->status == BTA_GATT_OK)
1164 p_clcb->p_srcb->mtu = p_data->p_cmpl->mtu;
1165
1166 /* configure MTU complete, callback */
1167 p_clcb->status = p_data->status;
1168 cb_data.cfg_mtu.conn_id = p_clcb->bta_conn_id;
1169 cb_data.cfg_mtu.status = p_data->status;
1170 cb_data.cfg_mtu.mtu = p_clcb->p_srcb->mtu;
1171
1172 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CFG_MTU_EVT, &cb_data);
1173 }
1174 /*******************************************************************************
1175 *
1176 * Function bta_gattc_op_cmpl
1177 *
1178 * Description operation completed.
1179 *
1180 * Returns None.
1181 *
1182 ******************************************************************************/
bta_gattc_op_cmpl(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1183 void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
1184 uint8_t op = (uint8_t)p_data->op_cmpl.op_code;
1185 uint8_t mapped_op = 0;
1186
1187 APPL_TRACE_DEBUG("bta_gattc_op_cmpl op = %d", op);
1188
1189 if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION) {
1190 APPL_TRACE_ERROR("unexpected operation, ignored");
1191 } else if (op >= GATTC_OPTYPE_READ) {
1192 if (p_clcb->p_q_cmd == NULL) {
1193 APPL_TRACE_ERROR("No pending command");
1194 return;
1195 }
1196 if (p_clcb->p_q_cmd->hdr.event !=
1197 bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) {
1198 mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT +
1199 GATTC_OPTYPE_READ;
1200 if (mapped_op > GATTC_OPTYPE_INDICATION) mapped_op = 0;
1201
1202 APPL_TRACE_ERROR(
1203 "expect op:(%s :0x%04x), receive unexpected operation (%s).",
1204 bta_gattc_op_code_name[mapped_op], p_clcb->p_q_cmd->hdr.event,
1205 bta_gattc_op_code_name[op]);
1206 return;
1207 }
1208
1209 /* Except for MTU configuration, discard responses if service change
1210 * indication is received before operation completed */
1211 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING &&
1212 p_clcb->p_srcb->srvc_hdl_chg && op != GATTC_OPTYPE_CONFIG) {
1213 APPL_TRACE_DEBUG(
1214 "Discard all responses when service change indication is received.");
1215 p_data->op_cmpl.status = GATT_ERROR;
1216 }
1217
1218 /* service handle change void the response, discard it */
1219 if (op == GATTC_OPTYPE_READ)
1220 bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
1221
1222 else if (op == GATTC_OPTYPE_WRITE)
1223 bta_gattc_write_cmpl(p_clcb, &p_data->op_cmpl);
1224
1225 else if (op == GATTC_OPTYPE_EXE_WRITE)
1226 bta_gattc_exec_cmpl(p_clcb, &p_data->op_cmpl);
1227
1228 else if (op == GATTC_OPTYPE_CONFIG)
1229 bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);
1230
1231 if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
1232 p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
1233 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1234 }
1235 }
1236 }
1237 /*******************************************************************************
1238 *
1239 * Function bta_gattc_op_cmpl
1240 *
1241 * Description operation completed.
1242 *
1243 * Returns None.
1244 *
1245 ******************************************************************************/
bta_gattc_ignore_op_cmpl(UNUSED_ATTR tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1246 void bta_gattc_ignore_op_cmpl(UNUSED_ATTR tBTA_GATTC_CLCB* p_clcb,
1247 tBTA_GATTC_DATA* p_data) {
1248 /* receive op complete when discovery is started, ignore the response,
1249 and wait for discovery finish and resent */
1250 APPL_TRACE_DEBUG("bta_gattc_ignore_op_cmpl op = %d",
1251 p_data->hdr.layer_specific);
1252 }
1253 /*******************************************************************************
1254 *
1255 * Function bta_gattc_search
1256 *
1257 * Description start a search in the local server cache
1258 *
1259 * Returns None.
1260 *
1261 ******************************************************************************/
bta_gattc_search(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1262 void bta_gattc_search(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
1263 tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR;
1264 tBTA_GATTC cb_data;
1265 APPL_TRACE_DEBUG("bta_gattc_search conn_id=%d", p_clcb->bta_conn_id);
1266 if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
1267 status = BTA_GATT_OK;
1268 /* search the local cache of a server device */
1269 bta_gattc_search_service(p_clcb, p_data->api_search.p_srvc_uuid);
1270 }
1271 cb_data.search_cmpl.status = status;
1272 cb_data.search_cmpl.conn_id = p_clcb->bta_conn_id;
1273
1274 /* end of search or no server cache available */
1275 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_CMPL_EVT, &cb_data);
1276 }
1277 /*******************************************************************************
1278 *
1279 * Function bta_gattc_q_cmd
1280 *
1281 * Description enqueue a command into control block, usually because
1282 * discovery operation is busy.
1283 *
1284 * Returns None.
1285 *
1286 ******************************************************************************/
bta_gattc_q_cmd(tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_DATA * p_data)1287 void bta_gattc_q_cmd(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
1288 bta_gattc_enqueue(p_clcb, p_data);
1289 }
1290
1291 /*******************************************************************************
1292 *
1293 * Function bta_gattc_fail
1294 *
1295 * Description report API call failure back to apps
1296 *
1297 * Returns None.
1298 *
1299 ******************************************************************************/
bta_gattc_fail(tBTA_GATTC_CLCB * p_clcb,UNUSED_ATTR tBTA_GATTC_DATA * p_data)1300 void bta_gattc_fail(tBTA_GATTC_CLCB* p_clcb,
1301 UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
1302 if (p_clcb->status == BTA_GATT_OK) {
1303 APPL_TRACE_ERROR("operation not supported at current state [%d]",
1304 p_clcb->state);
1305 }
1306 }
1307
1308 /*******************************************************************************
1309 *
1310 * Function bta_gattc_deregister_cmpl
1311 *
1312 * Description De-Register a GATT client application with BTA completed.
1313 *
1314 * Returns void
1315 *
1316 ******************************************************************************/
bta_gattc_deregister_cmpl(tBTA_GATTC_RCB * p_clreg)1317 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB* p_clreg) {
1318 tBTA_GATTC_IF client_if = p_clreg->client_if;
1319 tBTA_GATTC cb_data;
1320 tBTA_GATTC_CBACK* p_cback = p_clreg->p_cback;
1321
1322 memset(&cb_data, 0, sizeof(tBTA_GATTC));
1323
1324 GATT_Deregister(p_clreg->client_if);
1325 memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
1326
1327 cb_data.reg_oper.client_if = client_if;
1328 cb_data.reg_oper.status = BTA_GATT_OK;
1329
1330 if (p_cback) /* callback with de-register event */
1331 (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC*)&cb_data);
1332
1333 if (bta_gattc_num_reg_app() == 0 &&
1334 bta_gattc_cb.state == BTA_GATTC_STATE_DISABLING) {
1335 bta_gattc_cb.state = BTA_GATTC_STATE_DISABLED;
1336 }
1337 }
1338 /*******************************************************************************
1339 *
1340 * Function bta_gattc_conn_cback
1341 *
1342 * Description callback functions to GATT client stack.
1343 *
1344 * Returns void
1345 *
1346 ******************************************************************************/
bta_gattc_conn_cback(tGATT_IF gattc_if,BD_ADDR bda,uint16_t conn_id,bool connected,tGATT_DISCONN_REASON reason,tBT_TRANSPORT transport)1347 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda,
1348 uint16_t conn_id, bool connected,
1349 tGATT_DISCONN_REASON reason,
1350 tBT_TRANSPORT transport) {
1351 if (reason != 0) {
1352 APPL_TRACE_WARNING("%s() - cif=%d connected=%d conn_id=%d reason=0x%04x",
1353 __func__, gattc_if, connected, conn_id, reason);
1354 }
1355
1356 bt_bdaddr_t bdaddr;
1357 bdcpy(bdaddr.address, bda);
1358 if (connected)
1359 btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
1360 else
1361 btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason);
1362
1363 tBTA_GATTC_DATA* p_buf =
1364 (tBTA_GATTC_DATA*)osi_calloc(sizeof(tBTA_GATTC_DATA));
1365 p_buf->int_conn.hdr.event =
1366 connected ? BTA_GATTC_INT_CONN_EVT : BTA_GATTC_INT_DISCONN_EVT;
1367 p_buf->int_conn.hdr.layer_specific = conn_id;
1368 p_buf->int_conn.client_if = gattc_if;
1369 p_buf->int_conn.role = L2CA_GetBleConnRole(bda);
1370 p_buf->int_conn.reason = reason;
1371 p_buf->int_conn.transport = transport;
1372 bdcpy(p_buf->int_conn.remote_bda, bda);
1373
1374 bta_sys_sendmsg(p_buf);
1375 }
1376
1377 /*******************************************************************************
1378 *
1379 * Function bta_gattc_enc_cmpl_cback
1380 *
1381 * Description encryption complete callback function to GATT client stack.
1382 *
1383 * Returns void
1384 *
1385 ******************************************************************************/
bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if,BD_ADDR bda)1386 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda) {
1387 tBTA_GATTC_CLCB* p_clcb =
1388 bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE);
1389
1390 if (p_clcb == NULL) return;
1391
1392 #if (BTA_HH_LE_INCLUDED == TRUE)
1393 /* filter this event just for BTA HH LE GATT client,
1394 In the future, if we want to enable encryption complete event
1395 for all GATT clients, we can remove this code */
1396 if (!bta_hh_le_is_hh_gatt_if(gattc_if)) {
1397 return;
1398 }
1399 #endif
1400
1401 APPL_TRACE_DEBUG("%s: cif = %d", __func__, gattc_if);
1402
1403 tBTA_GATTC_DATA* p_buf =
1404 (tBTA_GATTC_DATA*)osi_calloc(sizeof(tBTA_GATTC_DATA));
1405 p_buf->enc_cmpl.hdr.event = BTA_GATTC_ENC_CMPL_EVT;
1406 p_buf->enc_cmpl.hdr.layer_specific = p_clcb->bta_conn_id;
1407 p_buf->enc_cmpl.client_if = gattc_if;
1408 bdcpy(p_buf->enc_cmpl.remote_bda, bda);
1409
1410 bta_sys_sendmsg(p_buf);
1411 }
1412
1413 /*******************************************************************************
1414 *
1415 * Function bta_gattc_process_api_refresh
1416 *
1417 * Description process refresh API to delete cache and start a new
1418 * discovery if currently connected.
1419 *
1420 * Returns None.
1421 *
1422 ******************************************************************************/
bta_gattc_process_api_refresh(tBTA_GATTC_DATA * p_msg)1423 void bta_gattc_process_api_refresh(tBTA_GATTC_DATA* p_msg) {
1424 tBTA_GATTC_SERV* p_srvc_cb =
1425 bta_gattc_find_srvr_cache(p_msg->api_conn.remote_bda);
1426 tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
1427 bool found = false;
1428 uint8_t i;
1429
1430 if (p_srvc_cb != NULL) {
1431 /* try to find a CLCB */
1432 if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) {
1433 for (i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
1434 if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) {
1435 found = true;
1436 break;
1437 }
1438 }
1439 if (found) {
1440 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1441 return;
1442 }
1443 }
1444 /* in all other cases, mark it and delete the cache */
1445 if (p_srvc_cb->p_srvc_cache != NULL) {
1446 list_free(p_srvc_cb->p_srvc_cache);
1447 p_srvc_cb->p_srvc_cache = NULL;
1448 }
1449 }
1450 /* used to reset cache in application */
1451 bta_gattc_cache_reset(p_msg->api_conn.remote_bda);
1452 }
1453 /*******************************************************************************
1454 *
1455 * Function bta_gattc_process_srvc_chg_ind
1456 *
1457 * Description process service change indication.
1458 *
1459 * Returns None.
1460 *
1461 ******************************************************************************/
bta_gattc_process_srvc_chg_ind(uint16_t conn_id,tBTA_GATTC_RCB * p_clrcb,tBTA_GATTC_SERV * p_srcb,tBTA_GATTC_CLCB * p_clcb,tBTA_GATTC_NOTIFY * p_notify,tGATT_VALUE * att_value)1462 bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, tBTA_GATTC_RCB* p_clrcb,
1463 tBTA_GATTC_SERV* p_srcb,
1464 tBTA_GATTC_CLCB* p_clcb,
1465 tBTA_GATTC_NOTIFY* p_notify,
1466 tGATT_VALUE* att_value) {
1467 tBT_UUID gattp_uuid, srvc_chg_uuid;
1468 bool processed = false;
1469 uint8_t i;
1470
1471 gattp_uuid.len = 2;
1472 gattp_uuid.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER;
1473
1474 srvc_chg_uuid.len = 2;
1475 srvc_chg_uuid.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
1476
1477 const tBTA_GATTC_CHARACTERISTIC* p_char =
1478 bta_gattc_get_characteristic_srcb(p_srcb, p_notify->handle);
1479 if (p_char &&
1480 bta_gattc_uuid_compare(&p_char->service->uuid, &gattp_uuid, true) &&
1481 bta_gattc_uuid_compare(&p_char->uuid, &srvc_chg_uuid, true)) {
1482 if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) {
1483 APPL_TRACE_ERROR(
1484 "%s: received malformed service changed indication, skipping",
1485 __func__);
1486 return false;
1487 }
1488
1489 uint8_t* p = att_value->value;
1490 uint16_t s_handle = ((uint16_t)(*(p)) + (((uint16_t)(*(p + 1))) << 8));
1491 uint16_t e_handle = ((uint16_t)(*(p + 2)) + (((uint16_t)(*(p + 3))) << 8));
1492
1493 APPL_TRACE_ERROR("%s: service changed s_handle:0x%04x e_handle:0x%04x",
1494 __func__, s_handle, e_handle);
1495
1496 processed = true;
1497 /* mark service handle change pending */
1498 p_srcb->srvc_hdl_chg = true;
1499 /* clear up all notification/indication registration */
1500 bta_gattc_clear_notif_registration(p_srcb, conn_id, s_handle, e_handle);
1501 /* service change indication all received, do discovery update */
1502 if (++p_srcb->update_count == bta_gattc_num_reg_app()) {
1503 /* not an opened connection; or connection busy */
1504 /* search for first available clcb and start discovery */
1505 if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) {
1506 for (i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
1507 if (bta_gattc_cb.clcb[i].in_use &&
1508 bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
1509 bta_gattc_cb.clcb[i].p_q_cmd == NULL) {
1510 p_clcb = &bta_gattc_cb.clcb[i];
1511 break;
1512 }
1513 }
1514 }
1515 /* send confirmation here if this is an indication, it should always be */
1516 GATTC_SendHandleValueConfirm(conn_id, att_value->handle);
1517
1518 /* if connection available, refresh cache by doing discovery now */
1519 if (p_clcb != NULL)
1520 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
1521 }
1522 /* notify applicationf or service change */
1523 if (p_clrcb->p_cback != NULL) {
1524 (*p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT,
1525 (tBTA_GATTC*)p_srcb->server_bda);
1526 }
1527 }
1528
1529 return processed;
1530 }
1531 /*******************************************************************************
1532 *
1533 * Function bta_gattc_proc_other_indication
1534 *
1535 * Description process all non-service change indication/notification.
1536 *
1537 * Returns None.
1538 *
1539 ******************************************************************************/
bta_gattc_proc_other_indication(tBTA_GATTC_CLCB * p_clcb,uint8_t op,tGATT_CL_COMPLETE * p_data,tBTA_GATTC_NOTIFY * p_notify)1540 void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB* p_clcb, uint8_t op,
1541 tGATT_CL_COMPLETE* p_data,
1542 tBTA_GATTC_NOTIFY* p_notify) {
1543 APPL_TRACE_DEBUG(
1544 "bta_gattc_proc_other_indication check \
1545 p_data->att_value.handle=%d p_data->handle=%d",
1546 p_data->att_value.handle, p_data->handle);
1547 APPL_TRACE_DEBUG("is_notify", p_notify->is_notify);
1548
1549 p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? false : true;
1550 p_notify->len = p_data->att_value.len;
1551 bdcpy(p_notify->bda, p_clcb->bda);
1552 memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
1553 p_notify->conn_id = p_clcb->bta_conn_id;
1554
1555 if (p_clcb->p_rcb->p_cback)
1556 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)p_notify);
1557 }
1558 /*******************************************************************************
1559 *
1560 * Function bta_gattc_process_indicate
1561 *
1562 * Description process indication/notification.
1563 *
1564 * Returns None.
1565 *
1566 ******************************************************************************/
bta_gattc_process_indicate(uint16_t conn_id,tGATTC_OPTYPE op,tGATT_CL_COMPLETE * p_data)1567 void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op,
1568 tGATT_CL_COMPLETE* p_data) {
1569 uint16_t handle = p_data->att_value.handle;
1570 tBTA_GATTC_CLCB* p_clcb;
1571 tBTA_GATTC_RCB* p_clrcb = NULL;
1572 tBTA_GATTC_SERV* p_srcb = NULL;
1573 tBTA_GATTC_NOTIFY notify;
1574 BD_ADDR remote_bda;
1575 tBTA_GATTC_IF gatt_if;
1576 tBTA_TRANSPORT transport;
1577
1578 if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
1579 APPL_TRACE_ERROR("%s indication/notif for unknown app", __func__);
1580 if (op == GATTC_OPTYPE_INDICATION)
1581 GATTC_SendHandleValueConfirm(conn_id, handle);
1582 return;
1583 }
1584
1585 p_clrcb = bta_gattc_cl_get_regcb(gatt_if);
1586 if (p_clrcb == NULL) {
1587 APPL_TRACE_ERROR("%s indication/notif for unregistered app", __func__);
1588 if (op == GATTC_OPTYPE_INDICATION)
1589 GATTC_SendHandleValueConfirm(conn_id, handle);
1590 return;
1591 }
1592
1593 p_srcb = bta_gattc_find_srcb(remote_bda);
1594 if (p_srcb == NULL) {
1595 APPL_TRACE_ERROR("%s indication/notif for unknown device, ignore",
1596 __func__);
1597 if (op == GATTC_OPTYPE_INDICATION)
1598 GATTC_SendHandleValueConfirm(conn_id, handle);
1599 return;
1600 }
1601
1602 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
1603
1604 notify.handle = handle;
1605 /* if non-service change indication/notification, forward to application */
1606 if (!bta_gattc_process_srvc_chg_ind(conn_id, p_clrcb, p_srcb, p_clcb, ¬ify,
1607 &p_data->att_value)) {
1608 /* if app registered for the notification */
1609 if (bta_gattc_check_notif_registry(p_clrcb, p_srcb, ¬ify)) {
1610 /* connection not open yet */
1611 if (p_clcb == NULL) {
1612 p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport);
1613
1614 if (p_clcb == NULL) {
1615 APPL_TRACE_ERROR("No resources");
1616 return;
1617 }
1618
1619 p_clcb->bta_conn_id = conn_id;
1620 p_clcb->transport = transport;
1621
1622 bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
1623 }
1624
1625 if (p_clcb != NULL)
1626 bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify);
1627 }
1628 /* no one intersted and need ack? */
1629 else if (op == GATTC_OPTYPE_INDICATION) {
1630 APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
1631 GATTC_SendHandleValueConfirm(conn_id, handle);
1632 }
1633 }
1634 }
1635 /*******************************************************************************
1636 *
1637 * Function bta_gattc_cmpl_cback
1638 *
1639 * Description client operation complete callback register with BTE GATT.
1640 *
1641 * Returns None.
1642 *
1643 ******************************************************************************/
bta_gattc_cmpl_cback(uint16_t conn_id,tGATTC_OPTYPE op,tGATT_STATUS status,tGATT_CL_COMPLETE * p_data)1644 static void bta_gattc_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op,
1645 tGATT_STATUS status,
1646 tGATT_CL_COMPLETE* p_data) {
1647 tBTA_GATTC_CLCB* p_clcb;
1648 APPL_TRACE_DEBUG("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
1649 conn_id, op, status);
1650
1651 /* notification and indication processed right away */
1652 if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION) {
1653 bta_gattc_process_indicate(conn_id, op, p_data);
1654 return;
1655 }
1656 /* for all other operation, not expected if w/o connection */
1657 else {
1658 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
1659 if (p_clcb == NULL) {
1660 APPL_TRACE_ERROR(
1661 "bta_gattc_cmpl_cback unknown conn_id = %d, ignore data", conn_id);
1662 return;
1663 }
1664 }
1665
1666 /* if over BR_EDR, inform PM for mode change */
1667 if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
1668 bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1669 bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
1670 }
1671
1672 bta_gattc_cmpl_sendmsg(conn_id, op, status, p_data);
1673 }
1674
1675 /*******************************************************************************
1676 *
1677 * Function bta_gattc_cmpl_sendmsg
1678 *
1679 * Description client operation complete send message
1680 *
1681 * Returns None.
1682 *
1683 ******************************************************************************/
bta_gattc_cmpl_sendmsg(uint16_t conn_id,tGATTC_OPTYPE op,tBTA_GATT_STATUS status,tGATT_CL_COMPLETE * p_data)1684 static void bta_gattc_cmpl_sendmsg(uint16_t conn_id, tGATTC_OPTYPE op,
1685 tBTA_GATT_STATUS status,
1686 tGATT_CL_COMPLETE* p_data) {
1687 const size_t len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
1688 tBTA_GATTC_OP_CMPL* p_buf = (tBTA_GATTC_OP_CMPL*)osi_calloc(len);
1689
1690 p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
1691 p_buf->hdr.layer_specific = conn_id;
1692 p_buf->status = status;
1693 p_buf->op_code = op;
1694
1695 if (p_data != NULL) {
1696 p_buf->p_cmpl = (tGATT_CL_COMPLETE*)(p_buf + 1);
1697 memcpy(p_buf->p_cmpl, p_data, sizeof(tGATT_CL_COMPLETE));
1698 }
1699
1700 bta_sys_sendmsg(p_buf);
1701 }
1702
1703 /*******************************************************************************
1704 *
1705 * Function bta_gattc_cong_cback
1706 *
1707 * Description congestion callback for BTA GATT client.
1708 *
1709 * Returns void
1710 *
1711 ******************************************************************************/
bta_gattc_cong_cback(uint16_t conn_id,bool congested)1712 static void bta_gattc_cong_cback(uint16_t conn_id, bool congested) {
1713 tBTA_GATTC_CLCB* p_clcb;
1714 tBTA_GATTC cb_data;
1715
1716 p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
1717 if (p_clcb != NULL) {
1718 if (p_clcb->p_rcb->p_cback) {
1719 cb_data.congest.conn_id = conn_id;
1720 cb_data.congest.congested = congested;
1721
1722 (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CONGEST_EVT, &cb_data);
1723 }
1724 }
1725 }
1726
bta_gattc_phy_update_cback(tGATT_IF gatt_if,uint16_t conn_id,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)1727 static void bta_gattc_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
1728 uint8_t tx_phy, uint8_t rx_phy,
1729 uint8_t status) {
1730 tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(gatt_if);
1731
1732 if (!p_clreg || !p_clreg->p_cback) {
1733 APPL_TRACE_ERROR("%s: client_if=%d not found", __func__, gatt_if);
1734 return;
1735 }
1736
1737 tBTA_GATTC cb_data;
1738 cb_data.phy_update.conn_id = conn_id;
1739 cb_data.phy_update.server_if = gatt_if;
1740 cb_data.phy_update.tx_phy = tx_phy;
1741 cb_data.phy_update.rx_phy = rx_phy;
1742 cb_data.phy_update.status = status;
1743 (*p_clreg->p_cback)(BTA_GATTC_PHY_UPDATE_EVT, &cb_data);
1744 }
1745
bta_gattc_conn_update_cback(tGATT_IF gatt_if,uint16_t conn_id,uint16_t interval,uint16_t latency,uint16_t timeout,uint8_t status)1746 static void bta_gattc_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
1747 uint16_t interval, uint16_t latency,
1748 uint16_t timeout, uint8_t status) {
1749 tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(gatt_if);
1750
1751 if (!p_clreg || !p_clreg->p_cback) {
1752 APPL_TRACE_ERROR("%s: client_if=%d not found", __func__, gatt_if);
1753 return;
1754 }
1755
1756 tBTA_GATTC cb_data;
1757 cb_data.conn_update.conn_id = conn_id;
1758 cb_data.conn_update.interval = interval;
1759 cb_data.conn_update.latency = latency;
1760 cb_data.conn_update.timeout = timeout;
1761 cb_data.conn_update.status = status;
1762 (*p_clreg->p_cback)(BTA_GATTC_CONN_UPDATE_EVT, &cb_data);
1763 }
1764