/*******************************************************************************
**
** Function         L2cap_Register
**
** Description      This function is called during the task startup
**                  to register interface functions with L2CAP.
**
*******************************************************************************/
static bt_status_t L2cap_Register (UINT16 psm, BOOLEAN ConnType, UINT16 SecLevel)
{

    BTIF_TRACE_DEBUG("L2cap_Register :: psm=%d", psm);
    if (!BTM_SetSecurityLevel (ConnType, "l2test", /*BTM_SEC_SERVICE_SDP_SERVER*/ BTM_SEC_PROTO_L2CAP,
                               SecLevel, psm, 0, 0))
    {
        BTIF_TRACE_DEBUG("Error:: BTM_SetSecurityLevel failed");
        return BT_STATUS_FAIL;
}
#if 1
    if(4113 == psm) {
        if (!BTM_SetSecurityLevel (ConnType, "l2test 4113", /*BTM_SEC_SERVICE_SDP_SERVER*/ BTM_SEC_PROTO_L2CAP,
                                   SecLevel, psm, 0, 0)) {
            BTIF_TRACE_DEBUG("Error:: BTM_SetSecurityLevel failed");
            return BT_STATUS_FAIL;
        }
    }
#endif
    g_Psm = L2CA_Register (psm, pl2test_l2c_appl);
    if(0 == g_Psm) {
        BTIF_TRACE_DEBUG("Error:: L2CA_Register failed");
        return BT_STATUS_FAIL;
    }
   return BT_STATUS_SUCCESS;
}
/*******************************************************************************
**
** Function         sdp_init
**
** Description      This function initializes the SDP unit.
**
** Returns          void
**
*******************************************************************************/
void sdp_init (void)
{
    /* Clears all structures and local SDP database (if Server is enabled) */
    memset (&sdp_cb, 0, sizeof (tSDP_CB));

    /* Initialize the L2CAP configuration. We only care about MTU and flush */
    sdp_cb.l2cap_my_cfg.mtu_present       = TRUE;
    sdp_cb.l2cap_my_cfg.mtu               = SDP_MTU_SIZE;
    sdp_cb.l2cap_my_cfg.flush_to_present  = TRUE;
    sdp_cb.l2cap_my_cfg.flush_to          = SDP_FLUSH_TO;

    sdp_cb.max_attr_list_size             = SDP_MTU_SIZE - 16;
    sdp_cb.max_recs_per_search            = SDP_MAX_DISC_SERVER_RECS;

#if SDP_SERVER_ENABLED == TRUE
    /* Register with Security Manager for the specific security level */
    if (!BTM_SetSecurityLevel (FALSE, SDP_SERVICE_NAME, BTM_SEC_SERVICE_SDP_SERVER,
                               SDP_SECURITY_LEVEL, SDP_PSM, 0, 0))
    {
        SDP_TRACE_ERROR0 ("Security Registration Server failed");
        return;
    }
#endif

#if SDP_CLIENT_ENABLED == TRUE
    /* Register with Security Manager for the specific security level */
    if (!BTM_SetSecurityLevel (TRUE, SDP_SERVICE_NAME, BTM_SEC_SERVICE_SDP_SERVER,
                               SDP_SECURITY_LEVEL, SDP_PSM, 0, 0))
    {
        SDP_TRACE_ERROR0 ("Security Registration for Client failed");
        return;
    }
#endif

#if defined(SDP_INITIAL_TRACE_LEVEL)
    sdp_cb.trace_level = SDP_INITIAL_TRACE_LEVEL;
#else
    sdp_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
#endif

    sdp_cb.reg_info.pL2CA_ConnectInd_Cb = sdp_connect_ind;
    sdp_cb.reg_info.pL2CA_ConnectCfm_Cb = sdp_connect_cfm;
    sdp_cb.reg_info.pL2CA_ConnectPnd_Cb = NULL;
    sdp_cb.reg_info.pL2CA_ConfigInd_Cb  = sdp_config_ind;
    sdp_cb.reg_info.pL2CA_ConfigCfm_Cb  = sdp_config_cfm;
    sdp_cb.reg_info.pL2CA_DisconnectInd_Cb = sdp_disconnect_ind;
    sdp_cb.reg_info.pL2CA_DisconnectCfm_Cb = sdp_disconnect_cfm;
    sdp_cb.reg_info.pL2CA_QoSViolationInd_Cb = NULL;
    sdp_cb.reg_info.pL2CA_DataInd_Cb = sdp_data_ind;
    sdp_cb.reg_info.pL2CA_CongestionStatus_Cb = NULL;
    sdp_cb.reg_info.pL2CA_TxComplete_Cb       = NULL;

    /* Now, register with L2CAP */
    if (!L2CA_Register (SDP_PSM, &sdp_cb.reg_info))
    {
        SDP_TRACE_ERROR0 ("SDP Registration failed");
    }
}
/*******************************************************************************
**
** Function         PAN_SetPanuSecurity
**
** Description      This function is used to register PANU service security
**                  level with Security Manager
**
** Parameters:      sec_mask    - Security mask for PANU role
**                  p_name      - Service name for PANU role
**
** Returns          none
**
*******************************************************************************/
static void PAN_SetPanuSecurity(UINT8 sec_mask, char *p_name)
{
#if (defined (PAN_SUPPORTS_ROLE_PANU) && PAN_SUPPORTS_ROLE_PANU == TRUE)
    if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_PANU,
        sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_PANU))
        || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_PANU,
        sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_PANU)))
    {
        PAN_TRACE_ERROR0 ("PAN Security Registration failed for  PANU");
    }
