Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [RFC v0 13/15] profile: Rename org.bluez.Profile->ProfileAgent
From: Marcel Holtmann @ 2012-10-19 16:10 UTC (permalink / raw)
  To: Mikel Astiz; +Cc: linux-bluetooth, Mikel Astiz
In-Reply-To: <1350661172-18125-14-git-send-email-mikel.astiz.oss@gmail.com>

Hi Mikel,

> The interface represents an external component supporting a specific
> profile by implementing an agent. Therefore ProfileAgent is a more
> accurate name for the D-Bus interface.

actually I think Johan and I discussed this. And the reason for keeping
the name Profile is that the external component implements the profile.
It is not just an agent, it is the profile.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH v6 01/16] doc: Add settings storage documentation
From: Marcel Holtmann @ 2012-10-19 16:12 UTC (permalink / raw)
  To: Frederic Danis; +Cc: linux-bluetooth
In-Reply-To: <50811E78.6060009@linux.intel.com>

Hi Fred,

> >> +Cache directory files
> >> +======================
> >> +
> >> +Each files, named by remote device address, contains 1 [General] group:
> >> +  [General]
> >> +  Name=device name a
> >
> > Is this the only thing we are storing in these files? Or are we planning
> > to store additional information at some point.
> >
> >> +Device directory files
> >> +======================
> >> +
> >> +Remote device info file will include a [General] group with device info,
> >> +[DeviceID], [LinkKey] and [LongTermKey] groups with related info:
> >> +  [General]
> >> +  Alias=
> >
> > Are we just doing the Alias here? We are not keeping the Name? In theory
> > we have a short name and full name actually. If we ever only got the
> > short name, we need to know that. Then we have to request the long name
> > next time.
> 
> Name is already stored in cache file. So I think we do not need to save 
> it also in device info file.
> 
> We may store both short and long names in the cache file.

I was assuming that the cache file is only used for LE devices with
static random addresses, but know I remember that we even need to store
the names for devices that we only discovered and not paired with.

Regards

Marcel



^ permalink raw reply

* Re: [PATCHv3 18/18] Bluetooth: Start channel move when socket option is changed
From: Mat Martineau @ 2012-10-19 16:16 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth, gustavo, sunnyk, marcel
In-Reply-To: <20121019093756.GM4249@aemeltch-MOBL1>


Hi Andrei -

On Fri, 19 Oct 2012, Andrei Emeltchenko wrote:

> Hi Mat,
>
> On Thu, Oct 18, 2012 at 10:58:50AM -0700, Mat Martineau wrote:
>> Channel moves are triggered by changes to the BT_CHANNEL_POLICY
>> sockopt when an ERTM or streaming-mode channel is connected.
>>
>> Moves are only started if enable_hs is true.
>>
>> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
>> Acked-by: Marcel Holtmann <marcel@holtmann.org>
>> ---
>>  include/net/bluetooth/l2cap.h |  1 +
>>  net/bluetooth/l2cap_core.c    | 20 ++++++++++++++++++++
>>  net/bluetooth/l2cap_sock.c    |  5 +++++
>>  3 files changed, 26 insertions(+)
>>
>> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
>> index b4c3c65..49783e9 100644
>> --- a/include/net/bluetooth/l2cap.h
>> +++ b/include/net/bluetooth/l2cap.h
>> @@ -809,5 +809,6 @@ void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
>>  void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
>>  void l2cap_chan_del(struct l2cap_chan *chan, int err);
>>  void l2cap_send_conn_req(struct l2cap_chan *chan);
>> +void l2cap_move_start(struct l2cap_chan *chan);
>>
>>  #endif /* __L2CAP_H */
>> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
>> index 8fa46de..b3d3f4f 100644
>> --- a/net/bluetooth/l2cap_core.c
>> +++ b/net/bluetooth/l2cap_core.c
>> @@ -4452,6 +4452,26 @@ static void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
>>  	}
>>  }
>>
>> +void l2cap_move_start(struct l2cap_chan *chan)
>> +{
>> +	BT_DBG("chan %p", chan);
>> +
>> +	if (chan->local_amp_id == 0) {
>
> I would rather use "if (!chan->local_amp_id)" or event better if compare to
> use "if (chan->local_amp_id == HCI_BRDER_ID)

Ok, done.

>> +		if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED)
>> +			return;
>> +		chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
>> +		chan->move_state = L2CAP_MOVE_WAIT_PREPARE;
>
> Isn't it a bit earlier to start move? We should first to query remote AMP
> controllers to find out AMP id, etc. Or how this supposed to work? Where
> do you move?

The move request isn't sent until after the remote AMP controllers 
have been queried.  Sending the AMP queries is part of the move 
process, so the channel move state machine takes it in to account as 
the MOVE_WAIT_PREPARE state.

When the userspace AMP API was defined, the BlueZ community settled on 
using the BT_CHANNEL_POLICY approach and not exporting the choice of 
remote AMP device to userspace.  The AMP manager is responsible for 
choosing the best available AMP controller (in practice so far, 
there's a maximum of one anyway).  The chosen controller ID is 
provided to L2CAP as the remote_amp_id parameter to 
l2cap_physical_cfm(), and L2CAP sends a move channel request with that 
ID.

>> +		/* Placeholder - start physical link setup */
>> +	} else {
>> +		chan->move_role = L2CAP_MOVE_ROLE_INITIATOR;
>> +		chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
>> +		chan->move_id = 0;
>> +		l2cap_move_start(chan);
>> +		l2cap_send_move_chan_req(chan, 0);
>> +		__set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
>> +	}
>> +}
>> +
>>  static void l2cap_do_create(struct l2cap_chan *chan, int result,
>>  			    u8 local_amp_id, u8 remote_amp_id)
>>  {
>> diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
>> index 5fae2bd..7cb4d73 100644
>> --- a/net/bluetooth/l2cap_sock.c
>> +++ b/net/bluetooth/l2cap_sock.c
>> @@ -735,6 +735,11 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
>>  		}
>>
>>  		chan->chan_policy = (u8) opt;
>> +
>> +		if (sk->sk_state == BT_CONNECTED &&
>> +		    chan->move_role == L2CAP_MOVE_ROLE_NONE)
>> +			l2cap_move_start(chan);
>> +
>>  		break;
>>
>>  	default:
>> --
>> 1.7.12.3

