]> granicus.if.org Git - esp-idf/blob - components/bt/bluedroid/stack/l2cap/l2c_ble.c
efc37857677fad3950b990dfea88e30ab219fb8c
[esp-idf] / components / bt / bluedroid / stack / l2cap / l2c_ble.c
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 "common/bt_target.h"
27 //#include "bt_utils.h"
28 #include "stack/l2cdefs.h"
29 #include "l2c_int.h"
30 #include "stack/btu.h"
31 #include "btm_int.h"
32 #include "stack/hcimsgs.h"
33 #include "device/controller.h"
34
35 #if (BLE_INCLUDED == TRUE)
36 static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb);
37
38 /*******************************************************************************
39 **
40 **  Function        L2CA_CancelBleConnectReq
41 **
42 **  Description     Cancel a pending connection attempt to a BLE device.
43 **
44 **  Parameters:     BD Address of remote
45 **
46 **  Return value:   TRUE if connection was cancelled
47 **
48 *******************************************************************************/
49 BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda)
50 {
51     tL2C_LCB *p_lcb;
52
53     /* There can be only one BLE connection request outstanding at a time */
54     if (btm_ble_get_conn_st() == BLE_CONN_IDLE) {
55         L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - no connection pending");
56         return (FALSE);
57     }
58
59     if (memcmp (rem_bda, l2cb.ble_connecting_bda, BD_ADDR_LEN)) {
60         L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - different  BDA Connecting: %08x%04x  Cancel: %08x%04x",
61                              (l2cb.ble_connecting_bda[0] << 24) + (l2cb.ble_connecting_bda[1] << 16) + (l2cb.ble_connecting_bda[2] << 8) + l2cb.ble_connecting_bda[3],
62                              (l2cb.ble_connecting_bda[4] << 8) + l2cb.ble_connecting_bda[5],
63                              (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], (rem_bda[4] << 8) + rem_bda[5]);
64
65         return (FALSE);
66     }
67
68     if (btsnd_hcic_ble_create_conn_cancel()) {
69         p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
70         /* Do not remove lcb if an LE link is already up as a peripheral */
71         if (p_lcb != NULL &&
72                 !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_ACL_IS_CONNECTED(rem_bda))) {
73             p_lcb->disc_reason = L2CAP_CONN_CANCEL;
74             l2cu_release_lcb (p_lcb);
75         }
76         /* update state to be cancel, wait for connection cancel complete */
77         btm_ble_set_conn_st (BLE_CONN_CANCEL);
78
79         return (TRUE);
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,
97                                   UINT16 latency, UINT16 timeout)
98 {
99     tL2C_LCB            *p_lcb;
100     tACL_CONN           *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE);
101
102     /* See if we have a link control block for the remote device */
103     p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
104
105     /* If we don't have one, create one and accept the connection. */
106     if (!p_lcb || !p_acl_cb) {
107         L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
108                              (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
109                              (rem_bda[4] << 8) + rem_bda[5]);
110         return (FALSE);
111     }
112
113     if (p_lcb->transport != BT_TRANSPORT_LE) {
114         L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
115                              (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
116                              (rem_bda[4] << 8) + rem_bda[5]);
117         return (FALSE);
118     }
119
120     if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PARAM_FULL){
121         UINT8 status = HCI_ERR_ILLEGAL_COMMAND;
122         L2CAP_TRACE_ERROR("There are two connection parameter requests that are being updated, please try later ");
123         if (conn_param_update_cb.update_conn_param_cb != NULL) {
124             tBTM_LE_UPDATE_CONN_PRAMS update_param;
125             update_param.max_conn_int = max_int;
126             update_param.min_conn_int = min_int;
127             update_param.conn_int = p_lcb->current_used_conn_interval;
128             update_param.slave_latency = p_lcb->current_used_conn_latency;
129             update_param.supervision_tout = p_lcb->current_used_conn_timeout;
130             (conn_param_update_cb.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param);
131         }
132         return (FALSE);
133     }
134
135     p_lcb->waiting_update_conn_min_interval = min_int;
136     p_lcb->waiting_update_conn_max_interval = max_int;
137     p_lcb->waiting_update_conn_latency = latency;
138     p_lcb->waiting_update_conn_timeout = timeout;
139     p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
140
141     if(l2cble_start_conn_update(p_lcb) == TRUE) {
142         UINT32 time = CalConnectParamTimeout(p_lcb);
143         btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time);
144     }
145
146     return (TRUE);
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 */
166     p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
167
168     if (!p_lcb) {
169         L2CAP_TRACE_WARNING ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x",
170                              (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
171                              (rem_bda[4] << 8) + rem_bda[5]);
172         return (FALSE);
173     }
174
175     L2CAP_TRACE_API ("%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x", __FUNCTION__,
176                      (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
177                      (rem_bda[4] << 8) + rem_bda[5], enable, p_lcb->conn_update_mask);
178
179     if (p_lcb->transport != BT_TRANSPORT_LE) {
180         L2CAP_TRACE_WARNING ("%s - BD_ADDR %08x%04x not LE (link role %d)", __FUNCTION__,
181                              (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
182                              (rem_bda[4] << 8) + rem_bda[5], p_lcb->link_role);
183         return (FALSE);
184     }
185
186     if (p_lcb->current_used_conn_interval <= BTM_BLE_CONN_INT_MAX_DEF && (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0){
187         return (FALSE);
188     }
189
190     if (enable) {
191         p_lcb->conn_update_mask &= ~L2C_BLE_CONN_UPDATE_DISABLE;
192     } else {
193         p_lcb->conn_update_mask |= L2C_BLE_CONN_UPDATE_DISABLE;
194     }
195
196     if (l2cble_start_conn_update(p_lcb) == TRUE) {
197         UINT32 time = CalConnectParamTimeout(p_lcb);
198         btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time);
199     }
200
201     return (TRUE);
202 }
203
204
205 /*******************************************************************************
206 **
207 ** Function         L2CA_GetBleConnRole
208 **
209 ** Description      This function returns the connection role.
210 **
211 ** Returns          link role.
212 **
213 *******************************************************************************/
214 UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr)
215 {
216     UINT8       role = HCI_ROLE_UNKNOWN;
217
218     tL2C_LCB *p_lcb;
219
220     if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_LE)) != NULL) {
221         role = p_lcb->link_role;
222     }
223
224     return role;
225 }
226
227 /*******************************************************************************
228 **
229 ** Function l2cble_notify_le_connection
230 **
231 ** Description This function notifiy the l2cap connection to the app layer
232 **
233 ** Returns none
234 **
235 *******************************************************************************/
236 void l2cble_notify_le_connection (BD_ADDR bda)
237 {
238     tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
239     tACL_CONN *p_acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE) ;
240
241     if (p_lcb != NULL && p_acl != NULL && p_lcb->link_state != LST_CONNECTED) {
242
243         if(p_acl->link_role == HCI_ROLE_SLAVE) {
244             //clear p_cb->state, controller will stop adv when ble connected.
245             tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
246             if(p_cb) {
247                 p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
248                 p_cb->state = BTM_BLE_STOP_ADV;
249             }
250         }
251         /* update link status */
252         btm_establish_continue(p_acl);
253         /* update l2cap link status and send callback */
254         p_lcb->link_state = LST_CONNECTED;
255         l2cu_process_fixed_chnl_resp (p_lcb);
256     }
257 }
258
259 /*******************************************************************************
260 **
261 ** Function         l2cble_scanner_conn_comp
262 **
263 ** Description      This function is called when an HCI Connection Complete
264 **                  event is received while we are a scanner (so we are master).
265 **
266 ** Returns          void
267 **
268 *******************************************************************************/
269 void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
270                                UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
271 {
272     tL2C_LCB            *p_lcb;
273     tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (bda);
274
275     L2CAP_TRACE_DEBUG ("l2cble_scanner_conn_comp: HANDLE=%d addr_type=%d conn_interval=%d slave_latency=%d supervision_tout=%d",
276                        handle,  type, conn_interval, conn_latency, conn_timeout);
277
278     l2cb.is_ble_connecting = FALSE;
279
280     /* See if we have a link control block for the remote device */
281     p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
282
283     /* If we don't have one, create one. this is auto connection complete. */
284     if (!p_lcb) {
285         p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
286         if (!p_lcb) {
287 #if (SMP_INCLUDED == TRUE)
288             btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
289             L2CAP_TRACE_ERROR ("l2cble_scanner_conn_comp - failed to allocate LCB");
290 #endif  ///SMP_INCLUDED == TRUE
291             return;
292         } else {
293             if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) {
294 #if (SMP_INCLUDED == TRUE)
295                 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
296                 L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB");
297 #endif  ///SMP_INCLUDED == TRUE
298                 return ;
299             }
300         }
301     } else if (p_lcb->link_state != LST_CONNECTING) {
302         L2CAP_TRACE_ERROR ("L2CAP got BLE scanner conn_comp in bad state: %d", p_lcb->link_state);
303         return;
304     }
305     btu_stop_timer(&p_lcb->timer_entry);
306
307     /* Save the handle */
308     p_lcb->handle = handle;
309
310     /* Connected OK. Change state to connected, we were scanning so we are master */
311     p_lcb->link_role  = HCI_ROLE_MASTER;
312     p_lcb->transport  = BT_TRANSPORT_LE;
313
314     /* update link parameter, set slave link as non-spec default upon link up */
315     p_lcb->waiting_update_conn_min_interval = p_lcb->waiting_update_conn_max_interval = p_lcb->current_used_conn_interval = conn_interval;
316     p_lcb->waiting_update_conn_timeout = p_lcb->current_used_conn_timeout = conn_timeout;
317     p_lcb->waiting_update_conn_latency = p_lcb->current_used_conn_latency = conn_latency;
318     p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM;
319     p_lcb->updating_param_flag = false;
320
321     /* If there are any preferred connection parameters, set them now */
322     if ( (p_dev_rec->conn_params.min_conn_int     >= BTM_BLE_CONN_INT_MIN ) &&
323             (p_dev_rec->conn_params.min_conn_int     <= BTM_BLE_CONN_INT_MAX ) &&
324             (p_dev_rec->conn_params.max_conn_int     >= BTM_BLE_CONN_INT_MIN ) &&
325             (p_dev_rec->conn_params.max_conn_int     <= BTM_BLE_CONN_INT_MAX ) &&
326             (p_dev_rec->conn_params.slave_latency    <= BTM_BLE_CONN_LATENCY_MAX ) &&
327             (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) &&
328             (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) &&
329             ((conn_interval < p_dev_rec->conn_params.min_conn_int &&
330               p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ||
331              (conn_interval > p_dev_rec->conn_params.max_conn_int) ||
332              (conn_latency > p_dev_rec->conn_params.slave_latency) ||
333              (conn_timeout > p_dev_rec->conn_params.supervision_tout))) {
334         L2CAP_TRACE_WARNING ("upd_ll_conn_params: HANDLE=%d min_conn_int=%d max_conn_int=%d slave_latency=%d supervision_tout=%d",
335                            handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int,
336                            p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout);
337
338         p_lcb->waiting_update_conn_min_interval = p_dev_rec->conn_params.min_conn_int;
339         p_lcb->waiting_update_conn_max_interval = p_dev_rec->conn_params.max_conn_int;
340         p_lcb->waiting_update_conn_timeout      = p_dev_rec->conn_params.supervision_tout;
341         p_lcb->waiting_update_conn_latency      = p_dev_rec->conn_params.slave_latency;
342
343         btsnd_hcic_ble_upd_ll_conn_params (handle,
344                                            p_dev_rec->conn_params.min_conn_int,
345                                            p_dev_rec->conn_params.max_conn_int,
346                                            p_dev_rec->conn_params.slave_latency,
347                                            p_dev_rec->conn_params.supervision_tout,
348                                            0, 0);
349     }
350
351     /* Tell BTM Acl management about the link */
352     btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
353
354     p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
355
356     btm_ble_set_conn_st(BLE_CONN_IDLE);
357
358 #if BLE_PRIVACY_SPT == TRUE
359     btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, TRUE);
360 #endif
361 }
362
363
364 /*******************************************************************************
365 **
366 ** Function         l2cble_advertiser_conn_comp
367 **
368 ** Description      This function is called when an HCI Connection Complete
369 **                  event is received while we are an advertiser (so we are slave).
370 **
371 ** Returns          void
372 **
373 *******************************************************************************/
374 void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
375                                   UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
376 {
377     tL2C_LCB            *p_lcb;
378     tBTM_SEC_DEV_REC    *p_dev_rec;
379     UNUSED(type);
380     UNUSED(conn_interval);
381     UNUSED(conn_latency);
382     UNUSED(conn_timeout);
383
384     /* See if we have a link control block for the remote device */
385     p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
386
387     /* If we don't have one, create one and accept the connection. */
388     if (!p_lcb) {
389         p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
390         if (!p_lcb) {
391 #if (SMP_INCLUDED == TRUE)
392             btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
393 #endif  ///SMP_INCLUDED == TRUE
394             L2CAP_TRACE_ERROR ("l2cble_advertiser_conn_comp - failed to allocate LCB");
395             return;
396         } else {
397             if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) {
398 #if (SMP_INCLUDED == TRUE)
399                 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
400 #endif  ///SMP_INCLUDED == TRUE
401                 L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB");
402                 return ;
403             }
404         }
405     }
406
407     /* Save the handle */
408     p_lcb->handle = handle;
409
410     /* Connected OK. Change state to connected, we were advertising, so we are slave */
411     p_lcb->link_role  = HCI_ROLE_SLAVE;
412     p_lcb->transport  = BT_TRANSPORT_LE;
413
414     /* update link parameter, set slave link as non-spec default upon link up */
415     p_lcb->waiting_update_conn_min_interval = p_lcb->waiting_update_conn_max_interval = p_lcb->current_used_conn_interval = conn_interval;
416     p_lcb->waiting_update_conn_timeout      =  p_lcb->current_used_conn_timeout = conn_timeout;
417     p_lcb->waiting_update_conn_latency      =  p_lcb->current_used_conn_latency = conn_latency;
418     p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM;
419     p_lcb->updating_param_flag = false;
420
421     /* Tell BTM Acl management about the link */
422     p_dev_rec = btm_find_or_alloc_dev (bda);
423
424     btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
425
426 #if BLE_PRIVACY_SPT == TRUE
427     btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, TRUE);
428 #endif
429
430     p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
431
432     if (!HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(controller_get_interface()->get_features_ble()->as_array)) {
433         p_lcb->link_state = LST_CONNECTED;
434         l2cu_process_fixed_chnl_resp (p_lcb);
435     }
436
437     /* when adv and initiating are both active, cancel the direct connection */
438     if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0) {
439         L2CA_CancelBleConnectReq(bda);
440     }
441 }
442
443 /*******************************************************************************
444 **
445 ** Function         l2cble_conn_comp
446 **
447 ** Description      This function is called when an HCI Connection Complete
448 **                  event is received.
449 **
450 ** Returns          void
451 **
452 *******************************************************************************/
453 void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type,
454                       UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
455 {
456     btm_ble_update_link_topology_mask(role, TRUE);
457
458     if (role == HCI_ROLE_MASTER) {
459         l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
460     } else {
461         l2cble_advertiser_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
462     }
463 }
464
465 /*******************************************************************************
466 **
467 **  Function        l2cble_start_conn_update
468 **
469 **  Description     start BLE connection parameter update process based on status
470 **
471 **  Parameters:     lcb : l2cap link control block
472 **
473 **  Return value:   true if successfully sending the request to peer device, else false.
474 **
475 *******************************************************************************/
476 static BOOLEAN l2cble_start_conn_update (tL2C_LCB *p_lcb)
477 {
478     UINT16 min_conn_int, max_conn_int, slave_latency, supervision_tout;
479 #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) && (BLE_SLAVE_UPD_CONN_PARAMS == TRUE)
480     tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
481 #endif    /* defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) && (BLE_SLAVE_UPD_CONN_PARAMS == TRUE */
482
483     if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) {
484         L2CAP_TRACE_WARNING("%s, the last connection update command still pending.", __func__);
485         p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PARAM_FULL;
486         return FALSE;
487     }
488
489     if (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) {
490         /* application requests to disable parameters update.
491            If parameters are already updated, lets set them
492            up to what has been requested during connection establishement */
493         if (p_lcb->conn_update_mask & L2C_BLE_NOT_DEFAULT_PARAM &&
494                 /* current connection interval is greater than default min */
495                 p_lcb->current_used_conn_interval > BTM_BLE_CONN_INT_MAX_DEF) {
496             /* use 6 * 1.25 = 7.5 ms as fast connection parameter, 0 slave latency */
497             min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN;
498             slave_latency = BTM_BLE_CONN_SLAVE_LATENCY_DEF;
499             supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF;
500
501             /* if both side 4.1, or we are master device, send HCI command */
502             if (p_lcb->link_role == HCI_ROLE_MASTER
503 #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) && (BLE_SLAVE_UPD_CONN_PARAMS == TRUE)
504                     || (HCI_LE_CONN_PARAM_REQ_SUPPORTED(controller_get_interface()->get_features_ble()->as_array) &&
505                         HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features))
506 #endif
507                ) {
508                 btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, min_conn_int, max_conn_int,
509                                                   slave_latency, supervision_tout, 0, 0);
510             } else {
511                 l2cu_send_peer_ble_par_req (p_lcb, min_conn_int, max_conn_int, slave_latency, supervision_tout);
512             }
513
514             //cache save
515             p_lcb->updating_conn_min_interval = min_conn_int;
516             p_lcb->updating_conn_max_interval = max_conn_int;
517             p_lcb->updating_param_flag = true;
518
519             p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
520             p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM;
521             p_lcb->conn_update_mask |=  L2C_BLE_NEW_CONN_PARAM;
522             return TRUE;
523         }else {
524             return FALSE;
525         }
526     } else {
527         /* application allows to do update, if we were delaying one do it now */
528         if (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM) {
529             /* if both side 4.1, or we are master device, send HCI command */
530             if (p_lcb->link_role == HCI_ROLE_MASTER
531 #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) && (BLE_SLAVE_UPD_CONN_PARAMS == TRUE)
532                     || (HCI_LE_CONN_PARAM_REQ_SUPPORTED(controller_get_interface()->get_features_ble()->as_array) &&
533                         HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features))
534 #endif
535                ) {
536                 btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->waiting_update_conn_min_interval,
537                                                   p_lcb->waiting_update_conn_max_interval, p_lcb->waiting_update_conn_latency, p_lcb->waiting_update_conn_timeout, 0, 0);
538             } else {
539                 l2cu_send_peer_ble_par_req (p_lcb, p_lcb->waiting_update_conn_min_interval, p_lcb->waiting_update_conn_max_interval,
540                                             p_lcb->waiting_update_conn_latency, p_lcb->waiting_update_conn_timeout);
541             }
542
543             //cache save
544             p_lcb->updating_conn_min_interval = p_lcb->waiting_update_conn_min_interval;
545             p_lcb->updating_conn_max_interval = p_lcb->waiting_update_conn_max_interval;
546             p_lcb->updating_param_flag = true;
547
548             p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
549             p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM;
550             p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM;
551             return TRUE;
552         } else {
553             return FALSE;
554         }
555     }
556 }
557
558 /*******************************************************************************
559 **
560 ** Function         l2cble_process_conn_update_evt
561 **
562 ** Description      This function enables the connection update request from remote
563 **                  after a successful connection update response is received.
564 **
565 ** Returns          void
566 **
567 *******************************************************************************/
568 void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_interval,
569                                                        UINT16 conn_latency, UINT16 conn_timeout)
570 {
571     tL2C_LCB *p_lcb;
572
573     /* See if we have a link control block for the remote device */
574     p_lcb = l2cu_find_lcb_by_handle(handle);
575     if (!p_lcb) {
576         L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Invalid handle: %d", handle);
577         return;
578     }
579     if (status == HCI_SUCCESS){
580         p_lcb->current_used_conn_interval = conn_interval;
581         p_lcb->current_used_conn_latency = conn_latency;
582         p_lcb->current_used_conn_timeout = conn_timeout;
583     }else{
584         L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Error status: %d", status);
585     }
586
587     p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
588     p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL;
589
590     btu_stop_timer(&p_lcb->upda_con_timer);
591
592     if (conn_param_update_cb.update_conn_param_cb != NULL) {
593         l2c_send_update_conn_params_cb(p_lcb, status);
594     }
595
596     if (l2cble_start_conn_update(p_lcb) == TRUE) {
597         UINT32 time = CalConnectParamTimeout(p_lcb);
598         btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time);
599     }
600
601     btu_stop_timer (&p_lcb->timer_entry);
602
603     L2CAP_TRACE_DEBUG("l2cble_process_conn_update_evt: conn_update_mask=%d", p_lcb->conn_update_mask);
604 }
605
606 /*******************************************************************************
607 **
608 ** Function         l2cble_get_conn_param_format_err_from_contoller
609 **
610 ** Description      This function is called when host get illegal connection paramrters
611 **                  format status from controller
612 **
613 ** Returns          void
614 **
615 *******************************************************************************/
616 void l2cble_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handle)
617 {
618     tL2C_LCB *p_lcb;
619
620     /* See if we have a link control block for the remote device */
621     p_lcb = l2cu_find_lcb_by_handle(handle);
622     if (!p_lcb) {
623         L2CAP_TRACE_ERROR("%s: Invalid handle: %d", __FUNCTION__, handle);
624         return;
625     }
626
627     p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
628
629     btu_stop_timer (&p_lcb->upda_con_timer);
630
631     if (conn_param_update_cb.update_conn_param_cb != NULL) {
632         l2c_send_update_conn_params_cb(p_lcb, status);
633     }
634     if ((p_lcb->conn_update_mask & L2C_BLE_UPDATE_PARAM_FULL) != 0){
635         p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL;
636         if (l2cble_start_conn_update(p_lcb) == TRUE) {
637             UINT32 time = CalConnectParamTimeout(p_lcb);
638             btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time);
639         }
640     }
641
642 }
643
644 /*******************************************************************************
645 **
646 ** Function         l2cble_process_sig_cmd
647 **
648 ** Description      This function is called when a signalling packet is received
649 **                  on the BLE signalling CID
650 **
651 ** Returns          void
652 **
653 *******************************************************************************/
654 void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
655 {
656     UINT8           *p_pkt_end;
657     UINT8           cmd_code, id;
658     UINT16          cmd_len;
659     UINT16          min_interval, max_interval, latency, timeout;
660
661     p_pkt_end = p + pkt_len;
662
663     STREAM_TO_UINT8  (cmd_code, p);
664     STREAM_TO_UINT8  (id, p);
665     STREAM_TO_UINT16 (cmd_len, p);
666
667     /* Check command length does not exceed packet length */
668     if ((p + cmd_len) > p_pkt_end) {
669         L2CAP_TRACE_WARNING ("L2CAP - LE - format error, pkt_len: %d  cmd_len: %d  code: %d", pkt_len, cmd_len, cmd_code);
670         return;
671     }
672
673     switch (cmd_code) {
674     case L2CAP_CMD_REJECT:
675     case L2CAP_CMD_ECHO_RSP:
676     case L2CAP_CMD_INFO_RSP:
677         p += 2;
678         break;
679     case L2CAP_CMD_ECHO_REQ:
680     case L2CAP_CMD_INFO_REQ:
681         l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
682         break;
683
684     case L2CAP_CMD_BLE_UPDATE_REQ:
685         STREAM_TO_UINT16 (min_interval, p); /* 0x0006 - 0x0C80 */
686         STREAM_TO_UINT16 (max_interval, p); /* 0x0006 - 0x0C80 */
687         STREAM_TO_UINT16 (latency, p);  /* 0x0000 - 0x03E8 */
688         STREAM_TO_UINT16 (timeout, p);  /* 0x000A - 0x0C80 */
689         /* If we are a master, the slave wants to update the parameters */
690         if (p_lcb->link_role == HCI_ROLE_MASTER) {
691             if (min_interval < BTM_BLE_CONN_INT_MIN || min_interval > BTM_BLE_CONN_INT_MAX ||
692                     max_interval < BTM_BLE_CONN_INT_MIN || max_interval > BTM_BLE_CONN_INT_MAX ||
693                     latency  > BTM_BLE_CONN_LATENCY_MAX ||
694                     timeout < BTM_BLE_CONN_SUP_TOUT_MIN || timeout > BTM_BLE_CONN_SUP_TOUT_MAX ||
695                     /* The supervision_timeout parameter defines the link supervision timeout for the connection.
696                        The supervision_timeout in milliseconds shall be large than (1 + latency) * max_interval * 2,
697                        where max_interval is given in milliseconds. (See [Vol 6] Part B, Section 4.5.2).
698                        supervision_timeout (mult of 10ms); conn_interval (mult of 1.25ms)
699                        (max_interval * 1.25 * 2) replaced by ((max_interval * 5) >> 1).
700                     */
701                     ((timeout * 10) < ((1 + latency) *((max_interval * 5) >> 1))) ||
702                     max_interval < min_interval) {
703                 l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_UNACCEPTABLE_PARAMS, id);
704
705                 L2CAP_TRACE_ERROR("slave connection parameters update failed, the parameters are out of range");
706
707             } else {
708
709                 l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id);
710                 p_lcb->waiting_update_conn_min_interval = min_interval;
711                 p_lcb->waiting_update_conn_max_interval = max_interval;
712                 p_lcb->waiting_update_conn_latency = latency;
713                 p_lcb->waiting_update_conn_timeout = timeout;
714                 p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
715
716                 if (l2cble_start_conn_update(p_lcb) == TRUE) {
717                     UINT32 time = CalConnectParamTimeout(p_lcb);
718                     btu_start_timer(&p_lcb->upda_con_timer, BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS, time);
719                 }
720             }
721         } else {
722             l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
723         }
724         break;
725
726     case L2CAP_CMD_BLE_UPDATE_RSP: {
727         UINT16 result = 0;
728         STREAM_TO_UINT16(result, p); //result = 0 connection param accepted, result = 1 connection param rejected.
729         UINT8 status = (result == 0) ? HCI_SUCCESS : HCI_ERR_PARAM_OUT_OF_RANGE;
730         if (status != HCI_SUCCESS) {
731             btu_stop_timer(&p_lcb->upda_con_timer);
732             p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
733             p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL;
734             l2c_send_update_conn_params_cb(p_lcb, status);
735         }
736         break;
737     }
738     default:
739         L2CAP_TRACE_WARNING ("L2CAP - LE - unknown cmd code: %d", cmd_code);
740         l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
741         return;
742     }
743 }
744
745 /*******************************************************************************
746 **
747 ** Function         l2cble_init_direct_conn
748 **
749 ** Description      This function is to initate a direct connection
750 **
751 ** Returns          TRUE connection initiated, FALSE otherwise.
752 **
753 *******************************************************************************/
754 BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
755 {
756 #if ( (defined BLE_PRIVACY_SPT) && (BLE_PRIVACY_SPT == TRUE))
757     //check for security device information in the cache
758     bool dev_rec_exist = true;
759     tBTM_SEC_DEV_REC *find_dev_rec = btm_find_dev (p_lcb->remote_bd_addr);
760     if(find_dev_rec == NULL) {
761         dev_rec_exist = false;
762     }
763
764 #endif
765     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
766     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
767     UINT16 scan_int;
768     UINT16 scan_win;
769     BD_ADDR peer_addr;
770     UINT8 peer_addr_type = BLE_ADDR_PUBLIC;
771     UINT8 own_addr_type = BLE_ADDR_PUBLIC;
772
773     /* There can be only one BLE connection request outstanding at a time */
774     if (p_dev_rec == NULL) {
775         L2CAP_TRACE_WARNING ("unknown device, can not initate connection");
776         return (FALSE);
777     }
778
779     scan_int = (p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int;
780     scan_win = (p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win;
781
782     peer_addr_type = p_lcb->ble_addr_type;
783     memcpy(peer_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
784
785 #if ( (defined BLE_PRIVACY_SPT) && (BLE_PRIVACY_SPT == TRUE))
786     own_addr_type = btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type;
787     if(dev_rec_exist) {
788         // if the current address information is valid, get the real address information
789         if(p_dev_rec->ble.current_addr_valid) {
790             peer_addr_type = p_dev_rec->ble.current_addr_type;
791             memcpy(peer_addr, p_dev_rec->ble.current_addr, 6);
792         } else {
793             /* find security device information but not find the real address information
794              * This state may be directly open without scanning. In this case, you must
795              * use the current adv address of the device to open*/
796         }
797     } else {
798         //not find security device information, We think this is a new device, connect directly
799     }
800
801     /* It will cause that scanner doesn't send scan request to advertiser
802     * which has sent IRK to us and we have stored the IRK in controller.
803     * It is a hardware limitation. The preliminary solution is not to
804     * send key to the controller, but to resolve the random address in host.
805     * so we need send the real address information to controller. */
806     /*
807     if (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) {
808         if (btm_cb.ble_ctr_cb.privacy_mode >=  BTM_PRIVACY_1_2) {
809             own_addr_type |= BLE_ADDR_TYPE_ID_BIT;
810         }
811
812         btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
813         btm_random_pseudo_to_identity_addr(peer_addr, &peer_addr_type);
814     } else {
815         btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, TRUE);
816     }
817     */
818 #endif
819
820     if (!btm_ble_topology_check(BTM_BLE_STATE_INIT)) {
821         l2cu_release_lcb (p_lcb);
822         L2CAP_TRACE_ERROR("initate direct connection fail, topology limitation");
823         return FALSE;
824     }
825
826     if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int      */
827                                         scan_win, /* UINT16 scan_win      */
828                                         FALSE,                   /* UINT8 white_list     */
829                                         peer_addr_type,          /* UINT8 addr_type_peer */
830                                         peer_addr,               /* BD_ADDR bda_peer     */
831                                         own_addr_type,         /* UINT8 addr_type_own  */
832                                         (UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
833                                                 p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),  /* UINT16 conn_int_min  */
834                                         (UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
835                                                 p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),  /* UINT16 conn_int_max  */
836                                         (UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
837                                                 p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), /* UINT16 conn_latency  */
838                                         (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
839                                                 p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), /* conn_timeout */
840                                         0,                       /* UINT16 min_len       */
841                                         0)) {                    /* UINT16 max_len       */
842         l2cu_release_lcb (p_lcb);
843         L2CAP_TRACE_ERROR("initate direct connection fail, no resources");
844         return (FALSE);
845     } else {
846         p_lcb->link_state = LST_CONNECTING;
847         l2cb.is_ble_connecting = TRUE;
848         memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN);
849         btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_BLE_LINK_CONNECT_TOUT);
850         btm_ble_set_conn_st (BLE_DIR_CONN);
851
852         return (TRUE);
853     }
854 }
855
856 /*******************************************************************************
857 **
858 ** Function         l2cble_create_conn
859 **
860 ** Description      This function initiates an acl connection via HCI
861 **
862 ** Returns          TRUE if successful, FALSE if connection not started.
863 **
864 *******************************************************************************/
865 BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb)
866 {
867     tBTM_BLE_CONN_ST     conn_st = btm_ble_get_conn_st();
868     BOOLEAN         rt = FALSE;
869
870     /* There can be only one BLE connection request outstanding at a time */
871     if (conn_st == BLE_CONN_IDLE) {
872         rt = l2cble_init_direct_conn(p_lcb);
873     } else {
874         L2CAP_TRACE_WARNING ("L2CAP - LE - cannot start new connection at conn st: %d", conn_st);
875
876         btm_ble_enqueue_direct_conn_req(p_lcb);
877
878         if (conn_st == BLE_BG_CONN) {
879             btm_ble_suspend_bg_conn();
880         }
881
882         rt = TRUE;
883     }
884     return rt;
885 }
886
887 /*******************************************************************************
888 **
889 ** Function         l2c_link_processs_ble_num_bufs
890 **
891 ** Description      This function is called when a "controller buffer size"
892 **                  event is first received from the controller. It updates
893 **                  the L2CAP values.
894 **
895 ** Returns          void
896 **
897 *******************************************************************************/
898 void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs)
899 {
900     if (num_lm_ble_bufs == 0) {
901         num_lm_ble_bufs = L2C_DEF_NUM_BLE_BUF_SHARED;
902         l2cb.num_lm_acl_bufs -= L2C_DEF_NUM_BLE_BUF_SHARED;
903     }
904     L2CAP_TRACE_DEBUG("num_lm_ble_bufs = %d",num_lm_ble_bufs);
905     l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs;
906 }
907
908 /*******************************************************************************
909 **
910 ** Function         l2c_ble_link_adjust_allocation
911 **
912 ** Description      This function is called when a link is created or removed
913 **                  to calculate the amount of packets each link may send to
914 **                  the HCI without an ack coming back.
915 **
916 **                  Currently, this is a simple allocation, dividing the
917 **                  number of Controller Packets by the number of links. In
918 **                  the future, QOS configuration should be examined.
919 **
920 ** Returns          void
921 **
922 *******************************************************************************/
923 void l2c_ble_link_adjust_allocation (void)
924 {
925     UINT16      qq, yy, qq_remainder;
926     tL2C_LCB    *p_lcb;
927     UINT16      hi_quota, low_quota;
928     UINT16      num_lowpri_links = 0;
929     UINT16      num_hipri_links  = 0;
930     UINT16      controller_xmit_quota = l2cb.num_lm_ble_bufs;
931     UINT16      high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
932
933     /* If no links active, reset buffer quotas and controller buffers */
934     if (l2cb.num_ble_links_active == 0) {
935         l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
936         l2cb.ble_round_robin_quota = l2cb.ble_round_robin_unacked = 0;
937         return;
938     }
939
940     /* First, count the links */
941     for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
942         if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) {
943             if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) {
944                 num_hipri_links++;
945             } else {
946                 num_lowpri_links++;
947             }
948         }
949     }
950
951     /* now adjust high priority link quota */
952     low_quota = num_lowpri_links ? 1 : 0;
953     while ( (num_hipri_links * high_pri_link_quota + low_quota) > controller_xmit_quota ) {
954         high_pri_link_quota--;
955     }
956
957
958     /* Work out the xmit quota and buffer quota high and low priorities */
959     hi_quota  = num_hipri_links * high_pri_link_quota;
960     low_quota = (hi_quota < controller_xmit_quota) ? controller_xmit_quota - hi_quota : 1;
961
962     /* Work out and save the HCI xmit quota for each low priority link */
963
964     /* If each low priority link cannot have at least one buffer */
965     if (num_lowpri_links > low_quota) {
966         l2cb.ble_round_robin_quota = low_quota;
967         qq = qq_remainder = 0;
968     }
969     /* If each low priority link can have at least one buffer */
970     else if (num_lowpri_links > 0) {
971         l2cb.ble_round_robin_quota = 0;
972         l2cb.ble_round_robin_unacked = 0;
973         qq = low_quota / num_lowpri_links;
974         qq_remainder = low_quota % num_lowpri_links;
975     }
976     /* If no low priority link */
977     else {
978         l2cb.ble_round_robin_quota = 0;
979         l2cb.ble_round_robin_unacked = 0;
980         qq = qq_remainder = 0;
981     }
982     L2CAP_TRACE_EVENT ("l2c_ble_link_adjust_allocation  num_hipri: %u  num_lowpri: %u  low_quota: %u  round_robin_quota: %u  qq: %u",
983                        num_hipri_links, num_lowpri_links, low_quota,
984                        l2cb.ble_round_robin_quota, qq);
985
986     /* Now, assign the quotas to each link */
987     for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
988         if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) {
989             if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) {
990                 p_lcb->link_xmit_quota   = high_pri_link_quota;
991             } else {
992                 /* Safety check in case we switched to round-robin with something outstanding */
993                 /* if sent_not_acked is added into round_robin_unacked then don't add it again */
994                 /* l2cap keeps updating sent_not_acked for exiting from round robin */
995                 if (( p_lcb->link_xmit_quota > 0 ) && ( qq == 0 )) {
996                     l2cb.ble_round_robin_unacked += p_lcb->sent_not_acked;
997                 }
998
999                 p_lcb->link_xmit_quota   = qq;
1000                 if (qq_remainder > 0) {
1001                     p_lcb->link_xmit_quota++;
1002                     qq_remainder--;
1003                 }
1004             }
1005
1006             L2CAP_TRACE_EVENT("l2c_ble_link_adjust_allocation LCB %d   Priority: %d  XmitQuota: %d",
1007                               yy, p_lcb->acl_priority, p_lcb->link_xmit_quota);
1008
1009             L2CAP_TRACE_EVENT("        SentNotAcked: %d  RRUnacked: %d",
1010                               p_lcb->sent_not_acked, l2cb.round_robin_unacked);
1011
1012             /* There is a special case where we have readjusted the link quotas and  */
1013             /* this link may have sent anything but some other link sent packets so  */
1014             /* so we may need a timer to kick off this link's transmissions.         */
1015             if ( (p_lcb->link_state == LST_CONNECTED)
1016                     && (!list_is_empty(p_lcb->link_xmit_data_q))
1017                     && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota) ) {
1018                 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_FLOW_CONTROL_TOUT);
1019             }
1020         }
1021     }
1022 }
1023
1024 #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
1025 /*******************************************************************************
1026 **
1027 ** Function         l2cble_process_rc_param_request_evt
1028 **
1029 ** Description      process LE Remote Connection Parameter Request Event.
1030 **
1031 ** Returns          void
1032 **
1033 *******************************************************************************/
1034 void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max,
1035         UINT16 latency, UINT16 timeout)
1036 {
1037     tL2C_LCB    *p_lcb = l2cu_find_lcb_by_handle (handle);
1038
1039     if (p_lcb != NULL) {
1040
1041         /* if update is enabled, always accept connection parameter update */
1042         if ((p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0) {
1043             p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
1044             btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0);
1045         }else {
1046             /* always accept connection parameters request which is sent by itself */
1047             if (int_max == BTM_BLE_CONN_INT_MIN) {
1048                 p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
1049                 btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0);
1050             }else {
1051                 L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled");
1052                 p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
1053                 btsnd_hcic_ble_rc_param_req_neg_reply (handle, HCI_ERR_UNACCEPT_CONN_INTERVAL);
1054             }
1055         }
1056
1057     } else {
1058         L2CAP_TRACE_WARNING("No link to update connection parameter")
1059     }
1060 }
1061 #endif
1062
1063 /*******************************************************************************
1064 **
1065 ** Function         l2cble_update_data_length
1066 **
1067 ** Description      This function update link tx data length if applicable
1068 **
1069 ** Returns          void
1070 **
1071 *******************************************************************************/
1072 void l2cble_update_data_length(tL2C_LCB *p_lcb)
1073 {
1074     UINT16 tx_mtu = 0;
1075     UINT16 i = 0;
1076
1077     L2CAP_TRACE_DEBUG("%s", __FUNCTION__);
1078
1079     /* See if we have a link control block for the connection */
1080     if (p_lcb == NULL) {
1081         return;
1082     }
1083
1084     for (i = 0; i < L2CAP_NUM_FIXED_CHNLS; i++) {
1085         if (i + L2CAP_FIRST_FIXED_CHNL != L2CAP_BLE_SIGNALLING_CID) {
1086             if ((p_lcb->p_fixed_ccbs[i] != NULL) &&
1087                     (tx_mtu < (p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD))) {
1088                 tx_mtu = p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD;
1089             }
1090         }
1091     }
1092
1093     if (tx_mtu > BTM_BLE_DATA_SIZE_MAX) {
1094         tx_mtu = BTM_BLE_DATA_SIZE_MAX;
1095     }
1096
1097     /* update TX data length if changed */
1098     if (p_lcb->tx_data_len != tx_mtu) {
1099         BTM_SetBleDataLength(p_lcb->remote_bd_addr, tx_mtu);
1100     }
1101
1102 }
1103
1104 /*******************************************************************************
1105 **
1106 ** Function         l2cble_process_data_length_change_evt
1107 **
1108 ** Description      This function process the data length change event
1109 **
1110 ** Returns          void
1111 **
1112 *******************************************************************************/
1113 void l2cble_process_data_length_change_event(UINT16 handle, UINT16 tx_data_len, UINT16 rx_data_len)
1114 {
1115     tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
1116
1117     L2CAP_TRACE_DEBUG("%s TX data len = %d", __FUNCTION__, tx_data_len);
1118     if (p_lcb == NULL) {
1119         return;
1120     }
1121
1122     if (tx_data_len > 0) {
1123         p_lcb->tx_data_len = tx_data_len;
1124     }
1125
1126     tACL_CONN *p_acl = btm_handle_to_acl(handle);
1127     if (p_acl != NULL && p_acl->p_set_pkt_data_cback){
1128        tBTM_LE_SET_PKT_DATA_LENGTH_PARAMS data_length_params;
1129        data_length_params.rx_len = tx_data_len;
1130        data_length_params.tx_len = rx_data_len;
1131        p_acl->data_length_params = data_length_params;
1132        (*p_acl->p_set_pkt_data_cback)(BTM_SUCCESS, &data_length_params);
1133     }
1134 }
1135
1136 /*******************************************************************************
1137 **
1138 ** Function         l2cble_set_fixed_channel_tx_data_length
1139 **
1140 ** Description      This function update max fixed channel tx data length if applicable
1141 **
1142 ** Returns          void
1143 **
1144 *******************************************************************************/
1145 void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 fix_cid, UINT16 tx_mtu)
1146 {
1147     tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(remote_bda, BT_TRANSPORT_LE);
1148     UINT16 cid = fix_cid - L2CAP_FIRST_FIXED_CHNL;
1149
1150     L2CAP_TRACE_DEBUG("%s TX MTU = %d", __FUNCTION__, tx_mtu);
1151
1152     if (!controller_get_interface()->supports_ble_packet_extension()) {
1153         L2CAP_TRACE_WARNING("%s, request not supported", __FUNCTION__);
1154         return;
1155     }
1156
1157     /* See if we have a link control block for the connection */
1158     if (p_lcb == NULL) {
1159         return;
1160     }
1161
1162     if (p_lcb->p_fixed_ccbs[cid] != NULL) {
1163         if (tx_mtu > BTM_BLE_DATA_SIZE_MAX) {
1164             tx_mtu = BTM_BLE_DATA_SIZE_MAX;
1165         }
1166
1167         p_lcb->p_fixed_ccbs[cid]->tx_data_len = tx_mtu;
1168     }
1169
1170     l2cble_update_data_length(p_lcb);
1171 }
1172
1173
1174 /*******************************************************************************
1175 **
1176 ** Function         l2c_send_update_conn_params_cb
1177 **
1178 ** Description      This function send the update connection parameter callback to the uplayer.
1179 **
1180 ** Returns          void
1181 **
1182 *******************************************************************************/
1183 void l2c_send_update_conn_params_cb(tL2C_LCB *p_lcb, UINT8 status)
1184 {
1185     if(conn_param_update_cb.update_conn_param_cb != NULL){
1186         tBTM_LE_UPDATE_CONN_PRAMS update_param;
1187         //if myself update the connection parameters
1188         if (p_lcb->updating_param_flag){
1189             update_param.max_conn_int = p_lcb->updating_conn_max_interval;
1190             update_param.min_conn_int = p_lcb->updating_conn_min_interval;
1191             p_lcb->updating_param_flag = false;
1192         }else{
1193             // remote device update the connection parameters
1194             update_param.max_conn_int = update_param.min_conn_int = 0;
1195         }
1196         // current connection parameters
1197         update_param.conn_int = p_lcb->current_used_conn_interval;
1198         update_param.slave_latency = p_lcb->current_used_conn_latency;
1199         update_param.supervision_tout = p_lcb->current_used_conn_timeout;
1200
1201         (conn_param_update_cb.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param);
1202     }
1203 }
1204
1205 /*******************************************************************************
1206 **
1207 ** Function         CalConnectParamTimeout
1208 **
1209 ** Description      This function is called to calculate the connection parameter timeout.
1210 **
1211 ** Returns          timeout
1212 **
1213 *******************************************************************************/
1214 UINT32 CalConnectParamTimeout(tL2C_LCB *p_lcb)
1215 {
1216     UINT32 timeout = 6;
1217     if (p_lcb != NULL){
1218         //1.25 * conn_int *(1+ latency) *32
1219         timeout = (40 * ( 1 + p_lcb->current_used_conn_latency) * p_lcb->current_used_conn_interval + 500) / 1000;
1220         if (timeout < 1){
1221             timeout = 1;
1222         }else if (timeout > 120){
1223             timeout = 120;
1224         }
1225     }
1226     return timeout;
1227 }
1228
1229 /*******************************************************************************
1230 **
1231 ** Function         l2cble_credit_based_conn_req
1232 **
1233 ** Description      This function sends LE Credit Based Connection Request for
1234 **                  LE connection oriented channels.
1235 **
1236 ** Returns          void
1237 **
1238 *******************************************************************************/
1239 void l2cble_credit_based_conn_req (tL2C_CCB *p_ccb)
1240 {
1241     if (!p_ccb) {
1242         return;
1243     }
1244
1245     if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE)
1246     {
1247         L2CAP_TRACE_WARNING ("LE link doesn't exist");
1248         return;
1249     }
1250
1251     l2cu_send_peer_ble_credit_based_conn_req (p_ccb);
1252     return;
1253 }
1254
1255 /*******************************************************************************
1256 **
1257 ** Function         l2cble_credit_based_conn_res
1258 **
1259 ** Description      This function sends LE Credit Based Connection Response for
1260 **                  LE connection oriented channels.
1261 **
1262 ** Returns          void
1263 **
1264 *******************************************************************************/
1265 void l2cble_credit_based_conn_res (tL2C_CCB *p_ccb, UINT16 result)
1266 {
1267     if (!p_ccb) {
1268         return;
1269     }
1270
1271     if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE)
1272     {
1273         L2CAP_TRACE_WARNING ("LE link doesn't exist");
1274         return;
1275     }
1276
1277     l2cu_send_peer_ble_credit_based_conn_res (p_ccb, result);
1278     return;
1279 }
1280
1281 /*******************************************************************************
1282 **
1283 ** Function         l2cble_send_flow_control_credit
1284 **
1285 ** Description      This function sends flow control credits for
1286 **                  LE connection oriented channels.
1287 **
1288 ** Returns          void
1289 **
1290 *******************************************************************************/
1291 void l2cble_send_flow_control_credit(tL2C_CCB *p_ccb, UINT16 credit_value)
1292 {
1293     if (!p_ccb) {
1294         return;
1295     }
1296
1297     if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE)
1298     {
1299         L2CAP_TRACE_WARNING ("LE link doesn't exist");
1300         return;
1301     }
1302
1303     l2cu_send_peer_ble_flow_control_credit(p_ccb, credit_value);
1304     return;
1305
1306 }
1307
1308 /*******************************************************************************
1309 **
1310 ** Function         l2cble_send_peer_disc_req
1311 **
1312 ** Description      This function sends disconnect request
1313 **                  to the peer LE device
1314 **
1315 ** Returns          void
1316 **
1317 *******************************************************************************/
1318 void l2cble_send_peer_disc_req(tL2C_CCB *p_ccb)
1319 {
1320     L2CAP_TRACE_DEBUG ("%s",__func__);
1321     if (!p_ccb) {
1322         return;
1323     }
1324
1325     if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE)
1326     {
1327         L2CAP_TRACE_WARNING ("LE link doesn't exist");
1328         return;
1329     }
1330
1331     l2cu_send_peer_ble_credit_based_disconn_req(p_ccb);
1332     return;
1333 }
1334
1335 #if (SMP_INCLUDED == TRUE)
1336 /*******************************************************************************
1337 **
1338 ** Function         l2cble_sec_comp
1339 **
1340 ** Description      This function is called when security procedure for an LE COC
1341 **                  link is done
1342 **
1343 ** Returns          void
1344 **
1345 *******************************************************************************/
1346 void  l2cble_sec_comp(BD_ADDR p_bda, tBT_TRANSPORT transport, void *p_ref_data, UINT8 status)
1347 {
1348     tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(p_bda, BT_TRANSPORT_LE);
1349     tL2CAP_SEC_DATA *p_buf = NULL;
1350     UINT8 sec_flag;
1351     UINT8 sec_act;
1352
1353     if (!p_lcb)
1354     {
1355         L2CAP_TRACE_WARNING ("%s security complete for unknown device", __func__);
1356         return;
1357     }
1358
1359     sec_act = p_lcb->sec_act;
1360     p_lcb->sec_act = 0;
1361
1362     if (!fixed_queue_is_empty(p_lcb->le_sec_pending_q))
1363     {
1364         p_buf = (tL2CAP_SEC_DATA*) fixed_queue_dequeue(p_lcb->le_sec_pending_q, FIXED_QUEUE_MAX_TIMEOUT);
1365         if (!p_buf)
1366         {
1367             L2CAP_TRACE_WARNING ("%s Security complete for request not initiated from L2CAP",
1368                     __func__);
1369             return;
1370         }
1371
1372         if (status != BTM_SUCCESS)
1373         {
1374             (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1375         }
1376         else
1377         {
1378             if (sec_act == BTM_SEC_ENCRYPT_MITM)
1379             {
1380                 BTM_GetSecurityFlagsByTransport(p_bda, &sec_flag, transport);
1381                 if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) {
1382                     (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1383                 }
1384                 else
1385                 {
1386                     L2CAP_TRACE_DEBUG ("%s MITM Protection Not present", __func__);
1387                     (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data,
1388                             BTM_FAILED_ON_SECURITY);
1389                 }
1390             }
1391             else
1392             {
1393                 L2CAP_TRACE_DEBUG ("%s MITM Protection not required sec_act = %d",
1394                         __func__, p_lcb->sec_act);
1395
1396                 (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1397             }
1398         }
1399     }
1400     else
1401     {
1402         L2CAP_TRACE_WARNING ("%s Security complete for request not initiated from L2CAP", __func__);
1403         return;
1404     }
1405     osi_free(p_buf);
1406
1407     while (!fixed_queue_is_empty(p_lcb->le_sec_pending_q))
1408     {
1409         p_buf = (tL2CAP_SEC_DATA*) fixed_queue_dequeue(p_lcb->le_sec_pending_q, FIXED_QUEUE_MAX_TIMEOUT);
1410
1411         if (status != BTM_SUCCESS) {
1412             (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
1413         } else {
1414             l2ble_sec_access_req(p_bda, p_buf->psm, p_buf->is_originator,
1415                     p_buf->p_callback, p_buf->p_ref_data);
1416         }
1417
1418        osi_free(p_buf);
1419     }
1420 }
1421
1422 /*******************************************************************************
1423 **
1424 ** Function         l2ble_sec_access_req
1425 **
1426 ** Description      This function is called by LE COC link to meet the
1427 **                  security requirement for the link
1428 **
1429 ** Returns          TRUE - security procedures are started
1430 **                  FALSE - failure
1431 **
1432 *******************************************************************************/
1433 BOOLEAN l2ble_sec_access_req(BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_originator, tL2CAP_SEC_CBACK *p_callback, void *p_ref_data)
1434 {
1435     L2CAP_TRACE_DEBUG ("%s", __func__);
1436     BOOLEAN status;
1437     tL2C_LCB *p_lcb = NULL;
1438
1439     if (!p_callback)
1440     {
1441         L2CAP_TRACE_ERROR("%s No callback function", __func__);
1442         return FALSE;
1443     }
1444
1445     p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
1446
1447     if (!p_lcb)
1448     {
1449         L2CAP_TRACE_ERROR ("%s Security check for unknown device", __func__);
1450         p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_UNKNOWN_ADDR);
1451         return FALSE;
1452     }
1453
1454     tL2CAP_SEC_DATA *p_buf = (tL2CAP_SEC_DATA*) osi_malloc((UINT16)sizeof(tL2CAP_SEC_DATA));
1455     if (!p_buf)
1456     {
1457         p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_NO_RESOURCES);
1458         return FALSE;
1459     }
1460
1461     p_buf->psm = psm;
1462     p_buf->is_originator = is_originator;
1463     p_buf->p_callback = p_callback;
1464     p_buf->p_ref_data = p_ref_data;
1465     fixed_queue_enqueue(p_lcb->le_sec_pending_q, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
1466     status = btm_ble_start_sec_check(bd_addr, psm, is_originator, &l2cble_sec_comp, p_ref_data);
1467
1468     return status;
1469 }
1470 #endif /* #if (SMP_INCLUDED == TRUE) */
1471 #endif /* (BLE_INCLUDED == TRUE) */
1472 /*******************************************************************************
1473 **
1474 ** Function         L2CA_GetDisconnectReason
1475 **
1476 ** Description      This function returns the disconnect reason code.
1477 **
1478 ** Returns          disconnect reason
1479 **
1480 *******************************************************************************/
1481 UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport)
1482 {
1483     tL2C_LCB            *p_lcb;
1484     UINT16              reason = 0;
1485
1486     if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda, transport)) != NULL) {
1487         reason = p_lcb->disc_reason;
1488     }
1489
1490     L2CAP_TRACE_DEBUG ("L2CA_GetDisconnectReason=%d ", reason);
1491
1492     return reason;
1493 }