Ejemplo n.º 1
0
/*******************************************************************************
**
** Function         avdt_ad_open_req
**
** Description      This function is called by a CCB or SCB to open a transport
**                  channel.  This function allocates and initializes a
**                  transport channel table entry.  The channel can be opened
**                  in two roles:  as an initiator or acceptor.  When opened
**                  as an initiator the function will start an L2CAP connection.
**                  When opened as an acceptor the function simply configures
**                  the table entry to listen for an incoming channel.
**
**
** Returns          Nothing.
**
*******************************************************************************/
void avdt_ad_open_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, UINT8 role)
{
    tAVDT_TC_TBL    *p_tbl;
    UINT16          lcid;

    if ((p_tbl = avdt_ad_tc_tbl_alloc(p_ccb)) == NULL) {
        AVDT_TRACE_ERROR("avdt_ad_open_req: Cannot allocate p_tbl");
        return;
    }


    p_tbl->tcid = avdt_ad_type_to_tcid(type, p_scb);
    AVDT_TRACE_DEBUG("avdt_ad_open_req: type: %d, role: %d, tcid:%d\n",
                     type, role, p_tbl->tcid);

    if (type == AVDT_CHAN_SIG) {
        /* if signaling, get mtu from registration control block */
        p_tbl->my_mtu = avdt_cb.rcb.ctrl_mtu;
        p_tbl->my_flush_to = L2CAP_DEFAULT_FLUSH_TO;
    } else {
        /* otherwise get mtu from scb */
        p_tbl->my_mtu = p_scb->cs.mtu;
        p_tbl->my_flush_to = p_scb->cs.flush_to;

        /* also set scb_hdl in rt_tbl */
        avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].scb_hdl = avdt_scb_to_hdl(p_scb);
        AVDT_TRACE_DEBUG("avdt_cb.ad.rt_tbl[%d][%d].scb_hdl = %d\n",
                         avdt_ccb_to_idx(p_ccb), p_tbl->tcid,
                         avdt_scb_to_hdl(p_scb));
    }

    /* if we're acceptor, we're done; just sit back and listen */
    if (role == AVDT_ACP) {
        p_tbl->state = AVDT_AD_ST_ACP;
    }
    /* else we're inititator, start the L2CAP connection */
    else {
        p_tbl->state = AVDT_AD_ST_CONN;

        /* call l2cap connect req */
        if ((lcid = L2CA_ConnectReq(AVDT_PSM, p_ccb->peer_addr)) != 0) {
            /* if connect req ok, store tcid in lcid table  */
            avdt_cb.ad.lcid_tbl[lcid - L2CAP_BASE_APPL_CID] = avdt_ad_tc_tbl_to_idx(p_tbl);
            AVDT_TRACE_DEBUG("avdt_cb.ad.lcid_tbl[%d] = %d\n",
                             (lcid - L2CAP_BASE_APPL_CID), avdt_ad_tc_tbl_to_idx(p_tbl));

            avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].lcid = lcid;
            AVDT_TRACE_DEBUG("avdt_cb.ad.rt_tbl[%d][%d].lcid = 0x%x\n",
                             avdt_ccb_to_idx(p_ccb), p_tbl->tcid,
                             lcid);
        } else {
            /* if connect req failed, call avdt_ad_tc_close_ind() */
            avdt_ad_tc_close_ind(p_tbl, 0);
        }
    }
}
Ejemplo n.º 2
0
/*******************************************************************************
**
** Function         avdt_scb_event
**
** Description      State machine event handling function for scb
**
**
** Returns          Nothing.
**
*******************************************************************************/
void avdt_scb_event(tAVDT_SCB *p_scb, UINT8 event, tAVDT_SCB_EVT *p_data)
{
    tAVDT_SCB_ST_TBL    state_table;
    UINT8               action;
    int                 i;

#if AVDT_DEBUG == TRUE
    AVDT_TRACE_EVENT("SCB hdl=%d event=%d/%s state=%s\n", avdt_scb_to_hdl(p_scb), event, avdt_scb_evt_str[event], avdt_scb_st_str[p_scb->state]);
#endif
    /* set current event */
    p_scb->curr_evt = event;

    /* look up the state table for the current state */
    state_table = avdt_scb_st_tbl[p_scb->state];

    /* set next state */
    if (p_scb->state != state_table[event][AVDT_SCB_NEXT_STATE]) {
        p_scb->state = state_table[event][AVDT_SCB_NEXT_STATE];
    }

    /* execute action functions */
    for (i = 0; i < AVDT_SCB_ACTIONS; i++) {
        if ((action = state_table[event][i]) != AVDT_SCB_IGNORE) {
            (*avdt_cb.p_scb_act[action])(p_scb, p_data);
        } else {
            break;
        }
    }
}
Ejemplo n.º 3
0
/*******************************************************************************
**
** Function         avdt_scb_dealloc
**
** Description      Deallocate a stream control block.
**
**
** Returns          void.
**
*******************************************************************************/
void avdt_scb_dealloc(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
{
    UNUSED(p_data);

    AVDT_TRACE_DEBUG("avdt_scb_dealloc hdl=%d\n", avdt_scb_to_hdl(p_scb));
    btu_stop_timer(&p_scb->timer_entry);

#if AVDT_MULTIPLEXING == TRUE
    /* free fragments we're holding, if any; it shouldn't happen */
    fixed_queue_free(p_scb->frag_q, osi_free_func);
#endif

    memset(p_scb, 0, sizeof(tAVDT_SCB));
}
Ejemplo n.º 4
0
/*******************************************************************************
**
** Function         avdt_ad_type_to_tcid
**
** Description      Derives the TCID from the channel type and SCB.
**
**
** Returns          TCID value.
**
*******************************************************************************/
UINT8 avdt_ad_type_to_tcid(UINT8 type, tAVDT_SCB *p_scb)
{
    UINT8 scb_idx;

    if (type == AVDT_CHAN_SIG) {
        return 0;
    } else {
        scb_idx = avdt_scb_to_hdl(p_scb) - 1;
        /*
        AVDT_TRACE_DEBUG("type: %d, tcid: %d", type, ((scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type));
        */
        return ((scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type);
    }
}
Ejemplo n.º 5
0
/*******************************************************************************
**
** Function         AVDT_CreateStream
**
** Description      Create a stream endpoint.  After a stream endpoint is
**                  created an application can initiate a connection between
**                  this endpoint and an endpoint on a peer device.  In
**                  addition, a peer device can discover, get the capabilities,
**                  and connect to this endpoint.
**
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
UINT16 AVDT_CreateStream(UINT8 *p_handle, tAVDT_CS *p_cs)
{
    UINT16      result = AVDT_SUCCESS;
    tAVDT_SCB   *p_scb;

    /* Verify parameters; if invalid, return failure */
    if (((p_cs->cfg.psc_mask & (~AVDT_PSC)) != 0) || (p_cs->p_ctrl_cback == NULL)) {
        result = AVDT_BAD_PARAMS;
    }
    /* Allocate scb; if no scbs, return failure */
    else if ((p_scb = avdt_scb_alloc(p_cs)) == NULL) {
        result = AVDT_NO_RESOURCES;
    } else {
        *p_handle = avdt_scb_to_hdl(p_scb);
    }
    return result;
}
Ejemplo n.º 6
0
/*******************************************************************************
**
** Function         avdt_scb_dealloc
**
** Description      Deallocate a stream control block.
**
**
** Returns          void.
**
*******************************************************************************/
void avdt_scb_dealloc(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
{
#if AVDT_MULTIPLEXING == TRUE
    void *p_buf;
#endif
    UNUSED(p_data);

    AVDT_TRACE_DEBUG("avdt_scb_dealloc hdl=%d", avdt_scb_to_hdl(p_scb));
    btu_stop_timer(&p_scb->timer_entry);

#if AVDT_MULTIPLEXING == TRUE
    /* free fragments we're holding, if any; it shouldn't happen */
    while ((p_buf = GKI_dequeue (&p_scb->frag_q)) != NULL)
        GKI_freebuf(p_buf);
#endif

    memset(p_scb, 0, sizeof(tAVDT_SCB));
}