예제 #1
0
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
	struct hci_ev_cmd_complete *ec;
	struct hci_ev_cmd_status *cs;
	u16 opcode, ocf, ogf;

	skb_pull(skb, HCI_EVENT_HDR_SIZE);

	BT_DBG("%s evt 0x%x", hdev->name, hdr->evt);

	switch (hdr->evt) {
	case HCI_EV_NUM_COMP_PKTS:
		hci_num_comp_pkts_evt(hdev, skb);
		break;

	case HCI_EV_INQUIRY_COMPLETE:
		hci_inquiry_complete_evt(hdev, skb);
		break;

	case HCI_EV_INQUIRY_RESULT:
		hci_inquiry_result_evt(hdev, skb);
		break;

	case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
		hci_inquiry_result_with_rssi_evt(hdev, skb);
		break;

	case HCI_EV_EXTENDED_INQUIRY_RESULT:
		hci_extended_inquiry_result_evt(hdev, skb);
		break;

	case HCI_EV_CONN_REQUEST:
		hci_conn_request_evt(hdev, skb);
		break;

	case HCI_EV_CONN_COMPLETE:
		hci_conn_complete_evt(hdev, skb);
		break;

	case HCI_EV_DISCONN_COMPLETE:
		hci_disconn_complete_evt(hdev, skb);
		break;

	case HCI_EV_ROLE_CHANGE:
		hci_role_change_evt(hdev, skb);
		break;

	case HCI_EV_MODE_CHANGE:
		hci_mode_change_evt(hdev, skb);
		break;

	case HCI_EV_AUTH_COMPLETE:
		hci_auth_complete_evt(hdev, skb);
		break;

	case HCI_EV_ENCRYPT_CHANGE:
		hci_encrypt_change_evt(hdev, skb);
		break;

	case HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE:
		hci_change_conn_link_key_complete_evt(hdev, skb);
		break;

	case HCI_EV_PIN_CODE_REQ:
		hci_pin_code_request_evt(hdev, skb);
		break;

	case HCI_EV_LINK_KEY_REQ:
		hci_link_key_request_evt(hdev, skb);
		break;

	case HCI_EV_LINK_KEY_NOTIFY:
		hci_link_key_notify_evt(hdev, skb);
		break;

	case HCI_EV_REMOTE_FEATURES:
		hci_remote_features_evt(hdev, skb);
		break;

	case HCI_EV_CLOCK_OFFSET:
		hci_clock_offset_evt(hdev, skb);
		break;

	case HCI_EV_PSCAN_REP_MODE:
		hci_pscan_rep_mode_evt(hdev, skb);
		break;

	case HCI_EV_SNIFF_SUBRATE:
		hci_sniff_subrate_evt(hdev, skb);
		break;

	case HCI_EV_CMD_STATUS:
		cs = (struct hci_ev_cmd_status *) skb->data;
		skb_pull(skb, sizeof(cs));

		opcode = __le16_to_cpu(cs->opcode);
		ogf = hci_opcode_ogf(opcode);
		ocf = hci_opcode_ocf(opcode);

		switch (ogf) {
		case OGF_INFO_PARAM:
			hci_cs_info_param(hdev, ocf, cs->status);
			break;

		case OGF_HOST_CTL:
			hci_cs_host_ctl(hdev, ocf, cs->status);
			break;

		case OGF_LINK_CTL:
			hci_cs_link_ctl(hdev, ocf, cs->status);
			break;

		case OGF_LINK_POLICY:
			hci_cs_link_policy(hdev, ocf, cs->status);
			break;

		default:
			BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
			break;
		}

		if (cs->ncmd) {
			atomic_set(&hdev->cmd_cnt, 1);
			if (!skb_queue_empty(&hdev->cmd_q))
				hci_sched_cmd(hdev);
		}
		break;

	case HCI_EV_CMD_COMPLETE:
		ec = (struct hci_ev_cmd_complete *) skb->data;
		skb_pull(skb, sizeof(*ec));

		opcode = __le16_to_cpu(ec->opcode);
		ogf = hci_opcode_ogf(opcode);
		ocf = hci_opcode_ocf(opcode);

		switch (ogf) {
		case OGF_INFO_PARAM:
			hci_cc_info_param(hdev, ocf, skb);
			break;

		case OGF_HOST_CTL:
			hci_cc_host_ctl(hdev, ocf, skb);
			break;

		case OGF_LINK_CTL:
			hci_cc_link_ctl(hdev, ocf, skb);
			break;

		case OGF_LINK_POLICY:
			hci_cc_link_policy(hdev, ocf, skb);
			break;

		default:
			BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
			break;
		}

		if (ec->ncmd) {
			atomic_set(&hdev->cmd_cnt, 1);
			if (!skb_queue_empty(&hdev->cmd_q))
				hci_sched_cmd(hdev);
		}
		break;
	}

	kfree_skb(skb);
	hdev->stat.evt_rx++;
}
예제 #2
0
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
	hci_event_hdr *he = (hci_event_hdr *) skb->data;
	evt_cmd_status *cs;
	evt_cmd_complete *ec;
	__u16 opcode, ocf, ogf;

	skb_pull(skb, HCI_EVENT_HDR_SIZE);

	BT_DBG("%s evt 0x%x", hdev->name, he->evt);

	switch (he->evt) {
	case EVT_NUM_COMP_PKTS:
		hci_num_comp_pkts_evt(hdev, skb);
		break;

	case EVT_INQUIRY_COMPLETE:
		hci_inquiry_complete_evt(hdev, skb);
		break;

	case EVT_INQUIRY_RESULT:
		hci_inquiry_result_evt(hdev, skb);
		break;

	case EVT_INQUIRY_RESULT_WITH_RSSI:
		hci_inquiry_result_with_rssi_evt(hdev, skb);
		break;

	case EVT_CONN_REQUEST:
		hci_conn_request_evt(hdev, skb);
		break;

	case EVT_CONN_COMPLETE:
		hci_conn_complete_evt(hdev, skb);
		break;

	case EVT_DISCONN_COMPLETE:
		hci_disconn_complete_evt(hdev, skb);
		break;

	case EVT_ROLE_CHANGE:
		hci_role_change_evt(hdev, skb);
		break;

	case EVT_AUTH_COMPLETE:
		hci_auth_complete_evt(hdev, skb);
		break;

	case EVT_ENCRYPT_CHANGE:
		hci_encrypt_change_evt(hdev, skb);
		break;

	case EVT_CMD_STATUS:
		cs = (evt_cmd_status *) skb->data;
		skb_pull(skb, EVT_CMD_STATUS_SIZE);
				
		opcode = __le16_to_cpu(cs->opcode);
		ogf = cmd_opcode_ogf(opcode);
		ocf = cmd_opcode_ocf(opcode);

		switch (ogf) {
		case OGF_INFO_PARAM:
			hci_cs_info_param(hdev, ocf, cs->status);
			break;

		case OGF_HOST_CTL:
			hci_cs_host_ctl(hdev, ocf, cs->status);
			break;

		case OGF_LINK_CTL:
			hci_cs_link_ctl(hdev, ocf, cs->status);
			break;

		case OGF_LINK_POLICY:
			hci_cs_link_policy(hdev, ocf, cs->status);
			break;

		default:
			BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
			break;
		};

		if (cs->ncmd) {
			atomic_set(&hdev->cmd_cnt, 1);
			if (!skb_queue_empty(&hdev->cmd_q))
				hci_sched_cmd(hdev);
		}
		break;

	case EVT_CMD_COMPLETE:
		ec = (evt_cmd_complete *) skb->data;
		skb_pull(skb, EVT_CMD_COMPLETE_SIZE);

		opcode = __le16_to_cpu(ec->opcode);
		ogf = cmd_opcode_ogf(opcode);
		ocf = cmd_opcode_ocf(opcode);

		switch (ogf) {
		case OGF_INFO_PARAM:
			hci_cc_info_param(hdev, ocf, skb);
			break;

		case OGF_HOST_CTL:
			hci_cc_host_ctl(hdev, ocf, skb);
			break;

		case OGF_LINK_CTL:
			hci_cc_link_ctl(hdev, ocf, skb);
			break;

		case OGF_LINK_POLICY:
			hci_cc_link_policy(hdev, ocf, skb);
			break;

		default:
			BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
			break;
		};

		if (ec->ncmd) {
			atomic_set(&hdev->cmd_cnt, 1);
			if (!skb_queue_empty(&hdev->cmd_q))
				hci_sched_cmd(hdev);
		}
		break;
	};

	kfree_skb(skb);
	hdev->stat.evt_rx++;
}