Commit 69990bbc authored by Marcel Holtmann's avatar Marcel Holtmann Committed by Marcel Holtmann

[Bluetooth] Get rid of hci_send_raw()

This patch removes the function hci_send_raw() and puts all its
logic directly into hci_sock_sendmsg().
parent 00a2c1c6
......@@ -472,7 +472,6 @@ int hci_unregister_notifier(struct notifier_block *nb);
int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
int hci_send_raw(struct sk_buff *skb);
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
......@@ -490,7 +489,7 @@ struct hci_pinfo {
};
/* HCI security filter */
#define HCI_SFLT_MAX_OGF 4
#define HCI_SFLT_MAX_OGF 5
struct hci_sec_filter {
unsigned long type_mask;
......
......@@ -951,43 +951,6 @@ static int hci_send_frame(struct sk_buff *skb)
return hdev->send(skb);
}
/* Send raw HCI frame */
int hci_send_raw(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
if (!hdev) {
kfree_skb(skb);
return -ENODEV;
}
BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
if (!test_bit(HCI_RAW, &hdev->flags)) {
/* Queue frame according it's type */
switch (skb->pkt_type) {
case HCI_COMMAND_PKT:
if (cmd_opcode_ogf(__le16_to_cpu(*(__u16 *)skb->data)) == OGF_VENDOR_CMD)
break;
skb_queue_tail(&hdev->cmd_q, skb);
hci_sched_cmd(hdev);
return 0;
case HCI_ACLDATA_PKT:
case HCI_SCODATA_PKT:
/* FIXME:
* Check header here and queue to apropriate connection.
*/
break;
}
}
skb_queue_tail(&hdev->raw_q, skb);
hci_sched_tx(hdev);
return 0;
}
/* Send HCI command */
int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
{
......
......@@ -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,6 +69,7 @@ static struct hci_sec_filter hci_sec_filter = {
{ 0xd9fe, 0x0 },
/* Commands */
{
{ 0x0 },
/* OGF_LINK_CTL */
{ 0x2a000002, 0x0, 0x0, 0x0 },
/* OGF_LINK_POLICY */
......@@ -75,7 +77,9 @@ static struct hci_sec_filter hci_sec_filter = {
/* OGF_HOST_CTL */
{ 0x80100000, 0x2a, 0x0, 0x0 },
/* OGF_INFO_PARAM */
{ 0x22a, 0x0, 0x0, 0x0 }
{ 0x22a, 0x0, 0x0, 0x0 },
/* OGF_STATUS_PARAM */
{ 0x2e, 0x0, 0x0, 0x0 }
}
};
......@@ -388,25 +392,37 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
skb->pkt_type = *((unsigned char *) skb->data);
skb_pull(skb, 1);
if (!capable(CAP_NET_RAW)) {
err = -EPERM;
skb->dev = (void *) hdev;
if (skb->pkt_type == HCI_COMMAND_PKT) {
u16 opcode = __le16_to_cpu(*(__u16 *)skb->data);
u16 ogf = hci_opcode_ogf(opcode) - 1;
u16 ocf = hci_opcode_ocf(opcode) & HCI_FLT_OCF_BITS;
u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data));
u16 ogf = hci_opcode_ogf(opcode);
u16 ocf = hci_opcode_ocf(opcode);
if (ogf > HCI_SFLT_MAX_OGF ||
!test_bit(ocf, hci_sec_filter.ocf_mask[ogf]))
if (((ogf > HCI_SFLT_MAX_OGF) ||
!test_bit(ocf & HCI_FLT_OCF_BITS, hci_sec_filter.ocf_mask[ogf])) &&
!capable(CAP_NET_RAW)) {
err = -EPERM;
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;
}
/* Send frame to HCI core */
skb->dev = (void *) hdev;
hci_send_raw(skb);
skb_queue_tail(&hdev->raw_q, skb);
hci_sched_tx(hdev);
}
err = len;
done:
......
......@@ -58,7 +58,7 @@ EXPORT_SYMBOL(hci_conn_encrypt);
EXPORT_SYMBOL(hci_send_acl);
EXPORT_SYMBOL(hci_send_sco);
EXPORT_SYMBOL(hci_send_raw);
EXPORT_SYMBOL(hci_send_cmd);
EXPORT_SYMBOL(hci_si_event);
/* Bluetooth lib */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment