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