The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 */ |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 51 | if (btm_ble_get_conn_st() == BLE_DIR_CONN) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 | } |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 75 | /* update conn state to IDLE */ |
| 76 | btm_ble_set_conn_st (BLE_CONN_IDLE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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, |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 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), |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 | *******************************************************************************/ |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 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) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 | |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 */ |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 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) && |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 | |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 | { |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 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 || |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 475 | /*(timeout >= max_interval && latency > (timeout * 10/(max_interval * 1.25) - 1)) ||*/ |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 476 | timeout < BTM_BLE_CONN_SUP_TOUT_MIN || timeout > BTM_BLE_CONN_SUP_TOUT_MAX || |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 477 | max_interval < min_interval) |
| 478 | { |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 479 | l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_UNACCEPTABLE_PARAMS, id); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 | ** |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 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 | ** |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 | { |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 590 | tBTM_BLE_CONN_ST conn_st = btm_ble_get_conn_st(); |
| 591 | BOOLEAN rt = FALSE; |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 592 | |
| 593 | /* There can be only one BLE connection request outstanding at a time */ |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 594 | if (conn_st == BLE_CONN_IDLE) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 595 | { |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 596 | rt = l2cble_init_direct_conn(p_lcb); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 597 | } |
| 598 | else |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 599 | { |
| 600 | L2CAP_TRACE_WARNING1 ("L2CAP - LE - cannot start new connection at conn st: %d", conn_st); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 601 | |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 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; |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 | { |
Andre Eisenbach | 0082e02 | 2013-04-03 13:56:05 -0700 | [diff] [blame^] | 625 | if (num_lm_ble_bufs == 0) |
| 626 | num_lm_ble_bufs = l2cb.num_lm_acl_bufs; |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 627 | l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs; |
| 628 | } |
| 629 | |
| 630 | #endif /* (BLE_INCLUDED == TRUE) */ |