Beispiel #1
0
/*******************************************************************************
**
** Function         AVDT_WriteDataReq
**
** Description      Send a media packet to the peer device.  The stream must
**                  be started before this function is called.  Also, this
**                  function can only be called if the stream is a SRC.
**
**                  When AVDTP has sent the media packet and is ready for the
**                  next packet, an AVDT_WRITE_CFM_EVT is sent to the
**                  application via the control callback.  The application must
**                  wait for the AVDT_WRITE_CFM_EVT before it makes the next
**                  call to AVDT_WriteDataReq().  If the applications calls
**                  AVDT_WriteDataReq() before it receives the event the packet
**                  will not be sent.  The application may make its first call
**                  to AVDT_WriteDataReq() after it receives an
**                  AVDT_START_CFM_EVT or AVDT_START_IND_EVT.
**
** Returns          AVDT_SUCCESS if successful, otherwise error.
**
*******************************************************************************/
extern UINT16 AVDT_WriteDataReq(UINT8 handle, UINT8 *p_data, UINT32 data_len,
                                UINT32 time_stamp, UINT8 m_pt, UINT8 marker)
{

    tAVDT_SCB       *p_scb;
    tAVDT_SCB_EVT   evt;
    UINT16          result = AVDT_SUCCESS;

    do {
        /* check length of media frame */
        if (data_len > AVDT_MAX_MEDIA_SIZE) {
            result = AVDT_BAD_PARAMS;
            break;
        }
        /* map handle to scb */
        if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) {
            result = AVDT_BAD_HANDLE;
            break;
        }
        AVDT_TRACE_WARNING("mux_tsid_media:%d\n", p_scb->curr_cfg.mux_tsid_media);

        if (p_scb->p_pkt != NULL
                || p_scb->p_ccb == NULL
                || !GKI_queue_is_empty(&p_scb->frag_q)
                || p_scb->frag_off != 0
                || p_scb->curr_cfg.mux_tsid_media == 0) {
            result = AVDT_ERR_BAD_STATE;
            AVDT_TRACE_WARNING("p_scb->p_pkt=%p, p_scb->p_ccb=%p, IsQueueEmpty=%x, p_scb->frag_off=%x\n",
                               p_scb->p_pkt, p_scb->p_ccb, GKI_queue_is_empty(&p_scb->frag_q), p_scb->frag_off);
            break;
        }
        evt.apiwrite.p_buf = 0; /* it will indicate using of fragments queue frag_q */
        /* create queue of media fragments */
        GKI_init_q (&evt.apiwrite.frag_q);

        /* compose fragments from media payload and put fragments into gueue */
        avdt_scb_queue_frags(p_scb, &p_data, &data_len, &evt.apiwrite.frag_q);

        if (GKI_queue_is_empty(&evt.apiwrite.frag_q)) {
            AVDT_TRACE_WARNING("AVDT_WriteDataReq out of GKI buffers");
            result = AVDT_ERR_RESOURCE;
            break;
        }
        evt.apiwrite.data_len = data_len;
        evt.apiwrite.p_data = p_data;

        /* process the fragments queue */
        evt.apiwrite.time_stamp = time_stamp;
        evt.apiwrite.m_pt = m_pt | (marker << 7);
        avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt);
    } while (0);

#if (BT_USE_TRACES == TRUE)
    if (result != AVDT_SUCCESS) {
        AVDT_TRACE_WARNING("*** AVDT_WriteDataReq failed result=%d\n", result);
    }
