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