1/******************************************************************************
2 *
3 *  Copyright (C) 2009-2013 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#include "bt_target.h"
21#include "btu.h"
22#include "gap_int.h"
23#include "l2cdefs.h"
24#include "l2c_int.h"
25#include <string.h>
26#if GAP_CONN_INCLUDED == TRUE
27#include "btm_int.h"
28
29/********************************************************************************/
30/*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
31/********************************************************************************/
32static void gap_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id);
33static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result);
34static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
35static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
36static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed);
37static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg);
38static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested);
39
40static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid);
41static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle);
42static tGAP_CCB *gap_allocate_ccb (void);
43static void      gap_release_ccb (tGAP_CCB *p_ccb);
44
45/*******************************************************************************
46**
47** Function         gap_conn_init
48**
49** Description      This function is called to initialize GAP connection management
50**
51** Returns          void
52**
53*******************************************************************************/
54void gap_conn_init (void)
55{
56#if AMP_INCLUDED == TRUE
57    gap_cb.conn.reg_info.pAMP_ConnectInd_Cb         = gap_connect_ind;
58    gap_cb.conn.reg_info.pAMP_ConnectCfm_Cb         = gap_connect_cfm;
59    gap_cb.conn.reg_info.pAMP_ConnectPnd_Cb         = NULL;
60    gap_cb.conn.reg_info.pAMP_ConfigInd_Cb          = gap_config_ind;
61    gap_cb.conn.reg_info.pAMP_ConfigCfm_Cb          = gap_config_cfm;
62    gap_cb.conn.reg_info.pAMP_DisconnectInd_Cb      = gap_disconnect_ind;
63    gap_cb.conn.reg_info.pAMP_DisconnectCfm_Cb      = NULL;
64    gap_cb.conn.reg_info.pAMP_QoSViolationInd_Cb    = NULL;
65    gap_cb.conn.reg_info.pAMP_DataInd_Cb            = gap_data_ind;
66    gap_cb.conn.reg_info.pAMP_CongestionStatus_Cb   = gap_congestion_ind;
67    gap_cb.conn.reg_info.pAMP_TxComplete_Cb         = NULL;
68    gap_cb.conn.reg_info.pAMP_MoveInd_Cb            = NULL;
69    gap_cb.conn.reg_info.pAMP_MoveRsp_Cb            = NULL;
70    gap_cb.conn.reg_info.pAMP_MoveCfm_Cb            = NULL; //gap_move_cfm
71    gap_cb.conn.reg_info.pAMP_MoveCfmRsp_Cb         = NULL; //gap_move_cfm_rsp
72
73#else
74    gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb       = gap_connect_ind;
75    gap_cb.conn.reg_info.pL2CA_ConnectCfm_Cb       = gap_connect_cfm;
76    gap_cb.conn.reg_info.pL2CA_ConnectPnd_Cb       = NULL;
77    gap_cb.conn.reg_info.pL2CA_ConfigInd_Cb        = gap_config_ind;
78    gap_cb.conn.reg_info.pL2CA_ConfigCfm_Cb        = gap_config_cfm;
79    gap_cb.conn.reg_info.pL2CA_DisconnectInd_Cb    = gap_disconnect_ind;
80    gap_cb.conn.reg_info.pL2CA_DisconnectCfm_Cb    = NULL;
81    gap_cb.conn.reg_info.pL2CA_QoSViolationInd_Cb  = NULL;
82    gap_cb.conn.reg_info.pL2CA_DataInd_Cb          = gap_data_ind;
83    gap_cb.conn.reg_info.pL2CA_CongestionStatus_Cb = gap_congestion_ind;
84    gap_cb.conn.reg_info.pL2CA_TxComplete_Cb       = NULL;
85#endif
86}
87
88
89/*******************************************************************************
90**
91** Function         GAP_ConnOpen
92**
93** Description      This function is called to open an L2CAP connection.
94**
95** Parameters:      is_server   - If TRUE, the connection is not created
96**                                but put into a "listen" mode waiting for
97**                                the remote side to connect.
98**
99**                  service_id  - Unique service ID from
100**                                BTM_SEC_SERVICE_FIRST_EMPTY (6)
101**                                to BTM_SEC_MAX_SERVICE_RECORDS (32)
102**
103**                  p_rem_bda   - Pointer to remote BD Address.
104**                                If a server, and we don't care about the
105**                                remote BD Address, then NULL should be passed.
106**
107**                  psm         - the PSM used for the connection
108**
109**                  p_config    - Optional pointer to configuration structure.
110**                                If NULL, the default GAP configuration will
111**                                be used.
112**
113**                  security    - security flags
114**                  chan_mode_mask - (GAP_FCR_CHAN_OPT_BASIC, GAP_FCR_CHAN_OPT_ERTM, GAP_FCR_CHAN_OPT_STREAM)
115**
116**                  p_cb        - Pointer to callback function for events.
117**
118** Returns          handle of the connection if successful, else GAP_INVALID_HANDLE
119**
120*******************************************************************************/
121UINT16 GAP_ConnOpen (char *p_serv_name, UINT8 service_id, BOOLEAN is_server,
122                     BD_ADDR p_rem_bda, UINT16 psm, tL2CAP_CFG_INFO *p_cfg,
123                     UINT16 security, UINT8 chan_mode_mask, tGAP_CONN_CALLBACK *p_cb)
124{
125    tGAP_CCB    *p_ccb;
126    UINT16       cid;
127    tBT_UUID    bt_uuid = {2, {GAP_PROTOCOL_ID}};
128
129    GAP_TRACE_EVENT0 ("GAP_CONN - Open Request");
130
131    /* Allocate a new CCB. Return if none available. */
132    if ((p_ccb = gap_allocate_ccb()) == NULL)
133        return (GAP_INVALID_HANDLE);
134
135    /* If caller specified a BD address, save it */
136    if (p_rem_bda)
137    {
138        /* the bd addr is not BT_BD_ANY, then a bd address was specified */
139        if (memcmp (p_rem_bda, BT_BD_ANY, BD_ADDR_LEN))
140            p_ccb->rem_addr_specified = TRUE;
141
142        memcpy (&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN);
143    }
144    else if (!is_server)
145    {
146        /* remore addr is not specified and is not a server -> bad */
147        return (GAP_INVALID_HANDLE);
148    }
149
150    /* A client MUST have specified a bd addr to connect with */
151    if (!p_ccb->rem_addr_specified && !is_server)
152    {
153        gap_release_ccb (p_ccb);
154        GAP_TRACE_ERROR0 ("GAP ERROR: Client must specify a remote BD ADDR to connect to!");
155        return (GAP_INVALID_HANDLE);
156    }
157
158    /* Check if configuration was specified */
159    if (p_cfg)
160        p_ccb->cfg = *p_cfg;
161
162    p_ccb->p_callback     = p_cb;
163
164    /* If originator, use a dynamic PSM */
165#if AMP_INCLUDED == TRUE
166    if (!is_server)
167        gap_cb.conn.reg_info.pAMP_ConnectInd_Cb  = NULL;
168    else
169        gap_cb.conn.reg_info.pAMP_ConnectInd_Cb  = gap_connect_ind;
170#else
171    if (!is_server)
172        gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = NULL;
173    else
174        gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = gap_connect_ind;
175#endif
176
177    /* Register the PSM with L2CAP */
178    if ((p_ccb->psm = L2CA_REGISTER (psm, &gap_cb.conn.reg_info, AMP_AUTOSWITCH_ALLOWED|AMP_USE_AMP_IF_POSSIBLE)) == 0)
179    {
180        GAP_TRACE_ERROR1 ("GAP_ConnOpen: Failure registering PSM 0x%04x", psm);
181        gap_release_ccb (p_ccb);
182        return (GAP_INVALID_HANDLE);
183    }
184
185    /* Register with Security Manager for the specific security level */
186    p_ccb->service_id = service_id;
187    if (!BTM_SetSecurityLevel ((UINT8)!is_server, p_serv_name, p_ccb->service_id, security, p_ccb->psm, 0, 0))
188    {
189        GAP_TRACE_ERROR0 ("GAP_CONN - Security Error");
190        gap_release_ccb (p_ccb);
191        return (GAP_INVALID_HANDLE);
192    }
193
194    /* Fill in eL2CAP parameter data */
195    if( p_ccb->cfg.fcr_present )
196    {
197        p_ccb->ertm_info.preferred_mode = p_ccb->cfg.fcr.mode;
198        p_ccb->ertm_info.user_rx_pool_id = GAP_DATA_POOL_ID;
199        p_ccb->ertm_info.user_tx_pool_id = GAP_DATA_POOL_ID;
200        p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID;
201        p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID;
202    }
203
204    /* optional FCR channel modes */
205    p_ccb->ertm_info.allowed_modes = (chan_mode_mask) ? chan_mode_mask : (UINT8)L2CAP_FCR_CHAN_OPT_BASIC;
206
207    if (is_server)
208    {
209        p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE; /* assume btm/l2cap would handle it */
210        p_ccb->con_state = GAP_CCB_STATE_LISTENING;
211        return (p_ccb->gap_handle);
212    }
213    else
214    {
215        /* We are the originator of this connection */
216        p_ccb->con_flags = GAP_CCB_FLAGS_IS_ORIG;
217
218        /* Transition to the next appropriate state, waiting for connection confirm. */
219        p_ccb->con_state = GAP_CCB_STATE_CONN_SETUP;
220
221        /* mark security done flag, when security is not required */
222        if ((security & (BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT) ) == 0)
223            p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
224
225        /* Check if L2CAP started the connection process */
226        if (p_rem_bda && ((cid = L2CA_CONNECT_REQ (p_ccb->psm, p_rem_bda, &p_ccb->ertm_info, &bt_uuid)) != 0))
227        {
228            p_ccb->connection_id = cid;
229            return (p_ccb->gap_handle);
230        }
231        else
232        {
233            gap_release_ccb (p_ccb);
234            return (GAP_INVALID_HANDLE);
235        }
236    }
237}
238
239
240/*******************************************************************************
241**
242** Function         GAP_ConnClose
243**
244** Description      This function is called to close a connection.
245**
246** Parameters:      handle      - Handle of the connection returned by GAP_ConnOpen
247**
248** Returns          BT_PASS             - closed OK
249**                  GAP_ERR_BAD_HANDLE  - invalid handle
250**
251*******************************************************************************/
252UINT16 GAP_ConnClose (UINT16 gap_handle)
253{
254    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
255
256    GAP_TRACE_EVENT1 ("GAP_CONN - close  handle: 0x%x", gap_handle);
257
258    if (p_ccb)
259    {
260        /* Check if we have a connection ID */
261        if (p_ccb->con_state != GAP_CCB_STATE_LISTENING)
262            L2CA_DISCONNECT_REQ (p_ccb->connection_id);
263
264        gap_release_ccb (p_ccb);
265
266        return (BT_PASS);
267    }
268
269    return (GAP_ERR_BAD_HANDLE);
270}
271
272
273
274/*******************************************************************************
275**
276** Function         GAP_ConnReadData
277**
278** Description      Normally not GKI aware application will call this function
279**                  after receiving GAP_EVT_RXDATA event.
280**
281** Parameters:      handle      - Handle of the connection returned in the Open
282**                  p_data      - Data area
283**                  max_len     - Byte count requested
284**                  p_len       - Byte count received
285**
286** Returns          BT_PASS             - data read
287**                  GAP_ERR_BAD_HANDLE  - invalid handle
288**                  GAP_NO_DATA_AVAIL   - no data available
289**
290*******************************************************************************/
291UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
292{
293    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
294    BT_HDR     *p_buf;
295    UINT16      copy_len;
296
297    if (!p_ccb)
298        return (GAP_ERR_BAD_HANDLE);
299
300    *p_len = 0;
301
302    p_buf = (BT_HDR *)GKI_getfirst (&p_ccb->rx_queue);
303    if (!p_buf)
304        return (GAP_NO_DATA_AVAIL);
305
306    GKI_disable();
307
308    while (max_len && p_buf)
309    {
310        copy_len = (p_buf->len > max_len)?max_len:p_buf->len;
311        max_len -= copy_len;
312        *p_len  += copy_len;
313        if (p_data)
314        {
315            memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, copy_len);
316            p_data += copy_len;
317        }
318
319        if (p_buf->len > copy_len)
320        {
321            p_buf->offset += copy_len;
322            p_buf->len    -= copy_len;
323            break;
324        }
325        else
326        {
327            if (max_len)
328            {
329                p_buf = (BT_HDR *)GKI_getnext (p_buf);
330            }
331            GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue));
332        }
333    }
334
335    p_ccb->rx_queue_size -= *p_len;
336
337    GKI_enable();
338
339    GAP_TRACE_EVENT2 ("GAP_ConnReadData - rx_queue_size left=%d, *p_len=%d",
340                                       p_ccb->rx_queue_size, *p_len);
341
342    return (BT_PASS);
343}
344
345/*******************************************************************************
346**
347** Function         GAP_GetRxQueueCnt
348**
349** Description      This function return number of bytes on the rx queue.
350**
351** Parameters:      handle     - Handle returned in the GAP_ConnOpen
352**                  p_rx_queue_count - Pointer to return queue count in.
353**
354**
355*******************************************************************************/
356int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count)
357{
358    tGAP_CCB    *p_ccb;
359    int         rc = BT_PASS;
360
361    /* Check that handle is valid */
362    if (handle < GAP_MAX_CONNECTIONS)
363    {
364        p_ccb = &gap_cb.conn.ccb_pool[handle];
365
366        if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
367        {
368            *p_rx_queue_count = p_ccb->rx_queue_size;
369        }
370        else
371            rc = GAP_INVALID_HANDLE;
372    }
373    else
374        rc = GAP_INVALID_HANDLE;
375
376    GAP_TRACE_EVENT2 ("GAP_GetRxQueueCnt - rc = 0x%04x, rx_queue_count=%d",
377                                       rc , *p_rx_queue_count);
378
379    return (rc);
380}
381
382/*******************************************************************************
383**
384** Function         GAP_ConnBTRead
385**
386** Description      Bluetooth aware applications will call this function after receiving
387**                  GAP_EVT_RXDATA event.
388**
389** Parameters:      handle      - Handle of the connection returned in the Open
390**                  pp_buf      - pointer to address of buffer with data,
391**
392** Returns          BT_PASS             - data read
393**                  GAP_ERR_BAD_HANDLE  - invalid handle
394**                  GAP_NO_DATA_AVAIL   - no data available
395**
396*******************************************************************************/
397UINT16 GAP_ConnBTRead (UINT16 gap_handle, BT_HDR **pp_buf)
398{
399    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
400    BT_HDR      *p_buf;
401
402    if (!p_ccb)
403        return (GAP_ERR_BAD_HANDLE);
404
405    p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->rx_queue);
406
407    if (p_buf)
408    {
409        *pp_buf = p_buf;
410
411        p_ccb->rx_queue_size -= p_buf->len;
412        return (BT_PASS);
413    }
414    else
415    {
416        *pp_buf = NULL;
417        return (GAP_NO_DATA_AVAIL);
418    }
419}
420
421
422/*******************************************************************************
423**
424** Function         GAP_ConnBTWrite
425**
426** Description      Bluetooth Aware applications can call this function to write data.
427**
428** Parameters:      handle      - Handle of the connection returned in the Open
429**                  p_buf      - pointer to address of buffer with data,
430**
431** Returns          BT_PASS                 - data read
432**                  GAP_ERR_BAD_HANDLE      - invalid handle
433**                  GAP_ERR_BAD_STATE       - connection not established
434**                  GAP_INVALID_BUF_OFFSET  - buffer offset is invalid
435*******************************************************************************/
436UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf)
437{
438    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
439
440    if (!p_ccb)
441    {
442        GKI_freebuf (p_buf);
443        return (GAP_ERR_BAD_HANDLE);
444    }
445
446    if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
447    {
448        GKI_freebuf (p_buf);
449        return (GAP_ERR_BAD_STATE);
450    }
451
452    if (p_buf->offset < L2CAP_MIN_OFFSET)
453    {
454        GKI_freebuf (p_buf);
455        return (GAP_ERR_BUF_OFFSET);
456    }
457
458    GKI_enqueue (&p_ccb->tx_queue, p_buf);
459
460    if (p_ccb->is_congested)
461    {
462        return (BT_PASS);
463    }
464
465    /* Send the buffer through L2CAP */
466#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
467    gap_send_event (gap_handle);
468#else
469    while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
470    {
471        UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
472
473        if (status == L2CAP_DW_CONGESTED)
474        {
475            p_ccb->is_congested = TRUE;
476            break;
477        }
478        else if (status != L2CAP_DW_SUCCESS)
479            return (GAP_ERR_BAD_STATE);
480    }
481#endif
482    return (BT_PASS);
483}
484
485
486/*******************************************************************************
487**
488** Function         GAP_ConnWriteData
489**
490** Description      Normally not GKI aware application will call this function
491**                  to send data to the connection.
492**
493** Parameters:      handle      - Handle of the connection returned in the Open
494**                  p_data      - Data area
495**                  max_len     - Byte count requested
496**                  p_len       - Byte count received
497**
498** Returns          BT_PASS                 - data read
499**                  GAP_ERR_BAD_HANDLE      - invalid handle
500**                  GAP_ERR_BAD_STATE       - connection not established
501**                  GAP_CONGESTION          - system is congested
502**
503*******************************************************************************/
504UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
505{
506    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
507    BT_HDR     *p_buf;
508
509    *p_len = 0;
510
511    if (!p_ccb)
512        return (GAP_ERR_BAD_HANDLE);
513
514    if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
515        return (GAP_ERR_BAD_STATE);
516
517    while (max_len)
518    {
519        if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
520        {
521            if ((p_buf = (BT_HDR *)GKI_getpoolbuf (p_ccb->ertm_info.user_tx_pool_id)) == NULL)
522                return (GAP_ERR_CONGESTED);
523        }
524        else
525        {
526            if ((p_buf = (BT_HDR *)GKI_getpoolbuf (GAP_DATA_POOL_ID)) == NULL)
527                return (GAP_ERR_CONGESTED);
528        }
529
530        p_buf->offset = L2CAP_MIN_OFFSET;
531        p_buf->len = (p_ccb->rem_mtu_size < max_len) ? p_ccb->rem_mtu_size : max_len;
532        p_buf->event = BT_EVT_TO_BTU_SP_DATA;
533
534        memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);
535
536        *p_len  += p_buf->len;
537        max_len -= p_buf->len;
538        p_data  += p_buf->len;
539
540        GAP_TRACE_EVENT1 ("GAP_WriteData %d bytes", p_buf->len);
541
542        GKI_enqueue (&p_ccb->tx_queue, p_buf);
543    }
544
545    if (p_ccb->is_congested)
546    {
547        return (BT_PASS);
548    }
549
550    /* Send the buffer through L2CAP */
551#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
552    gap_send_event (gap_handle);
553#else
554    while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
555    {
556        UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
557
558        if (status == L2CAP_DW_CONGESTED)
559        {
560            p_ccb->is_congested = TRUE;
561            break;
562        }
563        else if (status != L2CAP_DW_SUCCESS)
564            return (GAP_ERR_BAD_STATE);
565    }
566#endif
567    return (BT_PASS);
568}
569
570
571/*******************************************************************************
572**
573** Function         GAP_ConnReconfig
574**
575** Description      Applications can call this function to reconfigure the connection.
576**
577** Parameters:      handle      - Handle of the connection
578**                  p_cfg       - Pointer to new configuration
579**
580** Returns          BT_PASS                 - config process started
581**                  GAP_ERR_BAD_HANDLE      - invalid handle
582**
583*******************************************************************************/
584UINT16 GAP_ConnReconfig (UINT16 gap_handle, tL2CAP_CFG_INFO *p_cfg)
585{
586    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
587
588    if (!p_ccb)
589        return (GAP_ERR_BAD_HANDLE);
590
591    p_ccb->cfg = *p_cfg;
592
593    if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
594        L2CA_CONFIG_REQ (p_ccb->connection_id, p_cfg);
595
596    return (BT_PASS);
597}
598
599
600
601/*******************************************************************************
602**
603** Function         GAP_ConnSetIdleTimeout
604**
605** Description      Higher layers call this function to set the idle timeout for
606**                  a connection, or for all future connections. The "idle timeout"
607**                  is the amount of time that a connection can remain up with
608**                  no L2CAP channels on it. A timeout of zero means that the
609**                  connection will be torn down immediately when the last channel
610**                  is removed. A timeout of 0xFFFF means no timeout. Values are
611**                  in seconds.
612**
613** Parameters:      handle      - Handle of the connection
614**                  timeout     - in secs
615**                                0 = immediate disconnect when last channel is removed
616**                                0xFFFF = no idle timeout
617**
618** Returns          BT_PASS                 - config process started
619**                  GAP_ERR_BAD_HANDLE      - invalid handle
620**
621*******************************************************************************/
622UINT16 GAP_ConnSetIdleTimeout (UINT16 gap_handle, UINT16 timeout)
623{
624    tGAP_CCB    *p_ccb;
625
626    if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
627        return (GAP_ERR_BAD_HANDLE);
628
629    if (L2CA_SetIdleTimeout (p_ccb->connection_id, timeout, FALSE))
630        return (BT_PASS);
631    else
632        return (GAP_ERR_BAD_HANDLE);
633}
634
635
636
637/*******************************************************************************
638**
639** Function         GAP_ConnGetRemoteAddr
640**
641** Description      This function is called to get the remote BD address
642**                  of a connection.
643**
644** Parameters:      handle      - Handle of the connection returned by GAP_ConnOpen
645**
646** Returns          BT_PASS             - closed OK
647**                  GAP_ERR_BAD_HANDLE  - invalid handle
648**
649*******************************************************************************/
650UINT8 *GAP_ConnGetRemoteAddr (UINT16 gap_handle)
651{
652    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
653
654    GAP_TRACE_EVENT1 ("GAP_ConnGetRemoteAddr gap_handle = %d", gap_handle);
655
656    if ((p_ccb) && (p_ccb->con_state > GAP_CCB_STATE_LISTENING))
657    {
658        GAP_TRACE_EVENT6("GAP_ConnGetRemoteAddr bda :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", \
659                         p_ccb->rem_dev_address[0],p_ccb->rem_dev_address[1],p_ccb->rem_dev_address[2],
660                         p_ccb->rem_dev_address[3],p_ccb->rem_dev_address[4],p_ccb->rem_dev_address[5]);
661        return (p_ccb->rem_dev_address);
662    }
663    else
664    {
665        GAP_TRACE_EVENT0 ("GAP_ConnGetRemoteAddr return Error ");
666        return (NULL);
667    }
668}
669
670
671/*******************************************************************************
672**
673** Function         GAP_ConnGetRemMtuSize
674**
675** Description      Returns the remote device's MTU size
676**
677** Parameters:      handle      - Handle of the connection
678**
679** Returns          UINT16      - maximum size buffer that can be transmitted to the peer
680**
681*******************************************************************************/
682UINT16 GAP_ConnGetRemMtuSize (UINT16 gap_handle)
683{
684    tGAP_CCB    *p_ccb;
685
686    if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
687        return (0);
688
689    return (p_ccb->rem_mtu_size);
690}
691
692/*******************************************************************************
693**
694** Function         GAP_ConnGetL2CAPCid
695**
696** Description      Returns the L2CAP channel id
697**
698** Parameters:      handle      - Handle of the connection
699**
700** Returns          UINT16      - The L2CAP channel id
701**                  0, if error
702**
703*******************************************************************************/
704UINT16 GAP_ConnGetL2CAPCid (UINT16 gap_handle)
705{
706    tGAP_CCB    *p_ccb;
707
708    if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
709        return (0);
710
711    return (p_ccb->connection_id);
712}
713
714
715/*******************************************************************************
716**
717** Function         gap_connect_ind
718**
719** Description      This function handles an inbound connection indication
720**                  from L2CAP. This is the case where we are acting as a
721**                  server.
722**
723** Returns          void
724**
725*******************************************************************************/
726static void gap_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id)
727{
728    UINT16       xx;
729    tGAP_CCB     *p_ccb;
730    tBT_UUID    bt_uuid = {2, {GAP_PROTOCOL_ID}};
731
732    /* See if we have a CCB listening for the connection */
733    for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
734    {
735        if ((p_ccb->con_state == GAP_CCB_STATE_LISTENING)
736         && (p_ccb->psm == psm)
737         && ((p_ccb->rem_addr_specified == FALSE)
738           || (!memcmp (bd_addr, p_ccb->rem_dev_address, BD_ADDR_LEN))))
739            break;
740    }
741
742    if (xx == GAP_MAX_CONNECTIONS)
743    {
744        GAP_TRACE_WARNING0("*******");
745        GAP_TRACE_WARNING0("WARNING: GAP Conn Indication for Unexpected Bd Addr...Disconnecting");
746        GAP_TRACE_WARNING0("*******");
747
748        /* Disconnect because it is an unexpected connection */
749        L2CA_DISCONNECT_REQ (l2cap_cid);
750        return;
751    }
752
753    /* Transition to the next appropriate state, waiting for config setup. */
754    p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
755
756    /* Save the BD Address and Channel ID. */
757    memcpy (&p_ccb->rem_dev_address[0], bd_addr, BD_ADDR_LEN);
758    p_ccb->connection_id = l2cap_cid;
759
760    /* Send response to the L2CAP layer. */
761    L2CA_CONNECT_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK, &p_ccb->ertm_info, &bt_uuid);
762
763    GAP_TRACE_EVENT1("GAP_CONN - Rcvd L2CAP conn ind, CID: 0x%x", p_ccb->connection_id);
764
765    /* Send a Configuration Request. */
766    L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg);
767}
768
769/*******************************************************************************
770**
771** Function         gap_checks_con_flags
772**
773** Description      This function processes the L2CAP configuration indication
774**                  event.
775**
776** Returns          void
777**
778*******************************************************************************/
779static void gap_checks_con_flags (tGAP_CCB    *p_ccb)
780{
781    GAP_TRACE_EVENT1 ("gap_checks_con_flags conn_flags:0x%x, ", p_ccb->con_flags);
782    /* if all the required con_flags are set, report the OPEN event now */
783    if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE)
784    {
785        p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
786
787        p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
788    }
789}
790
791/*******************************************************************************
792**
793** Function         gap_sec_check_complete
794**
795** Description      The function called when Security Manager finishes
796**                  verification of the service side connection
797**
798** Returns          void
799**
800*******************************************************************************/
801static void gap_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
802{
803    tGAP_CCB *p_ccb = (tGAP_CCB *)p_ref_data;
804
805    GAP_TRACE_EVENT3 ("gap_sec_check_complete conn_state:%d, conn_flags:0x%x, status:%d",
806        p_ccb->con_state, p_ccb->con_flags, res);
807    if (p_ccb->con_state == GAP_CCB_STATE_IDLE)
808        return;
809
810    if (res == BTM_SUCCESS)
811    {
812        p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
813        gap_checks_con_flags (p_ccb);
814    }
815    else
816    {
817        /* security failed - disconnect the channel */
818        L2CA_DISCONNECT_REQ (p_ccb->connection_id);
819    }
820}
821
822/*******************************************************************************
823**
824** Function         gap_connect_cfm
825**
826** Description      This function handles the connect confirm events
827**                  from L2CAP. This is the case when we are acting as a
828**                  client and have sent a connect request.
829**
830** Returns          void
831**
832*******************************************************************************/
833static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result)
834{
835    tGAP_CCB    *p_ccb;
836
837    /* Find CCB based on CID */
838    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
839        return;
840
841    /* initiate security process, if needed */
842    if ( (p_ccb->con_flags & GAP_CCB_FLAGS_SEC_DONE) == 0)
843    {
844        btm_sec_mx_access_request (p_ccb->rem_dev_address, p_ccb->psm, TRUE,
845                                   0, 0, &gap_sec_check_complete, p_ccb);
846    }
847
848    /* If the connection response contains success status, then */
849    /* Transition to the next state and startup the timer.      */
850    if ((result == L2CAP_CONN_OK) && (p_ccb->con_state == GAP_CCB_STATE_CONN_SETUP))
851    {
852        p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
853
854        /* Send a Configuration Request. */
855        L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg);
856    }
857    else
858    {
859        /* Tell the user if he has a callback */
860        if (p_ccb->p_callback)
861            (*p_ccb->p_callback) (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
862
863        gap_release_ccb (p_ccb);
864    }
865}
866
867/*******************************************************************************
868**
869** Function         gap_config_ind
870**
871** Description      This function processes the L2CAP configuration indication
872**                  event.
873**
874** Returns          void
875**
876*******************************************************************************/
877static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
878{
879    tGAP_CCB    *p_ccb;
880    UINT16      local_mtu_size;
881
882    /* Find CCB based on CID */
883    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
884        return;
885
886    /* Remember the remote MTU size */
887
888    if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
889    {
890        local_mtu_size = GKI_get_pool_bufsize (p_ccb->ertm_info.user_tx_pool_id)
891                       - sizeof(BT_HDR) - L2CAP_MIN_OFFSET;
892    }
893    else
894        local_mtu_size = L2CAP_MTU_SIZE;
895
896    if ((!p_cfg->mtu_present)||(p_cfg->mtu > local_mtu_size))
897    {
898        p_ccb->rem_mtu_size = local_mtu_size;
899    }
900    else
901        p_ccb->rem_mtu_size = p_cfg->mtu;
902
903    /* For now, always accept configuration from the other side */
904    p_cfg->flush_to_present = FALSE;
905    p_cfg->mtu_present      = FALSE;
906    p_cfg->result           = L2CAP_CFG_OK;
907    p_cfg->fcs_present      = FALSE;
908
909    L2CA_CONFIG_RSP (l2cap_cid, p_cfg);
910
911    p_ccb->con_flags |= GAP_CCB_FLAGS_HIS_CFG_DONE;
912
913    gap_checks_con_flags (p_ccb);
914}
915
916
917/*******************************************************************************
918**
919** Function         gap_config_cfm
920**
921** Description      This function processes the L2CAP configuration confirmation
922**                  event.
923**
924** Returns          void
925**
926*******************************************************************************/
927static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
928{
929    tGAP_CCB    *p_ccb;
930
931    /* Find CCB based on CID */
932    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
933        return;
934
935    if (p_cfg->result == L2CAP_CFG_OK)
936    {
937        p_ccb->con_flags |= GAP_CCB_FLAGS_MY_CFG_DONE;
938
939
940        if (p_ccb->cfg.fcr_present)
941            p_ccb->cfg.fcr.mode = p_cfg->fcr.mode;
942        else
943            p_ccb->cfg.fcr.mode = L2CAP_FCR_BASIC_MODE;
944
945        gap_checks_con_flags (p_ccb);
946    }
947    else
948    {
949        p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
950        gap_release_ccb (p_ccb);
951    }
952}
953
954
955/*******************************************************************************
956**
957** Function         gap_disconnect_ind
958**
959** Description      This function handles a disconnect event from L2CAP. If
960**                  requested to, we ack the disconnect before dropping the CCB
961**
962** Returns          void
963**
964*******************************************************************************/
965static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed)
966{
967    tGAP_CCB    *p_ccb;
968
969    GAP_TRACE_EVENT1 ("GAP_CONN - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid);
970
971    /* Find CCB based on CID */
972    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
973        return;
974
975    if (ack_needed)
976        L2CA_DISCONNECT_RSP (l2cap_cid);
977
978    p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
979    gap_release_ccb (p_ccb);
980}
981
982
983/*******************************************************************************
984**
985** Function         gap_data_ind
986**
987** Description      This function is called when data is received from L2CAP.
988**
989** Returns          void
990**
991*******************************************************************************/
992static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
993{
994    tGAP_CCB    *p_ccb;
995
996    /* Find CCB based on CID */
997    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
998    {
999        GKI_freebuf (p_msg);
1000        return;
1001    }
1002
1003    if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
1004    {
1005        GKI_enqueue (&p_ccb->rx_queue, p_msg);
1006
1007        p_ccb->rx_queue_size += p_msg->len;
1008        /*
1009        GAP_TRACE_EVENT2 ("gap_data_ind - rx_queue_size=%d, msg len=%d",
1010                                       p_ccb->rx_queue_size, p_msg->len);
1011         */
1012
1013        p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL);
1014    }
1015    else
1016    {
1017        GKI_freebuf (p_msg);
1018    }
1019}
1020
1021
1022/*******************************************************************************
1023**
1024** Function         gap_congestion_ind
1025**
1026** Description      This is a callback function called by L2CAP when
1027**                  data L2CAP congestion status changes
1028**
1029*******************************************************************************/
1030static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested)
1031{
1032    tGAP_CCB    *p_ccb;
1033    UINT16       event;
1034    BT_HDR      *p_buf;
1035    UINT8        status;
1036
1037    GAP_TRACE_EVENT2 ("GAP_CONN - Rcvd L2CAP Is Congested (%d), CID: 0x%x",
1038                      is_congested, lcid);
1039
1040    /* Find CCB based on CID */
1041    if ((p_ccb = gap_find_ccb_by_cid (lcid)) == NULL)
1042        return;
1043
1044    p_ccb->is_congested = is_congested;
1045
1046    event = (is_congested) ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED;
1047    p_ccb->p_callback (p_ccb->gap_handle, event);
1048
1049    if (!is_congested)
1050    {
1051        while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
1052        {
1053            status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
1054
1055            if (status == L2CAP_DW_CONGESTED)
1056            {
1057                p_ccb->is_congested = TRUE;
1058                break;
1059            }
1060            else if (status != L2CAP_DW_SUCCESS)
1061                break;
1062        }
1063    }
1064}
1065
1066
1067/*******************************************************************************
1068**
1069** Function         gap_find_ccb_by_cid
1070**
1071** Description      This function searches the CCB table for an entry with the
1072**                  passed CID.
1073**
1074** Returns          the CCB address, or NULL if not found.
1075**
1076*******************************************************************************/
1077static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid)
1078{
1079    UINT16       xx;
1080    tGAP_CCB     *p_ccb;
1081
1082    /* Look through each connection control block */
1083    for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
1084    {
1085        if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->connection_id == cid))
1086            return (p_ccb);
1087    }
1088
1089    /* If here, not found */
1090    return (NULL);
1091}
1092
1093
1094/*******************************************************************************
1095**
1096** Function         gap_find_ccb_by_handle
1097**
1098** Description      This function searches the CCB table for an entry with the
1099**                  passed handle.
1100**
1101** Returns          the CCB address, or NULL if not found.
1102**
1103*******************************************************************************/
1104static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle)
1105{
1106    tGAP_CCB     *p_ccb;
1107
1108    /* Check that handle is valid */
1109    if (handle < GAP_MAX_CONNECTIONS)
1110    {
1111        p_ccb = &gap_cb.conn.ccb_pool[handle];
1112
1113        if (p_ccb->con_state != GAP_CCB_STATE_IDLE)
1114            return (p_ccb);
1115    }
1116
1117    /* If here, handle points to invalid connection */
1118    return (NULL);
1119}
1120
1121
1122/*******************************************************************************
1123**
1124** Function         gap_allocate_ccb
1125**
1126** Description      This function allocates a new CCB.
1127**
1128** Returns          CCB address, or NULL if none available.
1129**
1130*******************************************************************************/
1131static tGAP_CCB *gap_allocate_ccb (void)
1132{
1133    UINT16       xx;
1134    tGAP_CCB     *p_ccb;
1135
1136    /* Look through each connection control block for a free one */
1137    for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
1138    {
1139        if (p_ccb->con_state == GAP_CCB_STATE_IDLE)
1140        {
1141            memset (p_ccb, 0, sizeof (tGAP_CCB));
1142
1143            p_ccb->gap_handle   = xx;
1144            p_ccb->rem_mtu_size = L2CAP_MTU_SIZE;
1145
1146            return (p_ccb);
1147        }
1148    }
1149
1150    /* If here, no free CCB found */
1151    return (NULL);
1152}
1153
1154
1155/*******************************************************************************
1156**
1157** Function         gap_release_ccb
1158**
1159** Description      This function releases a CCB.
1160**
1161** Returns          void
1162**
1163*******************************************************************************/
1164static void gap_release_ccb (tGAP_CCB *p_ccb)
1165{
1166    UINT16       xx;
1167    UINT16      psm = p_ccb->psm;
1168    UINT8       service_id = p_ccb->service_id;
1169
1170    /* Drop any buffers we may be holding */
1171    p_ccb->rx_queue_size = 0;
1172
1173    while (p_ccb->rx_queue.p_first)
1174        GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue));
1175
1176    while (p_ccb->tx_queue.p_first)
1177        GKI_freebuf (GKI_dequeue (&p_ccb->tx_queue));
1178
1179    p_ccb->con_state = GAP_CCB_STATE_IDLE;
1180
1181    /* If no-one else is using the PSM, deregister from L2CAP */
1182    for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
1183    {
1184        if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->psm == psm))
1185            return;
1186    }
1187
1188    /* Free the security record for this PSM */
1189    BTM_SecClrService(service_id);
1190    L2CA_DEREGISTER (psm);
1191}
1192
1193#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
1194
1195/*******************************************************************************
1196**
1197** Function     gap_send_event
1198**
1199** Description  Send BT_EVT_TO_GAP_MSG event to BTU task
1200**
1201** Returns      None
1202**
1203*******************************************************************************/
1204void gap_send_event (UINT16 gap_handle)
1205{
1206    BT_HDR  *p_msg;
1207
1208    if ((p_msg = (BT_HDR*)GKI_getbuf(BT_HDR_SIZE)) != NULL)
1209    {
1210        p_msg->event  = BT_EVT_TO_GAP_MSG;
1211        p_msg->len    = 0;
1212        p_msg->offset = 0;
1213        p_msg->layer_specific = gap_handle;
1214
1215        GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg);
1216    }
1217    else
1218    {
1219        GAP_TRACE_ERROR0("Unable to allocate message buffer for event.");
1220    }
1221}
1222
1223/*******************************************************************************
1224**
1225** Function     gap_proc_btu_event
1226**
1227** Description  Event handler for BT_EVT_TO_GAP_MSG event from BTU task
1228**
1229** Returns      None
1230**
1231*******************************************************************************/
1232void gap_proc_btu_event(BT_HDR *p_msg)
1233{
1234    tGAP_CCB   *p_ccb = gap_find_ccb_by_handle (p_msg->layer_specific);
1235    UINT8       status;
1236    BT_HDR     *p_buf;
1237
1238    if (!p_ccb)
1239    {
1240        return;
1241    }
1242
1243    if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
1244    {
1245        return;
1246    }
1247
1248    if (p_ccb->is_congested)
1249    {
1250        return;
1251    }
1252
1253    /* Send the buffer through L2CAP */
1254
1255    while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
1256    {
1257        status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
1258
1259        if (status == L2CAP_DW_CONGESTED)
1260        {
1261            p_ccb->is_congested = TRUE;
1262            break;
1263        }
1264        else if (status != L2CAP_DW_SUCCESS)
1265            break;
1266    }
1267
1268}
1269#endif /* (GAP_CONN_POST_EVT_INCLUDED == TRUE) */
1270#endif  /* GAP_CONN_INCLUDED */
1271