18372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/******************************************************************************
28372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *
38372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *  Copyright (C) 2009-2013 Broadcom Corporation
48372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *
58372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *  Licensed under the Apache License, Version 2.0 (the "License");
68372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *  you may not use this file except in compliance with the License.
78372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *  You may obtain a copy of the License at:
88372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *
98372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *  http://www.apache.org/licenses/LICENSE-2.0
108372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *
118372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *  Unless required by applicable law or agreed to in writing, software
128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *  distributed under the License is distributed on an "AS IS" BASIS,
138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *  See the License for the specific language governing permissions and
158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *  limitations under the License.
168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz *
178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz ******************************************************************************/
188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#include "bt_target.h"
218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#include "bt_utils.h"
228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#include "btu.h"
238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#include "gap_int.h"
248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#include "l2cdefs.h"
258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#include "l2c_int.h"
268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#include <string.h>
271eb1ea0cf2da992a3193506806e571dcbe3ec947Pavlin Radoslavov#include "osi/include/mutex.h"
288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#if GAP_CONN_INCLUDED == TRUE
298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#include "btm_int.h"
308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/********************************************************************************/
328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/********************************************************************************/
348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id);
358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result);
368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed);
398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg);
408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested);
412bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jellastatic void gap_tx_complete_ind (UINT16 l2cap_cid, UINT16 sdu_sent);
428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid);
448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle);
458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic tGAP_CCB *gap_allocate_ccb (void);
468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void      gap_release_ccb (tGAP_CCB *p_ccb);
47ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kocharstatic void      gap_checks_con_flags (tGAP_CCB *p_ccb);
488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_conn_init
528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
538372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function is called to initialize GAP connection management
548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          void
568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzvoid gap_conn_init (void)
598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#if AMP_INCLUDED == TRUE
618372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_ConnectInd_Cb         = gap_connect_ind;
628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_ConnectCfm_Cb         = gap_connect_cfm;
638372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_ConnectPnd_Cb         = NULL;
648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_ConfigInd_Cb          = gap_config_ind;
658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_ConfigCfm_Cb          = gap_config_cfm;
668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_DisconnectInd_Cb      = gap_disconnect_ind;
678372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_DisconnectCfm_Cb      = NULL;
688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_QoSViolationInd_Cb    = NULL;
698372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_DataInd_Cb            = gap_data_ind;
708372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_CongestionStatus_Cb   = gap_congestion_ind;
718372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_TxComplete_Cb         = NULL;
728372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_MoveInd_Cb            = NULL;
738372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_MoveRsp_Cb            = NULL;
748372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_MoveCfm_Cb            = NULL; //gap_move_cfm
758372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pAMP_MoveCfmRsp_Cb         = NULL; //gap_move_cfm_rsp
768372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
778372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#else
788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb       = gap_connect_ind;
798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pL2CA_ConnectCfm_Cb       = gap_connect_cfm;
808372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pL2CA_ConnectPnd_Cb       = NULL;
818372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pL2CA_ConfigInd_Cb        = gap_config_ind;
828372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pL2CA_ConfigCfm_Cb        = gap_config_cfm;
838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pL2CA_DisconnectInd_Cb    = gap_disconnect_ind;
848372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pL2CA_DisconnectCfm_Cb    = NULL;
858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pL2CA_QoSViolationInd_Cb  = NULL;
868372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pL2CA_DataInd_Cb          = gap_data_ind;
878372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_cb.conn.reg_info.pL2CA_CongestionStatus_Cb = gap_congestion_ind;
882bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella    gap_cb.conn.reg_info.pL2CA_TxComplete_Cb       = gap_tx_complete_ind;
898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#endif
908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
948372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_ConnOpen
968372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
978372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function is called to open an L2CAP connection.
988372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
998372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      is_server   - If TRUE, the connection is not created
1008372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                but put into a "listen" mode waiting for
1018372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                the remote side to connect.
1028372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
1038372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  service_id  - Unique service ID from
1048372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                BTM_SEC_SERVICE_FIRST_EMPTY (6)
1058372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                to BTM_SEC_MAX_SERVICE_RECORDS (32)
1068372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
1078372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  p_rem_bda   - Pointer to remote BD Address.
1088372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                If a server, and we don't care about the
1098372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                remote BD Address, then NULL should be passed.
1108372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
1118372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  psm         - the PSM used for the connection
1128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
1138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  p_config    - Optional pointer to configuration structure.
1148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                If NULL, the default GAP configuration will
1158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                be used.
1168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
1178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  security    - security flags
1188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  chan_mode_mask - (GAP_FCR_CHAN_OPT_BASIC, GAP_FCR_CHAN_OPT_ERTM,
1198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                    GAP_FCR_CHAN_OPT_STREAM)
1208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
1218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  p_cb        - Pointer to callback function for events.
1228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
1238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          handle of the connection if successful, else GAP_INVALID_HANDLE
1248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
1258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
1268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim SchulzUINT16 GAP_ConnOpen (char *p_serv_name, UINT8 service_id, BOOLEAN is_server,
1278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                     BD_ADDR p_rem_bda, UINT16 psm, tL2CAP_CFG_INFO *p_cfg,
1288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                     tL2CAP_ERTM_INFO *ertm_info, UINT16 security, UINT8 chan_mode_mask,
129ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar                     tGAP_CONN_CALLBACK *p_cb, tBT_TRANSPORT transport)
1308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
1318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
1328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT16       cid;
1338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
1348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    GAP_TRACE_EVENT ("GAP_CONN - Open Request");
1358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
1368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Allocate a new CCB. Return if none available. */
1378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb = gap_allocate_ccb()) == NULL)
1388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_INVALID_HANDLE);
1398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
140ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    /* update the transport */
141ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    p_ccb->transport = transport;
142ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
1438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* If caller specified a BD address, save it */
1448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_rem_bda)
1458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
1468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /* the bd addr is not BT_BD_ANY, then a bd address was specified */
1478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (memcmp (p_rem_bda, BT_BD_ANY, BD_ADDR_LEN))
1488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_ccb->rem_addr_specified = TRUE;
1498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
1508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        memcpy (&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN);
1518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
1528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else if (!is_server)
1538372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
1548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /* remore addr is not specified and is not a server -> bad */
1558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_INVALID_HANDLE);
1568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
1578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
1588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* A client MUST have specified a bd addr to connect with */
1598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (!p_ccb->rem_addr_specified && !is_server)
1608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
1618372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_release_ccb (p_ccb);
1628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        GAP_TRACE_ERROR ("GAP ERROR: Client must specify a remote BD ADDR to connect to!");
1638372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_INVALID_HANDLE);
1648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
1658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
1668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Check if configuration was specified */
1678372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_cfg)
1688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->cfg = *p_cfg;
1698372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
170ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    /* Configure L2CAP COC, if transport is LE */
171ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    if (transport == BT_TRANSPORT_LE)
172ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    {
173ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        p_ccb->local_coc_cfg.credits = L2CAP_LE_DEFAULT_CREDIT;
174ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        p_ccb->local_coc_cfg.mtu = p_cfg->mtu;
175ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        p_ccb->local_coc_cfg.mps = L2CAP_LE_DEFAULT_MPS;
176ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    }
177ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
1788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->p_callback     = p_cb;
1798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
1808372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* If originator, use a dynamic PSM */
1818372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#if AMP_INCLUDED == TRUE
1828372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (!is_server)
1838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_cb.conn.reg_info.pAMP_ConnectInd_Cb  = NULL;
1848372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
1858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_cb.conn.reg_info.pAMP_ConnectInd_Cb  = gap_connect_ind;
1868372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#else
1878372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (!is_server)
1888372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = NULL;
1898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
1908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = gap_connect_ind;
1918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#endif
1928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
1938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Register the PSM with L2CAP */
194ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    if (transport == BT_TRANSPORT_BR_EDR)
1958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
196ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        p_ccb->psm = L2CA_REGISTER (psm, &gap_cb.conn.reg_info,
197ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar                    AMP_AUTOSWITCH_ALLOWED|AMP_USE_AMP_IF_POSSIBLE);
198ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        if (p_ccb->psm == 0)
199ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        {
200ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            GAP_TRACE_ERROR ("%s: Failure registering PSM 0x%04x", __func__, psm);
201ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            gap_release_ccb (p_ccb);
202ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            return (GAP_INVALID_HANDLE);
203ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        }
204ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    }
205ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
206ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    if (transport == BT_TRANSPORT_LE)
207ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    {
208ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        p_ccb->psm = L2CA_REGISTER_COC (psm, &gap_cb.conn.reg_info,
209ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar                    AMP_AUTOSWITCH_ALLOWED|AMP_USE_AMP_IF_POSSIBLE);
210ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        if (p_ccb->psm == 0)
211ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        {
212ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            GAP_TRACE_ERROR ("%s: Failure registering PSM 0x%04x", __func__, psm);
213ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            gap_release_ccb (p_ccb);
214ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            return (GAP_INVALID_HANDLE);
215ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        }
2168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
2178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
2188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Register with Security Manager for the specific security level */
2198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->service_id = service_id;
2208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (!BTM_SetSecurityLevel ((UINT8)!is_server, p_serv_name,
2218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                p_ccb->service_id, security, p_ccb->psm, 0, 0))
2228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
2238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        GAP_TRACE_ERROR ("GAP_CONN - Security Error");
2248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_release_ccb (p_ccb);
2258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_INVALID_HANDLE);
2268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
2278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
2288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Fill in eL2CAP parameter data */
2298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if( p_ccb->cfg.fcr_present )
2308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
2318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if(ertm_info == NULL) {
2328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_ccb->ertm_info.preferred_mode = p_ccb->cfg.fcr.mode;
2331d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov            p_ccb->ertm_info.user_rx_buf_size = GAP_DATA_BUF_SIZE;
2341d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov            p_ccb->ertm_info.user_tx_buf_size = GAP_DATA_BUF_SIZE;
2351d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov            p_ccb->ertm_info.fcr_rx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE;
2361d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov            p_ccb->ertm_info.fcr_tx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE;
2378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        } else {
2388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_ccb->ertm_info = *ertm_info;
2398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        }
2408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
2418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
2428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* optional FCR channel modes */
2438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if(ertm_info != NULL) {
2448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->ertm_info.allowed_modes =
2458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            (chan_mode_mask) ? chan_mode_mask : (UINT8)L2CAP_FCR_CHAN_OPT_BASIC;
2468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
2478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
2488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (is_server)
2498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
2508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE; /* assume btm/l2cap would handle it */
2518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->con_state = GAP_CCB_STATE_LISTENING;
2528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (p_ccb->gap_handle);
2538372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
2548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
2558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
2568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /* We are the originator of this connection */
2578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->con_flags = GAP_CCB_FLAGS_IS_ORIG;
2588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
2598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /* Transition to the next appropriate state, waiting for connection confirm. */
2608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->con_state = GAP_CCB_STATE_CONN_SETUP;
2618372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
2628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /* mark security done flag, when security is not required */
2638372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if ((security & (BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT) ) == 0)
2648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
2658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
2668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /* Check if L2CAP started the connection process */
267ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        if (p_rem_bda && (transport == BT_TRANSPORT_BR_EDR))
2688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        {
269ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            cid = L2CA_CONNECT_REQ (p_ccb->psm, p_rem_bda, &p_ccb->ertm_info);
270ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            if (cid != 0)
271ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            {
272ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar                p_ccb->connection_id = cid;
273ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar                return (p_ccb->gap_handle);
274ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            }
2758372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        }
276ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
277ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        if (p_rem_bda && (transport == BT_TRANSPORT_LE))
2788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        {
279ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            cid = L2CA_CONNECT_COC_REQ (p_ccb->psm, p_rem_bda, &p_ccb->local_coc_cfg);
280ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            if (cid != 0)
281ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            {
282ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar                p_ccb->connection_id = cid;
283ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar                return (p_ccb->gap_handle);
284ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            }
2858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        }
286ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
287ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        gap_release_ccb (p_ccb);
288ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        return (GAP_INVALID_HANDLE);
2898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
2908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
2918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
2928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
2938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
2948372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
2958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_ConnClose
2968372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
2978372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function is called to close a connection.
2988372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
2998372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      handle      - Handle of the connection returned by GAP_ConnOpen
3008372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
3018372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          BT_PASS             - closed OK
3028372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_ERR_BAD_HANDLE  - invalid handle
3038372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
3048372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
3058372aa5fa535ee4f09c09981b6125b54ace31fe2Kim SchulzUINT16 GAP_ConnClose (UINT16 gap_handle)
3068372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
3078372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
3088372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3098372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    GAP_TRACE_EVENT ("GAP_CONN - close  handle: 0x%x", gap_handle);
3108372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3118372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_ccb)
3128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
3138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /* Check if we have a connection ID */
3148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (p_ccb->con_state != GAP_CCB_STATE_LISTENING)
3158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            L2CA_DISCONNECT_REQ (p_ccb->connection_id);
3168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_release_ccb (p_ccb);
3188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (BT_PASS);
3208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
3218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    return (GAP_ERR_BAD_HANDLE);
3238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
3248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
3288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
3298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_ConnReadData
3308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
3318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      Normally not GKI aware application will call this function
3328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  after receiving GAP_EVT_RXDATA event.
3338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
3348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      handle      - Handle of the connection returned in the Open
3358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  p_data      - Data area
3368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  max_len     - Byte count requested
3378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  p_len       - Byte count received
3388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
3398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          BT_PASS             - data read
3408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_ERR_BAD_HANDLE  - invalid handle
3418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_NO_DATA_AVAIL   - no data available
3428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
3438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
3448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim SchulzUINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
3458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
3468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
3478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT16      copy_len;
3488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (!p_ccb)
3508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_ERR_BAD_HANDLE);
3518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    *p_len = 0;
3538372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3541a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    if (fixed_queue_is_empty(p_ccb->rx_queue))
3558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_NO_DATA_AVAIL);
3568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3571eb1ea0cf2da992a3193506806e571dcbe3ec947Pavlin Radoslavov    mutex_global_lock();
3588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3591a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    while (max_len)
3608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
3611a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        BT_HDR *p_buf = fixed_queue_try_peek_first(p_ccb->rx_queue);
3621a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        if (p_buf == NULL)
3631a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            break;
3641a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov
3658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        copy_len = (p_buf->len > max_len)?max_len:p_buf->len;
3668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        max_len -= copy_len;
3678372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        *p_len  += copy_len;
3688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (p_data)
3698372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        {
3708372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, copy_len);
3718372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_data += copy_len;
3728372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        }
3738372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3748372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (p_buf->len > copy_len)
3758372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        {
3768372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_buf->offset += copy_len;
3778372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_buf->len    -= copy_len;
3788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            break;
3798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        }
380abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(fixed_queue_try_dequeue(p_ccb->rx_queue));
3818372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
3828372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->rx_queue_size -= *p_len;
3848372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3851eb1ea0cf2da992a3193506806e571dcbe3ec947Pavlin Radoslavov    mutex_global_unlock();
3868372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3878372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    GAP_TRACE_EVENT ("GAP_ConnReadData - rx_queue_size left=%d, *p_len=%d",
3888372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                                       p_ccb->rx_queue_size, *p_len);
3898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    return (BT_PASS);
3918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
3928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
3938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
3948372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
3958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_GetRxQueueCnt
3968372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
3978372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function return number of bytes on the rx queue.
3988372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
3998372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      handle     - Handle returned in the GAP_ConnOpen
4008372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  p_rx_queue_count - Pointer to return queue count in.
4018372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4028372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4038372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
4048372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzint GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count)
4058372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
4068372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
4078372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    int         rc = BT_PASS;
4088372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4098372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Check that handle is valid */
4108372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (handle < GAP_MAX_CONNECTIONS)
4118372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
4128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb = &gap_cb.conn.ccb_pool[handle];
4138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
4158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        {
4168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            *p_rx_queue_count = p_ccb->rx_queue_size;
4178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        }
4188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        else
4198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            rc = GAP_INVALID_HANDLE;
4208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
4218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
4228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        rc = GAP_INVALID_HANDLE;
4238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    GAP_TRACE_EVENT ("GAP_GetRxQueueCnt - rc = 0x%04x, rx_queue_count=%d",
4258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                                       rc , *p_rx_queue_count);
4268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    return (rc);
4288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
4298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
4318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_ConnBTRead
4338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      Bluetooth aware applications will call this function after receiving
4358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_EVT_RXDATA event.
4368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      handle      - Handle of the connection returned in the Open
4388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  pp_buf      - pointer to address of buffer with data,
4398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          BT_PASS             - data read
4418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_ERR_BAD_HANDLE  - invalid handle
4428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_NO_DATA_AVAIL   - no data available
4438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
4458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim SchulzUINT16 GAP_ConnBTRead (UINT16 gap_handle, BT_HDR **pp_buf)
4468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
4478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
4488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    BT_HDR      *p_buf;
4498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (!p_ccb)
4518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_ERR_BAD_HANDLE);
4528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4531a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_ccb->rx_queue);
4548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_buf)
4568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
4578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        *pp_buf = p_buf;
4588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->rx_queue_size -= p_buf->len;
4608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (BT_PASS);
4618372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
4628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
4638372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
4648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        *pp_buf = NULL;
4658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_NO_DATA_AVAIL);
4668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
4678372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
4688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4698372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
4708372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4718372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_ConnWriteData
4728372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4738372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      Normally not GKI aware application will call this function
4748372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  to send data to the connection.
4758372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4768372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      handle      - Handle of the connection returned in the Open
4778372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  p_data      - Data area
4788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  max_len     - Byte count requested
4798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  p_len       - Byte count received
4808372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4818372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          BT_PASS                 - data read
4828372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_ERR_BAD_HANDLE      - invalid handle
4838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_ERR_BAD_STATE       - connection not established
4848372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_CONGESTION          - system is congested
4858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
4868372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
4878372aa5fa535ee4f09c09981b6125b54ace31fe2Kim SchulzUINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
4888372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
4898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
4908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    BT_HDR     *p_buf;
4918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    *p_len = 0;
4938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4948372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (!p_ccb)
4958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_ERR_BAD_HANDLE);
4968372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
4978372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
4988372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_ERR_BAD_STATE);
4998372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5008372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    while (max_len)
5018372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
5028372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
503abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov            p_buf = (BT_HDR *)osi_malloc(L2CAP_FCR_ERTM_BUF_SIZE);
5048372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        else
505abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov            p_buf = (BT_HDR *)osi_malloc(GAP_DATA_BUF_SIZE);
5068372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5078372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_buf->offset = L2CAP_MIN_OFFSET;
5088372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_buf->len = (p_ccb->rem_mtu_size < max_len) ? p_ccb->rem_mtu_size : max_len;
5098372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_buf->event = BT_EVT_TO_BTU_SP_DATA;
5108372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5118372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);
5128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        *p_len  += p_buf->len;
5148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        max_len -= p_buf->len;
5158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_data  += p_buf->len;
5168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        GAP_TRACE_EVENT ("GAP_WriteData %d bytes", p_buf->len);
5188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5191a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        fixed_queue_enqueue(p_ccb->tx_queue, p_buf);
5208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
5218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_ccb->is_congested)
5238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
5248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (BT_PASS);
5258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
5268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Send the buffer through L2CAP */
5288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
5298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_send_event (gap_handle);
5308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#else
5311a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    while ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_ccb->tx_queue)) != NULL)
5328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
5338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
5348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (status == L2CAP_DW_CONGESTED)
5368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        {
5378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_ccb->is_congested = TRUE;
5388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            break;
5398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        }
5408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        else if (status != L2CAP_DW_SUCCESS)
5418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            return (GAP_ERR_BAD_STATE);
5428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
5438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#endif
5448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    return (BT_PASS);
5458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
5468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
5498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
5508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_ConnReconfig
5518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
5528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      Applications can call this function to reconfigure the connection.
5538372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
5548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      handle      - Handle of the connection
5558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  p_cfg       - Pointer to new configuration
5568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
5578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          BT_PASS                 - config process started
5588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_ERR_BAD_HANDLE      - invalid handle
5598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
5608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
5618372aa5fa535ee4f09c09981b6125b54ace31fe2Kim SchulzUINT16 GAP_ConnReconfig (UINT16 gap_handle, tL2CAP_CFG_INFO *p_cfg)
5628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
5638372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
5648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (!p_ccb)
5668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_ERR_BAD_HANDLE);
5678372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->cfg = *p_cfg;
5698372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5708372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
5718372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        L2CA_CONFIG_REQ (p_ccb->connection_id, p_cfg);
5728372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5738372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    return (BT_PASS);
5748372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
5758372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5768372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5778372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
5788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
5798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
5808372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_ConnSetIdleTimeout
5818372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
5828372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      Higher layers call this function to set the idle timeout for
5838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  a connection, or for all future connections. The "idle timeout"
5848372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  is the amount of time that a connection can remain up with
5858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  no L2CAP channels on it. A timeout of zero means that the
5868372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  connection will be torn down immediately when the last channel
5878372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  is removed. A timeout of 0xFFFF means no timeout. Values are
5888372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  in seconds.
5898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
5908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      handle      - Handle of the connection
5918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  timeout     - in secs
5928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                0 = immediate disconnect when last channel is removed
5938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                                0xFFFF = no idle timeout
5948372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
5958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          BT_PASS                 - config process started
5968372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_ERR_BAD_HANDLE      - invalid handle
5978372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
5988372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
5998372aa5fa535ee4f09c09981b6125b54ace31fe2Kim SchulzUINT16 GAP_ConnSetIdleTimeout (UINT16 gap_handle, UINT16 timeout)
6008372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
6018372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
6028372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6038372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
6048372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_ERR_BAD_HANDLE);
6058372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6068372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (L2CA_SetIdleTimeout (p_ccb->connection_id, timeout, FALSE))
6078372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (BT_PASS);
6088372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
6098372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (GAP_ERR_BAD_HANDLE);
6108372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
6118372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
6158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_ConnGetRemoteAddr
6178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function is called to get the remote BD address
6198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  of a connection.
6208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      handle      - Handle of the connection returned by GAP_ConnOpen
6228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          BT_PASS             - closed OK
6248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  GAP_ERR_BAD_HANDLE  - invalid handle
6258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
6278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim SchulzUINT8 *GAP_ConnGetRemoteAddr (UINT16 gap_handle)
6288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
6298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
6308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    GAP_TRACE_EVENT ("GAP_ConnGetRemoteAddr gap_handle = %d", gap_handle);
6328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb) && (p_ccb->con_state > GAP_CCB_STATE_LISTENING))
6348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
6358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        GAP_TRACE_EVENT("GAP_ConnGetRemoteAddr bda :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", \
6368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                         p_ccb->rem_dev_address[0],p_ccb->rem_dev_address[1],p_ccb->rem_dev_address[2],
6378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                         p_ccb->rem_dev_address[3],p_ccb->rem_dev_address[4],p_ccb->rem_dev_address[5]);
6388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (p_ccb->rem_dev_address);
6398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
6408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
6418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
6428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        GAP_TRACE_EVENT ("GAP_ConnGetRemoteAddr return Error ");
6438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (NULL);
6448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
6458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
6468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
6498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_ConnGetRemMtuSize
6518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      Returns the remote device's MTU size
6538372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      handle      - Handle of the connection
6558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          UINT16      - maximum size buffer that can be transmitted to the peer
6578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
6598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim SchulzUINT16 GAP_ConnGetRemMtuSize (UINT16 gap_handle)
6608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
6618372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
6628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6638372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
6648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (0);
6658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    return (p_ccb->rem_mtu_size);
6678372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
6688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6698372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
6708372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6718372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         GAP_ConnGetL2CAPCid
6728372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6738372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      Returns the L2CAP channel id
6748372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6758372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Parameters:      handle      - Handle of the connection
6768372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6778372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          UINT16      - The L2CAP channel id
6788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  0, if error
6798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
6808372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
6818372aa5fa535ee4f09c09981b6125b54ace31fe2Kim SchulzUINT16 GAP_ConnGetL2CAPCid (UINT16 gap_handle)
6828372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
6838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
6848372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
6868372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return (0);
6878372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6888372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    return (p_ccb->connection_id);
6898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
6908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
6912bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella/*******************************************************************************
6922bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella**
6932bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella** Function         gap_tx_connect_ind
6942bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella**
6952bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella** Description      Sends out GAP_EVT_TX_EMPTY when transmission has been
6962bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella**                  completed.
6972bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella**
6982bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella** Returns          void
6992bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella**
7002bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella*******************************************************************************/
7012bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jellavoid gap_tx_complete_ind (UINT16 l2cap_cid, UINT16 sdu_sent)
7022bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella{
7032bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella    tGAP_CCB *p_ccb = gap_find_ccb_by_cid (l2cap_cid);
7042bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella    if (p_ccb == NULL)
7052bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella        return;
7062bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella
7072bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella    if ((p_ccb->con_state == GAP_CCB_STATE_CONNECTED) && (sdu_sent == 0xFFFF))
7082bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella    {
7092bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella        GAP_TRACE_EVENT("%s: GAP_EVT_TX_EMPTY", __func__);
7102bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella        p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_TX_EMPTY);
7112bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella    }
7122bbedbf283f30378aaf347f9f0dd7986ed408f64Srinu Jella}
7138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
7148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
7158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
7168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_connect_ind
7178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
7188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function handles an inbound connection indication
7198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  from L2CAP. This is the case where we are acting as a
7208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  server.
7218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
7228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          void
7238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
7248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
7258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id)
7268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
7278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT16       xx;
7288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB     *p_ccb;
7298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
7308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* See if we have a CCB listening for the connection */
7318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
7328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
7338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if ((p_ccb->con_state == GAP_CCB_STATE_LISTENING)
7348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz         && (p_ccb->psm == psm)
7358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz         && ((p_ccb->rem_addr_specified == FALSE)
7368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz           || (!memcmp (bd_addr, p_ccb->rem_dev_address, BD_ADDR_LEN))))
7378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            break;
7388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
7398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
7408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (xx == GAP_MAX_CONNECTIONS)
7418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
7428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        GAP_TRACE_WARNING("*******");
7438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        GAP_TRACE_WARNING("WARNING: GAP Conn Indication for Unexpected Bd Addr...Disconnecting");
7448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        GAP_TRACE_WARNING("*******");
7458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
7468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /* Disconnect because it is an unexpected connection */
7478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        L2CA_DISCONNECT_REQ (l2cap_cid);
7488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return;
7498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
7508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
7518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Transition to the next appropriate state, waiting for config setup. */
752ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    if (p_ccb->transport == BT_TRANSPORT_BR_EDR)
753ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
7548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
7558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Save the BD Address and Channel ID. */
7568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    memcpy (&p_ccb->rem_dev_address[0], bd_addr, BD_ADDR_LEN);
7578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->connection_id = l2cap_cid;
7588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
7598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Send response to the L2CAP layer. */
760ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    if (p_ccb->transport == BT_TRANSPORT_BR_EDR)
761ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        L2CA_CONNECT_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK, &p_ccb->ertm_info);
762ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
763ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    if (p_ccb->transport == BT_TRANSPORT_LE)
764ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    {
765ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        L2CA_CONNECT_COC_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK, &p_ccb->local_coc_cfg);
766ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
767ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        /* get the remote coc configuration */
768ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        L2CA_GET_PEER_COC_CONFIG(l2cap_cid, &p_ccb->peer_coc_cfg);
769ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        p_ccb->rem_mtu_size = p_ccb->peer_coc_cfg.mtu;
770ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
771ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        /* configuration is not required for LE COC */
772ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        p_ccb->con_flags |= GAP_CCB_FLAGS_HIS_CFG_DONE;
773ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        p_ccb->con_flags |= GAP_CCB_FLAGS_MY_CFG_DONE;
774ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        gap_checks_con_flags (p_ccb);
775ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    }
7768372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
7778372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    GAP_TRACE_EVENT("GAP_CONN - Rcvd L2CAP conn ind, CID: 0x%x", p_ccb->connection_id);
7788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
7798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Send a Configuration Request. */
780ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    if (p_ccb->transport == BT_TRANSPORT_BR_EDR)
781ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg);
7828372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
7838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
7848372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
7858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
7868372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_checks_con_flags
7878372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
7888372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function processes the L2CAP configuration indication
7898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  event.
7908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
7918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          void
7928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
7938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
7948372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_checks_con_flags (tGAP_CCB    *p_ccb)
7958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
7968372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    GAP_TRACE_EVENT ("gap_checks_con_flags conn_flags:0x%x, ", p_ccb->con_flags);
7978372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* if all the required con_flags are set, report the OPEN event now */
7988372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE)
7998372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
8008372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
8018372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
8028372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
8038372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
8048372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
8058372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
8068372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
8078372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
8088372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_sec_check_complete
8098372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
8108372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      The function called when Security Manager finishes
8118372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  verification of the service side connection
8128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
8138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          void
8148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
8158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
8168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
8178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
8188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB *p_ccb = (tGAP_CCB *)p_ref_data;
8198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UNUSED(bd_addr);
8208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UNUSED (transport);
8218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
8228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    GAP_TRACE_EVENT ("gap_sec_check_complete conn_state:%d, conn_flags:0x%x, status:%d",
8238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->con_state, p_ccb->con_flags, res);
8248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_ccb->con_state == GAP_CCB_STATE_IDLE)
8258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return;
8268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
8278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (res == BTM_SUCCESS)
8288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
8298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
8308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_checks_con_flags (p_ccb);
8318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
8328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
8338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
8348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /* security failed - disconnect the channel */
8358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        L2CA_DISCONNECT_REQ (p_ccb->connection_id);
8368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
8378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
8388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
8398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
8408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
8418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_connect_cfm
8428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
8438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function handles the connect confirm events
8448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  from L2CAP. This is the case when we are acting as a
8458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  client and have sent a connect request.
8468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
8478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          void
8488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
8498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
8508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result)
8518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
8528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
8538372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
8548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Find CCB based on CID */
8558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
8568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return;
8578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
8588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* initiate security process, if needed */
859ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    if ( (p_ccb->con_flags & GAP_CCB_FLAGS_SEC_DONE) == 0 && p_ccb->transport != BT_TRANSPORT_LE)
8608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
8618372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        btm_sec_mx_access_request (p_ccb->rem_dev_address, p_ccb->psm, TRUE,
8628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                                   0, 0, &gap_sec_check_complete, p_ccb);
8638372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
8648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
8658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* If the connection response contains success status, then */
8668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Transition to the next state and startup the timer.      */
8678372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((result == L2CAP_CONN_OK) && (p_ccb->con_state == GAP_CCB_STATE_CONN_SETUP))
8688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
869ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        if (p_ccb->transport == BT_TRANSPORT_BR_EDR)
870ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        {
871ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
8728372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
873ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            /* Send a Configuration Request. */
874ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg);
875ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        }
876ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
877ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        if (p_ccb->transport == BT_TRANSPORT_LE)
878ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        {
879ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            /* get the remote coc configuration */
880ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            L2CA_GET_PEER_COC_CONFIG(l2cap_cid, &p_ccb->peer_coc_cfg);
881ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            p_ccb->rem_mtu_size = p_ccb->peer_coc_cfg.mtu;
882ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
883ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            /* configuration is not required for LE COC */
884ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            p_ccb->con_flags |= GAP_CCB_FLAGS_HIS_CFG_DONE;
885ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            p_ccb->con_flags |= GAP_CCB_FLAGS_MY_CFG_DONE;
886ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
887ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar            gap_checks_con_flags (p_ccb);
888ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        }
8898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
8908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
8918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
8928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /* Tell the user if he has a callback */
8938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (p_ccb->p_callback)
8948372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            (*p_ccb->p_callback) (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
8958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
8968372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_release_ccb (p_ccb);
8978372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
8988372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
8998372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9008372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
9018372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9028372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_config_ind
9038372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9048372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function processes the L2CAP configuration indication
9058372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  event.
9068372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9078372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          void
9088372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9098372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
9108372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
9118372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
9128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
9138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT16      local_mtu_size;
9148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Find CCB based on CID */
9168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
9178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return;
9188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Remember the remote MTU size */
9208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
9228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
9231d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov        local_mtu_size = p_ccb->ertm_info.user_tx_buf_size
9248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                       - sizeof(BT_HDR) - L2CAP_MIN_OFFSET;
9258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
9268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
9278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        local_mtu_size = L2CAP_MTU_SIZE;
9288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((!p_cfg->mtu_present)||(p_cfg->mtu > local_mtu_size))
9308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
9318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->rem_mtu_size = local_mtu_size;
9328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
9338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
9348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->rem_mtu_size = p_cfg->mtu;
9358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* For now, always accept configuration from the other side */
9378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_cfg->flush_to_present = FALSE;
9388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_cfg->mtu_present      = FALSE;
9398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_cfg->result           = L2CAP_CFG_OK;
9408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_cfg->fcs_present      = FALSE;
9418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    L2CA_CONFIG_RSP (l2cap_cid, p_cfg);
9438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->con_flags |= GAP_CCB_FLAGS_HIS_CFG_DONE;
9458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_checks_con_flags (p_ccb);
9478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
9488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
9518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_config_cfm
9538372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function processes the L2CAP configuration confirmation
9558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  event.
9568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          void
9588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
9608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
9618372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
9628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
9638372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Find CCB based on CID */
9658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
9668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return;
9678372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_cfg->result == L2CAP_CFG_OK)
9698372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
9708372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->con_flags |= GAP_CCB_FLAGS_MY_CFG_DONE;
9718372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9728372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9738372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (p_ccb->cfg.fcr_present)
9748372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_ccb->cfg.fcr.mode = p_cfg->fcr.mode;
9758372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        else
9768372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_ccb->cfg.fcr.mode = L2CAP_FCR_BASIC_MODE;
9778372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_checks_con_flags (p_ccb);
9798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
9808372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
9818372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
9828372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
9838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        gap_release_ccb (p_ccb);
9848372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
9858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
9868372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9878372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
9888372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
9898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_disconnect_ind
9918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function handles a disconnect event from L2CAP. If
9938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  requested to, we ack the disconnect before dropping the CCB
9948372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          void
9968372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
9978372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
9988372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed)
9998372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
10008372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
10018372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10028372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    GAP_TRACE_EVENT ("GAP_CONN - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid);
10038372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10048372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Find CCB based on CID */
10058372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
10068372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return;
10078372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10088372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (ack_needed)
10098372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        L2CA_DISCONNECT_RSP (l2cap_cid);
10108372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10118372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
10128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    gap_release_ccb (p_ccb);
10138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
10148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
10178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
10188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_data_ind
10198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
10208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function is called when data is received from L2CAP.
10218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
10228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          void
10238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
10248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
10258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
10268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
10278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
10288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Find CCB based on CID */
10308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
10318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
1032abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(p_msg);
10338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return;
10348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
10358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
10378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
10381a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        fixed_queue_enqueue(p_ccb->rx_queue, p_msg);
10398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->rx_queue_size += p_msg->len;
10418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        /*
10428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        GAP_TRACE_EVENT ("gap_data_ind - rx_queue_size=%d, msg len=%d",
10438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                                       p_ccb->rx_queue_size, p_msg->len);
10448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz         */
10458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL);
10478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
10488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    else
10498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
1050abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(p_msg);
10518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
10528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
10538372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
10568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
10578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_congestion_ind
10588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
10598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This is a callback function called by L2CAP when
10608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  data L2CAP congestion status changes
10618372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
10628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
10638372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested)
10648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
10658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB    *p_ccb;
10668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT16       event;
10678372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    BT_HDR      *p_buf;
10688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT8        status;
10698372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10708372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    GAP_TRACE_EVENT ("GAP_CONN - Rcvd L2CAP Is Congested (%d), CID: 0x%x",
10718372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                      is_congested, lcid);
10728372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10738372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Find CCB based on CID */
10748372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_ccb = gap_find_ccb_by_cid (lcid)) == NULL)
10758372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        return;
10768372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10778372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->is_congested = is_congested;
10788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    event = (is_congested) ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED;
10808372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->p_callback (p_ccb->gap_handle, event);
10818372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10828372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (!is_congested)
10838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
10841a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        while ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_ccb->tx_queue)) != NULL)
10858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        {
10868372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
10878372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10888372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            if (status == L2CAP_DW_CONGESTED)
10898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            {
10908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                p_ccb->is_congested = TRUE;
10918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                break;
10928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            }
10938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            else if (status != L2CAP_DW_SUCCESS)
10948372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                break;
10958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        }
10968372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
10978372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
10988372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
10998372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11008372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
11018372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11028372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_find_ccb_by_cid
11038372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11048372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function searches the CCB table for an entry with the
11058372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  passed CID.
11068372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11078372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          the CCB address, or NULL if not found.
11088372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11098372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
11108372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid)
11118372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
11128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT16       xx;
11138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB     *p_ccb;
11148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Look through each connection control block */
11168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
11178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
11188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->connection_id == cid))
11198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            return (p_ccb);
11208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
11218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* If here, not found */
11238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    return (NULL);
11248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
11258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
11288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_find_ccb_by_handle
11308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function searches the CCB table for an entry with the
11328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**                  passed handle.
11338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          the CCB address, or NULL if not found.
11358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
11378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle)
11388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
11398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB     *p_ccb;
11408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Check that handle is valid */
11428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if (handle < GAP_MAX_CONNECTIONS)
11438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
11448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        p_ccb = &gap_cb.conn.ccb_pool[handle];
11458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (p_ccb->con_state != GAP_CCB_STATE_IDLE)
11478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            return (p_ccb);
11488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
11498372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* If here, handle points to invalid connection */
11518372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    return (NULL);
11528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
11538372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11548372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
11568372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_allocate_ccb
11588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function allocates a new CCB.
11608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11618372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          CCB address, or NULL if none available.
11628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11638372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
11648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic tGAP_CCB *gap_allocate_ccb (void)
11658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
11668372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT16       xx;
11678372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    tGAP_CCB     *p_ccb;
11688372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11698372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Look through each connection control block for a free one */
11708372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
11718372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
11728372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if (p_ccb->con_state == GAP_CCB_STATE_IDLE)
11738372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        {
11748372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            memset (p_ccb, 0, sizeof (tGAP_CCB));
11751a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            p_ccb->tx_queue = fixed_queue_new(SIZE_MAX);
11761a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            p_ccb->rx_queue = fixed_queue_new(SIZE_MAX);
11778372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_ccb->gap_handle   = xx;
11798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            p_ccb->rem_mtu_size = L2CAP_MTU_SIZE;
11808372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11818372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            return (p_ccb);
11828372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        }
11838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
11848372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* If here, no free CCB found */
11868372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    return (NULL);
11878372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
11888372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11898372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
11908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
11918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11928372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function         gap_release_ccb
11938372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11948372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description      This function releases a CCB.
11958372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11968372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns          void
11978372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
11988372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
11998372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzstatic void gap_release_ccb (tGAP_CCB *p_ccb)
12008372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
12018372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT16       xx;
12028372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT16      psm = p_ccb->psm;
12038372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    UINT8       service_id = p_ccb->service_id;
12048372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12058372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Drop any buffers we may be holding */
12068372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->rx_queue_size = 0;
12078372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12081a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    while (!fixed_queue_is_empty(p_ccb->rx_queue))
1209abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(fixed_queue_try_dequeue(p_ccb->rx_queue));
12101a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    fixed_queue_free(p_ccb->rx_queue, NULL);
12111a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    p_ccb->rx_queue = NULL;
12128372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12131a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    while (!fixed_queue_is_empty(p_ccb->tx_queue))
1214abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov        osi_free(fixed_queue_try_dequeue(p_ccb->tx_queue));
12151a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    fixed_queue_free(p_ccb->tx_queue, NULL);
12161a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    p_ccb->tx_queue = NULL;
12178372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    p_ccb->con_state = GAP_CCB_STATE_IDLE;
12198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* If no-one else is using the PSM, deregister from L2CAP */
12218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
12228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    {
12238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz        if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->psm == psm))
12248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            return;
12258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    }
12268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    /* Free the security record for this PSM */
12288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    BTM_SecClrService(service_id);
1229ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    if (p_ccb->transport == BT_TRANSPORT_BR_EDR)
1230ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        L2CA_DEREGISTER (psm);
1231ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar
1232ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar    if(p_ccb->transport == BT_TRANSPORT_LE)
1233ab99638f9a05ae7ed04ab0a75d48cbd1d78b36e8Navin Kochar        L2CA_DEREGISTER_COC (psm);
12348372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
12358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12368372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
12378372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12388372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz/*******************************************************************************
12398372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
12408372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Function     gap_send_event
12418372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
12428372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Description  Send BT_EVT_TO_GAP_MSG event to BTU task
12438372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
12448372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz** Returns      None
12458372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz**
12468372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz*******************************************************************************/
12478372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulzvoid gap_send_event (UINT16 gap_handle)
12488372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz{
12495fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    BT_HDR *p_msg = (BT_HDR *)osi_malloc(BT_HDR_SIZE);
12508372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12515fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p_msg->event  = BT_EVT_TO_GAP_MSG;
12525fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p_msg->len    = 0;
12535fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p_msg->offset = 0;
12545fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p_msg->layer_specific = gap_handle;
12558372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12565fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg);
12578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz}
12588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz
12598372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#endif /* (GAP_CONN_POST_EVT_INCLUDED == TRUE) */
12608372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#endif  /* GAP_CONN_INCLUDED */
1261