Beispiel #1
0
/*******************************************************************************
**
**  Function        l2c_ucd_delete_sec_pending_q
**
** Description      discard all of UCD packets in security pending queue
**
** Returns          None
**
*******************************************************************************/
void l2c_ucd_delete_sec_pending_q(tL2C_LCB  *p_lcb)
{
    /* clean up any security pending UCD */
    while (p_lcb->ucd_out_sec_pending_q.p_first) {
        osi_free(fixed_queue_try_dequeue(p_lcb->ucd_out_sec_pending_q));
	}
    fixed_queue_free(p_lcb->ucd_out_sec_pending_q, NULL);
    p_lcb->ucd_out_sec_pending_q = NULL;

    while (! fixed_queue_is_empty(p_lcb->ucd_in_sec_pending_q)) {
        osi_free(fixed_queue_try_dequeue(p_lcb->ucd_in_sec_pending_q));
	}
    fixed_queue_free(p_lcb->ucd_in_sec_pending_q);
    p_lcb->ucd_in_sec_pending_q = NULL;
}
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 (!fixed_queue_is_empty(p_ccb->rsp_q)) {
            while ((p_msg = (BT_HDR *)fixed_queue_try_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         avdt_ccb_clear_cmds
**
** Description      This function is called when the signaling channel is
**                  closed to clean up any pending commands.  For each pending
**                  command in the command queue, it frees the command and
**                  calls the application callback function indicating failure.
**                  Certain CCB variables are also initialized.
**
**
** Returns          void.
**
*******************************************************************************/
void avdt_ccb_clear_cmds(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
{
    int             i;
    tAVDT_SCB       *p_scb = &avdt_cb.scb[0];
    UINT8           err_code = AVDT_ERR_CONNECT;
    UNUSED(p_data);

    /* clear the ccb */
    avdt_ccb_clear_ccb(p_ccb);

    /* clear out command queue; this is a little tricky here; we need
    ** to handle the case where there is a command on deck in p_curr_cmd,
    ** plus we need to clear out the queue
    */
    do {
        /* we know p_curr_cmd = NULL after this */
        avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code);

        /* set up next message */
        p_ccb->p_curr_cmd = (BT_HDR *) fixed_queue_try_dequeue(p_ccb->cmd_q);

    } while (p_ccb->p_curr_cmd != NULL);

    /* send a CC_CLOSE_EVT any active scbs associated with this ccb */
    for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++) {
        if ((p_scb->allocated) && (p_scb->p_ccb == p_ccb)) {
            avdt_scb_event(p_scb, AVDT_SCB_CC_CLOSE_EVT, NULL);
        }
    }
}
Beispiel #4
0
/*******************************************************************************
**
** Function         avdt_ccb_clear_ccb
**
** Description      This function clears out certain buffers, queues, and
**                  other data elements of a ccb.
**
**
** Returns          void.
**
*******************************************************************************/
static void avdt_ccb_clear_ccb(tAVDT_CCB *p_ccb)
{
    BT_HDR          *p_buf;

    /* clear certain ccb variables */
    p_ccb->cong = FALSE;
    p_ccb->ret_count = 0;

    /* free message being fragmented */
    if (p_ccb->p_curr_msg != NULL) {
        osi_free(p_ccb->p_curr_msg);
        p_ccb->p_curr_msg = NULL;
    }

    /* free message being reassembled */
    if (p_ccb->p_rx_msg != NULL) {
        osi_free(p_ccb->p_rx_msg);
        p_ccb->p_rx_msg = NULL;
    }

    /* clear out response queue */
    while ((p_buf = (BT_HDR *) fixed_queue_try_dequeue(p_ccb->rsp_q)) != NULL) {
        osi_free(p_buf);
    }
}
Beispiel #5
0
/*******************************************************************************
**
**  Function        l2c_ucd_send_pending_out_sec_q
**
**  Description     dequeue UCD packet from security pending queue and
**                  enqueue it into CCB
**
**  Return          None
**
*******************************************************************************/
void l2c_ucd_send_pending_out_sec_q(tL2C_CCB  *p_ccb)
{
    BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_out_sec_pending_q);

    if (p_buf != NULL) {
        l2c_enqueue_peer_data (p_ccb, (BT_HDR *)p_buf);
        l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL);
    }
}
static void *run_thread(void *start_arg) {
  assert(start_arg != NULL);

  struct start_arg *start = start_arg;
  thread_t *thread = start->thread;

  assert(thread != NULL);

  if (prctl(PR_SET_NAME, (unsigned long)thread->name) == -1) {
    ALOGE("%s unable to set thread name: %s", __func__, strerror(errno));
    start->error = errno;
    semaphore_post(start->start_sem);
    return NULL;
  }
  thread->tid = gettid();

  semaphore_post(start->start_sem);

  reactor_object_t work_queue_object;
  work_queue_object.context = thread->work_queue;
  work_queue_object.fd = fixed_queue_get_dequeue_fd(thread->work_queue);
  work_queue_object.interest = REACTOR_INTEREST_READ;
  work_queue_object.read_ready = work_queue_read_cb;

  reactor_register(thread->reactor, &work_queue_object);
  reactor_start(thread->reactor);

  // Make sure we dispatch all queued work items before exiting the thread.
  // This allows a caller to safely tear down by enqueuing a teardown
  // work item and then joining the thread.
  size_t count = 0;
  work_item_t *item = fixed_queue_try_dequeue(thread->work_queue);
  while (item && count <= WORK_QUEUE_CAPACITY) {
    item->func(item->context);
    free(item);
    item = fixed_queue_try_dequeue(thread->work_queue);
    ++count;
  }

  if (count > WORK_QUEUE_CAPACITY)
    ALOGD("%s growing event queue on shutdown.", __func__);

  return NULL;
}
Beispiel #7
0
/*******************************************************************************
**
**  Function        l2c_ucd_discard_pending_out_sec_q
**
**  Description     dequeue UCD packet from security pending queue and
**                  discard it.
**
**  Return          None
**
*******************************************************************************/
void l2c_ucd_discard_pending_out_sec_q(tL2C_CCB  *p_ccb)
{
    BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_out_sec_pending_q);

    /* we may need to report to application */

    if (p_buf) {
        osi_free (p_buf);
    }
}
static void *run_thread(void *start_arg) {
  assert(start_arg != NULL);

  struct start_arg *start = start_arg;
  thread_t *thread = start->thread;

  assert(thread != NULL);

  if (prctl(PR_SET_NAME, (unsigned long)thread->name) == -1) {
    LOG_ERROR("%s unable to set thread name: %s", __func__, strerror(errno));
    start->error = errno;
    semaphore_post(start->start_sem);
    return NULL;
  }
  thread->tid = gettid();

  semaphore_post(start->start_sem);

  int fd = fixed_queue_get_dequeue_fd(thread->work_queue);
  void *context = thread->work_queue;

  reactor_object_t *work_queue_object = reactor_register(thread->reactor, fd, context, work_queue_read_cb, NULL);
  reactor_start(thread->reactor);
  reactor_unregister(work_queue_object);

  // Make sure we dispatch all queued work items before exiting the thread.
  // This allows a caller to safely tear down by enqueuing a teardown
  // work item and then joining the thread.
  size_t count = 0;
  work_item_t *item = fixed_queue_try_dequeue(thread->work_queue);
  while (item && count <= fixed_queue_capacity(thread->work_queue)) {
    item->func(item->context);
    osi_free(item);
    item = fixed_queue_try_dequeue(thread->work_queue);
    ++count;
  }

  if (count > fixed_queue_capacity(thread->work_queue))
    LOG_DEBUG("%s growing event queue on shutdown.", __func__);

  return NULL;
}
Beispiel #9
0
/*******************************************************************************
**
**  Function        l2c_ucd_check_pending_in_sec_q
**
**  Description     check incoming security
**
**  Return          TRUE if any UCD packet for security
**
*******************************************************************************/
BOOLEAN l2c_ucd_check_pending_in_sec_q(tL2C_CCB  *p_ccb)
{
    BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q);

    if (p_buf != NULL) {
        UINT16 psm;
        UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
        STREAM_TO_UINT16(psm, p)

        p_ccb->chnl_state = CST_TERM_W4_SEC_COMP;
        btm_sec_l2cap_access_req (p_ccb->p_lcb->remote_bd_addr, psm,
                                  p_ccb->p_lcb->handle, CONNLESS_TERM, &l2c_link_sec_comp, p_ccb);

        return (TRUE);
    }
    return (FALSE);
}
Beispiel #10
0
/*******************************************************************************
**
** Function         avdt_ccb_snd_cmd
**
** Description      This function is called the send the next command,
**                  if any, in the command queue.
**
**
** Returns          void.
**
*******************************************************************************/
void avdt_ccb_snd_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
{
    BT_HDR  *p_msg;
    UNUSED(p_data);

    /* do we have commands to send?  send next command;  make sure we're clear;
    ** not congested, not sending fragment, not waiting for response
    */
    if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd == NULL)) {
        if ((p_msg = (BT_HDR *) fixed_queue_try_dequeue(p_ccb->cmd_q)) != NULL) {
            /* make a copy of buffer in p_curr_cmd */
            if ((p_ccb->p_curr_cmd = (BT_HDR *) osi_malloc(AVDT_CMD_BUF_SIZE)) != NULL) {
                memcpy(p_ccb->p_curr_cmd, p_msg, (sizeof(BT_HDR) + p_msg->offset + p_msg->len));

                avdt_msg_send(p_ccb, p_msg);
            }
        }
    }
}
Beispiel #11
0
/*******************************************************************************
**
** Function         port_rfc_send_tx_data
**
** Description      This function is when forward data can be sent to the peer
**
*******************************************************************************/
UINT32 port_rfc_send_tx_data (tPORT *p_port)
{
    UINT32 events = 0;
    BT_HDR *p_buf;

    /* if there is data to be sent */
    if (p_port->tx.queue_size > 0) {
        /* while the rfcomm peer is not flow controlling us, and peer is ready */
        while (!p_port->tx.peer_fc && p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready) {
            /* get data from tx queue and send it */
            osi_mutex_global_lock();

            if ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_port->tx.queue)) != NULL) {
                p_port->tx.queue_size -= p_buf->len;

                osi_mutex_global_unlock();

                RFCOMM_TRACE_DEBUG ("Sending RFCOMM_DataReq tx.queue_size=%d", p_port->tx.queue_size);

                RFCOMM_DataReq (p_port->rfc.p_mcb, p_port->dlci, p_buf);

                events |= PORT_EV_TXCHAR;

                if (p_port->tx.queue_size == 0) {
                    events |= PORT_EV_TXEMPTY;
                    break;
                }
            }
            /* queue is empty-- all data sent */
            else {
                osi_mutex_global_unlock();

                events |= PORT_EV_TXEMPTY;
                break;
            }
        }
        /* If we flow controlled user based on the queue size enable data again */
        events |= port_flow_control_user (p_port);
    }
    return (events & p_port->ev_mask);
}
Beispiel #12
0
/*******************************************************************************
**
** Function         rfc_check_send_cmd
**
** Description      This function is called to send an RFCOMM command message
**                  or to handle the RFCOMM command message queue.
**
** Returns          void
**
*******************************************************************************/
void rfc_check_send_cmd(tRFC_MCB *p_mcb, BT_HDR *p_buf)
{
    BT_HDR  *p;

    /* if passed a buffer queue it */
    if (p_buf != NULL) {
        if (p_mcb->cmd_q == NULL) {
            RFCOMM_TRACE_ERROR("%s: empty queue: p_mcb = %p p_mcb->lcid = %u cached p_mcb = %p",
                               __func__, p_mcb, p_mcb->lcid,
                               rfc_find_lcid_mcb(p_mcb->lcid));
        }
        fixed_queue_enqueue(p_mcb->cmd_q, p_buf);
    }

    /* handle queue if L2CAP not congested */
    while (p_mcb->l2cap_congested == FALSE) {
        if ((p = (BT_HDR *)fixed_queue_try_dequeue(p_mcb->cmd_q)) == NULL) {
            break;
        }


        L2CA_DataWrite (p_mcb->lcid, p);
    }
}
Beispiel #13
0
static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
{
    tBT_SBC_HDR *p_msg;

    if (fixed_queue_is_empty(btc_aa_snk_cb.RxSbcQ)) {
        APPL_TRACE_DEBUG("  QUE  EMPTY ");
    } else {
        if (btc_aa_snk_cb.rx_flush == TRUE) {
            btc_a2dp_sink_flush_q(btc_aa_snk_cb.RxSbcQ);
            return;
        }

        while ((p_msg = (tBT_SBC_HDR *)fixed_queue_try_peek_first(btc_aa_snk_cb.RxSbcQ)) != NULL ) {
            btc_a2dp_sink_handle_inc_media(p_msg);
            p_msg = (tBT_SBC_HDR *)fixed_queue_try_dequeue(btc_aa_snk_cb.RxSbcQ);
            if ( p_msg == NULL ) {
                APPL_TRACE_ERROR("Insufficient data in que ");
                break;
            }
            osi_free(p_msg);
        }
        APPL_TRACE_DEBUG(" Process Frames - ");
    }
}
Beispiel #14
0
    return (FALSE);
}

