1/******************************************************************************
2 *
3 *  Copyright (C) 1999-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 the L2CAP UCD code
22 *
23 ******************************************************************************/
24
25#include <stdlib.h>
26#include <string.h>
27#include <stdio.h>
28
29#include "gki.h"
30#include "bt_types.h"
31#include "hcidefs.h"
32#include "hcimsgs.h"
33#include "l2cdefs.h"
34#include "l2c_int.h"
35#include "btu.h"
36#include "btm_api.h"
37#include "btm_int.h"
38
39#if (L2CAP_UCD_INCLUDED == TRUE)
40static BOOLEAN l2c_ucd_connect ( BD_ADDR rem_bda );
41
42/*******************************************************************************
43**
44** Function         l2c_ucd_discover_cback
45**
46** Description      UCD Discover callback
47**
48** Returns          void
49**
50*******************************************************************************/
51static void l2c_ucd_discover_cback (BD_ADDR rem_bda, UINT8 info_type, UINT32 data)
52{
53    tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
54    UINT16      xx;
55
56    L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_discover_cback");
57
58    for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
59    {
60        if (p_rcb->in_use)
61        {
62            /* if this application is waiting UCD reception info */
63            if (( info_type == L2CAP_UCD_INFO_TYPE_RECEPTION )
64                && ( p_rcb->ucd.state & L2C_UCD_STATE_W4_RECEPTION ))
65            {
66                p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (rem_bda, info_type, data);
67                p_rcb->ucd.state &= ~(L2C_UCD_STATE_W4_RECEPTION);
68            }
69
70            /* if this application is waiting UCD MTU info */
71            if (( info_type == L2CAP_UCD_INFO_TYPE_MTU )
72                && ( p_rcb->ucd.state & L2C_UCD_STATE_W4_MTU ))
73            {
74                p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (rem_bda, info_type, data);
75                p_rcb->ucd.state &= ~(L2C_UCD_STATE_W4_MTU);
76            }
77        }
78    }
79}
80
81/*******************************************************************************
82**
83** Function         l2c_ucd_data_ind_cback
84**
85** Description      UCD Data callback
86**
87** Returns          void
88**
89*******************************************************************************/
90static void l2c_ucd_data_ind_cback (BD_ADDR rem_bda, BT_HDR *p_buf)
91{
92    UINT8 *p;
93    UINT16 psm;
94    tL2C_RCB    *p_rcb;
95
96    L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_data_ind_cback");
97
98    p = (UINT8 *)(p_buf + 1) + p_buf->offset;
99    STREAM_TO_UINT16(psm, p)
100
101    p_buf->offset += L2CAP_UCD_OVERHEAD;
102    p_buf->len    -= L2CAP_UCD_OVERHEAD;
103
104    if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL)
105    {
106        L2CAP_TRACE_ERROR ("L2CAP - no RCB for l2c_ucd_data_ind_cback, PSM: 0x%04x", psm);
107        GKI_freebuf (p_buf);
108    }
109    else
110    {
111        p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(rem_bda, p_buf);
112    }
113}
114
115/*******************************************************************************
116**
117** Function         l2c_ucd_congestion_status_cback
118**
119** Description      UCD Congestion Status callback
120**
121** Returns          void
122**
123*******************************************************************************/
124static void l2c_ucd_congestion_status_cback (BD_ADDR rem_bda, BOOLEAN is_congested)
125{
126    tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
127    UINT16      xx;
128
129    L2CAP_TRACE_DEBUG ("L2CAP - l2c_ucd_congestion_status_cback");
130
131    for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
132    {
133        if (( p_rcb->in_use )
134          &&( p_rcb->ucd.state != L2C_UCD_STATE_UNUSED ))
135        {
136            if ( p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
137            {
138                L2CAP_TRACE_DEBUG ("L2CAP - Calling UCDCongestionStatus_Cb (%d), PSM=0x%04x, BDA: %08x%04x,",
139                                    is_congested, p_rcb->psm,
140                                    (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
141                                    (rem_bda[4]<<8)+rem_bda[5]);
142
143                p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb ( rem_bda, is_congested );
144            }
145        }
146    }
147}
148
149/*******************************************************************************
150**
151** Function         l2c_ucd_disconnect_ind_cback
152**
153** Description      UCD disconnect callback (This prevent to access null pointer)
154**
155** Returns          void
156**
157*******************************************************************************/
158static void l2c_ucd_disconnect_ind_cback (UINT16 cid, BOOLEAN result)
159{
160    /* do nothing */
161}
162
163/*******************************************************************************
164**
165** Function         l2c_ucd_config_ind_cback
166**
167** Description      UCD config callback (This prevent to access null pointer)
168**
169** Returns          void
170**
171*******************************************************************************/
172static void l2c_ucd_config_ind_cback (UINT16 cid, tL2CAP_CFG_INFO *p_cfg)
173{
174    /* do nothing */
175}
176
177/*******************************************************************************
178**
179** Function         l2c_ucd_config_cfm_cback
180**
181** Description      UCD config callback (This prevent to access null pointer)
182**
183** Returns          void
184**
185*******************************************************************************/
186static void l2c_ucd_config_cfm_cback (UINT16 cid, tL2CAP_CFG_INFO *p_cfg)
187{
188    /* do nothing */
189}
190
191/*******************************************************************************
192**
193**  Function        L2CA_UcdRegister
194**
195**  Description     Register PSM on UCD.
196**
197**  Parameters:     tL2CAP_UCD_CB_INFO
198**
199**  Return value:   TRUE if successs
200**
201*******************************************************************************/
202BOOLEAN L2CA_UcdRegister ( UINT16 psm, tL2CAP_UCD_CB_INFO *p_cb_info )
203{
204    tL2C_RCB             *p_rcb;
205
206    L2CAP_TRACE_API  ("L2CA_UcdRegister()  PSM: 0x%04x", psm);
207
208    if ((!p_cb_info->pL2CA_UCD_Discover_Cb)
209     || (!p_cb_info->pL2CA_UCD_Data_Cb))
210    {
211        L2CAP_TRACE_ERROR ("L2CAP - no callback registering PSM(0x%04x) on UCD", psm);
212        return (FALSE);
213    }
214
215    if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL)
216    {
217        L2CAP_TRACE_ERROR ("L2CAP - no RCB for L2CA_UcdRegister, PSM: 0x%04x", psm);
218        return (FALSE);
219    }
220
221    p_rcb->ucd.state   = L2C_UCD_STATE_W4_DATA;
222    p_rcb->ucd.cb_info = *p_cb_info;
223
224    /* check if master rcb is created for UCD */
225    if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) == NULL)
226    {
227        if ((p_rcb = l2cu_allocate_rcb (L2C_UCD_RCB_ID)) == NULL)
228        {
229            L2CAP_TRACE_ERROR ("L2CAP - no RCB available for L2CA_UcdRegister");
230            return (FALSE);
231        }
232        else
233        {
234            /* these callback functions will forward data to each UCD application */
235            p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb            = l2c_ucd_discover_cback;
236            p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb                = l2c_ucd_data_ind_cback;
237            p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb   = l2c_ucd_congestion_status_cback;
238
239            memset (&p_rcb->api, 0, sizeof(tL2CAP_APPL_INFO));
240            p_rcb->api.pL2CA_DisconnectInd_Cb        = l2c_ucd_disconnect_ind_cback;
241
242            /* This will make L2CAP check UCD congestion callback */
243            p_rcb->api.pL2CA_CongestionStatus_Cb     = NULL;
244
245            /* do nothing but prevent crash */
246            p_rcb->api.pL2CA_ConfigInd_Cb            = l2c_ucd_config_ind_cback;
247            p_rcb->api.pL2CA_ConfigCfm_Cb            = l2c_ucd_config_cfm_cback;
248        }
249    }
250
251    return (TRUE);
252}
253
254/*******************************************************************************
255**
256**  Function        L2CA_UcdDeregister
257**
258**  Description     Deregister PSM on UCD.
259**
260**  Parameters:     PSM
261**
262**  Return value:   TRUE if successs
263**
264*******************************************************************************/
265BOOLEAN L2CA_UcdDeregister ( UINT16 psm )
266{
267    tL2C_CCB    *p_ccb;
268    tL2C_RCB    *p_rcb;
269    UINT16      xx;
270
271    L2CAP_TRACE_API  ("L2CA_UcdDeregister()  PSM: 0x%04x", psm);
272
273    if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL)
274    {
275        L2CAP_TRACE_ERROR ("L2CAP - no RCB for L2CA_UcdDeregister, PSM: 0x%04x", psm);
276        return (FALSE);
277    }
278
279    p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
280
281    /* check this was the last UCD registration */
282    p_rcb = &l2cb.rcb_pool[0];
283
284    for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
285    {
286        if ((p_rcb->in_use) && (p_rcb->ucd.state != L2C_UCD_STATE_UNUSED))
287            return (TRUE);
288    }
289
290    /* delete master rcb for UCD */
291    if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) != NULL)
292    {
293        l2cu_release_rcb (p_rcb);
294    }
295
296    /* delete CCB for UCD */
297    p_ccb = l2cb.ccb_pool;
298    for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ )
299    {
300        if (( p_ccb->in_use )
301          &&( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID ))
302        {
303            l2cu_release_ccb (p_ccb);
304        }
305        p_ccb++;
306    }
307
308    return (TRUE);
309}
310
311/*******************************************************************************
312**
313**  Function        L2CA_UcdDiscover
314**
315**  Description     Discover UCD of remote device.
316**
317**  Parameters:     PSM
318**                  BD_ADDR of remote device
319**                  info_type : L2CAP_UCD_INFO_TYPE_RECEPTION
320**                              L2CAP_UCD_INFO_TYPE_MTU
321**
322**
323**  Return value:   TRUE if successs
324**
325*******************************************************************************/
326BOOLEAN L2CA_UcdDiscover ( UINT16 psm, BD_ADDR rem_bda, UINT8 info_type )
327{
328    tL2C_LCB        *p_lcb;
329    tL2C_CCB        *p_ccb;
330    tL2C_RCB        *p_rcb;
331
332    L2CAP_TRACE_API ("L2CA_UcdDiscover()  PSM: 0x%04x  BDA: %08x%04x, InfoType=0x%02x", psm,
333                      (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
334                      (rem_bda[4]<<8)+rem_bda[5], info_type);
335
336    /* Fail if the PSM is not registered */
337    if (((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL)
338        ||( p_rcb->ucd.state == L2C_UCD_STATE_UNUSED ))
339    {
340        L2CAP_TRACE_WARNING ("L2CAP - no RCB for L2CA_UcdDiscover, PSM: 0x%04x", psm);
341        return (FALSE);
342    }
343
344    /* First, see if we already have a link to the remote */
345    /* then find the channel control block for UCD. */
346    if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
347      ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
348    {
349        if ( l2c_ucd_connect (rem_bda) == FALSE )
350        {
351            return (FALSE);
352        }
353    }
354
355    /* set waiting flags in rcb */
356
357    if ( info_type & L2CAP_UCD_INFO_TYPE_RECEPTION )
358        p_rcb->ucd.state |= L2C_UCD_STATE_W4_RECEPTION;
359
360    if ( info_type & L2CAP_UCD_INFO_TYPE_MTU )
361        p_rcb->ucd.state |= L2C_UCD_STATE_W4_MTU;
362
363    /* if link is already established */
364    if ((p_lcb)&&(p_lcb->link_state == LST_CONNECTED))
365    {
366        if (!p_ccb)
367        {
368            p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID);
369        }
370        l2c_ucd_check_pending_info_req(p_ccb);
371    }
372    return (TRUE);
373}
374
375/*******************************************************************************
376**
377**  Function        L2CA_UcdDataWrite
378**
379**  Description     Send UCD to remote device
380**
381**  Parameters:     PSM
382**                  BD Address of remote
383**                  Pointer to buffer of type BT_HDR
384**                  flags : L2CAP_FLUSHABLE_CH_BASED
385**                          L2CAP_FLUSHABLE_PKT
386**                          L2CAP_NON_FLUSHABLE_PKT
387**
388** Return value     L2CAP_DW_SUCCESS, if data accepted
389**                  L2CAP_DW_FAILED,  if error
390**
391*******************************************************************************/
392UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 flags)
393{
394    tL2C_LCB        *p_lcb;
395    tL2C_CCB        *p_ccb;
396    tL2C_RCB        *p_rcb;
397    UINT8           *p;
398
399    L2CAP_TRACE_API ("L2CA_UcdDataWrite()  PSM: 0x%04x  BDA: %08x%04x", psm,
400                      (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
401                      (rem_bda[4]<<8)+rem_bda[5]);
402
403    /* Fail if the PSM is not registered */
404    if (((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL)
405        ||( p_rcb->ucd.state == L2C_UCD_STATE_UNUSED ))
406    {
407        L2CAP_TRACE_WARNING ("L2CAP - no RCB for L2CA_UcdDataWrite, PSM: 0x%04x", psm);
408        GKI_freebuf (p_buf);
409        return (L2CAP_DW_FAILED);
410    }
411
412    /* First, see if we already have a link to the remote */
413    /*  then find the channel control block for UCD */
414    if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
415      ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
416    {
417        if ( l2c_ucd_connect (rem_bda) == FALSE )
418        {
419            GKI_freebuf (p_buf);
420            return (L2CAP_DW_FAILED);
421        }
422
423        /* If we still don't have lcb and ccb after connect attempt, then can't proceed */
424        if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
425            || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
426        {
427            GKI_freebuf (p_buf);
428            return (L2CAP_DW_FAILED);
429        }
430    }
431
432    /* write PSM */
433    p_buf->offset -= L2CAP_UCD_OVERHEAD;
434    p_buf->len += L2CAP_UCD_OVERHEAD;
435    p = (UINT8 *)(p_buf + 1) + p_buf->offset;
436
437    UINT16_TO_STREAM (p, psm);
438
439    /* UCD MTU check */
440    if ((p_lcb->ucd_mtu) && (p_buf->len > p_lcb->ucd_mtu))
441    {
442        L2CAP_TRACE_WARNING ("L2CAP - Handle: 0x%04x  UCD bigger than peer's UCD mtu size cannot be sent", p_lcb->handle);
443        GKI_freebuf (p_buf);
444        return (L2CAP_DW_FAILED);
445    }
446
447    /* If already congested, do not accept any more packets */
448    if (p_ccb->cong_sent)
449    {
450        L2CAP_TRACE_ERROR ("L2CAP - Handle: 0x%04x UCD cannot be sent, already congested count: %u  buff_quota: %u",
451                            p_lcb->handle,
452                            (p_ccb->xmit_hold_q.count + p_lcb->ucd_out_sec_pending_q.count),
453                            p_ccb->buff_quota);
454
455        GKI_freebuf (p_buf);
456        return (L2CAP_DW_FAILED);
457    }
458
459    /* channel based, packet based flushable or non-flushable */
460    p_buf->layer_specific = flags;
461
462    l2c_csm_execute (p_ccb, L2CEVT_L2CA_DATA_WRITE, p_buf);
463
464    if (p_ccb->cong_sent)
465        return (L2CAP_DW_CONGESTED);
466    else
467        return (L2CAP_DW_SUCCESS);
468}
469
470/*******************************************************************************
471**
472**  Function        L2CA_UcdSetIdleTimeout
473**
474**  Description     Set UCD Idle timeout.
475**
476**  Parameters:     BD Addr
477**                  Timeout in second
478**
479**  Return value:   TRUE if successs
480**
481*******************************************************************************/
482BOOLEAN L2CA_UcdSetIdleTimeout ( BD_ADDR rem_bda, UINT16 timeout )
483{
484    tL2C_LCB        *p_lcb;
485    tL2C_CCB        *p_ccb;
486
487    L2CAP_TRACE_API ("L2CA_UcdSetIdleTimeout()  Timeout: 0x%04x  BDA: %08x%04x", timeout,
488                      (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
489                      (rem_bda[4]<<8)+rem_bda[5]);
490
491    /* First, see if we already have a link to the remote */
492    /* then find the channel control block. */
493    if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
494      ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
495    {
496        L2CAP_TRACE_WARNING ("L2CAP - no UCD channel");
497        return (FALSE);
498    }
499    else
500    {
501        p_ccb->fixed_chnl_idle_tout = timeout;
502        return (TRUE);
503    }
504}
505
506/*******************************************************************************
507**
508** Function         L2CA_UCDSetTxPriority
509**
510** Description      Sets the transmission priority for a connectionless channel.
511**
512** Returns          TRUE if a valid channel, else FALSE
513**
514*******************************************************************************/
515BOOLEAN L2CA_UCDSetTxPriority ( BD_ADDR rem_bda, tL2CAP_CHNL_PRIORITY priority )
516{
517    tL2C_LCB        *p_lcb;
518    tL2C_CCB        *p_ccb;
519
520    L2CAP_TRACE_API ("L2CA_UCDSetTxPriority()  priority: 0x%02x  BDA: %08x%04x", priority,
521                      (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
522                      (rem_bda[4]<<8)+rem_bda[5]);
523
524    if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
525    {
526        L2CAP_TRACE_WARNING ("L2CAP - no LCB for L2CA_UCDSetTxPriority");
527        return (FALSE);
528    }
529
530    /* Find the channel control block */
531    if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)
532    {
533        L2CAP_TRACE_WARNING ("L2CAP - no CCB for L2CA_UCDSetTxPriority");
534        return (FALSE);
535    }
536
537    /* it will update the order of CCB in LCB by priority and update round robin service variables */
538    l2cu_change_pri_ccb (p_ccb, priority);
539
540    return (TRUE);
541}
542
543/*******************************************************************************
544**
545**  Function        l2c_ucd_connect
546**
547**  Description     Connect UCD to remote device.
548**
549**  Parameters:     BD_ADDR of remote device
550**
551**  Return value:   TRUE if successs
552**
553*******************************************************************************/
554static BOOLEAN l2c_ucd_connect ( BD_ADDR rem_bda )
555{
556    tL2C_LCB        *p_lcb;
557    tL2C_CCB        *p_ccb;
558    tL2C_RCB        *p_rcb;
559
560    L2CAP_TRACE_DEBUG ("l2c_ucd_connect()  BDA: %08x%04x",
561                      (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
562                      (rem_bda[4]<<8)+rem_bda[5]);
563
564    /* Fail if we have not established communications with the controller */
565    if (!BTM_IsDeviceUp())
566    {
567        L2CAP_TRACE_WARNING ("l2c_ucd_connect - BTU not ready");
568        return (FALSE);
569    }
570
571    /* First, see if we already have a link to the remote */
572    if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
573    {
574        /* No link. Get an LCB and start link establishment */
575        if ( ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
576         ||  (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) )
577        {
578            L2CAP_TRACE_WARNING ("L2CAP - conn not started l2c_ucd_connect");
579            return (FALSE);
580        }
581    }
582    else if ( p_lcb->info_rx_bits & (1 << L2CAP_EXTENDED_FEATURES_INFO_TYPE) )
583    {
584        if (!(p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION))
585        {
586            L2CAP_TRACE_WARNING ("L2CAP - UCD is not supported by peer, l2c_ucd_connect");
587            return (FALSE);
588        }
589    }
590
591    /* Find the channel control block. */
592    if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL)
593    {
594        /* Allocate a channel control block */
595        if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL)
596        {
597            L2CAP_TRACE_WARNING ("L2CAP - no CCB for l2c_ucd_connect");
598            return (FALSE);
599        }
600        else
601        {
602            /* Set CID for the connection */
603            p_ccb->local_cid  = L2CAP_CONNECTIONLESS_CID;
604            p_ccb->remote_cid = L2CAP_CONNECTIONLESS_CID;
605
606            /* Set the default idle timeout value to use */
607            p_ccb->fixed_chnl_idle_tout = L2CAP_UCD_IDLE_TIMEOUT;
608
609            /* Set the default channel priority value to use */
610            l2cu_change_pri_ccb (p_ccb, L2CAP_UCD_CH_PRIORITY);
611
612            if ((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) == NULL)
613            {
614                L2CAP_TRACE_WARNING ("L2CAP - no UCD registered, l2c_ucd_connect");
615                return (FALSE);
616            }
617            /* Save UCD registration info */
618            p_ccb->p_rcb = p_rcb;
619
620            /* There is no configuration, so if the link is up, the channel is up */
621            if (p_lcb->link_state == LST_CONNECTED)
622            {
623                p_ccb->chnl_state = CST_OPEN;
624            }
625        }
626    }
627
628    return (TRUE);
629}
630
631/*******************************************************************************
632**
633**  Function        l2c_ucd_delete_sec_pending_q
634**
635** Description      discard all of UCD packets in security pending queue
636**
637** Returns          None
638**
639*******************************************************************************/
640void l2c_ucd_delete_sec_pending_q(tL2C_LCB  *p_lcb)
641{
642    /* clean up any security pending UCD */
643    while (p_lcb->ucd_out_sec_pending_q.p_first)
644        GKI_freebuf (GKI_dequeue (&p_lcb->ucd_out_sec_pending_q));
645
646    while (p_lcb->ucd_in_sec_pending_q.p_first)
647        GKI_freebuf (GKI_dequeue (&p_lcb->ucd_in_sec_pending_q));
648}
649
650/*******************************************************************************
651**
652**  Function        l2c_ucd_check_pending_info_req
653**
654** Description      check if any application is waiting for UCD information
655**
656**  Return          TRUE if any pending UCD info request
657**
658*******************************************************************************/
659BOOLEAN l2c_ucd_check_pending_info_req(tL2C_CCB  *p_ccb)
660{
661    tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
662    UINT16      xx;
663    BOOLEAN     pending = FALSE;
664
665    if (p_ccb == NULL)
666    {
667        L2CAP_TRACE_ERROR ("L2CAP - NULL p_ccb in l2c_ucd_check_pending_info_req");
668        return (FALSE);
669    }
670
671    for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
672    {
673        if (p_rcb->in_use)
674        {
675            /* if application is waiting UCD reception info */
676            if (p_rcb->ucd.state & L2C_UCD_STATE_W4_RECEPTION)
677            {
678                /* if this information is available */
679                if ( p_ccb->p_lcb->info_rx_bits & (1 << L2CAP_EXTENDED_FEATURES_INFO_TYPE) )
680                {
681                    if (!(p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION))
682                    {
683                        L2CAP_TRACE_WARNING ("L2CAP - UCD is not supported by peer, l2c_ucd_check_pending_info_req");
684
685                        l2c_ucd_delete_sec_pending_q(p_ccb->p_lcb);
686                        l2cu_release_ccb (p_ccb);
687                    }
688
689                    p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (p_ccb->p_lcb->remote_bd_addr,
690                                                                     L2CAP_UCD_INFO_TYPE_RECEPTION,
691                                                                     p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_UCD_RECEPTION);
692                }
693                else
694                {
695                    pending = TRUE;
696                    if (p_ccb->p_lcb->w4_info_rsp == FALSE)
697                    {
698                        l2cu_send_peer_info_req (p_ccb->p_lcb, L2CAP_EXTENDED_FEATURES_INFO_TYPE);
699                    }
700                }
701            }
702
703            /* if application is waiting for UCD MTU */
704            if (p_rcb->ucd.state & L2C_UCD_STATE_W4_MTU)
705            {
706                /* if this information is available */
707                if ( p_ccb->p_lcb->info_rx_bits & (1 << L2CAP_CONNLESS_MTU_INFO_TYPE))
708                {
709                    p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Discover_Cb (p_ccb->p_lcb->remote_bd_addr,
710                                                                     L2CAP_UCD_INFO_TYPE_MTU,
711                                                                     p_ccb->p_lcb->ucd_mtu);
712                }
713                else
714                {
715                    pending = TRUE;
716                    if (p_ccb->p_lcb->w4_info_rsp == FALSE)
717                    {
718                        l2cu_send_peer_info_req (p_ccb->p_lcb, L2CAP_CONNLESS_MTU_INFO_TYPE);
719                    }
720                }
721            }
722        }
723    }
724    return (pending);
725}
726
727/*******************************************************************************
728**
729**  Function        l2c_ucd_enqueue_pending_out_sec_q
730**
731**  Description     enqueue outgoing UCD packet into security pending queue
732**                  and check congestion
733**
734**  Return          None
735**
736*******************************************************************************/
737void l2c_ucd_enqueue_pending_out_sec_q(tL2C_CCB  *p_ccb, void *p_data)
738{
739    GKI_enqueue (&p_ccb->p_lcb->ucd_out_sec_pending_q, p_data);
740    l2cu_check_channel_congestion (p_ccb);
741}
742
743/*******************************************************************************
744**
745**  Function        l2c_ucd_check_pending_out_sec_q
746**
747**  Description     check outgoing security
748**
749**  Return          TRUE if any UCD packet for security
750**
751*******************************************************************************/
752BOOLEAN l2c_ucd_check_pending_out_sec_q(tL2C_CCB  *p_ccb)
753{
754    UINT8 *p;
755    UINT16 psm;
756    BT_HDR *p_buf;
757
758    if ( p_ccb->p_lcb->ucd_out_sec_pending_q.count )
759    {
760        p_buf = (BT_HDR*)(p_ccb->p_lcb->ucd_out_sec_pending_q.p_first);
761        p = (UINT8 *)(p_buf + 1) + p_buf->offset;
762        STREAM_TO_UINT16(psm, p)
763
764        p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
765        btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, psm,
766                                  p_ccb->p_lcb->handle, CONNLESS_ORIG, &l2c_link_sec_comp, p_ccb);
767
768        return (TRUE);
769    }
770    return (FALSE);
771}
772
773/*******************************************************************************
774**
775**  Function        l2c_ucd_send_pending_out_sec_q
776**
777**  Description     dequeue UCD packet from security pending queue and
778**                  enqueue it into CCB
779**
780**  Return          None
781**
782*******************************************************************************/
783void l2c_ucd_send_pending_out_sec_q(tL2C_CCB  *p_ccb)
784{
785    BT_HDR *p_buf;
786
787    if ( p_ccb->p_lcb->ucd_out_sec_pending_q.count )
788    {
789        p_buf = (BT_HDR*)GKI_dequeue (&p_ccb->p_lcb->ucd_out_sec_pending_q);
790
791        l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_buf);
792        l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL);
793    }
794}
795
796/*******************************************************************************
797**
798**  Function        l2c_ucd_discard_pending_out_sec_q
799**
800**  Description     dequeue UCD packet from security pending queue and
801**                  discard it.
802**
803**  Return          None
804**
805*******************************************************************************/
806void l2c_ucd_discard_pending_out_sec_q(tL2C_CCB  *p_ccb)
807{
808    BT_HDR *p_buf;
809
810    p_buf = (BT_HDR*)GKI_dequeue (&p_ccb->p_lcb->ucd_out_sec_pending_q);
811
812    /* we may need to report to application */
813
814    if (p_buf)
815    {
816        GKI_freebuf (p_buf);
817    }
818}
819
820/*******************************************************************************
821**
822**  Function        l2c_ucd_check_pending_in_sec_q
823**
824**  Description     check incoming security
825**
826**  Return          TRUE if any UCD packet for security
827**
828*******************************************************************************/
829BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB  *p_ccb)
830{
831    UINT8 *p;
832    UINT16 psm;
833    BT_HDR *p_buf;
834
835    if ( p_ccb->p_lcb->ucd_in_sec_pending_q.count )
836    {
837        p_buf = (BT_HDR*)(p_ccb->p_lcb->ucd_in_sec_pending_q.p_first);
838        p = (UINT8 *)(p_buf + 1) + p_buf->offset;
839        STREAM_TO_UINT16(psm, p)
840
841        p_ccb->chnl_state = CST_TERM_W4_SEC_COMP;
842        btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, psm,
843                                  p_ccb->p_lcb->handle, CONNLESS_TERM, &l2c_link_sec_comp, p_ccb);
844
845        return (TRUE);
846    }
847    return (FALSE);
848}
849
850/*******************************************************************************
851**
852**  Function        l2c_ucd_send_pending_in_sec_q
853**
854**  Description     dequeue UCD packet from security pending queue and
855**                  send it to application
856**
857**  Return          None
858**
859*******************************************************************************/
860void l2c_ucd_send_pending_in_sec_q(tL2C_CCB  *p_ccb)
861{
862    BT_HDR *p_buf;
863
864    if ( p_ccb->p_lcb->ucd_in_sec_pending_q.count )
865    {
866        p_buf = (BT_HDR*)GKI_dequeue (&p_ccb->p_lcb->ucd_in_sec_pending_q);
867
868        p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(p_ccb->p_lcb->remote_bd_addr, (BT_HDR *)p_buf);
869    }
870}
871
872/*******************************************************************************
873**
874**  Function        l2c_ucd_discard_pending_in_sec_q
875**
876**  Description     dequeue UCD packet from security pending queue and
877**                  discard it.
878**
879**  Return          None
880**
881*******************************************************************************/
882void l2c_ucd_discard_pending_in_sec_q(tL2C_CCB  *p_ccb)
883{
884    BT_HDR *p_buf;
885
886    p_buf = (BT_HDR*)GKI_dequeue (&p_ccb->p_lcb->ucd_in_sec_pending_q);
887
888    if (p_buf)
889    {
890        GKI_freebuf (p_buf);
891    }
892}
893
894/*******************************************************************************
895**
896**  Function        l2c_ucd_check_rx_pkts
897**
898**  Description     Check if UCD reception is registered.
899**                  Process received UCD packet if application is expecting.
900**
901**  Return          TRUE if UCD reception is registered
902**
903*******************************************************************************/
904BOOLEAN l2c_ucd_check_rx_pkts(tL2C_LCB  *p_lcb, BT_HDR *p_msg)
905{
906    tL2C_CCB   *p_ccb;
907    tL2C_RCB   *p_rcb;
908
909    if (((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) != NULL)
910      ||((p_rcb = l2cu_find_rcb_by_psm (L2C_UCD_RCB_ID)) != NULL))
911    {
912        if (p_ccb == NULL)
913        {
914            /* Allocate a channel control block */
915            if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL)
916            {
917                L2CAP_TRACE_WARNING ("L2CAP - no CCB for UCD reception");
918                GKI_freebuf (p_msg);
919                return TRUE;
920            }
921            else
922            {
923                /* Set CID for the connection */
924                p_ccb->local_cid  = L2CAP_CONNECTIONLESS_CID;
925                p_ccb->remote_cid = L2CAP_CONNECTIONLESS_CID;
926
927                /* Set the default idle timeout value to use */
928                p_ccb->fixed_chnl_idle_tout = L2CAP_UCD_IDLE_TIMEOUT;
929
930                /* Set the default channel priority value to use */
931                l2cu_change_pri_ccb (p_ccb, L2CAP_UCD_CH_PRIORITY);
932
933                /* Save registration info */
934                p_ccb->p_rcb = p_rcb;
935
936                p_ccb->chnl_state = CST_OPEN;
937            }
938        }
939        l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DATA, p_msg);
940        return TRUE;
941    }
942    else
943        return FALSE;
944}
945
946/*******************************************************************************
947**
948**  Function        l2c_ucd_process_event
949**
950**  Description     This is called from main state machine when LCID is connectionless
951**                  Process the event if it is for UCD.
952**
953**  Return          TRUE if the event is consumed by UCD
954**                  FALSE if the event needs to be processed by main state machine
955**
956*******************************************************************************/
957BOOLEAN l2c_ucd_process_event(tL2C_CCB *p_ccb, UINT16 event, void *p_data)
958{
959    /* if the event is not processed by this function, this variable will be set to FALSE */
960    BOOLEAN done = TRUE;
961
962    switch (p_ccb->chnl_state)
963    {
964    case CST_CLOSED:
965        switch (event)
966        {
967        case L2CEVT_LP_CONNECT_CFM:     /* Link came up         */
968            /* check if waiting for UCD info */
969            if (!l2c_ucd_check_pending_info_req (p_ccb))
970            {
971                /* check if any outgoing UCD packet is waiting security check */
972                if (!l2c_ucd_check_pending_out_sec_q(p_ccb))
973                {
974                    p_ccb->chnl_state = CST_OPEN;
975                }
976            }
977            break;
978
979        case L2CEVT_L2CAP_DATA:         /* Peer data packet rcvd    */
980            GKI_enqueue (&p_ccb->p_lcb->ucd_in_sec_pending_q, p_data);
981            break;
982
983        case L2CEVT_L2CA_DATA_WRITE:    /* Upper layer data to send */
984            l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
985            break;
986
987        case L2CEVT_L2CAP_INFO_RSP:
988            /* check if waiting for UCD info */
989            if (!l2c_ucd_check_pending_info_req (p_ccb))
990            {
991                /* check if any outgoing UCD packet is waiting security check */
992                if (!l2c_ucd_check_pending_out_sec_q(p_ccb))
993                {
994                    p_ccb->chnl_state = CST_OPEN;
995                }
996            }
997            break;
998
999        default:
1000            done = FALSE;   /* main state machine continues to process event */
1001            break;
1002        }
1003        break;
1004
1005    case CST_ORIG_W4_SEC_COMP:
1006        switch (event)
1007        {
1008        case L2CEVT_SEC_RE_SEND_CMD:    /* BTM has enough info to proceed */
1009            /* check if any outgoing UCD packet is waiting security check */
1010            if (!l2c_ucd_check_pending_out_sec_q(p_ccb))
1011            {
1012                p_ccb->chnl_state = CST_OPEN;
1013            }
1014            break;
1015
1016        case L2CEVT_SEC_COMP:           /* Security completed success */
1017            p_ccb->chnl_state = CST_OPEN;
1018            l2c_ucd_send_pending_out_sec_q(p_ccb);
1019
1020            if ( p_ccb->p_lcb->ucd_out_sec_pending_q.count )
1021            {
1022                /* start a timer to send next UCD packet in OPEN state */
1023                /* it will prevent stack overflow */
1024                btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, 0);
1025            }
1026            else
1027            {
1028                /* start a timer for idle timeout of UCD */
1029                btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout);
1030            }
1031            break;
1032
1033        case L2CEVT_SEC_COMP_NEG:
1034            p_ccb->chnl_state = CST_OPEN;
1035            l2c_ucd_discard_pending_out_sec_q(p_ccb);
1036
1037            /* start a timer for idle timeout of UCD */
1038            btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout);
1039            break;
1040
1041        case L2CEVT_L2CA_DATA_WRITE:    /* Upper layer data to send */
1042            l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
1043            break;
1044
1045        case L2CEVT_L2CAP_DATA:         /* Peer data packet rcvd    */
1046            GKI_enqueue (&p_ccb->p_lcb->ucd_in_sec_pending_q, p_data);
1047            break;
1048
1049        case L2CEVT_L2CAP_INFO_RSP:
1050            /* check if waiting for UCD info */
1051            l2c_ucd_check_pending_info_req (p_ccb);
1052            break;
1053
1054        default:
1055            done = FALSE;   /* main state machine continues to process event */
1056            break;
1057        }
1058        break;
1059
1060
1061    case CST_TERM_W4_SEC_COMP:
1062        switch (event)
1063        {
1064        case L2CEVT_SEC_COMP:
1065            p_ccb->chnl_state = CST_OPEN;
1066            l2c_ucd_send_pending_in_sec_q (p_ccb);
1067
1068            if ( p_ccb->p_lcb->ucd_in_sec_pending_q.count )
1069            {
1070                /* start a timer to check next UCD packet in OPEN state */
1071                /* it will prevent stack overflow */
1072                btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, 0);
1073            }
1074            else
1075            {
1076                /* start a timer for idle timeout of UCD */
1077                btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout);
1078            }
1079            break;
1080
1081        case L2CEVT_SEC_COMP_NEG:
1082            if (((tL2C_CONN_INFO *)p_data)->status == BTM_DELAY_CHECK)
1083            {
1084                done = FALSE;
1085                break;
1086            }
1087            p_ccb->chnl_state = CST_OPEN;
1088            l2c_ucd_discard_pending_in_sec_q (p_ccb);
1089
1090            /* start a timer for idle timeout of UCD */
1091            btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, p_ccb->fixed_chnl_idle_tout);
1092            break;
1093
1094        case L2CEVT_L2CA_DATA_WRITE:        /* Upper layer data to send */
1095            l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
1096            break;
1097
1098        case L2CEVT_L2CAP_DATA:             /* Peer data packet rcvd    */
1099            GKI_enqueue (&p_ccb->p_lcb->ucd_in_sec_pending_q, p_data);
1100            break;
1101
1102        case L2CEVT_SEC_RE_SEND_CMD:        /* BTM has enough info to proceed */
1103            /* check if any incoming UCD packet is waiting security check */
1104            if (!l2c_ucd_check_pending_in_sec_q(p_ccb))
1105            {
1106                p_ccb->chnl_state = CST_OPEN;
1107            }
1108            break;
1109
1110        case L2CEVT_L2CAP_INFO_RSP:
1111            /* check if waiting for UCD info */
1112            l2c_ucd_check_pending_info_req (p_ccb);
1113            break;
1114
1115        default:
1116            done = FALSE;   /* main state machine continues to process event */
1117            break;
1118        }
1119        break;
1120
1121    case CST_OPEN:
1122        switch (event)
1123        {
1124        case L2CEVT_L2CAP_DATA:             /* Peer data packet rcvd    */
1125            /* stop idle timer of UCD */
1126            btu_stop_timer (&p_ccb->timer_entry);
1127
1128            GKI_enqueue (&p_ccb->p_lcb->ucd_in_sec_pending_q, p_data);
1129            l2c_ucd_check_pending_in_sec_q (p_ccb);
1130            break;
1131
1132        case L2CEVT_L2CA_DATA_WRITE:        /* Upper layer data to send */
1133            /* stop idle timer of UCD */
1134            btu_stop_timer (&p_ccb->timer_entry);
1135
1136            l2c_ucd_enqueue_pending_out_sec_q(p_ccb, p_data);
1137
1138            /* coverity[check_return] */ /* coverity[unchecked_value] */
1139            /* success changes state, failure stays in current state */
1140            l2c_ucd_check_pending_out_sec_q (p_ccb);
1141            break;
1142
1143        case L2CEVT_TIMEOUT:
1144            /* check if any UCD packet is waiting security check */
1145            if ((!l2c_ucd_check_pending_in_sec_q(p_ccb))
1146              &&(!l2c_ucd_check_pending_out_sec_q(p_ccb)))
1147            {
1148                l2cu_release_ccb (p_ccb);
1149            }
1150            break;
1151
1152        case L2CEVT_L2CAP_INFO_RSP:
1153            /* check if waiting for UCD info */
1154            l2c_ucd_check_pending_info_req (p_ccb);
1155            break;
1156
1157        default:
1158            done = FALSE;   /* main state machine continues to process event */
1159            break;
1160        }
1161        break;
1162
1163    default:
1164        done = FALSE;   /* main state machine continues to process event */
1165        break;
1166    }
1167
1168    return done;
1169}
1170#endif /* (L2CAP_UCD_INCLUDED == TRUE) */
1171