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