#endif
}
示例#4
0
/*******************************************************************************
**
** Function         gatt_init
**
** Description      This function is enable the GATT profile on the device.
**                  It clears out the control blocks, and registers with L2CAP.
**
** Returns          void
**
*******************************************************************************/
void gatt_init (void)
{
    tL2CAP_FIXED_CHNL_REG  fixed_reg;

    GATT_TRACE_DEBUG("gatt_init()");

    memset (&gatt_cb, 0, sizeof(tGATT_CB));
    memset (&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG));

#if defined(GATT_INITIAL_TRACE_LEVEL)
    gatt_cb.trace_level = GATT_INITIAL_TRACE_LEVEL;
#else
    gatt_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
#endif
    gatt_cb.def_mtu_size = GATT_DEF_BLE_MTU_SIZE;
    GKI_init_q (&gatt_cb.sign_op_queue);
    GKI_init_q (&gatt_cb.srv_chg_clt_q);
    GKI_init_q (&gatt_cb.pending_new_srv_start_q);
    /* First, register fixed L2CAP channel for ATT over BLE */
    fixed_reg.fixed_chnl_opts.mode         = L2CAP_FCR_BASIC_MODE;
    fixed_reg.fixed_chnl_opts.max_transmit = 0xFF;
    fixed_reg.fixed_chnl_opts.rtrans_tout  = 2000;
    fixed_reg.fixed_chnl_opts.mon_tout     = 12000;
    fixed_reg.fixed_chnl_opts.mps          = 670;
    fixed_reg.fixed_chnl_opts.tx_win_sz    = 1;

    fixed_reg.pL2CA_FixedConn_Cb = gatt_le_connect_cback;
    fixed_reg.pL2CA_FixedData_Cb = gatt_le_data_ind;
    fixed_reg.pL2CA_FixedCong_Cb = gatt_le_cong_cback;      /* congestion callback */
    fixed_reg.default_idle_tout  = 0xffff;                  /* 0xffff default idle timeout */

    L2CA_RegisterFixedChannel (L2CAP_ATT_CID, &fixed_reg);

    /* Now, register with L2CAP for ATT PSM over BR/EDR */
    if (!L2CA_Register (BT_PSM_ATT, (tL2CAP_APPL_INFO *) &dyn_info))
    {
        GATT_TRACE_ERROR ("ATT Dynamic Registration failed");
    }

    BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0);
    BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0);

    gatt_cb.hdl_cfg.gatt_start_hdl = GATT_GATT_START_HANDLE;
    gatt_cb.hdl_cfg.gap_start_hdl  = GATT_GAP_START_HANDLE;
    gatt_cb.hdl_cfg.app_start_hdl  = GATT_APP_START_HANDLE;
    gatt_profile_db_init();

}
示例#5
0
/*******************************************************************************
**
** Function         bta_ag_start_servers
**
** Description      Setup RFCOMM servers for use by AG.
**
**
** Returns          void
**
*******************************************************************************/
void bta_ag_start_servers(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK services)
{
    int i;
    int bta_ag_port_status;

    services >>= BTA_HSP_SERVICE_ID;
    for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1)
    {
        /* if service is set in mask */
        if (services & 1)
        {
            BTM_SetSecurityLevel(FALSE, "", bta_ag_sec_id[i], p_scb->serv_sec_mask,
                BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, bta_ag_cb.profile[i].scn);

            bta_ag_port_status =  RFCOMM_CreateConnection(bta_ag_uuid[i], bta_ag_cb.profile[i].scn,
                TRUE, BTA_AG_MTU, (UINT8 *) bd_addr_any, &(p_scb->serv_handle[i]),
                bta_ag_mgmt_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]);

            if( bta_ag_port_status  == PORT_SUCCESS )
            {
                bta_ag_setup_port(p_scb, p_scb->serv_handle[i]);
            }
            else
            {
                /* TODO: CR#137125 to handle to error properly */
                APPL_TRACE_DEBUG("bta_ag_start_servers: RFCOMM_CreateConnection returned error:%d", bta_ag_port_status);
            }
        }
    }
}
示例#6
0
/*******************************************************************************
**
** Function         avdt_ccb_set_conn
**
** Description      Set CCB variables associated with AVDT_ConnectReq().
**
**
** Returns          void.
**
*******************************************************************************/
void avdt_ccb_set_conn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
{
    /* save callback */
    p_ccb->p_conn_cback = p_data->connect.p_cback;

    /* set security level */
    BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP, p_data->connect.sec_mask,
                         AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
}
示例#7
0
/*******************************************************************************
**
** Function         AVDT_Register
**
** Description      This is the system level registration function for the
**                  AVDTP protocol.  This function initializes AVDTP and
**                  prepares the protocol stack for its use.  This function
**                  must be called once by the system or platform using AVDTP
**                  before the other functions of the API an be used.
**
**
** Returns          void
**
*******************************************************************************/
void AVDT_Register(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback)
{
    /* register PSM with L2CAP */
    L2CA_Register(AVDT_PSM, (tL2CAP_APPL_INFO *) &avdt_l2c_appl);

    /* set security level */
    BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
                         AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
    BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
                         AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);

    /* do not use security on the media channel */
    BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
                         AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA);
    BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
                         AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA);

