Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH 0/2] sco: BT_DEFER_SETUP for SCO sockets
From: Frédéric Dalleau @ 2012-11-20 10:39 UTC (permalink / raw)
  To: Gustavo Padovan, linux-bluetooth
In-Reply-To: <20121119201958.GA14006@joana>

Hi Gustavo,

On 11/19/2012 09:19 PM, Gustavo Padovan wrote:
> Hi Frédéric,
>
> * Frédéric Dalleau <frederic.dalleau@linux.intel.com> [2012-11-19 17:35:55 +0100]:
>> Regarding testing, I'm still stuck by a txt timeout issue however, if the
>> delay between accept and recv is set to 0, then the connection is working fine.
>> And I even managed to get the sco connection established correctly once. So I
>> believed this emulator problem.
>
> You are telling me that your patch is not really working, I suggest you call
> this series RFC before you get everything sorted out. The approach in general
> is good, but I'd need confirmation that it works for actual defer delays, 3
> seconds for example, and not 0.

Sorry, I have been a bit premature, but for the reason explained
above I was confident.
So now I'm quite happy to say I successfully tested this series this 
morning, based on bluetooth-next, using delays from 0 to 35 secs several 
times in a row.

Regards,
Frédéric

^ permalink raw reply

* [PATCH v2] Bluetooth: Remove OOB data if device was discovered in band
From: Szymon Janc @ 2012-11-20 10:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

OOB authentication mechanism should be used only if pairing process
has been activated by previous OOB information exchange (Core Spec
4.0 , vol. 1, Part A, 5.1.4.3). Stored OOB data for specific device
should be removed if that device was discovered in band later on.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
V2:
Move OOB data removal to hci_inquiry_cache_update to cover all inquiry
events (ext/rssi) in one place.

 net/bluetooth/hci_core.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e3a49db..81f4bac 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -434,6 +434,8 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
 
 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
 
+	hci_remove_remote_oob_data(hdev, &data->bdaddr);
+
 	if (ssp)
 		*ssp = data->ssp_mode;
 
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH 1/4] neard: Use ENONET error when adapter is not enabled
From: Johan Hedberg @ 2012-11-20 10:25 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1353337438-21865-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Mon, Nov 19, 2012, Szymon Janc wrote:
> This results in returning error 'Disabled' instead of 'No such Device'.
> Will allow neard to properly set power state of Bluetooth carrier.
> ---
>  plugins/neard.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

All four patches have been applied after some minor coding style fixes
in patches 3 and 4. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 0/2] Add support for SCO defered setup in test
From: Johan Hedberg @ 2012-11-20 10:22 UTC (permalink / raw)
  To: Frédéric Dalleau; +Cc: linux-bluetooth
In-Reply-To: <1353340244-16443-1-git-send-email-frederic.dalleau@linux.intel.com>

Hi Frederic,

On Mon, Nov 19, 2012, Frédéric Dalleau wrote:
> This adds support for deferred setup in userspace test tools for SCO
> connections.
> 
> Regards,
> Frédéric
> 
> Frédéric Dalleau (2):
>   scotest: Add deferred setup option
>   btiotest: Enable deferred setup for sco sockets
> 
>  test/btiotest.c |   22 +++++++++++++++-----
>  test/scotest.c  |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
>  2 files changed, 72 insertions(+), 10 deletions(-)

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ] audio: Auto connect AVRCP in case of A2DP source is connected
From: Johan Hedberg @ 2012-11-20  9:23 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1353402781-21791-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Tue, Nov 20, 2012, Luiz Augusto von Dentz wrote:
> This enables the same logic used for A2DP sink, so it attempt to
> connect AVRCP if remote device support it.
> 
> Note this is necessary for some devices e.g. WP7 that don't connect
> even when being the initiator because it is not mandatory for target
> to do so even though it is recommended to avoid collisions while trying
> to estabilish the connection.
> ---
>  profiles/audio/device.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ] audio: Auto connect AVRCP in case of A2DP source is connected
From: Luiz Augusto von Dentz @ 2012-11-20  9:13 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This enables the same logic used for A2DP sink, so it attempt to
connect AVRCP if remote device support it.

Note this is necessary for some devices e.g. WP7 that don't connect
even when being the initiator because it is not mandatory for target
to do so even though it is recommended to avoid collisions while trying
to estabilish the connection.
---
 profiles/audio/device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/profiles/audio/device.c b/profiles/audio/device.c
