bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) { struct hci_event_hdr *hdr = (void *) skb->data; if (hdr->evt == HCI_EV_CMD_COMPLETE) { struct hci_ev_cmd_complete *ec; u16 opcode, ocf, ogf; ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); opcode = __le16_to_cpu(ec->opcode); ocf = hci_opcode_ocf(opcode); ogf = hci_opcode_ogf(opcode); if (ocf == BT_CMD_MODULE_CFG_REQ && priv->btmrvl_dev.sendcmdflag) { priv->btmrvl_dev.sendcmdflag = false; priv->adapter->cmd_complete = true; wake_up_interruptible(&priv->adapter->cmd_wait_q); } if (ogf == OGF) { BT_DBG("vendor event skipped: ogf 0x%4.4x ocf 0x%4.4x", ogf, ocf); kfree_skb(skb); return false; } } return true; }
void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) { struct hci_event_hdr *hdr = (void *) skb->data; struct hci_ev_cmd_complete *ec; u16 opcode, ocf; if (hdr->evt == HCI_EV_CMD_COMPLETE) { ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); opcode = __le16_to_cpu(ec->opcode); ocf = hci_opcode_ocf(opcode); if (ocf == BT_CMD_MODULE_CFG_REQ && priv->btmrvl_dev.sendcmdflag) { priv->btmrvl_dev.sendcmdflag = false; priv->adapter->cmd_complete = true; wake_up_interruptible(&priv->adapter->cmd_wait_q); } } }
/** * @brief This function verify the received event pkt * * Event format: * +--------+--------+--------+--------+--------+ * | Event | Length | ncmd | Opcode | * +--------+--------+--------+--------+--------+ * | 1-byte | 1-byte | 1-byte | 2-byte | * +--------+--------+--------+--------+--------+ * * @param priv A pointer to bt_private structure * @param skb A pointer to rx skb * @return N/A */ void check_evtpkt(bt_private * priv, struct sk_buff *skb) { struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data; struct hci_ev_cmd_complete *ec; u16 opcode, ocf; ENTER(); if (hdr->evt == HCI_EV_CMD_COMPLETE) { ec = (struct hci_ev_cmd_complete *) (skb->data + HCI_EVENT_HDR_SIZE); opcode = __le16_to_cpu(ec->opcode); ocf = hci_opcode_ocf(opcode); if ((ocf == BT_CMD_MODULE_CFG_REQ) && (priv->bt_dev.sendcmdflag == TRUE)) { priv->bt_dev.sendcmdflag = FALSE; priv->adapter->cmd_complete = TRUE; wake_up_interruptible(&priv->adapter->cmd_wait_q); } } LEAVE(); return; }
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++; }