Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: Remove no longer needed mgmt_new_settings() function
From: Marcel Holtmann @ 2013-10-06 11:11 UTC (permalink / raw)
  To: linux-bluetooth

The mgmt_new_settings() function was only needed to handle the
error case when re-enabling advertising failed. Since that is
now handled internally inside the management core, this function
is not needed anymore. So just remove it.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h | 1 -
 net/bluetooth/mgmt.c             | 9 ++-------
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 869f6ad..30e0fbb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1094,7 +1094,6 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
 int mgmt_index_added(struct hci_dev *hdev);
 int mgmt_index_removed(struct hci_dev *hdev);
-int mgmt_new_settings(struct hci_dev *hdev);
 int mgmt_set_powered_failed(struct hci_dev *hdev, int err);
 int mgmt_powered(struct hci_dev *hdev, u8 powered);
 int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 381faf6..dd48e2a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -890,11 +890,6 @@ static int new_settings(struct hci_dev *hdev, struct sock *skip)
 	return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip);
 }
 
-int mgmt_new_settings(struct hci_dev *hdev)
-{
-	return new_settings(hdev, NULL);
-}
-
 struct cmd_lookup {
 	struct sock *sk;
 	struct hci_dev *hdev;
@@ -4668,7 +4663,7 @@ static void adv_enable_complete(struct hci_dev *hdev, u8 status)
 	/* Clear the advertising mgmt setting if we failed to re-enable it */
 	if (status) {
 		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-		mgmt_new_settings(hdev);
+		new_settings(hdev, NULL);
 	}
 }
 
@@ -4690,6 +4685,6 @@ void mgmt_reenable_advertising(struct hci_dev *hdev)
 	 */
 	if (hci_req_run(&req, adv_enable_complete) < 0) {
 		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-		mgmt_new_settings(hdev);
+		new_settings(hdev, NULL);
 	}
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Use helper function for re-enabling advertising
From: Marcel Holtmann @ 2013-10-06 11:08 UTC (permalink / raw)
  To: linux-bluetooth

When the all LE connections have been disconneted, then it is up to
the host to re-enable advertising at that point. To ensure that the
correct advertising parameters are used, force the usage of the
common helper to enable advertising.

The change just moves the manual enabling of advertising from the
event handler into the management core so that the helper can
be actually shared.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_event.c        | 36 +-----------------------------------
 net/bluetooth/mgmt.c             | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 82c3974..869f6ad 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1151,6 +1151,7 @@ int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 bool mgmt_valid_hdev(struct hci_dev *hdev);
 int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
+void mgmt_reenable_advertising(struct hci_dev *hdev);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6eaef6e..224210c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1796,40 +1796,6 @@ static u8 hci_to_mgmt_reason(u8 err)
 	}
 }
 
-static void adv_enable_complete(struct hci_dev *hdev, u8 status)
-{
-	BT_DBG("%s status %u", hdev->name, status);
-
-	/* Clear the advertising mgmt setting if we failed to re-enable it */
-	if (status) {
-		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-		mgmt_new_settings(hdev);
-	}
-}
-
-static void reenable_advertising(struct hci_dev *hdev)
-{
-	struct hci_request req;
-	u8 enable = 0x01;
-
-	if (hdev->conn_hash.le_num)
-		return;
-
-	if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
-		return;
-
-	hci_req_init(&req, hdev);
-	hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
-
-	/* If this fails we have no option but to let user space know
-	 * that we've disabled advertising.
-	 */
-	if (hci_req_run(&req, adv_enable_complete) < 0) {
-		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
-		mgmt_new_settings(hdev);
-	}
-}
-
 static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_disconn_complete *ev = (void *) skb->data;
@@ -1878,7 +1844,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		 * is timed out due to Directed Advertising."
 		 */
 		if (type == LE_LINK)
-			reenable_advertising(hdev);
+			mgmt_reenable_advertising(hdev);
 	}
 
 unlock:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b78a0ee..381faf6 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4660,3 +4660,36 @@ int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
 	return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev),
 			  cmd ? cmd->sk : NULL);
 }
+
+static void adv_enable_complete(struct hci_dev *hdev, u8 status)
+{
+	BT_DBG("%s status %u", hdev->name, status);
+
+	/* Clear the advertising mgmt setting if we failed to re-enable it */
+	if (status) {
+		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
+		mgmt_new_settings(hdev);
+	}
+}
+
+void mgmt_reenable_advertising(struct hci_dev *hdev)
+{
+	struct hci_request req;
+
+	if (hdev->conn_hash.le_num)
+		return;
+
+	if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
+		return;
+
+	hci_req_init(&req, hdev);
+	enable_advertising(&req);
+
+	/* If this fails we have no option but to let user space know
+	 * that we've disabled advertising.
+	 */
+	if (hci_req_run(&req, adv_enable_complete) < 0) {
+		clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
+		mgmt_new_settings(hdev);
+	}
+}
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Set LE advertising parameters before enabling it
From: Marcel Holtmann @ 2013-10-06 10:17 UTC (permalink / raw)
  To: linux-bluetooth

The LE advertising parameters can only be modified when advertising
is disabled. So before enabling it, make sure the controller has all
the right parameters.

Right now all default values are used and thus this does no change
any existing behavior. One minor exception is that in case of single
mode LE-only controllers without a public address, now the random
address is used for advertising.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/mgmt.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 8386684..b78a0ee 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1413,16 +1413,30 @@ unlock:
 
 static void enable_advertising(struct hci_request *req)
 {
-	u8 adv = 0x01;
+	struct hci_dev *hdev = req->hdev;
+	struct hci_cp_le_set_adv_param cp;
+	u8 enable = 0x01;
+
+	memset(&cp, 0, sizeof(cp));
+	cp.min_interval = __constant_cpu_to_le16(0x0800);
+	cp.max_interval = __constant_cpu_to_le16(0x0800);
+	cp.type = LE_ADV_IND;
+	if (bacmp(&hdev->bdaddr, BDADDR_ANY))
+		cp.own_address_type = ADDR_LE_DEV_PUBLIC;
+	else
+		cp.own_address_type = ADDR_LE_DEV_RANDOM;
+	cp.channel_map = 0x07;
+
+	hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp);
 
-	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(adv), &adv);
+	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
 }
 
 static void disable_advertising(struct hci_request *req)
 {
-	u8 adv = 0x00;
+	u8 enable = 0x00;
 
-	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(adv), &adv);
+	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
 }
 
 static void le_enable_complete(struct hci_dev *hdev, u8 status)
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Add constants for LE advertising types
From: Marcel Holtmann @ 2013-10-06 10:03 UTC (permalink / raw)
  To: linux-bluetooth

Add constants for ADV_IND, ADV_DIRECT_IND, ADV_SCAN_IND and
ADV_NONCONN_IND advertising types.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 9b0e3f9..3616ea7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1046,6 +1046,11 @@ struct hci_rp_le_read_local_features {
 
 #define HCI_OP_LE_SET_RANDOM_ADDR	0x2005
 
+#define LE_ADV_IND			0x00
+#define LE_ADV_DIRECT_IND		0x01
+#define LE_ADV_SCAN_IND			0x02
+#define LE_ADV_NONCONN_IND		0x03
+
 #define HCI_OP_LE_SET_ADV_PARAM		0x2006
 struct hci_cp_le_set_adv_param {
 	__le16   min_interval;
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Use helper functions for enabling/disabling advertising
From: Marcel Holtmann @ 2013-10-06  9:55 UTC (permalink / raw)
  To: linux-bluetooth

The tasks of enabling and disabling advertising are required in many
cases. So refactor the actual HCI operations into two common helpers
to make the code simpler.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/mgmt.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e09ceff..8386684 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1411,6 +1411,20 @@ unlock:
 	return err;
 }
 
+static void enable_advertising(struct hci_request *req)
+{
+	u8 adv = 0x01;
+
+	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(adv), &adv);
+}
+
+static void disable_advertising(struct hci_request *req)
+{
+	u8 adv = 0x00;
+
+	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(adv), &adv);
+}
+
 static void le_enable_complete(struct hci_dev *hdev, u8 status)
 {
 	struct cmd_lookup match = { NULL, hdev };
@@ -1505,11 +1519,8 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
 
 	hci_req_init(&req, hdev);
 
-	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) && !val) {
-		u8 adv = 0x00;
-
-		hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(adv), &adv);
-	}
+	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) && !val)
+		disable_advertising(&req);
 
 	hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp),
 		    &hci_cp);
@@ -3283,7 +3294,10 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data, u1
 
 	hci_req_init(&req, hdev);
 
-	hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(val), &val);
+	if (val)
+		enable_advertising(&req);
+	else
+		disable_advertising(&req);
 
 	err = hci_req_run(&req, set_advertising_complete);
 	if (err < 0)
@@ -3861,12 +3875,9 @@ static int powered_update_hci(struct hci_dev *hdev)
 		if (bacmp(&hdev->static_addr, BDADDR_ANY))
 			hci_req_add(&req, HCI_OP_LE_SET_RANDOM_ADDR, 6,
 				    &hdev->static_addr);
-	}
-
-	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
-		u8 adv = 0x01;
 
-		hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(adv), &adv);
+		if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
+			enable_advertising(&req);
 	}
 
 	link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Make it clear that disabling LE disables advertising
