linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 0/5] Broadcaster/Observer MGMT API
@ 2012-08-10 21:01 Jefferson Delfes
  2012-08-10 21:01 ` [RFC 1/5] Bluetooth: Add new commands HCI for LE and BR/EDR Jefferson Delfes
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Jefferson Delfes @ 2012-08-10 21:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jefferson Delfes

After some discussions on BlueZ meeting, it was decided to have a MGMT API for
Broadcaster and Observer roles.

The normal flow for Broadcaster is set controller data for any data needed and
set broadcaster on. For now, kernel will try to pack as much data as possible
for Adv. In future, we may implement a rotation logic to send all data set by
userspace.
Use unset controller data with respective data_type to remove any data that
matches this data_type.
After adding or removing controller data, to update Adv data, you need to set
broadcaster off and after set broadcaster on, so adv. data can be updated on
the controller.

To start observer, just set observer to on. Any data will come from device
found event.

We have patches for userspace that will hit BlueZ ML next week.

Jefferson Delfes (5):
  Bluetooth: Add new commands HCI for LE and BR/EDR
  Bluetooth: Add set controller data MGMT command
  Bluetooth: Add unset controller data MGMT command
  Bluetooth: Add set broadcaster MGMT command
  Bluetooth: Add set observer MGMT command

 include/net/bluetooth/hci.h      |  30 +++++++
 include/net/bluetooth/hci_core.h |  15 ++++
 include/net/bluetooth/mgmt.h     |  23 ++++++
 net/bluetooth/hci_core.c         |  48 +++++++++++
 net/bluetooth/mgmt.c             | 167 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 283 insertions(+)

-- 
1.7.11.4


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [RFC 1/5] Bluetooth: Add new commands HCI for LE and BR/EDR
  2012-08-10 21:01 [RFC 0/5] Broadcaster/Observer MGMT API Jefferson Delfes
@ 2012-08-10 21:01 ` Jefferson Delfes
  2012-08-10 21:01 ` [RFC 2/5] Bluetooth: Add set controller data MGMT command Jefferson Delfes
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Jefferson Delfes @ 2012-08-10 21:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jefferson Delfes

Add some commands to control Advertising data.

Signed-off-by: Jefferson Delfes <jefferson.delfes@openbossa.org>
---
 include/net/bluetooth/hci.h | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 23cf413..e4d4717 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -326,6 +326,8 @@ enum {
 #define EIR_SSP_HASH_C		0x0E /* Simple Pairing Hash C */
 #define EIR_SSP_RAND_R		0x0F /* Simple Pairing Randomizer R */
 #define EIR_DEVICE_ID		0x10 /* device ID */
+#define EIR_SERVICE_DATA	0x16 /* Service Data */
+#define EIR_MANUFACTURER_DATA	0xFF /* Manufacturer Specific Data */
 
 /* -----  HCI Commands ---- */
 #define HCI_OP_NOP			0x0000
@@ -891,6 +893,32 @@ struct hci_rp_le_read_buffer_size {
 	__u8     le_max_pkt;
 } __packed;
 
+#define ADV_USE_ALL_CHANNELS	0x07
+
+#define HCI_OP_LE_SET_ADV_PARAMS	0x2006
+struct hci_cp_le_set_adv_params {
+	__le16   interval_min;
+	__le16   interval_max;
+	__u8     type;
+	__u8     own_address_type;
+	__u8     direct_address_type;
+	__u8     direct_address[6];
+	__u8     channel_map;
+	__u8     filter_policy;
+} __packed;
+
+#define HCI_MAX_ADV_LENGTH		31
+
+#define HCI_OP_LE_SET_ADV_DATA		0x2008
+struct hci_cp_le_set_adv_data {
+	__u8     data_len;
+	__u8     data[HCI_MAX_ADV_LENGTH];
+} __packed;
+
+#define HCI_OP_LE_SET_ADV_ENABLE	0x200a
+	#define ADVERTISING_DISABLE	0x00
+	#define ADVERTISING_ENABLE	0x01
+
 #define HCI_OP_LE_SET_SCAN_PARAM	0x200b
 struct hci_cp_le_set_scan_param {
 	__u8    type;
-- 
1.7.11.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [RFC 2/5] Bluetooth: Add set controller data MGMT command
  2012-08-10 21:01 [RFC 0/5] Broadcaster/Observer MGMT API Jefferson Delfes
  2012-08-10 21:01 ` [RFC 1/5] Bluetooth: Add new commands HCI for LE and BR/EDR Jefferson Delfes