index df57d81..5176a60 100644
--- a/profiles/audio/device.c
+++ b/profiles/audio/device.c
@@ -269,7 +269,7 @@ static void device_avdtp_cb(struct audio_device *dev, struct avdtp *session,
 				avdtp_session_state_t new_state,
 				void *user_data)
 {
-	if (!dev->sink || !dev->control)
+	if (!dev->control)
 		return;
 
 	if (new_state == AVDTP_SESSION_STATE_CONNECTED) {
-- 
1.7.11.7


^ permalink raw reply related

* Re: [PATCH] bluetooth: Increase HCI command tx timeout
From: Gustavo Padovan @ 2012-11-19 21:57 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1352714465-17015-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

* Szymon Janc <szymon.janc@tieto.com> [2012-11-12 11:01:05 +0100]:

> Read Local OOB Data command can take more than 1 second on some chips.
> e.g. on CSR 0a12:0001 first call to Read Local OOB Data after reset
> takes about 1300ms resulting in tx timeout error.
> 
> [27698.368655] Bluetooth: hci0 command 0x0c57 tx timeout
> 
> 2012-10-31 15:53:36.178585 < HCI Command: Read Local OOB Data (0x03|0x0057) plen 0
> 2012-10-31 15:53:37.496996 > HCI Event: Command Complete (0x0e) plen 36
>     Read Local OOB Data (0x03|0x0057) ncmd 1
>     status 0x00
>     hash 0x92219d9b447f2aa9dc12dda2ae7bae6a
>     randomizer 0xb1948d0febe4ea38ce85c4e66313beba
> 
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
> 
> Spec doesn't seem to be posing any restrictions on how fast should HCI response...
> I've increased timeout to 2 secs as this seems to fix this for me, but maybe this
> could be increased to something more, like 5 secs or sth to minimize tx timeout
> chance for other slow chips?  If chip doesn't response for command it is FUBAR
> anyway and having longer timeout would not make things that much worse (and
> could even improve things on slow chips..).
> 
> 
>  include/net/bluetooth/hci.h |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

This patch is now on bluetooth-next. Thanks. Moreover there was never a real
reason to have the timeout with a 1 second value, it just proved to be enough
at the time we added the timeout mechanism for hci commands.

	Gustavo

^ permalink raw reply

* Re: [PATCHv2] Bluetooth: Add support for BCM20702A0 [0b05, 17b5]
From: Gustavo Padovan @ 2012-11-19 21:41 UTC (permalink / raw)
  To: Jeff Cook; +Cc: linux-bluetooth, marcel, johan.hedberg, linux-kernel
In-Reply-To: <1352504388-28965-1-git-send-email-jeff@deserettechnology.com>

Hi Jeff,

* Jeff Cook <jeff@deserettechnology.com> [2012-11-09 16:39:48 -0700]:

> Vendor-specific ID for BCM20702A0.
> Support for bluetooth over Asus Wi-Fi GO!, included with Asus P8Z77-V
> Deluxe.
> 
> T:  Bus=07 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=  3 Spd=12  MxCh= 0
> D:  Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
> P:  Vendor=0b05 ProdID=17b5 Rev=01.12
> S:  Manufacturer=Broadcom Corp
> S:  Product=BCM20702A0
> S:  SerialNumber=94DBC98AC113
> C:  #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA
> I:  If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
> I:  If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
> I:  If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
> I:  If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)
> 
> Signed-off-by: Jeff Cook <jeff@deserettechnology.com>
> ---
>  drivers/bluetooth/btusb.c | 1 +
>  1 file changed, 1 insertion(+)

Patch has been applied to bluetooth-next. Thanks.

	Gustavo

^ permalink raw reply

* Re: [RFCv1 3/3] Bluetooth: trivial: Use __constant for constants
From: Gustavo Padovan @ 2012-11-19 21:36 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1352907572-7113-3-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

* Andrei Emeltchenko <Andrei.Emeltchenko.news@gmail.com> [2012-11-14 17:39:32 +0200]:

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

All 3 patches have been applied to bluetooth-next. Thanks.

	Gustavo

^ permalink raw reply

* Re: [PATCH 3/3] sdp: Upgrade datatype SEQ8 to SEQ16 when data size is greater than 256
From: Bart Westgeest @ 2012-11-19 21:33 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <CAJdJm_N1hJkdEqvOrgD8ErAzDT56wzPEYAiA+7KDR0Pah4P6sA@mail.gmail.com>

Hi Anderson,

>> +recalculate:
>> +       pdu_size = sdp_get_data_type_size(d->dtd);
>>          buf->data_size += pdu_size;
>>
>>          data_size = sdp_get_data_size(buf, d);
>> +       if (data_size > UCHAR_MAX && d->dtd == SDP_SEQ8) {
>> +               buf->data_size = orig_data_size;
>> +               d->dtd = SDP_SEQ16;
>> +               goto recalculate;
>
> IMHO, using "goto" here is too complicated for 3 lines of code that
> will just be run at most twice. So I would simply duplicate them
> inside the if(). But others may have different opinion on this regard.

I don't have strong feelings about this. I can change it.

One could argue that the way I did it shows that the *same* code needs 
to be executed again. (It the same code can also be moved into a 
do-while) - this, as well what I have currently, would allow for a data 
upgrade to SDP_SEQ16 -> SDP_SEQ32, and SDP_ALT8 -> SDP_ALT16-> SDP_ALT32 
as well, which theoretically are also needed as far as I can tell.

For the record, in any regard, I think the fix is rather ugly, goto 
statement or not. This problem is now 'fixed' in two places (the other 
one in sdp_append_to_buf, with the corresponding data length increase in 
sdp_gen_buffer). IMHO, the code requires a bigger cleanup. I actually 
made an attempt at it, but the fix got too big, and I opted for what I 
submitted instead.

To get back on topic, let me know if you or others want me to re-submit.

Bart

^ permalink raw reply

* Re: [RFC 4/4] Bluetooth: Set local_amp_id after getting Phylink Completed evt
From: Gustavo Padovan @ 2012-11-19 21:28 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1352996096-27374-4-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

* Andrei Emeltchenko <Andrei.Emeltchenko.news@gmail.com> [2012-11-15 18:14:56 +0200]:

> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> local_amp_id is used in l2cap_physical_cfm and shall be set up
> before calling it.
> 
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
>  net/bluetooth/amp.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
> index eb61aaa..ac9e8fe 100644
> --- a/net/bluetooth/amp.c
> +++ b/net/bluetooth/amp.c
> @@ -392,6 +392,7 @@ void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon)
>  
>  	set_bit(FLAG_EFS_ENABLE, &bredr_chan->flags);
>  	bredr_chan->remote_amp_id = hs_hcon->remote_id;
> +	bredr_chan->local_amp_id = hs_hcon->hdev->id;
>  	bredr_chan->hs_hcon = hs_hcon;
>  	bredr_chan->conn->mtu = hs_hcon->hdev->block_mtu;

I was able to apply patches 1 and 3 to bluetooth-next. The other 2 doesn't
apply for some reason, please rebase. Thanks.

	Gustavo

^ permalink raw reply

* Re: [PATCH 2/3] sdp: Limit side effects of sdp_get_data_type and sdp_get_data_size
From: Bart Westgeest @ 2012-11-19 21:06 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <CAJdJm_MSAw2EWV=Tp-ycdfhUi1wJdcdXdH+4YAdfGx1LRpWs-g@mail.gmail.com>

Hi Anderson,

>> -       sdp_get_data_type(buf, d->dtd);
>> -       sdp_get_data_size(buf, d);
>> +       buf->buf_size += sdp_get_data_type_size(d->dtd);
>> +       buf->buf_size += sdp_get_data_size(buf, d);
>
> No need to check for "if (!buf->data)" like in the original code?

I do not think there's a need for it, this modification is in 
sdp_gen_buffer. sdp_gen_buffer is called three times from the following 
functions: (1) sdp_attr_size, (2) sdp_append_to_pdu, and (3) 
gen_dataseq_pdu.

For (2) & (3), buf is memset to 0 prior to calling sdp_gen_buffer, thus 
buf->data is always NULL.

For (1), buf is also memset to 0 for the first call to sdp_attr_size, 
which is called repetitively in a foreach statement. Repetitive calls to 
sdp_gen_buffer on the same buffer will not (ever) result in an 
allocation of buf->data as far as I can tell.

>> -       pdu_size = sdp_get_data_type(buf, dtd);
>> +       pdu_size = sdp_get_data_type_size(dtd);
>
> Same here. Additionally, buf->buf_size is not being updated.

This modification is in sdp_gen_pdu. sdp_gen_pdu is never called with 
buf->data == NULL. If it would, then the initialization of seqp in 
sdp_gen_pdu is erroneous, since it uses buf->data without verifying it.

In addition, in the current code, sdp_gen_pdu is only called from three 
locations: (1) get_data_size, (2) sdp_append_to_pdu, (3) 
gen_dataseq_pdu. In all cases the buf->data is either allocated prior to 
calling (2 & 3), or (1) there's an if statement preventing sdp_gen_pdu 
from being called when buf->data == NULL.

Bart

^ permalink raw reply

* Re: [PATCH 3/3] sdp: Upgrade datatype SEQ8 to SEQ16 when data size is greater than 256
From: Anderson Lizardo @ 2012-11-19 20:38 UTC (permalink / raw)
  To: Bart Westgeest; +Cc: linux-bluetooth
In-Reply-To: <1353351872-10628-4-git-send-email-bart@elbrys.com>

Hi Bart,

On Mon, Nov 19, 2012 at 3:04 PM, Bart Westgeest <bart@elbrys.com> wrote:
> Fixes a bug where the complete sequence data is written, but the size
> is truncated to one byte.
> ---
>  lib/sdp.c |   18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/lib/sdp.c b/lib/sdp.c
> index 026163e..ceb1192 100644
> --- a/lib/sdp.c
> +++ b/lib/sdp.c
> @@ -786,23 +786,29 @@ static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d)
>
>  int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
>  {
> -       uint32_t pdu_size = 0, data_size = 0;
> +       uint32_t pdu_size, data_size;
>         unsigned char *src = NULL, is_seq = 0, is_alt = 0;
> -       uint8_t dtd = d->dtd;
>         uint16_t u16;
>         uint32_t u32;
>         uint64_t u64;
>         uint128_t u128;
>         uint8_t *seqp = buf->data + buf->data_size;
> +       uint32_t orig_data_size = buf->data_size;
>
> -       pdu_size = sdp_get_data_type_size(dtd);
> +recalculate:
> +       pdu_size = sdp_get_data_type_size(d->dtd);
>         buf->data_size += pdu_size;
>
>         data_size = sdp_get_data_size(buf, d);
> +       if (data_size > UCHAR_MAX && d->dtd == SDP_SEQ8) {
> +               buf->data_size = orig_data_size;
> +               d->dtd = SDP_SEQ16;
> +               goto recalculate;

IMHO, using "goto" here is too complicated for 3 lines of code that
will just be run at most twice. So I would simply duplicate them
inside the if(). But others may have different opinion on this regard.

> +       }
>
> -       *seqp = dtd;
> +       *seqp = d->dtd;
>
> -       switch (dtd) {
> +       switch (d->dtd) {
>         case SDP_DATA_NIL:
>                 break;
>         case SDP_UINT8:

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

^ permalink raw reply

* Re: [PATCH 2/3] sdp: Limit side effects of sdp_get_data_type and sdp_get_data_size
From: Anderson Lizardo @ 2012-11-19 20:24 UTC (permalink / raw)
  To: Bart Westgeest; +Cc: linux-bluetooth
In-Reply-To: <1353351872-10628-3-git-send-email-bart@elbrys.com>

Hi Bart,

On Mon, Nov 19, 2012 at 3:04 PM, Bart Westgeest <bart@elbrys.com> wrote:
> @@ -762,9 +757,6 @@ static int sdp_get_data_size(sdp_buf_t *buf, sdp_data_t *d)
>                 break;
>         }
>
> -       if (!buf->data)
> -               buf->buf_size += data_size;
> -
>         return data_size;
>  }
>
> @@ -783,8 +775,8 @@ static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d)
>         /* attribute length */
>         buf->buf_size += sizeof(uint8_t) + sizeof(uint16_t);
>
> -       sdp_get_data_type(buf, d->dtd);
> -       sdp_get_data_size(buf, d);
> +       buf->buf_size += sdp_get_data_type_size(d->dtd);
> +       buf->buf_size += sdp_get_data_size(buf, d);

