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