From: Marcel Holtmann @ 2013-10-06  9:40 UTC (permalink / raw)
  To: linux-bluetooth

This is not a functional change, just change the code to make it easy
to understand that advertising gets disabled before LE support will
be turned off.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/mgmt.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 7196722..e09ceff 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1505,8 +1505,11 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
 
 	hci_req_init(&req, hdev);
 
-	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) && !val)
-		hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(val), &val);
+	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) && !val) {
+		u8 adv = 0x00;
+
+		hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(adv), &adv);
+	}
 
 	hci_req_add(&req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp),
 		    &hci_cp);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Add HCI structure for LE advertising parameters command
From: Marcel Holtmann @ 2013-10-06  9:34 UTC (permalink / raw)
  To: linux-bluetooth

Add the basic HCI structure for building the LE advertising parameters
command.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 9f8d1c1..9b0e3f9 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1046,6 +1046,18 @@ struct hci_rp_le_read_local_features {
 
 #define HCI_OP_LE_SET_RANDOM_ADDR	0x2005
 
+#define HCI_OP_LE_SET_ADV_PARAM		0x2006
+struct hci_cp_le_set_adv_param {
+	__le16   min_interval;
+	__le16   max_interval;
+	__u8     type;
+	__u8     own_address_type;
+	__u8     direct_addr_type;
+	bdaddr_t direct_addr;
+	__u8     channel_map;
+	__u8     filter_policy;
+} __packed;
+
 #define HCI_OP_LE_READ_ADV_TX_POWER	0x2007
 struct hci_rp_le_read_adv_tx_power {
 	__u8	status;
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH 1/2] Bluetooth: Simplify device type check for AMP discover response
From: Johan Hedberg @ 2013-10-06  9:14 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381050516-44319-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Sun, Oct 06, 2013, Marcel Holtmann wrote:
> When counting the number for AMP controllers, a positive check is
> used. To be consistent, use the same check when actually adding
> the data for the AMP contollers.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  net/bluetooth/a2mp.c | 18 +++++++-----------
>  1 file changed, 7 insertions(+), 11 deletions(-)

Both patches in this set have been applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* [PATCH 2/2] Bluetooth: Use random address if public address is not available
From: Marcel Holtmann @ 2013-10-06  9:08 UTC (permalink / raw)
  To: linux-bluetooth

For single mode LE-only controllers, it is possible that they come
without a public address. If a public address is not available,
then use the random address for connection establishment and
scanning.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_conn.c | 4 ++++
 net/bluetooth/mgmt.c     | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 8b0d08f..2a220a8 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -59,6 +59,10 @@ static void hci_le_create_connection(struct hci_conn *conn)
 	cp.scan_window = __constant_cpu_to_le16(0x0030);
 	bacpy(&cp.peer_addr, &conn->dst);
 	cp.peer_addr_type = conn->dst_type;
+	if (bacmp(&hdev->bdaddr, BDADDR_ANY))
+		cp.own_address_type = ADDR_LE_DEV_PUBLIC;
+	else
+		cp.own_address_type = ADDR_LE_DEV_RANDOM;
 	cp.conn_interval_min = __constant_cpu_to_le16(0x0028);
 	cp.conn_interval_max = __constant_cpu_to_le16(0x0038);
 	cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 6e808d1..7196722 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2911,6 +2911,10 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
 		param_cp.type = LE_SCAN_ACTIVE;
 		param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT);
 		param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
+		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
+			param_cp.own_address_type = ADDR_LE_DEV_PUBLIC;
+		else
+			param_cp.own_address_type = ADDR_LE_DEV_RANDOM;
 		hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
 			    &param_cp);
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: Simplify device type check for AMP discover response
From: Marcel Holtmann @ 2013-10-06  9:08 UTC (permalink / raw)
  To: linux-bluetooth