Thanks,

--
Mat Martineau

Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply

* Re: [PATCHv3 10/18] Bluetooth: Add logical link confirm
From: Mat Martineau @ 2012-10-19 16:44 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth, gustavo, sunnyk, marcel
In-Reply-To: <20121019075355.GA4249@aemeltch-MOBL1>


Hi Andrei -

On Fri, 19 Oct 2012, Andrei Emeltchenko wrote:

> Hi Mat,
>
> On Thu, Oct 18, 2012 at 10:58:42AM -0700, Mat Martineau wrote:
>> The logical link confirm callback is executed when the AMP controller
>> completes its logical link setup.  During a channel move, a newly
>> formed logical link allows a move responder to send a move channel
>> response.  A move initiator will send a move channel confirm.  A
>> failed logical link will end the channel move and send an appropriate
>> response or confirm command indicating a failure.
>>
>> If the channel is being created on an AMP controller, L2CAP
>> configuration is started after the logical link is set up.
>
> Is L2CAP configuration started after channel is created which is happening
> after physical link is created? After Logical link establishment we finish
> EFS configuration process.

I need to rephrase that last sentence to say "configuration is 
completed after the logical link is set up".

>
>>
>> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
>> ---
>>  net/bluetooth/l2cap_core.c | 120 ++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 118 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
>> index 7e50aa4..8e50685 100644
>> --- a/net/bluetooth/l2cap_core.c
>> +++ b/net/bluetooth/l2cap_core.c
>> @@ -3799,6 +3799,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
>>  		goto unlock;
>>  	}
>>
>> +	chan->ident = cmd->ident;
>>  	l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
>>  	chan->num_conf_rsp++;
>>
>> @@ -4241,11 +4242,126 @@ static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident,
>>  	l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp);
>>  }
>>
>> +static void l2cap_logical_fail(struct l2cap_chan *chan)
>> +{
>> +	/* Logical link setup failed */
>> +	if (chan->state != BT_CONNECTED) {
>> +		/* Create channel failure, disconnect */
>> +		l2cap_send_disconn_req(chan->conn, chan, ECONNRESET);
>> +	} else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
>> +		l2cap_move_revert(chan);
>> +		chan->move_role = L2CAP_MOVE_ROLE_NONE;
>> +		chan->move_state = L2CAP_MOVE_STABLE;
>> +		l2cap_send_move_chan_rsp(chan->conn, chan->ident, chan->dcid,
>> +					 L2CAP_MR_NOT_SUPP);
>> +	} else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
>> +		if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP ||
>> +		    chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) {
>> +			/* Remote has only sent pending or
>> +			 * success responses, clean up
>> +			 */
>> +			l2cap_move_revert(chan);
>> +			chan->move_role = L2CAP_MOVE_ROLE_NONE;
>> +			chan->move_state = L2CAP_MOVE_STABLE;
>> +		}
>> +
>> +		/* Other amp move states imply that the move
>> +		 * has already aborted
>> +		 */
>> +		l2cap_send_move_chan_cfm(chan->conn, chan, chan->scid,
>> +					 L2CAP_MC_UNCONFIRMED);
>> +		__set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
>> +	}
>> +
>> +	chan->hs_hchan = NULL;
>> +	chan->hs_hcon = NULL;
>> +
>> +	/* Placeholder - free logical link */
>> +}
>> +
>> +static void l2cap_logical_create_channel(struct l2cap_chan *chan,
>> +					 struct hci_chan *hchan)
>> +{
>
> This is bad name IMO, the function finish L2CAP EFS configuration not
> creating logical link.

l2cap_logical_cfm had three paths:  failure, create channel, and move 
channel.  I was trying to come up with function names that reflected 
which activity was going on.  Maybe l2cap_logical_finish_create() and 
l2cap_logical_finish_move() would be more clear?


>> +	struct l2cap_conf_rsp rsp;
>> +	u8 code;
>> +
>> +	chan->hs_hcon = hchan->conn;
>> +	chan->hs_hcon->l2cap_data = chan->conn;
>> +
>> +	code = l2cap_build_conf_rsp(chan, &rsp,
>> +				    L2CAP_CONF_SUCCESS, 0);
>> +	l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CONF_RSP, code,
>> +		       &rsp);
>> +	set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
>> +
>> +	if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
>> +		int err = 0;
>> +
>> +		set_default_fcs(chan);
>> +
>> +		err = l2cap_ertm_init(chan);
>> +		if (err < 0)
>> +			l2cap_send_disconn_req(chan->conn, chan, -err);
>> +		else
>> +			l2cap_chan_ready(chan);
>> +	}
>> +}
>> +
>> +static void l2cap_logical_move_channel(struct l2cap_chan *chan,
>> +				       struct hci_chan *hchan)
>> +{
>> +	chan->hs_hcon = hchan->conn;
>> +	chan->hs_hcon->l2cap_data = chan->conn;
>> +
>> +	BT_DBG("move_state %d", chan->move_state);
>> +
>> +	switch (chan->move_state) {
>> +	case L2CAP_MOVE_WAIT_LOGICAL_COMP:
>> +		/* Move confirm will be sent after a success
>> +		 * response is received
>> +		 */
>> +		chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS;
>> +		break;
>> +	case L2CAP_MOVE_WAIT_LOGICAL_CFM:
>> +		if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
>> +			chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY;
>> +		} else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) {
>> +			chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP;
>> +			l2cap_send_move_chan_cfm(chan->conn, chan, chan->scid,
>> +						 L2CAP_MR_SUCCESS);
>> +			__set_chan_timer(chan, L2CAP_MOVE_TIMEOUT);
>> +		} else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) {
>> +			chan->move_state = L2CAP_MOVE_WAIT_CONFIRM;
>> +			l2cap_send_move_chan_rsp(chan->conn, chan->ident,
>> +						 chan->dcid, L2CAP_MR_SUCCESS);
>> +		}
>> +		break;
>> +	default:
>> +		/* Move was not in expected state, free the channel */
>> +		chan->hs_hchan = NULL;
>> +		chan->hs_hcon = NULL;
>> +
>> +		/* Placeholder - free the logical link */
>> +
>> +		chan->move_state = L2CAP_MOVE_STABLE;
>> +	}
>> +}
>> +
>> +/* Call with chan locked */
>>  static void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
>>  			      u8 status)
>>  {
>> -	/* Placeholder */
>> -	return;
>> +	BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
>> +
>> +	if (status) {
>> +		l2cap_logical_fail(chan);
>> +	} else if (chan->state != BT_CONNECTED) {
>> +		/* Ignore logical link if channel is on BR/EDR */
>> +		if (chan->local_amp_id)
>> +			l2cap_logical_create_channel(chan, hchan);
>> +	} else {
>> +		l2cap_logical_move_channel(chan, hchan);
>> +	}
>>  }
>>
>>  static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
>> --
>> 1.7.12.3

Regards,

--
Mat Martineau

Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


^ permalink raw reply

* [PATCH] Bluetooth: Fix having bogus entries in mgmt_read_index_list reply
From: Johan Hedberg @ 2012-10-19 17:10 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@intel.com>

The mgmt_read_index_list uses one loop to calculate the max needed size
of its response with the help of an upper-bound of the controller count.
The second loop is more strict as it checks for HCI_SETUP (which might
have gotten set after the first loop) and could result in some indexes
being skipped. Because of this the function needs to readjust the event
length and index count after filling in the response array.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Cc: stable@vger.kernel.org
---
 net/bluetooth/mgmt.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b127b88..e6d8f73 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -326,7 +326,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
 	struct hci_dev *d;
 	size_t rp_len;
 	u16 count;
-	int i, err;
+	int err;
 
 	BT_DBG("sock %p", sk);
 
@@ -347,9 +347,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
 		return -ENOMEM;
 	}
 
-	rp->num_controllers = cpu_to_le16(count);
-
-	i = 0;
+	count = 0;
 	list_for_each_entry(d, &hci_dev_list, list) {
 		if (test_bit(HCI_SETUP, &d->dev_flags))
 			continue;
@@ -357,10 +355,13 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data,
 		if (!mgmt_valid_hdev(d))
 			continue;
 
-		rp->index[i++] = cpu_to_le16(d->id);
+		rp->index[count++] = cpu_to_le16(d->id);
 		BT_DBG("Added hci%u", d->id);
 	}
 
+	rp->num_controllers = cpu_to_le16(count);
+	rp_len = sizeof(*rp) + (2 * count);
+
 	read_unlock(&hci_dev_list_lock);
 
 	err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp,
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 0/6] Bluetooth: Add basic support for single-mode controllers
From: Johan Hedberg @ 2012-10-19 17:15 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

This patch set adds initial support for single-mode controllers. I
haven't tested it yet with bluetoothd running but at least I'm able to
initialize and do some basic things with the virtual single-mode
controllers provided by b1ee.com (you can use emulator/b1ee to test
this).

FWIW, I've also tested that this doesn't break anything with the init
sequence for various other controllers that I have (includes 1.1, 1.2,
2.0, 2.1 and 4.0 controllers from several manufacturers).

Johan


^ permalink raw reply

* [PATCH 1/6] Bluetooth: Remove unnecessary LE init req from HCI core
From: Johan Hedberg @ 2012-10-19 17:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350666911-6334-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

The necessary LE commands will be sent through hci_event.c when the
local supported features indicates LE support.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/hci_core.c |   12 ------------
 1 file changed, 12 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 0ec776a..23359ef 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -273,14 +273,6 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 	}
 }
 
-static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
-{
-	BT_DBG("%s", hdev->name);
-
-	/* Read LE buffer size */
-	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
-}
-
 static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
 {
 	__u8 scan = opt;
@@ -687,10 +679,6 @@ int hci_dev_open(__u16 dev)
 
 		ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
 
-		if (lmp_host_le_capable(hdev))
-			ret = __hci_request(hdev, hci_le_init_req, 0,
-					    HCI_INIT_TIMEOUT);
-
 		clear_bit(HCI_INIT, &hdev->flags);
 	}
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/6] Bluetooth: Fix LE MTU reporting for HCIGETDEVINFO
From: Johan Hedberg @ 2012-10-19 17:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350666911-6334-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch fixes the use of le_mtu and le_pkts values in the
HCIGETDEVINFO ioctl for LE-only controllers.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/hci_core.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 23359ef..b5a2be2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1025,8 +1025,13 @@ int hci_get_dev_info(void __user *arg)
 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
 	di.flags    = hdev->flags;
 	di.pkt_type = hdev->pkt_type;
-	di.acl_mtu  = hdev->acl_mtu;
-	di.acl_pkts = hdev->acl_pkts;
+	if (lmp_bredr_capable(hdev)) {
+		di.acl_mtu  = hdev->acl_mtu;
+		di.acl_pkts = hdev->acl_pkts;
+	} else {
+		di.acl_mtu  = hdev->le_mtu;
+		di.acl_pkts = hdev->le_pkts;
+	}
 	di.sco_mtu  = hdev->sco_mtu;
 	di.sco_pkts = hdev->sco_pkts;
 	di.link_policy = hdev->link_policy;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 3/6] Bluetooth: Add initial support for LE-only controllers
From: Johan Hedberg @ 2012-10-19 17:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350666911-6334-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch splits off most the HCI init sequence commands from a fixed
set into a conditional one that is sent once the HCI_Read_Local_Features
command completes. This is necessary since many of the current fixed
commands are not allowed for LE-only controllers.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/hci_core.c  |   35 ---------------------------
 net/bluetooth/hci_event.c |   58 +++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 53 insertions(+), 40 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b5a2be2..d7014b3 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -178,48 +178,13 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
 
 static void bredr_init(struct hci_dev *hdev)
 {
-	struct hci_cp_delete_stored_link_key cp;
-	__le16 param;
-	__u8 flt_type;
-
 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
 
-	/* Mandatory initialization */
-
 	/* Read Local Supported Features */
 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
 
 	/* Read Local Version */
 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
-
-	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
-	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
-
-	/* Read BD Address */
-	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
-
-	/* Read Class of Device */
-	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
-
-	/* Read Local Name */
-	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
-
-	/* Read Voice Setting */
-	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
-
-	/* Optional initialization */
-
-	/* Clear Event Filters */
-	flt_type = HCI_FLT_CLEAR_ALL;
-	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
-
-	/* Connection accept timeout ~20 secs */
-	param = __constant_cpu_to_le16(0x7d00);
-	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
-
-	bacpy(&cp.bdaddr, BDADDR_ANY);
-	cp.delete_all = 1;
-	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
 }
 
 static void amp_init(struct hci_dev *hdev)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 0383635..f4f0b8b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -507,11 +507,13 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
 		return;
 
-	events[4] |= 0x01; /* Flow Specification Complete */
-	events[4] |= 0x02; /* Inquiry Result with RSSI */
-	events[4] |= 0x04; /* Read Remote Extended Features Complete */
-	events[5] |= 0x08; /* Synchronous Connection Complete */
-	events[5] |= 0x10; /* Synchronous Connection Changed */
+	if (lmp_bredr_capable(hdev)) {
+		events[4] |= 0x01; /* Flow Specification Complete */
+		events[4] |= 0x02; /* Inquiry Result with RSSI */
+		events[4] |= 0x04; /* Read Remote Extended Features Complete */
+		events[5] |= 0x08; /* Synchronous Connection Complete */
+		events[5] |= 0x10; /* Synchronous Connection Changed */
+	}
 
 	if (hdev->features[3] & LMP_RSSI_INQ)
 		events[4] |= 0x02; /* Inquiry Result with RSSI */
@@ -550,11 +552,57 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
 }
 
+static void bredr_init(struct hci_dev *hdev)
+{
+	struct hci_cp_delete_stored_link_key cp;
+	__le16 param;
+	__u8 flt_type;
+
+	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
+	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
+
+	/* Read Class of Device */
+	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
+
+	/* Read Local Name */
+	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
+
+	/* Read Voice Setting */
+	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
+
+	/* Clear Event Filters */
+	flt_type = HCI_FLT_CLEAR_ALL;
+	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
+
+	/* Connection accept timeout ~20 secs */
+	param = __constant_cpu_to_le16(0x7d00);
+	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
+
+	bacpy(&cp.bdaddr, BDADDR_ANY);
+	cp.delete_all = 1;
+	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
+}
+
+static void le_init(struct hci_dev *hdev)
+{
+	/* Read LE Buffer Size */
+	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
+}
+
 static void hci_setup(struct hci_dev *hdev)
 {
 	if (hdev->dev_type != HCI_BREDR)
 		return;
 
+	/* Read BD Address */
+	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
+
+	if (lmp_bredr_capable(hdev))
+		bredr_init(hdev);
+
+	if (lmp_le_capable(hdev))
+		le_init(hdev);
+
 	hci_setup_event_mask(hdev);
 
 	if (hdev->hci_ver > BLUETOOTH_VER_1_1)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 4/6] Bluetooth: Add setting of the LE event mask
From: Johan Hedberg @ 2012-10-19 17:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350666911-6334-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch adds setting of the LE event mask to the HCI init procedure
for LE-capable controllers. Right now we only set the default mask which
is good enough for the events available in the 4.0 core specification.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/hci_event.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f4f0b8b..78f1af5 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -550,6 +550,13 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
 		events[7] |= 0x20;	/* LE Meta-Event */
 
 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
+
+	if (lmp_le_capable(hdev)) {
+		memset(events, 0, sizeof(events));
+		events[0] = 0x1f;
+		hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK,
+			     sizeof(events), events);
+	}
 }
 
 static void bredr_init(struct hci_dev *hdev)
@@ -1066,6 +1073,15 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
 	hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
 }
 
+static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+	hci_req_complete(hdev, HCI_OP_LE_SET_EVENT_MASK, status);
+}
+
 static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
@@ -2489,6 +2505,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_cc_le_read_buffer_size(hdev, skb);
 		break;
 
+	case HCI_OP_LE_SET_EVENT_MASK:
+		hci_cc_le_set_event_mask(hdev, skb);
+		break;
+
 	case HCI_OP_USER_CONFIRM_REPLY:
 		hci_cc_user_confirm_reply(hdev, skb);
 		break;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 5/6] Bluetooth: Fix HCI command sending when powering on LE-only adapters
From: Johan Hedberg @ 2012-10-19 17:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350666911-6334-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch makes sure that we don't send BR/EDR-only commands for
LE-only adapters when they get powered on. Doing this would just cause
command errors.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/mgmt.c |   34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e6d8f73..3fe74f4 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2872,6 +2872,21 @@ static void settings_rsp(struct pending_cmd *cmd, void *data)
 	mgmt_pending_free(cmd);
 }
 
+static int set_bredr_scan(struct hci_dev *hdev)
+{
+	u8 scan = 0;
+
+	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
+		scan |= SCAN_PAGE;
+	if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
+		scan |= SCAN_INQUIRY;
+
+	if (!scan)
+		return 0;
+
+	return hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+}
+
 int mgmt_powered(struct hci_dev *hdev, u8 powered)
 {
 	struct cmd_lookup match = { NULL, hdev };
@@ -2883,19 +2898,12 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
 	mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
 
 	if (powered) {
-		u8 scan = 0;
-
-		if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
-			scan |= SCAN_PAGE;
-		if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
-			scan |= SCAN_INQUIRY;
-
-		if (scan)
-			hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
-
-		update_class(hdev);
-		update_name(hdev, hdev->dev_name);
-		update_eir(hdev);
+		if (lmp_bredr_capable(hdev)) {
+			set_bredr_scan(hdev);
+			update_class(hdev);
+			update_name(hdev, hdev->dev_name);
+			update_eir(hdev);
+		}
 	} else {
 		u8 status = MGMT_STATUS_NOT_POWERED;
 		mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 6/6] Bluetooth: Read adversiting channel TX power during init sequence
From: Johan Hedberg @ 2012-10-19 17:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350666911-6334-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch adds the reading of the LE advertising channel TX power to
the HCI init sequence of LE-capable controllers. This data will be used
e.g. for inclusion in the advertising data packets when advertising is
enabled.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci.h      |    6 ++++++
 include/net/bluetooth/hci_core.h |    2 ++
 net/bluetooth/hci_event.c        |   20 ++++++++++++++++++++
 3 files changed, 28 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 88cbbda..348f4bf 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -932,6 +932,12 @@ struct hci_rp_le_read_buffer_size {
 	__u8     le_max_pkt;
 } __packed;
 
+#define HCI_OP_LE_READ_ADV_TX_POWER	0x2007
+struct hci_rp_le_read_adv_tx_power {
+	__u8	status;
+	__s8	tx_power;
+} __packed;
+
 #define HCI_OP_LE_SET_SCAN_PARAM	0x200b
 struct hci_cp_le_set_scan_param {
 	__u8    type;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 9fe8e2d..8260bf2 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -278,6 +278,8 @@ struct hci_dev {
 	struct work_struct	le_scan;
 	struct le_scan_params	le_scan_params;
 
+	__s8			adv_tx_power;
+
 	int (*open)(struct hci_dev *hdev);
 	int (*close)(struct hci_dev *hdev);
 	int (*flush)(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 78f1af5..fd5a51c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -594,6 +594,9 @@ static void le_init(struct hci_dev *hdev)
 {
 	/* Read LE Buffer Size */
 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
+
+	/* Read LE Advertising Channel TX Power */
+	hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
 }
 
 static void hci_setup(struct hci_dev *hdev)
@@ -1073,6 +1076,19 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
 	hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
 }
 
+static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
+					struct sk_buff *skb)
+{
+	struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+	if (!rp->status)
+		hdev->adv_tx_power = rp->tx_power;
+
+	hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status);
+}
+
 static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	__u8 status = *((__u8 *) skb->data);
@@ -2505,6 +2521,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_cc_le_read_buffer_size(hdev, skb);
 		break;
 
+	case HCI_OP_LE_READ_ADV_TX_POWER:
+		hci_cc_le_read_adv_tx_power(hdev, skb);
+		break;
+
 	case HCI_OP_LE_SET_EVENT_MASK:
 		hci_cc_le_set_event_mask(hdev, skb);
 		break;
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH] Bluetooth: Fix having bogus entries in mgmt_read_index_list reply
From: Marcel Holtmann @ 2012-10-19 17:17 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1350666646-6276-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> The mgmt_read_index_list uses one loop to calculate the max needed size
> of its response with the help of an upper-bound of the controller count.
> The second loop is more strict as it checks for HCI_SETUP (which might
> have gotten set after the first loop) and could result in some indexes
> being skipped. Because of this the function needs to readjust the event
> length and index count after filling in the response array.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> Cc: stable@vger.kernel.org
> ---
>  net/bluetooth/mgmt.c |   11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 2/6] Bluetooth: Fix LE MTU reporting for HCIGETDEVINFO
From: Marcel Holtmann @ 2012-10-19 17:20 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1350666911-6334-3-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> This patch fixes the use of le_mtu and le_pkts values in the
> HCIGETDEVINFO ioctl for LE-only controllers.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
>  net/bluetooth/hci_core.c |    9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 23359ef..b5a2be2 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -1025,8 +1025,13 @@ int hci_get_dev_info(void __user *arg)
>  	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
>  	di.flags    = hdev->flags;
>  	di.pkt_type = hdev->pkt_type;
> -	di.acl_mtu  = hdev->acl_mtu;
> -	di.acl_pkts = hdev->acl_pkts;
> +	if (lmp_bredr_capable(hdev)) {
> +		di.acl_mtu  = hdev->acl_mtu;
> +		di.acl_pkts = hdev->acl_pkts;
> +	} else {
> +		di.acl_mtu  = hdev->le_mtu;
> +		di.acl_pkts = hdev->le_pkts;
> +	}
>  	di.sco_mtu  = hdev->sco_mtu;
>  	di.sco_pkts = hdev->sco_pkts;
>  	di.link_policy = hdev->link_policy;

shouldn't we ensure that di.sco_mtu and di.sco_pkts is set to 0 for LE
only devices. I rather make this explicit here instead of relying that
it is zeroed at controller creation. In theory there still is a code
path that might set these.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 3/6] Bluetooth: Add initial support for LE-only controllers
From: Marcel Holtmann @ 2012-10-19 17:23 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1350666911-6334-4-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> This patch splits off most the HCI init sequence commands from a fixed
> set into a conditional one that is sent once the HCI_Read_Local_Features
> command completes. This is necessary since many of the current fixed
> commands are not allowed for LE-only controllers.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
>  net/bluetooth/hci_core.c  |   35 ---------------------------
>  net/bluetooth/hci_event.c |   58 +++++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 53 insertions(+), 40 deletions(-)

I would merge this one with patch 1/6. Having them split up seems a bit
weird. Especially with 2/6 in between that has nothing to do with it.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 4/6] Bluetooth: Add setting of the LE event mask
From: Marcel Holtmann @ 2012-10-19 17:23 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1350666911-6334-5-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> This patch adds setting of the LE event mask to the HCI init procedure
> for LE-capable controllers. Right now we only set the default mask which
> is good enough for the events available in the 4.0 core specification.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
>  net/bluetooth/hci_event.c |   20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 5/6] Bluetooth: Fix HCI command sending when powering on LE-only adapters
From: Marcel Holtmann @ 2012-10-19 17:24 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1350666911-6334-6-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> This patch makes sure that we don't send BR/EDR-only commands for
> LE-only adapters when they get powered on. Doing this would just cause
> command errors.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
>  net/bluetooth/mgmt.c |   34 +++++++++++++++++++++-------------
>  1 file changed, 21 insertions(+), 13 deletions(-)

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 6/6] Bluetooth: Read adversiting channel TX power during init sequence
From: Marcel Holtmann @ 2012-10-19 17:25 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1350666911-6334-7-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> This patch adds the reading of the LE advertising channel TX power to
> the HCI init sequence of LE-capable controllers. This data will be used
> e.g. for inclusion in the advertising data packets when advertising is
> enabled.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
>  include/net/bluetooth/hci.h      |    6 ++++++
>  include/net/bluetooth/hci_core.h |    2 ++
>  net/bluetooth/hci_event.c        |   20 ++++++++++++++++++++
>  3 files changed, 28 insertions(+)

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 0/5 v2] Bluetooth: Add basic support for single-mode controllers
From: Marcel Holtmann @ 2012-10-19 17:57 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1350669469-7719-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> Here's an update to the initial set with Marcel's comments taken into
> account.

looks all good.

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel



^ permalink raw reply

* [PATCH 0/5 v2] Bluetooth: Add basic support for single-mode controllers
From: Johan Hedberg @ 2012-10-19 17:57 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

Here's an update to the initial set with Marcel's comments taken into
account.

Johan


^ permalink raw reply

* [PATCH 1/5 v2] Bluetooth: Add initial support for LE-only controllers
From: Johan Hedberg @ 2012-10-19 17:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350669469-7719-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch splits off most the HCI init sequence commands from a fixed
set into a conditional one that is sent once the HCI_Read_Local_Features
and HCI_Read_Local_Version_Information commands complete. This is
necessary since many of the current fixed commands are not allowed for
LE-only controllers.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/hci_core.c  |   47 ------------------------------------
 net/bluetooth/hci_event.c |   58 +++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 53 insertions(+), 52 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 0ec776a..dd05ed0 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -178,48 +178,13 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
 
 static void bredr_init(struct hci_dev *hdev)
 {
-	struct hci_cp_delete_stored_link_key cp;
-	__le16 param;
-	__u8 flt_type;
-
 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
 
-	/* Mandatory initialization */
-
 	/* Read Local Supported Features */
 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
 
 	/* Read Local Version */
 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
-
-	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
-	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
-
-	/* Read BD Address */
-	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
-
-	/* Read Class of Device */
-	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
-
-	/* Read Local Name */
-	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
-
-	/* Read Voice Setting */
-	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
-
-	/* Optional initialization */
-
-	/* Clear Event Filters */
-	flt_type = HCI_FLT_CLEAR_ALL;
-	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
-
-	/* Connection accept timeout ~20 secs */
-	param = __constant_cpu_to_le16(0x7d00);
-	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
-
-	bacpy(&cp.bdaddr, BDADDR_ANY);
-	cp.delete_all = 1;
-	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
 }
 
 static void amp_init(struct hci_dev *hdev)
@@ -273,14 +238,6 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 	}
 }
 
-static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
-{
-	BT_DBG("%s", hdev->name);
-
-	/* Read LE buffer size */
-	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
-}
-
 static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
 {
 	__u8 scan = opt;
@@ -687,10 +644,6 @@ int hci_dev_open(__u16 dev)
 
 		ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
 
-		if (lmp_host_le_capable(hdev))
-			ret = __hci_request(hdev, hci_le_init_req, 0,
-					    HCI_INIT_TIMEOUT);
-
 		clear_bit(HCI_INIT, &hdev->flags);
 	}
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 0383635..f4f0b8b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -507,11 +507,13 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
 		return;
 
-	events[4] |= 0x01; /* Flow Specification Complete */
-	events[4] |= 0x02; /* Inquiry Result with RSSI */
-	events[4] |= 0x04; /* Read Remote Extended Features Complete */
-	events[5] |= 0x08; /* Synchronous Connection Complete */
-	events[5] |= 0x10; /* Synchronous Connection Changed */
+	if (lmp_bredr_capable(hdev)) {
+		events[4] |= 0x01; /* Flow Specification Complete */
+		events[4] |= 0x02; /* Inquiry Result with RSSI */
+		events[4] |= 0x04; /* Read Remote Extended Features Complete */
+		events[5] |= 0x08; /* Synchronous Connection Complete */
+		events[5] |= 0x10; /* Synchronous Connection Changed */
+	}
 
 	if (hdev->features[3] & LMP_RSSI_INQ)
 		events[4] |= 0x02; /* Inquiry Result with RSSI */
@@ -550,11 +552,57 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
 }
 
+static void bredr_init(struct hci_dev *hdev)
+{
+	struct hci_cp_delete_stored_link_key cp;
+	__le16 param;
+	__u8 flt_type;
+
+	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
+	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
+
+	/* Read Class of Device */
+	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
+
+	/* Read Local Name */
+	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
+
+	/* Read Voice Setting */
+	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
+
+	/* Clear Event Filters */
+	flt_type = HCI_FLT_CLEAR_ALL;
+	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
+
+	/* Connection accept timeout ~20 secs */
+	param = __constant_cpu_to_le16(0x7d00);
+	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
+
+	bacpy(&cp.bdaddr, BDADDR_ANY);
+	cp.delete_all = 1;
+	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
+}
+
+static void le_init(struct hci_dev *hdev)
+{
+	/* Read LE Buffer Size */
+	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
+}
+
 static void hci_setup(struct hci_dev *hdev)
 {
 	if (hdev->dev_type != HCI_BREDR)
 		return;
 
+	/* Read BD Address */
+	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
+
+	if (lmp_bredr_capable(hdev))
+		bredr_init(hdev);
+
+	if (lmp_le_capable(hdev))
+		le_init(hdev);
+
 	hci_setup_event_mask(hdev);
 
 	if (hdev->hci_ver > BLUETOOTH_VER_1_1)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/5 v2] Bluetooth: Fix LE MTU reporting for HCIGETDEVINFO
From: Johan Hedberg @ 2012-10-19 17:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350669469-7719-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch fixes the use of le_mtu and le_pkts values in the
HCIGETDEVINFO ioctl for LE-only controllers.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/hci_core.c |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index dd05ed0..487308b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -990,10 +990,17 @@ int hci_get_dev_info(void __user *arg)
 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
 	di.flags    = hdev->flags;
 	di.pkt_type = hdev->pkt_type;
-	di.acl_mtu  = hdev->acl_mtu;
-	di.acl_pkts = hdev->acl_pkts;
-	di.sco_mtu  = hdev->sco_mtu;
-	di.sco_pkts = hdev->sco_pkts;
+	if (lmp_bredr_capable(hdev)) {
+		di.acl_mtu  = hdev->acl_mtu;
+		di.acl_pkts = hdev->acl_pkts;
+		di.sco_mtu  = hdev->sco_mtu;
+		di.sco_pkts = hdev->sco_pkts;
+	} else {
+		di.acl_mtu  = hdev->le_mtu;
+		di.acl_pkts = hdev->le_pkts;
+		di.sco_mtu  = 0;
+		di.sco_pkts = 0;
+	}
 	di.link_policy = hdev->link_policy;
 	di.link_mode   = hdev->link_mode;
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 3/5 v2] Bluetooth: Add setting of the LE event mask
From: Johan Hedberg @ 2012-10-19 17:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350669469-7719-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch adds setting of the LE event mask to the HCI init procedure
for LE-capable controllers. Right now we only set the default mask which
is good enough for the events available in the 4.0 core specification.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_event.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f4f0b8b..78f1af5 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -550,6 +550,13 @@ static void hci_setup_event_mask(struct hci_dev *hdev)
 		events[7] |= 0x20;	/* LE Meta-Event */
 
 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