No need to check for "if (!buf->data)" like in the original code?

>
>         if (buf->buf_size > UCHAR_MAX && d->dtd == SDP_SEQ8)
>                 buf->buf_size += sizeof(uint8_t);
> @@ -803,7 +795,7 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
>         uint128_t u128;
>         uint8_t *seqp = buf->data + buf->data_size;
>
> -       pdu_size = sdp_get_data_type(buf, dtd);
> +       pdu_size = sdp_get_data_type_size(dtd);

Same here. Additionally, buf->buf_size is not being updated.

>         buf->data_size += pdu_size;
>
>         data_size = sdp_get_data_size(buf, d);

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

^ permalink raw reply

* Re: [PATCH 0/2] sco: BT_DEFER_SETUP for SCO sockets
From: Gustavo Padovan @ 2012-11-19 20:19 UTC (permalink / raw)
  To: Frédéric Dalleau; +Cc: linux-bluetooth
In-Reply-To: <1353342958-25303-1-git-send-email-frederic.dalleau@linux.intel.com>

Hi Frédéric,

* Frédéric Dalleau <frederic.dalleau@linux.intel.com> [2012-11-19 17:35:55 +0100]:

> Hi,
> 
> This is a better view about what can be done to implement DEFER_SETUP on SCO
> sockets. hci layer get some changes since previous behavior was to accept all
> SCO connections.
> The ugly hci_proto_defer has been removed and replaced by an additional flag
> parameter to hci_proto_connect_ind.
> Regarding testing, I'm still stuck by a txt timeout issue however, if the
> delay between accept and recv is set to 0, then the connection is working fine.
> And I even managed to get the sco connection established correctly once. So I
> believed this emulator problem.