When counting the number for AMP controllers, a positive check is
used. To be consistent, use the same check when actually adding
the data for the AMP contollers.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/a2mp.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index ad8bda3..9410e27 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -78,24 +78,20 @@ u8 __next_ident(struct amp_mgr *mgr)
 /* hci_dev_list shall be locked */
 static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl)
 {
-	int i = 0;
 	struct hci_dev *hdev;
+	int i = 1;
 
 	cl[0].id = AMP_ID_BREDR;
 	cl[0].type = AMP_TYPE_BREDR;
 	cl[0].status = AMP_STATUS_BLUETOOTH_ONLY;
 
 	list_for_each_entry(hdev, &hci_dev_list, list) {
-		/* Iterate through AMP controllers */
-		if (hdev->dev_type != HCI_AMP)
-			continue;
-
-		/* Starting from second entry */
-		++i;
-
-		cl[i].id = hdev->id;
-		cl[i].type = hdev->amp_type;
-		cl[i].status = hdev->amp_status;
+		if (hdev->dev_type == HCI_AMP) {
+			cl[i].id = hdev->id;
+			cl[i].type = hdev->amp_type;
+			cl[i].status = hdev->amp_status;
+			i++;
+		}
 	}
 }
 
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH] Bluetooth: Use explicit check for BR/EDR device type
From: Johan Hedberg @ 2013-10-06  9:05 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381047382-37225-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Sun, Oct 06, 2013, Marcel Holtmann wrote:
> The BR/EDR and LE setup procedures apply only to BR/EDR device types
> and so check for that explicitly. Checking that it is not an AMP
> controller is dangerous in case there will be ever a third device
> type.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  net/bluetooth/hci_core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 1/2] Bluetooth: Reject enabling controllers without valid addresses
From: Johan Hedberg @ 2013-10-06  9:04 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381046938-34970-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Sun, Oct 06, 2013, Marcel Holtmann wrote:
> In case of a single mode LE-only controller it is possible that no
> public address is used. These type of controllers require a random
> address to be configured.
> 
> Without a configured static random address, such a controller is
> not functional. So reject powering on the controller in this case
> until it gets configured with a random address.
> 
> The controller setup stage is still run since it is the only way
> to determinate if a public address is available or not. So it is
> similar on how RFKILL gets handled during initial setup of the
> controller.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  net/bluetooth/hci_core.c | 43 +++++++++++++++++++++++++++++++++++--------
>  1 file changed, 35 insertions(+), 8 deletions(-)

This patch has been applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] Bluetooth: Check for non BR/EDR controller in AMP discover response
From: Johan Hedberg @ 2013-10-06  8:47 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381006673-14570-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Sat, Oct 05, 2013, Marcel Holtmann wrote:
> Within the AMP discover response, all controllers that are not the
> primary BR/EDR controller are valid.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  net/bluetooth/a2mp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 01/10] Bluetooth: Fix controller list for AMP discover response
From: Johan Hedberg @ 2013-10-06  8:47 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1380998869-64411-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Sat, Oct 05, 2013, Marcel Holtmann wrote:
> The AMP discover response should list exactly one BR/EDR controller
> and ignore all other BR/EDR controller.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  net/bluetooth/a2mp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

All patches in this set have been applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* [PATCH] Bluetooth: Use explicit check for BR/EDR device type
From: Marcel Holtmann @ 2013-10-06  8:16 UTC (permalink / raw)
  To: linux-bluetooth

The BR/EDR and LE setup procedures apply only to BR/EDR device types
and so check for that explicitly. Checking that it is not an AMP
controller is dangerous in case there will be ever a third device
type.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 86c022c..03a8b93 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2360,7 +2360,7 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	set_bit(HCI_SETUP, &hdev->dev_flags);
 