+
+	if (lmp_le_capable(hdev)) {
+		memset(events, 0, sizeof(events));
+		events[0] = 0x1f;
+		hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK,
+			     sizeof(events), events);
+	}
 }
 
 static void bredr_init(struct hci_dev *hdev)
@@ -1066,6 +1073,15 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
 	hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
 }
 
+static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+	hci_req_complete(hdev, HCI_OP_LE_SET_EVENT_MASK, status);
+}
+
 static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
@@ -2489,6 +2505,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_cc_le_read_buffer_size(hdev, skb);
 		break;
 
+	case HCI_OP_LE_SET_EVENT_MASK:
+		hci_cc_le_set_event_mask(hdev, skb);
+		break;
+
 	case HCI_OP_USER_CONFIRM_REPLY:
 		hci_cc_user_confirm_reply(hdev, skb);
 		break;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 4/5 v2] Bluetooth: Fix HCI command sending when powering on LE-only adapters
From: Johan Hedberg @ 2012-10-19 17:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350669469-7719-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch makes sure that we don't send BR/EDR-only commands for
LE-only adapters when they get powered on. Doing this would just cause
command errors.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/mgmt.c |   34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e6d8f73..3fe74f4 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2872,6 +2872,21 @@ static void settings_rsp(struct pending_cmd *cmd, void *data)
 	mgmt_pending_free(cmd);
 }
 
+static int set_bredr_scan(struct hci_dev *hdev)
+{
+	u8 scan = 0;
+
+	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
+		scan |= SCAN_PAGE;
+	if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
+		scan |= SCAN_INQUIRY;
+
+	if (!scan)
+		return 0;
+
+	return hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+}
+
 int mgmt_powered(struct hci_dev *hdev, u8 powered)
 {
 	struct cmd_lookup match = { NULL, hdev };
@@ -2883,19 +2898,12 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
 	mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
 
 	if (powered) {
-		u8 scan = 0;
-
-		if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
-			scan |= SCAN_PAGE;
-		if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
-			scan |= SCAN_INQUIRY;
-
-		if (scan)
-			hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
-
-		update_class(hdev);
-		update_name(hdev, hdev->dev_name);
-		update_eir(hdev);
+		if (lmp_bredr_capable(hdev)) {
+			set_bredr_scan(hdev);
+			update_class(hdev);
+			update_name(hdev, hdev->dev_name);
+			update_eir(hdev);
+		}
 	} else {
 		u8 status = MGMT_STATUS_NOT_POWERED;
 		mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 5/5 v2] Bluetooth: Read adversiting channel TX power during init sequence
From: Johan Hedberg @ 2012-10-19 17:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350669469-7719-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch adds the reading of the LE advertising channel TX power to
the HCI init sequence of LE-capable controllers. This data will be used
e.g. for inclusion in the advertising data packets when advertising is
enabled.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h      |    6 ++++++
 include/net/bluetooth/hci_core.h |    2 ++
 net/bluetooth/hci_event.c        |   20 ++++++++++++++++++++
 3 files changed, 28 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 88cbbda..348f4bf 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -932,6 +932,12 @@ struct hci_rp_le_read_buffer_size {
 	__u8     le_max_pkt;
 } __packed;
 
+#define HCI_OP_LE_READ_ADV_TX_POWER	0x2007
+struct hci_rp_le_read_adv_tx_power {
+	__u8	status;
+	__s8	tx_power;
+} __packed;
+
 #define HCI_OP_LE_SET_SCAN_PARAM	0x200b
 struct hci_cp_le_set_scan_param {
 	__u8    type;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 9fe8e2d..8260bf2 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -278,6 +278,8 @@ struct hci_dev {
 	struct work_struct	le_scan;
 	struct le_scan_params	le_scan_params;
 
+	__s8			adv_tx_power;
+
 	int (*open)(struct hci_dev *hdev);
 	int (*close)(struct hci_dev *hdev);
 	int (*flush)(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 78f1af5..fd5a51c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -594,6 +594,9 @@ static void le_init(struct hci_dev *hdev)
 {
 	/* Read LE Buffer Size */
 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
+
+	/* Read LE Advertising Channel TX Power */
+	hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
 }
 
 static void hci_setup(struct hci_dev *hdev)
@@ -1073,6 +1076,19 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
 	hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
 }
 
+static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
+					struct sk_buff *skb)
+{
+	struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
+
+	if (!rp->status)
+		hdev->adv_tx_power = rp->tx_power;
+
+	hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status);
+}
+
 static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	__u8 status = *((__u8 *) skb->data);
@@ -2505,6 +2521,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_cc_le_read_buffer_size(hdev, skb);
 		break;
 
+	case HCI_OP_LE_READ_ADV_TX_POWER:
+		hci_cc_le_read_adv_tx_power(hdev, skb);
+		break;
+
 	case HCI_OP_LE_SET_EVENT_MASK:
 		hci_cc_le_set_event_mask(hdev, skb);
 		break;
-- 
1.7.10.4


^ 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