Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH] Bluetooth: l2cap_physical_cfm() can be static
From: Andrei Emeltchenko @ 2012-10-25  7:13 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Fengguang Wu, Gustavo Padovan, Mat Martineau, linux-bluetooth
In-Reply-To: <1351130134.1785.85.camel@aeonflux>

Hi,

On Wed, Oct 24, 2012 at 06:55:34PM -0700, Marcel Holtmann wrote:
> Hi Fengguang,
> 
> > Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> > ---
> >  net/bluetooth/l2cap_core.c |    2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > --- linux-next.orig/net/bluetooth/l2cap_core.c	2012-10-25 08:23:52.456742699 +0800
> > +++ linux-next/net/bluetooth/l2cap_core.c	2012-10-25 08:23:55.056742760 +0800
> > @@ -4569,7 +4569,7 @@ static void l2cap_do_move_cancel(struct
> >  	l2cap_ertm_send(chan);
> >  }
> >  
> > -void l2cap_physical_cfm(struct l2cap_chan *chan, int result, u8 local_amp_id,
> > +static void l2cap_physical_cfm(struct l2cap_chan *chan, int result, u8 local_amp_id,
> >  			u8 remote_amp_id)
> 
> I rather wait for Mat to ACK or NACK this one. Maybe it is an oversight
> or we need that later on to be actually public.

Agree with Marcel here. This shall be public.

Best regards 
Andrei Emeltchenko 

^ permalink raw reply

* Re: [PATCH 5/6] Bluetooth: mgmt: Add support for switching to LE peripheral mode
From: Johan Hedberg @ 2012-10-25  7:50 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: Marcel Holtmann, linux-bluetooth
In-Reply-To: <20121025045605.GB12303@echo>

Hi Vinicius,

On Thu, Oct 25, 2012, Vinicius Costa Gomes wrote:
> So, what information will we use to set the advertising type and the
> Flags field in the advertising event (think general/limited
> discoverable modes)?

Take a look at the create_ad() function in the last patch of this set.
Setting the right flags value is really quite simple. The advertising
type could be selected in a similar way, i.e. through hdev->dev_flags.

Johan

^ permalink raw reply

* Re: [PATCH v7 13/16] device: Retrieve name from cache directory
From: Johan Hedberg @ 2012-10-25  9:52 UTC (permalink / raw)
  To: Frédéric Danis; +Cc: linux-bluetooth
In-Reply-To: <1351089258-25179-14-git-send-email-frederic.danis@linux.intel.com>

Hi Frédéric,

On Wed, Oct 24, 2012, Frédéric Danis wrote:
> ---
>  src/device.c |   25 ++++++++++++++++++++++++-
>  1 file changed, 24 insertions(+), 1 deletion(-)

I've applied patches 1-12 since they seemed fine to me but there are
some things to consider with 13-16:

> --- a/src/device.c
> +++ b/src/device.c
> @@ -1573,6 +1573,8 @@ struct btd_device *device_create(struct btd_adapter *adapter,
>  	const bdaddr_t *src;
>  	char srcaddr[18], alias[MAX_NAME_LENGTH + 1];
>  	uint16_t vendor, product, version;
> +	char filename[PATH_MAX + 1];
> +	GKeyFile *key_file;
>  
>  	device = g_try_malloc0(sizeof(struct btd_device));
>  	if (device == NULL)
> @@ -1600,7 +1602,28 @@ struct btd_device *device_create(struct btd_adapter *adapter,
>  	src = adapter_get_address(adapter);
>  	ba2str(src, srcaddr);
>  
> -	read_device_name(srcaddr, address, bdaddr_type, device->name);
> +	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", srcaddr,
> +			address);
> +	filename[PATH_MAX] = '\0';
> +	key_file = g_key_file_new();
> +
> +	if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
> +		char *str;
> +		int len;
> +
> +		str = g_key_file_get_string(key_file, "General", "Name", NULL);
> +		if (str) {
> +			len = strlen(str);
> +			if (len > HCI_MAX_NAME_LENGTH)
> +				str[HCI_MAX_NAME_LENGTH] = '\0';
> +
> +			strcpy(device->name, str);
> +			g_free(str);
> +		}
> +	}
> +
> +	g_key_file_free(key_file);
> +

I'd rather have you split off a separate function to load the config
like you have for adapters.

Regarding the device name, I think the idea is that removing the cache
shouldn't cause any bad behavior with the persistent part of the storage
(i.e. configured devices). So we should probably also have the name in
the per-device storage file and try to read it from there first and if
that fails fall back to the cache.

Johan

^ permalink raw reply

* Re: [PATCH v7 14/16] dbusoob: Store device name in cache directory
From: Johan Hedberg @ 2012-10-25  9:54 UTC (permalink / raw)
  To: Frédéric Danis; +Cc: linux-bluetooth
In-Reply-To: <1351089258-25179-15-git-send-email-frederic.danis@linux.intel.com>

Hi Frédéric,

On Wed, Oct 24, 2012, Frédéric Danis wrote:
> ---
>  plugins/dbusoob.c |   26 +++++++++++++++++++++++---
>  1 file changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
> index 5c5b6ef..82d512c 100644
> --- a/plugins/dbusoob.c
> +++ b/plugins/dbusoob.c
> @@ -31,6 +31,7 @@
>  
>  #include <errno.h>
>  #include <gdbus.h>
> +#include <sys/stat.h>
>  
>  #include <bluetooth/bluetooth.h>
>  #include <bluetooth/hci.h>
> @@ -194,6 +195,11 @@ static gboolean parse_data(DBusMessageIter *data, struct oob_data *remote_data)
>  static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
>  {
>  	bdaddr_t bdaddr;
> +	char filename[PATH_MAX + 1];
> +	char s_addr[18];
> +	GKeyFile *key_file;
> +	char *str;
> +	gsize length = 0;
>  
>  	str2ba(data->addr, &bdaddr);
>  
> @@ -207,9 +213,23 @@ static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
>  		write_remote_class(adapter_get_address(adapter), &bdaddr,
>  								data->class);
>  
> -	if (data->name)
> -		write_device_name(adapter_get_address(adapter), &bdaddr, 0,
> -								data->name);
> +	if (data->name) {
> +		ba2str(adapter_get_address(adapter), s_addr);
> +		snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
> +				s_addr, data->addr);
> +		filename[PATH_MAX] = '\0';
> +		create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
> +
> +		key_file = g_key_file_new();
> +		g_key_file_load_from_file(key_file, filename, 0, NULL);
> +		g_key_file_set_string(key_file, "General", "Name", data->name);
> +
> +		str = g_key_file_to_data(key_file, &length, NULL);
> +		g_file_set_contents(filename, str, length, NULL);
> +		g_free(str);
> +
> +		g_key_file_free(key_file);
> +	}

There shouldn't this kind of core-daemon keyfile access from plugins, In
this case you should get a btd_device object and simply do a
btd_device_set_name (and if that function doesn't yet write to storage
update it so that it does).

Johan

^ permalink raw reply

* Re: [PATCH v7 15/16] input: Retrieve device name from cache directory
From: Johan Hedberg @ 2012-10-25  9:55 UTC (permalink / raw)
  To: Frédéric Danis; +Cc: linux-bluetooth
In-Reply-To: <1351089258-25179-16-git-send-email-frederic.danis@linux.intel.com>

Hi Frédéric,

On Wed, Oct 24, 2012, Frédéric Danis wrote:
> ---
>  profiles/input/device.c |   26 ++++++++++++++++++++++----
>  1 file changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/profiles/input/device.c b/profiles/input/device.c
> index 9dd8002..41b7a5c 100644
> --- a/profiles/input/device.c
> +++ b/profiles/input/device.c
> @@ -37,6 +37,7 @@
>  #include <bluetooth/sdp_lib.h>
>  #include <bluetooth/uuid.h>
>  
> +#include <glib.h>
>  #include <gdbus.h>
>  
>  #include "log.h"
> @@ -757,7 +758,9 @@ static struct input_device *input_device_new(struct btd_device *device,
>  {
>  	struct btd_adapter *adapter = device_get_adapter(device);
>  	struct input_device *idev;
> -	char name[249], src_addr[18], dst_addr[18];
> +	char src_addr[18], dst_addr[18];
> +	char filename[PATH_MAX + 1];
> +	GKeyFile *key_file;
>  
>  	idev = g_new0(struct input_device, 1);
>  	bacpy(&idev->src, adapter_get_address(adapter));
> @@ -770,9 +773,24 @@ static struct input_device *input_device_new(struct btd_device *device,
>  	ba2str(&idev->src, src_addr);
>  	ba2str(&idev->dst, dst_addr);
>  
> -	if (read_device_name(src_addr, dst_addr, device_get_addr_type(device),
> -				name) == 0)
> -		idev->name = g_strdup(name);
> +	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", src_addr,
> +			dst_addr);
> +	filename[PATH_MAX] = '\0';
> +	key_file = g_key_file_new();
> +
> +	if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
> +		int len;
> +
> +		idev->name = g_key_file_get_string(key_file, "General",
> +								"Name", NULL);
> +		if (idev->name) {
> +			len = strlen(idev->name);
> +			if (len > HCI_MAX_NAME_LENGTH)
> +				idev->name[HCI_MAX_NAME_LENGTH] = '\0';
> +		}
> +	}
> +
> +	g_key_file_free(key_file);
>  
>  	if (g_dbus_register_interface(btd_get_dbus_connection(),
>  					idev->path, INPUT_DEVICE_INTERFACE,

Same thing here with accessing core-daemon keyfiles directly. Just use
the btd_device_get_name function.

Johan

^ permalink raw reply

* Re: [PATCH v7 16/16] hcitool: Retrieve names from cache directory
From: Johan Hedberg @ 2012-10-25  9:55 UTC (permalink / raw)
  To: Frédéric Danis; +Cc: linux-bluetooth
In-Reply-To: <1351089258-25179-17-git-send-email-frederic.danis@linux.intel.com>

Frédéric,

On Wed, Oct 24, 2012, Frédéric Danis wrote:
>  static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer)
>  {
> -	char filename[PATH_MAX + 1], addr[18];
> +	char filename[PATH_MAX + 1];
> +	char local_addr[18], peer_addr[18];
> +	GKeyFile *key_file;
> +	char *str = NULL;
> +	int len;
> +
> +	ba2str(local, local_addr);
> +	ba2str(peer, peer_addr);
> +
> +	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local_addr,
> +			peer_addr);
> +	filename[PATH_MAX] = '\0';
> +	key_file = g_key_file_new();
> +
> +	if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
> +		str = g_key_file_get_string(key_file, "General", "Name", NULL);
> +		if (str) {
> +			len = strlen(str);
> +			if (len > HCI_MAX_NAME_LENGTH)
> +				str[HCI_MAX_NAME_LENGTH] = '\0';
> +		}
> +	}
>  
> -	ba2str(local, addr);
> -	create_name(filename, PATH_MAX, STORAGEDIR, addr, "names");
> +	g_key_file_free(key_file);
>  
> -	ba2str(peer, addr);
> -	return textfile_get(filename, addr);
> +	return str;
>  }

This is the one exception where it's ok to directly go digging in the
cache, as we don't have the concept of btd_device in hcitool.

Johan

^ permalink raw reply

* Re: [RFC v0 12/15] input: Add profile .disconnect
From: Johan Hedberg @ 2012-10-25 10:39 UTC (permalink / raw)
  To: Mikel Astiz; +Cc: linux-bluetooth, Mikel Astiz
In-Reply-To: <1350661172-18125-13-git-send-email-mikel.astiz.oss@gmail.com>

Hi Mikel,

On Fri, Oct 19, 2012, Mikel Astiz wrote:
> From: Mikel Astiz <mikel.astiz@bmw-carit.de>
> 
> Add the disconnect hook to the btd_profile.
> ---
>  profiles/input/manager.c | 1 +
>  1 file changed, 1 insertion(+)

I've applied the patches up until this one with the exception of the
audio ones which I'll let Luiz to look at and sync up with the work he's
doing for audio right now. The last three will still need some
discussion as I'm not convinced that it's a good idea to have these
generic profile objects instead or Adapter.Connect/DisconnectProfile.

Johan

^ permalink raw reply

* Re: [PATCH 5/6] Bluetooth: mgmt: Add support for switching to LE peripheral mode
From: Anderson Lizardo @ 2012-10-25 10:41 UTC (permalink / raw)
  To: Vinicius Costa Gomes, Marcel Holtmann, linux-bluetooth
In-Reply-To: <20121025075045.GA22397@x220>

Hi Johan,

On Thu, Oct 25, 2012 at 3:50 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Vinicius,
>
> On Thu, Oct 25, 2012, Vinicius Costa Gomes wrote:
>> So, what information will we use to set the advertising type and the
>> Flags field in the advertising event (think general/limited
>> discoverable modes)?
>
> Take a look at the create_ad() function in the last patch of this set.
> Setting the right flags value is really quite simple. The advertising
> type could be selected in a similar way, i.e. through hdev->dev_flags.

I don't see any use now, but "actual" LE peripherals allow to use
directed advertising when for instance, they need to send an ATT
notification just to a specific device, and not let anyone else
connect to them. Do you see an easy way of selecting an specific
device to advertise to?

The issue here is that once LE Peripheral is enabled, any device can
connect to you (e.g. other previously bonded devices will for sure
attempt to reconnect). If you want to be connected by a specific
device, you need to use directed advertising from the beginning.

Also is LE advertising re-enabled when a connection is established
(remember it is disabled automatically by the controller after
connection is established)? And after an HCI Reset ?

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [RFC v0 05/15] network: Add network .connect and .disconnect
From: Johan Hedberg @ 2012-10-25 10:42 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: Mikel Astiz, linux-bluetooth, Mikel Astiz
In-Reply-To: <CAJdJm_NfFbRfLg9Jp_id3_z74P5A-Rg0VPnHvvD-6NopJWTB=Q@mail.gmail.com>

Hi Lizardo,

On Wed, Oct 24, 2012, Anderson Lizardo wrote:
> Hi Mikel,
> 
> On Fri, Oct 19, 2012 at 11:39 AM, Mikel Astiz <mikel.astiz.oss@gmail.com> wrote:
> > +static void connect_profile_cb(struct btd_device *device, int err,
> > +                                               const char *pdev, void *data)
> > +{
> > +       struct connect_req *req = data;
> > +
> > +       req->cb(req->profile, req->device, err);
> > +
> > +       g_free(req);
> > +}
> > +
> > +static int connect_profile(struct btd_device *dev, struct btd_profile *profile,
> > +                                               uint16_t id, btd_profile_cb cb)
> > +{
> > +       struct connect_req *req;
> > +       int err;
> > +
> > +       DBG("path %s id %u", device_get_path(dev), id);
> > +
> > +       req  = g_new0(struct connect_req, 1);
> > +       req->device = dev;
> 
> Isn't btd_device_ref() required here?

Looks like you're right and I missed this in my initial review. I went
ahead and pushed an extra patch to fix this.

Johan

^ permalink raw reply

* Re: [PATCH 5/6] Bluetooth: mgmt: Add support for switching to LE peripheral mode
From: Johan Hedberg @ 2012-10-25 11:48 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: Vinicius Costa Gomes, Marcel Holtmann, linux-bluetooth
In-Reply-To: <CAJdJm_Odk8_8dLjcYw9kfr+CCD0Q0bNgu9duhRo6oKXYAo9cKA@mail.gmail.com>

Hi Lizardo,

On Thu, Oct 25, 2012, Anderson Lizardo wrote:
> On Thu, Oct 25, 2012 at 3:50 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> > Hi Vinicius,
> >
> > On Thu, Oct 25, 2012, Vinicius Costa Gomes wrote:
> >> So, what information will we use to set the advertising type and the
> >> Flags field in the advertising event (think general/limited
> >> discoverable modes)?
> >
> > Take a look at the create_ad() function in the last patch of this set.
> > Setting the right flags value is really quite simple. The advertising
> > type could be selected in a similar way, i.e. through hdev->dev_flags.
> 
> I don't see any use now, but "actual" LE peripherals allow to use
> directed advertising when for instance, they need to send an ATT
> notification just to a specific device, and not let anyone else
> connect to them. Do you see an easy way of selecting an specific
> device to advertise to?
> 
> The issue here is that once LE Peripheral is enabled, any device can
> connect to you (e.g. other previously bonded devices will for sure
> attempt to reconnect). If you want to be connected by a specific
> device, you need to use directed advertising from the beginning.

This will need some more thinking. We could add a new mgmt command for
that, or if you wanna go crazy why not map this to the L2CAP socket
interface's connect() system call. I.e. if LE GAP is in peripheral mode
instead of doing HCI_LE_Create_Connection or just failing with "not
allowed" a socket connect() would simply trigger directed advertising to
the device in question and deliver the successful connection in the same
way as a central role triggered connect would do (unless we time out
waiting for the remote device to connect). Now that I think of this
second option it actually sounds quite natural and not so crazy after
all :)

> Also is LE advertising re-enabled when a connection is established
> (remember it is disabled automatically by the controller after
> connection is established)? And after an HCI Reset ?

The "after a connection" part is still missing and I'll have that as a
separate patch not to grow the already quite big patch. As for reset,
right now that's only sent when power-cycling the adapter and the HCI
init sequence then takes care of enabling advertising.

Johan

^ permalink raw reply

* Re: [PATCH 5/6] Bluetooth: mgmt: Add support for switching to LE peripheral mode
From: Johan Hedberg @ 2012-10-25 12:04 UTC (permalink / raw)
  To: Anderson Lizardo, Vinicius Costa Gomes, Marcel Holtmann,
	linux-bluetooth
In-Reply-To: <20121025114817.GA2197@x220>

Hi,

On Thu, Oct 25, 2012, Johan Hedberg wrote:
> This will need some more thinking. We could add a new mgmt command for
> that, or if you wanna go crazy why not map this to the L2CAP socket
> interface's connect() system call. I.e. if LE GAP is in peripheral mode
> instead of doing HCI_LE_Create_Connection or just failing with "not
> allowed" a socket connect() would simply trigger directed advertising to
> the device in question and deliver the successful connection in the same
> way as a central role triggered connect would do (unless we time out
> waiting for the remote device to connect). Now that I think of this
> second option it actually sounds quite natural and not so crazy after
> all :)

