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