1 /******************************************************************************
2 *
3 * Copyright 2009-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 functions relating to BLE management.
22 *
23 ******************************************************************************/
24
25 #define LOG_TAG "l2c_ble"
26
27 #include <base/logging.h>
28 #include <base/strings/stringprintf.h>
29 #include <log/log.h>
30
31 #ifdef __ANDROID__
32 #include <android/sysprop/BluetoothProperties.sysprop.h>
33 #endif
34
35 #include "bt_target.h"
36 #include "bta/include/bta_hearing_aid_api.h"
37 #include "btif/include/core_callbacks.h"
38 #include "btif/include/stack_manager.h"
39 #include "device/include/controller.h"
40 #include "main/shim/acl_api.h"
41 #include "main/shim/l2c_api.h"
42 #include "main/shim/shim.h"
43 #include "osi/include/allocator.h"
44 #include "osi/include/log.h"
45 #include "osi/include/osi.h"
46 #include "osi/include/properties.h"
47 #include "stack/btm/btm_dev.h"
48 #include "stack/btm/btm_sec.h"
49 #include "stack/include/acl_api.h"
50 #include "stack/include/l2c_api.h"
51 #include "stack/include/l2cdefs.h"
52 #include "stack/l2cap/l2c_int.h"
53 #include "stack_config.h"
54 #include "types/raw_address.h"
55
56 namespace {
57
58 constexpr char kBtmLogTag[] = "L2CAP";
59
60 }
61
62 tL2CAP_LE_RESULT_CODE btm_ble_start_sec_check(const RawAddress& bd_addr,
63 uint16_t psm, bool is_originator,
64 tBTM_SEC_CALLBACK* p_callback,
65 void* p_ref_data);
66
67 extern tBTM_CB btm_cb;
68
69 using base::StringPrintf;
70
71 static void l2cble_start_conn_update(tL2C_LCB* p_lcb);
72 static void l2cble_start_subrate_change(tL2C_LCB* p_lcb);
73 void gatt_notify_conn_update(const RawAddress& remote, uint16_t interval,
74 uint16_t latency, uint16_t timeout,
75 tHCI_STATUS status);
76
77 /*******************************************************************************
78 *
79 * Function L2CA_UpdateBleConnParams
80 *
81 * Description Update BLE connection parameters.
82 *
83 * Parameters: BD Address of remote
84 *
85 * Return value: true if update started
86 *
87 ******************************************************************************/
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)88 bool L2CA_UpdateBleConnParams(const RawAddress& rem_bda, uint16_t min_int,
89 uint16_t max_int, uint16_t latency,
90 uint16_t timeout, uint16_t min_ce_len,
91 uint16_t max_ce_len) {
92 if (bluetooth::shim::is_gd_l2cap_enabled()) {
93 bluetooth::shim::L2CA_LeConnectionUpdate(rem_bda, min_int, max_int, latency,
94 timeout, min_ce_len, max_ce_len);
95 return true;
96 }
97
98 tL2C_LCB* p_lcb;
99
100 /* See if we have a link control block for the remote device */
101 p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
102
103 /* If we do not have one, create one and accept the connection. */
104 if (!p_lcb || !BTM_IsAclConnectionUp(rem_bda, BT_TRANSPORT_LE)) {
105 LOG(WARNING) << __func__ << " - unknown BD_ADDR " << rem_bda;
106 return (false);
107 }
108
109 if (p_lcb->transport != BT_TRANSPORT_LE) {
110 LOG(WARNING) << __func__ << " - BD_ADDR " << rem_bda << " not LE";
111 return (false);
112 }
113
114 VLOG(2) << __func__ << ": BD_ADDR=" << rem_bda << ", min_int=" << min_int
115 << ", max_int=" << max_int << ", min_ce_len=" << min_ce_len
116 << ", max_ce_len=" << max_ce_len;
117
118 p_lcb->min_interval = min_int;
119 p_lcb->max_interval = max_int;
120 p_lcb->latency = latency;
121 p_lcb->timeout = timeout;
122 p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
123 p_lcb->min_ce_len = min_ce_len;
124 p_lcb->max_ce_len = max_ce_len;
125
126 l2cble_start_conn_update(p_lcb);
127
128 return (true);
129 }
130
131 /*******************************************************************************
132 *
133 * Function L2CA_EnableUpdateBleConnParams
134 *
135 * Description Enable or disable update based on the request from the peer
136 *
137 * Parameters: BD Address of remote
138 *
139 * Return value: true if update started
140 *
141 ******************************************************************************/
L2CA_EnableUpdateBleConnParams(const RawAddress & rem_bda,bool enable)142 bool L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda, bool enable) {
143 if (bluetooth::shim::is_gd_l2cap_enabled()) {
144 return bluetooth::shim::L2CA_EnableUpdateBleConnParams(rem_bda, enable);
145 }
146
147 if (stack_config_get_interface()->get_pts_conn_updates_disabled())
148 return false;
149
150 tL2C_LCB* p_lcb;
151
152 /* See if we have a link control block for the remote device */
153 p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
154
155 if (!p_lcb) {
156 LOG(WARNING) << __func__ << " - unknown BD_ADDR " << rem_bda;
157 return false;
158 }
159
160 VLOG(2) << __func__ << " - BD_ADDR " << rem_bda
161 << StringPrintf(" enable %d current upd state 0x%02x", enable,
162 p_lcb->conn_update_mask);
163
164 if (p_lcb->transport != BT_TRANSPORT_LE) {
165 LOG(WARNING) << __func__ << " - BD_ADDR " << rem_bda
166 << " not LE, link role " << p_lcb->LinkRole();
167 return false;
168 }
169
170 if (enable) {
171 p_lcb->conn_update_mask &= ~L2C_BLE_CONN_UPDATE_DISABLE;
172 p_lcb->subrate_req_mask &= ~L2C_BLE_SUBRATE_REQ_DISABLE;
173 } else {
174 p_lcb->conn_update_mask |= L2C_BLE_CONN_UPDATE_DISABLE;
175 p_lcb->subrate_req_mask |= L2C_BLE_SUBRATE_REQ_DISABLE;
176 }
177
178 l2cble_start_conn_update(p_lcb);
179
180 return (true);
181 }
182
L2CA_Consolidate(const RawAddress & identity_addr,const RawAddress & rpa)183 void L2CA_Consolidate(const RawAddress& identity_addr, const RawAddress& rpa) {
184 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rpa, BT_TRANSPORT_LE);
185 if (p_lcb == nullptr) {
186 return;
187 }
188
189 LOG_INFO("consolidating l2c_lcb record %s -> %s",
190 ADDRESS_TO_LOGGABLE_CSTR(rpa),
191 ADDRESS_TO_LOGGABLE_CSTR(identity_addr));
192 p_lcb->remote_bd_addr = identity_addr;
193 }
194
L2CA_GetBleConnRole(const RawAddress & bd_addr)195 hci_role_t L2CA_GetBleConnRole(const RawAddress& bd_addr) {
196 if (bluetooth::shim::is_gd_l2cap_enabled()) {
197 return bluetooth::shim::L2CA_GetBleConnRole(bd_addr);
198 }
199
200 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
201 if (p_lcb == nullptr) {
202 return HCI_ROLE_UNKNOWN;
203 }
204 return p_lcb->LinkRole();
205 }
206
207 /*******************************************************************************
208 *
209 * Function l2cble_notify_le_connection
210 *
211 * Description This function notifiy the l2cap connection to the app layer
212 *
213 * Returns none
214 *
215 ******************************************************************************/
l2cble_notify_le_connection(const RawAddress & bda)216 void l2cble_notify_le_connection(const RawAddress& bda) {
217 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
218 if (p_lcb == nullptr) {
219 LOG_WARN("Received notification for le connection but no lcb found");
220 return;
221 }
222
223 if (BTM_IsAclConnectionUp(bda, BT_TRANSPORT_LE) &&
224 p_lcb->link_state != LST_CONNECTED) {
225 /* update link status */
226 // TODO Move this back into acl layer
227 btm_establish_continue_from_address(bda, BT_TRANSPORT_LE);
228 /* update l2cap link status and send callback */
229 p_lcb->link_state = LST_CONNECTED;
230 l2cu_process_fixed_chnl_resp(p_lcb);
231 }
232
233 /* For all channels, send the event through their FSMs */
234 for (tL2C_CCB* p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
235 p_ccb = p_ccb->p_next_ccb) {
236 if (p_ccb->chnl_state == CST_CLOSED)
237 l2c_csm_execute(p_ccb, L2CEVT_LP_CONNECT_CFM, NULL);
238 }
239 }
240
241 /** This function is called when an HCI Connection Complete event is received.
242 */
l2cble_conn_comp(uint16_t handle,uint8_t role,const RawAddress & bda,tBLE_ADDR_TYPE type,uint16_t conn_interval,uint16_t conn_latency,uint16_t conn_timeout)243 bool l2cble_conn_comp(uint16_t handle, uint8_t role, const RawAddress& bda,
244 tBLE_ADDR_TYPE type, uint16_t conn_interval,
245 uint16_t conn_latency, uint16_t conn_timeout) {
246 // role == HCI_ROLE_CENTRAL => scanner completed connection
247 // role == HCI_ROLE_PERIPHERAL => advertiser completed connection
248
249 /* See if we have a link control block for the remote device */
250 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
251
252 /* If we do not have one, create one. this is auto connection complete. */
253 if (!p_lcb) {
254 p_lcb = l2cu_allocate_lcb(bda, false, BT_TRANSPORT_LE);
255 if (!p_lcb) {
256 LOG_ERROR("Unable to allocate link resource for le acl connection");
257 return false;
258 } else {
259 if (!l2cu_initialize_fixed_ccb(p_lcb, L2CAP_ATT_CID)) {
260 LOG_ERROR("Unable to allocate channel resource for le acl connection");
261 return false;
262 }
263 }
264 } else if (role == HCI_ROLE_CENTRAL && p_lcb->link_state != LST_CONNECTING) {
265 LOG_ERROR(
266 "Received le acl connection as role central but not in connecting "
267 "state");
268 return false;
269 }
270
271 if (role == HCI_ROLE_CENTRAL) alarm_cancel(p_lcb->l2c_lcb_timer);
272
273 /* Save the handle */
274 l2cu_set_lcb_handle(*p_lcb, handle);
275
276 /* Connected OK. Change state to connected, we were scanning so we are central
277 */
278 if (role == HCI_ROLE_CENTRAL) {
279 p_lcb->SetLinkRoleAsCentral();
280 } else {
281 p_lcb->SetLinkRoleAsPeripheral();
282 }
283
284 p_lcb->transport = BT_TRANSPORT_LE;
285
286 /* update link parameter, set peripheral link as non-spec default upon link up
287 */
288 p_lcb->min_interval = p_lcb->max_interval = conn_interval;
289 p_lcb->timeout = conn_timeout;
290 p_lcb->latency = conn_latency;
291 p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM;
292
293 p_lcb->subrate_req_mask = 0;
294 p_lcb->subrate_min = 1;
295 p_lcb->subrate_max = 1;
296 p_lcb->max_latency = 0;
297 p_lcb->cont_num = 0;
298 p_lcb->supervision_tout = 0;
299
300 p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT |
301 L2CAP_FIXED_CHNL_BLE_SIG_BIT |
302 L2CAP_FIXED_CHNL_SMP_BIT;
303
304 if (role == HCI_ROLE_PERIPHERAL) {
305 if (!controller_get_interface()
306 ->supports_ble_peripheral_initiated_feature_exchange()) {
307 p_lcb->link_state = LST_CONNECTED;
308 l2cu_process_fixed_chnl_resp(p_lcb);
309 }
310 }
311 return true;
312 }
313
l2cble_conn_comp_from_address_with_type(uint16_t handle,uint8_t role,const tBLE_BD_ADDR & address_with_type,uint16_t conn_interval,uint16_t conn_latency,uint16_t conn_timeout)314 bool l2cble_conn_comp_from_address_with_type(
315 uint16_t handle, uint8_t role, const tBLE_BD_ADDR& address_with_type,
316 uint16_t conn_interval, uint16_t conn_latency, uint16_t conn_timeout) {
317 return l2cble_conn_comp(handle, role, address_with_type.bda,
318 address_with_type.type, conn_interval, conn_latency,
319 conn_timeout);
320 }
321
322 /*******************************************************************************
323 *
324 * Function l2cble_start_conn_update
325 *
326 * Description Start the BLE connection parameter update process based on
327 * status.
328 *
329 * Parameters: lcb : l2cap link control block
330 *
331 * Return value: none
332 *
333 ******************************************************************************/
l2cble_start_conn_update(tL2C_LCB * p_lcb)334 static void l2cble_start_conn_update(tL2C_LCB* p_lcb) {
335 uint16_t min_conn_int, max_conn_int, peripheral_latency, supervision_tout;
336 if (!BTM_IsAclConnectionUp(p_lcb->remote_bd_addr, BT_TRANSPORT_LE)) {
337 LOG(ERROR) << "No known connection ACL for " << p_lcb->remote_bd_addr;
338 return;
339 }
340
341 // TODO(armansito): The return value of this call wasn't being used but the
342 // logic of this function might be depending on its side effects. We should
343 // verify if this call is needed at all and remove it otherwise.
344 btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
345
346 if ((p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) ||
347 (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_PENDING)) {
348 return;
349 }
350
351 if (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) {
352 /* application requests to disable parameters update.
353 If parameters are already updated, lets set them
354 up to what has been requested during connection establishement */
355 if (p_lcb->conn_update_mask & L2C_BLE_NOT_DEFAULT_PARAM &&
356 /* current connection interval is greater than default min */
357 p_lcb->min_interval > BTM_BLE_CONN_INT_MIN) {
358 /* use 7.5 ms as fast connection parameter, 0 peripheral latency */
359 min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN;
360
361 L2CA_AdjustConnectionIntervals(&min_conn_int, &max_conn_int,
362 BTM_BLE_CONN_INT_MIN);
363
364 peripheral_latency = BTM_BLE_CONN_PERIPHERAL_LATENCY_DEF;
365 supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF;
366
367 /* if both side 4.1, or we are central device, send HCI command */
368 if (p_lcb->IsLinkRoleCentral()
369 || (controller_get_interface()
370 ->supports_ble_connection_parameter_request() &&
371 acl_peer_supports_ble_connection_parameters_request(
372 p_lcb->remote_bd_addr))
373 ) {
374 btsnd_hcic_ble_upd_ll_conn_params(p_lcb->Handle(), min_conn_int,
375 max_conn_int, peripheral_latency,
376 supervision_tout, 0, 0);
377 p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
378 } else {
379 l2cu_send_peer_ble_par_req(p_lcb, min_conn_int, max_conn_int,
380 peripheral_latency, supervision_tout);
381 }
382 p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM;
383 p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
384 }
385 } else {
386 /* application allows to do update, if we were delaying one do it now */
387 if (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM) {
388 /* if both side 4.1, or we are central device, send HCI command */
389 if (p_lcb->IsLinkRoleCentral()
390 || (controller_get_interface()
391 ->supports_ble_connection_parameter_request() &&
392 acl_peer_supports_ble_connection_parameters_request(
393 p_lcb->remote_bd_addr))
394 ) {
395 btsnd_hcic_ble_upd_ll_conn_params(p_lcb->Handle(), p_lcb->min_interval,
396 p_lcb->max_interval, p_lcb->latency,
397 p_lcb->timeout, p_lcb->min_ce_len,
398 p_lcb->max_ce_len);
399 p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
400 } else {
401 l2cu_send_peer_ble_par_req(p_lcb, p_lcb->min_interval,
402 p_lcb->max_interval, p_lcb->latency,
403 p_lcb->timeout);
404 }
405 p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM;
406 p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM;
407 }
408 }
409 }
410
411 /*******************************************************************************
412 *
413 * Function l2cble_process_conn_update_evt
414 *
415 * Description This function enables the connection update request from
416 * remote after a successful connection update response is
417 * received.
418 *
419 * Returns void
420 *
421 ******************************************************************************/
l2cble_process_conn_update_evt(uint16_t handle,uint8_t status,uint16_t interval,uint16_t latency,uint16_t timeout)422 void l2cble_process_conn_update_evt(uint16_t handle, uint8_t status,
423 uint16_t interval, uint16_t latency,
424 uint16_t timeout) {
425 L2CAP_TRACE_DEBUG("%s", __func__);
426
427 /* See if we have a link control block for the remote device */
428 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
429 if (!p_lcb) {
430 L2CAP_TRACE_WARNING("%s: Invalid handle: %d", __func__, handle);
431 return;
432 }
433
434 p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
435
436 if (status != HCI_SUCCESS) {
437 L2CAP_TRACE_WARNING("%s: Error status: %d", __func__, status);
438 }
439
440 l2cble_start_conn_update(p_lcb);
441
442 l2cble_start_subrate_change(p_lcb);
443
444 L2CAP_TRACE_DEBUG("%s: conn_update_mask=%d , subrate_req_mask=%d", __func__,
445 p_lcb->conn_update_mask, p_lcb->subrate_req_mask);
446 }
447
448 /*******************************************************************************
449 *
450 * Function l2cble_handle_connect_rsp_neg
451 *
452 * Description This function sends error message to all the
453 * outstanding channels
454 *
455 * Returns void
456 *
457 ******************************************************************************/
l2cble_handle_connect_rsp_neg(tL2C_LCB * p_lcb,tL2C_CONN_INFO * con_info)458 static void l2cble_handle_connect_rsp_neg(tL2C_LCB* p_lcb,
459 tL2C_CONN_INFO* con_info) {
460 tL2C_CCB* temp_p_ccb = NULL;
461 for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) {
462 uint16_t cid = p_lcb->pending_ecoc_connection_cids[i];
463 temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
464 l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
465 con_info);
466 }
467
468 p_lcb->pending_ecoc_conn_cnt = 0;
469 memset(p_lcb->pending_ecoc_connection_cids, 0, L2CAP_CREDIT_BASED_MAX_CIDS);
470 }
471
472 /*******************************************************************************
473 *
474 * Function l2cble_process_sig_cmd
475 *
476 * Description This function is called when a signalling packet is received
477 * on the BLE signalling CID
478 *
479 * Returns void
480 *
481 ******************************************************************************/
l2cble_process_sig_cmd(tL2C_LCB * p_lcb,uint8_t * p,uint16_t pkt_len)482 void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) {
483 uint8_t* p_pkt_end;
484 uint8_t cmd_code, id;
485 uint16_t cmd_len;
486 uint16_t min_interval, max_interval, latency, timeout;
487 tL2C_CONN_INFO con_info;
488 uint16_t lcid = 0, rcid = 0, mtu = 0, mps = 0, initial_credit = 0;
489 tL2C_CCB *p_ccb = NULL, *temp_p_ccb = NULL;
490 tL2C_RCB* p_rcb;
491 uint16_t credit;
492 uint8_t num_of_channels;
493
494 p_pkt_end = p + pkt_len;
495
496 if (p + 4 > p_pkt_end) {
497 LOG(ERROR) << "invalid read";
498 return;
499 }
500
501 STREAM_TO_UINT8(cmd_code, p);
502 STREAM_TO_UINT8(id, p);
503 STREAM_TO_UINT16(cmd_len, p);
504
505 /* Check command length does not exceed packet length */
506 if ((p + cmd_len) > p_pkt_end) {
507 L2CAP_TRACE_WARNING(
508 "L2CAP - LE - format error, pkt_len: %d cmd_len: %d code: %d",
509 pkt_len, cmd_len, cmd_code);
510 return;
511 }
512
513 switch (cmd_code) {
514 case L2CAP_CMD_REJECT: {
515 uint16_t reason;
516
517 if (p + 2 > p_pkt_end) {
518 LOG(ERROR) << "invalid L2CAP_CMD_REJECT packet,"
519 << " not containing enough data for `reason` field";
520 return;
521 }
522
523 STREAM_TO_UINT16(reason, p);
524
525 if (reason == L2CAP_CMD_REJ_NOT_UNDERSTOOD &&
526 p_lcb->pending_ecoc_conn_cnt > 0) {
527 con_info.l2cap_result = L2CAP_LE_RESULT_NO_PSM;
528 l2cble_handle_connect_rsp_neg(p_lcb, &con_info);
529 }
530 } break;
531
532 case L2CAP_CMD_ECHO_REQ:
533 case L2CAP_CMD_ECHO_RSP:
534 case L2CAP_CMD_INFO_RSP:
535 case L2CAP_CMD_INFO_REQ:
536 l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
537 break;
538
539 case L2CAP_CMD_BLE_UPDATE_REQ:
540 if (p + 8 > p_pkt_end) {
541 LOG(ERROR) << "invalid read";
542 return;
543 }
544
545 STREAM_TO_UINT16(min_interval, p); /* 0x0006 - 0x0C80 */
546 STREAM_TO_UINT16(max_interval, p); /* 0x0006 - 0x0C80 */
547 STREAM_TO_UINT16(latency, p); /* 0x0000 - 0x03E8 */
548 STREAM_TO_UINT16(timeout, p); /* 0x000A - 0x0C80 */
549 /* If we are a central, the peripheral wants to update the parameters */
550 if (p_lcb->IsLinkRoleCentral()) {
551 L2CA_AdjustConnectionIntervals(&min_interval, &max_interval,
552 BTM_BLE_CONN_INT_MIN_LIMIT);
553
554 if (min_interval < BTM_BLE_CONN_INT_MIN ||
555 min_interval > BTM_BLE_CONN_INT_MAX ||
556 max_interval < BTM_BLE_CONN_INT_MIN ||
557 max_interval > BTM_BLE_CONN_INT_MAX ||
558 latency > BTM_BLE_CONN_LATENCY_MAX ||
559 /*(timeout >= max_interval && latency > (timeout * 10/(max_interval
560 * 1.25) - 1)) ||*/
561 timeout < BTM_BLE_CONN_SUP_TOUT_MIN ||
562 timeout > BTM_BLE_CONN_SUP_TOUT_MAX ||
563 max_interval < min_interval) {
564 l2cu_send_peer_ble_par_rsp(p_lcb, L2CAP_CFG_UNACCEPTABLE_PARAMS, id);
565 } else {
566 l2cu_send_peer_ble_par_rsp(p_lcb, L2CAP_CFG_OK, id);
567
568 p_lcb->min_interval = min_interval;
569 p_lcb->max_interval = max_interval;
570 p_lcb->latency = latency;
571 p_lcb->timeout = timeout;
572 p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
573
574 l2cble_start_conn_update(p_lcb);
575 }
576 } else
577 l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0,
578 0);
579 break;
580
581 case L2CAP_CMD_BLE_UPDATE_RSP:
582 p += 2;
583 break;
584
585 case L2CAP_CMD_CREDIT_BASED_CONN_REQ: {
586 if (p + 10 > p_pkt_end) {
587 LOG(ERROR) << "invalid L2CAP_CMD_CREDIT_BASED_CONN_REQ len";
588 return;
589 }
590
591 STREAM_TO_UINT16(con_info.psm, p);
592 STREAM_TO_UINT16(mtu, p);
593 STREAM_TO_UINT16(mps, p);
594 STREAM_TO_UINT16(initial_credit, p);
595
596 /* Check how many channels remote side wants. */
597 num_of_channels = (p_pkt_end - p) / sizeof(uint16_t);
598 if (num_of_channels > L2CAP_CREDIT_BASED_MAX_CIDS) {
599 LOG_WARN("L2CAP - invalid number of channels requested: %d",
600 num_of_channels);
601 l2cu_reject_credit_based_conn_req(p_lcb, id,
602 L2CAP_CREDIT_BASED_MAX_CIDS,
603 L2CAP_LE_RESULT_INVALID_PARAMETERS);
604 return;
605 }
606
607 LOG_DEBUG(
608 "Recv L2CAP_CMD_CREDIT_BASED_CONN_REQ with "
609 "mtu = %d, "
610 "mps = %d, "
611 "initial credit = %d"
612 "num_of_channels = %d",
613 mtu, mps, initial_credit, num_of_channels);
614
615 /* Check PSM Support */
616 p_rcb = l2cu_find_ble_rcb_by_psm(con_info.psm);
617 if (p_rcb == NULL) {
618 LOG_WARN("L2CAP - rcvd conn req for unknown PSM: 0x%04x", con_info.psm);
619 l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels,
620 L2CAP_LE_RESULT_NO_PSM);
621 return;
622 }
623
624 if (p_lcb->pending_ecoc_conn_cnt > 0) {
625 LOG_WARN("L2CAP - L2CAP_CMD_CREDIT_BASED_CONN_REQ collision:");
626 if (p_rcb->api.pL2CA_CreditBasedCollisionInd_Cb &&
627 con_info.psm == BT_PSM_EATT) {
628 (*p_rcb->api.pL2CA_CreditBasedCollisionInd_Cb)(p_lcb->remote_bd_addr);
629 }
630 l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels,
631 L2CAP_LE_RESULT_NO_RESOURCES);
632 return;
633 }
634
635 p_lcb->pending_ecoc_conn_cnt = num_of_channels;
636
637 if (!p_rcb->api.pL2CA_CreditBasedConnectInd_Cb) {
638 LOG_WARN("L2CAP - rcvd conn req for outgoing-only connection PSM: %d",
639 con_info.psm);
640 l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels,
641 L2CAP_CONN_NO_PSM);
642 return;
643 }
644
645 /* validate the parameters */
646 if (mtu < L2CAP_CREDIT_BASED_MIN_MTU ||
647 mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) {
648 LOG_ERROR("L2CAP don't like the params");
649 l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels,
650 L2CAP_LE_RESULT_INVALID_PARAMETERS);
651 return;
652 }
653
654 bool lead_cid_set = false;
655
656 for (int i = 0; i < num_of_channels; i++) {
657 STREAM_TO_UINT16(rcid, p);
658 temp_p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
659 if (temp_p_ccb) {
660 LOG_WARN("L2CAP - rcvd conn req for duplicated cid: 0x%04x", rcid);
661 p_lcb->pending_ecoc_connection_cids[i] = 0;
662 p_lcb->pending_l2cap_result =
663 L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED;
664 } else {
665 /* Allocate a ccb for this.*/
666 temp_p_ccb = l2cu_allocate_ccb(p_lcb, 0);
667 if (temp_p_ccb == NULL) {
668 LOG_ERROR("L2CAP - unable to allocate CCB");
669 p_lcb->pending_ecoc_connection_cids[i] = 0;
670 p_lcb->pending_l2cap_result = L2CAP_LE_RESULT_NO_RESOURCES;
671 continue;
672 }
673
674 temp_p_ccb->ecoc = true;
675 temp_p_ccb->remote_id = id;
676 temp_p_ccb->p_rcb = p_rcb;
677 temp_p_ccb->remote_cid = rcid;
678
679 temp_p_ccb->peer_conn_cfg.mtu = mtu;
680 temp_p_ccb->peer_conn_cfg.mps = mps;
681 temp_p_ccb->peer_conn_cfg.credits = initial_credit;
682
683 temp_p_ccb->tx_mps = mps;
684 temp_p_ccb->ble_sdu = NULL;
685 temp_p_ccb->ble_sdu_length = 0;
686 temp_p_ccb->is_first_seg = true;
687 temp_p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
688
689 /* This list will be used to prepare response */
690 p_lcb->pending_ecoc_connection_cids[i] = temp_p_ccb->local_cid;
691
692 /*This is going to be our lead p_ccb for state machine */
693 if (!lead_cid_set) {
694 p_ccb = temp_p_ccb;
695 p_ccb->local_conn_cfg.mtu = L2CAP_SDU_LENGTH_LE_MAX;
696 p_ccb->local_conn_cfg.mps =
697 controller_get_interface()->get_acl_data_size_ble();
698 p_lcb->pending_lead_cid = p_ccb->local_cid;
699 lead_cid_set = true;
700 }
701 }
702 }
703
704 if (!lead_cid_set) {
705 LOG_ERROR("L2CAP - unable to allocate CCB");
706 l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels,
707 p_lcb->pending_l2cap_result);
708 return;
709 }
710
711 LOG_DEBUG("L2CAP - processing peer credit based connect request");
712 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_REQ, NULL);
713 break;
714 }
715 case L2CAP_CMD_CREDIT_BASED_CONN_RES:
716 if (p + 8 > p_pkt_end) {
717 LOG(ERROR) << "invalid L2CAP_CMD_CREDIT_BASED_CONN_RES len";
718 return;
719 }
720
721 L2CAP_TRACE_DEBUG("Recv L2CAP_CMD_CREDIT_BASED_CONN_RES");
722 /* For all channels, see whose identifier matches this id */
723 for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb;
724 temp_p_ccb = temp_p_ccb->p_next_ccb) {
725 if (temp_p_ccb->local_id == id) {
726 p_ccb = temp_p_ccb;
727 break;
728 }
729 }
730
731 if (!p_ccb) {
732 L2CAP_TRACE_DEBUG(" Cannot find matching connection req");
733 con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_SOURCE_CID;
734 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
735 return;
736 }
737
738 STREAM_TO_UINT16(mtu, p);
739 STREAM_TO_UINT16(mps, p);
740 STREAM_TO_UINT16(initial_credit, p);
741 STREAM_TO_UINT16(con_info.l2cap_result, p);
742
743 /* When one of these result is sent back that means,
744 * all the channels has been rejected
745 */
746 if (con_info.l2cap_result == L2CAP_LE_RESULT_NO_PSM ||
747 con_info.l2cap_result ==
748 L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION ||
749 con_info.l2cap_result == L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP ||
750 con_info.l2cap_result == L2CAP_LE_RESULT_INSUFFICIENT_AUTHORIZATION ||
751 con_info.l2cap_result == L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS ||
752 con_info.l2cap_result == L2CAP_LE_RESULT_INVALID_PARAMETERS) {
753 L2CAP_TRACE_ERROR("L2CAP - not accepted. Status %d",
754 con_info.l2cap_result);
755 l2cble_handle_connect_rsp_neg(p_lcb, &con_info);
756 return;
757 }
758
759 /* validate the parameters */
760 if (mtu < L2CAP_CREDIT_BASED_MIN_MTU ||
761 mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) {
762 L2CAP_TRACE_ERROR("L2CAP - invalid params");
763 con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_PARAMETERS;
764 l2cble_handle_connect_rsp_neg(p_lcb, &con_info);
765 return;
766 }
767
768 /* At least some of the channels has been created and parameters are
769 * good*/
770 num_of_channels = (p_pkt_end - p) / sizeof(uint16_t);
771 if (num_of_channels != p_lcb->pending_ecoc_conn_cnt) {
772 L2CAP_TRACE_ERROR(
773 "Incorrect response."
774 "expected num of channels = %d",
775 "received num of channels = %d", num_of_channels,
776 p_lcb->pending_ecoc_conn_cnt);
777 return;
778 }
779
780 L2CAP_TRACE_DEBUG(
781 "mtu = %d, "
782 "mps = %d, "
783 "initial_credit = %d, "
784 "con_info.l2cap_result = %d"
785 "num_of_channels = %d",
786 mtu, mps, initial_credit, con_info.l2cap_result, num_of_channels);
787
788 con_info.peer_mtu = mtu;
789
790 /* Copy request data and clear it so user can perform another connect if
791 * needed in the callback. */
792 p_lcb->pending_ecoc_conn_cnt = 0;
793 uint16_t cids[L2CAP_CREDIT_BASED_MAX_CIDS];
794 std::copy_n(p_lcb->pending_ecoc_connection_cids,
795 L2CAP_CREDIT_BASED_MAX_CIDS, cids);
796 std::fill_n(p_lcb->pending_ecoc_connection_cids,
797 L2CAP_CREDIT_BASED_MAX_CIDS, 0);
798
799 for (int i = 0; i < num_of_channels; i++) {
800 uint16_t cid = cids[i];
801 STREAM_TO_UINT16(rcid, p);
802
803 if (rcid != 0) {
804 /* If remote cid is duplicated then disconnect original channel
805 * and current channel by sending event to upper layer
806 */
807 temp_p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
808 if (temp_p_ccb != nullptr) {
809 L2CAP_TRACE_ERROR(
810 "Already Allocated Destination cid. "
811 "rcid = %d "
812 "send peer_disc_req",
813 rcid);
814
815 l2cu_send_peer_disc_req(temp_p_ccb);
816
817 temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
818 con_info.l2cap_result = L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS;
819 l2c_csm_execute(temp_p_ccb,
820 L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
821 &con_info);
822 continue;
823 }
824 }
825
826 temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
827 temp_p_ccb->remote_cid = rcid;
828
829 L2CAP_TRACE_DEBUG(
830 "local cid = %d "
831 "remote cid = %d",
832 cid, temp_p_ccb->remote_cid);
833
834 /* Check if peer accepted channel, if not release the one not
835 * created
836 */
837 if (temp_p_ccb->remote_cid == 0) {
838 l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG,
839 &con_info);
840 } else {
841 temp_p_ccb->tx_mps = mps;
842 temp_p_ccb->ble_sdu = NULL;
843 temp_p_ccb->ble_sdu_length = 0;
844 temp_p_ccb->is_first_seg = true;
845 temp_p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
846 temp_p_ccb->peer_conn_cfg.mtu = mtu;
847 temp_p_ccb->peer_conn_cfg.mps = mps;
848 temp_p_ccb->peer_conn_cfg.credits = initial_credit;
849
850 l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP,
851 &con_info);
852 }
853 }
854
855 break;
856 case L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ: {
857 if (p + 6 > p_pkt_end) {
858 l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_UNACCAPTED_PARAM);
859 return;
860 }
861
862 STREAM_TO_UINT16(mtu, p);
863 STREAM_TO_UINT16(mps, p);
864
865 /* validate the parameters */
866 if (mtu < L2CAP_CREDIT_BASED_MIN_MTU ||
867 mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) {
868 L2CAP_TRACE_ERROR("L2CAP - invalid params");
869 l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_UNACCAPTED_PARAM);
870 return;
871 }
872
873 /* Check how many channels remote side wants to reconfigure */
874 num_of_channels = (p_pkt_end - p) / sizeof(uint16_t);
875
876 L2CAP_TRACE_DEBUG(
877 "Recv L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ with "
878 "mtu = %d, "
879 "mps = %d, "
880 "num_of_channels = %d",
881 mtu, mps, num_of_channels);
882
883 uint8_t* p_tmp = p;
884 for (int i = 0; i < num_of_channels; i++) {
885 STREAM_TO_UINT16(rcid, p_tmp);
886 p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
887 if (!p_ccb) {
888 L2CAP_TRACE_WARNING(
889 "L2CAP - rcvd config req for non existing cid: 0x%04x", rcid);
890 l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_INVALID_DCID);
891 return;
892 }
893
894 if (p_ccb->peer_conn_cfg.mtu > mtu) {
895 L2CAP_TRACE_WARNING(
896 "L2CAP - rcvd config req mtu reduction new mtu < mtu (%d < %d)",
897 mtu, p_ccb->peer_conn_cfg.mtu);
898 l2cu_send_ble_reconfig_rsp(p_lcb, id,
899 L2CAP_RECONFIG_REDUCTION_MTU_NO_ALLOWED);
900 return;
901 }
902
903 if (p_ccb->peer_conn_cfg.mps > mps && num_of_channels > 1) {
904 L2CAP_TRACE_WARNING(
905 "L2CAP - rcvd config req mps reduction new mps < mps (%d < %d)",
906 mtu, p_ccb->peer_conn_cfg.mtu);
907 l2cu_send_ble_reconfig_rsp(p_lcb, id,
908 L2CAP_RECONFIG_REDUCTION_MPS_NO_ALLOWED);
909 return;
910 }
911 }
912
913 for (int i = 0; i < num_of_channels; i++) {
914 STREAM_TO_UINT16(rcid, p);
915
916 /* Store new values */
917 p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
918 p_ccb->peer_conn_cfg.mtu = mtu;
919 p_ccb->peer_conn_cfg.mps = mps;
920 p_ccb->tx_mps = mps;
921
922 tL2CAP_LE_CFG_INFO le_cfg;
923 le_cfg.mps = mps;
924 le_cfg.mtu = mtu;
925
926 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CREDIT_BASED_RECONFIG_REQ, &le_cfg);
927 }
928
929 l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_SUCCEED);
930
931 break;
932 }
933
934 case L2CAP_CMD_CREDIT_BASED_RECONFIG_RES: {
935 uint16_t result;
936 if (p + sizeof(uint16_t) > p_pkt_end) {
937 LOG(ERROR) << "invalid read";
938 return;
939 }
940 STREAM_TO_UINT16(result, p);
941
942 L2CAP_TRACE_DEBUG(
943 "Recv L2CAP_CMD_CREDIT_BASED_RECONFIG_RES for "
944 "result = 0x%04x",
945 result);
946
947 p_lcb->pending_ecoc_reconfig_cfg.result = result;
948
949 /* All channels which are in reconfiguration state are marked with
950 * reconfig_started flag. Find it and send response
951 */
952 for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb;
953 temp_p_ccb = temp_p_ccb->p_next_ccb) {
954 if ((temp_p_ccb->in_use) && (temp_p_ccb->reconfig_started)) {
955 l2c_csm_execute(temp_p_ccb, L2CEVT_L2CAP_CREDIT_BASED_RECONFIG_RSP,
956 &p_lcb->pending_ecoc_reconfig_cfg);
957
958 temp_p_ccb->reconfig_started = false;
959 if (result == L2CAP_CFG_OK) {
960 temp_p_ccb->local_conn_cfg = p_lcb->pending_ecoc_reconfig_cfg;
961 }
962 }
963 }
964
965 break;
966 }
967
968 case L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ:
969 if (p + 10 > p_pkt_end) {
970 LOG(ERROR) << "invalid read";
971 return;
972 }
973
974 STREAM_TO_UINT16(con_info.psm, p);
975 STREAM_TO_UINT16(rcid, p);
976 STREAM_TO_UINT16(mtu, p);
977 STREAM_TO_UINT16(mps, p);
978 STREAM_TO_UINT16(initial_credit, p);
979
980 L2CAP_TRACE_DEBUG(
981 "Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ with "
982 "mtu = %d, "
983 "mps = %d, "
984 "initial credit = %d",
985 mtu, mps, initial_credit);
986
987 p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid);
988 if (p_ccb) {
989 L2CAP_TRACE_WARNING("L2CAP - rcvd conn req for duplicated cid: 0x%04x",
990 rcid);
991 l2cu_reject_ble_coc_connection(
992 p_lcb, id, L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED);
993 break;
994 }
995
996 p_rcb = l2cu_find_ble_rcb_by_psm(con_info.psm);
997 if (p_rcb == NULL) {
998 L2CAP_TRACE_WARNING("L2CAP - rcvd conn req for unknown PSM: 0x%04x",
999 con_info.psm);
1000 l2cu_reject_ble_coc_connection(p_lcb, id, L2CAP_LE_RESULT_NO_PSM);
1001 break;
1002 } else {
1003 if (!p_rcb->api.pL2CA_ConnectInd_Cb) {
1004 L2CAP_TRACE_WARNING(
1005 "L2CAP - rcvd conn req for outgoing-only connection PSM: %d",
1006 con_info.psm);
1007 l2cu_reject_ble_coc_connection(p_lcb, id, L2CAP_CONN_NO_PSM);
1008 break;
1009 }
1010 }
1011
1012 /* Allocate a ccb for this.*/
1013 p_ccb = l2cu_allocate_ccb(p_lcb, 0);
1014 if (p_ccb == NULL) {
1015 L2CAP_TRACE_ERROR("L2CAP - unable to allocate CCB");
1016 l2cu_reject_ble_connection(p_ccb, id, L2CAP_CONN_NO_RESOURCES);
1017 break;
1018 }
1019
1020 /* validate the parameters */
1021 if (mtu < L2CAP_LE_MIN_MTU || mps < L2CAP_LE_MIN_MPS ||
1022 mps > L2CAP_LE_MAX_MPS) {
1023 L2CAP_TRACE_ERROR("L2CAP do not like the params");
1024 l2cu_reject_ble_connection(p_ccb, id, L2CAP_CONN_NO_RESOURCES);
1025 break;
1026 }
1027
1028 p_ccb->remote_id = id;
1029 p_ccb->p_rcb = p_rcb;
1030 p_ccb->remote_cid = rcid;
1031
1032 p_ccb->local_conn_cfg.mtu = L2CAP_SDU_LENGTH_LE_MAX;
1033 p_ccb->local_conn_cfg.mps =
1034 controller_get_interface()->get_acl_data_size_ble();
1035 p_ccb->local_conn_cfg.credits = L2CA_LeCreditDefault();
1036 p_ccb->remote_credit_count = L2CA_LeCreditDefault();
1037
1038 p_ccb->peer_conn_cfg.mtu = mtu;
1039 p_ccb->peer_conn_cfg.mps = mps;
1040 p_ccb->peer_conn_cfg.credits = initial_credit;
1041
1042 p_ccb->tx_mps = mps;
1043 p_ccb->ble_sdu = NULL;
1044 p_ccb->ble_sdu_length = 0;
1045 p_ccb->is_first_seg = true;
1046 p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
1047
1048 p_ccb->connection_initiator = L2CAP_INITIATOR_REMOTE;
1049
1050 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_REQ, &con_info);
1051 break;
1052
1053 case L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES:
1054 L2CAP_TRACE_DEBUG("Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES");
1055 /* For all channels, see whose identifier matches this id */
1056 for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb;
1057 temp_p_ccb = temp_p_ccb->p_next_ccb) {
1058 if (temp_p_ccb->local_id == id) {
1059 p_ccb = temp_p_ccb;
1060 break;
1061 }
1062 }
1063 if (p_ccb) {
1064 L2CAP_TRACE_DEBUG("I remember the connection req");
1065 if (p + 10 > p_pkt_end) {
1066 LOG(ERROR) << "invalid read";
1067 return;
1068 }
1069
1070 STREAM_TO_UINT16(p_ccb->remote_cid, p);
1071 STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mtu, p);
1072 STREAM_TO_UINT16(p_ccb->peer_conn_cfg.mps, p);
1073 STREAM_TO_UINT16(p_ccb->peer_conn_cfg.credits, p);
1074 STREAM_TO_UINT16(con_info.l2cap_result, p);
1075 con_info.remote_cid = p_ccb->remote_cid;
1076
1077 L2CAP_TRACE_DEBUG(
1078 "remote_cid = %d, "
1079 "mtu = %d, "
1080 "mps = %d, "
1081 "initial_credit = %d, "
1082 "con_info.l2cap_result = %d",
1083 p_ccb->remote_cid, p_ccb->peer_conn_cfg.mtu,
1084 p_ccb->peer_conn_cfg.mps, p_ccb->peer_conn_cfg.credits,
1085 con_info.l2cap_result);
1086
1087 /* validate the parameters */
1088 if (p_ccb->peer_conn_cfg.mtu < L2CAP_LE_MIN_MTU ||
1089 p_ccb->peer_conn_cfg.mps < L2CAP_LE_MIN_MPS ||
1090 p_ccb->peer_conn_cfg.mps > L2CAP_LE_MAX_MPS) {
1091 L2CAP_TRACE_ERROR("L2CAP do not like the params");
1092 con_info.l2cap_result = L2CAP_LE_RESULT_NO_RESOURCES;
1093 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
1094 break;
1095 }
1096
1097 p_ccb->tx_mps = p_ccb->peer_conn_cfg.mps;
1098 p_ccb->ble_sdu = NULL;
1099 p_ccb->ble_sdu_length = 0;
1100 p_ccb->is_first_seg = true;
1101 p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
1102
1103 if (con_info.l2cap_result == L2CAP_LE_RESULT_CONN_OK)
1104 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP, &con_info);
1105 else
1106 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
1107 } else {
1108 L2CAP_TRACE_DEBUG("I DO NOT remember the connection req");
1109 con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_SOURCE_CID;
1110 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
1111 }
1112 break;
1113
1114 case L2CAP_CMD_BLE_FLOW_CTRL_CREDIT:
1115 if (p + 4 > p_pkt_end) {
1116 LOG(ERROR) << "invalid read";
1117 return;
1118 }
1119
1120 STREAM_TO_UINT16(lcid, p);
1121 p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, lcid);
1122 if (p_ccb == NULL) {
1123 L2CAP_TRACE_DEBUG("%s Credit received for unknown channel id %d",
1124 __func__, lcid);
1125 break;
1126 }
1127
1128 STREAM_TO_UINT16(credit, p);
1129 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT, &credit);
1130 L2CAP_TRACE_DEBUG("%s Credit received", __func__);
1131 break;
1132
1133 case L2CAP_CMD_DISC_REQ:
1134 if (p + 4 > p_pkt_end) {
1135 return;
1136 }
1137 STREAM_TO_UINT16(lcid, p);
1138 STREAM_TO_UINT16(rcid, p);
1139
1140 p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
1141 if (p_ccb != NULL) {
1142 if (p_ccb->remote_cid == rcid) {
1143 p_ccb->remote_id = id;
1144 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, NULL);
1145 }
1146 } else
1147 l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_INVALID_CID, id, 0, 0);
1148
1149 break;
1150
1151 case L2CAP_CMD_DISC_RSP:
1152 if (p + 4 > p_pkt_end) {
1153 LOG(ERROR) << "invalid read";
1154 return;
1155 }
1156 STREAM_TO_UINT16(rcid, p);
1157 STREAM_TO_UINT16(lcid, p);
1158
1159 p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
1160 if (p_ccb != NULL) {
1161 if ((p_ccb->remote_cid == rcid) && (p_ccb->local_id == id))
1162 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_RSP, NULL);
1163 }
1164 break;
1165
1166 default:
1167 L2CAP_TRACE_WARNING("L2CAP - LE - unknown cmd code: %d", cmd_code);
1168 l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
1169 break;
1170 }
1171 }
1172
1173 /** This function is to initate a direct connection. Returns true if connection
1174 * initiated, false otherwise. */
l2cble_create_conn(tL2C_LCB * p_lcb)1175 bool l2cble_create_conn(tL2C_LCB* p_lcb) {
1176 if (!acl_create_le_connection(p_lcb->remote_bd_addr)) {
1177 return false;
1178 }
1179
1180 p_lcb->link_state = LST_CONNECTING;
1181
1182 // TODO: we should not need this timer at all, the connection failure should
1183 // be reported from lower layer
1184 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_BLE_LINK_CONNECT_TIMEOUT_MS,
1185 l2c_lcb_timer_timeout, p_lcb);
1186 return true;
1187 }
1188
1189 /*******************************************************************************
1190 *
1191 * Function l2c_link_processs_ble_num_bufs
1192 *
1193 * Description This function is called when a "controller buffer size"
1194 * event is first received from the controller. It updates
1195 * the L2CAP values.
1196 *
1197 * Returns void
1198 *
1199 ******************************************************************************/
l2c_link_processs_ble_num_bufs(uint16_t num_lm_ble_bufs)1200 void l2c_link_processs_ble_num_bufs(uint16_t num_lm_ble_bufs) {
1201 if (bluetooth::shim::is_gd_l2cap_enabled()) {
1202 return;
1203 }
1204
1205 if (num_lm_ble_bufs == 0) {
1206 num_lm_ble_bufs = L2C_DEF_NUM_BLE_BUF_SHARED;
1207 l2cb.num_lm_acl_bufs -= L2C_DEF_NUM_BLE_BUF_SHARED;
1208 }
1209
1210 l2cb.num_lm_ble_bufs = num_lm_ble_bufs;
1211 l2cb.controller_le_xmit_window = num_lm_ble_bufs;
1212 }
1213
1214 /*******************************************************************************
1215 *
1216 * Function l2c_ble_link_adjust_allocation
1217 *
1218 * Description This function is called when a link is created or removed
1219 * to calculate the amount of packets each link may send to
1220 * the HCI without an ack coming back.
1221 *
1222 * Currently, this is a simple allocation, dividing the
1223 * number of Controller Packets by the number of links. In
1224 * the future, QOS configuration should be examined.
1225 *
1226 * Returns void
1227 *
1228 ******************************************************************************/
l2c_ble_link_adjust_allocation(void)1229 void l2c_ble_link_adjust_allocation(void) {
1230 uint16_t qq, yy, qq_remainder;
1231 tL2C_LCB* p_lcb;
1232 uint16_t hi_quota, low_quota;
1233 uint16_t num_lowpri_links = 0;
1234 uint16_t num_hipri_links = 0;
1235 uint16_t controller_xmit_quota = l2cb.num_lm_ble_bufs;
1236 uint16_t high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
1237
1238 /* If no links active, reset buffer quotas and controller buffers */
1239 if (l2cb.num_ble_links_active == 0) {
1240 l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
1241 l2cb.ble_round_robin_quota = l2cb.ble_round_robin_unacked = 0;
1242 return;
1243 }
1244
1245 /* First, count the links */
1246 for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
1247 if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) {
1248 if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)
1249 num_hipri_links++;
1250 else
1251 num_lowpri_links++;
1252 }
1253 }
1254
1255 /* now adjust high priority link quota */
1256 low_quota = num_lowpri_links ? 1 : 0;
1257 while ((num_hipri_links * high_pri_link_quota + low_quota) >
1258 controller_xmit_quota)
1259 high_pri_link_quota--;
1260
1261 /* Work out the xmit quota and buffer quota high and low priorities */
1262 hi_quota = num_hipri_links * high_pri_link_quota;
1263 low_quota =
1264 (hi_quota < controller_xmit_quota) ? controller_xmit_quota - hi_quota : 1;
1265
1266 /* Work out and save the HCI xmit quota for each low priority link */
1267
1268 /* If each low priority link cannot have at least one buffer */
1269 if (num_lowpri_links > low_quota) {
1270 l2cb.ble_round_robin_quota = low_quota;
1271 qq = qq_remainder = 0;
1272 }
1273 /* If each low priority link can have at least one buffer */
1274 else if (num_lowpri_links > 0) {
1275 l2cb.ble_round_robin_quota = 0;
1276 l2cb.ble_round_robin_unacked = 0;
1277 qq = low_quota / num_lowpri_links;
1278 qq_remainder = low_quota % num_lowpri_links;
1279 }
1280 /* If no low priority link */
1281 else {
1282 l2cb.ble_round_robin_quota = 0;
1283 l2cb.ble_round_robin_unacked = 0;
1284 qq = qq_remainder = 0;
1285 }
1286 L2CAP_TRACE_EVENT(
1287 "l2c_ble_link_adjust_allocation num_hipri: %u num_lowpri: %u "
1288 "low_quota: %u round_robin_quota: %u qq: %u",
1289 num_hipri_links, num_lowpri_links, low_quota, l2cb.ble_round_robin_quota,
1290 qq);
1291
1292 /* Now, assign the quotas to each link */
1293 for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
1294 if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) {
1295 if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) {
1296 p_lcb->link_xmit_quota = high_pri_link_quota;
1297 } else {
1298 /* Safety check in case we switched to round-robin with something
1299 * outstanding */
1300 /* if sent_not_acked is added into round_robin_unacked then do not add
1301 * it again */
1302 /* l2cap keeps updating sent_not_acked for exiting from round robin */
1303 if ((p_lcb->link_xmit_quota > 0) && (qq == 0))
1304 l2cb.ble_round_robin_unacked += p_lcb->sent_not_acked;
1305
1306 p_lcb->link_xmit_quota = qq;
1307 if (qq_remainder > 0) {
1308 p_lcb->link_xmit_quota++;
1309 qq_remainder--;
1310 }
1311 }
1312
1313 L2CAP_TRACE_EVENT(
1314 "l2c_ble_link_adjust_allocation LCB %d Priority: %d XmitQuota: %d",
1315 yy, p_lcb->acl_priority, p_lcb->link_xmit_quota);
1316
1317 L2CAP_TRACE_EVENT(" SentNotAcked: %d RRUnacked: %d",
1318 p_lcb->sent_not_acked, l2cb.round_robin_unacked);
1319
1320 /* There is a special case where we have readjusted the link quotas and */
1321 /* this link may have sent anything but some other link sent packets so */
1322 /* so we may need a timer to kick off this link's transmissions. */
1323 if ((p_lcb->link_state == LST_CONNECTED) &&
1324 (!list_is_empty(p_lcb->link_xmit_data_q)) &&
1325 (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
1326 alarm_set_on_mloop(p_lcb->l2c_lcb_timer,
1327 L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
1328 l2c_lcb_timer_timeout, p_lcb);
1329 }
1330 }
1331 }
1332 }
1333
1334 /*******************************************************************************
1335 *
1336 * Function l2cble_process_rc_param_request_evt
1337 *
1338 * Description process LE Remote Connection Parameter Request Event.
1339 *
1340 * Returns void
1341 *
1342 ******************************************************************************/
l2cble_process_rc_param_request_evt(uint16_t handle,uint16_t int_min,uint16_t int_max,uint16_t latency,uint16_t timeout)1343 void l2cble_process_rc_param_request_evt(uint16_t handle, uint16_t int_min,
1344 uint16_t int_max, uint16_t latency,
1345 uint16_t timeout) {
1346 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
1347
1348 if (p_lcb != NULL) {
1349 p_lcb->min_interval = int_min;
1350 p_lcb->max_interval = int_max;
1351 p_lcb->latency = latency;
1352 p_lcb->timeout = timeout;
1353
1354 /* if update is enabled, always accept connection parameter update */
1355 if ((p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0) {
1356 btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency,
1357 timeout, 0, 0);
1358 } else {
1359 L2CAP_TRACE_EVENT("L2CAP - LE - update currently disabled");
1360 p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
1361 btsnd_hcic_ble_rc_param_req_neg_reply(handle,
1362 HCI_ERR_UNACCEPT_CONN_INTERVAL);
1363 }
1364
1365 } else {
1366 L2CAP_TRACE_WARNING("No link to update connection parameter")
1367 }
1368 }
1369
1370 /*******************************************************************************
1371 *
1372 * Function l2cble_update_data_length
1373 *
1374 * Description This function update link tx data length if applicable
1375 *
1376 * Returns void
1377 *
1378 ******************************************************************************/
l2cble_update_data_length(tL2C_LCB * p_lcb)1379 void l2cble_update_data_length(tL2C_LCB* p_lcb) {
1380 uint16_t tx_mtu = 0;
1381 uint16_t i = 0;
1382
1383 L2CAP_TRACE_DEBUG("%s", __func__);
1384
1385 /* See if we have a link control block for the connection */
1386 if (p_lcb == NULL) return;
1387
1388 for (i = 0; i < L2CAP_NUM_FIXED_CHNLS; i++) {
1389 if (i + L2CAP_FIRST_FIXED_CHNL != L2CAP_BLE_SIGNALLING_CID) {
1390 if ((p_lcb->p_fixed_ccbs[i] != NULL) &&
1391 (tx_mtu < (p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD)))
1392 tx_mtu = p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD;
1393 }
1394 }
1395
1396 if (tx_mtu > BTM_BLE_DATA_SIZE_MAX) tx_mtu = BTM_BLE_DATA_SIZE_MAX;
1397
1398 /* update TX data length if changed */
1399 if (p_lcb->tx_data_len != tx_mtu)
1400 BTM_SetBleDataLength(p_lcb->remote_bd_addr, tx_mtu);
1401 }
1402
1403 /*******************************************************************************
1404 *
1405 * Function l2cble_process_data_length_change_evt
1406 *
1407 * Description This function process the data length change event
1408 *
1409 * Returns void
1410 *
1411 ******************************************************************************/
is_legal_tx_data_len(const uint16_t & tx_data_len)1412 static bool is_legal_tx_data_len(const uint16_t& tx_data_len) {
1413 return (tx_data_len >= 0x001B && tx_data_len <= 0x00FB);
1414 }
1415
l2cble_process_data_length_change_event(uint16_t handle,uint16_t tx_data_len,uint16_t rx_data_len)1416 void l2cble_process_data_length_change_event(uint16_t handle,
1417 uint16_t tx_data_len,
1418 uint16_t rx_data_len) {
1419 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
1420 if (p_lcb == nullptr) {
1421 LOG_WARN("Received data length change event for unknown ACL handle:0x%04x",
1422 handle);
1423 return;
1424 }
1425
1426 if (is_legal_tx_data_len(tx_data_len)) {
1427 if (p_lcb->tx_data_len != tx_data_len) {
1428 LOG_DEBUG(
1429 "Received data length change event for device:%s tx_data_len:%hu => "
1430 "%hu",
1431 ADDRESS_TO_LOGGABLE_CSTR(p_lcb->remote_bd_addr), p_lcb->tx_data_len,
1432 tx_data_len);
1433 BTM_LogHistory(kBtmLogTag, p_lcb->remote_bd_addr, "LE Data length change",
1434 base::StringPrintf("tx_octets:%hu => %hu",
1435 p_lcb->tx_data_len, tx_data_len));
1436 p_lcb->tx_data_len = tx_data_len;
1437 } else {
1438 LOG_DEBUG(
1439 "Received duplicated data length change event for device:%s "
1440 "tx_data_len:%hu",
1441 ADDRESS_TO_LOGGABLE_CSTR(p_lcb->remote_bd_addr), tx_data_len);
1442 }
1443 } else {
1444 LOG_WARN(
1445 "Received illegal data length change event for device:%s "
1446 "tx_data_len:%hu",
1447 ADDRESS_TO_LOGGABLE_CSTR(p_lcb->remote_bd_addr), tx_data_len);
1448 }
1449 /* ignore rx_data len for now */
1450 }
1451
1452 /*******************************************************************************
1453 *
1454 * Function l2cble_credit_based_conn_req
1455 *
1456 * Description This function sends LE Credit Based Connection Request for
1457 * LE connection oriented channels.
1458 *
1459 * Returns void
1460 *
1461 ******************************************************************************/
l2cble_credit_based_conn_req(tL2C_CCB * p_ccb)1462 void l2cble_credit_based_conn_req(tL2C_CCB* p_ccb) {
1463 if (!p_ccb) return;
1464
1465 if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1466 L2CAP_TRACE_WARNING("LE link doesn't exist");
1467 return;
1468 }
1469
1470 if (p_ccb->ecoc) {
1471 l2cu_send_peer_credit_based_conn_req(p_ccb);
1472 } else {
1473 l2cu_send_peer_ble_credit_based_conn_req(p_ccb);
1474 }
1475 return;
1476 }
1477
1478 /*******************************************************************************
1479 *
1480 * Function l2cble_credit_based_conn_res
1481 *
1482 * Description This function sends LE Credit Based Connection Response for
1483 * LE connection oriented channels.
1484 *
1485 * Returns void
1486 *
1487 ******************************************************************************/
l2cble_credit_based_conn_res(tL2C_CCB * p_ccb,uint16_t result)1488 void l2cble_credit_based_conn_res(tL2C_CCB* p_ccb, uint16_t result) {
1489 if (!p_ccb) return;
1490
1491 if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1492 L2CAP_TRACE_WARNING("LE link doesn't exist");
1493 return;
1494 }
1495
1496 l2cu_send_peer_ble_credit_based_conn_res(p_ccb, result);
1497 return;
1498 }
1499
1500 /*******************************************************************************
1501 *
1502 * Function l2cble_send_flow_control_credit
1503 *
1504 * Description This function sends flow control credits for
1505 * LE connection oriented channels.
1506 *
1507 * Returns void
1508 *
1509 ******************************************************************************/
l2cble_send_flow_control_credit(tL2C_CCB * p_ccb,uint16_t credit_value)1510 void l2cble_send_flow_control_credit(tL2C_CCB* p_ccb, uint16_t credit_value) {
1511 if (!p_ccb) return;
1512
1513 if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1514 L2CAP_TRACE_WARNING("LE link doesn't exist");
1515 return;
1516 }
1517
1518 l2cu_send_peer_ble_flow_control_credit(p_ccb, credit_value);
1519 return;
1520 }
1521
1522 /*******************************************************************************
1523 *
1524 * Function l2cble_send_peer_disc_req
1525 *
1526 * Description This function sends disconnect request
1527 * to the peer LE device
1528 *
1529 * Returns void
1530 *
1531 ******************************************************************************/
l2cble_send_peer_disc_req(tL2C_CCB * p_ccb)1532 void l2cble_send_peer_disc_req(tL2C_CCB* p_ccb) {
1533 L2CAP_TRACE_DEBUG("%s", __func__);
1534 if (!p_ccb) return;
1535
1536 if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
1537 L2CAP_TRACE_WARNING("LE link doesn't exist");
1538 return;
1539 }
1540
1541 l2cu_send_peer_ble_credit_based_disconn_req(p_ccb);
1542 return;
1543 }
1544
1545 /*******************************************************************************
1546 *
1547 * Function l2cble_sec_comp
1548 *
1549 * Description This function is called when security procedure for an LE
1550 * COC link is done
1551 *
1552 * Returns void
1553 *
1554 ******************************************************************************/
l2cble_sec_comp(const RawAddress * bda,tBT_TRANSPORT transport,void * p_ref_data,tBTM_STATUS status)1555 void l2cble_sec_comp(const RawAddress* bda, tBT_TRANSPORT transport,
1556 void* p_ref_data, tBTM_STATUS status) {
1557 const RawAddress& p_bda = *bda;
1558 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bda, BT_TRANSPORT_LE);
1559 tL2CAP_SEC_DATA* p_buf = NULL;
1560 uint8_t sec_act;
1561
1562 if (!p_lcb) {
1563 L2CAP_TRACE_WARNING("%s: security complete for unknown device. bda=%s",
1564 __func__, ADDRESS_TO_LOGGABLE_CSTR(*bda));
1565 return;
1566 }
1567
1568 sec_act = p_lcb->sec_act;
1569 p_lcb->sec_act = 0;
1570
1571 if (!fixed_queue_is_empty(p_lcb->le_sec_pending_q)) {
1572 p_buf = (tL2CAP_SEC_DATA*)fixed_queue_dequeue(p_lcb->le_sec_pending_q);
1573 if (!p_buf) {
1574 L2CAP_TRACE_WARNING(
1575 "%s Security complete for request not initiated from L2CAP",
1576 __func__);
1577 return;
1578 }
1579
1580 if (status != BTM_SUCCESS) {
1581 (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1582 osi_free(p_buf);
1583 } else {
1584 if (sec_act == BTM_SEC_ENCRYPT_MITM) {
1585 if (BTM_IsLinkKeyAuthed(p_bda, transport))
1586 (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data,
1587 status);
1588 else {
1589 L2CAP_TRACE_DEBUG("%s MITM Protection Not present", __func__);
1590 (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data,
1591 BTM_FAILED_ON_SECURITY);
1592 }
1593 } else {
1594 L2CAP_TRACE_DEBUG("%s MITM Protection not required sec_act = %d",
1595 __func__, p_lcb->sec_act);
1596
1597 (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data,
1598 status);
1599 }
1600 osi_free(p_buf);
1601 }
1602 } else {
1603 L2CAP_TRACE_WARNING(
1604 "%s Security complete for request not initiated from L2CAP", __func__);
1605 return;
1606 }
1607
1608 while (!fixed_queue_is_empty(p_lcb->le_sec_pending_q)) {
1609 p_buf = (tL2CAP_SEC_DATA*)fixed_queue_dequeue(p_lcb->le_sec_pending_q);
1610
1611 if (status != BTM_SUCCESS) {
1612 (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1613 osi_free(p_buf);
1614 }
1615 else {
1616 l2ble_sec_access_req(p_bda, p_buf->psm, p_buf->is_originator,
1617 p_buf->p_callback, p_buf->p_ref_data);
1618
1619 osi_free(p_buf);
1620 break;
1621 }
1622 }
1623 }
1624
1625 /*******************************************************************************
1626 *
1627 * Function l2ble_sec_access_req
1628 *
1629 * Description This function is called by LE COC link to meet the
1630 * security requirement for the link
1631 *
1632 * Returns Returns - L2CAP LE Connection Response Result Code.
1633 *
1634 ******************************************************************************/
l2ble_sec_access_req(const RawAddress & bd_addr,uint16_t psm,bool is_originator,tL2CAP_SEC_CBACK * p_callback,void * p_ref_data)1635 tL2CAP_LE_RESULT_CODE l2ble_sec_access_req(const RawAddress& bd_addr,
1636 uint16_t psm, bool is_originator,
1637 tL2CAP_SEC_CBACK* p_callback,
1638 void* p_ref_data) {
1639 tL2CAP_LE_RESULT_CODE result;
1640 tL2C_LCB* p_lcb = NULL;
1641
1642 if (!p_callback) {
1643 LOG_ERROR("No callback function");
1644 return L2CAP_LE_RESULT_NO_RESOURCES;
1645 }
1646
1647 p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
1648
1649 if (!p_lcb) {
1650 LOG_ERROR("Security check for unknown device");
1651 p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_UNKNOWN_ADDR);
1652 return L2CAP_LE_RESULT_NO_RESOURCES;
1653 }
1654
1655 tL2CAP_SEC_DATA* p_buf =
1656 (tL2CAP_SEC_DATA*)osi_malloc((uint16_t)sizeof(tL2CAP_SEC_DATA));
1657 if (!p_buf) {
1658 LOG_ERROR("No resources for connection");
1659 p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_NO_RESOURCES);
1660 return L2CAP_LE_RESULT_NO_RESOURCES;
1661 }
1662
1663 p_buf->psm = psm;
1664 p_buf->is_originator = is_originator;
1665 p_buf->p_callback = p_callback;
1666 p_buf->p_ref_data = p_ref_data;
1667 fixed_queue_enqueue(p_lcb->le_sec_pending_q, p_buf);
1668 result = btm_ble_start_sec_check(bd_addr, psm, is_originator,
1669 &l2cble_sec_comp, p_ref_data);
1670
1671 return result;
1672 }
1673
1674 /* This function is called to adjust the connection intervals based on various
1675 * constraints. For example, when there is at least one Hearing Aid device
1676 * bonded, the minimum interval is raised. On return, min_interval and
1677 * max_interval are updated. */
L2CA_AdjustConnectionIntervals(uint16_t * min_interval,uint16_t * max_interval,uint16_t floor_interval)1678 void L2CA_AdjustConnectionIntervals(uint16_t* min_interval,
1679 uint16_t* max_interval,
1680 uint16_t floor_interval) {
1681 // Allow for customization by systemprops for mainline
1682 uint16_t phone_min_interval = floor_interval;
1683 #ifdef __ANDROID__
1684 phone_min_interval =
1685 android::sysprop::BluetoothProperties::getGapLeConnMinLimit().value_or(
1686 floor_interval);
1687 #else
1688 phone_min_interval = (uint16_t)osi_property_get_int32(
1689 "bluetooth.core.gap.le.conn.min.limit", (int32_t)floor_interval);
1690 #endif
1691
1692 if (GetInterfaceToProfiles()
1693 ->profileSpecific_HACK->GetHearingAidDeviceCount()) {
1694 // When there are bonded Hearing Aid devices, we will constrained this
1695 // minimum interval.
1696 phone_min_interval = BTM_BLE_CONN_INT_MIN_HEARINGAID;
1697 L2CAP_TRACE_DEBUG("%s: Have Hearing Aids. Min. interval is set to %d",
1698 __func__, phone_min_interval);
1699 }
1700
1701 if (*min_interval < phone_min_interval) {
1702 L2CAP_TRACE_DEBUG("%s: requested min_interval=%d too small. Set to %d",
1703 __func__, *min_interval, phone_min_interval);
1704 *min_interval = phone_min_interval;
1705 }
1706
1707 // While this could result in connection parameters that fall
1708 // outside fo the range requested, this will allow the connection
1709 // to remain established.
1710 // In other words, this is a workaround for certain peripherals.
1711 if (*max_interval < phone_min_interval) {
1712 L2CAP_TRACE_DEBUG("%s: requested max_interval=%d too small. Set to %d",
1713 __func__, *max_interval, phone_min_interval);
1714 *max_interval = phone_min_interval;
1715 }
1716 }
1717
l2cble_use_preferred_conn_params(const RawAddress & bda)1718 void l2cble_use_preferred_conn_params(const RawAddress& bda) {
1719 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
1720 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda);
1721
1722 /* If there are any preferred connection parameters, set them now */
1723 if ((p_lcb != NULL) && (p_dev_rec != NULL) &&
1724 (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN) &&
1725 (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX) &&
1726 (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN) &&
1727 (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX) &&
1728 (p_dev_rec->conn_params.peripheral_latency <= BTM_BLE_CONN_LATENCY_MAX) &&
1729 (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) &&
1730 (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) &&
1731 ((p_lcb->min_interval < p_dev_rec->conn_params.min_conn_int &&
1732 p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ||
1733 (p_lcb->min_interval > p_dev_rec->conn_params.max_conn_int) ||
1734 (p_lcb->latency > p_dev_rec->conn_params.peripheral_latency) ||
1735 (p_lcb->timeout > p_dev_rec->conn_params.supervision_tout))) {
1736 BTM_TRACE_DEBUG(
1737 "%s: HANDLE=%d min_conn_int=%d max_conn_int=%d peripheral_latency=%d "
1738 "supervision_tout=%d",
1739 __func__, p_lcb->Handle(), p_dev_rec->conn_params.min_conn_int,
1740 p_dev_rec->conn_params.max_conn_int,
1741 p_dev_rec->conn_params.peripheral_latency,
1742 p_dev_rec->conn_params.supervision_tout);
1743
1744 p_lcb->min_interval = p_dev_rec->conn_params.min_conn_int;
1745 p_lcb->max_interval = p_dev_rec->conn_params.max_conn_int;
1746 p_lcb->timeout = p_dev_rec->conn_params.supervision_tout;
1747 p_lcb->latency = p_dev_rec->conn_params.peripheral_latency;
1748
1749 btsnd_hcic_ble_upd_ll_conn_params(
1750 p_lcb->Handle(), p_dev_rec->conn_params.min_conn_int,
1751 p_dev_rec->conn_params.max_conn_int,
1752 p_dev_rec->conn_params.peripheral_latency,
1753 p_dev_rec->conn_params.supervision_tout, 0, 0);
1754 }
1755 }
1756
1757 /*******************************************************************************
1758 *
1759 * Function l2cble_start_subrate_change
1760 *
1761 * Description Start the BLE subrate change process based on
1762 * status.
1763 *
1764 * Parameters: lcb : l2cap link control block
1765 *
1766 * Return value: none
1767 *
1768 ******************************************************************************/
l2cble_start_subrate_change(tL2C_LCB * p_lcb)1769 static void l2cble_start_subrate_change(tL2C_LCB* p_lcb) {
1770 if (!BTM_IsAclConnectionUp(p_lcb->remote_bd_addr, BT_TRANSPORT_LE)) {
1771 LOG(ERROR) << "No known connection ACL for "
1772 << ADDRESS_TO_LOGGABLE_STR(p_lcb->remote_bd_addr);
1773 return;
1774 }
1775
1776 btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
1777
1778 L2CAP_TRACE_DEBUG("%s: subrate_req_mask=%d conn_update_mask=%d", __func__,
1779 p_lcb->subrate_req_mask, p_lcb->conn_update_mask);
1780
1781 if (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_PENDING) {
1782 L2CAP_TRACE_DEBUG("%s: returning L2C_BLE_SUBRATE_REQ_PENDING ", __func__);
1783 return;
1784 }
1785
1786 if (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_DISABLE) {
1787 L2CAP_TRACE_DEBUG("%s: returning L2C_BLE_SUBRATE_REQ_DISABLE ", __func__);
1788 return;
1789 }
1790
1791 /* application allows to do update, if we were delaying one do it now */
1792 if (!(p_lcb->subrate_req_mask & L2C_BLE_NEW_SUBRATE_PARAM) ||
1793 (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) ||
1794 (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM)) {
1795 L2CAP_TRACE_DEBUG("%s: returning L2C_BLE_NEW_SUBRATE_PARAM", __func__);
1796 return;
1797 }
1798
1799 if (!controller_get_interface()->supports_ble_connection_subrating_host() ||
1800 !controller_get_interface()->supports_ble_connection_subrating() ||
1801 !acl_peer_supports_ble_connection_subrating(p_lcb->remote_bd_addr) ||
1802 !acl_peer_supports_ble_connection_subrating_host(p_lcb->remote_bd_addr)) {
1803 L2CAP_TRACE_DEBUG(
1804 "%s: returning L2C_BLE_NEW_SUBRATE_PARAM local_host_sup=%d, "
1805 "local_conn_subrarte_sup=%d, peer_subrate_sup=%d, peer_host_sup=%d",
1806 __func__,
1807 controller_get_interface()->supports_ble_connection_subrating_host(),
1808 controller_get_interface()->supports_ble_connection_subrating(),
1809 acl_peer_supports_ble_connection_subrating(p_lcb->remote_bd_addr),
1810 acl_peer_supports_ble_connection_subrating_host(p_lcb->remote_bd_addr));
1811 return;
1812 }
1813
1814 L2CAP_TRACE_DEBUG("%s: Sending HCI cmd for subrate req", __func__);
1815 bluetooth::shim::ACL_LeSubrateRequest(
1816 p_lcb->Handle(), p_lcb->subrate_min, p_lcb->subrate_max,
1817 p_lcb->max_latency, p_lcb->cont_num, p_lcb->supervision_tout);
1818
1819 p_lcb->subrate_req_mask |= L2C_BLE_SUBRATE_REQ_PENDING;
1820 p_lcb->subrate_req_mask &= ~L2C_BLE_NEW_SUBRATE_PARAM;
1821 p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM;
1822 }
1823
1824 /*******************************************************************************
1825 *
1826 * Function L2CA_SetDefaultSubrate
1827 *
1828 * Description BLE Set Default Subrate
1829 *
1830 * Parameters: Subrate parameters
1831 *
1832 * Return value: void
1833 *
1834 ******************************************************************************/
L2CA_SetDefaultSubrate(uint16_t subrate_min,uint16_t subrate_max,uint16_t max_latency,uint16_t cont_num,uint16_t timeout)1835 void L2CA_SetDefaultSubrate(uint16_t subrate_min, uint16_t subrate_max,
1836 uint16_t max_latency, uint16_t cont_num,
1837 uint16_t timeout) {
1838 VLOG(1) << __func__ << " subrate_min=" << subrate_min
1839 << ", subrate_max=" << subrate_max << ", max_latency=" << max_latency
1840 << ", cont_num=" << cont_num << ", timeout=" << timeout;
1841
1842 bluetooth::shim::ACL_LeSetDefaultSubrate(subrate_min, subrate_max,
1843 max_latency, cont_num, timeout);
1844 }
1845
1846 /*******************************************************************************
1847 *
1848 * Function L2CA_SubrateRequest
1849 *
1850 * Description BLE Subrate request.
1851 *
1852 * Parameters: Subrate parameters
1853 *
1854 * Return value: true if update started
1855 *
1856 ******************************************************************************/
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)1857 bool L2CA_SubrateRequest(const RawAddress& rem_bda, uint16_t subrate_min,
1858 uint16_t subrate_max, uint16_t max_latency,
1859 uint16_t cont_num, uint16_t timeout) {
1860 tL2C_LCB* p_lcb;
1861
1862 /* See if we have a link control block for the remote device */
1863 p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
1864
1865 /* If we don't have one, create one and accept the connection. */
1866 if (!p_lcb || !BTM_IsAclConnectionUp(rem_bda, BT_TRANSPORT_LE)) {
1867 LOG(WARNING) << __func__ << " - unknown BD_ADDR "
1868 << ADDRESS_TO_LOGGABLE_STR(rem_bda);
1869 return (false);
1870 }
1871
1872 if (p_lcb->transport != BT_TRANSPORT_LE) {
1873 LOG(WARNING) << __func__ << " - BD_ADDR "
1874 << ADDRESS_TO_LOGGABLE_STR(rem_bda) << " not LE";
1875 return (false);
1876 }
1877
1878 VLOG(1) << __func__ << ": BD_ADDR=" << ADDRESS_TO_LOGGABLE_STR(rem_bda)
1879 << ", subrate_min=" << subrate_min << ", subrate_max=" << subrate_max
1880 << ", max_latency=" << max_latency << ", cont_num=" << cont_num
1881 << ", timeout=" << timeout;
1882
1883 p_lcb->subrate_min = subrate_min;
1884 p_lcb->subrate_max = subrate_max;
1885 p_lcb->max_latency = max_latency;
1886 p_lcb->cont_num = cont_num;
1887 p_lcb->subrate_req_mask |= L2C_BLE_NEW_SUBRATE_PARAM;
1888 p_lcb->supervision_tout = timeout;
1889
1890 l2cble_start_subrate_change(p_lcb);
1891
1892 return (true);
1893 }
1894
1895 /*******************************************************************************
1896 *
1897 * Function l2cble_process_subrate_change_evt
1898 *
1899 * Description This function enables LE subrating
1900 * after a successful subrate change process is
1901 * done.
1902 *
1903 * Parameters: LE connection handle
1904 * status
1905 * subrate factor
1906 * peripheral latency
1907 * continuation number
1908 * supervision timeout
1909 *
1910 * Returns void
1911 *
1912 ******************************************************************************/
l2cble_process_subrate_change_evt(uint16_t handle,uint8_t status,uint16_t subrate_factor,uint16_t peripheral_latency,uint16_t cont_num,uint16_t timeout)1913 void l2cble_process_subrate_change_evt(uint16_t handle, uint8_t status,
1914 uint16_t subrate_factor,
1915 uint16_t peripheral_latency,
1916 uint16_t cont_num, uint16_t timeout) {
1917 L2CAP_TRACE_DEBUG("%s", __func__);
1918
1919 /* See if we have a link control block for the remote device */
1920 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
1921 if (!p_lcb) {
1922 L2CAP_TRACE_WARNING("%s: Invalid handle: %d", __func__, handle);
1923 return;
1924 }
1925
1926 p_lcb->subrate_req_mask &= ~L2C_BLE_SUBRATE_REQ_PENDING;
1927
1928 if (status != HCI_SUCCESS) {
1929 L2CAP_TRACE_WARNING("%s: Error status: %d", __func__, status);
1930 }
1931
1932 l2cble_start_conn_update(p_lcb);
1933
1934 l2cble_start_subrate_change(p_lcb);
1935
1936 L2CAP_TRACE_DEBUG("%s: conn_update_mask=%d , subrate_req_mask=%d", __func__,
1937 p_lcb->conn_update_mask, p_lcb->subrate_req_mask);
1938 }
1939