Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6422ec6 authored by Antti Julku's avatar Antti Julku Committed by Gustavo Padovan
Browse files

Bluetooth: Add mgmt command for fast connectable mode



Add command to management interface for enabling/disabling the
fast connectable mode.

Signed-off-by: default avatarAntti Julku <antti.julku@nokia.com>
Signed-off-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
parent cfafccf7
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -716,6 +716,16 @@ struct hci_rp_read_bd_addr {
	bdaddr_t bdaddr;
} __packed;

#define HCI_OP_WRITE_PAGE_SCAN_ACTIVITY	0x0c1c
struct hci_cp_write_page_scan_activity {
	__le16   interval;
	__le16   window;
} __packed;

#define HCI_OP_WRITE_PAGE_SCAN_TYPE	0x0c47
	#define PAGE_SCAN_TYPE_STANDARD		0x00
	#define PAGE_SCAN_TYPE_INTERLACED	0x01

#define HCI_OP_LE_SET_EVENT_MASK	0x2001
struct hci_cp_le_set_event_mask {
	__u8     mask[8];
+5 −0
Original line number Diff line number Diff line
@@ -211,6 +211,11 @@ struct mgmt_cp_unblock_device {
	bdaddr_t bdaddr;
} __packed;

#define MGMT_OP_SET_FAST_CONNECTABLE	0x001F
struct mgmt_cp_set_fast_connectable {
	__u8 enable;
} __packed;

#define MGMT_EV_CMD_COMPLETE		0x0001
struct mgmt_ev_cmd_complete {
	__le16 opcode;
+60 −0
Original line number Diff line number Diff line
@@ -1760,6 +1760,62 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data,
	return err;
}

static int set_fast_connectable(struct sock *sk, u16 index,
					unsigned char *data, u16 len)
{
	struct hci_dev *hdev;
	struct mgmt_cp_set_fast_connectable *cp = (void *) data;
	struct hci_cp_write_page_scan_activity acp;
	u8 type;
	int err;

	BT_DBG("hci%u", index);

	if (len != sizeof(*cp))
		return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
								EINVAL);

	hdev = hci_dev_get(index);
	if (!hdev)
		return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
								ENODEV);

	hci_dev_lock(hdev);

	if (cp->enable) {
		type = PAGE_SCAN_TYPE_INTERLACED;
		acp.interval = 0x0024;	/* 22.5 msec page scan interval */
	} else {
		type = PAGE_SCAN_TYPE_STANDARD;	/* default */
		acp.interval = 0x0800;	/* default 1.28 sec page scan */
	}

	acp.window = 0x0012;	/* default 11.25 msec page scan window */

	err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
						sizeof(acp), &acp);
	if (err < 0) {
		err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
								-err);
		goto done;
	}

	err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
	if (err < 0) {
		err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
								-err);
		goto done;
	}

	err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
							NULL, 0);
done:
	hci_dev_unlock(hdev);
	hci_dev_put(hdev);

	return err;
}

int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
{
	unsigned char *buf;
@@ -1880,6 +1936,10 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
	case MGMT_OP_UNBLOCK_DEVICE:
		err = unblock_device(sk, index, buf + sizeof(*hdr), len);
		break;
	case MGMT_OP_SET_FAST_CONNECTABLE:
		err = set_fast_connectable(sk, index, buf + sizeof(*hdr),
								len);
		break;
	default:
		BT_DBG("Unknown op %u", opcode);
		err = cmd_status(sk, index, opcode, 0x01);