/*******************************************************************************
**
**  Function        l2c_ucd_send_pending_in_sec_q
**
**  Description     dequeue UCD packet from security pending queue and
**                  send it to application
**
**  Return          None
**
*******************************************************************************/
void l2c_ucd_send_pending_in_sec_q(tL2C_CCB  *p_ccb)
{
    BT_HDR *p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->p_lcb->ucd_in_sec_pending_q)

    if (p_buf != NULL) {
        p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Data_Cb(p_ccb->p_lcb->remote_bd_addr, (BT_HDR *)p_buf);
    }
}

/*******************************************************************************
**
**  Function        l2c_ucd_discard_pending_in_sec_q
**
**  Description     dequeue UCD packet from security pending queue and
**                  discard it.
**
**  Return          None
**
Beispiel #15
0
/*******************************************************************************
**
** Function         port_release_port
**
** Description      Release port infor control block.
**
** Returns          Pointer to the PORT or NULL if not found
**
*******************************************************************************/
void port_release_port (tPORT *p_port)
{
    BT_HDR *p_buf;
    UINT32 mask;
    tPORT_CALLBACK *p_port_cb;
    tPORT_STATE user_port_pars;

    osi_mutex_global_lock();
    RFCOMM_TRACE_DEBUG("port_release_port, p_port:%p", p_port);
    while ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_port->rx.queue)) != NULL) {
        osi_free (p_buf);
    }

    p_port->rx.queue_size = 0;

    while ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_port->tx.queue)) != NULL) {
        osi_free (p_buf);
    }

    p_port->tx.queue_size = 0;

    osi_mutex_global_unlock();

    p_port->state = PORT_STATE_CLOSED;

    if (p_port->rfc.state == RFC_STATE_CLOSED) {
        RFCOMM_TRACE_DEBUG ("rfc_port_closed DONE");
        if (p_port->rfc.p_mcb) {
            p_port->rfc.p_mcb->port_inx[p_port->dlci] = 0;

            /* If there are no more ports opened on this MCB release it */
            rfc_check_mcb_active (p_port->rfc.p_mcb);
        }
        rfc_port_timer_stop (p_port);
        fixed_queue_free(p_port->tx.queue, NULL);
        p_port->tx.queue = NULL;
        fixed_queue_free(p_port->rx.queue, NULL);
        p_port->rx.queue = NULL;
		
        RFCOMM_TRACE_DEBUG ("port_release_port:p_port->keep_port_handle:%d", p_port->keep_port_handle);
        if ( p_port->keep_port_handle ) {
            RFCOMM_TRACE_DEBUG ("port_release_port:Initialize handle:%d", p_port->inx);
            /* save event mask and callback */
            mask = p_port->ev_mask;
            p_port_cb = p_port->p_callback;
            user_port_pars = p_port->user_port_pars;

            port_set_defaults(p_port);
            /* restore */
            p_port->ev_mask         = mask;
            p_port->p_callback      = p_port_cb;
            p_port->user_port_pars  = user_port_pars;
            p_port->mtu             = p_port->keep_mtu;

            p_port->state           = PORT_STATE_OPENING;
            p_port->rfc.p_mcb       = NULL;
            if (p_port->is_server) {
                p_port->dlci       &= 0xfe;
            }

            p_port->local_ctrl.modem_signal = p_port->default_signal_state;
            memcpy (p_port->bd_addr, BT_BD_ANY, BD_ADDR_LEN);
        } else {
            RFCOMM_TRACE_DEBUG ("port_release_port:Clean-up handle:%d", p_port->inx);
            memset (p_port, 0, sizeof (tPORT));
        }
    }
}
Beispiel #16
0
/*******************************************************************************
 **
 ** Function         btc_a2dp_sink_flush_q
 **
 ** Description
 **
 ** Returns          void
 **
 *******************************************************************************/
static void btc_a2dp_sink_flush_q(fixed_queue_t *p_q)
{
    while (! fixed_queue_is_empty(p_q)) {
        osi_free(fixed_queue_try_dequeue(p_q));
    }
}