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