@ 2012-08-10 21:01 ` Jefferson Delfes
  2012-08-10 21:01 ` [RFC 3/5] Bluetooth: Add unset " Jefferson Delfes
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Jefferson Delfes @ 2012-08-10 21:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jefferson Delfes

This command will be used to sets EIR data for BR/EDR and/or AD for LE.

Signed-off-by: Jefferson Delfes <jefferson.delfes@openbossa.org>
---
 include/net/bluetooth/hci_core.h | 14 ++++++++++++++
 include/net/bluetooth/mgmt.h     | 11 +++++++++++
 net/bluetooth/hci_core.c         | 32 ++++++++++++++++++++++++++++++++
 net/bluetooth/mgmt.c             | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 90 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 41d9439..3a61227 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -122,6 +122,14 @@ struct le_scan_params {
 	int timeout;
 };
 
+struct controller_data {
+	struct list_head list;
+	u8 flags;
+	u8 data_type;
+	u8 data_length;
+	u8 data[0];
+};
+
 #define HCI_MAX_SHORT_NAME_LENGTH	10
 
 #define NUM_REASSEMBLY 4
@@ -269,6 +277,8 @@ struct hci_dev {
 	struct work_struct	le_scan;
 	struct le_scan_params	le_scan_params;
 
+	struct list_head	controller_data;
+
 	int (*open)(struct hci_dev *hdev);
 	int (*close)(struct hci_dev *hdev);
 	int (*flush)(struct hci_dev *hdev);
@@ -715,6 +725,10 @@ void hci_conn_init_sysfs(struct hci_conn *conn);
 void hci_conn_add_sysfs(struct hci_conn *conn);
 void hci_conn_del_sysfs(struct hci_conn *conn);
 
+int hci_controller_data_add(struct hci_dev *hdev, u8 flags, u8 data_type,
+			    u8 data_length, u8 *data);
+int hci_controller_data_clear(struct hci_dev *hdev);
+
 #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev))
 
 /* ----- LMP capabilities ----- */
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 4348ee8..1afa399 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -350,6 +350,17 @@ struct mgmt_cp_set_device_id {
 } __packed;
 #define MGMT_SET_DEVICE_ID_SIZE		8
 
+#define MGMT_DATA_HIGH_PRIORITY		BIT(0)
+
+#define MGMT_OP_SET_CONTROLLER_DATA	0x0029
+struct mgmt_cp_set_controller_data {
+	__u8	flags;
+	__u8	data_type;
+	__u8	data_length;
+	__u8	data[0];
+} __packed;
+#define MGMT_SET_CONTROLLER_DATA_SIZE	3
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index fa974a1..2e38a1b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1441,6 +1441,36 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
 	return 0;
 }
 
