Linux bluetooth development
 help / color / mirror / Atom feed
* Re: Next BlueZ developer meeting
From: Marcel Holtmann @ 2010-08-07  5:12 UTC (permalink / raw)
  To: Ron Shaffer; +Cc: linux-bluetooth
In-Reply-To: <4C5C8A7A.8060301@codeaurora.org>

Hi Ron,

> Can you send out the event specifics - times and meeting places?

the event details will be provided by the LinuxCon when you register on
Sunday morning. The registration will start at 8am along with the
continental breakfast. And we have our room from 9am - 6pm. I assume it
will be Aegean room on the Ballroom level, but we will see when we get
there.

Since we start on a Sunday, we can take it certainly easy and start
around 10am. So no rush ;)

Regards

Marcel



^ permalink raw reply

* Re: Question about BlueZ licenses (LGPL and Apache)
From: Marcel Holtmann @ 2010-08-07  5:07 UTC (permalink / raw)
  To: Madhavi Manchala; +Cc: linux-bluetooth
In-Reply-To: <AANLkTimiBsL60-8w4MPoP=g8Fo_+U-SrSBTa9--aqEK4@mail.gmail.com>

Hi Madhavi,

> I am trying to implement a custom voice codec on the android bluetooth
> platform by linking it, into the A2DP module. I have heard different
> versions from different people regarding the licenses (like LGPL and
> Apache License). So, before starting my work, I would like to know if
> I would be forced to reveal my source code, once I implement my codec
> on BlueZ stack. Please let me know, so that I can choose my platform,
> before starting my work.

BlueZ (bluetoothd and libbluetooth) is licensed under GPL 2.0 license
and nothing else. It is pretty clear in the COPYING file. There are a
few source code files licensed under LGPL, but after linking the end
result is still GPL. If in doubt ask your lawyer since nobody here on
the mailing list can give you official legal advise.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: Johan Hedberg @ 2010-08-07  3:10 UTC (permalink / raw)
  To: Inga Stotland; +Cc: linux-bluetooth, marcel, rshaffer
In-Reply-To: <1281119724-28882-1-git-send-email-ingas@codeaurora.org>

Hi Inga,

On Fri, Aug 06, 2010, Inga Stotland wrote:
> If service UUIDs are present in EIR, they are written to
> "device properties" dictionary  when emitting "Device Found" signal.
> This allows peek at available services offered by a remote device
> without establishing SDP connection.
> ---
>  src/adapter.c  |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  src/adapter.h  |    4 +-
>  src/dbus-hci.c |    6 ++--
>  3 files changed, 110 insertions(+), 8 deletions(-)

The patch is now upstream. Thanks!

Johan

^ permalink raw reply

* Re: Next BlueZ developer meeting
From: Ron Shaffer @ 2010-08-06 22:19 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1278555742.10421.11.camel@localhost.localdomain>

On 7/7/2010 9:22 PM, Marcel Holtmann wrote:
> Hello once more,
> 
>>> our next BlueZ developer meeting will be held as mini-summit as part of
>>> the LinuxCon in Boston.
>>>
>>> 	http://events.linuxfoundation.org/events/linuxcon/mini-summits
>>>
>>> I like to invite interested developers to join us in Boston. The summit
>>> will be held on Sunday, 8th and Monday, 9th of July.
>>
>> I obviously meant 8th and 9th of August. Sorry for the confusion.
> 
> I just got reminded that the registration fee for LinuxCon increases on
> July, 15th. So if you already know that you are attending you might
> wanna register sooner than later. The link is here:
> 
> http://events.linuxfoundation.org/component/registrationpro/?func=details&did=27
> 
> Regards
> 
> Marcel
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

Can you send out the event specifics - times and meeting places?

Thanks,

-- 
Ron Shaffer
Employee of the Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply

* [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: Inga Stotland @ 2010-08-06 18:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, marcel, rshaffer, Inga Stotland
In-Reply-To: <20100806173042.GA28198@jh-x301>

If service UUIDs are present in EIR, they are written to
"device properties" dictionary  when emitting "Device Found" signal.
This allows peek at available services offered by a remote device
without establishing SDP connection.
---
 src/adapter.c  |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/adapter.h  |    4 +-
 src/dbus-hci.c |    6 ++--
 3 files changed, 110 insertions(+), 8 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index c142a4a..5746cbc 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2749,8 +2749,102 @@ static void emit_device_found(const char *path, const char *address,
 	g_dbus_send_message(connection, signal);
 }
 
+static char **get_eir_uuids(uint8_t *eir_data, size_t *uuid_count)
+{
+	uint16_t len = 0;
+	char **uuids;
+	size_t total;
+	size_t uuid16_count = 0;
+	size_t uuid32_count = 0;
+	size_t uuid128_count = 0;
+	uint8_t *uuid16;
+	uint8_t *uuid32;
+	uint8_t *uuid128;
+	uuid_t service;
+	unsigned int i;
+
+	while (len < EIR_DATA_LENGTH - 1) {
+		uint8_t type = eir_data[1];
+		uint8_t field_len = eir_data[0];
+
+		/* Check for the end of EIR */
+		if (field_len == 0)
+			break;
+
+		switch (type) {
+		case EIR_UUID16_SOME:
+		case EIR_UUID16_ALL:
+			uuid16_count = field_len / 2;
+			uuid16 = &eir_data[2];
+			break;
+		case EIR_UUID32_SOME:
+		case EIR_UUID32_ALL:
+			uuid32_count = field_len / 4;
+			uuid32 = &eir_data[2];
+			break;
+		case EIR_UUID128_SOME:
+		case EIR_UUID128_ALL:
+			uuid128_count = field_len / 16;
+			uuid128 = &eir_data[2];
+			break;
+		}
+
+		len += field_len + 1;
+		eir_data += field_len + 1;
+	}
+
+	/* Bail out if got incorrect length */
+	if (len > EIR_DATA_LENGTH)
+		return NULL;
+
+	total = uuid16_count + uuid32_count + uuid128_count;
+	*uuid_count = total;
+
+	if (!total)
+		return NULL;
+
+	uuids = g_new0(char *, total + 1);
+
+	/* Generate uuids in SDP format (EIR data is Little Endian) */
+	service.type = SDP_UUID16;
+	for (i = 0; i < uuid16_count; i++) {
+		uint16_t val16 = uuid16[1];
+
+		val16 = (val16 << 8) + uuid16[0];
+		service.value.uuid16 = val16;
+		uuids[i] = bt_uuid2string(&service);
+		uuid16 += 2;
+	}
+
+	service.type = SDP_UUID32;
+	for (i = uuid16_count; i < uuid32_count + uuid16_count; i++) {
+		uint32_t val32 = uuid32[3];
+		int k;
+
+		for (k = 2; k >= 0; k--)
+			val32 = (val32 << 8) + uuid32[k];
+
+		service.value.uuid32 = val32;
+		uuids[i] = bt_uuid2string(&service);
+		uuid32 += 4;
+	}
+
+	service.type = SDP_UUID128;
+	for (i = uuid32_count + uuid16_count; i < total; i++) {
+		int k;
+
+		for (k = 0; k < 16; k++)
+			service.value.uuid128.data[k] = uuid128[16 - k - 1];
+
+		uuids[i] = bt_uuid2string(&service);
+		uuid128 += 16;
+	}
+
+	return uuids;
+}
+
 void adapter_emit_device_found(struct btd_adapter *adapter,
-				struct remote_dev_info *dev)
+				struct remote_dev_info *dev, uint8_t *eir_data)
 {
 	struct btd_device *device;
 	char peer_addr[18], local_addr[18];
@@ -2758,6 +2852,8 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
 	dbus_bool_t paired = FALSE;
 	dbus_int16_t rssi = dev->rssi;
 	char *alias;
+	char **uuids = NULL;
+	size_t uuid_count = 0;
 
 	ba2str(&dev->bdaddr, peer_addr);
 	ba2str(&adapter->bdaddr, local_addr);
@@ -2777,6 +2873,10 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
 	} else
 		alias = g_strdup(dev->alias);
 
+	/* Extract UUIDs from extended inquiry response if any*/
+	if (eir_data != NULL)
+		uuids = get_eir_uuids(eir_data, &uuid_count);
+
 	emit_device_found(adapter->path, paddr,
 			"Address", DBUS_TYPE_STRING, &paddr,
 			"Class", DBUS_TYPE_UINT32, &dev->class,
@@ -2786,15 +2886,17 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
 			"Alias", DBUS_TYPE_STRING, &alias,
 			"LegacyPairing", DBUS_TYPE_BOOLEAN, &dev->legacy,
 			"Paired", DBUS_TYPE_BOOLEAN, &paired,
+			"UUIDs", DBUS_TYPE_ARRAY, &uuids, uuid_count,
 			NULL);
 
 	g_free(alias);
+	g_strfreev(uuids);
 }
 
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 				int8_t rssi, uint32_t class, const char *name,
 				const char *alias, gboolean legacy,
-				name_status_t name_status)
+				name_status_t name_status, uint8_t *eir_data)
 {
 	struct remote_dev_info *dev, match;
 
@@ -2833,7 +2935,7 @@ done:
 	adapter->found_devices = g_slist_sort(adapter->found_devices,
 						(GCompareFunc) dev_rssi_cmp);
 
-	adapter_emit_device_found(adapter, dev);
+	adapter_emit_device_found(adapter, dev, eir_data);
 }
 
 int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr)
diff --git a/src/adapter.h b/src/adapter.h
index 8226514..a7eca0e 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -113,10 +113,10 @@ struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 				int8_t rssi, uint32_t class, const char *name,
 				const char *alias, gboolean legacy,
-				name_status_t name_status);
+				name_status_t name_status, uint8_t *eir_data);
 int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr);
 void adapter_emit_device_found(struct btd_adapter *adapter,
-				struct remote_dev_info *dev);
+				struct remote_dev_info *dev, uint8_t *eir_data);
 void adapter_update_oor_devices(struct btd_adapter *adapter);
 void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode);
 void adapter_setname_complete(bdaddr_t *local, uint8_t status);
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index b83506f..6d27caa 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -515,7 +515,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 	if (dev) {
 		adapter_update_found_devices(adapter, peer, rssi, class,
 						NULL, NULL, dev->legacy,
-						NAME_NOT_REQUIRED);
+						NAME_NOT_REQUIRED, data);
 		return;
 	}
 
@@ -566,7 +566,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 
 	/* add in the list to track name sent/pending */
 	adapter_update_found_devices(adapter, peer, rssi, class, name, alias,
-					legacy, name_status);
+					legacy, name_status, data);
 
 	g_free(name);
 	g_free(alias);
@@ -642,7 +642,7 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,
 	if (dev_info) {
 		g_free(dev_info->name);
 		dev_info->name = g_strdup(name);
-		adapter_emit_device_found(adapter, dev_info);
+		adapter_emit_device_found(adapter, dev_info, NULL);
 	}
 
 	if (device)
-- 
1.7.2