You are telling me that your patch is not really working, I suggest you call
this series RFC before you get everything sorted out. The approach in general
is good, but I'd need confirmation that it works for actual defer delays, 3
seconds for example, and not 0.

	Gustavo

^ permalink raw reply

* [PATCH 3/3] sdp: Upgrade datatype SEQ8 to SEQ16 when data size is greater than 256
From: Bart Westgeest @ 2012-11-19 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bart Westgeest
In-Reply-To: <1353351872-10628-1-git-send-email-bart@elbrys.com>

Fixes a bug where the complete sequence data is written, but the size
is truncated to one byte.
---
 lib/sdp.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index 026163e..ceb1192 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -786,23 +786,29 @@ static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d)
 
 int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
 {
-	uint32_t pdu_size = 0, data_size = 0;
+	uint32_t pdu_size, data_size;
 	unsigned char *src = NULL, is_seq = 0, is_alt = 0;
-	uint8_t dtd = d->dtd;
 	uint16_t u16;
 	uint32_t u32;
 	uint64_t u64;
 	uint128_t u128;
 	uint8_t *seqp = buf->data + buf->data_size;
+	uint32_t orig_data_size = buf->data_size;
 
-	pdu_size = sdp_get_data_type_size(dtd);
+recalculate:
+	pdu_size = sdp_get_data_type_size(d->dtd);
 	buf->data_size += pdu_size;
 
 	data_size = sdp_get_data_size(buf, d);
+	if (data_size > UCHAR_MAX && d->dtd == SDP_SEQ8) {
+		buf->data_size = orig_data_size;
+		d->dtd = SDP_SEQ16;
+		goto recalculate;
+	}
 
-	*seqp = dtd;
+	*seqp = d->dtd;
 
-	switch (dtd) {
+	switch (d->dtd) {
 	case SDP_DATA_NIL:
 		break;
 	case SDP_UINT8:
@@ -884,7 +890,7 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
 		if (src && buf->buf_size >= buf->data_size + data_size) {
 			memcpy(buf->data + buf->data_size, src, data_size);
 			buf->data_size += data_size;
-		} else if (dtd != SDP_DATA_NIL) {
+		} else if (d->dtd != SDP_DATA_NIL) {
 			SDPDBG("Gen PDU : Can't copy from invalid source or dest\n");
 		}
 	}
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/3] sdp: Limit side effects of sdp_get_data_type and sdp_get_data_size
From: Bart Westgeest @ 2012-11-19 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bart Westgeest
In-Reply-To: <1353351872-10628-1-git-send-email-bart@elbrys.com>

Remove modification of buf->buf_size in 'get' functions. Data is
still indirectly modified due to recursive nature of code.

Renamed sdp_get_data_type to sdp_get_data_type_size.
---
 lib/sdp.c |   26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index dba3f59..026163e 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -633,37 +633,32 @@ void sdp_set_seq_len(uint8_t *ptr, uint32_t length)
 	}
 }
 
-static int sdp_get_data_type(sdp_buf_t *buf, uint8_t dtd)
+static int sdp_get_data_type_size(uint8_t dtd)
 {
-	int data_type = 0;
-
-	data_type += sizeof(uint8_t);
+	int size = sizeof(uint8_t);
 
 	switch (dtd) {
 	case SDP_SEQ8:
 	case SDP_TEXT_STR8:
 	case SDP_URL_STR8:
 	case SDP_ALT8:
-		data_type += sizeof(uint8_t);
+		size += sizeof(uint8_t);
 		break;
 	case SDP_SEQ16:
 	case SDP_TEXT_STR16:
 	case SDP_URL_STR16:
 	case SDP_ALT16:
-		data_type += sizeof(uint16_t);
+		size += sizeof(uint16_t);
 		break;
 	case SDP_SEQ32:
 	case SDP_TEXT_STR32:
 	case SDP_URL_STR32:
 	case SDP_ALT32:
-		data_type += sizeof(uint32_t);
+		size += sizeof(uint32_t);
 		break;
 	}
 
-	if (!buf->data)
-		buf->buf_size += data_type;
-
-	return data_type;
+	return size;
 }
 
 void sdp_set_attrid(sdp_buf_t *buf, uint16_t attr)
@@ -762,9 +757,6 @@ static int sdp_get_data_size(sdp_buf_t *buf, sdp_data_t *d)
 		break;
 	}
 
-	if (!buf->data)
-		buf->buf_size += data_size;
-
 	return data_size;
 }
 
@@ -783,8 +775,8 @@ static int sdp_gen_buffer(sdp_buf_t *buf, sdp_data_t *d)
 	/* attribute length */
 	buf->buf_size += sizeof(uint8_t) + sizeof(uint16_t);
 
-	sdp_get_data_type(buf, d->dtd);
-	sdp_get_data_size(buf, d);
+	buf->buf_size += sdp_get_data_type_size(d->dtd);
+	buf->buf_size += sdp_get_data_size(buf, d);
 
 	if (buf->buf_size > UCHAR_MAX && d->dtd == SDP_SEQ8)
 		buf->buf_size += sizeof(uint8_t);
@@ -803,7 +795,7 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
 	uint128_t u128;
 	uint8_t *seqp = buf->data + buf->data_size;
 
-	pdu_size = sdp_get_data_type(buf, dtd);
+	pdu_size = sdp_get_data_type_size(dtd);
 	buf->data_size += pdu_size;
 
 	data_size = sdp_get_data_size(buf, d);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 1/3] sdp: Inlined single use of function sdp_set_data_type
From: Bart Westgeest @ 2012-11-19 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bart Westgeest
In-Reply-To: <1353351872-10628-1-git-send-email-bart@elbrys.com>

Inlining single use of sdp_set_data_type to improve code readability,
since the function was doing more than just setting the data type.
---
 lib/sdp.c |   18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index 1a5bf01..dba3f59 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -666,18 +666,6 @@ static int sdp_get_data_type(sdp_buf_t *buf, uint8_t dtd)
 	return data_type;
 }
 
-static int sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd)
-{
-	int data_type = 0;
-	uint8_t *p = buf->data + buf->data_size;
-
-	*p = dtd;
-	data_type = sdp_get_data_type(buf, dtd);
-	buf->data_size += data_type;
-
-	return data_type;
-}
-
 void sdp_set_attrid(sdp_buf_t *buf, uint16_t attr)
 {
 	uint8_t *p = buf->data;
@@ -815,9 +803,13 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d)
 	uint128_t u128;
 	uint8_t *seqp = buf->data + buf->data_size;
 
-	pdu_size = sdp_set_data_type(buf, dtd);
+	pdu_size = sdp_get_data_type(buf, dtd);
+	buf->data_size += pdu_size;
+
 	data_size = sdp_get_data_size(buf, d);
 
+	*seqp = dtd;
+
 	switch (dtd) {
 	case SDP_DATA_NIL:
 		break;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 0/3] Fix corrupted SDP response for sequence size > 256
From: Bart Westgeest @ 2012-11-19 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bart Westgeest

This patchset includes minor refactoring and a bug fix. The bug
is exposed when a data sequence grows beyond 256 bytes, in this case the
complete sequence data is written, but the size is truncated to one
byte, resulting in a corrupted SDP response.

RE: Feedback on potential fix for issue while advertising Feature List

Bart Westgeest (3):
  sdp: Inlined single use of function sdp_set_data_type
  sdp: Limit side effects of sdp_get_data_type and sdp_get_data_size
  sdp: Upgrade datatype SEQ8 to SEQ16 when data size is greater than
    256

 lib/sdp.c |   56 +++++++++++++++++++++++---------------------------------
 1 file changed, 23 insertions(+), 33 deletions(-)

-- 
1.7.10.4


^ permalink raw reply

* Re: [PATCH 1/5] adapter: Remove not needed variable from btd_adapter_get_mode
From: Johan Hedberg @ 2012-11-19 18:32 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1353337366-21590-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Mon, Nov 19, 2012, Szymon Janc wrote:
> address is no longer used and can be removed.
> ---
>  src/adapter.c |    4 ----
>  1 file changed, 4 deletions(-)

All five patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH 2/2] Bluetooth: Implement deferred sco socket setup
From: Frédéric Dalleau @ 2012-11-19 16:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1353342958-25303-1-git-send-email-frederic.dalleau@linux.intel.com>