+int hci_controller_data_add(struct hci_dev *hdev, u8 flags, u8 data_type,
+			    u8 data_length, u8 *data)
+{
+	struct controller_data *c_data;
+
+	c_data = kmalloc(sizeof(*c_data) + data_length, GFP_KERNEL);
+	if (!c_data)
+		return -ENOMEM;
+
+	c_data->flags = flags;
+	c_data->data_type = data_type;
+	c_data->data_length = data_length;
+	memcpy(c_data->data, data, data_length);
+
+	list_add(&c_data->list, &hdev->controller_data);
+	return 0;
+}
+
+int hci_controller_data_clear(struct hci_dev *hdev)
+{
+	struct controller_data *c_data, *n;
+
+	list_for_each_entry_safe(c_data, n, &hdev->controller_data, list) {
+		list_del(&c_data->list);
+		kfree(c_data);
+	}
+
+	return 0;
+}
+
 struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
 {
 	struct bdaddr_list *b;
@@ -1652,6 +1682,7 @@ struct hci_dev *hci_alloc_dev(void)
 	INIT_LIST_HEAD(&hdev->link_keys);
 	INIT_LIST_HEAD(&hdev->long_term_keys);
 	INIT_LIST_HEAD(&hdev->remote_oob_data);
+	INIT_LIST_HEAD(&hdev->controller_data);
 
 	INIT_WORK(&hdev->rx_work, hci_rx_work);
 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
@@ -1817,6 +1848,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
 	hci_link_keys_clear(hdev);
 	hci_smp_ltks_clear(hdev);
 	hci_remote_oob_data_clear(hdev);
+	hci_controller_data_clear(hdev);
 	hci_dev_unlock(hdev);
 
 	hci_dev_put(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a3329cb..9e9702a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2684,6 +2684,38 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
 	return 0;
 }
 
+static int set_controller_data(struct sock *sk, struct hci_dev *hdev,
+			       void *data, u16 len)
+{
+	struct mgmt_cp_set_controller_data *cp = data;
+
+	BT_DBG("%s", hdev->name);
+
+	if (cp->flags > MGMT_DATA_HIGH_PRIORITY)
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_CONTROLLER_DATA,
+				  MGMT_STATUS_INVALID_PARAMS);
+
+	if (cp->data_type != EIR_SERVICE_DATA &&
+	    cp->data_type != EIR_MANUFACTURER_DATA)
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_CONTROLLER_DATA,
+				  MGMT_STATUS_INVALID_PARAMS);
+
+	if (cp->data_length > HCI_MAX_EIR_LENGTH - 2)
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_CONTROLLER_DATA,
+				  MGMT_STATUS_INVALID_PARAMS);
+
+	BT_DBG("flags:0x%02x type:0x%02x length:%i", cp->flags, cp->data_type,
+	       cp->data_length);
+
+	hci_dev_lock(hdev);
+	hci_controller_data_add(hdev, cp->flags, cp->data_type, cp->data_length,
+				cp->data);
+	hci_dev_unlock(hdev);
+
+	return cmd_complete(sk, hdev->id, MGMT_OP_SET_CONTROLLER_DATA, 0, NULL,
+			    0);
+}
+
 static const struct mgmt_handler {
 	int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
 		     u16 data_len);
@@ -2731,6 +2763,7 @@ static const struct mgmt_handler {
 	{ block_device,           false, MGMT_BLOCK_DEVICE_SIZE },
 	{ unblock_device,         false, MGMT_UNBLOCK_DEVICE_SIZE },
 	{ set_device_id,          false, MGMT_SET_DEVICE_ID_SIZE },
+	{ set_controller_data,    true,  MGMT_SET_CONTROLLER_DATA_SIZE },
 };
 
 
-- 
1.7.11.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [RFC 3/5] Bluetooth: Add unset controller data MGMT command
  2012-08-10 21:01 [RFC 0/5] Broadcaster/Observer MGMT API Jefferson Delfes
  2012-08-10 21:01 ` [RFC 1/5] Bluetooth: Add new commands HCI for LE and BR/EDR Jefferson Delfes
  2012-08-10 21:01 ` [RFC 2/5] Bluetooth: Add set controller data MGMT command Jefferson Delfes