-- 
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* Re: [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: ingas @ 2010-08-06 18:18 UTC (permalink / raw)
  To: johan.hedberg; +Cc: linux-bluetooth
In-Reply-To: <20100806173042.GA28198@jh-x301>

>
> There's still however one issue (I only now tried to compile the patch):
>
> src/adapter.c: In function ‘get_eir_uuids’:
> src/adapter.c:2810: error: comparison between signed and unsigned integer
> expressions
> src/adapter.c:2820: error: comparison between signed and unsigned integer
> expressions
> src/adapter.c:2833: error: comparison between signed and unsigned integer
> expressions
> make[1]: *** [src/adapter.o] Error 1
>
> Could you please fix it and always in the future ensure that the code
> compiles cleanly when configured with ./bootstrap-configure. Also, could
> you make the commit message more descriptive. The summary line should be
> a very short summary of what the patch is about and the more detailed
> description should be in the message body.
>

Oops, sorry about that: I was using bootstrap and configure as separate
scripts. Apparently the warning level is not set high enough in there.
Will fix and resubmit.

Regards,

Inga




^ permalink raw reply

* Re: [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: Johan Hedberg @ 2010-08-06 17:30 UTC (permalink / raw)
  To: ingas; +Cc: linux-bluetooth, rshaffer
In-Reply-To: <1844054b1cfff4c91e67223013eb09ac.squirrel@www.codeaurora.org>

Hi Inga,

On Fri, Aug 06, 2010, ingas@codeaurora.org wrote:
> > On Thu, Aug 05, 2010, Inga Stotland wrote:
> >> +	while (len < EIR_DATA_LENGTH - 1) {
> >> +		uint8_t type = eir_data[1];
> >> +		uint8_t field_len = eir_data[0];
> >> +
> >> +		/* Check for the end of EIR */
> >> +		if (field_len == 0)
> >> +			break;
> >
> > Shouldn't there also be another check here:
> >
> > 		/* Bail out if field_len claims to reach beyond the EIR
> > 		 * data end */
> > 		if (len + field_len + 1 >= EIR_DATA_LENGTH)
> > 			break;
> >
> 
> After reading in eir_data[0] & eir_data[1] (and those reads are valid due
> to passing the "while (len < EIR_DATA_LENGTH - 1)" check above) there are
> no more memory accesses in the loop. And if we do end up reading in field
> length that's bogus, we fail the "while" check on next iteration, exit the
> loop, fail the "(len > EIR_DATA_LENGTH)" and bail out of the routine with
> NULL return value.

Yep, you're right. What got me unnerved was that you still set pointers
to potentially out-of-bounds data in the switch statement, but as you
say the if check after the switch statement ensures that the pointers
don't get accessed if something went beyond the EIR data length.

There's still however one issue (I only now tried to compile the patch):

src/adapter.c: In function ‘get_eir_uuids’:
src/adapter.c:2810: error: comparison between signed and unsigned integer expressions
src/adapter.c:2820: error: comparison between signed and unsigned integer expressions
src/adapter.c:2833: error: comparison between signed and unsigned integer expressions
make[1]: *** [src/adapter.o] Error 1

Could you please fix it and always in the future ensure that the code
compiles cleanly when configured with ./bootstrap-configure. Also, could
you make the commit message more descriptive. The summary line should be
a very short summary of what the patch is about and the more detailed
description should be in the message body.

Johan

^ permalink raw reply

* Re: [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: ingas @ 2010-08-06 16:16 UTC (permalink / raw)
  To: johan.hedberg; +Cc: linux-bluetooth, rshaffer
In-Reply-To: <20100806075552.GA22150@jh-x301>

Hi Johan,

> Hi Inga,
>
> On Thu, Aug 05, 2010, Inga Stotland wrote:
>> +	while (len < EIR_DATA_LENGTH - 1) {
>> +		uint8_t type = eir_data[1];
>> +		uint8_t field_len = eir_data[0];
>> +
>> +		/* Check for the end of EIR */
>> +		if (field_len == 0)
>> +			break;
>
> Shouldn't there also be another check here:
>
> 		/* Bail out if field_len claims to reach beyond the EIR
> 		 * data end */
> 		if (len + field_len + 1 >= EIR_DATA_LENGTH)
> 			break;
>

After reading in eir_data[0] & eir_data[1] (and those reads are valid due
to passing the "while (len < EIR_DATA_LENGTH - 1)" check above) there are
no more memory accesses in the loop. And if we do end up reading in field
length that's bogus, we fail the "while" check on next iteration, exit the
loop, fail the "(len > EIR_DATA_LENGTH)" and bail out of the routine with
NULL return value.

Actually, I originally had the check for field length inside the loop, but
then moved it outside for efficiency reasons.

Thanks,

Inga


--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


>



^ permalink raw reply

* Question about BlueZ licenses (LGPL and Apache)
From: Madhavi Manchala @ 2010-08-06 15:44 UTC (permalink / raw)
  To: linux-bluetooth

Dear All,

I am trying to implement a custom voice codec on the android bluetooth
platform by linking it, into the A2DP module. I have heard different
versions from different people regarding the licenses (like LGPL and
Apache License). So, before starting my work, I would like to know if
I would be forced to reveal my source code, once I implement my codec
on BlueZ stack. Please let me know, so that I can choose my platform,
before starting my work.

Regards,
Madhavi.

^ permalink raw reply

* [PATCH] add mailing list as bug report address to configure.ac
From: Uwe Kleine-König @ 2010-08-06 14:20 UTC (permalink / raw)
  To: linux-bluetooth

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 configure.ac |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/configure.ac b/configure.ac
index b004f6e..2804d29 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 AC_PREREQ(2.60)
-AC_INIT(bluez, 4.69)
+AC_INIT(bluez, 4.69, [linux-bluetooth@vger.kernel.org])
 
 AM_INIT_AUTOMAKE([foreign subdir-objects])
 AM_CONFIG_HEADER(config.h)
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/2] add three missing api documents to EXTRA_DIST
From: Uwe Kleine-König @ 2010-08-06 14:18 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1281104283-8792-1-git-send-email-u.kleine-koenig@pengutronix.de>

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
Hello,

there are still a few files in bluez.git/doc that are not listed in EXTRA_DIST:

 - bluez-docs.xml
 - gtk-doc.make
 - version.xml.in

I didn't know if I should add these, too, so I just point that out.

Best regards
Uwe

 Makefile.am |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 4bb82fe..7007026 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -316,9 +316,12 @@ EXTRA_DIST += \
 	      doc/audio-api.txt \
 	      doc/control-api.txt \
 	      doc/device-api.txt \
+	      doc/health-api.txt \
+	      doc/hfp-api.txt \
 	      doc/input-api.txt \
 	      doc/manager-api.txt \
 	      doc/network-api.txt \
+	      doc/node-api.txt \
 	      doc/serial-api.txt \
 	      doc/service-api.txt \
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/2] list api docs alphabetically and one per line in EXTRA_DIST
From: Uwe Kleine-König @ 2010-08-06 14:18 UTC (permalink / raw)
  To: linux-bluetooth

This makes further changes to the list easier to review

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 Makefile.am |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 65d4312..4bb82fe 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -309,11 +309,18 @@ udevdir = $(libexecdir)/udev
 dist_udev_SCRIPTS = scripts/bluetooth_serial
 endif
 
-EXTRA_DIST += doc/manager-api.txt \
-		doc/adapter-api.txt doc/device-api.txt \
-		doc/service-api.txt doc/agent-api.txt doc/attribute-api.txt \
-		doc/serial-api.txt doc/network-api.txt \
-		doc/input-api.txt doc/audio-api.txt doc/control-api.txt
+EXTRA_DIST += \
+	      doc/adapter-api.txt \
+	      doc/agent-api.txt \
+	      doc/attribute-api.txt \
+	      doc/audio-api.txt \
+	      doc/control-api.txt \
+	      doc/device-api.txt \
+	      doc/input-api.txt \
+	      doc/manager-api.txt \
+	      doc/network-api.txt \
+	      doc/serial-api.txt \
+	      doc/service-api.txt \
 
 AM_YFLAGS = -d
 
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: Johan Hedberg @ 2010-08-06  7:58 UTC (permalink / raw)
  To: Inga Stotland, linux-bluetooth, marcel, rshaffer
In-Reply-To: <20100806075552.GA22150@jh-x301>

Hi,

On Fri, Aug 06, 2010, Johan Hedberg wrote:
> 		/* Bail out if field_len claims to reach beyond the EIR
> 		 * data end */
> 		if (len + field_len + 1 >= EIR_DATA_LENGTH)
> 			break;

Sorry, that should actually be > and not >= since it's fine if the end
of the field coincides with the end of EIR data.

Johan

^ permalink raw reply

* Re: [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: Johan Hedberg @ 2010-08-06  7:55 UTC (permalink / raw)
  To: Inga Stotland; +Cc: linux-bluetooth, marcel, rshaffer
In-Reply-To: <1281047801-4044-1-git-send-email-ingas@codeaurora.org>

Hi Inga,

On Thu, Aug 05, 2010, Inga Stotland wrote:
> +	while (len < EIR_DATA_LENGTH - 1) {
> +		uint8_t type = eir_data[1];
> +		uint8_t field_len = eir_data[0];
> +
> +		/* Check for the end of EIR */
> +		if (field_len == 0)
> +			break;

Shouldn't there also be another check here:

		/* Bail out if field_len claims to reach beyond the EIR
		 * data end */
		if (len + field_len + 1 >= EIR_DATA_LENGTH)
			break;

Johan

^ permalink raw reply

* [PATCH 9/9] Bluetooth: Use 3-DH5 payload size for default ERTM max PDU size.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>

The previous value of 672 for L2CAP_DEFAULT_MAX_PDU_SIZE is based on
the default L2CAP MTU.  That default MTU is calculated from the size
of two DH5 packets, minus ACL and L2CAP b-frame header overhead.

ERTM is used with newer basebands that typically support larger 3-DH5
packets, and i-frames and s-frames have more header overhead.  With
clean RF conditions, basebands will typically attempt to use 1021-byte
3-DH5 packets for maximum throughput.  Adjusting for 2 bytes of ACL
headers plus 10 bytes of worst-case L2CAP headers yields 1009 bytes
of payload.

This PDU size imposes less overhead for header bytes and gives the
baseband the option to choose 3-DH5 packets, but is small enough for
ERTM traffic to interleave well with other L2CAP or SCO data.
672-byte payloads do not allow the most efficient over-the-air
packet choice, and cannot achieve maximum throughput over BR/EDR.

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
 include/net/bluetooth/l2cap.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 16e412f..6c24144 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -35,7 +35,7 @@
 #define L2CAP_DEFAULT_MAX_TX		3
 #define L2CAP_DEFAULT_RETRANS_TO	2000    /* 2 seconds */
 #define L2CAP_DEFAULT_MONITOR_TO	12000   /* 12 seconds */
-#define L2CAP_DEFAULT_MAX_PDU_SIZE	672
+#define L2CAP_DEFAULT_MAX_PDU_SIZE	1009    /* Sized for 3-DH5 packet */
 #define L2CAP_DEFAULT_ACK_TO		200
 #define L2CAP_LOCAL_BUSY_TRIES		12
 
-- 
1.7.1

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply related

* [PATCH 8/9] Bluetooth: Use a stream-oriented recvmsg with SOCK_STREAM L2CAP sockets.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>

L2CAP ERTM sockets can be opened with the SOCK_STREAM socket type,
which is a mandatory request for ERTM mode.

However, these sockets still have SOCK_SEQPACKET read semantics when
bt_sock_recvmsg() is used to pull data from the receive queue.  If the
application is only reading part of a frame, then the unread portion
of the frame is discarded.  If the application requests more bytes
than are in the current frame, only the current frame's data is
returned.

This patch utilizes common code derived from RFCOMM's recvmsg()
function to make L2CAP SOCK_STREAM reads behave like RFCOMM reads (and
other SOCK_STREAM sockets in general).  The application may read one
byte at a time from the input stream and not lose any data, and may
also read across L2CAP frame boundaries.

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
 net/bluetooth/l2cap.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 43e0eae..cd0e150 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1956,7 +1956,10 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
 
 	release_sock(sk);
 
-	return bt_sock_recvmsg(iocb, sock, msg, len, flags);
+	if (sock->type == SOCK_STREAM)
+		return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
+	else
+		return bt_sock_recvmsg(iocb, sock, msg, len, flags);
 }
 
 static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
-- 
1.7.1

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply related

* [PATCH 7/9] Bluetooth: Use common SOCK_STREAM receive code in RFCOMM.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>

To reduce code duplication, have rfcomm_sock_recvmsg() call
bt_sock_stream_recvmsg().  The common bt_sock_stream_recvmsg()
code is nearly identical, with the RFCOMM-specific functionality
for deferred setup and connection unthrottling left in
rfcomm_sock_recvmsg().

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
 net/bluetooth/rfcomm/sock.c |  104 +++----------------------------------------
 1 files changed, 6 insertions(+), 98 deletions(-)

diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 44a6232..4396f47 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -617,121 +617,29 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 	return sent;
 }
 
-static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
-{
-	DECLARE_WAITQUEUE(wait, current);
-
-	add_wait_queue(sk_sleep(sk), &wait);
-	for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
-
-		if (!skb_queue_empty(&sk->sk_receive_queue) ||
-		    sk->sk_err ||
-		    (sk->sk_shutdown & RCV_SHUTDOWN) ||
-		    signal_pending(current) ||
-		    !timeo)
-			break;
-
-		set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
-		release_sock(sk);
-		timeo = schedule_timeout(timeo);
-		lock_sock(sk);
-		clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
-	}
-
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk_sleep(sk), &wait);
-	return timeo;
-}
-
 static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 			       struct msghdr *msg, size_t size, int flags)
 {
 	struct sock *sk = sock->sk;
 	struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-	int err = 0;
-	size_t target, copied = 0;
-	long timeo;
+	int len;
 
 	if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
 		rfcomm_dlc_accept(d);
 		return 0;
 	}
 
