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