@ 2012-08-10 21:01 ` Jefferson Delfes
  2012-08-10 21:01 ` [RFC 4/5] Bluetooth: Add set broadcaster " Jefferson Delfes
  2012-08-10 21:01 ` [RFC 5/5] Bluetooth: Add set observer " Jefferson Delfes
  4 siblings, 0 replies; 8+ messages in thread
From: Jefferson Delfes @ 2012-08-10 21:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jefferson Delfes

This command will remove controller data from EIR and/or AD.

Signed-off-by: Jefferson Delfes <jefferson.delfes@openbossa.org>
---
 include/net/bluetooth/hci_core.h |  1 +
 include/net/bluetooth/mgmt.h     |  6 ++++++
 net/bluetooth/hci_core.c         | 16 ++++++++++++++++
 net/bluetooth/mgmt.c             | 16 ++++++++++++++++
 4 files changed, 39 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3a61227..5e6b477 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -728,6 +728,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 int hci_controller_data_add(struct hci_dev *hdev, u8 flags, u8 data_type,
 			    u8 data_length, u8 *data);
 int hci_controller_data_clear(struct hci_dev *hdev);
+int hci_controller_data_remove(struct hci_dev *hdev, u8 data_type);
 
 #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev))
 
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 1afa399..eda2755 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -361,6 +361,12 @@ struct mgmt_cp_set_controller_data {
 } __packed;
 #define MGMT_SET_CONTROLLER_DATA_SIZE	3
 
+#define MGMT_OP_UNSET_CONTROLLER_DATA	0x002A
+struct mgmt_cp_unset_controller_data {
+	__u8	data_type;
+} __packed;
+#define MGMT_UNSET_CONTROLLER_DATA_SIZE	1
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 2e38a1b..80280fa 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1471,6 +1471,22 @@ int hci_controller_data_clear(struct hci_dev *hdev)
 	return 0;
 }
 
+int hci_controller_data_remove(struct hci_dev *hdev, u8 data_type)
+{
+	struct controller_data *match, *n;
+	int matches = 0;
+
+	list_for_each_entry_safe(match, n, &hdev->controller_data, list) {
+		if (data_type == match->data_type) {
+			list_del(&match->list);
+			kfree(match);
+			matches++;
+		}
+	}
+
+	return matches;
+}
+
 struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
 {
 	struct bdaddr_list *b;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 9e9702a..51d0e2f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2716,6 +2716,21 @@ static int set_controller_data(struct sock *sk, struct hci_dev *hdev,
 			    0);
 }
 
+static int unset_controller_data(struct sock *sk, struct hci_dev *hdev,
+				 void *data, u16 len)
+{
+	struct mgmt_cp_unset_controller_data *cp = data;
+
+	BT_DBG("%s type:0x%02x", hdev->name, cp->data_type);
+
+	hci_dev_lock(hdev);
+	hci_controller_data_remove(hdev, cp->data_type);
+	hci_dev_unlock(hdev);
+
+	return cmd_complete(sk, hdev->id, MGMT_OP_UNSET_CONTROLLER_DATA, 0,
+			    NULL, 0);
+}
+
 static const struct mgmt_handler {
 	int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
 		     u16 data_len);
@@ -2764,6 +2779,7 @@ static const struct mgmt_handler {
 	{ unblock_device,         false, MGMT_UNBLOCK_DEVICE_SIZE },
 	{ set_device_id,          false, MGMT_SET_DEVICE_ID_SIZE },
 	{ set_controller_data,    true,  MGMT_SET_CONTROLLER_DATA_SIZE },
+	{ unset_controller_data,  false, MGMT_UNSET_CONTROLLER_DATA_SIZE },
 };
 
 
-- 
1.7.11.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [RFC 4/5] Bluetooth: Add set broadcaster MGMT command
  2012-08-10 21:01 [RFC 0/5] Broadcaster/Observer MGMT API Jefferson Delfes
                   ` (2 preceding siblings ...)
  2012-08-10 21:01 ` [RFC 3/5] Bluetooth: Add unset " Jefferson Delfes
@ 2012-08-10 21:01 ` Jefferson Delfes
  2012-08-14  9:13   ` Johan Hedberg
  2012-08-10 21:01 ` [RFC 5/5] Bluetooth: Add set observer " Jefferson Delfes
  4 siblings, 1 reply; 8+ messages in thread
From: Jefferson Delfes @ 2012-08-10 21:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jefferson Delfes

This command will enable or disable broadcaster mode. Data can be added
with set_controller_data command. If there are more data that can be
broadcasted, it will be ignored for while.