There's on problem with this though: we'd still be undirected
connectable between doing mgmt_set_le(peripheral) and issuing the socket
connect(). So maybe we might need to introduce a mgmt_set_le_connectable
command and a "le-connectable" setting after all (that could only be set
in peripheral mode).

Johan

^ permalink raw reply

* [RFCv1 00/11] Handling physical and logical link
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350493622.26318.114.camel@aeonflux>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Set of patches adding handling for physical and logical link
complete events.

Changes:
	* rfcv1: Rebased on top of Mat's patches, preserve Marcel's ack for
	not-changed-much patches only.
	* rfcv0: original 

Andrei Emeltchenko (11):
  Bluetooth: trivial: Remove unneeded assignment
  Bluetooth: Use helper function sending EFS conf rsp
  Bluetooth: AMP: Process Physical Link Complete evt
  Bluetooth: AMP: Process Logical Link complete evt
  Bluetooth: AMP: Add Logical Link Create function
  Bluetooth: AMP: Process Disc Logical Link
  Bluetooth: AMP: Process Disc Physical Link Complete evt
  Bluetooth: AMP: Remove hci_conn receiving error command status
  Bluetooth: Disconnect logical link when deleteing chan
  Bluetooth: Add put(hcon) when deleting hchan
  Bluetooth: AMP: Check for hs_hcon instead of ctrl_id

 include/net/bluetooth/amp.h   |    3 +
 include/net/bluetooth/l2cap.h |    2 +
 net/bluetooth/amp.c           |   70 ++++++++++++++++
 net/bluetooth/hci_conn.c      |    2 +
 net/bluetooth/hci_event.c     |  177 ++++++++++++++++++++++++++++++++++++++++-
 net/bluetooth/l2cap_core.c    |   41 ++++++----
 6 files changed, 276 insertions(+), 19 deletions(-)

