l2c_ble.c revision 847b706a9cfba9dc749240b33276a7e02df30f29
1/****************************************************************************** 2 * 3 * Copyright (C) 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#include <string.h> 26#include "bt_target.h" 27#include "bt_utils.h" 28#include "l2cdefs.h" 29#include "l2c_int.h" 30#include "btu.h" 31#include "btm_int.h" 32#include "hcimsgs.h" 33 34#if (BLE_INCLUDED == TRUE) 35#define L2CA_GET_UPD_ST(x) ((x) & UPD_ST_MASK) 36#define L2CA_SET_UPD_ST(x, y) x = (((x) & ~UPD_ST_MASK) | (y)) 37 38 39#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) 40#include "vendor_ble.h" 41#endif 42/******************************************************************************* 43** 44** Function L2CA_CancelBleConnectReq 45** 46** Description Cancel a pending connection attempt to a BLE device. 47** 48** Parameters: BD Address of remote 49** 50** Return value: TRUE if connection was cancelled 51** 52*******************************************************************************/ 53BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda) 54{ 55 tL2C_LCB *p_lcb; 56 57 /* There can be only one BLE connection request outstanding at a time */ 58 if (btm_ble_get_conn_st() == BLE_CONN_IDLE) 59 { 60 L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - no connection pending"); 61 return(FALSE); 62 } 63 64 if (memcmp (rem_bda, l2cb.ble_connecting_bda, BD_ADDR_LEN)) 65 { 66 L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - different BDA Connecting: %08x%04x Cancel: %08x%04x", 67 (l2cb.ble_connecting_bda[0]<<24)+(l2cb.ble_connecting_bda[1]<<16)+(l2cb.ble_connecting_bda[2]<<8)+l2cb.ble_connecting_bda[3], 68 (l2cb.ble_connecting_bda[4]<<8)+l2cb.ble_connecting_bda[5], 69 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); 70 71 return(FALSE); 72 } 73 74 if (btsnd_hcic_ble_create_conn_cancel()) 75 { 76 77 if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE)) != NULL) 78 { 79 p_lcb->disc_reason = L2CAP_CONN_CANCEL; 80 l2cu_release_lcb (p_lcb); 81 } 82 /* update state to be cancel, wait for connection cancel complete */ 83 btm_ble_set_conn_st (BLE_CONN_CANCEL); 84 85 return(TRUE); 86 } 87 else 88 return(FALSE); 89} 90 91/******************************************************************************* 92** 93** Function L2CA_UpdateBleConnParams 94** 95** Description Update BLE connection parameters. 96** 97** Parameters: BD Address of remote 98** 99** Return value: TRUE if update started 100** 101*******************************************************************************/ 102BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int, 103 UINT16 latency, UINT16 timeout) 104{ 105 tL2C_LCB *p_lcb; 106 tACL_CONN *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE); 107 108 /* See if we have a link control block for the remote device */ 109 p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE); 110 111 /* If we don't have one, create one and accept the connection. */ 112 if (!p_lcb || !p_acl_cb) 113 { 114 L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x", 115 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 116 (rem_bda[4]<<8)+rem_bda[5]); 117 return(FALSE); 118 } 119 120 if (p_lcb->transport != BT_TRANSPORT_LE) 121 { 122 L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE", 123 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 124 (rem_bda[4]<<8)+rem_bda[5]); 125 return(FALSE); 126 } 127#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) 128 /* if both 4.1 compliant */ 129 if ((HCI_LE_CONN_PARAM_REQ_SUPPORTED(btm_cb.devcb.local_le_features) && 130 HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features))) 131 { 132 /* TODO: CE length selection ?? */ 133 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int, 134 latency, timeout, 0, 0); 135 } 136 else 137 /* if either side does not support Connection Parameters Request 138 Link Layer Control Procedure, 139 use Link Layer Connection Update procedure */ 140#endif 141 { 142 if (p_lcb->link_role == HCI_ROLE_MASTER) 143 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int, 144 latency, timeout, 0, 0); 145 else 146 l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout); 147 } 148 return(TRUE); 149 150} 151 152 153/******************************************************************************* 154** 155** Function L2CA_EnableUpdateBleConnParams 156** 157** Description Enable or disable update based on the request from the peer 158** 159** Parameters: BD Address of remote 160** 161** Return value: TRUE if update started 162** 163*******************************************************************************/ 164BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable) 165{ 166 tL2C_LCB *p_lcb; 167 168 /* See if we have a link control block for the remote device */ 169 p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE); 170 171 if (!p_lcb) 172 { 173 L2CAP_TRACE_WARNING ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x", 174 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 175 (rem_bda[4]<<8)+rem_bda[5]); 176 return (FALSE); 177 } 178 179 L2CAP_TRACE_API ("%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x",__FUNCTION__, 180 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 181 (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->conn_update_mask); 182 183 if (p_lcb->transport != BT_TRANSPORT_LE || (p_lcb->link_role != HCI_ROLE_MASTER)) 184 { 185 L2CAP_TRACE_WARNING ("%s - BD_ADDR %08x%04x not LE or not master %d", __FUNCTION__, 186 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], 187 (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role); 188 return (FALSE); 189 } 190 191 if (enable) 192 { 193 if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) == UPD_DISABLED) 194 { 195 p_lcb->conn_param_enb.param = (TIMER_PARAM_TYPE)p_lcb; 196 btu_start_timer (&p_lcb->conn_param_enb, BTU_TTYPE_L2CAP_END_CONN_UPD, 197 L2CAP_BLE_ENB_CONN_PARAM_TOUT); 198 L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENB_TOUT); 199 } 200 } 201 else if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) != UPD_DISABLED) 202 { 203 btu_stop_timer(&p_lcb->conn_param_enb); 204 205 if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED) 206 { 207 208 /* 209 application requests to disable parameters update.If parameters are already updated, 210 lets set them up to what has been requested during connection establishement 211 */ 212 if ((p_lcb->conn_update_mask & UPD_REQUEST) != 0) 213 { 214 /* revert back to default */ 215 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, 216 BTM_BLE_CONN_INT_MIN_DEF, 217 BTM_BLE_CONN_INT_MAX_DEF, 218 BTM_BLE_CONN_SLAVE_LATENCY_DEF, 219 BTM_BLE_CONN_TIMEOUT_DEF, 220 0, 0); 221 } 222 } 223 L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_DISABLED); 224 225 } 226 227 return (TRUE); 228 229} 230 231 232/******************************************************************************* 233** 234** Function L2CA_GetBleConnRole 235** 236** Description This function returns the connection role. 237** 238** Returns link role. 239** 240*******************************************************************************/ 241UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr) 242{ 243 UINT8 role = HCI_ROLE_UNKNOWN; 244 245 tL2C_LCB *p_lcb; 246 247 if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_LE)) != NULL) 248 role = p_lcb->link_role; 249 250 return role; 251} 252/******************************************************************************* 253** 254** Function L2CA_GetDisconnectReason 255** 256** Description This function returns the disconnect reason code. 257** 258** Returns disconnect reason 259** 260*******************************************************************************/ 261UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport) 262{ 263 tL2C_LCB *p_lcb; 264 UINT16 reason = 0; 265 266 if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda, transport)) != NULL) 267 reason = p_lcb->disc_reason; 268 269 L2CAP_TRACE_DEBUG ("L2CA_GetDisconnectReason=%d ",reason); 270 271 return reason; 272} 273 274/******************************************************************************* 275** 276** Function l2cble_scanner_conn_comp 277** 278** Description This function is called when an HCI Connection Complete 279** event is received while we are a scanner (so we are master). 280** 281** Returns void 282** 283*******************************************************************************/ 284void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, 285 UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) 286{ 287 tL2C_LCB *p_lcb; 288 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bda); 289 290 L2CAP_TRACE_DEBUG ("l2cble_scanner_conn_comp: HANDLE=%d addr_type=%d conn_interval=%d slave_latency=%d supervision_tout=%d", 291 handle, type, conn_interval, conn_latency, conn_timeout); 292 293 l2cb.is_ble_connecting = FALSE; 294 295 /* See if we have a link control block for the remote device */ 296 p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE); 297 298 /* If we don't have one, create one. this is auto connection complete. */ 299 if (!p_lcb) 300 { 301 p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE); 302 if (!p_lcb) 303 { 304 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); 305 L2CAP_TRACE_ERROR ("l2cble_scanner_conn_comp - failed to allocate LCB"); 306 return; 307 } 308 else 309 { 310 if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) 311 { 312 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); 313 L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB"); 314 return ; 315 } 316 } 317 } 318 else if (p_lcb->link_state != LST_CONNECTING) 319 { 320 L2CAP_TRACE_ERROR ("L2CAP got BLE scanner conn_comp in bad state: %d", p_lcb->link_state); 321 return; 322 } 323 btu_stop_timer(&p_lcb->timer_entry); 324 325 /* Save the handle */ 326 p_lcb->handle = handle; 327 328 /* Connected OK. Change state to connected, we were scanning so we are master */ 329 p_lcb->link_state = LST_CONNECTED; 330 p_lcb->link_role = HCI_ROLE_MASTER; 331 p_lcb->transport = BT_TRANSPORT_LE; 332 333 /* If there are any preferred connection parameters, set them now */ 334 if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) && 335 (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX ) && 336 (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN ) && 337 (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX ) && 338 (p_dev_rec->conn_params.slave_latency <= BTM_BLE_CONN_LATENCY_MAX ) && 339 (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) && 340 (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) && 341 ((conn_interval < p_dev_rec->conn_params.min_conn_int && 342 p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) || 343 (conn_interval > p_dev_rec->conn_params.max_conn_int) || 344 (conn_latency > p_dev_rec->conn_params.slave_latency) || 345 (conn_timeout > p_dev_rec->conn_params.supervision_tout))) 346 { 347 L2CAP_TRACE_ERROR ("upd_ll_conn_params: HANDLE=%d min_conn_int=%d max_conn_int=%d slave_latency=%d supervision_tout=%d", 348 handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int, 349 p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout); 350 351 btsnd_hcic_ble_upd_ll_conn_params (handle, 352 p_dev_rec->conn_params.min_conn_int, 353 p_dev_rec->conn_params.max_conn_int, 354 p_dev_rec->conn_params.slave_latency, 355 p_dev_rec->conn_params.supervision_tout, 356 0, 0); 357 } 358 359 /* Tell BTM Acl management about the link */ 360 btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE); 361 362 p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT; 363 364 l2cu_process_fixed_chnl_resp (p_lcb); 365 366 btm_ble_set_conn_st(BLE_CONN_IDLE); 367} 368 369 370/******************************************************************************* 371** 372** Function l2cble_advertiser_conn_comp 373** 374** Description This function is called when an HCI Connection Complete 375** event is received while we are an advertiser (so we are slave). 376** 377** Returns void 378** 379*******************************************************************************/ 380void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, 381 UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) 382{ 383 tL2C_LCB *p_lcb; 384 tBTM_SEC_DEV_REC *p_dev_rec; 385 UNUSED(type); 386 UNUSED(conn_interval); 387 UNUSED(conn_latency); 388 UNUSED(conn_timeout); 389 390 /* See if we have a link control block for the remote device */ 391 p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE); 392 393 /* If we don't have one, create one and accept the connection. */ 394 if (!p_lcb) 395 { 396 p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE); 397 if (!p_lcb) 398 { 399 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); 400 L2CAP_TRACE_ERROR ("l2cble_advertiser_conn_comp - failed to allocate LCB"); 401 return; 402 } 403 else 404 { 405 if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) 406 { 407 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); 408 L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB"); 409 return ; 410 } 411 } 412 } 413 414 /* Save the handle */ 415 p_lcb->handle = handle; 416 417 /* Connected OK. Change state to connected, we were advertising, so we are slave */ 418 p_lcb->link_state = LST_CONNECTED; 419 p_lcb->link_role = HCI_ROLE_SLAVE; 420 p_lcb->transport = BT_TRANSPORT_LE; 421 422 /* Tell BTM Acl management about the link */ 423 p_dev_rec = btm_find_or_alloc_dev (bda); 424 425 btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE); 426 427 p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT; 428 429 l2cu_process_fixed_chnl_resp (p_lcb); 430 431 /* when adv and initiating are both active, cancel the direct connection */ 432 if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0) 433 { 434 L2CA_CancelBleConnectReq(bda); 435 } 436} 437 438/******************************************************************************* 439** 440** Function l2cble_conn_comp 441** 442** Description This function is called when an HCI Connection Complete 443** event is received. 444** 445** Returns void 446** 447*******************************************************************************/ 448void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type, 449 UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) 450{ 451 if (role == HCI_ROLE_MASTER) 452 { 453 l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout); 454 } 455 else 456 { 457 l2cble_advertiser_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout); 458 } 459} 460/******************************************************************************* 461** 462** Function l2cble_process_sig_cmd 463** 464** Description This function is called when a signalling packet is received 465** on the BLE signalling CID 466** 467** Returns void 468** 469*******************************************************************************/ 470void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) 471{ 472 UINT8 *p_pkt_end; 473 UINT8 cmd_code, id; 474 UINT16 cmd_len, rej_reason; 475 UINT16 result; 476 UINT16 min_interval, max_interval, latency, timeout; 477 478 p_pkt_end = p + pkt_len; 479 480 STREAM_TO_UINT8 (cmd_code, p); 481 STREAM_TO_UINT8 (id, p); 482 STREAM_TO_UINT16 (cmd_len, p); 483 484 /* Check command length does not exceed packet length */ 485 if ((p + cmd_len) > p_pkt_end) 486 { 487 L2CAP_TRACE_WARNING ("L2CAP - LE - format error, pkt_len: %d cmd_len: %d code: %d", pkt_len, cmd_len, cmd_code); 488 return; 489 } 490 491 switch (cmd_code) 492 { 493 case L2CAP_CMD_REJECT: 494 case L2CAP_CMD_ECHO_RSP: 495 case L2CAP_CMD_INFO_RSP: 496 STREAM_TO_UINT16 (rej_reason, p); 497 break; 498 case L2CAP_CMD_ECHO_REQ: 499 case L2CAP_CMD_INFO_REQ: 500 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); 501 break; 502 503 case L2CAP_CMD_BLE_UPDATE_REQ: 504 STREAM_TO_UINT16 (min_interval, p); /* 0x0006 - 0x0C80 */ 505 STREAM_TO_UINT16 (max_interval, p); /* 0x0006 - 0x0C80 */ 506 STREAM_TO_UINT16 (latency, p); /* 0x0000 - 0x03E8 */ 507 STREAM_TO_UINT16 (timeout, p); /* 0x000A - 0x0C80 */ 508 /* If we are a master, the slave wants to update the parameters */ 509 if (p_lcb->link_role == HCI_ROLE_MASTER) 510 { 511 if (min_interval < BTM_BLE_CONN_INT_MIN || min_interval > BTM_BLE_CONN_INT_MAX || 512 max_interval < BTM_BLE_CONN_INT_MIN || max_interval > BTM_BLE_CONN_INT_MAX || 513 latency > BTM_BLE_CONN_LATENCY_MAX || 514 /*(timeout >= max_interval && latency > (timeout * 10/(max_interval * 1.25) - 1)) ||*/ 515 timeout < BTM_BLE_CONN_SUP_TOUT_MIN || timeout > BTM_BLE_CONN_SUP_TOUT_MAX || 516 max_interval < min_interval) 517 { 518 l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_UNACCEPTABLE_PARAMS, id); 519 } 520 else 521 { 522 523 l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id); 524 525 p_lcb->min_interval = min_interval; 526 p_lcb->max_interval = max_interval; 527 p_lcb->latency = latency; 528 p_lcb->timeout = timeout; 529 p_lcb->conn_update_mask |= UPD_REQUEST; 530 531 if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED) 532 { 533 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval, 534 latency, timeout, 0, 0); 535 } 536 else 537 { 538 L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled"); 539 } 540 541 } 542 } 543 else 544 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); 545 break; 546 547 case L2CAP_CMD_BLE_UPDATE_RSP: 548 STREAM_TO_UINT16 (result, p); 549 break; 550 551 default: 552 L2CAP_TRACE_WARNING ("L2CAP - LE - unknown cmd code: %d", cmd_code); 553 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); 554 return; 555 } 556} 557/******************************************************************************* 558** 559** Function l2c_enable_conn_param_timeout 560** 561** Description This function process the connection parameter enabling timeout 562** 563** Returns None. 564** 565*******************************************************************************/ 566void l2c_enable_conn_param_timeout(tL2C_LCB * p_lcb) 567{ 568 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr); 569 570 571 /* application allows to do update, if we were delaying one do it now, otherwise 572 just mark lcb that updates are enabled */ 573 if (p_lcb->conn_update_mask & UPD_REQUEST) 574 { 575 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval, 576 p_lcb->latency, p_lcb->timeout, 0, 0); 577 } 578 else 579 { 580 /* if preferred number has been set, set to preferred conn parameter */ 581 if (p_dev_rec && p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) 582 { 583 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, 584 (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? 585 p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), 586 (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? 587 p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), 588 (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? 589 p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), 590 (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? 591 p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), 592 0, 0); 593 } 594 } 595 L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENABLED); 596 597} 598/******************************************************************************* 599** 600** Function l2cble_init_direct_conn 601** 602** Description This function is to initate a direct connection 603** 604** Returns TRUE connection initiated, FALSE otherwise. 605** 606*******************************************************************************/ 607BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) 608{ 609 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr); 610 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; 611 UINT16 scan_int, scan_win; 612 BD_ADDR init_addr; 613 UINT8 init_addr_type = BLE_ADDR_PUBLIC, 614 own_addr_type = BLE_ADDR_PUBLIC; 615 616 /* There can be only one BLE connection request outstanding at a time */ 617 if (p_dev_rec == NULL) 618 { 619 L2CAP_TRACE_WARNING ("unknown device, can not initate connection"); 620 return(FALSE); 621 } 622 623 scan_int = (p_cb->scan_int == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int; 624 scan_win = (p_cb->scan_win == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win; 625 626 init_addr_type = p_lcb->ble_addr_type; 627 memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN); 628 629#if BLE_PRIVACY_SPT == TRUE 630 if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA) 631 { 632 init_addr_type = BLE_ADDR_RANDOM; 633 //memcpy(init_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN); 634 } 635 /* if privacy is on and current do not consider using reconnection address */ 636 if (btm_cb.ble_ctr_cb.privacy ) /* && p_dev_rec->ble.use_reconn_addr */ 637 own_addr_type = BLE_ADDR_RANDOM; 638#endif 639 640 if (!btm_ble_topology_check(BTM_BLE_STATE_INIT)) 641 { 642 l2cu_release_lcb (p_lcb); 643 L2CAP_TRACE_ERROR("initate direct connection fail, topology limitation"); 644 return FALSE; 645 } 646#if BLE_PRIVACY_SPT == TRUE 647#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) 648 extern tBTM_STATUS BTM_BleEnableIRKFeature(BOOLEAN enable); 649 if (btm_ble_vendor_irk_list_load_dev(p_dev_rec)) 650 BTM_BleEnableIRKFeature(TRUE); 651 652 btm_random_pseudo_to_public(init_addr, &init_addr_type); 653#endif 654#endif 655 if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */ 656 scan_win, /* UINT16 scan_win */ 657 FALSE, /* UINT8 white_list */ 658 init_addr_type, /* UINT8 addr_type_peer */ 659 init_addr, /* BD_ADDR bda_peer */ 660 own_addr_type, /* UINT8 addr_type_own */ 661 (UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? 662 p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* conn_int_min */ 663 (UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? 664 p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), /* conn_int_max */ 665 (UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? 666 p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), /* UINT16 conn_latency */ 667 (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? 668 p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), /* conn_timeout */ 669 0, /* UINT16 min_len */ 670 0)) /* UINT16 max_len */ 671 { 672 l2cu_release_lcb (p_lcb); 673 L2CAP_TRACE_ERROR("initate direct connection fail, no resources"); 674 return (FALSE); 675 } 676 else 677 { 678 p_lcb->link_state = LST_CONNECTING; 679 l2cb.is_ble_connecting = TRUE; 680 memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN); 681 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_BLE_LINK_CONNECT_TOUT); 682 btm_ble_set_conn_st (BLE_DIR_CONN); 683 684 return (TRUE); 685 } 686} 687 688/******************************************************************************* 689** 690** Function l2cble_create_conn 691** 692** Description This function initiates an acl connection via HCI 693** 694** Returns TRUE if successful, FALSE if connection not started. 695** 696*******************************************************************************/ 697BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb) 698{ 699 tBTM_BLE_CONN_ST conn_st = btm_ble_get_conn_st(); 700 BOOLEAN rt = FALSE; 701 702 /* There can be only one BLE connection request outstanding at a time */ 703 if (conn_st == BLE_CONN_IDLE) 704 { 705 rt = l2cble_init_direct_conn(p_lcb); 706 } 707 else 708 { 709 L2CAP_TRACE_WARNING ("L2CAP - LE - cannot start new connection at conn st: %d", conn_st); 710 711 btm_ble_enqueue_direct_conn_req(p_lcb); 712 713 if (conn_st == BLE_BG_CONN) 714 btm_ble_suspend_bg_conn(); 715 716 rt = TRUE; 717 } 718 return rt; 719} 720 721/******************************************************************************* 722** 723** Function l2c_link_processs_ble_num_bufs 724** 725** Description This function is called when a "controller buffer size" 726** event is first received from the controller. It updates 727** the L2CAP values. 728** 729** Returns void 730** 731*******************************************************************************/ 732void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs) 733{ 734 if (num_lm_ble_bufs == 0) 735 { 736 num_lm_ble_bufs = L2C_DEF_NUM_BLE_BUF_SHARED; 737 l2cb.num_lm_acl_bufs -= L2C_DEF_NUM_BLE_BUF_SHARED; 738 } 739 740 l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs; 741} 742 743#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) 744/******************************************************************************* 745** 746** Function l2cble_process_rc_param_request_evt 747** 748** Description process LE Remote Connection Parameter Request Event. 749** 750** Returns void 751** 752*******************************************************************************/ 753void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max, 754 UINT16 latency, UINT16 timeout) 755{ 756 tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle (handle); 757 758 if (p_lcb != NULL) 759 { 760 p_lcb->min_interval = int_min; 761 p_lcb->max_interval = int_max; 762 p_lcb->latency = latency; 763 p_lcb->timeout = timeout; 764 p_lcb->conn_update_mask |= UPD_REQUEST; 765 766 /* TODO: revisit: if update is enabled, always accept connection parameter update */ 767 if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED) 768 { 769 btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0); 770 } 771 else 772 { 773 L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled"); 774 btsnd_hcic_ble_rc_param_req_neg_reply (handle,HCI_ERR_UNACCEPT_CONN_INTERVAL); 775 } 776 777 } 778 else 779 { 780 L2CAP_TRACE_WARNING("No link to update connection parameter") 781 } 782} 783#endif 784 785 786#endif /* (BLE_INCLUDED == TRUE) */ 787