Signed-off-by: Jefferson Delfes <jefferson.delfes@openbossa.org>
---
 include/net/bluetooth/hci.h  |  1 +
 include/net/bluetooth/mgmt.h |  3 ++
 net/bluetooth/mgmt.c         | 75 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index e4d4717..80f585a 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -118,6 +118,7 @@ enum {
 	HCI_LINK_SECURITY,
 	HCI_PENDING_CLASS,
 	HCI_PERIODIC_INQ,
+	HCI_BROADCASTER,
 };
 
 /* HCI ioctl defines */
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index eda2755..2e85012 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -92,6 +92,7 @@ struct mgmt_rp_read_index_list {
 #define MGMT_SETTING_BREDR		0x00000080
 #define MGMT_SETTING_HS			0x00000100
 #define MGMT_SETTING_LE			0x00000200
+#define MGMT_SETTING_BROADCASTER	0x00000400
 
 #define MGMT_OP_READ_INFO		0x0004
 #define MGMT_READ_INFO_SIZE		0
@@ -367,6 +368,8 @@ struct mgmt_cp_unset_controller_data {
 } __packed;
 #define MGMT_UNSET_CONTROLLER_DATA_SIZE	1
 
+#define MGMT_OP_SET_BROADCASTER		0x002B
+
 #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 51d0e2f..ae4910a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -379,6 +379,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
 	settings |= MGMT_SETTING_FAST_CONNECTABLE;
 	settings |= MGMT_SETTING_DISCOVERABLE;
 	settings |= MGMT_SETTING_PAIRABLE;
+	settings |= MGMT_SETTING_BROADCASTER;
 
 	if (lmp_ssp_capable(hdev))
 		settings |= MGMT_SETTING_SSP;
@@ -419,6 +420,9 @@ static u32 get_current_settings(struct hci_dev *hdev)
 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
 		settings |= MGMT_SETTING_LE;
 
+	if (test_bit(HCI_BROADCASTER, &hdev->dev_flags))
+		settings |= MGMT_SETTING_BROADCASTER;
+
 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags))
 		settings |= MGMT_SETTING_LINK_SECURITY;
 
@@ -2731,6 +2735,76 @@ static int unset_controller_data(struct sock *sk, struct hci_dev *hdev,
 			    NULL, 0);
 }
 
+static int set_broadcaster_le(struct hci_dev *hdev, u8 enable)
+{
+	BT_DBG("%s enable:%i", hdev->name, enable);
+
+	if (enable) {
+		struct hci_cp_le_set_adv_params params;
+		struct hci_cp_le_set_adv_data data;
+		struct controller_data *d;
+
+		params.interval_min = __constant_cpu_to_le16(0x0800);
+		params.interval_max = __constant_cpu_to_le16(0x0800);
+		params.type = ADV_NONCONN_IND;
+		params.own_address_type = ADDR_LE_DEV_PUBLIC;
+		params.direct_address_type = ADDR_LE_DEV_PUBLIC;
+		memset(&params.direct_address, 0,
+		       sizeof(params.direct_address));
+		params.channel_map = ADV_USE_ALL_CHANNELS;
+		params.filter_policy = 0x00;
+		hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_PARAMS, sizeof(params),
+			     &params);
+
+		data.data_len = 0;
+		memset(&data.data, 0, sizeof(data.data));
+		list_for_each_entry(d, &hdev->controller_data, list) {
+			if (data.data_len + d->data_length + 2 >
+			    HCI_MAX_ADV_LENGTH)
+				break;
+
+			data.data[data.data_len] = d->data_length + 1;
+			data.data[data.data_len + 1] = d->data_type;
+			memcpy(&data.data[data.data_len + 2], d->data,
+			       d->data_length);
+			data.data_len += d->data_length + 2;
+		}
+		hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_DATA, sizeof(data), &data);
+	}
+
+	return hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable),
+			    &enable);
+}
+
+static int set_broadcaster(struct sock *sk, struct hci_dev *hdev, void *data,
+			   u16 len)
+{
+	struct mgmt_mode *cp = data;
+	int err;
+
+	BT_DBG("%s val:%i", hdev->name, cp->val);
+
+	if (cp->val)
+		set_bit(HCI_BROADCASTER, &hdev->dev_flags);
+	else
+		clear_bit(HCI_BROADCASTER, &hdev->dev_flags);
+
+	hci_dev_lock(hdev);
+
+	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
+		set_broadcaster_le(hdev, cp->val);
+
+	err = send_settings_rsp(sk, MGMT_OP_SET_BROADCASTER, hdev);
+	if (err < 0)
+		goto failed;
+
+	err = new_settings(hdev, sk);
+
+failed:
+	hci_dev_unlock(hdev);
+	return err;
+}
+
 static const struct mgmt_handler {
 	int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
 		     u16 data_len);
