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