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