1 /******************************************************************************
2  *
3  *  Copyright 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/include/btif_storage.h"
30 #include "connection_manager.h"
31 #include "device/include/interop.h"
32 #include "l2c_api.h"
33 #include "osi/include/osi.h"
34 #include "stack/btm/btm_ble_int.h"
35 #include "stack/btm/btm_dev.h"
36 #include "stack/btm/btm_sec.h"
37 #include "stack/eatt/eatt.h"
38 #include "stack/gatt/gatt_int.h"
39 #include "stack/include/l2cap_acl_interface.h"
40 
41 using base::StringPrintf;
42 using bluetooth::eatt::EattExtension;
43 
44 /******************************************************************************/
45 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
46 /******************************************************************************/
47 static void gatt_le_connect_cback(uint16_t chan, const RawAddress& bd_addr,
48                                   bool connected, uint16_t reason,
49                                   tBT_TRANSPORT transport);
50 static void gatt_le_data_ind(uint16_t chan, const RawAddress& bd_addr,
51                              BT_HDR* p_buf);
52 static void gatt_le_cong_cback(const RawAddress& remote_bda, bool congest);
53 
54 static void gatt_l2cif_connect_ind_cback(const RawAddress& bd_addr,
55                                          uint16_t l2cap_cid, uint16_t psm,
56                                          uint8_t l2cap_id);
57 static void gatt_l2cif_connect_cfm_cback(uint16_t l2cap_cid, uint16_t result);
58 static void gatt_l2cif_config_ind_cback(uint16_t l2cap_cid,
59                                         tL2CAP_CFG_INFO* p_cfg);
60 static void gatt_l2cif_config_cfm_cback(uint16_t lcid, uint16_t result,
61                                         tL2CAP_CFG_INFO* p_cfg);
62 static void gatt_l2cif_disconnect_ind_cback(uint16_t l2cap_cid,
63                                             bool ack_needed);
64 static void gatt_l2cif_disconnect(uint16_t l2cap_cid);
65 static void gatt_l2cif_data_ind_cback(uint16_t l2cap_cid, BT_HDR* p_msg);
66 static void gatt_send_conn_cback(tGATT_TCB* p_tcb);
67 static void gatt_l2cif_congest_cback(uint16_t cid, bool congested);
68 static void gatt_on_l2cap_error(uint16_t lcid, uint16_t result);
69 
70 static const tL2CAP_APPL_INFO dyn_info = {
71     gatt_l2cif_connect_ind_cback,
72     gatt_l2cif_connect_cfm_cback,
73     gatt_l2cif_config_ind_cback,
74     gatt_l2cif_config_cfm_cback,
75     gatt_l2cif_disconnect_ind_cback,
76     gatt_l2cif_data_ind_cback,
77     gatt_l2cif_congest_cback,
78     NULL,
79     gatt_on_l2cap_error,
80     NULL,
81     NULL,
82     NULL
83 };
84 
85 tGATT_CB gatt_cb;
86 
87 /*******************************************************************************
88  *
89  * Function         gatt_init
90  *
91  * Description      This function is enable the GATT profile on the device.
92  *                  It clears out the control blocks, and registers with L2CAP.
93  *
94  * Returns          void
95  *
96  ******************************************************************************/
gatt_init(void)97 void gatt_init(void) {
98   tL2CAP_FIXED_CHNL_REG fixed_reg;
99 
100   VLOG(1) << __func__;
101 
102   gatt_cb = tGATT_CB();
103   connection_manager::reset(true);
104   memset(&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG));
105 
106   gatt_cb.sign_op_queue = fixed_queue_new(SIZE_MAX);
107   gatt_cb.srv_chg_clt_q = fixed_queue_new(SIZE_MAX);
108   /* First, register fixed L2CAP channel for ATT over BLE */
109   fixed_reg.pL2CA_FixedConn_Cb = gatt_le_connect_cback;
110   fixed_reg.pL2CA_FixedData_Cb = gatt_le_data_ind;
111   fixed_reg.pL2CA_FixedCong_Cb = gatt_le_cong_cback; /* congestion callback */
112   fixed_reg.default_idle_tout = 0xffff; /* 0xffff default idle timeout */
113 
114   L2CA_RegisterFixedChannel(L2CAP_ATT_CID, &fixed_reg);
115 
116   /* Now, register with L2CAP for ATT PSM over BR/EDR */
117   if (!L2CA_Register2(BT_PSM_ATT, dyn_info, false /* enable_snoop */, nullptr,
118                       GATT_MAX_MTU_SIZE, 0, BTM_SEC_NONE)) {
119     LOG(ERROR) << "ATT Dynamic Registration failed";
120   }
121 
122   gatt_cb.hdl_cfg.gatt_start_hdl = GATT_GATT_START_HANDLE;
123   gatt_cb.hdl_cfg.gap_start_hdl = GATT_GAP_START_HANDLE;
124   gatt_cb.hdl_cfg.app_start_hdl = GATT_APP_START_HANDLE;
125 
126   gatt_cb.hdl_list_info = new std::list<tGATT_HDL_LIST_ELEM>();
127   gatt_cb.srv_list_info = new std::list<tGATT_SRV_LIST_ELEM>();
128   gatt_profile_db_init();
129 
130   EattExtension::GetInstance()->Start();
131 }
132 
133 /*******************************************************************************
134  *
135  * Function         gatt_free
136  *
137  * Description      This function frees resources used by the GATT profile.
138  *
139  * Returns          void
140  *
141  ******************************************************************************/
gatt_free(void)142 void gatt_free(void) {
143   int i;
144   VLOG(1) << __func__;
145 
146   fixed_queue_free(gatt_cb.sign_op_queue, NULL);
147   gatt_cb.sign_op_queue = NULL;
148   fixed_queue_free(gatt_cb.srv_chg_clt_q, NULL);
149   gatt_cb.srv_chg_clt_q = NULL;
150   for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
151     gatt_cb.tcb[i].pending_enc_clcb = std::queue<tGATT_CLCB*>();
152 
153     fixed_queue_free(gatt_cb.tcb[i].pending_ind_q, NULL);
154     gatt_cb.tcb[i].pending_ind_q = NULL;
155 
156     alarm_free(gatt_cb.tcb[i].conf_timer);
157     gatt_cb.tcb[i].conf_timer = NULL;
158 
159     alarm_free(gatt_cb.tcb[i].ind_ack_timer);
160     gatt_cb.tcb[i].ind_ack_timer = NULL;
161 
162     fixed_queue_free(gatt_cb.tcb[i].sr_cmd.multi_rsp_q, NULL);
163     gatt_cb.tcb[i].sr_cmd.multi_rsp_q = NULL;
164 
165     if (gatt_cb.tcb[i].eatt)
166       EattExtension::GetInstance()->FreeGattResources(gatt_cb.tcb[i].peer_bda);
167   }
168 
169   gatt_cb.hdl_list_info->clear();
170   delete gatt_cb.hdl_list_info;
171   gatt_cb.hdl_list_info = nullptr;
172   gatt_cb.srv_list_info->clear();
173   delete gatt_cb.srv_list_info;
174   gatt_cb.srv_list_info = nullptr;
175 
176   EattExtension::GetInstance()->Stop();
177 }
178 
gatt_find_in_device_record(const RawAddress & bd_addr,tBLE_BD_ADDR * address_with_type)179 void gatt_find_in_device_record(const RawAddress& bd_addr,
180                                 tBLE_BD_ADDR* address_with_type) {
181   const tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
182   if (p_dev_rec == nullptr) {
183     return;
184   }
185 
186   if (p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) {
187     if (p_dev_rec->ble.identity_address_with_type.bda.IsEmpty()) {
188       *address_with_type = {.type = p_dev_rec->ble.ble_addr_type,
189                             .bda = bd_addr};
190       return;
191     }
192     *address_with_type = p_dev_rec->ble.identity_address_with_type;
193     return;
194   }
195   *address_with_type = {.type = BLE_ADDR_PUBLIC, .bda = bd_addr};
196   return;
197 }
198 
199 /*******************************************************************************
200  *
201  * Function         gatt_connect
202  *
203  * Description      This function is called to initiate a connection to a peer
204  *                  device.
205  *
206  * Parameter        rem_bda: remote device address to connect to.
207  *
208  * Returns          true if connection is started, otherwise return false.
209  *
210  ******************************************************************************/
gatt_connect(const RawAddress & rem_bda,tGATT_TCB * p_tcb,tBT_TRANSPORT transport,uint8_t initiating_phys,tGATT_IF gatt_if)211 bool gatt_connect(const RawAddress& rem_bda, tGATT_TCB* p_tcb,
212                   tBT_TRANSPORT transport, uint8_t initiating_phys,
213                   tGATT_IF gatt_if) {
214   if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN)
215     gatt_set_ch_state(p_tcb, GATT_CH_CONN);
216 
217   if (transport != BT_TRANSPORT_LE) {
218     p_tcb->att_lcid = L2CA_ConnectReq2(BT_PSM_ATT, rem_bda, BTM_SEC_NONE);
219     return p_tcb->att_lcid != 0;
220   }
221 
222   // Already connected, mark the link as used
223   if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) {
224     gatt_update_app_use_link_flag(gatt_if, p_tcb, true, true);
225     return true;
226   }
227 
228   p_tcb->att_lcid = L2CAP_ATT_CID;
229   return acl_create_le_connection_with_id(gatt_if, rem_bda);
230 }
231 
232 /*******************************************************************************
233  *
234  * Function         gatt_disconnect
235  *
236  * Description      This function is called to disconnect to an ATT device.
237  *
238  * Parameter        p_tcb: pointer to the TCB to disconnect.
239  *
240  * Returns          true: if connection found and to be disconnected; otherwise
241  *                  return false.
242  *
243  ******************************************************************************/
gatt_disconnect(tGATT_TCB * p_tcb)244 bool gatt_disconnect(tGATT_TCB* p_tcb) {
245   VLOG(1) << __func__;
246 
247   if (!p_tcb) return false;
248 
249   tGATT_CH_STATE ch_state = gatt_get_ch_state(p_tcb);
250   if (ch_state == GATT_CH_CLOSING) {
251     VLOG(1) << __func__ << " already in closing state";
252     return true;
253   }
254 
255   if (p_tcb->att_lcid == L2CAP_ATT_CID) {
256     if (ch_state == GATT_CH_OPEN) {
257       L2CA_RemoveFixedChnl(L2CAP_ATT_CID, p_tcb->peer_bda);
258       gatt_set_ch_state(p_tcb, GATT_CH_CLOSING);
259     } else {
260       connection_manager::direct_connect_remove(CONN_MGR_ID_L2CAP,
261                                                 p_tcb->peer_bda);
262       gatt_cleanup_upon_disc(p_tcb->peer_bda, GATT_CONN_TERMINATE_LOCAL_HOST,
263                              p_tcb->transport);
264     }
265   } else {
266     if ((ch_state == GATT_CH_OPEN) || (ch_state == GATT_CH_CFG)) {
267       gatt_l2cif_disconnect(p_tcb->att_lcid);
268     } else {
269       VLOG(1) << __func__ << " gatt_disconnect channel not opened";
270     }
271   }
272 
273   return true;
274 }
275 
276 /*******************************************************************************
277  *
278  * Function         gatt_update_app_hold_link_status
279  *
280  * Description      Update the application use link status
281  *
282  * Returns          true if any modifications are made or
283  *                  when it already exists, false otherwise.
284  *
285  ******************************************************************************/
gatt_update_app_hold_link_status(tGATT_IF gatt_if,tGATT_TCB * p_tcb,bool is_add)286 bool gatt_update_app_hold_link_status(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
287                                       bool is_add) {
288   auto& holders = p_tcb->app_hold_link;
289 
290   VLOG(1) << __func__;
291   if (is_add) {
292     auto ret = holders.insert(gatt_if);
293     if (ret.second) {
294       VLOG(1) << "added gatt_if=" << +gatt_if;
295     } else {
296       VLOG(1) << "attempt to add already existing gatt_if=" << +gatt_if;
297     }
298     return true;
299   }
300 
301   //! is_add
302   if (!holders.erase(gatt_if)) {
303     VLOG(1) << "attempt to remove nonexisting gatt_if=" << +gatt_if;
304     return false;
305   }
306 
307   VLOG(1) << "removed gatt_if=" << +gatt_if;
308   return true;
309 }
310 
311 /*******************************************************************************
312  *
313  * Function         gatt_update_app_use_link_flag
314  *
315  * Description      Update the application use link flag and optional to check
316  *                  the acl link if the link is up then set the idle time out
317  *                  accordingly
318  *
319  * Returns          void.
320  *
321  ******************************************************************************/
gatt_update_app_use_link_flag(tGATT_IF gatt_if,tGATT_TCB * p_tcb,bool is_add,bool check_acl_link)322 void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
323                                    bool is_add, bool check_acl_link) {
324   VLOG(1) << StringPrintf("%s: is_add=%d chk_link=%d", __func__, is_add,
325                           check_acl_link);
326 
327   if (!p_tcb) return;
328 
329   // If we make no modification, i.e. kill app that was never connected to a
330   // device, skip updating the device state.
331   if (!gatt_update_app_hold_link_status(gatt_if, p_tcb, is_add)) return;
332 
333   if (!check_acl_link) {
334     return;
335   }
336 
337   bool is_valid_handle =
338       (BTM_GetHCIConnHandle(p_tcb->peer_bda, p_tcb->transport) !=
339        GATT_INVALID_ACL_HANDLE);
340 
341   if (is_add) {
342     if (p_tcb->att_lcid == L2CAP_ATT_CID && is_valid_handle) {
343       VLOG(1) << "disable link idle timer";
344       /* acl link is connected disable the idle timeout */
345       GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT,
346                           p_tcb->transport);
347     }
348   } else {
349     if (p_tcb->app_hold_link.empty()) {
350       // acl link is connected but no application needs to use the link
351       if (p_tcb->att_lcid == L2CAP_ATT_CID && is_valid_handle) {
352 
353         /* Drop EATT before closing ATT */
354         EattExtension::GetInstance()->Disconnect(p_tcb->peer_bda);
355 
356         /* for fixed channel, set the timeout value to
357            GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */
358         VLOG(1) << " start link idle timer = "
359                 << GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP << " sec";
360         GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP,
361                             p_tcb->transport);
362       } else
363         // disconnect the dynamic channel
364         gatt_disconnect(p_tcb);
365     }
366   }
367 }
368 
369 /** GATT connection initiation */
gatt_act_connect(tGATT_REG * p_reg,const RawAddress & bd_addr,tBT_TRANSPORT transport,int8_t initiating_phys)370 bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr,
371                       tBT_TRANSPORT transport, int8_t initiating_phys) {
372   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
373   if (p_tcb != NULL) {
374     /* before link down, another app try to open a GATT connection */
375     uint8_t st = gatt_get_ch_state(p_tcb);
376     if (st == GATT_CH_OPEN && p_tcb->app_hold_link.empty() &&
377         transport == BT_TRANSPORT_LE) {
378       if (!gatt_connect(bd_addr, p_tcb, transport, initiating_phys,
379                         p_reg->gatt_if))
380         return false;
381     } else if (st == GATT_CH_CLOSING) {
382       LOG(INFO) << "Must finish disconnection before new connection";
383       /* need to complete the closing first */
384       return false;
385     }
386 
387     return true;
388   }
389 
390   p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport);
391   if (!p_tcb) {
392     LOG(ERROR) << "Max TCB for gatt_if [ " << +p_reg->gatt_if << "] reached.";
393     return false;
394   }
395 
396   if (!gatt_connect(bd_addr, p_tcb, transport, initiating_phys,
397                     p_reg->gatt_if)) {
398     LOG(ERROR) << "gatt_connect failed";
399     fixed_queue_free(p_tcb->pending_ind_q, NULL);
400     *p_tcb = tGATT_TCB();
401     return false;
402   }
403 
404   return true;
405 }
406 
407 namespace connection_manager {
on_connection_timed_out(uint8_t app_id,const RawAddress & address)408 void on_connection_timed_out(uint8_t app_id, const RawAddress& address) {
409   gatt_le_connect_cback(L2CAP_ATT_CID, address, false, 0xff, BT_TRANSPORT_LE);
410 }
411 }  // namespace connection_manager
412 
413 /** This callback function is called by L2CAP to indicate that the ATT fixed
414  * channel for LE is connected (conn = true)/disconnected (conn = false).
415  */
gatt_le_connect_cback(uint16_t chan,const RawAddress & bd_addr,bool connected,uint16_t reason,tBT_TRANSPORT transport)416 static void gatt_le_connect_cback(uint16_t chan, const RawAddress& bd_addr,
417                                   bool connected, uint16_t reason,
418                                   tBT_TRANSPORT transport) {
419   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
420   bool check_srv_chg = false;
421   tGATTS_SRV_CHG* p_srv_chg_clt = NULL;
422 
423   if (transport == BT_TRANSPORT_BR_EDR) {
424     LOG_WARN("Ignoring fixed channel connect/disconnect on br_edr for GATT");
425     return;
426   }
427 
428   VLOG(1) << "GATT   ATT protocol channel with BDA: " << bd_addr << " is "
429           << ((connected) ? "connected" : "disconnected");
430 
431   p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr);
432   if (p_srv_chg_clt != NULL) {
433     check_srv_chg = true;
434   } else {
435     if (btm_sec_is_a_bonded_dev(bd_addr))
436       gatt_add_a_bonded_dev_for_srv_chg(bd_addr);
437   }
438 
439   if (!connected) {
440     gatt_cleanup_upon_disc(bd_addr, static_cast<tGATT_DISCONN_REASON>(reason),
441                            transport);
442     return;
443   }
444 
445   /* do we have a channel initiating a connection? */
446   if (p_tcb) {
447     /* we are initiating connection */
448     if (gatt_get_ch_state(p_tcb) == GATT_CH_CONN) {
449       /* send callback */
450       gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
451       p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE;
452 
453       gatt_send_conn_cback(p_tcb);
454     }
455     if (check_srv_chg) gatt_chk_srv_chg(p_srv_chg_clt);
456   }
457   /* this is incoming connection or background connection callback */
458 
459   else {
460     p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_LE);
461     if (!p_tcb) {
462       LOG(ERROR) << "CCB max out, no rsources";
463       return;
464     }
465 
466     p_tcb->att_lcid = L2CAP_ATT_CID;
467 
468     gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
469 
470     p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE;
471 
472     gatt_send_conn_cback(p_tcb);
473     if (check_srv_chg) {
474       gatt_chk_srv_chg(p_srv_chg_clt);
475     }
476   }
477 
478   EattExtension::GetInstance()->Connect(bd_addr);
479 }
480 
481 /** This function is called to process the congestion callback from lcb */
gatt_channel_congestion(tGATT_TCB * p_tcb,bool congested)482 static void gatt_channel_congestion(tGATT_TCB* p_tcb, bool congested) {
483   uint8_t i = 0;
484   tGATT_REG* p_reg = NULL;
485   uint16_t conn_id;
486 
487   /* if uncongested, check to see if there is any more pending data */
488   if (p_tcb != NULL && !congested) {
489     gatt_cl_send_next_cmd_inq(*p_tcb);
490   }
491   /* notifying all applications for the connection up event */
492   for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
493     if (p_reg->in_use) {
494       if (p_reg->app_cb.p_congestion_cb) {
495         conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
496         (*p_reg->app_cb.p_congestion_cb)(conn_id, congested);
497       }
498     }
499   }
500 }
501 
gatt_notify_phy_updated(tGATT_STATUS status,uint16_t handle,uint8_t tx_phy,uint8_t rx_phy)502 void gatt_notify_phy_updated(tGATT_STATUS status, uint16_t handle,
503                              uint8_t tx_phy, uint8_t rx_phy) {
504   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(handle);
505   if (!p_dev_rec) {
506     LOG_WARN("No Device Found!");
507     return;
508   }
509 
510   tGATT_TCB* p_tcb =
511       gatt_find_tcb_by_addr(p_dev_rec->ble.pseudo_addr, BT_TRANSPORT_LE);
512   if (!p_tcb) return;
513 
514   for (int i = 0; i < GATT_MAX_APPS; i++) {
515     tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
516     if (p_reg->in_use && p_reg->app_cb.p_phy_update_cb) {
517       uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
518       (*p_reg->app_cb.p_phy_update_cb)(p_reg->gatt_if, conn_id, tx_phy, rx_phy,
519                                        status);
520     }
521   }
522 }
523 
gatt_notify_conn_update(const RawAddress & remote,uint16_t interval,uint16_t latency,uint16_t timeout,tHCI_STATUS status)524 void gatt_notify_conn_update(const RawAddress& remote, uint16_t interval,
525                              uint16_t latency, uint16_t timeout,
526                              tHCI_STATUS status) {
527   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(remote, BT_TRANSPORT_LE);
528 
529   if (!p_tcb) return;
530 
531   for (int i = 0; i < GATT_MAX_APPS; i++) {
532     tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
533     if (p_reg->in_use && p_reg->app_cb.p_conn_update_cb) {
534       uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
535       (*p_reg->app_cb.p_conn_update_cb)(p_reg->gatt_if, conn_id, interval,
536                                         latency, timeout,
537                                         static_cast<tGATT_STATUS>(status));
538     }
539   }
540 }
541 
542 /** This function is called when GATT fixed channel is congested or uncongested
543  */
gatt_le_cong_cback(const RawAddress & remote_bda,bool congested)544 static void gatt_le_cong_cback(const RawAddress& remote_bda, bool congested) {
545   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(remote_bda, BT_TRANSPORT_LE);
546   if (!p_tcb) return;
547 
548   /* if uncongested, check to see if there is any more pending data */
549     gatt_channel_congestion(p_tcb, congested);
550 }
551 
552 /*******************************************************************************
553  *
554  * Function         gatt_le_data_ind
555  *
556  * Description      This function is called when data is received from L2CAP.
557  *                  if we are the originator of the connection, we are the ATT
558  *                  client, and the received message is queued up for the
559  *                  client.
560  *
561  *                  If we are the destination of the connection, we are the ATT
562  *                  server, so the message is passed to the server processing
563  *                  function.
564  *
565  * Returns          void
566  *
567  ******************************************************************************/
gatt_le_data_ind(uint16_t chan,const RawAddress & bd_addr,BT_HDR * p_buf)568 static void gatt_le_data_ind(uint16_t chan, const RawAddress& bd_addr,
569                              BT_HDR* p_buf) {
570 
571   /* Find CCB based on bd addr */
572   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
573   if (p_tcb) {
574     if (gatt_get_ch_state(p_tcb) < GATT_CH_OPEN) {
575       LOG(WARNING) << "ATT - Ignored L2CAP data while in state: "
576                    << +gatt_get_ch_state(p_tcb);
577     } else
578       gatt_data_process(*p_tcb, L2CAP_ATT_CID, p_buf);
579   }
580 
581   osi_free(p_buf);
582 }
583 
584 /*******************************************************************************
585  *
586  * Function         gatt_l2cif_connect_ind
587  *
588  * Description      This function handles an inbound connection indication
589  *                  from L2CAP. This is the case where we are acting as a
590  *                  server.
591  *
592  * Returns          void
593  *
594  ******************************************************************************/
gatt_l2cif_connect_ind_cback(const RawAddress & bd_addr,uint16_t lcid,UNUSED_ATTR uint16_t psm,uint8_t id)595 static void gatt_l2cif_connect_ind_cback(const RawAddress& bd_addr,
596                                          uint16_t lcid,
597                                          UNUSED_ATTR uint16_t psm, uint8_t id) {
598   uint8_t result = L2CAP_CONN_OK;
599   LOG(INFO) << "Connection indication cid = " << +lcid;
600 
601   /* new connection ? */
602   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_BR_EDR);
603   if (p_tcb == NULL) {
604     /* allocate tcb */
605     p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_BR_EDR);
606     if (p_tcb == NULL) {
607       /* no tcb available, reject L2CAP connection */
608       result = L2CAP_CONN_NO_RESOURCES;
609     } else
610       p_tcb->att_lcid = lcid;
611 
612   } else /* existing connection , reject it */
613   {
614     result = L2CAP_CONN_NO_RESOURCES;
615   }
616 
617   /* If we reject the connection, send DisconnectReq */
618   if (result != L2CAP_CONN_OK) {
619     L2CA_DisconnectReq(lcid);
620     return;
621   }
622 
623   /* transition to configuration state */
624   gatt_set_ch_state(p_tcb, GATT_CH_CFG);
625 }
626 
gatt_on_l2cap_error(uint16_t lcid,uint16_t result)627 static void gatt_on_l2cap_error(uint16_t lcid, uint16_t result) {
628   tGATT_TCB* p_tcb = gatt_find_tcb_by_cid(lcid);
629   if (p_tcb == nullptr) return;
630   if (gatt_get_ch_state(p_tcb) == GATT_CH_CONN) {
631     gatt_cleanup_upon_disc(p_tcb->peer_bda, GATT_CONN_L2C_FAILURE,
632                            BT_TRANSPORT_BR_EDR);
633   } else {
634     gatt_l2cif_disconnect(lcid);
635   }
636 }
637 
638 /** This is the L2CAP connect confirm callback function */
gatt_l2cif_connect_cfm_cback(uint16_t lcid,uint16_t result)639 static void gatt_l2cif_connect_cfm_cback(uint16_t lcid, uint16_t result) {
640   tGATT_TCB* p_tcb;
641 
642   /* look up clcb for this channel */
643   p_tcb = gatt_find_tcb_by_cid(lcid);
644   if (!p_tcb) return;
645 
646   VLOG(1) << __func__
647           << StringPrintf(" result: %d ch_state: %d, lcid:0x%x", result,
648                           gatt_get_ch_state(p_tcb), p_tcb->att_lcid);
649 
650   if (gatt_get_ch_state(p_tcb) == GATT_CH_CONN && result == L2CAP_CONN_OK) {
651     gatt_set_ch_state(p_tcb, GATT_CH_CFG);
652   } else {
653     gatt_on_l2cap_error(lcid, result);
654   }
655 }
656 
657 /** This is the L2CAP config confirm callback function */
gatt_l2cif_config_cfm_cback(uint16_t lcid,uint16_t initiator,tL2CAP_CFG_INFO * p_cfg)658 void gatt_l2cif_config_cfm_cback(uint16_t lcid, uint16_t initiator,
659                                  tL2CAP_CFG_INFO* p_cfg) {
660   gatt_l2cif_config_ind_cback(lcid, p_cfg);
661 
662   /* look up clcb for this channel */
663   tGATT_TCB* p_tcb = gatt_find_tcb_by_cid(lcid);
664   if (!p_tcb) return;
665 
666   /* if in incorrect state */
667   if (gatt_get_ch_state(p_tcb) != GATT_CH_CFG) return;
668 
669   gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
670 
671   tGATTS_SRV_CHG* p_srv_chg_clt =
672       gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda);
673   if (p_srv_chg_clt != NULL) {
674     gatt_chk_srv_chg(p_srv_chg_clt);
675   } else {
676     if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
677       gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
678   }
679 
680   /* send callback */
681   gatt_send_conn_cback(p_tcb);
682 }
683 
684 /** This is the L2CAP config indication callback function */
gatt_l2cif_config_ind_cback(uint16_t lcid,tL2CAP_CFG_INFO * p_cfg)685 void gatt_l2cif_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) {
686   /* look up clcb for this channel */
687   tGATT_TCB* p_tcb = gatt_find_tcb_by_cid(lcid);
688   if (!p_tcb) return;
689 
690   /* GATT uses the smaller of our MTU and peer's MTU  */
691   if (p_cfg->mtu_present && p_cfg->mtu < L2CAP_DEFAULT_MTU)
692     p_tcb->payload_size = p_cfg->mtu;
693   else
694     p_tcb->payload_size = L2CAP_DEFAULT_MTU;
695 }
696 
697 /** This is the L2CAP disconnect indication callback function */
gatt_l2cif_disconnect_ind_cback(uint16_t lcid,bool ack_needed)698 void gatt_l2cif_disconnect_ind_cback(uint16_t lcid, bool ack_needed) {
699 
700   /* look up clcb for this channel */
701   tGATT_TCB* p_tcb = gatt_find_tcb_by_cid(lcid);
702   if (!p_tcb) return;
703 
704   if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL) {
705     if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
706       gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
707   }
708   /* send disconnect callback */
709   gatt_cleanup_upon_disc(p_tcb->peer_bda, GATT_CONN_TERMINATE_PEER_USER,
710                          BT_TRANSPORT_BR_EDR);
711 }
712 
gatt_l2cif_disconnect(uint16_t lcid)713 static void gatt_l2cif_disconnect(uint16_t lcid) {
714   L2CA_DisconnectReq(lcid);
715 
716   /* look up clcb for this channel */
717   tGATT_TCB* p_tcb = gatt_find_tcb_by_cid(lcid);
718   if (!p_tcb) return;
719 
720   /* If the device is not in the service changed client list, add it... */
721   if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL) {
722     if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
723       gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
724   }
725 
726   gatt_cleanup_upon_disc(p_tcb->peer_bda, GATT_CONN_TERMINATE_LOCAL_HOST,
727                          BT_TRANSPORT_BR_EDR);
728 }
729 
730 /** This is the L2CAP data indication callback function */
gatt_l2cif_data_ind_cback(uint16_t lcid,BT_HDR * p_buf)731 static void gatt_l2cif_data_ind_cback(uint16_t lcid, BT_HDR* p_buf) {
732   /* look up clcb for this channel */
733   tGATT_TCB* p_tcb = gatt_find_tcb_by_cid(lcid);
734   if (p_tcb && gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) {
735     /* process the data */
736     gatt_data_process(*p_tcb, lcid, p_buf);
737   }
738 
739   osi_free(p_buf);
740 }
741 
742 /** L2CAP congestion callback */
gatt_l2cif_congest_cback(uint16_t lcid,bool congested)743 static void gatt_l2cif_congest_cback(uint16_t lcid, bool congested) {
744   tGATT_TCB* p_tcb = gatt_find_tcb_by_cid(lcid);
745 
746   if (p_tcb != NULL) {
747     gatt_channel_congestion(p_tcb, congested);
748   }
749 }
750 
751 /** Callback used to notify layer above about a connection */
gatt_send_conn_cback(tGATT_TCB * p_tcb)752 static void gatt_send_conn_cback(tGATT_TCB* p_tcb) {
753   uint8_t i;
754   tGATT_REG* p_reg;
755   uint16_t conn_id;
756 
757   std::set<tGATT_IF> apps =
758       connection_manager::get_apps_connecting_to(p_tcb->peer_bda);
759 
760   /* notifying all applications for the connection up event */
761   for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
762     if (!p_reg->in_use) continue;
763 
764     if (apps.find(p_reg->gatt_if) != apps.end())
765       gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, true);
766 
767     if (p_reg->app_cb.p_conn_cb) {
768       conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
769       (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id,
770                                  kGattConnected, GATT_CONN_OK,
771                                  p_tcb->transport);
772     }
773   }
774 
775   /* Remove the direct connection */
776   connection_manager::on_connection_complete(p_tcb->peer_bda);
777 
778   if (!p_tcb->app_hold_link.empty() && p_tcb->att_lcid == L2CAP_ATT_CID) {
779     /* disable idle timeout if one or more clients are holding the link disable
780      * the idle timer */
781     GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT,
782                         p_tcb->transport);
783   }
784 }
785 
786 /*******************************************************************************
787  *
788  * Function         gatt_le_data_ind
789  *
790  * Description      This function is called when data is received from L2CAP.
791  *                  if we are the originator of the connection, we are the ATT
792  *                  client, and the received message is queued up for the
793  *                  client.
794  *
795  *                  If we are the destination of the connection, we are the ATT
796  *                  server, so the message is passed to the server processing
797  *                  function.
798  *
799  * Returns          void
800  *
801  ******************************************************************************/
gatt_data_process(tGATT_TCB & tcb,uint16_t cid,BT_HDR * p_buf)802 void gatt_data_process(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_buf) {
803   uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
804   uint8_t op_code, pseudo_op_code;
805 
806   if (p_buf->len <= 0) {
807     LOG(ERROR) << "invalid data length, ignore";
808     return;
809   }
810 
811   uint16_t msg_len = p_buf->len - 1;
812   STREAM_TO_UINT8(op_code, p);
813 
814   /* remove the two MSBs associated with sign write and write cmd */
815   pseudo_op_code = op_code & (~GATT_WRITE_CMD_MASK);
816 
817   if (pseudo_op_code >= GATT_OP_CODE_MAX) {
818     /* Note: PTS: GATT/SR/UNS/BI-01-C mandates error on unsupported ATT request.
819      */
820     LOG(ERROR) << __func__
821                << ": ATT - Rcvd L2CAP data, unknown cmd: " << loghex(op_code);
822     gatt_send_error_rsp(tcb, cid, GATT_REQ_NOT_SUPPORTED, op_code, 0, false);
823     return;
824   }
825 
826   if (op_code == GATT_SIGN_CMD_WRITE) {
827     gatt_verify_signature(tcb, cid, p_buf);
828   } else {
829     /* message from client */
830     if ((op_code % 2) == 0)
831       gatt_server_handle_client_req(tcb, cid, op_code, msg_len, p);
832     else
833       gatt_client_handle_server_rsp(tcb, cid, op_code, msg_len, p);
834   }
835 }
836 
837 /** Add a bonded dev to the service changed client list */
gatt_add_a_bonded_dev_for_srv_chg(const RawAddress & bda)838 void gatt_add_a_bonded_dev_for_srv_chg(const RawAddress& bda) {
839   tGATTS_SRV_CHG_REQ req;
840   tGATTS_SRV_CHG srv_chg_clt;
841 
842   srv_chg_clt.bda = bda;
843   srv_chg_clt.srv_changed = false;
844   if (!gatt_add_srv_chg_clt(&srv_chg_clt)) return;
845 
846   req.srv_chg.bda = bda;
847   req.srv_chg.srv_changed = false;
848   if (gatt_cb.cb_info.p_srv_chg_callback)
849     (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_ADD_CLIENT, &req,
850                                           NULL);
851 }
852 
853 /** This function is called to send a service chnaged indication to the
854  * specified bd address */
gatt_send_srv_chg_ind(const RawAddress & peer_bda)855 void gatt_send_srv_chg_ind(const RawAddress& peer_bda) {
856   VLOG(1) << __func__;
857 
858   if (!gatt_cb.handle_of_h_r) return;
859 
860   uint16_t conn_id = gatt_profile_find_conn_id_by_bd_addr(peer_bda);
861   if (conn_id == GATT_INVALID_CONN_ID) {
862     LOG(ERROR) << "Unable to find conn_id for " << peer_bda;
863     return;
864   }
865 
866   uint8_t handle_range[GATT_SIZE_OF_SRV_CHG_HNDL_RANGE];
867   uint8_t* p = handle_range;
868   UINT16_TO_STREAM(p, 1);
869   UINT16_TO_STREAM(p, 0xFFFF);
870   GATTS_HandleValueIndication(conn_id, gatt_cb.handle_of_h_r,
871                               GATT_SIZE_OF_SRV_CHG_HNDL_RANGE, handle_range);
872 }
873 
874 /** Check sending service chnaged Indication is required or not if required then
875  * send the Indication */
gatt_chk_srv_chg(tGATTS_SRV_CHG * p_srv_chg_clt)876 void gatt_chk_srv_chg(tGATTS_SRV_CHG* p_srv_chg_clt) {
877   VLOG(1) << __func__ << " srv_changed=" << +p_srv_chg_clt->srv_changed;
878 
879   if (p_srv_chg_clt->srv_changed) {
880     gatt_send_srv_chg_ind(p_srv_chg_clt->bda);
881   }
882 }
883 
884 /** This function is used to initialize the service changed attribute value */
gatt_init_srv_chg(void)885 void gatt_init_srv_chg(void) {
886   tGATTS_SRV_CHG_REQ req;
887   tGATTS_SRV_CHG_RSP rsp;
888   tGATTS_SRV_CHG srv_chg_clt;
889 
890   VLOG(1) << __func__;
891   if (!gatt_cb.cb_info.p_srv_chg_callback) {
892     VLOG(1) << __func__ << " callback not registered yet";
893     return;
894   }
895 
896   bool status = (*gatt_cb.cb_info.p_srv_chg_callback)(
897       GATTS_SRV_CHG_CMD_READ_NUM_CLENTS, NULL, &rsp);
898 
899   if (!(status && rsp.num_clients)) return;
900 
901   VLOG(1) << "num_srv_chg_clt_clients=" << +rsp.num_clients;
902   uint8_t num_clients = rsp.num_clients;
903   uint8_t i = 1; /* use one based index */
904   while ((i <= num_clients) && status) {
905     req.client_read_index = i;
906     status = (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_READ_CLENT,
907                                                    &req, &rsp);
908     if (status) {
909       memcpy(&srv_chg_clt, &rsp.srv_chg, sizeof(tGATTS_SRV_CHG));
910       if (gatt_add_srv_chg_clt(&srv_chg_clt) == NULL) {
911         LOG(ERROR) << "Unable to add a service change client";
912         status = false;
913       }
914     }
915     i++;
916   }
917 }
918 
919 /**This function is process the service changed request */
gatt_proc_srv_chg(void)920 void gatt_proc_srv_chg(void) {
921   RawAddress bda;
922   tBT_TRANSPORT transport;
923   uint8_t found_idx;
924 
925   VLOG(1) << __func__;
926 
927   if (!gatt_cb.cb_info.p_srv_chg_callback || !gatt_cb.handle_of_h_r) return;
928 
929   gatt_set_srv_chg();
930   uint8_t start_idx = 0;
931   while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) {
932     tGATT_TCB* p_tcb = &gatt_cb.tcb[found_idx];
933 
934     bool send_indication = true;
935 
936     if (gatt_is_srv_chg_ind_pending(p_tcb)) {
937       send_indication = false;
938       VLOG(1) << "discard srv chg - already has one in the queue";
939     }
940 
941     // Some LE GATT clients don't respond to service changed indications.
942     char remote_name[BTM_MAX_REM_BD_NAME_LEN] = "";
943     if (send_indication &&
944         btif_storage_get_stored_remote_name(bda, remote_name)) {
945       if (interop_match_name(INTEROP_GATTC_NO_SERVICE_CHANGED_IND,
946                              remote_name)) {
947         VLOG(1) << "discard srv chg - interop matched " << remote_name;
948         send_indication = false;
949       }
950     }
951 
952     if (send_indication) gatt_send_srv_chg_ind(bda);
953 
954     start_idx = ++found_idx;
955   }
956 }
957 
958 /** This function set the ch_state in tcb */
gatt_set_ch_state(tGATT_TCB * p_tcb,tGATT_CH_STATE ch_state)959 void gatt_set_ch_state(tGATT_TCB* p_tcb, tGATT_CH_STATE ch_state) {
960   if (!p_tcb) return;
961 
962   VLOG(1) << __func__ << ": old=" << +p_tcb->ch_state
963           << " new=" << loghex(static_cast<uint8_t>(ch_state));
964   p_tcb->ch_state = ch_state;
965 }
966 
967 /** This function get the ch_state in tcb */
gatt_get_ch_state(tGATT_TCB * p_tcb)968 tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) {
969   if (!p_tcb) return GATT_CH_CLOSE;
970 
971   VLOG(1) << "gatt_get_ch_state: ch_state=" << +p_tcb->ch_state;
972   return p_tcb->ch_state;
973 }
974