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" |
Mike J. Chen | 5cd8bff | 2014-01-31 18:16:59 -0800 | [diff] [blame] | 27 | #include "bt_utils.h" |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 28 | #include "l2cdefs.h" |
| 29 | #include "l2c_int.h" |
| 30 | #include "btu.h" |
| 31 | #include "btm_int.h" |
| 32 | #include "hcimsgs.h" |
| 33 | |
| 34 | #if (BLE_INCLUDED == TRUE) |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 35 | #define L2CA_GET_UPD_ST(x) ((x) & UPD_ST_MASK) |
| 36 | #define L2CA_SET_UPD_ST(x, y) x = (((x) & ~UPD_ST_MASK) | (y)) |
| 37 | |
Wei Wang | ed534e3 | 2014-05-20 06:30:13 +0000 | [diff] [blame] | 38 | #include "vendor_ble.h" |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 39 | /******************************************************************************* |
| 40 | ** |
| 41 | ** Function L2CA_CancelBleConnectReq |
| 42 | ** |
| 43 | ** Description Cancel a pending connection attempt to a BLE device. |
| 44 | ** |
| 45 | ** Parameters: BD Address of remote |
| 46 | ** |
| 47 | ** Return value: TRUE if connection was cancelled |
| 48 | ** |
| 49 | *******************************************************************************/ |
| 50 | BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda) |
| 51 | { |
| 52 | tL2C_LCB *p_lcb; |
| 53 | |
| 54 | /* There can be only one BLE connection request outstanding at a time */ |
Andre Eisenbach | 6975b4d | 2013-08-05 16:55:38 -0700 | [diff] [blame] | 55 | if (btm_ble_get_conn_st() == BLE_CONN_IDLE) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 56 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 57 | L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - no connection pending"); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 58 | return(FALSE); |
| 59 | } |
| 60 | |
| 61 | if (memcmp (rem_bda, l2cb.ble_connecting_bda, BD_ADDR_LEN)) |
| 62 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 63 | L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - different BDA Connecting: %08x%04x Cancel: %08x%04x", |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 64 | (l2cb.ble_connecting_bda[0]<<24)+(l2cb.ble_connecting_bda[1]<<16)+(l2cb.ble_connecting_bda[2]<<8)+l2cb.ble_connecting_bda[3], |
| 65 | (l2cb.ble_connecting_bda[4]<<8)+l2cb.ble_connecting_bda[5], |
| 66 | (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]); |
| 67 | |
| 68 | return(FALSE); |
| 69 | } |
| 70 | |
| 71 | if (btsnd_hcic_ble_create_conn_cancel()) |
| 72 | { |
| 73 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 74 | if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE)) != NULL) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 75 | { |
| 76 | p_lcb->disc_reason = L2CAP_CONN_CANCEL; |
| 77 | l2cu_release_lcb (p_lcb); |
| 78 | } |
Andre Eisenbach | 6975b4d | 2013-08-05 16:55:38 -0700 | [diff] [blame] | 79 | /* update state to be cancel, wait for connection cancel complete */ |
| 80 | btm_ble_set_conn_st (BLE_CONN_CANCEL); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 81 | |
| 82 | return(TRUE); |
| 83 | } |
| 84 | else |
| 85 | return(FALSE); |
| 86 | } |
| 87 | |
Zhihai Xu | 15d0a0c | 2013-12-17 20:33:09 -0800 | [diff] [blame] | 88 | /******************************************************************************* |
| 89 | ** |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 90 | ** Function L2CA_UpdateBleConnParams |
| 91 | ** |
| 92 | ** Description Update BLE connection parameters. |
| 93 | ** |
| 94 | ** Parameters: BD Address of remote |
| 95 | ** |
| 96 | ** Return value: TRUE if update started |
| 97 | ** |
| 98 | *******************************************************************************/ |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 99 | BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int, |
| 100 | UINT16 latency, UINT16 timeout) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 101 | { |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 102 | tL2C_LCB *p_lcb; |
| 103 | tACL_CONN *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 104 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 105 | /* See if we have a link control block for the remote device */ |
| 106 | p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 107 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 108 | /* If we don't have one, create one and accept the connection. */ |
| 109 | if (!p_lcb || !p_acl_cb) |
| 110 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 111 | L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x", |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 112 | (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], |
| 113 | (rem_bda[4]<<8)+rem_bda[5]); |
| 114 | return(FALSE); |
| 115 | } |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 116 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 117 | if (p_lcb->transport != BT_TRANSPORT_LE) |
| 118 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 119 | L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE", |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 120 | (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], |
| 121 | (rem_bda[4]<<8)+rem_bda[5]); |
| 122 | return(FALSE); |
| 123 | } |
| 124 | #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) |
| 125 | /* if both 4.1 compliant */ |
| 126 | if ((HCI_LE_CONN_PARAM_REQ_SUPPORTED(btm_cb.devcb.local_le_features) && |
| 127 | HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features))) |
| 128 | { |
| 129 | /* TODO: CE length selection ?? */ |
| 130 | btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int, |
| 131 | latency, timeout, 0, 0); |
| 132 | } |
| 133 | else |
| 134 | /* if either side does not support Connection Parameters Request |
| 135 | Link Layer Control Procedure, |
| 136 | use Link Layer Connection Update procedure */ |
| 137 | #endif |
| 138 | { |
| 139 | if (p_lcb->link_role == HCI_ROLE_MASTER) |
| 140 | btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int, |
| 141 | latency, timeout, 0, 0); |
| 142 | else |
| 143 | l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout); |
| 144 | } |
| 145 | return(TRUE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 146 | |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 147 | } |
| 148 | |
| 149 | |
| 150 | /******************************************************************************* |
| 151 | ** |
| 152 | ** Function L2CA_EnableUpdateBleConnParams |
| 153 | ** |
| 154 | ** Description Enable or disable update based on the request from the peer |
| 155 | ** |
| 156 | ** Parameters: BD Address of remote |
| 157 | ** |
| 158 | ** Return value: TRUE if update started |
| 159 | ** |
| 160 | *******************************************************************************/ |
| 161 | BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable) |
| 162 | { |
| 163 | tL2C_LCB *p_lcb; |
| 164 | |
| 165 | /* See if we have a link control block for the remote device */ |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 166 | p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 167 | |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 168 | if (!p_lcb) |
| 169 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 170 | L2CAP_TRACE_WARNING ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x", |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 171 | (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], |
| 172 | (rem_bda[4]<<8)+rem_bda[5]); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 173 | return (FALSE); |
| 174 | } |
| 175 | |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 176 | L2CAP_TRACE_API ("%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x",__FUNCTION__, |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 177 | (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], |
| 178 | (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->conn_update_mask); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 179 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 180 | if (p_lcb->transport != BT_TRANSPORT_LE || (p_lcb->link_role != HCI_ROLE_MASTER)) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 181 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 182 | L2CAP_TRACE_WARNING ("%s - BD_ADDR %08x%04x not LE or not master %d", __FUNCTION__, |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 183 | (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], |
| 184 | (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 185 | return (FALSE); |
| 186 | } |
| 187 | |
| 188 | if (enable) |
| 189 | { |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 190 | if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) == UPD_DISABLED) |
| 191 | { |
| 192 | p_lcb->conn_param_enb.param = (TIMER_PARAM_TYPE)p_lcb; |
| 193 | btu_start_timer (&p_lcb->conn_param_enb, BTU_TTYPE_L2CAP_END_CONN_UPD, |
| 194 | L2CAP_BLE_ENB_CONN_PARAM_TOUT); |
| 195 | L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENB_TOUT); |
| 196 | } |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 197 | } |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 198 | else if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) != UPD_DISABLED) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 199 | { |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 200 | btu_stop_timer(&p_lcb->conn_param_enb); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 201 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 202 | if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED) |
| 203 | { |
| 204 | |
| 205 | /* |
| 206 | application requests to disable parameters update.If parameters are already updated, |
| 207 | lets set them up to what has been requested during connection establishement |
| 208 | */ |
| 209 | if ((p_lcb->conn_update_mask & UPD_REQUEST) != 0) |
| 210 | { |
| 211 | /* revert back to default */ |
| 212 | btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, |
| 213 | BTM_BLE_CONN_INT_MIN_DEF, |
| 214 | BTM_BLE_CONN_INT_MAX_DEF, |
| 215 | BTM_BLE_CONN_SLAVE_LATENCY_DEF, |
| 216 | BTM_BLE_CONN_TIMEOUT_DEF, |
| 217 | 0, 0); |
| 218 | } |
| 219 | } |
| 220 | L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_DISABLED); |
| 221 | |
| 222 | } |
Zhihai Xu | 15d0a0c | 2013-12-17 20:33:09 -0800 | [diff] [blame] | 223 | |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 224 | return (TRUE); |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 225 | |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 226 | } |
| 227 | |
Zhihai Xu | 15d0a0c | 2013-12-17 20:33:09 -0800 | [diff] [blame] | 228 | |
| 229 | /******************************************************************************* |
| 230 | ** |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 231 | ** Function L2CA_GetBleConnRole |
| 232 | ** |
| 233 | ** Description This function returns the connection role. |
| 234 | ** |
| 235 | ** Returns link role. |
| 236 | ** |
| 237 | *******************************************************************************/ |
| 238 | UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr) |
| 239 | { |
| 240 | UINT8 role = HCI_ROLE_UNKNOWN; |
| 241 | |
| 242 | tL2C_LCB *p_lcb; |
| 243 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 244 | if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_LE)) != NULL) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 245 | role = p_lcb->link_role; |
| 246 | |
| 247 | return role; |
| 248 | } |
| 249 | /******************************************************************************* |
| 250 | ** |
| 251 | ** Function L2CA_GetDisconnectReason |
| 252 | ** |
| 253 | ** Description This function returns the disconnect reason code. |
| 254 | ** |
| 255 | ** Returns disconnect reason |
| 256 | ** |
| 257 | *******************************************************************************/ |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 258 | UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 259 | { |
| 260 | tL2C_LCB *p_lcb; |
| 261 | UINT16 reason = 0; |
| 262 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 263 | if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda, transport)) != NULL) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 264 | reason = p_lcb->disc_reason; |
| 265 | |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 266 | L2CAP_TRACE_DEBUG ("L2CA_GetDisconnectReason=%d ",reason); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 267 | |
| 268 | return reason; |
| 269 | } |
| 270 | |
| 271 | /******************************************************************************* |
| 272 | ** |
Priti Aghera | 9c29d08 | 2014-09-02 15:41:56 -0700 | [diff] [blame] | 273 | ** Function l2cble_notify_le_connection |
| 274 | ** |
| 275 | ** Description This function notifiy the l2cap connection to the app layer |
| 276 | ** |
| 277 | ** Returns none |
| 278 | ** |
| 279 | *******************************************************************************/ |
| 280 | void l2cble_notify_le_connection (BD_ADDR bda) |
| 281 | { |
| 282 | tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE); |
Prerepa Viswanadham | 7ae2515 | 2014-09-10 17:08:11 -0700 | [diff] [blame^] | 283 | tACL_CONN *p_acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE) ; |
Priti Aghera | 9c29d08 | 2014-09-02 15:41:56 -0700 | [diff] [blame] | 284 | |
Prerepa Viswanadham | 7ae2515 | 2014-09-10 17:08:11 -0700 | [diff] [blame^] | 285 | if (p_lcb != NULL && p_acl != NULL && p_lcb->link_state != LST_CONNECTED) |
| 286 | { |
| 287 | /* update link status */ |
| 288 | btm_establish_continue(p_acl); |
| 289 | /* update l2cap link status and send callback */ |
| 290 | p_lcb->link_state = LST_CONNECTED; |
Priti Aghera | 9c29d08 | 2014-09-02 15:41:56 -0700 | [diff] [blame] | 291 | l2cu_process_fixed_chnl_resp (p_lcb); |
Prerepa Viswanadham | 7ae2515 | 2014-09-10 17:08:11 -0700 | [diff] [blame^] | 292 | } |
Priti Aghera | 9c29d08 | 2014-09-02 15:41:56 -0700 | [diff] [blame] | 293 | } |
| 294 | |
| 295 | /******************************************************************************* |
| 296 | ** |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 297 | ** Function l2cble_scanner_conn_comp |
| 298 | ** |
| 299 | ** Description This function is called when an HCI Connection Complete |
| 300 | ** event is received while we are a scanner (so we are master). |
| 301 | ** |
| 302 | ** Returns void |
| 303 | ** |
| 304 | *******************************************************************************/ |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 305 | void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, |
| 306 | UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 307 | { |
| 308 | tL2C_LCB *p_lcb; |
| 309 | tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bda); |
| 310 | |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 311 | L2CAP_TRACE_DEBUG ("l2cble_scanner_conn_comp: HANDLE=%d addr_type=%d conn_interval=%d slave_latency=%d supervision_tout=%d", |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 312 | handle, type, conn_interval, conn_latency, conn_timeout); |
| 313 | |
| 314 | l2cb.is_ble_connecting = FALSE; |
| 315 | |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 316 | /* See if we have a link control block for the remote device */ |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 317 | p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 318 | |
| 319 | /* If we don't have one, create one. this is auto connection complete. */ |
| 320 | if (!p_lcb) |
| 321 | { |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 322 | p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 323 | if (!p_lcb) |
| 324 | { |
| 325 | btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 326 | L2CAP_TRACE_ERROR ("l2cble_scanner_conn_comp - failed to allocate LCB"); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 327 | return; |
| 328 | } |
| 329 | else |
| 330 | { |
| 331 | if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) |
| 332 | { |
| 333 | btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 334 | L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB"); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 335 | return ; |
| 336 | } |
| 337 | } |
| 338 | } |
| 339 | else if (p_lcb->link_state != LST_CONNECTING) |
| 340 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 341 | L2CAP_TRACE_ERROR ("L2CAP got BLE scanner conn_comp in bad state: %d", p_lcb->link_state); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 342 | return; |
| 343 | } |
| 344 | btu_stop_timer(&p_lcb->timer_entry); |
| 345 | |
| 346 | /* Save the handle */ |
| 347 | p_lcb->handle = handle; |
| 348 | |
| 349 | /* Connected OK. Change state to connected, we were scanning so we are master */ |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 350 | p_lcb->link_role = HCI_ROLE_MASTER; |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 351 | p_lcb->transport = BT_TRANSPORT_LE; |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 352 | |
| 353 | /* If there are any preferred connection parameters, set them now */ |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 354 | if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) && |
| 355 | (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX ) && |
| 356 | (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN ) && |
| 357 | (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX ) && |
| 358 | (p_dev_rec->conn_params.slave_latency <= BTM_BLE_CONN_LATENCY_MAX ) && |
| 359 | (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) && |
| 360 | (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] | 361 | ((conn_interval < p_dev_rec->conn_params.min_conn_int && |
| 362 | p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) || |
| 363 | (conn_interval > p_dev_rec->conn_params.max_conn_int) || |
| 364 | (conn_latency > p_dev_rec->conn_params.slave_latency) || |
| 365 | (conn_timeout > p_dev_rec->conn_params.supervision_tout))) |
| 366 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 367 | L2CAP_TRACE_ERROR ("upd_ll_conn_params: HANDLE=%d min_conn_int=%d max_conn_int=%d slave_latency=%d supervision_tout=%d", |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 368 | handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int, |
| 369 | p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout); |
| 370 | |
| 371 | btsnd_hcic_ble_upd_ll_conn_params (handle, |
| 372 | p_dev_rec->conn_params.min_conn_int, |
| 373 | p_dev_rec->conn_params.max_conn_int, |
| 374 | p_dev_rec->conn_params.slave_latency, |
| 375 | p_dev_rec->conn_params.supervision_tout, |
| 376 | 0, 0); |
| 377 | } |
| 378 | |
| 379 | /* Tell BTM Acl management about the link */ |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 380 | btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 381 | |
| 382 | p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT; |
| 383 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 384 | btm_ble_set_conn_st(BLE_CONN_IDLE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 385 | } |
| 386 | |
| 387 | |
| 388 | /******************************************************************************* |
| 389 | ** |
| 390 | ** Function l2cble_advertiser_conn_comp |
| 391 | ** |
| 392 | ** Description This function is called when an HCI Connection Complete |
| 393 | ** event is received while we are an advertiser (so we are slave). |
| 394 | ** |
| 395 | ** Returns void |
| 396 | ** |
| 397 | *******************************************************************************/ |
| 398 | void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, |
| 399 | UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) |
| 400 | { |
| 401 | tL2C_LCB *p_lcb; |
| 402 | tBTM_SEC_DEV_REC *p_dev_rec; |
Mike J. Chen | 5cd8bff | 2014-01-31 18:16:59 -0800 | [diff] [blame] | 403 | UNUSED(type); |
| 404 | UNUSED(conn_interval); |
| 405 | UNUSED(conn_latency); |
| 406 | UNUSED(conn_timeout); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 407 | |
| 408 | /* See if we have a link control block for the remote device */ |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 409 | p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 410 | |
| 411 | /* If we don't have one, create one and accept the connection. */ |
| 412 | if (!p_lcb) |
| 413 | { |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 414 | p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 415 | if (!p_lcb) |
| 416 | { |
| 417 | btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 418 | L2CAP_TRACE_ERROR ("l2cble_advertiser_conn_comp - failed to allocate LCB"); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 419 | return; |
| 420 | } |
| 421 | else |
| 422 | { |
| 423 | if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) |
| 424 | { |
| 425 | btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 426 | L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB"); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 427 | return ; |
| 428 | } |
| 429 | } |
| 430 | } |
| 431 | |
| 432 | /* Save the handle */ |
| 433 | p_lcb->handle = handle; |
| 434 | |
| 435 | /* Connected OK. Change state to connected, we were advertising, so we are slave */ |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 436 | p_lcb->link_role = HCI_ROLE_SLAVE; |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 437 | p_lcb->transport = BT_TRANSPORT_LE; |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 438 | |
| 439 | /* Tell BTM Acl management about the link */ |
| 440 | p_dev_rec = btm_find_or_alloc_dev (bda); |
| 441 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 442 | btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 443 | |
| 444 | p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT; |
| 445 | |
Priti Aghera | 9c29d08 | 2014-09-02 15:41:56 -0700 | [diff] [blame] | 446 | if (!HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(btm_cb.devcb.local_le_features)) |
| 447 | { |
Prerepa Viswanadham | 7ae2515 | 2014-09-10 17:08:11 -0700 | [diff] [blame^] | 448 | p_lcb->link_state = LST_CONNECTED; |
Priti Aghera | 9c29d08 | 2014-09-02 15:41:56 -0700 | [diff] [blame] | 449 | l2cu_process_fixed_chnl_resp (p_lcb); |
| 450 | } |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 451 | |
| 452 | /* when adv and initiating are both active, cancel the direct connection */ |
| 453 | if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0) |
| 454 | { |
| 455 | L2CA_CancelBleConnectReq(bda); |
| 456 | } |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 457 | } |
| 458 | |
| 459 | /******************************************************************************* |
| 460 | ** |
| 461 | ** Function l2cble_conn_comp |
| 462 | ** |
| 463 | ** Description This function is called when an HCI Connection Complete |
| 464 | ** event is received. |
| 465 | ** |
| 466 | ** Returns void |
| 467 | ** |
| 468 | *******************************************************************************/ |
| 469 | void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type, |
| 470 | UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) |
| 471 | { |
| 472 | if (role == HCI_ROLE_MASTER) |
| 473 | { |
| 474 | l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout); |
| 475 | } |
| 476 | else |
| 477 | { |
| 478 | l2cble_advertiser_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout); |
| 479 | } |
| 480 | } |
| 481 | /******************************************************************************* |
| 482 | ** |
| 483 | ** Function l2cble_process_sig_cmd |
| 484 | ** |
| 485 | ** Description This function is called when a signalling packet is received |
| 486 | ** on the BLE signalling CID |
| 487 | ** |
| 488 | ** Returns void |
| 489 | ** |
| 490 | *******************************************************************************/ |
| 491 | void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) |
| 492 | { |
| 493 | UINT8 *p_pkt_end; |
| 494 | UINT8 cmd_code, id; |
| 495 | UINT16 cmd_len, rej_reason; |
| 496 | UINT16 result; |
| 497 | UINT16 min_interval, max_interval, latency, timeout; |
| 498 | |
| 499 | p_pkt_end = p + pkt_len; |
| 500 | |
| 501 | STREAM_TO_UINT8 (cmd_code, p); |
| 502 | STREAM_TO_UINT8 (id, p); |
| 503 | STREAM_TO_UINT16 (cmd_len, p); |
| 504 | |
| 505 | /* Check command length does not exceed packet length */ |
| 506 | if ((p + cmd_len) > p_pkt_end) |
| 507 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 508 | L2CAP_TRACE_WARNING ("L2CAP - LE - format error, pkt_len: %d cmd_len: %d code: %d", pkt_len, cmd_len, cmd_code); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 509 | return; |
| 510 | } |
| 511 | |
| 512 | switch (cmd_code) |
| 513 | { |
| 514 | case L2CAP_CMD_REJECT: |
| 515 | case L2CAP_CMD_ECHO_RSP: |
| 516 | case L2CAP_CMD_INFO_RSP: |
| 517 | STREAM_TO_UINT16 (rej_reason, p); |
| 518 | break; |
| 519 | case L2CAP_CMD_ECHO_REQ: |
| 520 | case L2CAP_CMD_INFO_REQ: |
| 521 | l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); |
| 522 | break; |
| 523 | |
| 524 | case L2CAP_CMD_BLE_UPDATE_REQ: |
| 525 | STREAM_TO_UINT16 (min_interval, p); /* 0x0006 - 0x0C80 */ |
| 526 | STREAM_TO_UINT16 (max_interval, p); /* 0x0006 - 0x0C80 */ |
| 527 | STREAM_TO_UINT16 (latency, p); /* 0x0000 - 0x03E8 */ |
| 528 | STREAM_TO_UINT16 (timeout, p); /* 0x000A - 0x0C80 */ |
| 529 | /* If we are a master, the slave wants to update the parameters */ |
| 530 | if (p_lcb->link_role == HCI_ROLE_MASTER) |
| 531 | { |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 532 | if (min_interval < BTM_BLE_CONN_INT_MIN || min_interval > BTM_BLE_CONN_INT_MAX || |
| 533 | max_interval < BTM_BLE_CONN_INT_MIN || max_interval > BTM_BLE_CONN_INT_MAX || |
| 534 | latency > BTM_BLE_CONN_LATENCY_MAX || |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 535 | /*(timeout >= max_interval && latency > (timeout * 10/(max_interval * 1.25) - 1)) ||*/ |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 536 | 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] | 537 | max_interval < min_interval) |
| 538 | { |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 539 | 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] | 540 | } |
| 541 | else |
| 542 | { |
| 543 | |
| 544 | l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id); |
| 545 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 546 | p_lcb->min_interval = min_interval; |
| 547 | p_lcb->max_interval = max_interval; |
| 548 | p_lcb->latency = latency; |
| 549 | p_lcb->timeout = timeout; |
| 550 | p_lcb->conn_update_mask |= UPD_REQUEST; |
| 551 | |
| 552 | if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED) |
| 553 | { |
| 554 | btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval, |
| 555 | latency, timeout, 0, 0); |
| 556 | } |
| 557 | else |
| 558 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 559 | L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled"); |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 560 | } |
| 561 | |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 562 | } |
| 563 | } |
| 564 | else |
| 565 | l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); |
| 566 | break; |
| 567 | |
| 568 | case L2CAP_CMD_BLE_UPDATE_RSP: |
| 569 | STREAM_TO_UINT16 (result, p); |
| 570 | break; |
| 571 | |
| 572 | default: |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 573 | L2CAP_TRACE_WARNING ("L2CAP - LE - unknown cmd code: %d", cmd_code); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 574 | l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); |
| 575 | return; |
| 576 | } |
| 577 | } |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 578 | /******************************************************************************* |
| 579 | ** |
| 580 | ** Function l2c_enable_conn_param_timeout |
| 581 | ** |
| 582 | ** Description This function process the connection parameter enabling timeout |
| 583 | ** |
| 584 | ** Returns None. |
| 585 | ** |
| 586 | *******************************************************************************/ |
| 587 | void l2c_enable_conn_param_timeout(tL2C_LCB * p_lcb) |
| 588 | { |
| 589 | tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 590 | |
| 591 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 592 | /* application allows to do update, if we were delaying one do it now, otherwise |
| 593 | just mark lcb that updates are enabled */ |
| 594 | if (p_lcb->conn_update_mask & UPD_REQUEST) |
| 595 | { |
| 596 | btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval, |
| 597 | p_lcb->latency, p_lcb->timeout, 0, 0); |
| 598 | } |
| 599 | else |
| 600 | { |
| 601 | /* if preferred number has been set, set to preferred conn parameter */ |
| 602 | if (p_dev_rec && p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) |
| 603 | { |
| 604 | btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, |
| 605 | (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? |
| 606 | p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), |
| 607 | (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? |
| 608 | p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), |
| 609 | (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? |
| 610 | p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), |
| 611 | (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? |
| 612 | p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), |
| 613 | 0, 0); |
| 614 | } |
| 615 | } |
| 616 | L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENABLED); |
| 617 | |
| 618 | } |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 619 | /******************************************************************************* |
| 620 | ** |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 621 | ** Function l2cble_init_direct_conn |
| 622 | ** |
| 623 | ** Description This function is to initate a direct connection |
| 624 | ** |
| 625 | ** Returns TRUE connection initiated, FALSE otherwise. |
| 626 | ** |
| 627 | *******************************************************************************/ |
| 628 | BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) |
| 629 | { |
| 630 | tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr); |
| 631 | tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; |
| 632 | UINT16 scan_int, scan_win; |
| 633 | BD_ADDR init_addr; |
| 634 | UINT8 init_addr_type = BLE_ADDR_PUBLIC, |
| 635 | own_addr_type = BLE_ADDR_PUBLIC; |
| 636 | |
| 637 | /* There can be only one BLE connection request outstanding at a time */ |
| 638 | if (p_dev_rec == NULL) |
| 639 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 640 | L2CAP_TRACE_WARNING ("unknown device, can not initate connection"); |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 641 | return(FALSE); |
| 642 | } |
| 643 | |
| 644 | scan_int = (p_cb->scan_int == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int; |
| 645 | scan_win = (p_cb->scan_win == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win; |
| 646 | |
| 647 | init_addr_type = p_lcb->ble_addr_type; |
| 648 | memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN); |
| 649 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 650 | #if BLE_PRIVACY_SPT == TRUE |
Zhihai Xu | 8b35b3f | 2014-03-11 15:01:45 -0700 | [diff] [blame] | 651 | if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA) |
| 652 | { |
| 653 | init_addr_type = BLE_ADDR_RANDOM; |
Zhihai Xu | 8b35b3f | 2014-03-11 15:01:45 -0700 | [diff] [blame] | 654 | } |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 655 | /* if privacy is on and current do not consider using reconnection address */ |
| 656 | if (btm_cb.ble_ctr_cb.privacy ) /* && p_dev_rec->ble.use_reconn_addr */ |
| 657 | own_addr_type = BLE_ADDR_RANDOM; |
Zhihai Xu | 8b35b3f | 2014-03-11 15:01:45 -0700 | [diff] [blame] | 658 | #endif |
| 659 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 660 | if (!btm_ble_topology_check(BTM_BLE_STATE_INIT)) |
| 661 | { |
| 662 | l2cu_release_lcb (p_lcb); |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 663 | L2CAP_TRACE_ERROR("initate direct connection fail, topology limitation"); |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 664 | return FALSE; |
| 665 | } |
Prerepa Viswanadham | 16fe082 | 2014-08-07 11:38:06 -0700 | [diff] [blame] | 666 | if (btm_ble_vendor_irk_list_load_dev(p_dev_rec) && |
| 667 | (btm_cb.cmn_ble_vsc_cb.rpa_offloading == TRUE )) |
| 668 | { |
| 669 | btm_ble_vendor_enable_irk_feature(TRUE); |
| 670 | btm_random_pseudo_to_public(init_addr, &init_addr_type); |
| 671 | } |
Wei Wang | ed534e3 | 2014-05-20 06:30:13 +0000 | [diff] [blame] | 672 | |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 673 | if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */ |
| 674 | scan_win, /* UINT16 scan_win */ |
| 675 | FALSE, /* UINT8 white_list */ |
Andre Eisenbach | 6975b4d | 2013-08-05 16:55:38 -0700 | [diff] [blame] | 676 | init_addr_type, /* UINT8 addr_type_peer */ |
| 677 | init_addr, /* BD_ADDR bda_peer */ |
| 678 | own_addr_type, /* UINT8 addr_type_own */ |
Zhihai Xu | 3dc5945 | 2013-10-25 16:47:49 -0700 | [diff] [blame] | 679 | (UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? |
| 680 | p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* conn_int_min */ |
| 681 | (UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? |
| 682 | p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), /* conn_int_max */ |
| 683 | (UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? |
Steve Paik | 9c07b33 | 2014-06-19 15:50:46 -0700 | [diff] [blame] | 684 | p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), /* UINT16 conn_latency */ |
Zhihai Xu | 3dc5945 | 2013-10-25 16:47:49 -0700 | [diff] [blame] | 685 | (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? |
Steve Paik | 9c07b33 | 2014-06-19 15:50:46 -0700 | [diff] [blame] | 686 | p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), /* conn_timeout */ |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 687 | 0, /* UINT16 min_len */ |
| 688 | 0)) /* UINT16 max_len */ |
| 689 | { |
| 690 | l2cu_release_lcb (p_lcb); |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 691 | L2CAP_TRACE_ERROR("initate direct connection fail, no resources"); |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 692 | return (FALSE); |
| 693 | } |
| 694 | else |
| 695 | { |
| 696 | p_lcb->link_state = LST_CONNECTING; |
Andre Eisenbach | 6975b4d | 2013-08-05 16:55:38 -0700 | [diff] [blame] | 697 | l2cb.is_ble_connecting = TRUE; |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 698 | memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN); |
| 699 | btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_BLE_LINK_CONNECT_TOUT); |
| 700 | btm_ble_set_conn_st (BLE_DIR_CONN); |
| 701 | |
| 702 | return (TRUE); |
| 703 | } |
| 704 | } |
| 705 | |
| 706 | /******************************************************************************* |
| 707 | ** |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 708 | ** Function l2cble_create_conn |
| 709 | ** |
| 710 | ** Description This function initiates an acl connection via HCI |
| 711 | ** |
| 712 | ** Returns TRUE if successful, FALSE if connection not started. |
| 713 | ** |
| 714 | *******************************************************************************/ |
| 715 | BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb) |
| 716 | { |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 717 | tBTM_BLE_CONN_ST conn_st = btm_ble_get_conn_st(); |
| 718 | BOOLEAN rt = FALSE; |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 719 | |
| 720 | /* 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] | 721 | if (conn_st == BLE_CONN_IDLE) |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 722 | { |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 723 | rt = l2cble_init_direct_conn(p_lcb); |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 724 | } |
| 725 | else |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 726 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 727 | L2CAP_TRACE_WARNING ("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] | 728 | |
Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 729 | btm_ble_enqueue_direct_conn_req(p_lcb); |
| 730 | |
| 731 | if (conn_st == BLE_BG_CONN) |
| 732 | btm_ble_suspend_bg_conn(); |
| 733 | |
| 734 | rt = TRUE; |
| 735 | } |
| 736 | return rt; |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 737 | } |
| 738 | |
| 739 | /******************************************************************************* |
| 740 | ** |
| 741 | ** Function l2c_link_processs_ble_num_bufs |
| 742 | ** |
| 743 | ** Description This function is called when a "controller buffer size" |
| 744 | ** event is first received from the controller. It updates |
| 745 | ** the L2CAP values. |
| 746 | ** |
| 747 | ** Returns void |
| 748 | ** |
| 749 | *******************************************************************************/ |
| 750 | void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs) |
| 751 | { |
Andre Eisenbach | 0082e02 | 2013-04-03 13:56:05 -0700 | [diff] [blame] | 752 | if (num_lm_ble_bufs == 0) |
Andre Eisenbach | 12c3f49 | 2013-04-24 16:02:04 -0700 | [diff] [blame] | 753 | { |
| 754 | num_lm_ble_bufs = L2C_DEF_NUM_BLE_BUF_SHARED; |
| 755 | l2cb.num_lm_acl_bufs -= L2C_DEF_NUM_BLE_BUF_SHARED; |
| 756 | } |
| 757 | |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 758 | l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs; |
| 759 | } |
| 760 | |
Mudumba Ananth | 92ac2d8 | 2014-07-11 00:05:54 -0700 | [diff] [blame] | 761 | /******************************************************************************* |
| 762 | ** |
| 763 | ** Function l2c_ble_link_adjust_allocation |
| 764 | ** |
| 765 | ** Description This function is called when a link is created or removed |
| 766 | ** to calculate the amount of packets each link may send to |
| 767 | ** the HCI without an ack coming back. |
| 768 | ** |
| 769 | ** Currently, this is a simple allocation, dividing the |
| 770 | ** number of Controller Packets by the number of links. In |
| 771 | ** the future, QOS configuration should be examined. |
| 772 | ** |
| 773 | ** Returns void |
| 774 | ** |
| 775 | *******************************************************************************/ |
| 776 | void l2c_ble_link_adjust_allocation (void) |
| 777 | { |
| 778 | UINT16 qq, yy, qq_remainder; |
| 779 | tL2C_LCB *p_lcb; |
| 780 | UINT16 hi_quota, low_quota; |
| 781 | UINT16 num_lowpri_links = 0; |
| 782 | UINT16 num_hipri_links = 0; |
| 783 | UINT16 controller_xmit_quota = l2cb.num_lm_ble_bufs; |
| 784 | UINT16 high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A; |
| 785 | |
| 786 | /* If no links active, reset buffer quotas and controller buffers */ |
| 787 | if (l2cb.num_ble_links_active == 0) |
| 788 | { |
| 789 | l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs; |
| 790 | l2cb.ble_round_robin_quota = l2cb.ble_round_robin_unacked = 0; |
| 791 | return; |
| 792 | } |
| 793 | |
| 794 | /* First, count the links */ |
| 795 | for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) |
| 796 | { |
| 797 | if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) |
| 798 | { |
| 799 | if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) |
| 800 | num_hipri_links++; |
| 801 | else |
| 802 | num_lowpri_links++; |
| 803 | } |
| 804 | } |
| 805 | |
| 806 | /* now adjust high priority link quota */ |
| 807 | low_quota = num_lowpri_links ? 1 : 0; |
| 808 | while ( (num_hipri_links * high_pri_link_quota + low_quota) > controller_xmit_quota ) |
| 809 | high_pri_link_quota--; |
| 810 | |
| 811 | |
| 812 | /* Work out the xmit quota and buffer quota high and low priorities */ |
| 813 | hi_quota = num_hipri_links * high_pri_link_quota; |
| 814 | low_quota = (hi_quota < controller_xmit_quota) ? controller_xmit_quota - hi_quota : 1; |
| 815 | |
| 816 | /* Work out and save the HCI xmit quota for each low priority link */ |
| 817 | |
| 818 | /* If each low priority link cannot have at least one buffer */ |
| 819 | if (num_lowpri_links > low_quota) |
| 820 | { |
| 821 | l2cb.ble_round_robin_quota = low_quota; |
| 822 | qq = qq_remainder = 0; |
| 823 | } |
| 824 | /* If each low priority link can have at least one buffer */ |
| 825 | else if (num_lowpri_links > 0) |
| 826 | { |
| 827 | l2cb.ble_round_robin_quota = 0; |
| 828 | l2cb.ble_round_robin_unacked = 0; |
| 829 | qq = low_quota / num_lowpri_links; |
| 830 | qq_remainder = low_quota % num_lowpri_links; |
| 831 | } |
| 832 | /* If no low priority link */ |
| 833 | else |
| 834 | { |
| 835 | l2cb.ble_round_robin_quota = 0; |
| 836 | l2cb.ble_round_robin_unacked = 0; |
| 837 | qq = qq_remainder = 0; |
| 838 | } |
| 839 | L2CAP_TRACE_EVENT ("l2c_ble_link_adjust_allocation num_hipri: %u num_lowpri: %u low_quota: %u round_robin_quota: %u qq: %u", |
| 840 | num_hipri_links, num_lowpri_links, low_quota, |
| 841 | l2cb.ble_round_robin_quota, qq); |
| 842 | |
| 843 | /* Now, assign the quotas to each link */ |
| 844 | for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) |
| 845 | { |
| 846 | if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) |
| 847 | { |
| 848 | if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) |
| 849 | { |
| 850 | p_lcb->link_xmit_quota = high_pri_link_quota; |
| 851 | } |
| 852 | else |
| 853 | { |
| 854 | /* Safety check in case we switched to round-robin with something outstanding */ |
| 855 | /* if sent_not_acked is added into round_robin_unacked then don't add it again */ |
| 856 | /* l2cap keeps updating sent_not_acked for exiting from round robin */ |
| 857 | if (( p_lcb->link_xmit_quota > 0 )&&( qq == 0 )) |
| 858 | l2cb.ble_round_robin_unacked += p_lcb->sent_not_acked; |
| 859 | |
| 860 | p_lcb->link_xmit_quota = qq; |
| 861 | if (qq_remainder > 0) |
| 862 | { |
| 863 | p_lcb->link_xmit_quota++; |
| 864 | qq_remainder--; |
| 865 | } |
| 866 | } |
| 867 | |
| 868 | L2CAP_TRACE_EVENT("l2c_ble_link_adjust_allocation LCB %d Priority: %d XmitQuota: %d", |
| 869 | yy, p_lcb->acl_priority, p_lcb->link_xmit_quota); |
| 870 | |
| 871 | L2CAP_TRACE_EVENT(" SentNotAcked: %d RRUnacked: %d", |
| 872 | p_lcb->sent_not_acked, l2cb.round_robin_unacked); |
| 873 | |
| 874 | /* There is a special case where we have readjusted the link quotas and */ |
| 875 | /* this link may have sent anything but some other link sent packets so */ |
| 876 | /* so we may need a timer to kick off this link's transmissions. */ |
| 877 | if ( (p_lcb->link_state == LST_CONNECTED) |
| 878 | && (p_lcb->link_xmit_data_q.count) |
| 879 | && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota) ) |
| 880 | btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_FLOW_CONTROL_TOUT); |
| 881 | } |
| 882 | } |
| 883 | } |
| 884 | |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 885 | #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) |
| 886 | /******************************************************************************* |
| 887 | ** |
| 888 | ** Function l2cble_process_rc_param_request_evt |
| 889 | ** |
| 890 | ** Description process LE Remote Connection Parameter Request Event. |
| 891 | ** |
| 892 | ** Returns void |
| 893 | ** |
| 894 | *******************************************************************************/ |
| 895 | void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max, |
| 896 | UINT16 latency, UINT16 timeout) |
| 897 | { |
| 898 | tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle (handle); |
| 899 | |
| 900 | if (p_lcb != NULL) |
| 901 | { |
| 902 | p_lcb->min_interval = int_min; |
| 903 | p_lcb->max_interval = int_max; |
| 904 | p_lcb->latency = latency; |
| 905 | p_lcb->timeout = timeout; |
| 906 | p_lcb->conn_update_mask |= UPD_REQUEST; |
| 907 | |
| 908 | /* TODO: revisit: if update is enabled, always accept connection parameter update */ |
| 909 | if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED) |
| 910 | { |
| 911 | btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0); |
| 912 | } |
| 913 | else |
| 914 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 915 | L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled"); |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 916 | btsnd_hcic_ble_rc_param_req_neg_reply (handle,HCI_ERR_UNACCEPT_CONN_INTERVAL); |
| 917 | } |
| 918 | |
| 919 | } |
| 920 | else |
| 921 | { |
Sharvil Nanavati | a51c9d9 | 2014-05-04 01:08:21 -0700 | [diff] [blame] | 922 | L2CAP_TRACE_WARNING("No link to update connection parameter") |
Ganesh Ganapathi Batta | 7fa4fba | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 923 | } |
| 924 | } |
| 925 | #endif |
| 926 | |
| 927 | |
The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 928 | #endif /* (BLE_INCLUDED == TRUE) */ |