-	if (flags & MSG_OOB)
-		return -EOPNOTSUPP;
-
-	msg->msg_namelen = 0;
-
-	BT_DBG("sk %p size %zu", sk, size);
+	len = bt_sock_stream_recvmsg(iocb, sock, msg, size, flags);
 
 	lock_sock(sk);
+	if (!(flags & MSG_PEEK) && len > 0)
+		atomic_sub(len, &sk->sk_rmem_alloc);
 
-	target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
-	timeo  = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-
-	do {
-		struct sk_buff *skb;
-		int chunk;
-
-		skb = skb_dequeue(&sk->sk_receive_queue);
-		if (!skb) {
-			if (copied >= target)
-				break;
-
-			if ((err = sock_error(sk)) != 0)
-				break;
-			if (sk->sk_shutdown & RCV_SHUTDOWN)
-				break;
-
-			err = -EAGAIN;
-			if (!timeo)
-				break;
-
-			timeo = rfcomm_sock_data_wait(sk, timeo);
-
-			if (signal_pending(current)) {
-				err = sock_intr_errno(timeo);
-				goto out;
-			}
-			continue;
-		}
-
-		chunk = min_t(unsigned int, skb->len, size);
-		if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
-			skb_queue_head(&sk->sk_receive_queue, skb);
-			if (!copied)
-				copied = -EFAULT;
-			break;
-		}
-		copied += chunk;
-		size   -= chunk;
-
-		sock_recv_ts_and_drops(msg, sk, skb);
-
-		if (!(flags & MSG_PEEK)) {
-			atomic_sub(chunk, &sk->sk_rmem_alloc);
-
-			skb_pull(skb, chunk);
-			if (skb->len) {
-				skb_queue_head(&sk->sk_receive_queue, skb);
-				break;
-			}
-			kfree_skb(skb);
-
-		} else {
-			/* put message back and return */
-			skb_queue_head(&sk->sk_receive_queue, skb);
-			break;
-		}
-	} while (size);
-
-out:
 	if (atomic_read(&sk->sk_rmem_alloc) <= (sk->sk_rcvbuf >> 2))
 		rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
-
 	release_sock(sk);
-	return copied ? : err;
+
+	return len;
 }
 
 static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
-- 
1.7.1

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply related

* [PATCH 6/9] Bluetooth: Add common code for stream-oriented recvmsg()
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>

This commit adds a bt_sock_stream_recvmsg() function for use by any
Bluetooth code that uses SOCK_STREAM sockets.  This code is copied
from rfcomm_sock_recvmsg() with minimal modifications to remove
RFCOMM-specific functionality and improve readability.

L2CAP (with the SOCK_STREAM socket type) and RFCOMM have common needs
when it comes to reading data.  Proper stream read semantics require
that applications can read from a stream one byte at a time and not
lose any data.  The RFCOMM code already operated on and pulled data
from the underlying L2CAP socket, so very few changes were required to
make the code more generic for use with non-RFCOMM data over L2CAP.

Applications that need more awareness of L2CAP frame boundaries are
still free to use SOCK_SEQPACKET sockets, and may verify that they
connection did not fall back to basic mode by calling getsockopt().

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
 include/net/bluetooth/bluetooth.h |    2 +
 net/bluetooth/af_bluetooth.c      |  109 +++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 27a902d..08b6c2a 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -126,6 +126,8 @@ int  bt_sock_unregister(int proto);
 void bt_sock_link(struct bt_sock_list *l, struct sock *s);
 void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
 int  bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags);
+int  bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+			struct msghdr *msg, size_t len, int flags);
 uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
 int  bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 int  bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 421c45b..77a26fe 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -265,6 +265,115 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 }
 EXPORT_SYMBOL(bt_sock_recvmsg);
 
+static long bt_sock_data_wait(struct sock *sk, long timeo)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	add_wait_queue(sk_sleep(sk), &wait);
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (!skb_queue_empty(&sk->sk_receive_queue))
+			break;
+
+		if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
+			break;
+
+		if (signal_pending(current) || !timeo)
+			break;
+
+		set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+		release_sock(sk);
+		timeo = schedule_timeout(timeo);
+		lock_sock(sk);
+		clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+	}
+
+	__set_current_state(TASK_RUNNING);
+	remove_wait_queue(sk_sleep(sk), &wait);
+	return timeo;
+}
+
+int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+			       struct msghdr *msg, size_t size, int flags)
+{
+	struct sock *sk = sock->sk;
+	int err = 0;
+	size_t target, copied = 0;
+	long timeo;
+
+	if (flags & MSG_OOB)
+		return -EOPNOTSUPP;
+
+	msg->msg_namelen = 0;
+
+	BT_DBG("sk %p size %zu", sk, size);
+
+	lock_sock(sk);
+
+	target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
+	timeo  = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+
+	do {
+		struct sk_buff *skb;
+		int chunk;
+
+		skb = skb_dequeue(&sk->sk_receive_queue);
+		if (!skb) {
+			if (copied >= target)
+				break;
+
+			if ((err = sock_error(sk)) != 0)
+				break;
+			if (sk->sk_shutdown & RCV_SHUTDOWN)
+				break;
+
+			err = -EAGAIN;
+			if (!timeo)
+				break;
+
+			timeo = bt_sock_data_wait(sk, timeo);
+
+			if (signal_pending(current)) {
+				err = sock_intr_errno(timeo);
+				goto out;
+			}
+			continue;
+		}
+
+		chunk = min_t(unsigned int, skb->len, size);
+		if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+			skb_queue_head(&sk->sk_receive_queue, skb);
+			if (!copied)
+				copied = -EFAULT;
+			break;
+		}
+		copied += chunk;
+		size   -= chunk;
+
+		sock_recv_ts_and_drops(msg, sk, skb);
+
+		if (!(flags & MSG_PEEK)) {
+			skb_pull(skb, chunk);
+			if (skb->len) {
+				skb_queue_head(&sk->sk_receive_queue, skb);
+				break;
+			}
+			kfree_skb(skb);
+
+		} else {
+			/* put message back and return */
+			skb_queue_head(&sk->sk_receive_queue, skb);
+			break;
+		}
+	} while (size);
+
+out:
+	release_sock(sk);
+	return copied ? : err;
+}
+EXPORT_SYMBOL(bt_sock_stream_recvmsg);
+
 static inline unsigned int bt_accept_poll(struct sock *parent)
 {
 	struct list_head *p, *n;
-- 
1.7.1

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply related

* [PATCH 5/9] Bluetooth: Fix incorrect setting of remote_tx_win for L2CAP ERTM.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>

remote_tx_win is intended to be set on receipt of an L2CAP
configuration request.  The value is used to determine the size of the
transmit window on the remote side of an ERTM connection, so L2CAP
can stop sending frames when that remote window is full.

An incorrect remote_tx_win value will cause the stack to not fully
utilize the tx window (performance impact), or to overfill the remote
tx window (causing dropped frames or a disconnect).

This patch removes an extra setting of remote_tx_win when a
configuration response is received.  The transmit window has a
different meaning in a response - it is an informational value
less than or equal to the local tx_win.

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
 net/bluetooth/l2cap.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 5541b56..43e0eae 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2819,7 +2819,6 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
 	if (*result == L2CAP_CONF_SUCCESS) {
 		switch (rfc.mode) {
 		case L2CAP_MODE_ERTM:
-			pi->remote_tx_win   = rfc.txwin_size;
 			pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
 			pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
 			pi->mps    = le16_to_cpu(rfc.max_pdu_size);
@@ -2875,7 +2874,6 @@ static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len)
 done:
 	switch (rfc.mode) {
 	case L2CAP_MODE_ERTM:
-		pi->remote_tx_win   = rfc.txwin_size;
 		pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
 		pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
 		pi->mps    = le16_to_cpu(rfc.max_pdu_size);
-- 
1.7.1

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply related

* [PATCH 4/9] Bluetooth: Fix endianness issue with L2CAP MPS configuration.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>

Incoming configuration values must be converted to native CPU order
before use.  This fixes a bug where a little-endian MPS value is
compared to a native CPU value.  On big-endian processors, this
can cause ERTM and streaming mode segmentation to produce PDUs
that are larger than the remote stack is expecting, or that would
produce fragmented skbs that the current FCS code cannot handle.

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
 net/bluetooth/l2cap.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 77ba106..5541b56 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2717,8 +2717,9 @@ done:
 		case L2CAP_MODE_ERTM:
 			pi->remote_tx_win = rfc.txwin_size;
 			pi->remote_max_tx = rfc.max_transmit;
-			if (rfc.max_pdu_size > pi->conn->mtu - 10)
-				rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
+
+			if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
+				rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
 
 			pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
 
@@ -2735,8 +2736,8 @@ done:
 			break;
 
 		case L2CAP_MODE_STREAMING:
-			if (rfc.max_pdu_size > pi->conn->mtu - 10)
-				rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
+			if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
+				rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
 
 			pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
 
-- 
1.7.1

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply related

* [PATCH 3/9] Bluetooth: Validate PSM values in calls to connect() and bind().
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>

Valid L2CAP PSMs are odd numbers, and the least significant bit of the
most significant byte must be 0.

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
 net/bluetooth/l2cap.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index bc10be8..77ba106 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1008,6 +1008,12 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
 		goto done;
 	}
 
+	/* If specified, PSM must be odd and lsb of upper byte must be 0 */
+	if (la.l2_psm && (__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001) {
+		err = -EINVAL;
+		goto done;
+	}
+
 	if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
 				!capable(CAP_NET_BIND_SERVICE)) {
 		err = -EACCES;
@@ -1190,6 +1196,12 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
 		goto done;
 	}
 
+	/* PSM must be odd and lsb of upper byte must be 0 */
+	if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001) {
+		err = -EINVAL;
+		goto done;
+	}
+
 	/* Set destination address and psm */
 	bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
 	l2cap_pi(sk)->psm = la.l2_psm;
-- 
1.7.1

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply related

* [PATCH 2/9] Bluetooth: Change default ERTM retransmit timeout.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>

The L2CAP spec requires that the ERTM retransmit timeout be at least 2
seconds for BR/EDR connections.

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
 include/net/bluetooth/l2cap.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 636724b..16e412f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -33,7 +33,7 @@
 #define L2CAP_DEFAULT_FLUSH_TO		0xffff
 #define L2CAP_DEFAULT_TX_WINDOW		63
 #define L2CAP_DEFAULT_MAX_TX		3
-#define L2CAP_DEFAULT_RETRANS_TO	1000    /* 1 second */
+#define L2CAP_DEFAULT_RETRANS_TO	2000    /* 2 seconds */
 #define L2CAP_DEFAULT_MONITOR_TO	12000   /* 12 seconds */
 #define L2CAP_DEFAULT_MAX_PDU_SIZE	672
 #define L2CAP_DEFAULT_ACK_TO		200
-- 
1.7.1

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply related

* [PATCH 1/9] Bluetooth: Only enable for L2CAP FCS for ERTM or streaming.
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1281048867-32630-1-git-send-email-mathewm@codeaurora.org>

This fixes a bug which caused the FCS setting to show L2CAP_FCS_CRC16
with L2CAP modes other than ERTM or streaming.  At present, this only
affects the FCS value shown with getsockopt() for basic mode.

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
 net/bluetooth/l2cap.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 3e3cd9d..bc10be8 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -3072,6 +3072,16 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
 	return 0;
 }
 
+static inline int l2cap_fcs_needed(struct l2cap_pinfo *pi)
+{
+	if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
+		return 0;
+
+	/* FCS is enabled if one or both sides request it. */
+	return !(pi->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
+		pi->fcs == L2CAP_FCS_CRC16;
+}
+
 static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
 {
 	struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
@@ -3136,8 +3146,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 		goto unlock;
 
 	if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
-		if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
-		    l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
+		if (l2cap_fcs_needed(l2cap_pi(sk)))
 			l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
 
 		sk->sk_state = BT_CONNECTED;
@@ -3226,8 +3235,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 	l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
 
 	if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
-		if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
-		    l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
+		if (l2cap_fcs_needed(l2cap_pi(sk)))
 			l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
 
 		sk->sk_state = BT_CONNECTED;
-- 
1.7.1

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply related

* [PATCH v3 0/9] Bluetooth: L2CAP updates for PSM validation and ERTM
From: Mat Martineau @ 2010-08-05 22:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm

This is a collection of ERTM-related patches, including some L2CAP
configuration fixes and allowing partial-frame reads from L2CAP
SOCK_STREAM sockets.  PSM validation is also included, although that
is not restricted to ERTM.

--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum



^ permalink raw reply

* [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: Inga Stotland @ 2010-08-05 22:36 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, marcel, rshaffer, Inga Stotland
In-Reply-To: <20100805102513.GA7221@jh-x301>

---
 src/adapter.c  |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/adapter.h  |    4 +-
 src/dbus-hci.c |    6 ++--
 3 files changed, 110 insertions(+), 8 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index c142a4a..b2b5be8 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2749,8 +2749,102 @@ static void emit_device_found(const char *path, const char *address,
 	g_dbus_send_message(connection, signal);
 }
 
+static char **get_eir_uuids(uint8_t *eir_data, size_t *uuid_count)
+{
+	uint16_t len = 0;
+	char **uuids;
+	size_t total;
+	size_t uuid16_count = 0;
+	size_t uuid32_count = 0;
+	size_t uuid128_count = 0;
+	uint8_t *uuid16;
+	uint8_t *uuid32;
+	uint8_t *uuid128;
+	uuid_t service;
+	int i;
+
+	while (len < EIR_DATA_LENGTH - 1) {
+		uint8_t type = eir_data[1];
+		uint8_t field_len = eir_data[0];
+
+		/* Check for the end of EIR */
+		if (field_len == 0)
+			break;
+
+		switch (type) {
+		case EIR_UUID16_SOME:
+		case EIR_UUID16_ALL:
+			uuid16_count = field_len / 2;
+			uuid16 = &eir_data[2];
+			break;
+		case EIR_UUID32_SOME:
+		case EIR_UUID32_ALL:
+			uuid32_count = field_len / 4;
+			uuid32 = &eir_data[2];
+			break;
+		case EIR_UUID128_SOME:
+		case EIR_UUID128_ALL:
+			uuid128_count = field_len / 16;
+			uuid128 = &eir_data[2];
+			break;
+		}
+
+		len += field_len + 1;
+		eir_data += field_len + 1;
+	}
+
+	/* Bail out if got incorrect length */
+	if (len > EIR_DATA_LENGTH)
+		return NULL;
+
+	total = uuid16_count + uuid32_count + uuid128_count;
+	*uuid_count = total;
+
+	if (!total)
+		return NULL;
+
+	uuids = g_new0(char *, total + 1);
+
+	/* Generate uuids in SDP format (EIR data is Little Endian) */
+	service.type = SDP_UUID16;
+	for (i = 0; i < uuid16_count; i++) {
+		uint16_t val16 = uuid16[1];
+
+		val16 = (val16 << 8) + uuid16[0];
+		service.value.uuid16 = val16;
+		uuids[i] = bt_uuid2string(&service);
+		uuid16 += 2;
+	}
+
+	service.type = SDP_UUID32;
+	for (i = uuid16_count; i < uuid32_count + uuid16_count; i++) {
+		uint32_t val32 = uuid32[3];
+		int k;
+
+		for (k = 2; k >= 0; k--)
+			val32 = (val32 << 8) + uuid32[k];
+
+		service.value.uuid32 = val32;
+		uuids[i] = bt_uuid2string(&service);
+		uuid32 += 4;
+	}
+
+	service.type = SDP_UUID128;
+	for (i = uuid32_count + uuid16_count; i < total; i++) {
+		int k;
+
+		for (k = 0; k < 16; k++)
+			service.value.uuid128.data[k] = uuid128[16 - k - 1];
+
+		uuids[i] = bt_uuid2string(&service);
+		uuid128 += 16;
+	}
+
+	return uuids;
+}
+
 void adapter_emit_device_found(struct btd_adapter *adapter,
-				struct remote_dev_info *dev)
+				struct remote_dev_info *dev, uint8_t *eir_data)
 {
 	struct btd_device *device;
 	char peer_addr[18], local_addr[18];
@@ -2758,6 +2852,8 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
 	dbus_bool_t paired = FALSE;
 	dbus_int16_t rssi = dev->rssi;
 	char *alias;
+	char **uuids = NULL;
+	size_t uuid_count = 0;
 
 	ba2str(&dev->bdaddr, peer_addr);
 	ba2str(&adapter->bdaddr, local_addr);
@@ -2777,6 +2873,10 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
 	} else
 		alias = g_strdup(dev->alias);
 
+	/* Extract UUIDs from extended inquiry response if any*/
+	if (eir_data != NULL)
+		uuids = get_eir_uuids(eir_data, &uuid_count);
+
 	emit_device_found(adapter->path, paddr,
 			"Address", DBUS_TYPE_STRING, &paddr,
 			"Class", DBUS_TYPE_UINT32, &dev->class,
@@ -2786,15 +2886,17 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
 			"Alias", DBUS_TYPE_STRING, &alias,
 			"LegacyPairing", DBUS_TYPE_BOOLEAN, &dev->legacy,
 			"Paired", DBUS_TYPE_BOOLEAN, &paired,
+			"UUIDs", DBUS_TYPE_ARRAY, &uuids, uuid_count,
 			NULL);
 
 	g_free(alias);
+	g_strfreev(uuids);
 }
 
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 				int8_t rssi, uint32_t class, const char *name,
 				const char *alias, gboolean legacy,
-				name_status_t name_status)
+				name_status_t name_status, uint8_t *eir_data)
 {
 	struct remote_dev_info *dev, match;
 
@@ -2833,7 +2935,7 @@ done:
 	adapter->found_devices = g_slist_sort(adapter->found_devices,
 						(GCompareFunc) dev_rssi_cmp);
 
-	adapter_emit_device_found(adapter, dev);
+	adapter_emit_device_found(adapter, dev, eir_data);
 }
 
 int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr)
diff --git a/src/adapter.h b/src/adapter.h
index 8226514..a7eca0e 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -113,10 +113,10 @@ struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter
 void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 				int8_t rssi, uint32_t class, const char *name,
 				const char *alias, gboolean legacy,
-				name_status_t name_status);
+				name_status_t name_status, uint8_t *eir_data);
 int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr);
 void adapter_emit_device_found(struct btd_adapter *adapter,
-				struct remote_dev_info *dev);
+				struct remote_dev_info *dev, uint8_t *eir_data);
 void adapter_update_oor_devices(struct btd_adapter *adapter);
 void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode);
 void adapter_setname_complete(bdaddr_t *local, uint8_t status);
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index b83506f..6d27caa 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -515,7 +515,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 	if (dev) {
 		adapter_update_found_devices(adapter, peer, rssi, class,
 						NULL, NULL, dev->legacy,
-						NAME_NOT_REQUIRED);
+						NAME_NOT_REQUIRED, data);
 		return;
 	}
 
@@ -566,7 +566,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
 
 	/* add in the list to track name sent/pending */
 	adapter_update_found_devices(adapter, peer, rssi, class, name, alias,
-					legacy, name_status);
+					legacy, name_status, data);
 
 	g_free(name);
 	g_free(alias);
@@ -642,7 +642,7 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,
 	if (dev_info) {
 		g_free(dev_info->name);
 		dev_info->name = g_strdup(name);
-		adapter_emit_device_found(adapter, dev_info);
+		adapter_emit_device_found(adapter, dev_info, NULL);
 	}
 
 	if (device)
-- 
1.7.2

-- 
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ 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