In order to authenticate and configure an incoming SCO connection, the
BT_DEFER_SETUP option was added. This option is intended to defer reply
to Connect Request on SCO sockets.
When a connection is requested, the listening socket is unblocked but
the effective connection setup happens only on first recv. Any send
between accept and recv fails with -ENOTCONN.
---
 include/net/bluetooth/hci_core.h |    9 ++++---
 net/bluetooth/hci_event.c        |   53 +++++++++++++++++++++++++++++++++++---
 net/bluetooth/sco.c              |   35 ++++++++++++++++++++++---
 3 files changed, 87 insertions(+), 10 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ef5b85d..8fceb35 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -376,7 +376,7 @@ extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt);
 extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb,
 			      u16 flags);
 
-extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
+extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags);
 extern void sco_connect_cfm(struct hci_conn *hcon, __u8 status);
 extern void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason);
 extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
@@ -577,6 +577,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
 int hci_conn_del(struct hci_conn *conn);
 void hci_conn_hash_flush(struct hci_dev *hdev);
 void hci_conn_check_pending(struct hci_dev *hdev);
+void hci_conn_accept(struct hci_conn *conn, int mask);
 
 struct hci_chan *hci_chan_create(struct hci_conn *conn);
 void hci_chan_del(struct hci_chan *chan);
@@ -779,8 +780,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 #define lmp_host_le_br_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE_BREDR)
 
 /* ----- HCI protocols ----- */
+#define HCI_PROTO_DEFER             0x01
+
 static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
-								__u8 type)
+						__u8 type, __u8 *flags)
 {
 	switch (type) {
 	case ACL_LINK:
@@ -788,7 +791,7 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
 
 	case SCO_LINK:
 	case ESCO_LINK:
-		return sco_connect_ind(hdev, bdaddr);
+		return sco_connect_ind(hdev, bdaddr, flags);
 
 	default:
 		BT_ERR("unknown link type %d", type);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 9f5c5f2..f883ef5 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2047,15 +2047,54 @@ unlock:
 	hci_conn_check_pending(hdev);
 }
 
+void hci_conn_accept(struct hci_conn *conn, int mask)
+{
+	struct hci_dev *hdev = conn->hdev;
+
+	BT_DBG("conn %p", conn);
+
+	if (!lmp_esco_capable(hdev)) {
+		struct hci_cp_accept_conn_req cp;
+
+		conn->state = BT_CONFIG;
+		bacpy(&cp.bdaddr, &conn->dst);
+
+		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
+			cp.role = 0x00; /* Become master */
+		else
+			cp.role = 0x01; /* Remain slave */
+
+		hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
+			     &cp);
+	} else /* lmp_esco_capable(hdev)) */ {
+		struct hci_cp_accept_sync_conn_req cp;
+
+		conn->state = BT_CONFIG;
+		bacpy(&cp.bdaddr, &conn->dst);
+		cp.pkt_type = cpu_to_le16(conn->pkt_type);
+
+		cp.tx_bandwidth   = __constant_cpu_to_le32(0x00001f40);
+		cp.rx_bandwidth   = __constant_cpu_to_le32(0x00001f40);
+		cp.max_latency    = __constant_cpu_to_le16(0xffff);
+		cp.content_format = cpu_to_le16(hdev->voice_setting);
+		cp.retrans_effort = 0xff;
+
+		hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
+			     sizeof(cp), &cp);
+	}
+}
+
 static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_conn_request *ev = (void *) skb->data;
 	int mask = hdev->link_mode;
+	__u8 flags = 0;
 
 	BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
 	       ev->link_type);
 
-	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
+	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
+				      &flags);
 
 	if ((mask & HCI_LM_ACCEPT) &&
 	    !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
@@ -2081,12 +2120,13 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		}
 
 		memcpy(conn->dev_class, ev->dev_class, 3);
-		conn->state = BT_CONNECT;
 
 		hci_dev_unlock(hdev);
 
-		if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
+		if (ev->link_type == ACL_LINK ||
+		    (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
 			struct hci_cp_accept_conn_req cp;
+			conn->state = BT_CONNECT;
 
 			bacpy(&cp.bdaddr, &ev->bdaddr);
 
@@ -2097,8 +2137,9 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 			hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
 				     &cp);
-		} else {
+		} else if (!(flags & HCI_PROTO_DEFER)) {
 			struct hci_cp_accept_sync_conn_req cp;
+			conn->state = BT_CONNECT;
 
 			bacpy(&cp.bdaddr, &ev->bdaddr);
 			cp.pkt_type = cpu_to_le16(conn->pkt_type);
@@ -2111,6 +2152,10 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 			hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
 				     sizeof(cp), &cp);
+		} else {
+			conn->state = BT_CONNECT2;
+			hci_proto_connect_cfm(conn, 0);
+			hci_conn_put(conn);
 		}
 	} else {
 		/* Connection rejected */
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index c6678f2..77210bf 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -397,6 +397,7 @@ static void sco_sock_init(struct sock *sk, struct sock *parent)
 
 	if (parent) {
 		sk->sk_type = parent->sk_type;
+		bt_sk(sk)->flags = bt_sk(parent)->flags;
 		security_sk_clone(parent, sk);
 	}
 }
@@ -662,6 +663,28 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 	return err;
 }
 