@@ -2780,6 +2854,7 @@ static const struct mgmt_handler {
 	{ set_device_id,          false, MGMT_SET_DEVICE_ID_SIZE },
 	{ set_controller_data,    true,  MGMT_SET_CONTROLLER_DATA_SIZE },
 	{ unset_controller_data,  false, MGMT_UNSET_CONTROLLER_DATA_SIZE },
+	{ set_broadcaster,        false, MGMT_SETTING_SIZE },
 };
 
 
-- 
1.7.11.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [RFC 5/5] Bluetooth: Add set observer MGMT command
  2012-08-10 21:01 [RFC 0/5] Broadcaster/Observer MGMT API Jefferson Delfes
                   ` (3 preceding siblings ...)
  2012-08-10 21:01 ` [RFC 4/5] Bluetooth: Add set broadcaster " Jefferson Delfes
@ 2012-08-10 21:01 ` Jefferson Delfes
  4 siblings, 0 replies; 8+ messages in thread
From: Jefferson Delfes @ 2012-08-10 21:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jefferson Delfes

This command will enable or disable observer mode. In that mode,
discovery will be started, so any broadcast will be received in device
found event.

Signed-off-by: Jefferson Delfes <jefferson.delfes@openbossa.org>
---
 include/net/bluetooth/hci.h  |  1 +
 include/net/bluetooth/mgmt.h |  3 +++
 net/bluetooth/mgmt.c         | 43 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 80f585a..17ea1ad 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -119,6 +119,7 @@ enum {
 	HCI_PENDING_CLASS,
 	HCI_PERIODIC_INQ,
 	HCI_BROADCASTER,
+	HCI_OBSERVER,
 };
 
 /* HCI ioctl defines */
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 2e85012..69525f9 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -93,6 +93,7 @@ struct mgmt_rp_read_index_list {
 #define MGMT_SETTING_HS			0x00000100
 #define MGMT_SETTING_LE			0x00000200
 #define MGMT_SETTING_BROADCASTER	0x00000400
+#define MGMT_SETTING_OBSERVER		0x00000800
 
 #define MGMT_OP_READ_INFO		0x0004
 #define MGMT_READ_INFO_SIZE		0
@@ -370,6 +371,8 @@ struct mgmt_cp_unset_controller_data {
 
 #define MGMT_OP_SET_BROADCASTER		0x002B
 
+#define MGMT_OP_SET_OBSERVER		0x002C
+
 #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 ae4910a..845ce2d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -380,6 +380,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
 	settings |= MGMT_SETTING_DISCOVERABLE;
 	settings |= MGMT_SETTING_PAIRABLE;
 	settings |= MGMT_SETTING_BROADCASTER;
+	settings |= MGMT_SETTING_OBSERVER;
 
 	if (lmp_ssp_capable(hdev))
 		settings |= MGMT_SETTING_SSP;
@@ -423,6 +424,9 @@ static u32 get_current_settings(struct hci_dev *hdev)
 	if (test_bit(HCI_BROADCASTER, &hdev->dev_flags))
 		settings |= MGMT_SETTING_BROADCASTER;
 
+	if (test_bit(HCI_OBSERVER, &hdev->dev_flags))
+		settings |= MGMT_SETTING_OBSERVER;
+
 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags))
 		settings |= MGMT_SETTING_LINK_SECURITY;
 
@@ -2805,6 +2809,44 @@ failed:
 	return err;
 }
 
+static int set_observer_le(struct hci_dev *hdev, u8 enable)
+{
+	struct hci_cp_le_set_scan_enable cmd;
+
+	cmd.enable = enable;
+	cmd.filter_dup = 0;
+	return hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cmd), &cmd);
+}
+
+static int set_observer(struct sock *sk, struct hci_dev *hdev, void *data,
+			u16 len)
+{
+	struct mgmt_mode *cp = data;
+	int err;
+
+	BT_DBG("%s val:%i", hdev->name, cp->val);
+
+	if (cp->val)
+		set_bit(HCI_OBSERVER, &hdev->dev_flags);
+	else
+		clear_bit(HCI_OBSERVER, &hdev->dev_flags);
+
+	hci_dev_lock(hdev);
+
+	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
+		set_observer_le(hdev, cp->val);
+
+	err = send_settings_rsp(sk, MGMT_OP_SET_OBSERVER, hdev);
+	if (err < 0)
+		goto failed;
+
+	err = new_settings(hdev, sk);
+
+failed:
+	hci_dev_unlock(hdev);
+	return err;
+}
+
 static const struct mgmt_handler {
 	int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
 		     u16 data_len);
@@ -2855,6 +2897,7 @@ static const struct mgmt_handler {
 	{ set_controller_data,    true,  MGMT_SET_CONTROLLER_DATA_SIZE },
 	{ unset_controller_data,  false, MGMT_UNSET_CONTROLLER_DATA_SIZE },
 	{ set_broadcaster,        false, MGMT_SETTING_SIZE },
+	{ set_observer,           false, MGMT_SETTING_SIZE },
 };
 
 
-- 
1.7.11.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [RFC 4/5] Bluetooth: Add set broadcaster MGMT command
  2012-08-10 21:01 ` [RFC 4/5] Bluetooth: Add set broadcaster " Jefferson Delfes
