patch-2.4.21 linux-2.4.21/net/bluetooth/hci_sock.c

Next file: linux-2.4.21/net/bluetooth/l2cap.c
Previous file: linux-2.4.21/net/bluetooth/hci_core.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.20/net/bluetooth/hci_sock.c linux-2.4.21/net/bluetooth/hci_sock.c
@@ -49,6 +49,7 @@
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -68,14 +69,17 @@
 	{ 0xd9fe, 0x0 },
 	/* Commands */
 	{
+		{ 0x0 },
 		/* OGF_LINK_CTL */
-		{ 0x2a000002, 0x0, 0x0, 0x0 },
+		{ 0x2a000002, 0x0, 0x0, 0x0  },
 		/* OGF_LINK_POLICY */
-		{ 0x1200, 0x0, 0x0, 0x0     },
+		{ 0x1200, 0x0, 0x0, 0x0      },
 		/* OGF_HOST_CTL */
-		{ 0x80100000, 0xa, 0x0, 0x0 },
+		{ 0x80100000, 0x2a, 0x0, 0x0 },
 		/* OGF_INFO_PARAM */
-		{ 0x22a, 0x0, 0x0, 0x0      }
+		{ 0x22a, 0x0, 0x0, 0x0       },
+		/* OGF_STATUS_PARAM */
+		{ 0x2e, 0x0, 0x0, 0x0        }
 	}
 };
 
@@ -387,25 +391,37 @@
 
 	skb->pkt_type = *((unsigned char *) skb->data);
 	skb_pull(skb, 1);
+	skb->dev = (void *) hdev;
 
-	if (!capable(CAP_NET_RAW)) {
-		err = -EPERM;
+	if (skb->pkt_type == HCI_COMMAND_PKT) {
+		u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data));
+		u16 ogf = cmd_opcode_ogf(opcode);
+		u16 ocf = cmd_opcode_ocf(opcode);
+
+		if (((ogf > HCI_SFLT_MAX_OGF) || 
+				!hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
+		    			!capable(CAP_NET_RAW)) {
+			err = -EPERM;
+			goto drop;
+		}
 
-		if (skb->pkt_type == HCI_COMMAND_PKT) {
-			__u16 opcode = __le16_to_cpu(*(__u16 *)skb->data);
-			__u16 ogf = cmd_opcode_ogf(opcode) - 1;
-			__u16 ocf = cmd_opcode_ocf(opcode) & HCI_FLT_OCF_BITS;
-
-			if (ogf > HCI_SFLT_MAX_OGF ||
-					!hci_test_bit(ocf, &hci_sec_filter.ocf_mask[ogf]))
-				goto drop;
-		} else
+		if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
+			skb_queue_tail(&hdev->raw_q, skb);
+			hci_sched_tx(hdev);
+		} else {
+			skb_queue_tail(&hdev->cmd_q, skb);
+			hci_sched_cmd(hdev);
+		}
+	} else {
+		if (!capable(CAP_NET_RAW)) {
+			err = -EPERM;
 			goto drop;
+		}
+
+		skb_queue_tail(&hdev->raw_q, skb);
+		hci_sched_tx(hdev);
 	}
-		
-	/* Send frame to HCI core */
-	skb->dev = (void *) hdev;
-	hci_send_raw(skb);
+
 	err = len;
 
 done:

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)