+static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
+			      struct msghdr *msg, size_t len, int flags)
+{
+	struct sock *sk = sock->sk;
+	struct sco_pinfo *pi = sco_pi(sk);
+
+	lock_sock(sk);
+
+	if (sk->sk_state == BT_CONNECT2 &&
+			test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
+		hci_conn_accept(pi->conn->hcon, 0);
+		sk->sk_state = BT_CONFIG;
+
+		release_sock(sk);
+		return 0;
+	}
+
+	release_sock(sk);
+
+	return bt_sock_recvmsg(iocb, sock, msg, len, flags);
+}
+
 static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
 {
 	struct sock *sk = sock->sk;
@@ -906,7 +929,10 @@ static void sco_conn_ready(struct sco_conn *conn)
 		hci_conn_hold(conn->hcon);
 		__sco_chan_add(conn, sk, parent);
 
-		sk->sk_state = BT_CONNECTED;
+		if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
+			sk->sk_state = BT_CONNECT2;
+		else
+			sk->sk_state = BT_CONNECTED;
 
 		/* Wake up parent */
 		parent->sk_data_ready(parent, 1);
@@ -919,7 +945,7 @@ done:
 }
 
 /* ----- SCO interface with lower layer (HCI) ----- */
-int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
+int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
 {
 	struct sock *sk;
 	struct hlist_node *node;
@@ -936,6 +962,9 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
 		if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) ||
 		    !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
 			lm |= HCI_LM_ACCEPT;
+
+			if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
+				*flags |= HCI_PROTO_DEFER;
 			break;
 		}
 	}
@@ -1024,7 +1053,7 @@ static const struct proto_ops sco_sock_ops = {
 	.accept		= sco_sock_accept,
 	.getname	= sco_sock_getname,
 	.sendmsg	= sco_sock_sendmsg,
-	.recvmsg	= bt_sock_recvmsg,
+	.recvmsg	= sco_sock_recvmsg,
 	.poll		= bt_sock_poll,
 	.ioctl		= bt_sock_ioctl,
 	.mmap		= sock_no_mmap,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: Add BT_DEFER_SETUP option to sco socket
From: Frédéric Dalleau @ 2012-11-19 16:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1353342958-25303-1-git-send-email-frederic.dalleau@linux.intel.com>

This option will set the BT_SK_DEFER_SETUP bit in socket flags.
---
 net/bluetooth/sco.c |   32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 450cdcd..c6678f2 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -666,12 +666,31 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
 {
 	struct sock *sk = sock->sk;
 	int err = 0;
+	u32 opt;
 
 	BT_DBG("sk %p", sk);
 
 	lock_sock(sk);
 
 	switch (optname) {
+
+	case BT_DEFER_SETUP:
+		if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
+			err = -EINVAL;
+			break;
+		}
+
+		if (get_user(opt, (u32 __user *) optval)) {
+			err = -EFAULT;
+			break;
+		}
+
+		if (opt)
+			set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
+		else
+			clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -753,6 +772,19 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
 	lock_sock(sk);
 
 	switch (optname) {
+
+	case BT_DEFER_SETUP:
+		if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
+			err = -EINVAL;
+			break;
+		}
+
+		if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
+			     (u32 __user *) optval))
+			err = -EFAULT;
+
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 0/2] sco: BT_DEFER_SETUP for SCO sockets
From: Frédéric Dalleau @ 2012-11-19 16:35 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau

Hi,

This is a better view about what can be done to implement DEFER_SETUP on SCO
sockets. hci layer get some changes since previous behavior was to accept all
SCO connections.
The ugly hci_proto_defer has been removed and replaced by an additional flag
parameter to hci_proto_connect_ind.
Regarding testing, I'm still stuck by a txt timeout issue however, if the
delay between accept and recv is set to 0, then the connection is working fine.
And I even managed to get the sco connection established correctly once. So I
believed this emulator problem.
Now I'm trying without emulator.

Let me know what you think.

Best regards,
Frédéric


Frédéric Dalleau (2):
  Bluetooth: Add BT_DEFER_SETUP option to sco socket
  Bluetooth: Implement deferred sco socket setup

 include/net/bluetooth/hci_core.h |    9 +++--
 net/bluetooth/hci_event.c        |   53 +++++++++++++++++++++++++++---
 net/bluetooth/sco.c              |   67 ++++++++++++++++++++++++++++++++++++--
 3 files changed, 119 insertions(+), 10 deletions(-)

-- 
1.7.9.5


^ permalink raw reply

* [PATCH 2/2] btiotest: Enable deferred setup for sco sockets
From: Frédéric Dalleau @ 2012-11-19 15:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1353340244-16443-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 test/btiotest.c |   22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/test/btiotest.c b/test/btiotest.c
index 4cafcc3..593bafc 100644
--- a/test/btiotest.c
+++ b/test/btiotest.c
@@ -461,24 +461,35 @@ static void sco_connect(const char *src, const char *dst, gint disconn)
 	}
 }
 
