Move blacklisting functions to hci_core.c, so that they can
be used by both management interface and hci socket interface.
Signed-off-by: Antti Julku <[email protected]>
---
include/net/bluetooth/hci_core.h | 2 +
net/bluetooth/hci_core.c | 79 ++++++++++++++++++++++++++++++++++++++
net/bluetooth/hci_sock.c | 70 +++------------------------------
3 files changed, 87 insertions(+), 64 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index fe05946..26233d4 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -529,6 +529,8 @@ int hci_inquiry(void __user *arg);
struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_blacklist_clear(struct hci_dev *hdev);
+int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr);
+int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_uuids_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index f62ca19..8f5bee1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1205,6 +1205,85 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
return 0;
}
+struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
+ bdaddr_t *bdaddr)
+{
+ struct list_head *p;
+
+ list_for_each(p, &hdev->blacklist) {
+ struct bdaddr_list *b;
+
+ b = list_entry(p, struct bdaddr_list, list);
+
+ if (bacmp(bdaddr, &b->bdaddr) == 0)
+ return b;
+ }
+
+ return NULL;
+}
+
+int hci_blacklist_clear(struct hci_dev *hdev)
+{
+ struct list_head *p, *n;
+
+ list_for_each_safe(p, n, &hdev->blacklist) {
+ struct bdaddr_list *b;
+
+ b = list_entry(p, struct bdaddr_list, list);
+
+ list_del(p);
+ kfree(b);
+ }
+
+ return 0;
+}
+
+int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+ struct bdaddr_list *entry;
+
+ hci_dev_lock(hdev);
+
+ if (bacmp(bdaddr, BDADDR_ANY) == 0)
+ return -EBADF;
+
+ if (hci_blacklist_lookup(hdev, bdaddr))
+ return -EEXIST;
+
+ entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
+ bacpy(&entry->bdaddr, bdaddr);
+
+ list_add(&entry->list, &hdev->blacklist);
+
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
+int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+ struct bdaddr_list *entry;
+
+ hci_dev_lock(hdev);
+
+ if (bacmp(bdaddr, BDADDR_ANY) == 0)
+ return hci_blacklist_clear(hdev);
+
+ entry = hci_blacklist_lookup(hdev, bdaddr);
+ if (!entry)
+ return -ENOENT;
+
+ list_del(&entry->list);
+ kfree(entry);
+
+ hci_dev_unlock(hdev);
+
+ return 0;
+}
+
static void hci_clear_adv_cache(unsigned long arg)
{
struct hci_dev *hdev = (void *) arg;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 295e4a8..ff02cf5 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -180,82 +180,24 @@ static int hci_sock_release(struct socket *sock)
return 0;
}
-struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
-{
- struct list_head *p;
-
- list_for_each(p, &hdev->blacklist) {
- struct bdaddr_list *b;
-
- b = list_entry(p, struct bdaddr_list, list);
-
- if (bacmp(bdaddr, &b->bdaddr) == 0)
- return b;
- }
-
- return NULL;
-}
-
-static int hci_blacklist_add(struct hci_dev *hdev, void __user *arg)
+static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
{
bdaddr_t bdaddr;
- struct bdaddr_list *entry;
if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
return -EFAULT;
- if (bacmp(&bdaddr, BDADDR_ANY) == 0)
- return -EBADF;
-
- if (hci_blacklist_lookup(hdev, &bdaddr))
- return -EEXIST;
-
- entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
- if (!entry)
- return -ENOMEM;
-
- bacpy(&entry->bdaddr, &bdaddr);
-
- list_add(&entry->list, &hdev->blacklist);
-
- return 0;
-}
-
-int hci_blacklist_clear(struct hci_dev *hdev)
-{
- struct list_head *p, *n;
-
- list_for_each_safe(p, n, &hdev->blacklist) {
- struct bdaddr_list *b;
-
- b = list_entry(p, struct bdaddr_list, list);
-
- list_del(p);
- kfree(b);
- }
-
- return 0;
+ return hci_blacklist_add(hdev, &bdaddr);
}
-static int hci_blacklist_del(struct hci_dev *hdev, void __user *arg)
+static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
{
bdaddr_t bdaddr;
- struct bdaddr_list *entry;
if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
return -EFAULT;
- if (bacmp(&bdaddr, BDADDR_ANY) == 0)
- return hci_blacklist_clear(hdev);
-
- entry = hci_blacklist_lookup(hdev, &bdaddr);
- if (!entry)
- return -ENOENT;
-
- list_del(&entry->list);
- kfree(entry);
-
- return 0;
+ return hci_blacklist_del(hdev, &bdaddr);
}
/* Ioctls that require bound socket */
@@ -290,12 +232,12 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
case HCIBLOCKADDR:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
- return hci_blacklist_add(hdev, (void __user *) arg);
+ return hci_sock_blacklist_add(hdev, (void __user *) arg);
case HCIUNBLOCKADDR:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
- return hci_blacklist_del(hdev, (void __user *) arg);
+ return hci_sock_blacklist_del(hdev, (void __user *) arg);
default:
if (hdev->ioctl)
--
1.7.2.5
* Johan Hedberg <[email protected]> [2011-06-15 22:48:49 +0300]:
> Hi Gustavo,
>
> On Wed, Jun 15, 2011, Gustavo F. Padovan wrote:
> > > +#define MGMT_OP_BLOCK_DEVICE 0x001D
> > > +struct mgmt_cp_block_device {
> > > + bdaddr_t bdaddr;
> > > +} __packed;
> > > +
> > > +#define MGMT_OP_UNBLOCK_DEVICE 0x001E
> >
> > To make hci code consistent call replace _DEVICE by _ADDR in both macros.
>
> I think Antti was just taking example from MGMT_OP_PAIR_DEVICE. To me
> "device" sounds better than "addr" as far as the management interface is
> concerned, but I'm not gonna object if you wanna change these
> occurrences to addr.
Fair enough. Both patches applied. Thanks.
Gustavo
Hi Gustavo,
On Wed, Jun 15, 2011, Gustavo F. Padovan wrote:
> > +#define MGMT_OP_BLOCK_DEVICE 0x001D
> > +struct mgmt_cp_block_device {
> > + bdaddr_t bdaddr;
> > +} __packed;
> > +
> > +#define MGMT_OP_UNBLOCK_DEVICE 0x001E
>
> To make hci code consistent call replace _DEVICE by _ADDR in both macros.
I think Antti was just taking example from MGMT_OP_PAIR_DEVICE. To me
"device" sounds better than "addr" as far as the management interface is
concerned, but I'm not gonna object if you wanna change these
occurrences to addr.
Johan
Johan
* Antti Julku <[email protected]> [2011-06-15 12:01:15 +0300]:
> Management interface commands for blocking and unblocking devices.
>
> Signed-off-by: Antti Julku <[email protected]>
> ---
> include/net/bluetooth/mgmt.h | 10 ++++++
> net/bluetooth/mgmt.c | 70 ++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 80 insertions(+), 0 deletions(-)
>
> diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
> index 4899286..45bea25 100644
> --- a/include/net/bluetooth/mgmt.h
> +++ b/include/net/bluetooth/mgmt.h
> @@ -199,6 +199,16 @@ struct mgmt_cp_remove_remote_oob_data {
>
> #define MGMT_OP_STOP_DISCOVERY 0x001C
>
> +#define MGMT_OP_BLOCK_DEVICE 0x001D
> +struct mgmt_cp_block_device {
> + bdaddr_t bdaddr;
> +} __packed;
> +
> +#define MGMT_OP_UNBLOCK_DEVICE 0x001E
To make hci code consistent call replace _DEVICE by _ADDR in both macros.
Gustavo
Management interface commands for blocking and unblocking devices.
Signed-off-by: Antti Julku <[email protected]>
---
include/net/bluetooth/mgmt.h | 10 ++++++
net/bluetooth/mgmt.c | 70 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 4899286..45bea25 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -199,6 +199,16 @@ struct mgmt_cp_remove_remote_oob_data {
#define MGMT_OP_STOP_DISCOVERY 0x001C
+#define MGMT_OP_BLOCK_DEVICE 0x001D
+struct mgmt_cp_block_device {
+ bdaddr_t bdaddr;
+} __packed;
+
+#define MGMT_OP_UNBLOCK_DEVICE 0x001E
+struct mgmt_cp_unblock_device {
+ bdaddr_t bdaddr;
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d192089..64c0418 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1666,6 +1666,70 @@ failed:
return err;
}
+static int block_device(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
+{
+ struct hci_dev *hdev;
+ struct mgmt_cp_block_device *cp;
+ int err;
+
+ BT_DBG("hci%u", index);
+
+ cp = (void *) data;
+
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
+ EINVAL);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
+ ENODEV);
+
+ err = hci_blacklist_add(hdev, &cp->bdaddr);
+
+ if (err < 0)
+ err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, -err);
+ else
+ err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE,
+ NULL, 0);
+ hci_dev_put(hdev);
+
+ return err;
+}
+
+static int unblock_device(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
+{
+ struct hci_dev *hdev;
+ struct mgmt_cp_unblock_device *cp;
+ int err;
+
+ BT_DBG("hci%u", index);
+
+ cp = (void *) data;
+
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
+ EINVAL);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
+ ENODEV);
+
+ err = hci_blacklist_del(hdev, &cp->bdaddr);
+
+ if (err < 0)
+ err = cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, -err);
+ else
+ err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE,
+ NULL, 0);
+ hci_dev_put(hdev);
+
+ return err;
+}
+
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
{
unsigned char *buf;
@@ -1780,6 +1844,12 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
case MGMT_OP_STOP_DISCOVERY:
err = stop_discovery(sk, index);
break;
+ case MGMT_OP_BLOCK_DEVICE:
+ err = block_device(sk, index, buf + sizeof(*hdr), len);
+ break;
+ case MGMT_OP_UNBLOCK_DEVICE:
+ err = unblock_device(sk, index, buf + sizeof(*hdr), len);
+ break;
default:
BT_DBG("Unknown op %u", opcode);
err = cmd_status(sk, index, opcode, 0x01);
--
1.7.2.5