Commit d5b82b88 authored by Maksim Krasnyanskiy's avatar Maksim Krasnyanskiy

Merge bk://linux-bt.bkbits.net/marcel-2.5

into qualcomm.com:/usr/src/linux-2.5
parents 05b9ae6f 69990bbc
......@@ -85,6 +85,7 @@ enum {
#define HCISETLINKMODE _IOW('H', 226, int)
#define HCISETACLMTU _IOW('H', 227, int)
#define HCISETSCOMTU _IOW('H', 228, int)
#define HCISETRAWVND _IOW('H', 229, int)
#define HCIINQUIRY _IOR('H', 240, int)
......@@ -386,6 +387,12 @@ struct hci_rp_write_link_policy {
/* Status params */
#define OGF_STATUS_PARAM 0x05
/* Testing commands */
#define OGF_TESTING_CMD 0x3E
/* Vendor specific commands */
#define OGF_VENDOR_CMD 0x3F
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
......
......@@ -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,40 +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:
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:
......
......@@ -257,7 +257,7 @@ static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *de
static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, int priority)
{
if (size || atomic_read(&dev->wmem_alloc) < dev->sndbuf) {
if (atomic_read(&dev->wmem_alloc) < dev->sndbuf) {
struct sk_buff *skb = alloc_skb(size, priority);
if (skb) {
rfcomm_set_owner_w(skb, dev);
......
......@@ -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