-- 
1.7.9.5


^ permalink raw reply

* [RFCv1 01/11] Bluetooth: trivial: Remove unneeded assignment
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Assignment is not needed here since err is always gets value.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 net/bluetooth/l2cap_core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index fae0c70..962a322 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4386,7 +4386,7 @@ static void l2cap_logical_finish_create(struct l2cap_chan *chan,
 	set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
 
 	if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
-		int err = 0;
+		int err;
 
 		set_default_fcs(chan);
 
-- 
1.7.9.5


^ permalink raw reply related

* [RFCv1 02/11] Bluetooth: Use helper function sending EFS conf rsp
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

There is helper function used to send EFS Configuration Response.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 net/bluetooth/l2cap_core.c |    7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 962a322..600d808 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4374,16 +4374,11 @@ static void l2cap_logical_finish_create(struct l2cap_chan *chan,
 					struct hci_chan *hchan)
 {
 	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);
+	l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
 
 	if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
 		int err;
-- 
1.7.9.5


^ permalink raw reply related

* [RFCv1 03/11] Bluetooth: AMP: Process Physical Link Complete evt
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Add processing for HCI Physical Link Complete event. Upon
successful status received start L2CAP create channel process.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_event.c |   55 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index aae8053..183d8bd 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3637,6 +3637,57 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
+static void hci_phy_link_complete_evt(struct hci_dev *hdev,
+				      struct sk_buff *skb)
+{
+	struct hci_ev_phy_link_complete *ev = (void *) skb->data;
+	struct hci_conn *hcon, *bredr_hcon;
+
+	BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
+	       ev->status);
+
+	hci_dev_lock(hdev);
+
+	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
+	if (!hcon) {
+		hci_dev_unlock(hdev);
+		return;
+	}
+
+	if (ev->status) {
+		hci_conn_del(hcon);
+		hci_dev_unlock(hdev);
+		return;
+	}
+
+	bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
+
+	hcon->state = BT_CONNECTED;
+	bacpy(&hcon->dst, &bredr_hcon->dst);
+
+	hci_conn_hold(hcon);
+	hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
+	hci_conn_put(hcon);
+
+	hci_conn_hold_device(hcon);
+	hci_conn_add_sysfs(hcon);
+
+	hci_dev_unlock(hdev);
+
+	if (hcon->out) {
+		struct hci_dev *bredr_hdev = hci_dev_hold(bredr_hcon->hdev);
+
+		if (!bredr_hdev)
+			return;
+
+		/* Placeholder - create chan req
+		l2cap_chan_create_cfm(bredr_hcon, hcon->remote_id);
+		*/
+
+		hci_dev_put(bredr_hdev);
+	}
+}
+
 static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -3964,6 +4015,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_remote_oob_data_request_evt(hdev, skb);
 		break;
 
