Exemplo n.º 1
0
/****************************************************
 * Invoked from bluetooth stack via hdev->send()
 * to send the packet out via ar6k to PAL firmware.
 *
 * For HCI command packet wmi_send_hci_cmd() is invoked.
 * wmi_send_hci_cmd adds WMI_CMD_HDR and sends the packet
 * to PAL firmware.
 *
 * For HCI ACL data packet wmi_data_hdr_add is invoked
 * to add WMI_DATA_HDR to the packet.  ar6000_acl_data_tx
 * is then invoked to send the packet to PAL firmware.
 ******************************************************/
static int btpal_send_frame(struct sk_buff *skb)
{
	struct hci_dev *hdev = (struct hci_dev *)skb->dev;
	HCI_TRANSPORT_PACKET_TYPE type;
	ar6k_hci_pal_info_t *pHciPalInfo;
	A_STATUS status = A_OK;
	struct sk_buff *txSkb = NULL;
	AR_SOFTC_DEV_T *ar;

	if (!hdev) {
		PRIN_LOG("HCI PAL: btpal_send_frame - no device\n");
		return -ENODEV;
	}

	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
		PRIN_LOG("HCI PAL: btpal_send_frame - not open\n");
		return -EBUSY;
	}

	pHciPalInfo = (ar6k_hci_pal_info_t *)hdev->driver_data;
	A_ASSERT(pHciPalInfo != NULL);
	ar = pHciPalInfo->ar;

	PRIN_LOG("+btpal_send_frame type: %d \n",bt_cb(skb)->pkt_type);
	type = HCI_COMMAND_TYPE;

	switch (bt_cb(skb)->pkt_type) {
		case HCI_COMMAND_PKT:
			type = HCI_COMMAND_TYPE;
			hdev->stat.cmd_tx++;
			break;

		case HCI_ACLDATA_PKT:
			type = HCI_ACL_TYPE;
			hdev->stat.acl_tx++;
			break;

		case HCI_SCODATA_PKT:
			/* we don't support SCO over the pal */
			kfree_skb(skb);
			return 0;
		default:
			A_ASSERT(FALSE);
			kfree_skb(skb);
			return 0;
	}

    	if(loghci) {
		A_PRINTF(">>> Send HCI %s packet len: %d\n",
				(type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL",
				skb->len);
		if (type == HCI_COMMAND_TYPE) {
			A_PRINTF("HCI Command: OGF:0x%X OCF:0x%X \r\n",
				(HCI_GET_OP_CODE(skb->data)) >> 10, 
				(HCI_GET_OP_CODE(skb->data)) & 0x3FF);
		}
		DebugDumpBytes(skb->data,skb->len,"BT HCI SEND Packet Dump");
	}
/*
 * bt_send_frame - send data frames
*/
static int bt_send_frame(struct sk_buff *skb)
{
    struct hci_dev             *hdev = (struct hci_dev *)skb->dev;
    HCI_TRANSPORT_PACKET_TYPE  type;
    AR6K_HCI_BRIDGE_INFO       *pHcidevInfo;
    HTC_PACKET                 *pPacket;
    A_STATUS                   status = A_OK;
    struct sk_buff             *txSkb = NULL;
    
    if (!hdev) {
        AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_send_frame - no device\n"));
        return -ENODEV;
    }
      
    if (!test_bit(HCI_RUNNING, &hdev->flags)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_send_frame - not open\n"));
        return -EBUSY;
    }
  
    pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)hdev->driver_data;   
    A_ASSERT(pHcidevInfo != NULL);
      
    AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb)->pkt_type));
    type = HCI_COMMAND_TYPE;
    
    switch (bt_cb(skb)->pkt_type) {
        case HCI_COMMAND_PKT:
            type = HCI_COMMAND_TYPE;
            hdev->stat.cmd_tx++;
            break;
 
        case HCI_ACLDATA_PKT:
            type = HCI_ACL_TYPE;
            hdev->stat.acl_tx++;
            break;

        case HCI_SCODATA_PKT:
            /* we don't support SCO over the bridge */
            kfree_skb(skb);
            return 0;
        default:
            A_ASSERT(FALSE);
            kfree_skb(skb);
            return 0;
    } 

    if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
        AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(">>> Send HCI %s packet len: %d\n",
                        (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL",
                        skb->len));
        if (type == HCI_COMMAND_TYPE) {
            A_UINT16 opcode = HCI_GET_OP_CODE(skb->data);
            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("    HCI Command: OGF:0x%X OCF:0x%X \r\n", 
                  opcode >> 10, opcode & 0x3FF));
        }
        AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump");
    }
Exemplo n.º 3
0
ATHBT_STATE_INDICATION FCore_FilterBTCommand(BT_FILTER_CORE_INFO *pCore, A_UINT8 *pBuffer, int Length, ATHBT_STATE *pNewState)
{
    ATHBT_STATE_INDICATION indication = ATH_BT_NOOP;
    ATHBT_STATE            state = STATE_OFF;
    A_UINT16               command;


    if (!IS_LINK_CONTROL_CMD(pBuffer)) {
            /* we only filter link control commands */
        return indication;
    }

    command = HCI_GET_OP_CODE(pBuffer);

    switch (command) {
        case HCI_INQUIRY :
            if (IS_STATE_FILTER_IGNORED(pCore, ATH_BT_INQUIRY)) {
                break;
            }
            indication = ATH_BT_INQUIRY;
            state = STATE_ON;
            break;

        case HCI_INQUIRY_CANCEL :
            if (IS_STATE_FILTER_IGNORED(pCore, ATH_BT_INQUIRY)) {
                break;
            }
            indication = ATH_BT_INQUIRY;
            state = STATE_OFF;
            break;

        case HCI_CREATE_CONNECTION :
            if (IS_STATE_FILTER_IGNORED(pCore, ATH_BT_CONNECT)) {
                break;
            }
            indication = ATH_BT_CONNECT;
            state = STATE_ON;
            break;

        case HCI_ACCEPT_CONN_REQ :
            if (IS_STATE_FILTER_IGNORED(pCore, ATH_BT_CONNECT)) {
                break;
            }
            indication = ATH_BT_CONNECT;
            state = STATE_ON;
            break;

        case HCI_ADD_SCO :
            /* we do not need to handle this command, we can pick up the connection complete event */
        case HCI_DISCONNECT :
            /* we don't need to handle this command as we can pick up the disconnect event */
        case HCI_PER_INQUIRY :
        case HCI_PER_INQUIRY_CANCEL :
            /* we do not handle these currently */
        default :
            break;
    }

    if (indication != ATH_BT_NOOP) {
            /* the HCI filter simply determines the "precise" state and calls the shared function */
        return FCore_FilterIndicatePreciseState(pCore, indication, state, pNewState);
    }

    return ATH_BT_NOOP;
}