Commit 7fbec224 authored by Antti Julku's avatar Antti Julku Committed by Gustavo F. Padovan
Browse files

Bluetooth: Add blacklisting support for mgmt interface



Management interface commands for blocking and unblocking devices.

Signed-off-by: default avatarAntti Julku <antti.julku@nokia.com>
Signed-off-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
parent b2a66aad
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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;
+70 −0
Original line number Diff line number Diff line
@@ -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);