#if AVDT_REPORTING == TRUE
    /* do not use security on the reporting channel */
    BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
                         AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT);
    BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
                         AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT);
#endif

    /* initialize AVDTP data structures */
    avdt_scb_init();
    avdt_ccb_init();
    avdt_ad_init();

    /* copy registration struct */
    memcpy(&avdt_cb.rcb, p_reg, sizeof(tAVDT_REG));
    avdt_cb.p_conn_cback = p_cback;
}
示例#8
0
/*******************************************************************************
**
** Function         bta_ag_rfc_do_open
**
** Description      Open an RFCOMM connection to the peer device.
**
**
** Returns          void
**
*******************************************************************************/
void bta_ag_rfc_do_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
{
    BTM_SetSecurityLevel(TRUE, "", bta_ag_sec_id[p_scb->conn_service],
        p_scb->cli_sec_mask, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, p_scb->peer_scn);

    if (RFCOMM_CreateConnection(bta_ag_uuid[p_scb->conn_service], p_scb->peer_scn,
            FALSE, BTA_AG_MTU, p_scb->peer_addr, &(p_scb->conn_handle),
            bta_ag_mgmt_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]) == PORT_SUCCESS)
    {
        bta_ag_setup_port(p_scb, p_scb->conn_handle);
        APPL_TRACE_DEBUG("bta_ag_rfc_do_open : conn_handle = %d", p_scb->conn_handle);
    }
    /* RFCOMM create connection failed; send ourselves RFCOMM close event */
    else
    {
        bta_ag_sm_execute(p_scb, BTA_AG_RFC_CLOSE_EVT, p_data);
    }
}
/*******************************************************************************
**
** Function         mca_ccb_snd_rsp
**
** Description      This function builds a response and sends it to
**                  the peer.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_snd_rsp(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    tMCA_CCB_MSG *p_msg = (tMCA_CCB_MSG *)p_data;
    BT_HDR  *p_pkt;
    UINT8   *p, *p_start;
    BOOLEAN chk_mdl = FALSE;
    tMCA_DCB    *p_dcb;

    MCA_TRACE_DEBUG ("mca_ccb_snd_rsp cong=%d req=%d", p_ccb->cong, p_msg->op_code);
    /* assume that API functions verified the parameters */
    p_pkt = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
    if (p_pkt)
    {
        p_pkt->offset = L2CAP_MIN_OFFSET;
        p = p_start = (UINT8*)(p_pkt + 1) + L2CAP_MIN_OFFSET;
        *p++ = p_msg->op_code;
        *p++ = p_msg->rsp_code;
        UINT16_TO_BE_STREAM (p, p_msg->mdl_id);
        if (p_msg->op_code == MCA_OP_MDL_CREATE_RSP)
        {
            *p++ = p_msg->param;
            chk_mdl = TRUE;
        }
        else if (p_msg->op_code == MCA_OP_MDL_RECONNECT_RSP)
            chk_mdl = TRUE;

        if (chk_mdl && p_msg->rsp_code == MCA_RSP_SUCCESS)
        {
            p_dcb = mca_dcb_by_hdl(p_msg->dcb_idx);
            BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_MCAP_DATA, p_ccb->sec_mask,
                                 p_ccb->p_rcb->reg.data_psm, BTM_SEC_PROTO_MCA, p_msg->dcb_idx);
            p_ccb->status = MCA_CCB_STAT_PENDING;
            /* set p_tx_req to block API_REQ/API_RSP before DL is up */
            mca_free_buf ((void **)&p_ccb->p_tx_req);
            p_ccb->p_tx_req = p_ccb->p_rx_msg;
            p_ccb->p_rx_msg = NULL;
            p_ccb->p_tx_req->dcb_idx = p_msg->dcb_idx;
        }
        mca_free_buf ((void **)&p_ccb->p_rx_msg);
        p_pkt->len = p - p_start;
        L2CA_DataWrite (p_ccb->lcid, p_pkt);
    }

}
示例#10
0
tHID_STATUS HID_HostSetSecurityLevel( char serv_name[], UINT8 sec_lvl )
{
    if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HID_SEC_CTRL,
                               sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_SEC_CHN))
    {
        HIDH_TRACE_ERROR0 ("Security Registration 1 failed");
        return (HID_ERR_NO_RESOURCES);
    }

    if (!BTM_SetSecurityLevel (TRUE, serv_name, BTM_SEC_SERVICE_HID_SEC_CTRL,
                               sec_lvl, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_SEC_CHN))
    {
        HIDH_TRACE_ERROR0 ("Security Registration 2 failed");
        return (HID_ERR_NO_RESOURCES);
    }

    if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HID_NOSEC_CTRL,
                               BTM_SEC_NONE, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_NOSEC_CHN))
    {
        HIDH_TRACE_ERROR0 ("Security Registration 3 failed");
        return (HID_ERR_NO_RESOURCES);
    }

    if (!BTM_SetSecurityLevel (TRUE, serv_name, BTM_SEC_SERVICE_HID_NOSEC_CTRL,
                               BTM_SEC_NONE, HID_PSM_CONTROL, BTM_SEC_PROTO_HID, HID_NOSEC_CHN))
    {
        HIDH_TRACE_ERROR0 ("Security Registration 4 failed");
        return (HID_ERR_NO_RESOURCES);
    }

    if (!BTM_SetSecurityLevel (TRUE, serv_name, BTM_SEC_SERVICE_HID_INTR,
                               BTM_SEC_NONE, HID_PSM_INTERRUPT, BTM_SEC_PROTO_HID, 0))
    {
        HIDH_TRACE_ERROR0 ("Security Registration 5 failed");
        return (HID_ERR_NO_RESOURCES);
    }

    if (!BTM_SetSecurityLevel (FALSE, serv_name, BTM_SEC_SERVICE_HID_INTR,
                               BTM_SEC_NONE, HID_PSM_INTERRUPT, BTM_SEC_PROTO_HID, 0))
    {
        HIDH_TRACE_ERROR0 ("Security Registration 6 failed");
        return (HID_ERR_NO_RESOURCES);
    }

    return( HID_SUCCESS );
}
示例#11
0
/*******************************************************************************
**
** Function         GAP_ConnOpen
**
** Description      This function is called to open an L2CAP connection.
**
** Parameters:      is_server   - If TRUE, the connection is not created
**                                but put into a "listen" mode waiting for
**                                the remote side to connect.
**
**                  service_id  - Unique service ID from
**                                BTM_SEC_SERVICE_FIRST_EMPTY (6)
**                                to BTM_SEC_MAX_SERVICE_RECORDS (32)
**
**                  p_rem_bda   - Pointer to remote BD Address.
**                                If a server, and we don't care about the
**                                remote BD Address, then NULL should be passed.
**
**                  psm         - the PSM used for the connection
**
**                  p_config    - Optional pointer to configuration structure.
**                                If NULL, the default GAP configuration will
**                                be used.
**
**                  security    - security flags
**                  chan_mode_mask - (GAP_FCR_CHAN_OPT_BASIC, GAP_FCR_CHAN_OPT_ERTM,
**                                    GAP_FCR_CHAN_OPT_STREAM)
**
**                  p_cb        - Pointer to callback function for events.
**
** Returns          handle of the connection if successful, else GAP_INVALID_HANDLE
**
*******************************************************************************/
UINT16 GAP_ConnOpen (char *p_serv_name, UINT8 service_id, BOOLEAN is_server,
                     BD_ADDR p_rem_bda, UINT16 psm, tL2CAP_CFG_INFO *p_cfg,
                     tL2CAP_ERTM_INFO *ertm_info, UINT16 security, UINT8 chan_mode_mask,
                     tGAP_CONN_CALLBACK *p_cb)
{
    tGAP_CCB    *p_ccb;
    UINT16       cid;

    GAP_TRACE_EVENT ("GAP_CONN - Open Request");

    /* Allocate a new CCB. Return if none available. */
    if ((p_ccb = gap_allocate_ccb()) == NULL)
        return (GAP_INVALID_HANDLE);

    /* If caller specified a BD address, save it */
    if (p_rem_bda)
    {
        /* the bd addr is not BT_BD_ANY, then a bd address was specified */
        if (memcmp (p_rem_bda, BT_BD_ANY, BD_ADDR_LEN))
            p_ccb->rem_addr_specified = TRUE;

        memcpy (&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN);
    }
    else if (!is_server)
    {
        /* remore addr is not specified and is not a server -> bad */
        return (GAP_INVALID_HANDLE);
    }

    /* A client MUST have specified a bd addr to connect with */
    if (!p_ccb->rem_addr_specified && !is_server)
    {
        gap_release_ccb (p_ccb);
        GAP_TRACE_ERROR ("GAP ERROR: Client must specify a remote BD ADDR to connect to!");
        return (GAP_INVALID_HANDLE);
    }

    /* Check if configuration was specified */
    if (p_cfg)
        p_ccb->cfg = *p_cfg;

    p_ccb->p_callback     = p_cb;

    /* If originator, use a dynamic PSM */
#if AMP_INCLUDED == TRUE
    if (!is_server)
        gap_cb.conn.reg_info.pAMP_ConnectInd_Cb  = NULL;
    else
        gap_cb.conn.reg_info.pAMP_ConnectInd_Cb  = gap_connect_ind;
#else
    if (!is_server)
        gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = NULL;
    else
        gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = gap_connect_ind;
#endif

    /* Register the PSM with L2CAP */
    if ((p_ccb->psm = L2CA_REGISTER (psm, &gap_cb.conn.reg_info,
                    AMP_AUTOSWITCH_ALLOWED|AMP_USE_AMP_IF_POSSIBLE)) == 0)
    {
        GAP_TRACE_ERROR ("GAP_ConnOpen: Failure registering PSM 0x%04x", psm);
        gap_release_ccb (p_ccb);
        return (GAP_INVALID_HANDLE);
    }

    /* Register with Security Manager for the specific security level */
    p_ccb->service_id = service_id;
    if (!BTM_SetSecurityLevel ((UINT8)!is_server, p_serv_name,
                p_ccb->service_id, security, p_ccb->psm, 0, 0))
    {
        GAP_TRACE_ERROR ("GAP_CONN - Security Error");
        gap_release_ccb (p_ccb);
        return (GAP_INVALID_HANDLE);
    }

    /* Fill in eL2CAP parameter data */
    if( p_ccb->cfg.fcr_present )
    {
        if(ertm_info == NULL) {
            p_ccb->ertm_info.preferred_mode = p_ccb->cfg.fcr.mode;
            p_ccb->ertm_info.user_rx_pool_id = GAP_DATA_POOL_ID;
            p_ccb->ertm_info.user_tx_pool_id = GAP_DATA_POOL_ID;
            p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID;
            p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID;
        } else {
            p_ccb->ertm_info = *ertm_info;
        }
    }

    /* optional FCR channel modes */
    if(ertm_info != NULL) {
        p_ccb->ertm_info.allowed_modes =
            (chan_mode_mask) ? chan_mode_mask : (UINT8)L2CAP_FCR_CHAN_OPT_BASIC;
    }

    if (is_server)
    {
        p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE; /* assume btm/l2cap would handle it */
        p_ccb->con_state = GAP_CCB_STATE_LISTENING;
        return (p_ccb->gap_handle);
    }
    else
    {
        /* We are the originator of this connection */
        p_ccb->con_flags = GAP_CCB_FLAGS_IS_ORIG;

        /* Transition to the next appropriate state, waiting for connection confirm. */
        p_ccb->con_state = GAP_CCB_STATE_CONN_SETUP;

        /* mark security done flag, when security is not required */
        if ((security & (BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT) ) == 0)
            p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;

        /* Check if L2CAP started the connection process */
        if (p_rem_bda && ((cid = L2CA_CONNECT_REQ (p_ccb->psm, p_rem_bda, &p_ccb->ertm_info)) != 0))
        {
            p_ccb->connection_id = cid;
            return (p_ccb->gap_handle);
        }
        else
        {
            gap_release_ccb (p_ccb);
            return (GAP_INVALID_HANDLE);
        }
    }
}
/*******************************************************************************
**
** Function         mca_ccb_hdl_rsp
**
** Description      This function is called when a MCAP response is received from
**                  the peer.  It calls the application callback function with
**                  the results.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_hdl_rsp(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    BT_HDR  *p_pkt = &p_data->hdr;
    UINT8   *p;
    tMCA_CTRL   evt_data;
    BOOLEAN     chk_mdl = FALSE;
    tMCA_DCB    *p_dcb;
    tMCA_RESULT result = MCA_BAD_HANDLE;
    tMCA_TC_TBL *p_tbl;

    if (p_ccb->p_tx_req)
    {
        /* verify that the received response matches the sent request */
        p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
        evt_data.hdr.op_code = *p++;
        if ((evt_data.hdr.op_code == 0) ||
                ((p_ccb->p_tx_req->op_code + 1) == evt_data.hdr.op_code))
        {
            evt_data.rsp.rsp_code = *p++;
            mca_stop_timer(p_ccb);
            BE_STREAM_TO_UINT16 (evt_data.hdr.mdl_id, p);
            if (evt_data.hdr.op_code == MCA_OP_MDL_CREATE_RSP)
            {
                evt_data.create_cfm.cfg = *p++;
                chk_mdl = TRUE;
            }
            else if (evt_data.hdr.op_code == MCA_OP_MDL_RECONNECT_RSP)
                chk_mdl = TRUE;

            if (chk_mdl)
            {
                p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx);
                if (p_dcb && evt_data.rsp.rsp_code == MCA_RSP_SUCCESS)
                {
                    if (evt_data.hdr.mdl_id != p_dcb->mdl_id)
                    {
                        MCA_TRACE_ERROR ("peer's mdl_id=%d != our mdl_id=%d", evt_data.hdr.mdl_id, p_dcb->mdl_id);
                        /* change the response code to be an error */
                        if (evt_data.rsp.rsp_code == MCA_RSP_SUCCESS)
                        {
                            evt_data.rsp.rsp_code = MCA_RSP_BAD_MDL;
                            /* send Abort */
                            p_ccb->status = MCA_CCB_STAT_PENDING;
                            MCA_Abort(mca_ccb_to_hdl(p_ccb));
                        }
                    }
                    else if (p_dcb->p_chnl_cfg)
                    {
                        /* the data channel configuration is known. Proceed with data channel initiation */
                        BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_MCAP_DATA, p_ccb->sec_mask,
                                             p_ccb->data_vpsm, BTM_SEC_PROTO_MCA, p_ccb->p_tx_req->dcb_idx);
                        p_dcb->lcid = mca_l2c_open_req(p_ccb->peer_addr, p_ccb->data_vpsm, p_dcb->p_chnl_cfg);
                        if (p_dcb->lcid)
                        {
                            p_tbl = mca_tc_tbl_dalloc(p_dcb);
                            if (p_tbl)
                            {
                                p_tbl->state = MCA_TC_ST_CONN;
                                p_ccb->status = MCA_CCB_STAT_PENDING;
                                result = MCA_SUCCESS;
                            }
                        }
                    }
                    else
                    {
                        /* mark this MCL as pending and wait for MCA_DataChnlCfg */
                        p_ccb->status = MCA_CCB_STAT_PENDING;
                        result = MCA_SUCCESS;
                    }
                }

                if (result != MCA_SUCCESS && p_dcb)
                {
                    mca_dcb_dealloc(p_dcb, NULL);
                }
            } /* end of chk_mdl */

            if (p_ccb->status != MCA_CCB_STAT_PENDING)
                mca_free_buf ((void **)&p_ccb->p_tx_req);
            mca_ccb_report_event(p_ccb, evt_data.hdr.op_code, &evt_data);
        }
        /* else a bad response is received */
    }
    else
    {
        /* not expecting any response. drop it */
        MCA_TRACE_WARNING ("dropping received rsp (not expecting a response)");
    }
    GKI_freebuf (p_data);
}
示例#13
0
/*******************************************************************************
**
** Function         pan_register_with_sdp
**
** Description
**
** Returns
**
*******************************************************************************/
UINT32 pan_register_with_sdp (UINT16 uuid, UINT8 sec_mask, char *p_name, char *p_desc)
{
    UINT32  sdp_handle;
    UINT16  browse_list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    UINT16  security = 0;
    UINT8   availability;
    UINT32  proto_len = (UINT32)pan_proto_elem_data[1];

    /* Create a record */
    sdp_handle = SDP_CreateRecord ();

    if (sdp_handle == 0)
    {
        PAN_TRACE_ERROR0 ("PAN_SetRole - could not create SDP record");
        return 0;
    }

    /* Service Class ID List */
    SDP_AddServiceClassIdList (sdp_handle, 1, &uuid);

    /* Add protocol element sequence from the constant string */
    SDP_AddAttribute (sdp_handle, ATTR_ID_PROTOCOL_DESC_LIST, DATA_ELE_SEQ_DESC_TYPE,
                      proto_len, (UINT8 *)(pan_proto_elem_data+2));

// btla-specific ++
#if 0
    availability = 0xFF;
    SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_AVAILABILITY, UINT_DESC_TYPE, 1, &availability);
