1/******************************************************************************
2 *
3 *  Copyright (C) 2008-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 main ATT functions
22 *
23 ******************************************************************************/
24
25#include "bt_target.h"
26
27#include "bt_common.h"
28#include "bt_utils.h"
29#include "btif_storage.h"
30#include "btm_ble_int.h"
31#include "btm_int.h"
32#include "device/include/interop.h"
33#include "gatt_int.h"
34#include "l2c_api.h"
35#include "osi/include/osi.h"
36
37/* Configuration flags. */
38#define GATT_L2C_CFG_IND_DONE (1 << 0)
39#define GATT_L2C_CFG_CFM_DONE (1 << 1)
40
41/* minimum GATT MTU size over BR/EDR link
42*/
43#define GATT_MIN_BR_MTU_SIZE 48
44
45/******************************************************************************/
46/*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
47/******************************************************************************/
48static void gatt_le_connect_cback(uint16_t chan, BD_ADDR bd_addr,
49                                  bool connected, uint16_t reason,
50                                  tBT_TRANSPORT transport);
51static void gatt_le_data_ind(uint16_t chan, BD_ADDR bd_addr, BT_HDR* p_buf);
52static void gatt_le_cong_cback(BD_ADDR remote_bda, bool congest);
53
54static void gatt_l2cif_connect_ind_cback(BD_ADDR bd_addr, uint16_t l2cap_cid,
55                                         uint16_t psm, uint8_t l2cap_id);
56static void gatt_l2cif_connect_cfm_cback(uint16_t l2cap_cid, uint16_t result);
57static void gatt_l2cif_config_ind_cback(uint16_t l2cap_cid,
58                                        tL2CAP_CFG_INFO* p_cfg);
59static void gatt_l2cif_config_cfm_cback(uint16_t l2cap_cid,
60                                        tL2CAP_CFG_INFO* p_cfg);
61static void gatt_l2cif_disconnect_ind_cback(uint16_t l2cap_cid,
62                                            bool ack_needed);
63static void gatt_l2cif_disconnect_cfm_cback(uint16_t l2cap_cid,
64                                            uint16_t result);
65static void gatt_l2cif_data_ind_cback(uint16_t l2cap_cid, BT_HDR* p_msg);
66static void gatt_send_conn_cback(tGATT_TCB* p_tcb);
67static void gatt_l2cif_congest_cback(uint16_t cid, bool congested);
68
69static const tL2CAP_APPL_INFO dyn_info = {gatt_l2cif_connect_ind_cback,
70                                          gatt_l2cif_connect_cfm_cback,
71                                          NULL,
72                                          gatt_l2cif_config_ind_cback,
73                                          gatt_l2cif_config_cfm_cback,
74                                          gatt_l2cif_disconnect_ind_cback,
75                                          gatt_l2cif_disconnect_cfm_cback,
76                                          NULL,
77                                          gatt_l2cif_data_ind_cback,
78                                          gatt_l2cif_congest_cback,
79                                          NULL};
80
81tGATT_CB gatt_cb;
82
83/*******************************************************************************
84 *
85 * Function         gatt_init
86 *
87 * Description      This function is enable the GATT profile on the device.
88 *                  It clears out the control blocks, and registers with L2CAP.
89 *
90 * Returns          void
91 *
92 ******************************************************************************/
93void gatt_init(void) {
94  tL2CAP_FIXED_CHNL_REG fixed_reg;
95
96  GATT_TRACE_DEBUG("gatt_init()");
97
98  memset(&gatt_cb, 0, sizeof(tGATT_CB));
99  memset(&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG));
100
101#if defined(GATT_INITIAL_TRACE_LEVEL)
102  gatt_cb.trace_level = GATT_INITIAL_TRACE_LEVEL;
103#else
104  gatt_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
105#endif
106  gatt_cb.def_mtu_size = GATT_DEF_BLE_MTU_SIZE;
107  gatt_cb.sign_op_queue = fixed_queue_new(SIZE_MAX);
108  gatt_cb.srv_chg_clt_q = fixed_queue_new(SIZE_MAX);
109  /* First, register fixed L2CAP channel for ATT over BLE */
110  fixed_reg.fixed_chnl_opts.mode = L2CAP_FCR_BASIC_MODE;
111  fixed_reg.fixed_chnl_opts.max_transmit = 0xFF;
112  fixed_reg.fixed_chnl_opts.rtrans_tout = 2000;
113  fixed_reg.fixed_chnl_opts.mon_tout = 12000;
114  fixed_reg.fixed_chnl_opts.mps = 670;
115  fixed_reg.fixed_chnl_opts.tx_win_sz = 1;
116
117  fixed_reg.pL2CA_FixedConn_Cb = gatt_le_connect_cback;
118  fixed_reg.pL2CA_FixedData_Cb = gatt_le_data_ind;
119  fixed_reg.pL2CA_FixedCong_Cb = gatt_le_cong_cback; /* congestion callback */
120  fixed_reg.default_idle_tout = 0xffff; /* 0xffff default idle timeout */
121
122  L2CA_RegisterFixedChannel(L2CAP_ATT_CID, &fixed_reg);
123
124  /* Now, register with L2CAP for ATT PSM over BR/EDR */
125  if (!L2CA_Register(BT_PSM_ATT, (tL2CAP_APPL_INFO*)&dyn_info)) {
126    GATT_TRACE_ERROR("ATT Dynamic Registration failed");
127  }
128
129  BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT,
130                       0, 0);
131  BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT,
132                       0, 0);
133
134  gatt_cb.hdl_cfg.gatt_start_hdl = GATT_GATT_START_HANDLE;
135  gatt_cb.hdl_cfg.gap_start_hdl = GATT_GAP_START_HANDLE;
136  gatt_cb.hdl_cfg.app_start_hdl = GATT_APP_START_HANDLE;
137
138  gatt_cb.hdl_list_info = new std::list<tGATT_HDL_LIST_ELEM>();
139  gatt_cb.srv_list_info = new std::list<tGATT_SRV_LIST_ELEM>();
140  gatt_profile_db_init();
141}
142
143/*******************************************************************************
144 *
145 * Function         gatt_free
146 *
147 * Description      This function frees resources used by the GATT profile.
148 *
149 * Returns          void
150 *
151 ******************************************************************************/
152void gatt_free(void) {
153  int i;
154  GATT_TRACE_DEBUG("gatt_free()");
155
156  fixed_queue_free(gatt_cb.sign_op_queue, NULL);
157  gatt_cb.sign_op_queue = NULL;
158  fixed_queue_free(gatt_cb.srv_chg_clt_q, NULL);
159  gatt_cb.srv_chg_clt_q = NULL;
160  for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
161    fixed_queue_free(gatt_cb.tcb[i].pending_enc_clcb, NULL);
162    gatt_cb.tcb[i].pending_enc_clcb = NULL;
163
164    fixed_queue_free(gatt_cb.tcb[i].pending_ind_q, NULL);
165    gatt_cb.tcb[i].pending_ind_q = NULL;
166
167    alarm_free(gatt_cb.tcb[i].conf_timer);
168    gatt_cb.tcb[i].conf_timer = NULL;
169
170    alarm_free(gatt_cb.tcb[i].ind_ack_timer);
171    gatt_cb.tcb[i].ind_ack_timer = NULL;
172
173    fixed_queue_free(gatt_cb.tcb[i].sr_cmd.multi_rsp_q, NULL);
174    gatt_cb.tcb[i].sr_cmd.multi_rsp_q = NULL;
175  }
176
177  gatt_cb.hdl_list_info->clear();
178  gatt_cb.hdl_list_info = nullptr;
179  gatt_cb.srv_list_info->clear();
180  gatt_cb.srv_list_info = nullptr;
181}
182
183/*******************************************************************************
184 *
185 * Function         gatt_connect
186 *
187 * Description      This function is called to initiate a connection to a peer
188 *                  device.
189 *
190 * Parameter        rem_bda: remote device address to connect to.
191 *
192 * Returns          true if connection is started, otherwise return false.
193 *
194 ******************************************************************************/
195bool gatt_connect(BD_ADDR rem_bda, tGATT_TCB* p_tcb, tBT_TRANSPORT transport,
196                  uint8_t initiating_phys) {
197  bool gatt_ret = false;
198
199  if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN)
200    gatt_set_ch_state(p_tcb, GATT_CH_CONN);
201
202  if (transport == BT_TRANSPORT_LE) {
203    p_tcb->att_lcid = L2CAP_ATT_CID;
204    gatt_ret = L2CA_ConnectFixedChnl(L2CAP_ATT_CID, rem_bda, initiating_phys);
205  } else {
206    p_tcb->att_lcid = L2CA_ConnectReq(BT_PSM_ATT, rem_bda);
207    if (p_tcb->att_lcid != 0) gatt_ret = true;
208  }
209
210  return gatt_ret;
211}
212
213/*******************************************************************************
214 *
215 * Function         gatt_disconnect
216 *
217 * Description      This function is called to disconnect to an ATT device.
218 *
219 * Parameter        p_tcb: pointer to the TCB to disconnect.
220 *
221 * Returns          true: if connection found and to be disconnected; otherwise
222 *                  return false.
223 *
224 ******************************************************************************/
225bool gatt_disconnect(tGATT_TCB* p_tcb) {
226  bool ret = false;
227  tGATT_CH_STATE ch_state;
228
229  GATT_TRACE_EVENT("%s", __func__);
230
231  if (p_tcb != NULL) {
232    ret = true;
233    ch_state = gatt_get_ch_state(p_tcb);
234    if (ch_state != GATT_CH_CLOSING) {
235      if (p_tcb->att_lcid == L2CAP_ATT_CID) {
236        if (ch_state == GATT_CH_OPEN) {
237          /* only LCB exist between remote device and local */
238          ret = L2CA_RemoveFixedChnl(L2CAP_ATT_CID, p_tcb->peer_bda);
239        } else {
240          ret = L2CA_CancelBleConnectReq(p_tcb->peer_bda);
241          if (!ret) gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
242        }
243        gatt_set_ch_state(p_tcb, GATT_CH_CLOSING);
244      } else {
245        if ((ch_state == GATT_CH_OPEN) || (ch_state == GATT_CH_CFG))
246          ret = L2CA_DisconnectReq(p_tcb->att_lcid);
247        else
248          GATT_TRACE_DEBUG("%s gatt_disconnect channel not opened", __func__);
249      }
250    } else {
251      GATT_TRACE_DEBUG("%s already in closing state", __func__);
252    }
253  }
254
255  return ret;
256}
257
258/*******************************************************************************
259 *
260 * Function         gatt_update_app_hold_link_status
261 *
262 * Description      Update the application use link status
263 *
264 * Returns          true if any modifications are made or
265 *                  when it already exists, false otherwise.
266 *
267 ******************************************************************************/
268bool gatt_update_app_hold_link_status(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
269                                      bool is_add) {
270  for (int i = 0; i < GATT_MAX_APPS; i++) {
271    if (p_tcb->app_hold_link[i] == gatt_if && is_add) {
272      GATT_TRACE_DEBUG("%s: gatt_if %d already exists at idx %d", __func__,
273                       gatt_if, i);
274      return true;
275    }
276  }
277
278  for (int i = 0; i < GATT_MAX_APPS; i++) {
279    if (p_tcb->app_hold_link[i] == 0 && is_add) {
280      p_tcb->app_hold_link[i] = gatt_if;
281      GATT_TRACE_DEBUG("%s: added gatt_if=%d idx=%d ", __func__, gatt_if, i);
282      return true;
283    } else if (p_tcb->app_hold_link[i] == gatt_if && !is_add) {
284      p_tcb->app_hold_link[i] = 0;
285      GATT_TRACE_DEBUG("%s: removed gatt_if=%d idx=%d", __func__, gatt_if, i);
286      return true;
287    }
288  }
289
290  GATT_TRACE_DEBUG("%s: gatt_if=%d not found; is_add=%d", __func__, gatt_if,
291                   is_add);
292  return false;
293}
294
295/*******************************************************************************
296 *
297 * Function         gatt_update_app_use_link_flag
298 *
299 * Description      Update the application use link flag and optional to check
300 *                  the acl link if the link is up then set the idle time out
301 *                  accordingly
302 *
303 * Returns          void.
304 *
305 ******************************************************************************/
306void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
307                                   bool is_add, bool check_acl_link) {
308  GATT_TRACE_DEBUG("%s: is_add=%d chk_link=%d", __func__, is_add,
309                   check_acl_link);
310
311  if (!p_tcb) return;
312
313  // If we make no modification, i.e. kill app that was never connected to a
314  // device, skip updating the device state.
315  if (!gatt_update_app_hold_link_status(gatt_if, p_tcb, is_add)) return;
316
317  if (!check_acl_link ||
318      p_tcb->att_lcid !=
319          L2CAP_ATT_CID || /* only update link idle timer for fixed channel */
320      (BTM_GetHCIConnHandle(p_tcb->peer_bda, p_tcb->transport) ==
321       GATT_INVALID_ACL_HANDLE)) {
322    return;
323  }
324
325  if (is_add) {
326    GATT_TRACE_DEBUG("%s: disable link idle timer", __func__);
327    /* acl link is connected disable the idle timeout */
328    GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT,
329                        p_tcb->transport);
330  } else {
331    if (!gatt_num_apps_hold_link(p_tcb)) {
332      /* acl link is connected but no application needs to use the link
333         so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds
334         */
335      GATT_TRACE_DEBUG("%s: start link idle timer =%d sec", __func__,
336                       GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP);
337      GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP,
338                          p_tcb->transport);
339    }
340  }
341}
342
343/*******************************************************************************
344 *
345 * Function         gatt_act_connect
346 *
347 * Description      GATT connection initiation.
348 *
349 * Returns          void.
350 *
351 ******************************************************************************/
352bool gatt_act_connect(tGATT_REG* p_reg, BD_ADDR bd_addr,
353                      tBT_TRANSPORT transport, bool opportunistic,
354                      int8_t initiating_phys) {
355  bool ret = false;
356  tGATT_TCB* p_tcb;
357  uint8_t st;
358
359  p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
360  if (p_tcb != NULL) {
361    ret = true;
362    st = gatt_get_ch_state(p_tcb);
363
364    /* before link down, another app try to open a GATT connection */
365    if (st == GATT_CH_OPEN && gatt_num_apps_hold_link(p_tcb) == 0 &&
366        transport == BT_TRANSPORT_LE) {
367      if (!gatt_connect(bd_addr, p_tcb, transport, initiating_phys))
368        ret = false;
369    } else if (st == GATT_CH_CLOSING) {
370      /* need to complete the closing first */
371      ret = false;
372    }
373  } else {
374    p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport);
375    if (p_tcb != NULL) {
376      if (!gatt_connect(bd_addr, p_tcb, transport, initiating_phys)) {
377        GATT_TRACE_ERROR("gatt_connect failed");
378        fixed_queue_free(p_tcb->pending_enc_clcb, NULL);
379        fixed_queue_free(p_tcb->pending_ind_q, NULL);
380        memset(p_tcb, 0, sizeof(tGATT_TCB));
381      } else
382        ret = true;
383    } else {
384      ret = 0;
385      GATT_TRACE_ERROR("Max TCB for gatt_if [%d] reached.", p_reg->gatt_if);
386    }
387  }
388
389  if (ret) {
390    if (!opportunistic)
391      gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, false);
392    else
393      GATT_TRACE_DEBUG(
394          "%s: connection is opportunistic, not updating app usage", __func__);
395  }
396
397  return ret;
398}
399
400/*******************************************************************************
401 *
402 * Function         gatt_le_connect_cback
403 *
404 * Description      This callback function is called by L2CAP to indicate that
405 *                  the ATT fixed channel for LE is
406 *                      connected (conn = true)/disconnected (conn = false).
407 *
408 ******************************************************************************/
409static void gatt_le_connect_cback(uint16_t chan, BD_ADDR bd_addr,
410                                  bool connected, uint16_t reason,
411                                  tBT_TRANSPORT transport) {
412  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
413  bool check_srv_chg = false;
414  tGATTS_SRV_CHG* p_srv_chg_clt = NULL;
415
416  /* ignore all fixed channel connect/disconnect on BR/EDR link for GATT */
417  if (transport == BT_TRANSPORT_BR_EDR) return;
418
419  GATT_TRACE_DEBUG(
420      "GATT   ATT protocol channel with BDA: %08x%04x is %s",
421      (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
422      (bd_addr[4] << 8) + bd_addr[5],
423      (connected) ? "connected" : "disconnected");
424
425  p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr);
426  if (p_srv_chg_clt != NULL) {
427    check_srv_chg = true;
428  } else {
429    if (btm_sec_is_a_bonded_dev(bd_addr))
430      gatt_add_a_bonded_dev_for_srv_chg(bd_addr);
431  }
432
433  if (connected) {
434    /* do we have a channel initiating a connection? */
435    if (p_tcb) {
436      /* we are initiating connection */
437      if (gatt_get_ch_state(p_tcb) == GATT_CH_CONN) {
438        /* send callback */
439        gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
440        p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE;
441
442        gatt_send_conn_cback(p_tcb);
443      }
444      if (check_srv_chg) gatt_chk_srv_chg(p_srv_chg_clt);
445    }
446    /* this is incoming connection or background connection callback */
447
448    else {
449      p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_LE);
450      if (p_tcb != NULL) {
451        p_tcb->att_lcid = L2CAP_ATT_CID;
452
453        gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
454
455        p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE;
456
457        gatt_send_conn_cback(p_tcb);
458        if (check_srv_chg) {
459          gatt_chk_srv_chg(p_srv_chg_clt);
460        }
461      } else {
462        GATT_TRACE_ERROR("CCB max out, no rsources");
463      }
464    }
465  } else {
466    gatt_cleanup_upon_disc(bd_addr, reason, transport);
467    GATT_TRACE_DEBUG("ATT disconnected");
468  }
469}
470
471/*******************************************************************************
472 *
473 * Function         gatt_channel_congestion
474 *
475 * Description      This function is called to process the congestion callback
476 *                  from lcb
477 *
478 * Returns          void
479 *
480 ******************************************************************************/
481static void gatt_channel_congestion(tGATT_TCB* p_tcb, bool congested) {
482  uint8_t i = 0;
483  tGATT_REG* p_reg = NULL;
484  uint16_t conn_id;
485
486  /* if uncongested, check to see if there is any more pending data */
487  if (p_tcb != NULL && congested == false) {
488    gatt_cl_send_next_cmd_inq(p_tcb);
489  }
490  /* notifying all applications for the connection up event */
491  for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
492    if (p_reg->in_use) {
493      if (p_reg->app_cb.p_congestion_cb) {
494        conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
495        (*p_reg->app_cb.p_congestion_cb)(conn_id, congested);
496      }
497    }
498  }
499}
500
501void gatt_notify_phy_updated(tGATT_TCB* p_tcb, uint8_t tx_phy, uint8_t rx_phy,
502                             uint8_t status) {
503  for (int i = 0; i < GATT_MAX_APPS; i++) {
504    tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
505    if (p_reg->in_use && p_reg->app_cb.p_phy_update_cb) {
506      uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
507      (*p_reg->app_cb.p_phy_update_cb)(p_reg->gatt_if, conn_id, tx_phy, rx_phy,
508                                       status);
509    }
510  }
511}
512
513void gatt_notify_conn_update(uint16_t handle, uint16_t interval,
514                             uint16_t latency, uint16_t timeout,
515                             uint8_t status) {
516  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(handle);
517  if (!p_dev_rec) {
518    return;
519  }
520
521  tGATT_TCB* p_tcb =
522      gatt_find_tcb_by_addr(p_dev_rec->ble.pseudo_addr, BT_TRANSPORT_LE);
523  if (p_tcb == NULL) return;
524
525  for (int i = 0; i < GATT_MAX_APPS; i++) {
526    tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
527    if (p_reg->in_use && p_reg->app_cb.p_conn_update_cb) {
528      uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
529      (*p_reg->app_cb.p_conn_update_cb)(p_reg->gatt_if, conn_id, interval,
530                                        latency, timeout, status);
531    }
532  }
533}
534
535/*******************************************************************************
536 *
537 * Function         gatt_le_cong_cback
538 *
539 * Description      This function is called when GATT fixed channel is congested
540 *                  or uncongested.
541 *
542 * Returns          void
543 *
544 ******************************************************************************/
545static void gatt_le_cong_cback(BD_ADDR remote_bda, bool congested) {
546  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(remote_bda, BT_TRANSPORT_LE);
547
548  /* if uncongested, check to see if there is any more pending data */
549  if (p_tcb != NULL) {
550    gatt_channel_congestion(p_tcb, congested);
551  }
552}
553
554/*******************************************************************************
555 *
556 * Function         gatt_le_data_ind
557 *
558 * Description      This function is called when data is received from L2CAP.
559 *                  if we are the originator of the connection, we are the ATT
560 *                  client, and the received message is queued up for the
561 *                  client.
562 *
563 *                  If we are the destination of the connection, we are the ATT
564 *                  server, so the message is passed to the server processing
565 *                  function.
566 *
567 * Returns          void
568 *
569 ******************************************************************************/
570static void gatt_le_data_ind(uint16_t chan, BD_ADDR bd_addr, BT_HDR* p_buf) {
571  tGATT_TCB* p_tcb;
572
573  /* Find CCB based on bd addr */
574  if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE)) != NULL &&
575      gatt_get_ch_state(p_tcb) >= GATT_CH_OPEN) {
576    gatt_data_process(p_tcb, p_buf);
577  } else {
578    osi_free(p_buf);
579
580    if (p_tcb != NULL) {
581      GATT_TRACE_WARNING("ATT - Ignored L2CAP data while in state: %d",
582                         gatt_get_ch_state(p_tcb));
583    }
584  }
585}
586
587/*******************************************************************************
588 *
589 * Function         gatt_l2cif_connect_ind
590 *
591 * Description      This function handles an inbound connection indication
592 *                  from L2CAP. This is the case where we are acting as a
593 *                  server.
594 *
595 * Returns          void
596 *
597 ******************************************************************************/
598static void gatt_l2cif_connect_ind_cback(BD_ADDR bd_addr, uint16_t lcid,
599                                         UNUSED_ATTR uint16_t psm, uint8_t id) {
600  /* do we already have a control channel for this peer? */
601  uint8_t result = L2CAP_CONN_OK;
602  tL2CAP_CFG_INFO cfg;
603  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_BR_EDR);
604
605  GATT_TRACE_ERROR("Connection indication cid = %d", lcid);
606  /* new connection ? */
607  if (p_tcb == NULL) {
608    /* allocate tcb */
609    p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_BR_EDR);
610    if (p_tcb == NULL) {
611      /* no tcb available, reject L2CAP connection */
612      result = L2CAP_CONN_NO_RESOURCES;
613    } else
614      p_tcb->att_lcid = lcid;
615
616  } else /* existing connection , reject it */
617  {
618    result = L2CAP_CONN_NO_RESOURCES;
619  }
620
621  /* Send L2CAP connect rsp */
622  L2CA_ConnectRsp(bd_addr, id, lcid, result, 0);
623
624  /* if result ok, proceed with connection */
625  if (result == L2CAP_CONN_OK) {
626    /* transition to configuration state */
627    gatt_set_ch_state(p_tcb, GATT_CH_CFG);
628
629    /* Send L2CAP config req */
630    memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
631    cfg.mtu_present = true;
632    cfg.mtu = GATT_MAX_MTU_SIZE;
633
634    L2CA_ConfigReq(lcid, &cfg);
635  }
636}
637
638/*******************************************************************************
639 *
640 * Function         gatt_l2c_connect_cfm_cback
641 *
642 * Description      This is the L2CAP connect confirm callback function.
643 *
644 *
645 * Returns          void
646 *
647 ******************************************************************************/
648static void gatt_l2cif_connect_cfm_cback(uint16_t lcid, uint16_t result) {
649  tGATT_TCB* p_tcb;
650  tL2CAP_CFG_INFO cfg;
651
652  /* look up clcb for this channel */
653  p_tcb = gatt_find_tcb_by_cid(lcid);
654  if (p_tcb != NULL) {
655    GATT_TRACE_DEBUG(
656        "gatt_l2c_connect_cfm_cback result: %d ch_state: %d, lcid:0x%x", result,
657        gatt_get_ch_state(p_tcb), p_tcb->att_lcid);
658
659    /* if in correct state */
660    if (gatt_get_ch_state(p_tcb) == GATT_CH_CONN) {
661      /* if result successful */
662      if (result == L2CAP_CONN_OK) {
663        /* set channel state */
664        gatt_set_ch_state(p_tcb, GATT_CH_CFG);
665
666        /* Send L2CAP config req */
667        memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
668        cfg.mtu_present = true;
669        cfg.mtu = GATT_MAX_MTU_SIZE;
670        L2CA_ConfigReq(lcid, &cfg);
671      }
672      /* else initiating connection failure */
673      else {
674        gatt_cleanup_upon_disc(p_tcb->peer_bda, result, GATT_TRANSPORT_BR_EDR);
675      }
676    } else /* wrong state, disconnect it */
677    {
678      if (result == L2CAP_CONN_OK) {
679        /* just in case the peer also accepts our connection - Send L2CAP
680         * disconnect req */
681        L2CA_DisconnectReq(lcid);
682      }
683    }
684  }
685}
686
687/*******************************************************************************
688 *
689 * Function         gatt_l2cif_config_cfm_cback
690 *
691 * Description      This is the L2CAP config confirm callback function.
692 *
693 *
694 * Returns          void
695 *
696 ******************************************************************************/
697void gatt_l2cif_config_cfm_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) {
698  tGATT_TCB* p_tcb;
699  tGATTS_SRV_CHG* p_srv_chg_clt = NULL;
700
701  /* look up clcb for this channel */
702  p_tcb = gatt_find_tcb_by_cid(lcid);
703  if (p_tcb != NULL) {
704    /* if in correct state */
705    if (gatt_get_ch_state(p_tcb) == GATT_CH_CFG) {
706      /* if result successful */
707      if (p_cfg->result == L2CAP_CFG_OK) {
708        /* update flags */
709        p_tcb->ch_flags |= GATT_L2C_CFG_CFM_DONE;
710
711        /* if configuration complete */
712        if (p_tcb->ch_flags & GATT_L2C_CFG_IND_DONE) {
713          gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
714
715          p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda);
716          if (p_srv_chg_clt != NULL) {
717            gatt_chk_srv_chg(p_srv_chg_clt);
718          } else {
719            if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
720              gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
721          }
722
723          /* send callback */
724          gatt_send_conn_cback(p_tcb);
725        }
726      }
727      /* else failure */
728      else {
729        /* Send L2CAP disconnect req */
730        L2CA_DisconnectReq(lcid);
731      }
732    }
733  }
734}
735
736/*******************************************************************************
737 *
738 * Function         gatt_l2cif_config_ind_cback
739 *
740 * Description      This is the L2CAP config indication callback function.
741 *
742 *
743 * Returns          void
744 *
745 ******************************************************************************/
746void gatt_l2cif_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) {
747  tGATT_TCB* p_tcb;
748  tGATTS_SRV_CHG* p_srv_chg_clt = NULL;
749  /* look up clcb for this channel */
750  p_tcb = gatt_find_tcb_by_cid(lcid);
751  if (p_tcb != NULL) {
752    /* GATT uses the smaller of our MTU and peer's MTU  */
753    if (p_cfg->mtu_present &&
754        (p_cfg->mtu >= GATT_MIN_BR_MTU_SIZE && p_cfg->mtu < L2CAP_DEFAULT_MTU))
755      p_tcb->payload_size = p_cfg->mtu;
756    else
757      p_tcb->payload_size = L2CAP_DEFAULT_MTU;
758
759    /* send L2CAP configure response */
760    memset(p_cfg, 0, sizeof(tL2CAP_CFG_INFO));
761    p_cfg->result = L2CAP_CFG_OK;
762    L2CA_ConfigRsp(lcid, p_cfg);
763
764    /* if first config ind */
765    if ((p_tcb->ch_flags & GATT_L2C_CFG_IND_DONE) == 0) {
766      /* update flags */
767      p_tcb->ch_flags |= GATT_L2C_CFG_IND_DONE;
768
769      /* if configuration complete */
770      if (p_tcb->ch_flags & GATT_L2C_CFG_CFM_DONE) {
771        gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
772        p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda);
773        if (p_srv_chg_clt != NULL) {
774          gatt_chk_srv_chg(p_srv_chg_clt);
775        } else {
776          if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
777            gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
778        }
779
780        /* send callback */
781        gatt_send_conn_cback(p_tcb);
782      }
783    }
784  }
785}
786
787/*******************************************************************************
788 *
789 * Function         gatt_l2cif_disconnect_ind_cback
790 *
791 * Description      This is the L2CAP disconnect indication callback function.
792 *
793 *
794 * Returns          void
795 *
796 ******************************************************************************/
797void gatt_l2cif_disconnect_ind_cback(uint16_t lcid, bool ack_needed) {
798  tGATT_TCB* p_tcb;
799  uint16_t reason;
800
801  /* look up clcb for this channel */
802  p_tcb = gatt_find_tcb_by_cid(lcid);
803  if (p_tcb != NULL) {
804    if (ack_needed) {
805      /* send L2CAP disconnect response */
806      L2CA_DisconnectRsp(lcid);
807    }
808    if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL) {
809      if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
810        gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
811    }
812    /* if ACL link is still up, no reason is logged, l2cap is disconnect from
813     * peer */
814    reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport);
815    if (reason == 0) reason = GATT_CONN_TERMINATE_PEER_USER;
816
817    /* send disconnect callback */
818    gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR);
819  }
820}
821
822/*******************************************************************************
823 *
824 * Function         gatt_l2cif_disconnect_cfm_cback
825 *
826 * Description      This is the L2CAP disconnect confirm callback function.
827 *
828 *
829 * Returns          void
830 *
831 ******************************************************************************/
832static void gatt_l2cif_disconnect_cfm_cback(uint16_t lcid,
833                                            UNUSED_ATTR uint16_t result) {
834  tGATT_TCB* p_tcb;
835  uint16_t reason;
836
837  /* look up clcb for this channel */
838  p_tcb = gatt_find_tcb_by_cid(lcid);
839  if (p_tcb != NULL) {
840    /* If the device is not in the service changed client list, add it... */
841    if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL) {
842      if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
843        gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
844    }
845
846    /* send disconnect callback */
847    /* if ACL link is still up, no reason is logged, l2cap is disconnect from
848     * peer */
849    reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport);
850    if (reason == 0) reason = GATT_CONN_TERMINATE_LOCAL_HOST;
851
852    gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR);
853  }
854}
855
856/*******************************************************************************
857 *
858 * Function         gatt_l2cif_data_ind_cback
859 *
860 * Description      This is the L2CAP data indication callback function.
861 *
862 *
863 * Returns          void
864 *
865 ******************************************************************************/
866static void gatt_l2cif_data_ind_cback(uint16_t lcid, BT_HDR* p_buf) {
867  tGATT_TCB* p_tcb;
868
869  /* look up clcb for this channel */
870  if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL &&
871      gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) {
872    /* process the data */
873    gatt_data_process(p_tcb, p_buf);
874  } else /* prevent buffer leak */
875    osi_free(p_buf);
876}
877
878/*******************************************************************************
879 *
880 * Function         gatt_l2cif_congest_cback
881 *
882 * Description      L2CAP congestion callback
883 *
884 * Returns          void
885 *
886 ******************************************************************************/
887static void gatt_l2cif_congest_cback(uint16_t lcid, bool congested) {
888  tGATT_TCB* p_tcb = gatt_find_tcb_by_cid(lcid);
889
890  if (p_tcb != NULL) {
891    gatt_channel_congestion(p_tcb, congested);
892  }
893}
894
895/*******************************************************************************
896 *
897 * Function         gatt_send_conn_cback
898 *
899 * Description      Callback used to notify layer above about a connection.
900 *
901 *
902 * Returns          void
903 *
904 ******************************************************************************/
905static void gatt_send_conn_cback(tGATT_TCB* p_tcb) {
906  uint8_t i;
907  tGATT_REG* p_reg;
908  tGATT_BG_CONN_DEV* p_bg_dev = NULL;
909  uint16_t conn_id;
910
911  p_bg_dev = gatt_find_bg_dev(p_tcb->peer_bda);
912
913  /* notifying all applications for the connection up event */
914  for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
915    if (p_reg->in_use) {
916      if (p_bg_dev && gatt_is_bg_dev_for_app(p_bg_dev, p_reg->gatt_if))
917        gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, true);
918
919      if (p_reg->app_cb.p_conn_cb) {
920        conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
921        (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id,
922                                   true, 0, p_tcb->transport);
923      }
924    }
925  }
926
927  if (gatt_num_apps_hold_link(p_tcb) && p_tcb->att_lcid == L2CAP_ATT_CID) {
928    /* disable idle timeout if one or more clients are holding the link disable
929     * the idle timer */
930    GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT,
931                        p_tcb->transport);
932  }
933}
934
935/*******************************************************************************
936 *
937 * Function         gatt_le_data_ind
938 *
939 * Description      This function is called when data is received from L2CAP.
940 *                  if we are the originator of the connection, we are the ATT
941 *                  client, and the received message is queued up for the
942 *                  client.
943 *
944 *                  If we are the destination of the connection, we are the ATT
945 *                  server, so the message is passed to the server processing
946 *                  function.
947 *
948 * Returns          void
949 *
950 ******************************************************************************/
951void gatt_data_process(tGATT_TCB* p_tcb, BT_HDR* p_buf) {
952  uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
953  uint8_t op_code, pseudo_op_code;
954  uint16_t msg_len;
955
956  if (p_buf->len > 0) {
957    msg_len = p_buf->len - 1;
958    STREAM_TO_UINT8(op_code, p);
959
960    /* remove the two MSBs associated with sign write and write cmd */
961    pseudo_op_code = op_code & (~GATT_WRITE_CMD_MASK);
962
963    if (pseudo_op_code < GATT_OP_CODE_MAX) {
964      if (op_code == GATT_SIGN_CMD_WRITE) {
965        gatt_verify_signature(p_tcb, p_buf);
966      } else {
967        /* message from client */
968        if ((op_code % 2) == 0)
969          gatt_server_handle_client_req(p_tcb, op_code, msg_len, p);
970        else
971          gatt_client_handle_server_rsp(p_tcb, op_code, msg_len, p);
972      }
973    } else {
974      GATT_TRACE_ERROR("ATT - Rcvd L2CAP data, unknown cmd: 0x%x", op_code);
975    }
976  } else {
977    GATT_TRACE_ERROR("invalid data length, ignore");
978  }
979
980  osi_free(p_buf);
981}
982
983/*******************************************************************************
984 *
985 * Function         gatt_add_a_bonded_dev_for_srv_chg
986 *
987 * Description      Add a bonded dev to the service changed client list
988 *
989 * Returns          void
990 *
991 ******************************************************************************/
992void gatt_add_a_bonded_dev_for_srv_chg(BD_ADDR bda) {
993  tGATTS_SRV_CHG_REQ req;
994  tGATTS_SRV_CHG srv_chg_clt;
995
996  memcpy(srv_chg_clt.bda, bda, BD_ADDR_LEN);
997  srv_chg_clt.srv_changed = false;
998  if (gatt_add_srv_chg_clt(&srv_chg_clt) != NULL) {
999    memcpy(req.srv_chg.bda, bda, BD_ADDR_LEN);
1000    req.srv_chg.srv_changed = false;
1001    if (gatt_cb.cb_info.p_srv_chg_callback)
1002      (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_ADD_CLIENT, &req,
1003                                            NULL);
1004  }
1005}
1006
1007/*******************************************************************************
1008 *
1009 * Function         gatt_send_srv_chg_ind
1010 *
1011 * Description      This function is called to send a service chnaged indication
1012 *                  to the specified bd address
1013 *
1014 * Returns          void
1015 *
1016 ******************************************************************************/
1017void gatt_send_srv_chg_ind(BD_ADDR peer_bda) {
1018  uint8_t handle_range[GATT_SIZE_OF_SRV_CHG_HNDL_RANGE];
1019  uint8_t* p = handle_range;
1020  uint16_t conn_id;
1021
1022  GATT_TRACE_DEBUG("gatt_send_srv_chg_ind");
1023
1024  if (gatt_cb.handle_of_h_r) {
1025    conn_id = gatt_profile_find_conn_id_by_bd_addr(peer_bda);
1026    if (conn_id != GATT_INVALID_CONN_ID) {
1027      UINT16_TO_STREAM(p, 1);
1028      UINT16_TO_STREAM(p, 0xFFFF);
1029      GATTS_HandleValueIndication(conn_id, gatt_cb.handle_of_h_r,
1030                                  GATT_SIZE_OF_SRV_CHG_HNDL_RANGE,
1031                                  handle_range);
1032    } else {
1033      GATT_TRACE_ERROR("Unable to find conn_id for  %08x%04x ",
1034                       (peer_bda[0] << 24) + (peer_bda[1] << 16) +
1035                           (peer_bda[2] << 8) + peer_bda[3],
1036                       (peer_bda[4] << 8) + peer_bda[5]);
1037    }
1038  }
1039}
1040
1041/*******************************************************************************
1042 *
1043 * Function         gatt_chk_srv_chg
1044 *
1045 * Description      Check sending service chnaged Indication is required or not
1046 *                  if required then send the Indication
1047 *
1048 * Returns          void
1049 *
1050 ******************************************************************************/
1051void gatt_chk_srv_chg(tGATTS_SRV_CHG* p_srv_chg_clt) {
1052  GATT_TRACE_DEBUG("gatt_chk_srv_chg srv_changed=%d",
1053                   p_srv_chg_clt->srv_changed);
1054
1055  if (p_srv_chg_clt->srv_changed) {
1056    gatt_send_srv_chg_ind(p_srv_chg_clt->bda);
1057  }
1058}
1059
1060/*******************************************************************************
1061 *
1062 * Function         gatt_init_srv_chg
1063 *
1064 * Description      This function is used to initialize the service changed
1065 *                  attribute value
1066 *
1067 * Returns          void
1068 *
1069 ******************************************************************************/
1070void gatt_init_srv_chg(void) {
1071  tGATTS_SRV_CHG_REQ req;
1072  tGATTS_SRV_CHG_RSP rsp;
1073  bool status;
1074  uint8_t num_clients, i;
1075  tGATTS_SRV_CHG srv_chg_clt;
1076
1077  GATT_TRACE_DEBUG("gatt_init_srv_chg");
1078  if (gatt_cb.cb_info.p_srv_chg_callback) {
1079    status = (*gatt_cb.cb_info.p_srv_chg_callback)(
1080        GATTS_SRV_CHG_CMD_READ_NUM_CLENTS, NULL, &rsp);
1081
1082    if (status && rsp.num_clients) {
1083      GATT_TRACE_DEBUG("gatt_init_srv_chg num_srv_chg_clt_clients=%d",
1084                       rsp.num_clients);
1085      num_clients = rsp.num_clients;
1086      i = 1; /* use one based index */
1087      while ((i <= num_clients) && status) {
1088        req.client_read_index = i;
1089        status = (*gatt_cb.cb_info.p_srv_chg_callback)(
1090            GATTS_SRV_CHG_CMD_READ_CLENT, &req, &rsp);
1091        if (status == true) {
1092          memcpy(&srv_chg_clt, &rsp.srv_chg, sizeof(tGATTS_SRV_CHG));
1093          if (gatt_add_srv_chg_clt(&srv_chg_clt) == NULL) {
1094            GATT_TRACE_ERROR("Unable to add a service change client");
1095            status = false;
1096          }
1097        }
1098        i++;
1099      }
1100    }
1101  } else {
1102    GATT_TRACE_DEBUG("gatt_init_srv_chg callback not registered yet");
1103  }
1104}
1105
1106/*******************************************************************************
1107 *
1108 * Function         gatt_proc_srv_chg
1109 *
1110 * Description      This function is process the service changed request
1111 *
1112 * Returns          void
1113 *
1114 ******************************************************************************/
1115void gatt_proc_srv_chg(void) {
1116  uint8_t start_idx, found_idx;
1117  BD_ADDR bda;
1118  tGATT_TCB* p_tcb;
1119  tBT_TRANSPORT transport;
1120
1121  GATT_TRACE_DEBUG("gatt_proc_srv_chg");
1122
1123  if (gatt_cb.cb_info.p_srv_chg_callback && gatt_cb.handle_of_h_r) {
1124    gatt_set_srv_chg();
1125    start_idx = 0;
1126    while (
1127        gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) {
1128      p_tcb = &gatt_cb.tcb[found_idx];
1129
1130      bool send_indication = true;
1131
1132      if (gatt_is_srv_chg_ind_pending(p_tcb)) {
1133        send_indication = false;
1134        GATT_TRACE_DEBUG("discard srv chg - already has one in the queue");
1135      }
1136
1137      // Some LE GATT clients don't respond to service changed indications.
1138      char remote_name[BTM_MAX_REM_BD_NAME_LEN] = "";
1139      bt_bdaddr_t bd_addr;
1140      for (int i = 0; i < 6; i++) bd_addr.address[i] = bda[i];
1141      if (send_indication &&
1142          btif_storage_get_stored_remote_name(bd_addr, remote_name)) {
1143        if (interop_match_name(INTEROP_GATTC_NO_SERVICE_CHANGED_IND,
1144                               remote_name)) {
1145          GATT_TRACE_DEBUG("discard srv chg - interop matched %s", remote_name);
1146          send_indication = false;
1147        }
1148      }
1149
1150      if (send_indication) gatt_send_srv_chg_ind(bda);
1151
1152      start_idx = ++found_idx;
1153    }
1154  }
1155}
1156
1157/*******************************************************************************
1158 *
1159 * Function         gatt_set_ch_state
1160 *
1161 * Description      This function set the ch_state in tcb
1162 *
1163 * Returns          none
1164 *
1165 ******************************************************************************/
1166void gatt_set_ch_state(tGATT_TCB* p_tcb, tGATT_CH_STATE ch_state) {
1167  if (p_tcb) {
1168    GATT_TRACE_DEBUG("gatt_set_ch_state: old=%d new=%d", p_tcb->ch_state,
1169                     ch_state);
1170    p_tcb->ch_state = ch_state;
1171  }
1172}
1173
1174/*******************************************************************************
1175 *
1176 * Function         gatt_get_ch_state
1177 *
1178 * Description      This function get the ch_state in tcb
1179 *
1180 * Returns          none
1181 *
1182 ******************************************************************************/
1183tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) {
1184  tGATT_CH_STATE ch_state = GATT_CH_CLOSE;
1185  if (p_tcb) {
1186    GATT_TRACE_DEBUG("gatt_get_ch_state: ch_state=%d", p_tcb->ch_state);
1187    ch_state = p_tcb->ch_state;
1188  }
1189  return ch_state;
1190}
1191