Bluetooth: Add support for vendor specific diagnostic channel
authorMarcel Holtmann <marcel@holtmann.org>
Wed, 7 Oct 2015 14:38:35 +0000 (16:38 +0200)
committerJohan Hedberg <johan.hedberg@intel.com>
Thu, 8 Oct 2015 06:51:13 +0000 (09:51 +0300)
Introduce hci_recv_diag function for HCI drivers to allow sending vendor
specific diagnostic messages into the Bluetooth core stack. The messages
are not processed, but they are forwarded to the monitor channel and can
be retrieved by user space diagnostic tools.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_mon.h
net/bluetooth/hci_core.c
net/bluetooth/hci_sock.c

index e7f938cac7c663b207e5f8bbbdbe65058f0bd491..cf75c4391945e7ba2925f05733211ddda0f7b8cf 100644 (file)
@@ -262,6 +262,7 @@ enum {
 #define HCI_ACLDATA_PKT                0x02
 #define HCI_SCODATA_PKT                0x03
 #define HCI_EVENT_PKT          0x04
+#define HCI_DIAG_PKT           0xf0
 #define HCI_VENDOR_PKT         0xff
 
 /* HCI packet types */
index 61dc786358bee8afdfd93a07dbf6f91bc002b4ee..d473b67a2c65061e236df6797a4f47889dc659b8 100644 (file)
@@ -1066,6 +1066,7 @@ int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance);
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
 int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb);
+int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb);
 
 void hci_init_sysfs(struct hci_dev *hdev);
 void hci_conn_init_sysfs(struct hci_conn *conn);
index 842bb754a0789c94057089e45956f491d3412906..2b67567cf28d6d3c9b762ab0226a7818464428d2 100644 (file)
@@ -42,6 +42,7 @@ struct hci_mon_hdr {
 #define HCI_MON_OPEN_INDEX     8
 #define HCI_MON_CLOSE_INDEX    9
 #define HCI_MON_INDEX_INFO     10
+#define HCI_MON_VENDOR_DIAG    11
 
 struct hci_mon_new_index {
        __u8            type;
index 40a67017bd325efc75b81098d09bea76b7db1ac2..8193845a9b60defb8d21477157b30c09fb0c5d12 100644 (file)
@@ -3493,6 +3493,21 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(hci_recv_frame);
 
+/* Receive diagnostic message from HCI drivers */
+int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       /* Time stamp */
+       __net_timestamp(skb);
+
+       /* Mark as diagnostic packet and send to monitor */
+       bt_cb(skb)->pkt_type = HCI_DIAG_PKT;
+       hci_send_to_monitor(hdev, skb);
+
+       kfree_skb(skb);
+       return 0;
+}
+EXPORT_SYMBOL(hci_recv_diag);
+
 /* ---- Interface to upper protocols ---- */
 
 int hci_register_cb(struct hci_cb *cb)
index 9bf30db89d894456c0eb7a3b4199d98ce5ce0cf2..9a100c1fd7b5ec13cdec4b852e70ca769700a067 100644 (file)
@@ -279,6 +279,9 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
                else
                        opcode = cpu_to_le16(HCI_MON_SCO_TX_PKT);
                break;
+       case HCI_DIAG_PKT:
+               opcode = cpu_to_le16(HCI_MON_VENDOR_DIAG);
+               break;
        default:
                return;
        }