+	case HCI_EV_PHY_LINK_COMPLETE:
+		hci_phy_link_complete_evt(hdev, skb);
+		break;
+
 	case HCI_EV_NUM_COMP_BLOCKS:
 		hci_num_comp_blocks_evt(hdev, skb);
 		break;
-- 
1.7.9.5


^ permalink raw reply related

* [RFCv1 04/11] Bluetooth: AMP: Process Logical Link complete evt
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

After receiving HCI Logical Link Complete event finish EFS
configuration by sending L2CAP Conf Response with success code.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 include/net/bluetooth/l2cap.h |    2 ++
 net/bluetooth/hci_event.c     |   42 +++++++++++++++++++++++++++++++++++++++++
 net/bluetooth/l2cap_core.c    |    4 ++--
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 49783e9..24c61ef 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -810,5 +810,7 @@ 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);
+void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
+		       u8 status);
 
 #endif /* __L2CAP_H */
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 183d8bd..00021cb 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3688,6 +3688,44 @@ static void hci_phy_link_complete_evt(struct hci_dev *hdev,
 	}
 }
 
+static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_logical_link_complete *ev = (void *) skb->data;
+	struct hci_conn *hcon;
+	struct hci_chan *hchan;
+	struct amp_mgr *mgr;
+
+	BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
+	       hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
+	       ev->status);
+
+	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
+	if (!hcon)
+		return;
+
+	/* Create AMP hchan */
+	hchan = hci_chan_create(hcon);
+	if (!hchan)
+		return;
+
+	hchan->handle = le16_to_cpu(ev->handle);
+
+	BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
+
+	mgr = hcon->amp_mgr;
+	if (mgr && mgr->bredr_chan) {
+		struct l2cap_chan *bredr_chan = mgr->bredr_chan;
+
+		l2cap_chan_lock(bredr_chan);
+
+		bredr_chan->conn->mtu = hdev->block_mtu;
+		l2cap_logical_cfm(bredr_chan, hchan, 0);
+		hci_conn_hold(hcon);
+
+		l2cap_chan_unlock(bredr_chan);
+	}
+}
+
 static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -4019,6 +4057,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_phy_link_complete_evt(hdev, skb);
 		break;
 
