1 /******************************************************************************
2 *
3 * Copyright 2024 The Android Open Source Project
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 functions relating to BLE connection parameter
22 *management.
23 *
24 ******************************************************************************/
25
26 #define LOG_TAG "l2c_ble_conn_params"
27
28 #include <bluetooth/log.h>
29
30 #include "hci/controller_interface.h"
31 #include "hci/event_checkers.h"
32 #include "hci/hci_interface.h"
33 #include "hci/hci_packets.h"
34 #include "internal_include/stack_config.h"
35 #include "main/shim/acl_api.h"
36 #include "main/shim/entry.h"
37 #include "stack/btm/btm_dev.h"
38 #include "stack/include/acl_api.h"
39 #include "stack/include/btm_ble_api_types.h"
40 #include "stack/include/btm_client_interface.h"
41 #include "stack/include/l2cap_hci_link_interface.h"
42 #include "stack/include/l2cap_interface.h"
43 #include "stack/include/main_thread.h"
44 #include "stack/l2cap/l2c_int.h"
45 #include "types/raw_address.h"
46
47 using namespace bluetooth;
48
49 void l2cble_start_conn_update(tL2C_LCB* p_lcb);
50 static void l2cble_start_subrate_change(tL2C_LCB* p_lcb);
51
52 /*******************************************************************************
53 *
54 * Function L2CA_UpdateBleConnParams
55 *
56 * Description Update BLE connection parameters.
57 *
58 * Parameters: BD Address of remote
59 *
60 * Return value: true if update started
61 *
62 ******************************************************************************/
L2CA_UpdateBleConnParams(const RawAddress & rem_bda,uint16_t min_int,uint16_t max_int,uint16_t latency,uint16_t timeout,uint16_t min_ce_len,uint16_t max_ce_len)63 bool L2CA_UpdateBleConnParams(const RawAddress& rem_bda, uint16_t min_int, uint16_t max_int,
64 uint16_t latency, uint16_t timeout, uint16_t min_ce_len,
65 uint16_t max_ce_len) {
66 /* See if we have a link control block for the remote device */
67 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
68
69 /* If we do not have one, create one and accept the connection. */
70 if (!p_lcb || !get_btm_client_interface().peer.BTM_IsAclConnectionUp(rem_bda, BT_TRANSPORT_LE)) {
71 log::warn("- unknown BD_ADDR {}", rem_bda);
72 return false;
73 }
74
75 if (p_lcb->transport != BT_TRANSPORT_LE) {
76 log::warn("- BD_ADDR {} not LE", rem_bda);
77 return false;
78 }
79
80 log::verbose("BD_ADDR={}, min_int={}, max_int={}, min_ce_len={}, max_ce_len={}", rem_bda, min_int,
81 max_int, min_ce_len, max_ce_len);
82
83 p_lcb->min_interval = min_int;
84 p_lcb->max_interval = max_int;
85 p_lcb->latency = latency;
86 p_lcb->timeout = timeout;
87 p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
88 p_lcb->min_ce_len = min_ce_len;
89 p_lcb->max_ce_len = max_ce_len;
90
91 l2cble_start_conn_update(p_lcb);
92
93 return true;
94 }
95
96 static bool l2c_enable_update_ble_conn_params(tL2C_LCB* p_lcb, bool enable);
97
98 /* When called with lock=true, LE connection parameters will be locked on
99 * fastest value, and we won't accept request to change it from remote. When
100 * called with lock=false, parameters are relaxed.
101 */
L2CA_LockBleConnParamsForServiceDiscovery(const RawAddress & rem_bda,bool lock)102 void L2CA_LockBleConnParamsForServiceDiscovery(const RawAddress& rem_bda, bool lock) {
103 if (stack_config_get_interface()->get_pts_conn_updates_disabled()) {
104 return;
105 }
106
107 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
108 if (!p_lcb) {
109 log::warn("unknown address {}", rem_bda);
110 return;
111 }
112
113 if (p_lcb->transport != BT_TRANSPORT_LE) {
114 log::warn("{} not LE, link role {}", rem_bda, p_lcb->LinkRole());
115 return;
116 }
117
118 if (lock == p_lcb->conn_update_blocked_by_service_discovery) {
119 log::warn("{} service discovery already locked/unlocked conn params: {}", rem_bda, lock);
120 return;
121 }
122
123 p_lcb->conn_update_blocked_by_service_discovery = lock;
124
125 if (p_lcb->conn_update_blocked_by_profile_connection) {
126 log::info("{} conn params stay locked because of audio setup", rem_bda);
127 return;
128 }
129
130 log::info("{} Locking/unlocking conn params for service discovery: {}", rem_bda, lock);
131 l2c_enable_update_ble_conn_params(p_lcb, !lock);
132 }
133
134 /* When called with lock=true, LE connection parameters will be locked on
135 * fastest value, and we won't accept request to change it from remote. When
136 * called with lock=false, parameters are relaxed.
137 */
L2CA_LockBleConnParamsForProfileConnection(const RawAddress & rem_bda,bool lock)138 void L2CA_LockBleConnParamsForProfileConnection(const RawAddress& rem_bda, bool lock) {
139 if (stack_config_get_interface()->get_pts_conn_updates_disabled()) {
140 return;
141 }
142
143 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
144 if (!p_lcb) {
145 log::warn("unknown address {}", rem_bda);
146 return;
147 }
148
149 if (p_lcb->transport != BT_TRANSPORT_LE) {
150 log::warn("{} not LE, link role {}", rem_bda, p_lcb->LinkRole());
151 return;
152 }
153
154 if (lock == p_lcb->conn_update_blocked_by_profile_connection) {
155 log::info("{} audio setup already locked/unlocked conn params: {}", rem_bda, lock);
156 return;
157 }
158
159 p_lcb->conn_update_blocked_by_profile_connection = lock;
160
161 if (p_lcb->conn_update_blocked_by_service_discovery) {
162 log::info("{} conn params stay locked because of service discovery", rem_bda);
163 return;
164 }
165
166 log::info("{} Locking/unlocking conn params for audio setup: {}", rem_bda, lock);
167 l2c_enable_update_ble_conn_params(p_lcb, !lock);
168 }
169
l2c_enable_update_ble_conn_params(tL2C_LCB * p_lcb,bool enable)170 static bool l2c_enable_update_ble_conn_params(tL2C_LCB* p_lcb, bool enable) {
171 log::debug("{} enable {} current upd state 0x{:02x}", p_lcb->remote_bd_addr, enable,
172 p_lcb->conn_update_mask);
173
174 if (enable) {
175 p_lcb->conn_update_mask &= ~L2C_BLE_CONN_UPDATE_DISABLE;
176 p_lcb->subrate_req_mask &= ~L2C_BLE_SUBRATE_REQ_DISABLE;
177 } else {
178 p_lcb->conn_update_mask |= L2C_BLE_CONN_UPDATE_DISABLE;
179 p_lcb->subrate_req_mask |= L2C_BLE_SUBRATE_REQ_DISABLE;
180 }
181
182 l2cble_start_conn_update(p_lcb);
183
184 return true;
185 }
186
187 /*******************************************************************************
188 *
189 * Function l2cble_start_conn_update
190 *
191 * Description Start the BLE connection parameter update process based on
192 * status.
193 *
194 * Parameters: lcb : l2cap link control block
195 *
196 * Return value: none
197 *
198 ******************************************************************************/
l2cble_start_conn_update(tL2C_LCB * p_lcb)199 void l2cble_start_conn_update(tL2C_LCB* p_lcb) {
200 uint16_t min_conn_int, max_conn_int, peripheral_latency, supervision_tout;
201 if (!BTM_IsAclConnectionUp(p_lcb->remote_bd_addr, BT_TRANSPORT_LE)) {
202 log::error("No known connection ACL for {}", p_lcb->remote_bd_addr);
203 return;
204 }
205
206 // TODO(armansito): The return value of this call wasn't being used but the
207 // logic of this function might be depending on its side effects. We should
208 // verify if this call is needed at all and remove it otherwise.
209 btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
210
211 if ((p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) ||
212 (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_PENDING)) {
213 return;
214 }
215
216 if (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) {
217 /* application requests to disable parameters update.
218 If parameters are already updated, lets set them
219 up to what has been requested during connection establishement */
220 if (p_lcb->conn_update_mask & L2C_BLE_NOT_DEFAULT_PARAM &&
221 /* current connection interval is greater than default min */
222 p_lcb->min_interval > BTM_BLE_CONN_INT_MIN) {
223 /* use 7.5 ms as fast connection parameter, 0 peripheral latency */
224 min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN;
225
226 stack::l2cap::get_interface().L2CA_AdjustConnectionIntervals(&min_conn_int, &max_conn_int,
227 BTM_BLE_CONN_INT_MIN);
228
229 peripheral_latency = BTM_BLE_CONN_PERIPHERAL_LATENCY_DEF;
230 supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF;
231
232 /* if both side 4.1, or we are central device, send HCI command */
233 if (p_lcb->IsLinkRoleCentral() ||
234 (bluetooth::shim::GetController()->SupportsBleConnectionParametersRequest() &&
235 acl_peer_supports_ble_connection_parameters_request(p_lcb->remote_bd_addr))) {
236 acl_ble_connection_parameters_request(p_lcb->Handle(), min_conn_int, max_conn_int,
237 peripheral_latency, supervision_tout, 0, 0);
238 p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
239 } else {
240 l2cu_send_peer_ble_par_req(p_lcb, min_conn_int, max_conn_int, peripheral_latency,
241 supervision_tout);
242 }
243 p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM;
244 p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
245 }
246 } else {
247 /* application allows to do update, if we were delaying one do it now */
248 if (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM) {
249 /* if both side 4.1, or we are central device, send HCI command */
250 if (p_lcb->IsLinkRoleCentral() ||
251 (bluetooth::shim::GetController()->SupportsBleConnectionParametersRequest() &&
252 acl_peer_supports_ble_connection_parameters_request(p_lcb->remote_bd_addr))) {
253 acl_ble_connection_parameters_request(p_lcb->Handle(), p_lcb->min_interval,
254 p_lcb->max_interval, p_lcb->latency, p_lcb->timeout,
255 p_lcb->min_ce_len, p_lcb->max_ce_len);
256 p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
257 } else {
258 l2cu_send_peer_ble_par_req(p_lcb, p_lcb->min_interval, p_lcb->max_interval, p_lcb->latency,
259 p_lcb->timeout);
260 }
261 p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM;
262 p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM;
263 }
264 }
265 }
266
267 /*******************************************************************************
268 *
269 * Function l2cble_process_conn_update_evt
270 *
271 * Description This function enables the connection update request from
272 * remote after a successful connection update response is
273 * received.
274 *
275 * Returns void
276 *
277 ******************************************************************************/
l2cble_process_conn_update_evt(uint16_t handle,uint8_t status,uint16_t,uint16_t,uint16_t)278 void l2cble_process_conn_update_evt(uint16_t handle, uint8_t status, uint16_t /* interval */,
279 uint16_t /* latency */, uint16_t /* timeout */) {
280 log::verbose("");
281
282 /* See if we have a link control block for the remote device */
283 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
284 if (!p_lcb) {
285 log::warn("Invalid handle: {}", handle);
286 return;
287 }
288
289 p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
290
291 if (status != HCI_SUCCESS) {
292 log::warn("Error status: {}", status);
293 }
294
295 l2cble_start_conn_update(p_lcb);
296
297 l2cble_start_subrate_change(p_lcb);
298
299 log::verbose("conn_update_mask={} , subrate_req_mask={}", p_lcb->conn_update_mask,
300 p_lcb->subrate_req_mask);
301 }
302
303 /*******************************************************************************
304 *
305 * Function l2cble_process_rc_param_request_evt
306 *
307 * Description process LE Remote Connection Parameter Request Event.
308 *
309 * Returns void
310 *
311 ******************************************************************************/
l2cble_process_rc_param_request_evt(uint16_t handle,uint16_t int_min,uint16_t int_max,uint16_t latency,uint16_t timeout)312 void l2cble_process_rc_param_request_evt(uint16_t handle, uint16_t int_min, uint16_t int_max,
313 uint16_t latency, uint16_t timeout) {
314 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
315 if (!p_lcb) {
316 log::warn("No link to update connection parameter");
317 return;
318 }
319
320 p_lcb->min_interval = int_min;
321 p_lcb->max_interval = int_max;
322 p_lcb->latency = latency;
323 p_lcb->timeout = timeout;
324
325 /* if update is enabled, always accept connection parameter update */
326 if ((p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0) {
327 shim::GetHciLayer()->EnqueueCommand(
328 hci::LeRemoteConnectionParameterRequestReplyBuilder::Create(handle, int_min, int_max,
329 latency, timeout, 0, 0),
330 get_main()->BindOnce(
331 hci::check_complete<hci::LeRemoteConnectionParameterRequestReplyCompleteView>));
332 } else {
333 log::verbose("L2CAP - LE - update currently disabled");
334 p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
335 shim::GetHciLayer()->EnqueueCommand(
336 hci::LeRemoteConnectionParameterRequestNegativeReplyBuilder::Create(
337 handle, hci::ErrorCode::UNACCEPTABLE_CONNECTION_PARAMETERS),
338 get_main()->BindOnce(
339 hci::check_complete<
340 hci::LeRemoteConnectionParameterRequestNegativeReplyCompleteView>));
341 }
342 }
343
l2cble_use_preferred_conn_params(const RawAddress & bda)344 void l2cble_use_preferred_conn_params(const RawAddress& bda) {
345 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
346 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda);
347
348 /* If there are any preferred connection parameters, set them now */
349 if ((p_lcb != NULL) && (p_dev_rec != NULL) &&
350 (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN) &&
351 (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX) &&
352 (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN) &&
353 (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX) &&
354 (p_dev_rec->conn_params.peripheral_latency <= BTM_BLE_CONN_LATENCY_MAX) &&
355 (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) &&
356 (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) &&
357 ((p_lcb->min_interval < p_dev_rec->conn_params.min_conn_int &&
358 p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ||
359 (p_lcb->min_interval > p_dev_rec->conn_params.max_conn_int) ||
360 (p_lcb->latency > p_dev_rec->conn_params.peripheral_latency) ||
361 (p_lcb->timeout > p_dev_rec->conn_params.supervision_tout))) {
362 log::verbose(
363 "HANDLE={} min_conn_int={} max_conn_int={} peripheral_latency={} "
364 "supervision_tout={}",
365 p_lcb->Handle(), p_dev_rec->conn_params.min_conn_int,
366 p_dev_rec->conn_params.max_conn_int, p_dev_rec->conn_params.peripheral_latency,
367 p_dev_rec->conn_params.supervision_tout);
368
369 p_lcb->min_interval = p_dev_rec->conn_params.min_conn_int;
370 p_lcb->max_interval = p_dev_rec->conn_params.max_conn_int;
371 p_lcb->timeout = p_dev_rec->conn_params.supervision_tout;
372 p_lcb->latency = p_dev_rec->conn_params.peripheral_latency;
373
374 acl_ble_connection_parameters_request(p_lcb->Handle(), p_dev_rec->conn_params.min_conn_int,
375 p_dev_rec->conn_params.max_conn_int,
376 p_dev_rec->conn_params.peripheral_latency,
377 p_dev_rec->conn_params.supervision_tout, 0, 0);
378 }
379 }
380
381 /*******************************************************************************
382 *
383 * Function l2cble_start_subrate_change
384 *
385 * Description Start the BLE subrate change process based on
386 * status.
387 *
388 * Parameters: lcb : l2cap link control block
389 *
390 * Return value: none
391 *
392 ******************************************************************************/
l2cble_start_subrate_change(tL2C_LCB * p_lcb)393 static void l2cble_start_subrate_change(tL2C_LCB* p_lcb) {
394 if (!get_btm_client_interface().peer.BTM_IsAclConnectionUp(p_lcb->remote_bd_addr,
395 BT_TRANSPORT_LE)) {
396 log::error("No known connection ACL for {}", p_lcb->remote_bd_addr);
397 return;
398 }
399
400 btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
401
402 log::verbose("subrate_req_mask={} conn_update_mask={}", p_lcb->subrate_req_mask,
403 p_lcb->conn_update_mask);
404
405 if (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_PENDING) {
406 log::verbose("returning L2C_BLE_SUBRATE_REQ_PENDING");
407 return;
408 }
409
410 if (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_DISABLE) {
411 log::verbose("returning L2C_BLE_SUBRATE_REQ_DISABLE");
412 return;
413 }
414
415 /* application allows to do update, if we were delaying one do it now */
416 if (!(p_lcb->subrate_req_mask & L2C_BLE_NEW_SUBRATE_PARAM) ||
417 (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) ||
418 (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM)) {
419 log::verbose("returning L2C_BLE_NEW_SUBRATE_PARAM");
420 return;
421 }
422
423 if (!bluetooth::shim::GetController()->SupportsBleConnectionSubrating() ||
424 !acl_peer_supports_ble_connection_subrating(p_lcb->remote_bd_addr) ||
425 !acl_peer_supports_ble_connection_subrating_host(p_lcb->remote_bd_addr)) {
426 log::verbose(
427 "returning L2C_BLE_NEW_SUBRATE_PARAM local_host_sup={}, "
428 "local_conn_subrarte_sup={}, peer_subrate_sup={}, peer_host_sup={}",
429 bluetooth::shim::GetController()->SupportsBleConnectionSubratingHost(),
430 bluetooth::shim::GetController()->SupportsBleConnectionSubrating(),
431 acl_peer_supports_ble_connection_subrating(p_lcb->remote_bd_addr),
432 acl_peer_supports_ble_connection_subrating_host(p_lcb->remote_bd_addr));
433 return;
434 }
435
436 log::verbose("Sending HCI cmd for subrate req");
437 bluetooth::shim::ACL_LeSubrateRequest(p_lcb->Handle(), p_lcb->subrate_min, p_lcb->subrate_max,
438 p_lcb->max_latency, p_lcb->cont_num,
439 p_lcb->supervision_tout);
440
441 p_lcb->subrate_req_mask |= L2C_BLE_SUBRATE_REQ_PENDING;
442 p_lcb->subrate_req_mask &= ~L2C_BLE_NEW_SUBRATE_PARAM;
443 p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM;
444 }
445
446 /*******************************************************************************
447 *
448 * Function L2CA_SetDefaultSubrate
449 *
450 * Description BLE Set Default Subrate
451 *
452 * Parameters: Subrate parameters
453 *
454 * Return value: void
455 *
456 ******************************************************************************/
L2CA_SetDefaultSubrate(uint16_t subrate_min,uint16_t subrate_max,uint16_t max_latency,uint16_t cont_num,uint16_t timeout)457 void L2CA_SetDefaultSubrate(uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency,
458 uint16_t cont_num, uint16_t timeout) {
459 log::verbose("subrate_min={}, subrate_max={}, max_latency={}, cont_num={}, timeout={}",
460 subrate_min, subrate_max, max_latency, cont_num, timeout);
461
462 bluetooth::shim::ACL_LeSetDefaultSubrate(subrate_min, subrate_max, max_latency, cont_num,
463 timeout);
464 }
465
466 /*******************************************************************************
467 *
468 * Function L2CA_SubrateRequest
469 *
470 * Description BLE Subrate request.
471 *
472 * Parameters: Subrate parameters
473 *
474 * Return value: true if update started
475 *
476 ******************************************************************************/
L2CA_SubrateRequest(const RawAddress & rem_bda,uint16_t subrate_min,uint16_t subrate_max,uint16_t max_latency,uint16_t cont_num,uint16_t timeout)477 bool L2CA_SubrateRequest(const RawAddress& rem_bda, uint16_t subrate_min, uint16_t subrate_max,
478 uint16_t max_latency, uint16_t cont_num, uint16_t timeout) {
479 /* See if we have a link control block for the remote device */
480 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
481
482 /* If we don't have one, create one and accept the connection. */
483 if (!p_lcb || !get_btm_client_interface().peer.BTM_IsAclConnectionUp(rem_bda, BT_TRANSPORT_LE)) {
484 log::warn("unknown BD_ADDR {}", rem_bda);
485 return false;
486 }
487
488 if (p_lcb->transport != BT_TRANSPORT_LE) {
489 log::warn("BD_ADDR {} not LE", rem_bda);
490 return false;
491 }
492
493 log::verbose(
494 "BD_ADDR={}, subrate_min={}, subrate_max={}, max_latency={}, "
495 "cont_num={}, timeout={}",
496 rem_bda, subrate_min, subrate_max, max_latency, cont_num, timeout);
497
498 p_lcb->subrate_min = subrate_min;
499 p_lcb->subrate_max = subrate_max;
500 p_lcb->max_latency = max_latency;
501 p_lcb->cont_num = cont_num;
502 p_lcb->subrate_req_mask |= L2C_BLE_NEW_SUBRATE_PARAM;
503 p_lcb->supervision_tout = timeout;
504
505 l2cble_start_subrate_change(p_lcb);
506
507 return true;
508 }
509
510 /*******************************************************************************
511 *
512 * Function l2cble_process_subrate_change_evt
513 *
514 * Description This function enables LE subrating
515 * after a successful subrate change process is
516 * done.
517 *
518 * Parameters: LE connection handle
519 * status
520 * subrate factor
521 * peripheral latency
522 * continuation number
523 * supervision timeout
524 *
525 * Returns void
526 *
527 ******************************************************************************/
l2cble_process_subrate_change_evt(uint16_t handle,uint8_t status,uint16_t,uint16_t,uint16_t,uint16_t)528 void l2cble_process_subrate_change_evt(uint16_t handle, uint8_t status,
529 uint16_t /* subrate_factor */,
530 uint16_t /* peripheral_latency */, uint16_t /* cont_num */,
531 uint16_t /* timeout */) {
532 log::verbose("");
533
534 /* See if we have a link control block for the remote device */
535 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
536 if (!p_lcb) {
537 log::warn("Invalid handle: {}", handle);
538 return;
539 }
540
541 p_lcb->subrate_req_mask &= ~L2C_BLE_SUBRATE_REQ_PENDING;
542
543 if (status != HCI_SUCCESS) {
544 log::warn("Error status: {}", status);
545 }
546
547 l2cble_start_conn_update(p_lcb);
548
549 l2cble_start_subrate_change(p_lcb);
550
551 log::verbose("conn_update_mask={} , subrate_req_mask={}", p_lcb->conn_update_mask,
552 p_lcb->subrate_req_mask);
553 }
554