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