-	if (hdev->dev_type != HCI_AMP) {
+	if (hdev->dev_type == HCI_BREDR) {
 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
 		/* Assume BR/EDR support until proven otherwise (such as
 		 * through reading supported features during init.
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 2/2] Bluetooth: Use random address if public address is not available
From: Marcel Holtmann @ 2013-10-06  8:08 UTC (permalink / raw)
  To: linux-bluetooth

For single mode LE-only controllers, it is possible that they come
without a public address. If a public address is not available,
then use the random address for connection establishment and
scanning.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_conn.c | 4 ++++
 net/bluetooth/mgmt.c     | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index bd3a3f5..16697ae 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -59,6 +59,10 @@ static void hci_le_create_connection(struct hci_conn *conn)
 	cp.scan_window = cpu_to_le16(hdev->le_scan_window);
 	bacpy(&cp.peer_addr, &conn->dst);
 	cp.peer_addr_type = conn->dst_type;
+	if (bacmp(&hdev->bdaddr, BDADDR_ANY))
+		cp.own_address_type = ADDR_LE_DEV_PUBLIC;
+	else
+		cp.own_address_type = ADDR_LE_DEV_RANDOM;
 	cp.conn_interval_min = __constant_cpu_to_le16(0x0028);
 	cp.conn_interval_max = __constant_cpu_to_le16(0x0038);
 	cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f018fed..d488049 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2911,6 +2911,10 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
 		param_cp.type = LE_SCAN_ACTIVE;
 		param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT);
 		param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
+		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
+			param_cp.own_address_type = ADDR_LE_DEV_PUBLIC;
+		else
+			param_cp.own_address_type = ADDR_LE_DEV_RANDOM;
 		hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
 			    &param_cp);
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: Reject enabling controllers without valid addresses
From: Marcel Holtmann @ 2013-10-06  8:08 UTC (permalink / raw)
  To: linux-bluetooth

In case of a single mode LE-only controller it is possible that no
public address is used. These type of controllers require a random
address to be configured.

Without a configured static random address, such a controller is
not functional. So reject powering on the controller in this case
until it gets configured with a random address.

The controller setup stage is still run since it is the only way
to determinate if a public address is available or not. So it is
similar on how RFKILL gets handled during initial setup of the
controller.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 43 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 35 insertions(+), 8 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index a8bb9fd..86c022c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1196,13 +1196,29 @@ static int hci_dev_do_open(struct hci_dev *hdev)
 		goto done;
 	}
 
-	/* Check for rfkill but allow the HCI setup stage to proceed
-	 * (which in itself doesn't cause any RF activity).
-	 */
-	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) &&
-	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
-		ret = -ERFKILL;
-		goto done;
+	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
+		/* Check for rfkill but allow the HCI setup stage to
+		 * proceed (which in itself doesn't cause any RF activity).
+		 */
+		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
+			ret = -ERFKILL;
+			goto done;
+		}
+
+		/* Check for valid public address or a configured static
+		 * random adddress, but let the HCI setup proceed to
+		 * be able to determine if there is a public address
+		 * or not.
+		 *
+		 * This check is only valid for BR/EDR controllers
+		 * since AMP controllers do not have an address.
+		 */
+		if (hdev->dev_type == HCI_BREDR &&
+		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
+		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
+			ret = -EADDRNOTAVAIL;
+			goto done;
+		}
 	}
 
 	if (test_bit(HCI_UP, &hdev->flags)) {
@@ -1288,6 +1304,10 @@ int hci_dev_open(__u16 dev)
 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
 		cancel_delayed_work(&hdev->power_off);
 
+	/* After this call it is guaranteed that the setup procedure
+	 * has finished. This means that error conditions like RFKILL
+	 * or no valid public or static random address apply.
+	 */
 	flush_workqueue(hdev->req_workqueue);
 
 	err = hci_dev_do_open(hdev);
@@ -1703,7 +1723,14 @@ static void hci_power_on(struct work_struct *work)
 		return;
 	}
 
-	if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
+	/* During the HCI setup phase, a few error conditions are
+	 * ignored and they need to be checked now. If they are still
+	 * valid, it is important to turn the device back off.
+	 */
+	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
+	    (hdev->dev_type == HCI_BREDR &&
+	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
+	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
 		hci_dev_do_close(hdev);
 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Check for non BR/EDR controller in AMP discover response
From: Marcel Holtmann @ 2013-10-05 20:57 UTC (permalink / raw)
  To: linux-bluetooth

Within the AMP discover response, all controllers that are not the
primary BR/EDR controller are valid.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/a2mp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 5278a65..9410e27 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -206,7 +206,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
 		BT_DBG("Remote AMP id %d type %d status %d", cl->id, cl->type,
 		       cl->status);
 
-		if (cl->id != AMP_ID_BREDR && cl->type == HCI_AMP) {
+		if (cl->id != AMP_ID_BREDR && cl->type != AMP_TYPE_BREDR) {
 			struct a2mp_info_req req;
 
 			found = true;
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Extra sanity check for AMP discover response
From: Marcel Holtmann @ 2013-10-05 18:56 UTC (permalink / raw)
  To: linux-bluetooth

Just in case the Bluetooth standard introduces a third device type,
make sure that we only include AMP controllers in the AMP discover
response.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/a2mp.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 529789d..5278a65 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -78,24 +78,20 @@ u8 __next_ident(struct amp_mgr *mgr)
 /* hci_dev_list shall be locked */
 static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl)
 {
-	int i = 0;
 	struct hci_dev *hdev;
+	int i = 1;
 
 	cl[0].id = AMP_ID_BREDR;
 	cl[0].type = AMP_TYPE_BREDR;
 	cl[0].status = AMP_STATUS_BLUETOOTH_ONLY;
 
 	list_for_each_entry(hdev, &hci_dev_list, list) {
-		/* Iterate through AMP controllers */
-		if (hdev->dev_type != HCI_AMP)
-			continue;
-
-		/* Starting from second entry */
-		++i;
-
-		cl[i].id = hdev->id;
-		cl[i].type = hdev->amp_type;
-		cl[i].status = hdev->amp_status;
+		if (hdev->dev_type == HCI_AMP) {
+			cl[i].id = hdev->id;
+			cl[i].type = hdev->amp_type;
+			cl[i].status = hdev->amp_status;
+			i++;
+		}
 	}
 }
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 10/10] Bluetooth: Simplify check if L2CAP connection is AMP capable
From: Marcel Holtmann @ 2013-10-05 18:47 UTC (permalink / raw)
  To: linux-bluetooth

The check if a L2CAP connection is AMP capable was a little bit
complicated. This changes the code to make it simpler and more
readable.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/l2cap_core.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 2efdb17..a9a7df6 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1012,30 +1012,30 @@ static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
 	return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
 }
 