#endif
    return result;
}
Beispiel #2
0
/*******************************************************************************
**
** Function         avdt_ccb_snd_msg
**
** Description
**
**
** Returns          void.
**
*******************************************************************************/
void avdt_ccb_snd_msg(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
{
    BT_HDR      *p_msg;
    UNUSED(p_data);

    /* if not congested */
    if (!p_ccb->cong)
    {
        /* are we sending a fragmented message? continue sending fragment */
        if (p_ccb->p_curr_msg != NULL)
        {
            avdt_msg_send(p_ccb, NULL);
        }
        /* do we have responses to send?  send them */
        else if (!GKI_queue_is_empty(&p_ccb->rsp_q))
        {
            while ((p_msg = (BT_HDR *) GKI_dequeue(&p_ccb->rsp_q)) != NULL)
            {
                if (avdt_msg_send(p_ccb, p_msg) == TRUE)
                {
                    /* break out if congested */
                    break;
                }
            }
        }

        /* do we have commands to send?  send next command */
        avdt_ccb_snd_cmd(p_ccb, NULL);
    }
}
Beispiel #3
0
/*******************************************************************************
**
** Function         gatt_sec_check_complete
**
** Description      security check complete and proceed to data sending action.
**
** Returns          void.
**
*******************************************************************************/
void gatt_sec_check_complete(BOOLEAN sec_check_ok, tGATT_CLCB   *p_clcb, UINT8 sec_act)
{
    if (p_clcb && p_clcb->p_tcb && GKI_queue_is_empty(&p_clcb->p_tcb->pending_enc_clcb)) {
        gatt_set_sec_act(p_clcb->p_tcb, GATT_SEC_NONE);
    }
#if (GATTC_INCLUDED == TRUE)
    if (!sec_check_ok) {
        gatt_end_operation(p_clcb, GATT_AUTH_FAIL, NULL);
    } else if (p_clcb->operation == GATTC_OPTYPE_WRITE) {
        gatt_act_write(p_clcb, sec_act);
    } else if (p_clcb->operation == GATTC_OPTYPE_READ) {
        gatt_act_read(p_clcb, p_clcb->counter);
    }
#endif  ///GATTC_INCLUDED == TRUE
}
/*******************************************************************************
**
** Function         btm_send_pending_direct_conn
**
** Description      This function send the pending direct connection request in queue
**
** Returns          TRUE if started, FALSE otherwise
**
*******************************************************************************/
BOOLEAN btm_send_pending_direct_conn(void)
{
    tBTM_BLE_CONN_REQ *p_req;
    BOOLEAN     rt = FALSE;

    if (!GKI_queue_is_empty(&btm_cb.ble_ctr_cb.conn_pending_q))
    {
        p_req = (tBTM_BLE_CONN_REQ*)GKI_dequeue (&btm_cb.ble_ctr_cb.conn_pending_q);

        rt = l2cble_init_direct_conn((tL2C_LCB *)(p_req->p_param));

        GKI_freebuf((void *)p_req);
    }

    return rt;
}
/*******************************************************************************
**
** Function         bta_gattc_srcb_alloc
**
** Description      allocate server cache control block
**
** Returns          pointer to the server cache.
**
*******************************************************************************/
tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda)
{
    tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0],
                             *p_recycle = NULL;
    BOOLEAN         found = FALSE;
    UINT8           i;

    for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_tcb ++)
    {
        if (!p_tcb->in_use)
        {
            found = TRUE;
            break;
        }
        else if (!p_tcb->connected)
        {
            p_recycle = p_tcb;
        }
    }

    /* if not found, try to recycle one known device */
    if (!found && !p_recycle)
        p_tcb = NULL;
    else if (!found && p_recycle)
        p_tcb = p_recycle;

    if (p_tcb != NULL)
    {
        while (!GKI_queue_is_empty(&p_tcb->cache_buffer))
            GKI_freebuf (GKI_dequeue (&p_tcb->cache_buffer));

        utl_freebuf((void **)&p_tcb->p_srvc_list);
        memset(p_tcb, 0 , sizeof(tBTA_GATTC_SERV));

        p_tcb->in_use = TRUE;
        bdcpy(p_tcb->server_bda, bda);
    }
    return p_tcb;
}
static inline void free_gki_que(BUFFER_Q* q)
{
    while(!GKI_queue_is_empty(q))
           GKI_freebuf(GKI_dequeue(q));
}
Beispiel #7
0
/*******************************************************************************
**
** Function         rfc_port_sm_opened
**
** Description      This function handles events for the port in the OPENED
**                  state
**
** Returns          void
**
*******************************************************************************/
void rfc_port_sm_opened (tPORT *p_port, UINT16 event, void *p_data)
{
    switch (event)
    {
    case RFC_EVENT_OPEN:
        RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
        return;

    case RFC_EVENT_CLOSE:
        rfc_port_timer_start (p_port, RFC_DISC_TIMEOUT);
        rfc_send_disc (p_port->rfc.p_mcb, p_port->dlci);
        p_port->rfc.expected_rsp = 0;
        p_port->rfc.state = RFC_STATE_DISC_WAIT_UA;
        return;

    case RFC_EVENT_CLEAR:
        rfc_port_closed (p_port);
        return;

    case RFC_EVENT_DATA:
        /* Send credits in the frame.  Pass them in the layer specific member of the hdr. */
        /* There might be an initial case when we reduced rx_max and credit_rx is still */
        /* bigger.  Make sure that we do not send 255 */
        if ((p_port->rfc.p_mcb->flow == PORT_FC_CREDIT)
         && (((BT_HDR *)p_data)->len < p_port->peer_mtu)
         && (!p_port->rx.user_fc)
         && (p_port->credit_rx_max > p_port->credit_rx))
        {
            ((BT_HDR *)p_data)->layer_specific = (UINT8) (p_port->credit_rx_max - p_port->credit_rx);
            p_port->credit_rx = p_port->credit_rx_max;
        }
        else
        {
            ((BT_HDR *)p_data)->layer_specific = 0;
        }
        rfc_send_buf_uih (p_port->rfc.p_mcb, p_port->dlci, (BT_HDR *)p_data);
        rfc_dec_credit (p_port);
        return;

    case RFC_EVENT_UA:
        return;

    case RFC_EVENT_SABME:
        rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
        return;

    case RFC_EVENT_DM:
        PORT_DlcReleaseInd (p_port->rfc.p_mcb, p_port->dlci);
        rfc_port_closed (p_port);
        return;

    case RFC_EVENT_DISC:
        p_port->rfc.state = RFC_STATE_CLOSED;
        rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
        if(!GKI_queue_is_empty(&p_port->rx.queue))
        {
            /* give a chance to upper stack to close port properly */
            RFCOMM_TRACE_DEBUG("port queue is not empty");
            rfc_port_timer_start (p_port, RFC_DISC_TIMEOUT);
        }
        else
            PORT_DlcReleaseInd (p_port->rfc.p_mcb, p_port->dlci);
        return;

    case RFC_EVENT_UIH:
        rfc_port_uplink_data (p_port, (BT_HDR *)p_data);
        return;

    case RFC_EVENT_TIMEOUT:
        Port_TimeOutCloseMux( p_port->rfc.p_mcb ) ;
        RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
        return;
    }
    RFCOMM_TRACE_WARNING ("Port state opened Event ignored %d", event);
}