#endif
// btla-specific --

    /* Language base */
    SDP_AddLanguageBaseAttrIDList (sdp_handle, LANG_ID_CODE_ENGLISH, LANG_ID_CHAR_ENCODE_UTF8, LANGUAGE_BASE_ID);

    /* Profile descriptor list */
    SDP_AddProfileDescriptorList (sdp_handle, uuid, PAN_PROFILE_VERSION);

    /* Service Name */
    SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
                        (UINT8) (strlen(p_name) + 1), (UINT8 *)p_name);

    /* Service description */
    SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE,
                        (UINT8) (strlen(p_desc) + 1), (UINT8 *)p_desc);

    /* Security description */
    if (sec_mask)
    {
        UINT16_TO_BE_FIELD(&security, 0x0001);
    }
    SDP_AddAttribute (sdp_handle, ATTR_ID_SECURITY_DESCRIPTION, UINT_DESC_TYPE, 2, (UINT8 *)&security);

#if (defined (PAN_SUPPORTS_ROLE_NAP) && PAN_SUPPORTS_ROLE_NAP == TRUE)
    if (uuid == UUID_SERVCLASS_NAP)
    {
        UINT16  NetAccessType = 0x0005;      /* Ethernet */
        UINT32  NetAccessRate = 0x0001312D0; /* 10Mb/sec */
        UINT8   array[10], *p;

        /* Net access type. */
        p = array;
        UINT16_TO_BE_STREAM (p, NetAccessType);
        SDP_AddAttribute (sdp_handle, ATTR_ID_NET_ACCESS_TYPE, UINT_DESC_TYPE, 2, array);

        /* Net access rate. */
        p = array;
        UINT32_TO_BE_STREAM (p, NetAccessRate);
        SDP_AddAttribute (sdp_handle, ATTR_ID_MAX_NET_ACCESS_RATE, UINT_DESC_TYPE, 4, array);

        /* Register with Security Manager for the specific security level */
        if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_NAP,
                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_NAP))
         || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_NAP,
                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_NAP)))
        {
            PAN_TRACE_ERROR0 ("PAN Security Registration failed for PANU");
        }
    }
#endif
#if (defined (PAN_SUPPORTS_ROLE_GN) && PAN_SUPPORTS_ROLE_GN == TRUE)
    if (uuid == UUID_SERVCLASS_GN)
    {
        if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_GN,
                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_GN))
         || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_GN,
                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_GN)))
        {
            PAN_TRACE_ERROR0 ("PAN Security Registration failed for GN");
        }
    }
#endif
#if (defined (PAN_SUPPORTS_ROLE_PANU) && PAN_SUPPORTS_ROLE_PANU == TRUE)
    if (uuid == UUID_SERVCLASS_PANU)
    {
        if ((!BTM_SetSecurityLevel (TRUE, p_name, BTM_SEC_SERVICE_BNEP_PANU,
                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_PANU))
         || (!BTM_SetSecurityLevel (FALSE, p_name, BTM_SEC_SERVICE_BNEP_PANU,
                                    sec_mask, BT_PSM_BNEP, BTM_SEC_PROTO_BNEP, UUID_SERVCLASS_PANU)))
        {
            PAN_TRACE_ERROR0 ("PAN Security Registration failed for PANU");
        }
    }
#endif

    /* Make the service browsable */
    SDP_AddUuidSequence (sdp_handle,  ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_list);


    return sdp_handle;
}