@ 2012-08-14  9:13   ` Johan Hedberg
  2012-08-29 17:42     ` Aloisio Almeida
  0 siblings, 1 reply; 8+ messages in thread
From: Johan Hedberg @ 2012-08-14  9:13 UTC (permalink / raw)
  To: Jefferson Delfes; +Cc: linux-bluetooth

Hi Jefferson,

On Fri, Aug 10, 2012, Jefferson Delfes wrote:
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -379,6 +379,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
>  	settings |= MGMT_SETTING_FAST_CONNECTABLE;
>  	settings |= MGMT_SETTING_DISCOVERABLE;
>  	settings |= MGMT_SETTING_PAIRABLE;
> +	settings |= MGMT_SETTING_BROADCASTER;

Shouldn't this be behind the same conditional as MGMT_SETTING_LE? I.e.
only when hdev->features indicates LE support.

Johan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC 4/5] Bluetooth: Add set broadcaster MGMT command
  2012-08-14  9:13   ` Johan Hedberg
@ 2012-08-29 17:42     ` Aloisio Almeida
  0 siblings, 0 replies; 8+ messages in thread
From: Aloisio Almeida @ 2012-08-29 17:42 UTC (permalink / raw)
  To: Jefferson Delfes, linux-bluetooth

Hi Johan,

It was decided to have broadcaster/observer in BR/EDR also. I think it
was decided in the Bluez meeting, right?

For now we're thinking in use this on BR/EDR only controllers. Dual
mode controllers would use LE for broadcasting.

I'm working on adding this feature right now. Further I'll send the v2.

Aloisio

On Tue, Aug 14, 2012 at 6:13 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Jefferson,
>
> On Fri, Aug 10, 2012, Jefferson Delfes wrote:
>> --- a/net/bluetooth/mgmt.c
>> +++ b/net/bluetooth/mgmt.c
>> @@ -379,6 +379,7 @@ static u32 get_supported_settings(struct hci_dev *hdev)
>>       settings |= MGMT_SETTING_FAST_CONNECTABLE;
>>       settings |= MGMT_SETTING_DISCOVERABLE;
>>       settings |= MGMT_SETTING_PAIRABLE;
>> +     settings |= MGMT_SETTING_BROADCASTER;
>
> Shouldn't this be behind the same conditional as MGMT_SETTING_LE? I.e.
> only when hdev->features indicates LE support.
>
> Johan
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2012-08-29 17:42 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-10 21:01 [RFC 0/5] Broadcaster/Observer MGMT API Jefferson Delfes
2012-08-10 21:01 ` [RFC 1/5] Bluetooth: Add new commands HCI for LE and BR/EDR Jefferson Delfes
2012-08-10 21:01 ` [RFC 2/5] Bluetooth: Add set controller data MGMT command Jefferson Delfes
2012-08-10 21:01 ` [RFC 3/5] Bluetooth: Add unset " Jefferson Delfes
2012-08-10 21:01 ` [RFC 4/5] Bluetooth: Add set broadcaster " Jefferson Delfes
2012-08-14  9:13   ` Johan Hedberg
2012-08-29 17:42     ` Aloisio Almeida
2012-08-10 21:01 ` [RFC 5/5] Bluetooth: Add set observer " Jefferson Delfes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).