-/* returns true if at least one AMP active */
-static inline bool hci_amp_capable(void)
+static bool __amp_capable(struct l2cap_chan *chan)
 {
+	struct l2cap_conn *conn = chan->conn;
 	struct hci_dev *hdev;
-	bool ret = false;
+	bool amp_available = false;
+
+	if (!conn->hs_enabled)
+		return false;
+
+	if (!(conn->fixed_chan_mask & L2CAP_FC_A2MP))
+		return false;
 
 	read_lock(&hci_dev_list_lock);
-	list_for_each_entry(hdev, &hci_dev_list, list)
+	list_for_each_entry(hdev, &hci_dev_list, list) {
 		if (hdev->amp_type != AMP_TYPE_BREDR &&
-		    test_bit(HCI_UP, &hdev->flags))
-			ret = true;
+		    test_bit(HCI_UP, &hdev->flags)) {
+			amp_available = true;
+			break;
+		}
+	}
 	read_unlock(&hci_dev_list_lock);
 
-	return ret;
-}
-
-static bool __amp_capable(struct l2cap_chan *chan)
-{
-	struct l2cap_conn *conn = chan->conn;
-
-	if (conn->hs_enabled && hci_amp_capable() &&
-	    chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
-	    conn->fixed_chan_mask & L2CAP_FC_A2MP)
-		return true;
+	if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED)
+		return amp_available;
 
 	return false;
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 09/10] Bluetooth: Move hci_amp_capable() function into L2CAP core
From: Marcel Holtmann @ 2013-10-05 18:47 UTC (permalink / raw)
  To: linux-bluetooth

The hci_amp_capable() function has only a single user inside the L2CAP
core. Instead of exporting the function, place it next to its user.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h | 16 ----------------
 net/bluetooth/l2cap_core.c       | 16 ++++++++++++++++
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 86e2dbe..0791544 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -797,22 +797,6 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 #define lmp_host_le_capable(dev)   (!!((dev)->features[1][0] & LMP_HOST_LE))
 #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))
 
-/* returns true if at least one AMP active */
-static inline bool hci_amp_capable(void)
-{
-	struct hci_dev *hdev;
-	bool ret = false;
-
-	read_lock(&hci_dev_list_lock);
-	list_for_each_entry(hdev, &hci_dev_list, list)
-		if (hdev->amp_type != AMP_TYPE_BREDR &&
-		    test_bit(HCI_UP, &hdev->flags))
-			ret = true;
-	read_unlock(&hci_dev_list_lock);
-
-	return ret;
-}
-
 /* ----- HCI protocols ----- */
 #define HCI_PROTO_DEFER             0x01
 
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b0208e2..2efdb17 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1012,6 +1012,22 @@ static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
 	return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
 }
 
+/* returns true if at least one AMP active */
+static inline bool hci_amp_capable(void)
+{
+	struct hci_dev *hdev;
+	bool ret = false;
+
+	read_lock(&hci_dev_list_lock);
+	list_for_each_entry(hdev, &hci_dev_list, list)
+		if (hdev->amp_type != AMP_TYPE_BREDR &&
+		    test_bit(HCI_UP, &hdev->flags))
+			ret = true;
+	read_unlock(&hci_dev_list_lock);
+
+	return ret;
+}
+
 static bool __amp_capable(struct l2cap_chan *chan)
 {
 	struct l2cap_conn *conn = chan->conn;
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 08/10] Bluetooth: Remove check for number of AMP controller
From: Marcel Holtmann @ 2013-10-05 18:47 UTC (permalink / raw)
  To: linux-bluetooth

The number of controllers for the AMP discover response has already
been calculated. And since the hci_dev_list lock is held, it can not
change. So there is no need for any extra checks.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/a2mp.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index a1aae5c..529789d 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -76,7 +76,7 @@ u8 __next_ident(struct amp_mgr *mgr)
 }
 
 /* hci_dev_list shall be locked */
-static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl, u8 num_ctrl)
+static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl)
 {
 	int i = 0;
 	struct hci_dev *hdev;
@@ -91,8 +91,7 @@ static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl, u8 num_ctrl)
 			continue;
 
 		/* Starting from second entry */
-		if (++i >= num_ctrl)
-			return;
+		++i;
 
 		cl[i].id = hdev->id;
 		cl[i].type = hdev->amp_type;
@@ -166,7 +165,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
 	rsp->mtu = __constant_cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU);
 	rsp->ext_feat = 0;
 
