/*******************************************************************************
**
** Function         mca_dcb_close_by_mdl_id
**
** Description      This function finds the DCB for a mdl_id and
**                  disconnect the mdl
**
** Returns          void
**
*******************************************************************************/
void mca_dcb_close_by_mdl_id(tMCA_CCB*p_ccb, UINT16 mdl_id)
{
    tMCA_DCB *p_dcb;
    unsigned int i;

    MCA_TRACE_DEBUG("mca_dcb_close_by_mdl_id mdl_id=%d", mdl_id);
    i = mca_ccb_to_hdl(p_ccb)-1;
    if( i*MCA_NUM_MDLS < MCA_NUM_DCBS)
        p_dcb = &mca_cb.dcb[i*MCA_NUM_MDLS];
    else
    {
        MCA_TRACE_WARNING("dcb index out of range");
        return;
    }
    for (i=0; i<MCA_NUM_MDLS; i++, p_dcb++)
    {
        if (p_dcb->state)
        {
            if (p_dcb->mdl_id == mdl_id)
            {
                mca_dcb_event(p_dcb, MCA_DCB_API_CLOSE_EVT, NULL);
                break;
            }
            else if (mdl_id == MCA_ALL_MDL_ID)
            {
                mca_dcb_event(p_dcb, MCA_DCB_API_CLOSE_EVT, NULL);
            }
        }
    }
}
/*******************************************************************************
**
** Function         mca_ccb_snd_req
**
** Description      This function builds a request and sends it to the peer.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_snd_req(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 is_abort = FALSE;
    tMCA_DCB *p_dcb;

    MCA_TRACE_DEBUG ("mca_ccb_snd_req cong=%d req=%d", p_ccb->cong, p_msg->op_code);
    /* check for abort request */
    if ((p_ccb->status == MCA_CCB_STAT_PENDING) && (p_msg->op_code == MCA_OP_MDL_ABORT_REQ))
    {
        p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx);
        /* the Abort API does not have the associated mdl_id.
         * Get the mdl_id in dcb to compose the request */
        if (p_dcb)
        {
            p_msg->mdl_id = p_dcb->mdl_id;
            mca_dcb_event(p_dcb, MCA_DCB_API_CLOSE_EVT, NULL);
        }
        mca_free_buf ((void **)&p_ccb->p_tx_req);
        p_ccb->status = MCA_CCB_STAT_NORM;
        is_abort = TRUE;
    }

    /* no pending outgoing messages or it's an abort request for a pending data channel */
    if ((!p_ccb->p_tx_req) || is_abort)
    {
        p_ccb->p_tx_req = p_msg;
        if (!p_ccb->cong)
        {
            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;
                UINT16_TO_BE_STREAM (p, p_msg->mdl_id);
                if (p_msg->op_code == MCA_OP_MDL_CREATE_REQ)
                {
                    *p++ = p_msg->mdep_id;
                    *p++ = p_msg->param;
                }
                p_msg->hdr.layer_specific = TRUE;   /* mark this message as sent */
                p_pkt->len = p - p_start;
                L2CA_DataWrite (p_ccb->lcid, p_pkt);
                p_ccb->timer_entry.param = (TIMER_PARAM_TYPE) p_ccb;
                btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_MCA_CCB_RSP, p_ccb->p_rcb->reg.rsp_tout);
            }
        }
        /* else the L2CAP channel is congested. keep the message to be sent later */
    }
    else
    {
        MCA_TRACE_WARNING ("dropping api req");
        GKI_freebuf (p_data);
    }
}
Esempio n. 3
0
/*******************************************************************************
**
** Function         mca_dcb_do_disconn
**
** Description      This function closes a data channel.
**
** Returns          void.
**
*******************************************************************************/
void mca_dcb_do_disconn (tMCA_DCB *p_dcb, tMCA_DCB_EVT *p_data)
{
    tMCA_CLOSE  close;
    UNUSED(p_data);

    if ((p_dcb->lcid == 0) || (L2CA_DisconnectReq(p_dcb->lcid) == FALSE))
    {
        close.param  = MCA_INT;
        close.reason = L2CAP_DISC_OK;
        close.lcid   = 0;
        mca_dcb_event(p_dcb, MCA_DCB_TC_CLOSE_EVT, (tMCA_DCB_EVT *) &close);
    }
}