OSDN Git Service

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