-	__a2mp_add_cl(mgr, rsp->cl, num_ctrl);
+	__a2mp_add_cl(mgr, rsp->cl);
 
 	read_unlock(&hci_dev_list_lock);
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 07/10] Bluetooth: Remove pointless inline function
From: Marcel Holtmann @ 2013-10-05 18:47 UTC (permalink / raw)
  To: linux-bluetooth

The inline function for BR/EDR controller AMP discover response
info is rather useless. Just include the code into the function
that builds the whole response.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/a2mp.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 6dfef73..a1aae5c 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -75,20 +75,15 @@ u8 __next_ident(struct amp_mgr *mgr)
 	return mgr->ident;
 }
 
-static inline void __a2mp_cl_bredr(struct a2mp_cl *cl)
-{
-	cl->id = AMP_ID_BREDR;
-	cl->type = AMP_TYPE_BREDR;
-	cl->status = AMP_STATUS_BLUETOOTH_ONLY;
-}
-
 /* hci_dev_list shall be locked */
 static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl, u8 num_ctrl)
 {
 	int i = 0;
 	struct hci_dev *hdev;
 
-	__a2mp_cl_bredr(cl);
+	cl[0].id = AMP_ID_BREDR;
+	cl[0].type = AMP_TYPE_BREDR;
+	cl[0].status = AMP_STATUS_BLUETOOTH_ONLY;
 
 	list_for_each_entry(hdev, &hci_dev_list, list) {
 		/* Iterate through AMP controllers */
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 06/10] Bluetooth: Rename AMP status constants and use them
From: Marcel Holtmann @ 2013-10-05 18:47 UTC (permalink / raw)
  To: linux-bluetooth

The AMP controller status constants need to be actually used to avoid
crypted hardcoded numbers.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h | 14 +++++++-------
 net/bluetooth/a2mp.c        |  2 +-
 net/bluetooth/hci_core.c    |  2 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 393eabc..9f8d1c1 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -71,13 +71,13 @@
 #define AMP_TYPE_80211	0x01
 
 /* AMP controller status */
-#define AMP_CTRL_POWERED_DOWN			0x00
-#define AMP_CTRL_BLUETOOTH_ONLY			0x01
-#define AMP_CTRL_NO_CAPACITY			0x02
-#define AMP_CTRL_LOW_CAPACITY			0x03
-#define AMP_CTRL_MEDIUM_CAPACITY		0x04
-#define AMP_CTRL_HIGH_CAPACITY			0x05
-#define AMP_CTRL_FULL_CAPACITY			0x06
+#define AMP_STATUS_POWERED_DOWN			0x00
+#define AMP_STATUS_BLUETOOTH_ONLY		0x01
+#define AMP_STATUS_NO_CAPACITY			0x02
+#define AMP_STATUS_LOW_CAPACITY			0x03
+#define AMP_STATUS_MEDIUM_CAPACITY		0x04
+#define AMP_STATUS_HIGH_CAPACITY		0x05
+#define AMP_STATUS_FULL_CAPACITY		0x06
 
 /* HCI device quirks */
 enum {
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 6d62d31..6dfef73 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -79,7 +79,7 @@ static inline void __a2mp_cl_bredr(struct a2mp_cl *cl)
 {
 	cl->id = AMP_ID_BREDR;
 	cl->type = AMP_TYPE_BREDR;
-	cl->status = 1;
+	cl->status = AMP_STATUS_BLUETOOTH_ONLY;
 }
 
 /* hci_dev_list shall be locked */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c3c7c12..a8bb9fd 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1381,7 +1381,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 	}
 
 	/* Controller radio is available but is currently powered down */
-	hdev->amp_status = 0;
+	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
 
 	memset(hdev->eir, 0, sizeof(hdev->eir));
 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 05/10] Bluetooth: Use explicit AMP controller id value for BR/EDR
From: Marcel Holtmann @ 2013-10-05 18:47 UTC (permalink / raw)
  To: linux-bluetooth

The special AMP controller id 0 is reserved for the BR/EDR controller
that has the main link. It is a fixed value and so use a constant for
this throughout the code to make it more visible when the handling is
for the BR/EDR channel or when it is for the AMP channel.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h |  2 +-
 net/bluetooth/a2mp.c        |  4 ++--
 net/bluetooth/l2cap_core.c  | 28 ++++++++++++++--------------
 3 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 8e3076e..393eabc 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -64,7 +64,7 @@
 #define HCI_AMP		0x01
 
 /* First BR/EDR Controller shall have ID = 0 */