+	case HCI_EV_LOGICAL_LINK_COMPLETE:
+		hci_loglink_complete_evt(hdev, skb);
+		break;
+
 	case HCI_EV_NUM_COMP_BLOCKS:
 		hci_num_comp_blocks_evt(hdev, skb);
 		break;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 600d808..d1728af 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4428,8 +4428,8 @@ static void l2cap_logical_finish_move(struct l2cap_chan *chan,
 }
 
 /* Call with chan locked */
-static void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
-			      u8 status)
+void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
+		       u8 status)
 {
 	BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status);
 
-- 
1.7.9.5


^ permalink raw reply related

* [RFCv1 05/11] Bluetooth: AMP: Add Logical Link Create function
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

After physical link is created logical link needs to be created.
The process starts after L2CAP channel is created and L2CAP
Configuration Response with result PENDING is received.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/amp.h |    1 +
 net/bluetooth/amp.c         |   49 +++++++++++++++++++++++++++++++++++++++++++
 net/bluetooth/hci_event.c   |    9 ++++++++
 net/bluetooth/l2cap_core.c  |   17 +++++++++++----
 4 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index 2e7c79e..70d5c15 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -46,5 +46,6 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
 			struct hci_conn *hcon);
 void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
 void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
+void amp_create_logical_link(struct l2cap_chan *chan);
 
 #endif /* __AMP_H */
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 231d7ef..fbb6360 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -372,3 +372,52 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
 
 	hci_send_cmd(hdev, HCI_OP_ACCEPT_PHY_LINK, sizeof(cp), &cp);
 }
+
+void amp_create_logical_link(struct l2cap_chan *chan)
+{
+	struct hci_cp_create_accept_logical_link cp;
+	struct hci_conn *hcon;
+	struct hci_dev *hdev;
+
+	BT_DBG("chan %p", chan);
+
+	if (!chan->hs_hcon)
+		return;
+
+	hdev = hci_dev_hold(chan->hs_hcon->hdev);
+	if (!hdev)
+		return;
+
+	BT_DBG("chan %p ctrl_id %d dst %pMR", chan, chan->ctrl_id,
+	       chan->conn->dst);
+
+	hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, chan->conn->dst);
+	if (!hcon)
+		goto done;
+
+	cp.phy_handle = hcon->handle;
+
+	cp.tx_flow_spec.id = chan->local_id;
+	cp.tx_flow_spec.stype = chan->local_stype;
+	cp.tx_flow_spec.msdu = cpu_to_le16(chan->local_msdu);
+	cp.tx_flow_spec.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
+	cp.tx_flow_spec.acc_lat = cpu_to_le32(chan->local_acc_lat);
+	cp.tx_flow_spec.flush_to = cpu_to_le32(chan->local_flush_to);
+
+	cp.rx_flow_spec.id = chan->remote_id;
+	cp.rx_flow_spec.stype = chan->remote_stype;
+	cp.rx_flow_spec.msdu = cpu_to_le16(chan->remote_msdu);
+	cp.rx_flow_spec.sdu_itime = cpu_to_le32(chan->remote_sdu_itime);
+	cp.rx_flow_spec.acc_lat = cpu_to_le32(chan->remote_acc_lat);
+	cp.rx_flow_spec.flush_to = cpu_to_le32(chan->remote_flush_to);
+
+	if (hcon->out)
+		hci_send_cmd(hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp),
+			     &cp);
+	else
+		hci_send_cmd(hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp),
+			     &cp);
+
+done:
+	hci_dev_put(hdev);
+}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 00021cb..2c562a7 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1829,6 +1829,11 @@ static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
 	amp_write_remote_assoc(hdev, cp->phy_handle);
 }
 
+static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status)
+{
+	BT_DBG("%s status 0x%2.2x", hdev->name, status);
+}
+
 static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	__u8 status = *((__u8 *) skb->data);
@@ -2663,6 +2668,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_cs_accept_phylink(hdev, ev->status);
 		break;
 
+	case HCI_OP_CREATE_LOGICAL_LINK:
+		hci_cs_create_logical_link(hdev, ev->status);
+		break;
+
 	default:
 		BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
 		break;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d1728af..8e1525f 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -38,6 +38,7 @@
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/smp.h>
 #include <net/bluetooth/a2mp.h>
+#include <net/bluetooth/amp.h>
 
 bool disable_ertm;
 
@@ -1013,6 +1014,12 @@ static bool __amp_capable(struct l2cap_chan *chan)
 		return false;
 }
 
+static bool l2cap_check_efs(struct l2cap_chan *chan)
+{
+	/* Check EFS parameters */
+	return true;
+}
+
 void l2cap_send_conn_req(struct l2cap_chan *chan)
 {
 	struct l2cap_conn *conn = chan->conn;
@@ -3948,13 +3955,15 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
 				goto done;
 			}
 
-			/* check compatibility */
-
 			if (!chan->ctrl_id)
 				l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
 							0);
-			else
-				chan->ident = cmd->ident;
+			else {
+				if (l2cap_check_efs(chan)) {
+					amp_create_logical_link(chan);
+					chan->ident = cmd->ident;
+				}
+			}
 		}
 		goto done;
 
-- 
1.7.9.5


^ permalink raw reply related

* [RFCv1 06/11] Bluetooth: AMP: Process Disc Logical Link
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Add processing for HCI Disconnection Logical Link Complete
Event.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/amp.h |    1 +
 net/bluetooth/amp.c         |    7 +++++++
 net/bluetooth/hci_event.c   |   28 ++++++++++++++++++++++++++++
 3 files changed, 36 insertions(+)

diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index 70d5c15..405fb9c 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -47,5 +47,6 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
 void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
 void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
 void amp_create_logical_link(struct l2cap_chan *chan);
+void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason);
 
 #endif /* __AMP_H */
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index fbb6360..0f3fef3 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -421,3 +421,10 @@ void amp_create_logical_link(struct l2cap_chan *chan)
 done:
 	hci_dev_put(hdev);
 }
+
+void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason)
+{
+	BT_DBG("hchan %p", hchan);
+
+	hci_chan_del(hchan);
+}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 2c562a7..3dae3ac 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3735,6 +3735,30 @@ static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	}
 }
 
+static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
+					     struct sk_buff *skb)
+{
+	struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
+	struct hci_chan *hchan;
+
+	BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
+	       le16_to_cpu(ev->handle), ev->status);
+
+	if (ev->status)
+		return;
+
+	hci_dev_lock(hdev);
+
+	hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
+	if (!hchan)
+		goto unlock;
+
+	amp_destroy_logical_link(hchan, ev->reason);
+
+unlock:
+	hci_dev_unlock(hdev);
+}
+
 static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -4070,6 +4094,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_loglink_complete_evt(hdev, skb);
 		break;
 
+	case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
+		hci_disconn_loglink_complete_evt(hdev, skb);
+		break;
+
 	case HCI_EV_NUM_COMP_BLOCKS:
 		hci_num_comp_blocks_evt(hdev, skb);
 		break;
-- 
1.7.9.5


^ permalink raw reply related