-static void sco_listen(const char *src, gint disconn)
+static void sco_listen(const char *src, gboolean defer, gint reject,
+				gint disconn, gint accept)
 {
 	struct io_data *data;
+	BtIOConnect conn;
+	BtIOConfirm cfm;
 	GIOChannel *sco_srv;
 	GError *err = NULL;
 
 	printf("Listening for SCO connections\n");
 
-	data = io_data_new(NULL, -1, disconn, -1);
+	if (defer) {
+		conn = NULL;
+		cfm = confirm_cb;
+	} else {
+		conn = connect_cb;
+		cfm = NULL;
+	}
+
+	data = io_data_new(NULL, reject, disconn, accept);
 
 	if (src)
-		sco_srv = bt_io_listen(connect_cb, NULL, data,
+		sco_srv = bt_io_listen(conn, cfm, data,
 					(GDestroyNotify) io_data_unref,
 					&err,
 					BT_IO_OPT_SOURCE, src,
 					BT_IO_OPT_INVALID);
 	else
-		sco_srv = bt_io_listen(connect_cb, NULL, data,
+		sco_srv = bt_io_listen(conn, cfm, data,
 					(GDestroyNotify) io_data_unref,
 					&err, BT_IO_OPT_INVALID);
 
@@ -588,7 +599,8 @@ int main(int argc, char *argv[])
 		if (argc > 1)
 			sco_connect(opt_dev, argv[1], opt_disconn);
 		else
-			sco_listen(opt_dev, opt_disconn);
+			sco_listen(opt_dev, opt_defer, opt_reject,
+					opt_disconn, opt_accept);
 	}
 
 	signal(SIGTERM, sig_term);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/2] scotest: Add deferred setup option
From: Frédéric Dalleau @ 2012-11-19 15:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1353340244-16443-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 test/scotest.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 55 insertions(+), 5 deletions(-)

diff --git a/test/scotest.c b/test/scotest.c
index de65edf..a40e395 100644
--- a/test/scotest.c
+++ b/test/scotest.c
@@ -57,6 +57,8 @@ static long data_size = 672;
 
 static bdaddr_t bdaddr;
 
+static int defer_setup = 0;
+
 static float tv2fl(struct timeval tv)
 {
 	return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0);
@@ -147,6 +149,14 @@ static void do_listen(void (*handler)(int sk))
 		goto error;
 	}
 
+	/* Enable deferred setup */
+	if (defer_setup && setsockopt(sk, SOL_BLUETOOTH, BT_DEFER_SETUP,
+				&defer_setup, sizeof(defer_setup)) < 0) {
+		syslog(LOG_ERR, "Can't enable deferred setup : %s (%d)",
+							strerror(errno), errno);
+		goto error;
+	}
+
 	/* Listen for connections */
 	if (listen(sk, 10)) {
 		syslog(LOG_ERR,"Can not listen on the socket: %s (%d)",
@@ -181,8 +191,10 @@ static void do_listen(void (*handler)(int sk))
 		if (getsockopt(nsk, SOL_SCO, SCO_CONNINFO, &conn, &optlen) < 0) {
 			syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)",
 							strerror(errno), errno);
-			close(nsk);
-			goto error;
+			if (!defer_setup) {
+				close(nsk);
+				goto error;
+			}
 		}
 
 		ba2str(&addr.sco_bdaddr, ba);
@@ -190,6 +202,18 @@ static void do_listen(void (*handler)(int sk))
 			ba, conn.hci_handle,
 			conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]);
 
+		/* Handle deferred setup */
+		if (defer_setup) {
+			syslog(LOG_INFO, "Waiting for %d seconds",
+							abs(defer_setup) - 1);
+			sleep(abs(defer_setup) - 1);
+
+			if (defer_setup < 0) {
+				close(nsk);
+				goto error;
+			}
+		}
+
 		handler(nsk);
 
 		syslog(LOG_INFO, "Disconnect");
@@ -207,6 +231,15 @@ static void dump_mode(int sk)
 {
 	int len;
 
+	if (defer_setup) {
+		len = read(sk, buf, sizeof(buf));
+		if (len < 0)
+			syslog(LOG_ERR, "Initial read error: %s (%d)",
+						strerror(errno), errno);
+		else
+			syslog(LOG_INFO, "Initial bytes %d", len);
+	}
+
 	syslog(LOG_INFO,"Receiving ...");
 	while ((len = read(sk, buf, data_size)) > 0)
 		syslog(LOG_INFO, "Recevied %d bytes", len);
@@ -216,6 +249,16 @@ static void recv_mode(int sk)
 {
 	struct timeval tv_beg,tv_end,tv_diff;
 	long total;
+	int len;
+
+	if (defer_setup) {
+		len = read(sk, buf, sizeof(buf));
+		if (len < 0)
+			syslog(LOG_ERR, "Initial read error: %s (%d)",
+						strerror(errno), errno);
+		else
+			syslog(LOG_INFO, "Initial bytes %d", len);
+	}
 
 	syslog(LOG_INFO, "Receiving ...");
 
@@ -328,14 +371,17 @@ static void usage(void)
 {
 	printf("scotest - SCO testing\n"
 		"Usage:\n");
-	printf("\tscotest <mode> [-b bytes] [bd_addr]\n");
+	printf("\tscotest <mode> [options] [bd_addr]\n");
 	printf("Modes:\n"
 		"\t-d dump (server)\n"
 		"\t-c reconnect (client)\n"
 		"\t-m multiple connects (client)\n"
 		"\t-r receive (server)\n"
 		"\t-s connect and send (client)\n"
-		"\t-n connect and be silent (client)\n");
+		"\t-n connect and be silent (client)\n"
+		"Options:\n"
+		"\t[-b bytes]\n"
+		"\t[-W seconds] enable deferred setup\n");
 }
 
 int main(int argc ,char *argv[])
@@ -343,7 +389,7 @@ int main(int argc ,char *argv[])
 	struct sigaction sa;
 	int opt, sk, mode = RECV;
 
-	while ((opt=getopt(argc,argv,"rdscmnb:")) != EOF) {
+	while ((opt = getopt(argc, argv, "rdscmnb:W:")) != EOF) {
 		switch(opt) {
 		case 'r':
 			mode = RECV;
@@ -373,6 +419,10 @@ int main(int argc ,char *argv[])
 			data_size = atoi(optarg);
 			break;
 
+		case 'W':
+			defer_setup = atoi(optarg);
+			break;
+
 		default:
 			usage();
 			exit(1);
-- 
1.7.9.5


^ 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