-#define HCI_BREDR_ID	0
+#define AMP_ID_BREDR	0x00
 
 /* AMP controller types */
 #define AMP_TYPE_BREDR	0x00
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index b2ef3d3..6d62d31 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -77,7 +77,7 @@ u8 __next_ident(struct amp_mgr *mgr)
 
 static inline void __a2mp_cl_bredr(struct a2mp_cl *cl)
 {
-	cl->id = 0;
+	cl->id = AMP_ID_BREDR;
 	cl->type = AMP_TYPE_BREDR;
 	cl->status = 1;
 }
@@ -216,7 +216,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
 		BT_DBG("Remote AMP id %d type %d status %d", cl->id, cl->type,
 		       cl->status);
 
-		if (cl->id != HCI_BREDR_ID && cl->type == HCI_AMP) {
+		if (cl->id != AMP_ID_BREDR && cl->type == HCI_AMP) {
 			struct a2mp_info_req req;
 
 			found = true;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 02dba4e..b0208e2 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3046,8 +3046,8 @@ int l2cap_ertm_init(struct l2cap_chan *chan)
 
 	skb_queue_head_init(&chan->tx_q);
 
-	chan->local_amp_id = 0;
-	chan->move_id = 0;
+	chan->local_amp_id = AMP_ID_BREDR;
+	chan->move_id = AMP_ID_BREDR;
 	chan->move_state = L2CAP_MOVE_STABLE;
 	chan->move_role = L2CAP_MOVE_ROLE_NONE;
 
@@ -3100,7 +3100,7 @@ static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
 static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
 				      struct l2cap_conf_rfc *rfc)
 {
-	if (chan->local_amp_id && chan->hs_hcon) {
+	if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) {
 		u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to;
 
 		/* Class 1 devices have must have ERTM timeouts
@@ -3791,12 +3791,12 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
 				 * The connection will succeed after the
 				 * physical link is up.
 				 */
-				if (amp_id) {
-					__l2cap_state_change(chan, BT_CONNECT2);
-					result = L2CAP_CR_PEND;
-				} else {
+				if (amp_id == AMP_ID_BREDR) {
 					__l2cap_state_change(chan, BT_CONFIG);
 					result = L2CAP_CR_SUCCESS;
+				} else {
+					__l2cap_state_change(chan, BT_CONNECT2);
+					result = L2CAP_CR_PEND;
 				}
 				status = L2CAP_CS_NO_INFO;
 			}
@@ -4423,7 +4423,7 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn,
 	BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id);
 
 	/* For controller id 0 make BR/EDR connection */
-	if (req->amp_id == HCI_BREDR_ID) {
+	if (req->amp_id == AMP_ID_BREDR) {
 		l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
 			      req->amp_id);
 		return 0;
@@ -4658,7 +4658,7 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
 
 	if (chan->state != BT_CONNECTED) {
 		/* Ignore logical link if channel is on BR/EDR */
-		if (chan->local_amp_id)
+		if (chan->local_amp_id != AMP_ID_BREDR)
 			l2cap_logical_finish_create(chan, hchan);
 	} else {
 		l2cap_logical_finish_move(chan, hchan);
@@ -4669,7 +4669,7 @@ void l2cap_move_start(struct l2cap_chan *chan)
 {
 	BT_DBG("chan %p", chan);
 
-	if (chan->local_amp_id == HCI_BREDR_ID) {
+	if (chan->local_amp_id == AMP_ID_BREDR) {
 		if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
 			return;
 		chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
@@ -4868,7 +4868,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
 		goto send_move_response;
 	}
 
-	if (req->dest_amp_id) {
+	if (req->dest_amp_id != AMP_ID_BREDR) {
 		struct hci_dev *hdev;
 		hdev = hci_dev_get(req->dest_amp_id);
 		if (!hdev || hdev->dev_type != HCI_AMP ||
@@ -4898,7 +4898,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
 	chan->move_id = req->dest_amp_id;
 	icid = chan->dcid;
 
-	if (!req->dest_amp_id) {
+	if (req->dest_amp_id == AMP_ID_BREDR) {
 		/* Moving to BR/EDR */
 		if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
 			chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
@@ -5090,7 +5090,7 @@ static int l2cap_move_channel_confirm(struct l2cap_conn *conn,
 	if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) {
 		if (result == L2CAP_MC_CONFIRMED) {
 			chan->local_amp_id = chan->move_id;
-			if (!chan->local_amp_id)
+			if (chan->local_amp_id == AMP_ID_BREDR)
 				__release_logical_link(chan);
 		} else {
 			chan->move_id = chan->local_amp_id;
@@ -5130,7 +5130,7 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn,
 	if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) {
 		chan->local_amp_id = chan->move_id;
 
-		if (!chan->local_amp_id && chan->hs_hchan)
+		if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan)
 			__release_logical_link(chan);
 
 		l2cap_move_done(chan);
-- 
1.8.3.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox