예제 #1
0
/*******************************************************************************
**
** Function         gap_release_ccb
**
** Description      This function releases a CCB.
**
** Returns          void
**
*******************************************************************************/
static void gap_release_ccb (tGAP_CCB *p_ccb)
{
    UINT16       xx;
    UINT16      psm = p_ccb->psm;
    UINT8       service_id = p_ccb->service_id;

    /* Drop any buffers we may be holding */
    p_ccb->rx_queue_size = 0;

    while (p_ccb->rx_queue._p_first)
        GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue));

    while (p_ccb->tx_queue._p_first)
        GKI_freebuf (GKI_dequeue (&p_ccb->tx_queue));

    p_ccb->con_state = GAP_CCB_STATE_IDLE;

    /* If no-one else is using the PSM, deregister from L2CAP */
    for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
    {
        if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->psm == psm))
            return;
    }

    /* Free the security record for this PSM */
    BTM_SecClrService(service_id);
    L2CA_DEREGISTER (psm);
}
예제 #2
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)
    {
        GKI_freebuf(p_ccb->p_curr_msg);
        p_ccb->p_curr_msg = NULL;
    }

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

    /* clear out response queue */
    while ((p_buf = (BT_HDR *) GKI_dequeue(&p_ccb->rsp_q)) != NULL)
    {
        GKI_freebuf(p_buf);
    }
}
예제 #3
0
/*******************************************************************************
**
** Function         nfc_hal_send_nci_msg_to_nfc_task
**
** Description      This function is called to send nci message to nfc task
**
** Returns          void
**
*******************************************************************************/
void nfc_hal_send_nci_msg_to_nfc_task (NFC_HDR * p_msg)
{        

#ifdef SWISSKNIFEVERSION
    if(!shortCircuit && !sent){ 
 
    #ifdef NFC_HAL_SHARED_GKI
        /* Using shared NFC/HAL GKI resources - send message buffer directly to NFC_TASK for processing */
        p_msg->event = BT_EVT_TO_NFC_NCI;
        GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
    #else
        /* Send NCI message to the stack */
        nfc_hal_cb.p_data_cback (p_msg->len, (UINT8 *) ((p_msg + 1)
                                     + p_msg->offset));
        GKI_freebuf(p_msg);
    #endif
    }
    else{
        GKI_freebuf(p_msg);
    }
#else

    #ifdef NFC_HAL_SHARED_GKI
        /* Using shared NFC/HAL GKI resources - send message buffer directly to NFC_TASK for processing */
        p_msg->event = BT_EVT_TO_NFC_NCI;
        GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
    #else
        /* Send NCI message to the stack */
        nfc_hal_cb.p_data_cback (p_msg->len, (UINT8 *) ((p_msg + 1)
                                     + p_msg->offset));
        GKI_freebuf(p_msg);
    #endif

#endif    
}
/*******************************************************************************
**
** Function         nfc_hal_main_handle_terminate
**
** Description      Handle NFI transport shutdown
**
** Returns          nothing
**
*******************************************************************************/
static void nfc_hal_main_handle_terminate (void)
{
    NFC_HDR *p_msg;

    /* dequeue and free buffer */
    if (nfc_hal_cb.ncit_cb.p_pend_cmd != NULL)
    {
        GKI_freebuf (nfc_hal_cb.ncit_cb.p_pend_cmd);
        nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
    }

    /* Free unsent nfc rx buffer */
    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
    {
        GKI_freebuf (nfc_hal_cb.ncit_cb.p_rcv_msg);
        nfc_hal_cb.ncit_cb.p_rcv_msg  = NULL;
    }

    /* Free buffer for pending fragmented response/notification */
    if (nfc_hal_cb.ncit_cb.p_frag_msg)
    {
        GKI_freebuf (nfc_hal_cb.ncit_cb.p_frag_msg);
        nfc_hal_cb.ncit_cb.p_frag_msg = NULL;
    }

    /* Free buffers in the tx mbox */
    while ((p_msg = (NFC_HDR *) GKI_read_mbox (NFC_HAL_TASK_MBOX)) != NULL)
    {
        GKI_freebuf (p_msg);
    }

    /* notify closing transport */
    nfc_hal_dm_shutting_down_nfcc ();
}
예제 #5
0
/*******************************************************************************
 **
 ** Function         btusb_lite_hci_acl_send
 **
 ** Description      Send an ACL packet to HCI
 **
 ** Returns          Void
 **
 *******************************************************************************/
int btusb_lite_hci_acl_send(struct btusb *p_dev, BT_HDR *p_msg, UINT16 con_hdl)
{
    UINT8 *p_data;

    /* Sanity */
    if (p_msg->offset < BTUSB_LITE_HCI_ACL_HDR_SIZE)
    {
        BTUSB_ERR("offset too small=%d\n", p_msg->offset);
        GKI_freebuf(p_msg); /* Free this ACL buffer */
        return -1;
    }

    /* Decrement offset to add headers */
    p_msg->offset -= BTUSB_LITE_HCI_ACL_HDR_SIZE;

    /* Get address of the HCI Header */
    p_data = (UINT8 *)(p_msg + 1) + p_msg->offset;

    /* Write L2CAP Header (length field is SBC Frames + RTP/A2DP/Media Header) */
    p_data = btusb_lite_hci_write_acl_header(p_data, con_hdl, p_msg->len);

    /* Increment length */
    p_msg->len += BTUSB_LITE_HCI_ACL_HDR_SIZE;

    p_data = (UINT8 *)(p_msg + 1) + p_msg->offset;
    btusb_submit_acl(p_dev, p_data, p_msg->len);

    GKI_freebuf(p_msg); /* Free this ACL buffer */
    return 0;
}
예제 #6
0
/*******************************************************************************
**
** Function         gap_data_ind
**
** Description      This function is called when data is received from L2CAP.
**
** Returns          void
**
*******************************************************************************/
static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
{
    tGAP_CCB    *p_ccb;

    /* Find CCB based on CID */
    if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
    {
        GKI_freebuf (p_msg);
        return;
    }

    if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
    {
        GKI_enqueue (&p_ccb->rx_queue, p_msg);

        p_ccb->rx_queue_size += p_msg->len;
        /*
        GAP_TRACE_EVENT ("gap_data_ind - rx_queue_size=%d, msg len=%d",
                                       p_ccb->rx_queue_size, p_msg->len);
         */

        p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL);
    }
    else
    {
        GKI_freebuf (p_msg);
    }
}
예제 #7
0
int bta_co_rfc_data_incoming(void *user_data, BT_HDR *p_buf) {
  pthread_mutex_lock(&slot_lock);

  int ret = 0;
  uint32_t id = (uintptr_t)user_data;
  rfc_slot_t *slot = find_rfc_slot_by_id(id);
  if (!slot)
    goto out;

  if (list_is_empty(slot->incoming_queue)) {
    switch (send_data_to_app(slot->fd, p_buf)) {
      case SENT_NONE:
      case SENT_PARTIAL:
        list_append(slot->incoming_queue, p_buf);
        btsock_thread_add_fd(pth, slot->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_WR, slot->id);
        break;

      case SENT_ALL:
        GKI_freebuf(p_buf);
        ret = 1;  // Enable data flow.
        break;

      case SENT_FAILED:
        GKI_freebuf(p_buf);
        cleanup_rfc_slot(slot);
        break;
    }
  } else {
    list_append(slot->incoming_queue, p_buf);
  }

out:;
  pthread_mutex_unlock(&slot_lock);
  return ret;  // Return 0 to disable data flow.
}
예제 #8
0
/*******************************************************************************
**
** Function         rfc_port_sm_sabme_wait_ua
**
** Description      This function handles events when SABME on the DLC was
**                  sent and SM is waiting for UA or DM.
**
** Returns          void
**
*******************************************************************************/
void rfc_port_sm_sabme_wait_ua (tPORT *p_port, UINT16 event, void *p_data)
{
    switch (event)
    {
    case RFC_EVENT_OPEN:
    case RFC_EVENT_ESTABLISH_RSP:
        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:
        GKI_freebuf (p_data);
        break;

    case RFC_EVENT_UA:
        rfc_port_timer_stop (p_port);
        p_port->rfc.state = RFC_STATE_OPENED;
        PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_SUCCESS);
        return;

    case RFC_EVENT_DM:
        p_port->rfc.p_mcb->is_disc_initiator = TRUE;
        PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
        rfc_port_closed (p_port);
        return;

    case RFC_EVENT_DISC:
        rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
        PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
        rfc_port_closed (p_port);
        return;

    case RFC_EVENT_SABME:
        /* Continue to wait for the UA the SABME this side sent */
        rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
        return;

    case RFC_EVENT_UIH:
        GKI_freebuf (p_data);
        return;

    case RFC_EVENT_TIMEOUT:
        p_port->rfc.state = RFC_STATE_CLOSED;
        PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
        return;
    }
    RFCOMM_TRACE_WARNING ("Port state sabme_wait_ua Event ignored %d", event);
}
예제 #9
0
/*******************************************************************************
**
** Function         gatt_enc_cmpl_cback
**
** Description      link encryption complete callback.
**
** Returns
**
*******************************************************************************/
void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
{
    tGATT_TCB   *p_tcb;
    UINT8       sec_flag;
    BOOLEAN     status = FALSE;
    tGATT_PENDING_ENC_CLCB  *p_buf;
    UINT16       count;
    UNUSED(p_ref_data);

    GATT_TRACE_DEBUG("gatt_enc_cmpl_cback");
    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, transport)) != NULL)
    {
        if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING)
            return;

        if ((p_buf = (tGATT_PENDING_ENC_CLCB *)GKI_dequeue (&p_tcb->pending_enc_clcb)) != NULL)
        {
            if (result == BTM_SUCCESS)
            {
                if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM )
                {
                    BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport);

                    if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
                    {
                        status = TRUE;
                    }
                }
                else
                {
                    status = TRUE;
                }
            }
            gatt_sec_check_complete(status , p_buf->p_clcb, p_tcb->sec_act);
            GKI_freebuf(p_buf);
            /* start all other pending operation in queue */
            count = p_tcb->pending_enc_clcb.count;
            for (; count > 0; count --)
            {
                if ((p_buf = (tGATT_PENDING_ENC_CLCB *)GKI_dequeue (&p_tcb->pending_enc_clcb)) != NULL)
                {
                    gatt_security_check_start(p_buf->p_clcb);
                    GKI_freebuf(p_buf);
                }
                else
                    break;
            }
        }
        else
        {
            GATT_TRACE_ERROR("Unknown operation encryption completed");
        }
    }
    else
    {
        GATT_TRACE_ERROR("enc callback for unknown bd_addr");
    }
}
예제 #10
0
/*******************************************************************************
**
** Function         rfc_port_sm_state_closed
**
** Description      This function handles events when the port is in
**                  CLOSED state. This state exists when port is
**                  being initially established.
**
** Returns          void
**
*******************************************************************************/
void rfc_port_sm_state_closed (tPORT *p_port, UINT16 event, void *p_data)
{
    switch (event)
    {
    case RFC_EVENT_OPEN:
        p_port->rfc.state = RFC_STATE_ORIG_WAIT_SEC_CHECK;
        btm_sec_mx_access_request (p_port->rfc.p_mcb->bd_addr, BT_PSM_RFCOMM, TRUE,
                                   BTM_SEC_PROTO_RFCOMM, (UINT32)(p_port->dlci / 2),
                                   &rfc_sec_check_complete, p_port);
        return;

    case RFC_EVENT_CLOSE:
        break;

    case RFC_EVENT_CLEAR:
        return;

    case RFC_EVENT_DATA:
        GKI_freebuf (p_data);
        break;

    case RFC_EVENT_SABME:
        /* make sure the multiplexer disconnect timer is not running (reconnect case) */
        rfc_timer_stop(p_port->rfc.p_mcb );

        /* Open will be continued after security checks are passed */
        p_port->rfc.state = RFC_STATE_TERM_WAIT_SEC_CHECK;
        btm_sec_mx_access_request (p_port->rfc.p_mcb->bd_addr, BT_PSM_RFCOMM, FALSE,
                                   BTM_SEC_PROTO_RFCOMM, (UINT32)(p_port->dlci / 2),
                                   &rfc_sec_check_complete, p_port);
        return;

    case RFC_EVENT_UA:
        return;

    case RFC_EVENT_DM:
        rfc_port_closed (p_port);
        return;

    case RFC_EVENT_UIH:
        GKI_freebuf (p_data);
        rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, FALSE);
        return;

    case RFC_EVENT_DISC:
        rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, FALSE);
        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 closed Event ignored %d", event);
    return;
}
/*******************************************************************************
**
** Function         bta_pan_tx_path
**
** Description      Handle the TX data path (data sent from BTA to the phone).
**
**
** Returns          void
**
*******************************************************************************/
void bta_pan_tx_path(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
{

    BT_HDR * p_buf;
    /* if data path configured for tx pull */
    if ((bta_pan_cb.flow_mask & BTA_PAN_TX_MASK) == BTA_PAN_TX_PULL)
    {
        bta_pan_pm_conn_busy(p_scb);
        /* call application callout function for tx path */
        bta_pan_co_tx_path(p_scb->handle, p_scb->app_id);

        /* free data that exceeds queue level */
        while(p_scb->data_queue.count > bta_pan_cb.q_level)
            GKI_freebuf(GKI_dequeue(&p_scb->data_queue));
        bta_pan_pm_conn_idle(p_scb);
    }
    /* if configured for zero copy push */
    else if ((bta_pan_cb.flow_mask & BTA_PAN_TX_MASK) == BTA_PAN_TX_PUSH_BUF)
    {
        /* if app can accept data */
        if (p_scb->app_flow_enable == TRUE)
        {
            /* read data from the queue */
            if ((p_buf = (BT_HDR *)GKI_dequeue(&p_scb->data_queue)) != NULL)
            {
                /* send data to application */
                bta_pan_co_tx_writebuf(p_scb->handle,
                                        p_scb->app_id,
                                        ((tBTA_PAN_DATA_PARAMS *)p_buf)->src,
                                        ((tBTA_PAN_DATA_PARAMS *)p_buf)->dst,
                                        ((tBTA_PAN_DATA_PARAMS *)p_buf)->protocol,
                                        p_buf,
                                        ((tBTA_PAN_DATA_PARAMS *)p_buf)->ext,
                                        ((tBTA_PAN_DATA_PARAMS *)p_buf)->forward);

            }
            /* free data that exceeds queue level  */
            while(p_scb->data_queue.count > bta_pan_cb.q_level)
                GKI_freebuf(GKI_dequeue(&p_scb->data_queue));

            /* if there is more data to be passed to
            upper layer */
            if(p_scb->data_queue.count)
            {
                if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
                {
                    p_buf->layer_specific = p_scb->handle;
                    p_buf->event = BTA_PAN_RX_FROM_BNEP_READY_EVT;
                    bta_sys_sendmsg(p_buf);
                }

            }

        }
    }
}
/*******************************************************************************
**
** Function         bta_pan_data_buf_ind_cback
**
** Description      data indication callback from pan profile
**
**
** Returns          void
**
*******************************************************************************/
static void bta_pan_data_buf_ind_cback(UINT16 handle, BD_ADDR src, BD_ADDR dst, UINT16 protocol, BT_HDR *p_buf,
                                   BOOLEAN ext, BOOLEAN forward)
{
    tBTA_PAN_SCB *p_scb;
    BT_HDR * p_event;
    BT_HDR *p_new_buf;

    if ( sizeof(tBTA_PAN_DATA_PARAMS) > p_buf->offset )
    {
        /* offset smaller than data structure in front of actual data */
        p_new_buf = (BT_HDR *)GKI_getpoolbuf( PAN_POOL_ID );
        if(!p_new_buf)
        {
            APPL_TRACE_WARNING0("Cannot get a PAN GKI buffer");
            GKI_freebuf( p_buf );
            return;
        }
        else
        {
            memcpy( (UINT8 *)(p_new_buf+1)+sizeof(tBTA_PAN_DATA_PARAMS), (UINT8 *)(p_buf+1)+p_buf->offset, p_buf->len );
            p_new_buf->len    = p_buf->len;
            p_new_buf->offset = sizeof(tBTA_PAN_DATA_PARAMS);
            GKI_freebuf( p_buf );
        }
    }
    else
    {
        p_new_buf = p_buf;
    }
    /* copy params into the space before the data */
    bdcpy(((tBTA_PAN_DATA_PARAMS *)p_new_buf)->src, src);
    bdcpy(((tBTA_PAN_DATA_PARAMS *)p_new_buf)->dst, dst);
    ((tBTA_PAN_DATA_PARAMS *)p_new_buf)->protocol = protocol;
    ((tBTA_PAN_DATA_PARAMS *)p_new_buf)->ext = ext;
    ((tBTA_PAN_DATA_PARAMS *)p_new_buf)->forward = forward;


    if((p_scb = bta_pan_scb_by_handle(handle)) == NULL)
    {

        GKI_freebuf( p_new_buf );
        return;
    }

    GKI_enqueue(&p_scb->data_queue, p_new_buf);
    if ((p_event = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    {
        p_event->layer_specific = handle;
        p_event->event = BTA_PAN_RX_FROM_BNEP_READY_EVT;
        bta_sys_sendmsg(p_event);
    }

}
예제 #13
0
파일: smp_l2c.c 프로젝트: morrey/bt_bcm
/*******************************************************************************
**
** Function         smp_br_data_received
**
** Description      This function is called when data is received from L2CAP on
**                  SMP BR channel.
**
** Returns          void
**
*******************************************************************************/
static void smp_br_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf)
{
    tSMP_CB *p_cb = &smp_cb;
    UINT8   *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
    UINT8   cmd ;
    SMP_TRACE_EVENT ("SMDBG l2c %s", __func__);

    STREAM_TO_UINT8(cmd, p);

    /* sanity check */
    if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd))
    {
        SMP_TRACE_WARNING( "Ignore received command with RESERVED code 0x%02x", cmd);
        GKI_freebuf(p_buf);
        return;
    }

    /* reject the pairing request if there is an on-going SMP pairing */
    if (SMP_OPCODE_PAIRING_REQ == cmd)
    {
        if ((p_cb->state == SMP_STATE_IDLE) && (p_cb->br_state == SMP_BR_STATE_IDLE))
        {
            p_cb->role = HCI_ROLE_SLAVE;
            p_cb->smp_over_br = TRUE;
            memcpy(&p_cb->pairing_bda[0], bd_addr, BD_ADDR_LEN);
        }
        else if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN))
        {
            GKI_freebuf (p_buf);
            smp_reject_unexpected_pairing_command(bd_addr);
            return;
        }
        /* else, out of state pairing request received, passed into State Machine */
    }

    if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN) == 0)
    {
        btu_stop_timer (&p_cb->rsp_timer_ent);
        btu_start_timer (&p_cb->rsp_timer_ent, BTU_TTYPE_SMP_PAIRING_CMD,
                             SMP_WAIT_FOR_RSP_TOUT);

        p_cb->rcvd_cmd_code = cmd;
        p_cb->rcvd_cmd_len = (UINT8) p_buf->len;
        smp_br_state_machine_event(p_cb, cmd, p);
    }

    GKI_freebuf (p_buf);
}
예제 #14
0
/*******************************************************************************
**
** Function         GAP_ConnBTWrite
**
** Description      Bluetooth Aware applications can call this function to write data.
**
** Parameters:      handle      - Handle of the connection returned in the Open
**                  p_buf      - pointer to address of buffer with data,
**
** Returns          BT_PASS                 - data read
**                  GAP_ERR_BAD_HANDLE      - invalid handle
**                  GAP_ERR_BAD_STATE       - connection not established
**                  GAP_INVALID_BUF_OFFSET  - buffer offset is invalid
*******************************************************************************/
UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf)
{
    tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);

    if (!p_ccb)
    {
        GKI_freebuf (p_buf);
        return (GAP_ERR_BAD_HANDLE);
    }

    if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
    {
        GKI_freebuf (p_buf);
        return (GAP_ERR_BAD_STATE);
    }

    if (p_buf->offset < L2CAP_MIN_OFFSET)
    {
        GKI_freebuf (p_buf);
        return (GAP_ERR_BUF_OFFSET);
    }

    GKI_enqueue (&p_ccb->tx_queue, p_buf);

    if (p_ccb->is_congested)
    {
        return (BT_PASS);
    }

    /* Send the buffer through L2CAP */
#if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
    gap_send_event (gap_handle);
#else
    while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
    {
        UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);

        if (status == L2CAP_DW_CONGESTED)
        {
            p_ccb->is_congested = TRUE;
            break;
        }
        else if (status != L2CAP_DW_SUCCESS)
            return (GAP_ERR_BAD_STATE);
    }
#endif
    return (BT_PASS);
}
/*******************************************************************************
**
** Function         nfc_hal_main_open_transport
**
** Description      Open transport and prepare for new incoming message;
**
** Returns          nothing
**
*******************************************************************************/
static void nfc_hal_main_open_transport (void)
{
    tUSERIAL_OPEN_CFG open_cfg;

    /* Initialize control block */
    nfc_hal_cb.ncit_cb.rcv_state = NFC_HAL_RCV_IDLE_ST; /* to process packet type */

    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
    {
        GKI_freebuf (nfc_hal_cb.ncit_cb.p_rcv_msg);
        nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
    }

    /* open transport */
    open_cfg.fmt    = (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1);
    open_cfg.baud   = nfc_hal_trans_cfg.userial_baud;
    open_cfg.fc     = nfc_hal_trans_cfg.userial_fc;
    open_cfg.buf    = USERIAL_BUF_BYTE;

    USERIAL_Open (USERIAL_NFC_PORT, &open_cfg, nfc_hal_main_userial_cback);

    {
        /* Wait for NFCC to enable - Core reset notification */
        NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_NFCC_ENABLE);

        /* NFCC Enable timeout */
        nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
                                        ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000);
    }
}
예제 #16
0
/*******************************************************************************
**
** Function         HID_HostWriteDev
**
** Description      This function is called when the host has a report to send.
**
**                  report_id: is only used on GET_REPORT transaction if is specified.
**                              only valid when it's a non-zero value.
**
** Returns          void
**
*******************************************************************************/
tHID_STATUS HID_HostWriteDev( UINT8 dev_handle, UINT8 t_type,
                              UINT8 param, UINT16 data, UINT8 report_id, BT_HDR *pbuf  )
{
    tHID_STATUS status = HID_SUCCESS;

    if( !hh_cb.reg_flag )
    {
        HIDH_TRACE_ERROR0("HID_ERR_NOT_REGISTERED");
        status = HID_ERR_NOT_REGISTERED;
    }

    if( (dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use) )
    {
        HIDH_TRACE_ERROR0("HID_ERR_INVALID_PARAM");
        status = HID_ERR_INVALID_PARAM;
    }

    if( hh_cb.devices[dev_handle].state != HID_DEV_CONNECTED )
    {
        HIDH_TRACE_ERROR1("HID_ERR_NO_CONNECTION dev_handle %d", dev_handle);
        status = HID_ERR_NO_CONNECTION;
    }

    if (status != HID_SUCCESS)
    {
        if (pbuf)
            GKI_freebuf ((void *)pbuf);
    }
    else
        status = hidh_conn_snd_data( dev_handle, t_type, param, data, report_id, pbuf ) ;

    return status;
}
/*******************************************************************************
**
** Function         btm_ble_dequeue_direct_conn_req
**
** Description      This function dequeues the direct connection request
**
** Returns          None.
**
*******************************************************************************/
void btm_ble_dequeue_direct_conn_req(BD_ADDR rem_bda)
{
    tBTM_BLE_CONN_REQ   *p_req = NULL;
    tL2C_LCB *p_lcb;
    if(btm_cb.ble_ctr_cb.conn_pending_q.count)
    {
        p_req = (tBTM_BLE_CONN_REQ*)GKI_getfirst(&btm_cb.ble_ctr_cb.conn_pending_q);
    }
    while(p_req != NULL)
    {
        p_lcb = (tL2C_LCB *)p_req->p_param;
        if((p_lcb != NULL) && (p_lcb->in_use))
        {
            //If BD address matches
            if(!memcmp (rem_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN))
            {
                GKI_remove_from_queue(&btm_cb.ble_ctr_cb.conn_pending_q, p_req);
                l2cu_release_lcb ((tL2C_LCB *)p_req->p_param);
                GKI_freebuf((void *)p_req);
                break;
            }
        }
        p_req = (tBTM_BLE_CONN_REQ*)GKI_getnext(p_req);
    }
}
예제 #18
0
파일: smp_cmac.c 프로젝트: Exchizz/esp-idf
/*******************************************************************************
**
** Function         cmac_aes_cleanup
**
** Description      clean up function for AES_CMAC algorithm.
**
** Returns          void
**
*******************************************************************************/
static void cmac_aes_cleanup(void)
{
    if (cmac_cb.text != NULL) {
        GKI_freebuf(cmac_cb.text);
    }
    memset(&cmac_cb, 0, sizeof(tCMAC_CB));
}
/*******************************************************************************
**
** Function         bta_pan_disable
**
** Description
**
**
**
** Returns          void
**
*******************************************************************************/
void bta_pan_disable(void)
{

    BT_HDR *p_buf;
    tBTA_PAN_SCB *p_scb = &bta_pan_cb.scb[0];
    UINT8 i;


    /* close all connections */
    PAN_SetRole (0, NULL, NULL, NULL, NULL);

#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&(BTA_EIR_CANNED_UUID_LIST != TRUE)
    bta_sys_remove_uuid(UUID_SERVCLASS_NAP);
    bta_sys_remove_uuid(UUID_SERVCLASS_GN);
    bta_sys_remove_uuid(UUID_SERVCLASS_PANU);
#endif
    /* free all queued up data buffers */
    for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
    {
        if (p_scb->in_use)
        {
            while((p_buf = (BT_HDR *)GKI_dequeue(&p_scb->data_queue)) != NULL)
                GKI_freebuf(p_buf);

            bta_pan_co_close(p_scb->handle, p_scb->app_id);

        }
    }



    PAN_Deregister();

}
예제 #20
0
파일: avdt_ad.c 프로젝트: Exchizz/esp-idf
/*******************************************************************************
**
** Function         avdt_ad_tc_data_ind
**
** Description      This function is called by the L2CAP interface layer when
**                  incoming data is received from L2CAP.  It looks up the CCB
**                  or SCB for the channel and routes the data accordingly.
**
**
** Returns          Nothing.
**
*******************************************************************************/
void avdt_ad_tc_data_ind(tAVDT_TC_TBL *p_tbl, BT_HDR *p_buf)
{
    tAVDT_CCB   *p_ccb;
    tAVDT_SCB   *p_scb;

    /* store type (media, recovery, reporting) */
    p_buf->layer_specific = avdt_ad_tcid_to_type(p_tbl->tcid);


    /* if signaling channel, handle control message */
    if (p_tbl->tcid == 0) {
        p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
        avdt_msg_ind(p_ccb, p_buf);
    }
    /* if media or other channel, send event to scb */
    else {
        p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
        if (p_scb != NULL) {
            avdt_scb_event(p_scb, AVDT_SCB_TC_DATA_EVT, (tAVDT_SCB_EVT *) &p_buf);
        } else {
            GKI_freebuf(p_buf);
            AVDT_TRACE_ERROR(" avdt_ad_tc_data_ind buffer freed");
        }
    }
}
예제 #21
0
파일: avct_lcb.c 프로젝트: morrey/bt_bcm
/*******************************************************************************
**
** Function         avct_lcb_dealloc
**
** Description      Deallocate a link control block.
**
**
** Returns          void.
**
*******************************************************************************/
void avct_lcb_dealloc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
{
    tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
    BOOLEAN     found = FALSE;
    int         i;
    UNUSED(p_data);

    AVCT_TRACE_DEBUG("avct_lcb_dealloc %d", p_lcb->allocated);

    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
    {
        /* if ccb allocated and */
        if (p_ccb->allocated)
        {
            if (p_ccb->p_lcb == p_lcb)
            {
                AVCT_TRACE_DEBUG("avct_lcb_dealloc used by ccb: %d", i);
                found = TRUE;
                break;
            }
        }
    }

    if (!found)
    {
        AVCT_TRACE_DEBUG("avct_lcb_dealloc now");

        /* clear reassembled msg buffer if in use */
        if (p_lcb->p_rx_msg != NULL)
        {
            GKI_freebuf(p_lcb->p_rx_msg);
        }
        memset(p_lcb, 0, sizeof(tAVCT_LCB));
    }
}
예제 #22
0
/*******************************************************************************
**
** Function         llcp_sdp_proc_deactivation
**
** Description      Report SDP failure for any pending request because of deactivation
**
**
** Returns          void
**
*******************************************************************************/
void llcp_sdp_proc_deactivation (void)
{
    UINT8 i;

    LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_deactivation ()");

    for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
    {
        if (llcp_cb.sdp_cb.transac[i].p_cback)
        {
            (*llcp_cb.sdp_cb.transac[i].p_cback) (llcp_cb.sdp_cb.transac[i].tid, 0x00);

            llcp_cb.sdp_cb.transac[i].p_cback = NULL;
        }
    }

    /* free any pending SNL PDU */
    if (llcp_cb.sdp_cb.p_snl)
    {
        GKI_freebuf (llcp_cb.sdp_cb.p_snl);
        llcp_cb.sdp_cb.p_snl = NULL;
    }

    llcp_cb.sdp_cb.next_tid = 0;
#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
    llcp_cb.dta_snl_resp = FALSE;
#endif
}
/*******************************************************************************
**
** Function         llcp_sdp_proc_deactivation
**
** Description      Report SDP failure for any pending request because of deactivation
**
**
** Returns          void
**
*******************************************************************************/
void llcp_sdp_proc_deactivation (void)
{
    UINT8 i;

    LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_deactivation ()");

    for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
    {
        if (llcp_cb.sdp_cb.transac[i].p_cback)
        {
            (*llcp_cb.sdp_cb.transac[i].p_cback) (llcp_cb.sdp_cb.transac[i].tid, 0x00);

            llcp_cb.sdp_cb.transac[i].p_cback = NULL;
        }
    }

    /* free any pending SNL PDU */
    if (llcp_cb.sdp_cb.p_snl)
    {
        GKI_freebuf (llcp_cb.sdp_cb.p_snl);
        llcp_cb.sdp_cb.p_snl = NULL;
    }

    llcp_cb.sdp_cb.next_tid = 0;
}
예제 #24
0
/*******************************************************************************
**
** Function         avdt_ccb_cmd_fail
**
** Description      This function is called when there is a response timeout.
**                  The currently pending command is freed and we fake a
**                  reject message back to ourselves.
**
**
** Returns          void.
**
*******************************************************************************/
void avdt_ccb_cmd_fail(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
{
    tAVDT_MSG       msg;
    UINT8           evt;
    tAVDT_SCB       *p_scb;

    if (p_ccb->p_curr_cmd != NULL)
    {
        /* set up data */
        msg.hdr.err_code = p_data->err_code;
        msg.hdr.err_param = 0;
        msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);

        /* pretend that we received a rej message */
        evt = avdt_msg_rej_2_evt[p_ccb->p_curr_cmd->event - 1];

        if (evt & AVDT_CCB_MKR)
        {
            avdt_ccb_event(p_ccb, (UINT8) (evt & ~AVDT_CCB_MKR), (tAVDT_CCB_EVT *) &msg);
        }
        else
        {
            /* we get the scb out of the current cmd */
            p_scb = avdt_scb_by_hdl(*((UINT8 *)(p_ccb->p_curr_cmd + 1)));
            if (p_scb != NULL)
            {
                avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT *) &msg);
            }
        }

        GKI_freebuf(p_ccb->p_curr_cmd);
        p_ccb->p_curr_cmd = NULL;
    }
}
/*******************************************************************************
**
** Function         sdp_data_ind
**
** Description      This function is called when data is received from L2CAP.
**                  if we are the originator of the connection, we are the SDP
**                  client, and the received message is queued up for the client.
**
**                  If we are the destination of the connection, we are the SDP
**                  server, so the message is passed to the server processing
**                  function.
**
** Returns          void
**
*******************************************************************************/
static void sdp_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
{
    tCONN_CB    *p_ccb;

    /* Find CCB based on CID */
    if ((p_ccb = sdpu_find_ccb_by_cid (l2cap_cid)) != NULL)
    {
        if (p_ccb->con_state == SDP_STATE_CONNECTED)
        {
            if (p_ccb->con_flags & SDP_FLAGS_IS_ORIG)
                sdp_disc_server_rsp (p_ccb, p_msg);
            else
                sdp_server_handle_client_req (p_ccb, p_msg);
        }
        else
        {
            SDP_TRACE_WARNING2 ("SDP - Ignored L2CAP data while in state: %d, CID: 0x%x",
                                p_ccb->con_state, l2cap_cid);
        }
    }
    else
    {
        SDP_TRACE_WARNING1 ("SDP - Rcvd L2CAP data, unknown CID: 0x%x", l2cap_cid);
    }

    GKI_freebuf (p_msg);
}
예제 #26
0
파일: gatt_auth.c 프로젝트: Exchizz/esp-idf
/*******************************************************************************
**
** Function         gatt_notify_enc_cmpl
**
** Description      link encryption complete notification for all encryption process
**                  initiated outside GATT.
**
** Returns
**
*******************************************************************************/
void gatt_notify_enc_cmpl(BD_ADDR bd_addr)
{
    tGATT_TCB   *p_tcb;
    tGATT_PENDING_ENC_CLCB  *p_buf;
    UINT16       count;
    UINT8        i = 0;

    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE)) != NULL) {
        for (i = 0; i < GATT_MAX_APPS; i++) {
            if (gatt_cb.cl_rcb[i].in_use && gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb) {
                (*gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)(gatt_cb.cl_rcb[i].gatt_if, bd_addr);
            }
        }

        if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) {
            gatt_set_sec_act(p_tcb, GATT_SEC_NONE);

            count = GKI_queue_length(&p_tcb->pending_enc_clcb);

            for (; count > 0; count --) {
                if ((p_buf = (tGATT_PENDING_ENC_CLCB *)GKI_dequeue (&p_tcb->pending_enc_clcb)) != NULL) {
                    gatt_security_check_start(p_buf->p_clcb);
                    GKI_freebuf(p_buf);
                } else {
                    break;
                }
            }
        }
    } else {
        GATT_TRACE_DEBUG("notify GATT for encryption completion of unknown device");
    }
    return;
}
/*******************************************************************************
**
** Function         bta_ag_free_db
**
** Description      Free discovery database.
**
**
** Returns          void
**
*******************************************************************************/
void bta_ag_free_db(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
{
    if (p_scb->p_disc_db != NULL)
    {
        GKI_freebuf(p_scb->p_disc_db);
        p_scb->p_disc_db = NULL;
    }
}
예제 #28
0
/*******************************************************************************
**
** Function         avdt_ccb_free_cmd
**
** Description      This function is called when a response is received for a
**                  currently pending command.  The command is freed.
**
**
** Returns          void.
**
*******************************************************************************/
void avdt_ccb_free_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
{
    if (p_ccb->p_curr_cmd != NULL)
    {
        GKI_freebuf(p_ccb->p_curr_cmd);
        p_ccb->p_curr_cmd = 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);
    }
}
예제 #30
0
/*******************************************************************************
**
** Function         rfc_port_sm_disc_wait_ua
**
** Description      This function handles events when DISC on the DLC was
**                  sent and SM is waiting for UA or DM.
**
** Returns          void
**
*******************************************************************************/
void rfc_port_sm_disc_wait_ua (tPORT *p_port, UINT16 event, void *p_data)
{
    switch (event)
    {
    case RFC_EVENT_OPEN:
    case RFC_EVENT_ESTABLISH_RSP:
        RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
        return;

    case RFC_EVENT_CLEAR:
        rfc_port_closed (p_port);
        return;

    case RFC_EVENT_DATA:
        GKI_freebuf (p_data);
        return;

    case RFC_EVENT_UA:
        p_port->rfc.p_mcb->is_disc_initiator = TRUE;
        /* Case falls through */

   case RFC_EVENT_DM:
        rfc_port_closed (p_port);
        return;

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

    case RFC_EVENT_DISC:
        rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE);
        return;

    case RFC_EVENT_UIH:
        GKI_freebuf (p_data);
        rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, FALSE);
        return;

    case RFC_EVENT_TIMEOUT:
        rfc_port_closed (p_port);
        return;
    }

    RFCOMM_TRACE_WARNING ("Port state disc_wait_ua Event ignored %d", event);
}