* [RFCv1 07/11] Bluetooth: AMP: Process Disc Physical Link Complete evt
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Add processing for HCI Disconnection Physical Link Complete Event.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_event.c |   26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 3dae3ac..14c5f3f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3759,6 +3759,28 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
+static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
+					     struct sk_buff *skb)
+{
+	struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
+	struct hci_conn *hcon;
+
+	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+
+	if (ev->status)
+		return;
+
+	hci_dev_lock(hdev);
+
+	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
+	if (hcon) {
+		hcon->state = BT_CLOSED;
+		hci_conn_del(hcon);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
 static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -4098,6 +4120,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_disconn_loglink_complete_evt(hdev, skb);
 		break;
 
+	case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
+		hci_disconn_phylink_complete_evt(hdev, skb);
+		break;
+
 	case HCI_EV_NUM_COMP_BLOCKS:
 		hci_num_comp_blocks_evt(hdev, skb);
 		break;
-- 
1.7.9.5


^ permalink raw reply related

* [RFCv1 08/11] Bluetooth: AMP: Remove hci_conn receiving error command status
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

When receiving HCI Event: Command Status for Create Physical Link
with Error code remove AMP hcon.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_event.c |   17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 14c5f3f..827243d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1803,14 +1803,23 @@ static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
-	if (status)
-		return;
-
 	cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
 	if (!cp)
 		return;
 
-	amp_write_remote_assoc(hdev, cp->phy_handle);
+	hci_dev_lock(hdev);
+
+	if (status) {
+		struct hci_conn *hcon;
+
+		hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
+		if (hcon)
+			hci_conn_del(hcon);
+	} else {
+		amp_write_remote_assoc(hdev, cp->phy_handle);
+	}
+
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
-- 
1.7.9.5


^ permalink raw reply related

* [RFCv1 09/11] Bluetooth: Disconnect logical link when deleteing chan
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Disconnect logical link for high speed channel hs_hchan
associated with L2CAP channel chan.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/amp.h |    1 +
 net/bluetooth/amp.c         |   14 ++++++++++++++
 net/bluetooth/l2cap_core.c  |    7 +++++++
 3 files changed, 22 insertions(+)

diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index 405fb9c..f1c0017 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -47,6 +47,7 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
 void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
 void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
 void amp_create_logical_link(struct l2cap_chan *chan);
+void amp_disconnect_logical_link(struct hci_chan *hchan);
 void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason);
 
 #endif /* __AMP_H */
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 0f3fef3..917e034 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -422,6 +422,20 @@ done:
 	hci_dev_put(hdev);
 }
 
+void amp_disconnect_logical_link(struct hci_chan *hchan)
+{
+	struct hci_conn *hcon = hchan->conn;
+	struct hci_cp_disconn_logical_link cp;
+
+	if (hcon->state != BT_CONNECTED) {
+		BT_DBG("hchan %p not connected", hchan);
+		return;
+	}
+
+	cp.log_handle = cpu_to_le16(hchan->handle);
+	hci_send_cmd(hcon->hdev, HCI_OP_DISCONN_LOGICAL_LINK, sizeof(cp), &cp);
+}
+
 void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason)
 {
 	BT_DBG("hchan %p", hchan);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 8e1525f..e46fd56 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -578,6 +578,13 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
 			mgr->bredr_chan = NULL;
 	}
 
+	if (chan->hs_hchan) {
+		struct hci_chan *hs_hchan = chan->hs_hchan;
+
+		BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan);
+		amp_disconnect_logical_link(hs_hchan);
+	}
+
 	chan->ops->teardown(chan, err);
 
 	if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
-- 
1.7.9.5


^ permalink raw reply related

* [RFCv1 10/11] Bluetooth: Add put(hcon) when deleting hchan
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

When refcnt reaches zero disconnect timeout will run and hci_conn
will be disconnected.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 net/bluetooth/hci_conn.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index dc331ce..25bfce0 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -980,6 +980,8 @@ void hci_chan_del(struct hci_chan *chan)
 
 	synchronize_rcu();
 
+	hci_conn_put(conn);
+
 	skb_queue_purge(&chan->data_q);
 	kfree(chan);
 }
-- 
1.7.9.5


^ permalink raw reply related

* [RFCv1 11/11] Bluetooth: AMP: Check for hs_hcon instead of ctrl_id
From: Andrei Emeltchenko @ 2012-10-25 12:20 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1351167652-12346-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

When deciding whether to send EFS configuration response with success,
check rather for existence of High Speed physical link hs_hcon then
ctrl_id. There might be cases when there is ctrl_id but high speed link
is not established yet.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 net/bluetooth/l2cap_core.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e46fd56..ac44365 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3912,7 +3912,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
 		/* check compatibility */
 
 		/* Send rsp for BR/EDR channel */
-		if (!chan->ctrl_id)
+		if (!chan->hs_hcon)
 			l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
 		else
 			chan->ident = cmd->ident;
@@ -3962,7 +3962,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
 				goto done;
 			}
 
-			if (!chan->ctrl_id)
+			if (!chan->hs_hcon)
 				l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
 							0);
 			else {
-- 
1.7.9.5


^ permalink raw reply related

* Re: [RFCv1 01/11] Bluetooth: trivial: Remove unneeded assignment
From: Marcel Holtmann @ 2012-10-25 13:06 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1351167652-12346-2-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

> Assignment is not needed here since err is always gets value.
> 
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
>  net/bluetooth/l2cap_core.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

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

Regards

Marcel



^ permalink raw reply

* Re: [RFCv1 02/11] Bluetooth: Use helper function sending EFS conf rsp
From: Marcel Holtmann @ 2012-10-25 13:07 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1351167652-12346-3-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

> There is helper function used to send EFS Configuration Response.
> 
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
>  net/bluetooth/l2cap_core.c |    7 +------
>  1 file changed, 1 insertion(+), 6 deletions(-)

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

Regards

Marcel



^ permalink raw reply


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