All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* bluez: A2DP backchannel
@ 2018-07-11 11:04 Pali Rohár
  2018-07-11 13:34 ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 11+ messages in thread
From: Pali Rohár @ 2018-07-11 11:04 UTC (permalink / raw)
  To: linux-bluetooth

Hi!

Some vendor A2DP bluetooth codecs like FastStream or aptX Low Latency
supports backchannel. Which means that they are bi-directional and in
A2DP they supports not only (music) playback, but also receiving
backchannel (microphone) voice.

How to establish this bi-directional A2DP transfer with backchannel via
bluez daemon?

-- 
Pali Rohár
pali.rohar@gmail.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: bluez: A2DP backchannel
  2018-07-11 11:04 bluez: A2DP backchannel Pali Rohár
@ 2018-07-11 13:34 ` Luiz Augusto von Dentz
  2018-07-11 14:37   ` Pali Rohár
  0 siblings, 1 reply; 11+ messages in thread
From: Luiz Augusto von Dentz @ 2018-07-11 13:34 UTC (permalink / raw)
  To: Pali Rohár; +Cc: linux-bluetooth@vger.kernel.org

Hi Pali,

On Wed, Jul 11, 2018 at 2:04 PM, Pali Roh=C3=A1r <pali.rohar@gmail.com> wro=
te:
> Hi!
>
> Some vendor A2DP bluetooth codecs like FastStream or aptX Low Latency
> supports backchannel. Which means that they are bi-directional and in
> A2DP they supports not only (music) playback, but also receiving
> backchannel (microphone) voice.
>
> How to establish this bi-directional A2DP transfer with backchannel via
> bluez daemon?

There is no such thing as bi-directional in AVDTP, which is a screw up
from the spec authors, luckily we don't have to stick to it since our
sockets are bi-directional so you can send and receive data at same
time, though the configuration must be the same in either direction
otherwise we would have to support transport multiplexing to have
multiple configuration done using the same channel.

--=20
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: bluez: A2DP backchannel
  2018-07-11 13:34 ` Luiz Augusto von Dentz
@ 2018-07-11 14:37   ` Pali Rohár
  2018-07-28 19:26     ` Pali Rohár
  0 siblings, 1 reply; 11+ messages in thread
From: Pali Rohár @ 2018-07-11 14:37 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org

On Wednesday 11 July 2018 16:34:14 Luiz Augusto von Dentz wrote:
> Hi Pali,
> 
> On Wed, Jul 11, 2018 at 2:04 PM, Pali Rohár <pali.rohar@gmail.com> wrote:
> > Hi!
> >
> > Some vendor A2DP bluetooth codecs like FastStream or aptX Low Latency
> > supports backchannel. Which means that they are bi-directional and in
> > A2DP they supports not only (music) playback, but also receiving
> > backchannel (microphone) voice.
> >
> > How to establish this bi-directional A2DP transfer with backchannel via
> > bluez daemon?
> 
> There is no such thing as bi-directional in AVDTP, which is a screw up
> from the spec authors,

So it means that those vendor A2DP codecs somehow extends AVDTP, right?
I would need to figure out how A2DP devices send voice data... At least
backchannel activation for FastStream is via one bit in codec parameters
like other codec parameters.

> luckily we don't have to stick to it since our
> sockets are bi-directional so you can send and receive data at same
> time, though the configuration must be the same in either direction
> otherwise we would have to support transport multiplexing to have
> multiple configuration done using the same channel.

So does it mean that I can read from file descriptor received from dbus
which is used for sending encoded A2DP audio samples? And if other side
(e.g device with FastStream or aptX LL vendor codec) send voice via A2DP
then I receive them on that file descriptor?

-- 
Pali Rohár
pali.rohar@gmail.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: bluez: A2DP backchannel
  2018-07-11 14:37   ` Pali Rohár
@ 2018-07-28 19:26     ` Pali Rohár
  2018-07-30 11:05       ` Marcel Holtmann
  0 siblings, 1 reply; 11+ messages in thread
From: Pali Rohár @ 2018-07-28 19:26 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 2801 bytes --]

On Wednesday 11 July 2018 16:37:47 Pali Rohár wrote:
> On Wednesday 11 July 2018 16:34:14 Luiz Augusto von Dentz wrote:
> > Hi Pali,
> > 
> > On Wed, Jul 11, 2018 at 2:04 PM, Pali Rohár <pali.rohar@gmail.com> wrote:
> > > Hi!
> > >
> > > Some vendor A2DP bluetooth codecs like FastStream or aptX Low Latency
> > > supports backchannel. Which means that they are bi-directional and in
> > > A2DP they supports not only (music) playback, but also receiving
> > > backchannel (microphone) voice.
> > >
> > > How to establish this bi-directional A2DP transfer with backchannel via
> > > bluez daemon?
> > 
> > There is no such thing as bi-directional in AVDTP, which is a screw up
> > from the spec authors,
> 
> So it means that those vendor A2DP codecs somehow extends AVDTP, right?
> I would need to figure out how A2DP devices send voice data... At least
> backchannel activation for FastStream is via one bit in codec parameters
> like other codec parameters.
> 
> > luckily we don't have to stick to it since our
> > sockets are bi-directional so you can send and receive data at same
> > time, though the configuration must be the same in either direction
> > otherwise we would have to support transport multiplexing to have
> > multiple configuration done using the same channel.
> 
> So does it mean that I can read from file descriptor received from dbus
> which is used for sending encoded A2DP audio samples? And if other side
> (e.g device with FastStream or aptX LL vendor codec) send voice via A2DP
> then I receive them on that file descriptor?

Now I established A2DP connection with FastStream codec and in btmon I
see that my headset started sending some data to channel 65 in this A2DP
mode.

So definitely it is possible to send data from headset to computer (that
backchannel) in A2DP mode despite what A2DP specification says.

I managed to modify pulseaudio code to start encoding and streaming
FastStream data to headset and it is working.

Now the challenge would be how to get those data which headset send to
channel 65? Is bluez really sending them via file descriptor which is
used for writing from host to headset?

Via btmon I was able to dump data from this channel 65 and via some
sed/perl magic I converted received voice data and played it:

$ btmon > /tmp/dump
CTRL+C
$ grep 'Channel: 65' -A 14 /tmp/dump | grep '^        ' | sed 's/^        //;s/  .*//' | tr ' ' '\n' | perl -ne 'print chr(hex($_))' > /tmp/voice.sbc
$ sbcdec -f /tmp/voice.snd /tmp/voice.sbc
$ play /tmp/voice.snd

And I heard clear voice. So FastStream is really just rebranded SBC
codec (with fixed parameters; without RTP) and in A2DP bluetooth profile
provides nice bi-directional channels.

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: bluez: A2DP backchannel
  2018-07-28 19:26     ` Pali Rohár
@ 2018-07-30 11:05       ` Marcel Holtmann
  2018-07-30 17:10         ` Pali Rohár
  0 siblings, 1 reply; 11+ messages in thread
From: Marcel Holtmann @ 2018-07-30 11:05 UTC (permalink / raw)
  To: Pali Rohár; +Cc: Luiz Augusto von Dentz, linux-bluetooth@vger.kernel.org

Hi Pali,

>>>> Some vendor A2DP bluetooth codecs like FastStream or aptX Low Latency
>>>> supports backchannel. Which means that they are bi-directional and in
>>>> A2DP they supports not only (music) playback, but also receiving
>>>> backchannel (microphone) voice.
>>>> 
>>>> How to establish this bi-directional A2DP transfer with backchannel via
>>>> bluez daemon?
>>> 
>>> There is no such thing as bi-directional in AVDTP, which is a screw up
>>> from the spec authors,
>> 
>> So it means that those vendor A2DP codecs somehow extends AVDTP, right?
>> I would need to figure out how A2DP devices send voice data... At least
>> backchannel activation for FastStream is via one bit in codec parameters
>> like other codec parameters.
>> 
>>> luckily we don't have to stick to it since our
>>> sockets are bi-directional so you can send and receive data at same
>>> time, though the configuration must be the same in either direction
>>> otherwise we would have to support transport multiplexing to have
>>> multiple configuration done using the same channel.
>> 
>> So does it mean that I can read from file descriptor received from dbus
>> which is used for sending encoded A2DP audio samples? And if other side
>> (e.g device with FastStream or aptX LL vendor codec) send voice via A2DP
>> then I receive them on that file descriptor?
> 
> Now I established A2DP connection with FastStream codec and in btmon I
> see that my headset started sending some data to channel 65 in this A2DP
> mode.
> 
> So definitely it is possible to send data from headset to computer (that
> backchannel) in A2DP mode despite what A2DP specification says.
> 
> I managed to modify pulseaudio code to start encoding and streaming
> FastStream data to headset and it is working.
> 
> Now the challenge would be how to get those data which headset send to
> channel 65? Is bluez really sending them via file descriptor which is
> used for writing from host to headset?
> 
> Via btmon I was able to dump data from this channel 65 and via some
> sed/perl magic I converted received voice data and played it:
> 
> $ btmon > /tmp/dump
> CTRL+C
> $ grep 'Channel: 65' -A 14 /tmp/dump | grep '^        ' | sed 's/^        //;s/  .*//' | tr ' ' '\n' | perl -ne 'print chr(hex($_))' > /tmp/voice.sbc
> $ sbcdec -f /tmp/voice.snd /tmp/voice.sbc
> $ play /tmp/voice.snd
> 
> And I heard clear voice. So FastStream is really just rebranded SBC
> codec (with fixed parameters; without RTP) and in A2DP bluetooth profile
> provides nice bi-directional channels.

can you show us at least a few of these channel 65 frames from btmon decoding. If it is via L2CAP fixed PSM, then in theory there needs to be some sort of channel establishment. Or if this via L2CAP fixed CID, then it is essentially unicast connectionless data. Both can be handled via L2CAP sockets, but you need to create sockets for these to receive the data.

On a side note, fixed CID 65 and fixed PSM 65 are both Bluetooth SIG reserved values, so seems like this codec is still violating the standard.

Regards

Marcel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: bluez: A2DP backchannel
  2018-07-30 11:05       ` Marcel Holtmann
@ 2018-07-30 17:10         ` Pali Rohár
  2018-07-30 18:15           ` Marcel Holtmann
  0 siblings, 1 reply; 11+ messages in thread
From: Pali Rohár @ 2018-07-30 17:10 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Luiz Augusto von Dentz, linux-bluetooth@vger.kernel.org


[-- Attachment #1.1: Type: text/plain, Size: 3618 bytes --]

On Monday 30 July 2018 13:05:33 Marcel Holtmann wrote:
> Hi Pali,
> 
> >>>> Some vendor A2DP bluetooth codecs like FastStream or aptX Low Latency
> >>>> supports backchannel. Which means that they are bi-directional and in
> >>>> A2DP they supports not only (music) playback, but also receiving
> >>>> backchannel (microphone) voice.
> >>>> 
> >>>> How to establish this bi-directional A2DP transfer with backchannel via
> >>>> bluez daemon?
> >>> 
> >>> There is no such thing as bi-directional in AVDTP, which is a screw up
> >>> from the spec authors,
> >> 
> >> So it means that those vendor A2DP codecs somehow extends AVDTP, right?
> >> I would need to figure out how A2DP devices send voice data... At least
> >> backchannel activation for FastStream is via one bit in codec parameters
> >> like other codec parameters.
> >> 
> >>> luckily we don't have to stick to it since our
> >>> sockets are bi-directional so you can send and receive data at same
> >>> time, though the configuration must be the same in either direction
> >>> otherwise we would have to support transport multiplexing to have
> >>> multiple configuration done using the same channel.
> >> 
> >> So does it mean that I can read from file descriptor received from dbus
> >> which is used for sending encoded A2DP audio samples? And if other side
> >> (e.g device with FastStream or aptX LL vendor codec) send voice via A2DP
> >> then I receive them on that file descriptor?
> > 
> > Now I established A2DP connection with FastStream codec and in btmon I
> > see that my headset started sending some data to channel 65 in this A2DP
> > mode.
> > 
> > So definitely it is possible to send data from headset to computer (that
> > backchannel) in A2DP mode despite what A2DP specification says.
> > 
> > I managed to modify pulseaudio code to start encoding and streaming
> > FastStream data to headset and it is working.
> > 
> > Now the challenge would be how to get those data which headset send to
> > channel 65? Is bluez really sending them via file descriptor which is
> > used for writing from host to headset?
> > 
> > Via btmon I was able to dump data from this channel 65 and via some
> > sed/perl magic I converted received voice data and played it:
> > 
> > $ btmon > /tmp/dump
> > CTRL+C
> > $ grep 'Channel: 65' -A 14 /tmp/dump | grep '^        ' | sed 's/^        //;s/  .*//' | tr ' ' '\n' | perl -ne 'print chr(hex($_))' > /tmp/voice.sbc
> > $ sbcdec -f /tmp/voice.snd /tmp/voice.sbc
> > $ play /tmp/voice.snd
> > 
> > And I heard clear voice. So FastStream is really just rebranded SBC
> > codec (with fixed parameters; without RTP) and in A2DP bluetooth profile
> > provides nice bi-directional channels.
> 
> can you show us at least a few of these channel 65 frames from btmon decoding. If it is via L2CAP fixed PSM, then in theory there needs to be some sort of channel establishment. Or if this via L2CAP fixed CID, then it is essentially unicast connectionless data. Both can be handled via L2CAP sockets, but you need to create sockets for these to receive the data.
> 
> On a side note, fixed CID 65 and fixed PSM 65 are both Bluetooth SIG reserved values, so seems like this codec is still violating the standard.

Hi! In attachment is btmon dump with codec negotiation, connect, both
sink and source data and disconnect. Interesting is that now channel 65
is used for both sink and source. Yesterday when I was doing tests I
remember that different channel was used for microphone input and audio
playback.

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #1.2: btmon.gz --]
[-- Type: application/gzip, Size: 118765 bytes --]

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: bluez: A2DP backchannel
  2018-07-30 17:10         ` Pali Rohár
@ 2018-07-30 18:15           ` Marcel Holtmann
  2018-07-30 18:25             ` Pali Rohár
  0 siblings, 1 reply; 11+ messages in thread
From: Marcel Holtmann @ 2018-07-30 18:15 UTC (permalink / raw)
  To: Pali Rohár; +Cc: Luiz Augusto von Dentz, linux-bluetooth@vger.kernel.org

Hi Pali,

>>>>>> Some vendor A2DP bluetooth codecs like FastStream or aptX Low Latency
>>>>>> supports backchannel. Which means that they are bi-directional and in
>>>>>> A2DP they supports not only (music) playback, but also receiving
>>>>>> backchannel (microphone) voice.
>>>>>> 
>>>>>> How to establish this bi-directional A2DP transfer with backchannel via
>>>>>> bluez daemon?
>>>>> 
>>>>> There is no such thing as bi-directional in AVDTP, which is a screw up
>>>>> from the spec authors,
>>>> 
>>>> So it means that those vendor A2DP codecs somehow extends AVDTP, right?
>>>> I would need to figure out how A2DP devices send voice data... At least
>>>> backchannel activation for FastStream is via one bit in codec parameters
>>>> like other codec parameters.
>>>> 
>>>>> luckily we don't have to stick to it since our
>>>>> sockets are bi-directional so you can send and receive data at same
>>>>> time, though the configuration must be the same in either direction
>>>>> otherwise we would have to support transport multiplexing to have
>>>>> multiple configuration done using the same channel.
>>>> 
>>>> So does it mean that I can read from file descriptor received from dbus
>>>> which is used for sending encoded A2DP audio samples? And if other side
>>>> (e.g device with FastStream or aptX LL vendor codec) send voice via A2DP
>>>> then I receive them on that file descriptor?
>>> 
>>> Now I established A2DP connection with FastStream codec and in btmon I
>>> see that my headset started sending some data to channel 65 in this A2DP
>>> mode.
>>> 
>>> So definitely it is possible to send data from headset to computer (that
>>> backchannel) in A2DP mode despite what A2DP specification says.
>>> 
>>> I managed to modify pulseaudio code to start encoding and streaming
>>> FastStream data to headset and it is working.
>>> 
>>> Now the challenge would be how to get those data which headset send to
>>> channel 65? Is bluez really sending them via file descriptor which is
>>> used for writing from host to headset?
>>> 
>>> Via btmon I was able to dump data from this channel 65 and via some
>>> sed/perl magic I converted received voice data and played it:
>>> 
>>> $ btmon > /tmp/dump
>>> CTRL+C
>>> $ grep 'Channel: 65' -A 14 /tmp/dump | grep '^        ' | sed 's/^        //;s/  .*//' | tr ' ' '\n' | perl -ne 'print chr(hex($_))' > /tmp/voice.sbc
>>> $ sbcdec -f /tmp/voice.snd /tmp/voice.sbc
>>> $ play /tmp/voice.snd
>>> 
>>> And I heard clear voice. So FastStream is really just rebranded SBC
>>> codec (with fixed parameters; without RTP) and in A2DP bluetooth profile
>>> provides nice bi-directional channels.
>> 
>> can you show us at least a few of these channel 65 frames from btmon decoding. If it is via L2CAP fixed PSM, then in theory there needs to be some sort of channel establishment. Or if this via L2CAP fixed CID, then it is essentially unicast connectionless data. Both can be handled via L2CAP sockets, but you need to create sockets for these to receive the data.
>> 
>> On a side note, fixed CID 65 and fixed PSM 65 are both Bluetooth SIG reserved values, so seems like this codec is still violating the standard.
> 
> Hi! In attachment is btmon dump with codec negotiation, connect, both
> sink and source data and disconnect. Interesting is that now channel 65
> is used for both sink and source. Yesterday when I was doing tests I
> remember that different channel was used for microphone input and audio
> playback.

so the Channel: 65 is a CID and is assigned dynamically. They can be different in each direction and by chance you get Source CID: 65 and Destination CID: 65. What I am seeing is that you get TX and RX on that PSM 25 which seems to be the established media channel. This means the file descriptor you already have for sending audio, just read from it and you should be getting the back channel receiving audio. L2CAP channels are always bi-directional.

Regards

Marcel



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: bluez: A2DP backchannel
  2018-07-30 18:15           ` Marcel Holtmann
@ 2018-07-30 18:25             ` Pali Rohár
  2018-07-30 19:39               ` Marcel Holtmann
  0 siblings, 1 reply; 11+ messages in thread
From: Pali Rohár @ 2018-07-30 18:25 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Luiz Augusto von Dentz, linux-bluetooth@vger.kernel.org


[-- Attachment #1.1: Type: text/plain, Size: 4591 bytes --]

On Monday 30 July 2018 20:15:37 Marcel Holtmann wrote:
> Hi Pali,
> 
> >>>>>> Some vendor A2DP bluetooth codecs like FastStream or aptX Low Latency
> >>>>>> supports backchannel. Which means that they are bi-directional and in
> >>>>>> A2DP they supports not only (music) playback, but also receiving
> >>>>>> backchannel (microphone) voice.
> >>>>>> 
> >>>>>> How to establish this bi-directional A2DP transfer with backchannel via
> >>>>>> bluez daemon?
> >>>>> 
> >>>>> There is no such thing as bi-directional in AVDTP, which is a screw up
> >>>>> from the spec authors,
> >>>> 
> >>>> So it means that those vendor A2DP codecs somehow extends AVDTP, right?
> >>>> I would need to figure out how A2DP devices send voice data... At least
> >>>> backchannel activation for FastStream is via one bit in codec parameters
> >>>> like other codec parameters.
> >>>> 
> >>>>> luckily we don't have to stick to it since our
> >>>>> sockets are bi-directional so you can send and receive data at same
> >>>>> time, though the configuration must be the same in either direction
> >>>>> otherwise we would have to support transport multiplexing to have
> >>>>> multiple configuration done using the same channel.
> >>>> 
> >>>> So does it mean that I can read from file descriptor received from dbus
> >>>> which is used for sending encoded A2DP audio samples? And if other side
> >>>> (e.g device with FastStream or aptX LL vendor codec) send voice via A2DP
> >>>> then I receive them on that file descriptor?
> >>> 
> >>> Now I established A2DP connection with FastStream codec and in btmon I
> >>> see that my headset started sending some data to channel 65 in this A2DP
> >>> mode.
> >>> 
> >>> So definitely it is possible to send data from headset to computer (that
> >>> backchannel) in A2DP mode despite what A2DP specification says.
> >>> 
> >>> I managed to modify pulseaudio code to start encoding and streaming
> >>> FastStream data to headset and it is working.
> >>> 
> >>> Now the challenge would be how to get those data which headset send to
> >>> channel 65? Is bluez really sending them via file descriptor which is
> >>> used for writing from host to headset?
> >>> 
> >>> Via btmon I was able to dump data from this channel 65 and via some
> >>> sed/perl magic I converted received voice data and played it:
> >>> 
> >>> $ btmon > /tmp/dump
> >>> CTRL+C
> >>> $ grep 'Channel: 65' -A 14 /tmp/dump | grep '^        ' | sed 's/^        //;s/  .*//' | tr ' ' '\n' | perl -ne 'print chr(hex($_))' > /tmp/voice.sbc
> >>> $ sbcdec -f /tmp/voice.snd /tmp/voice.sbc
> >>> $ play /tmp/voice.snd
> >>> 
> >>> And I heard clear voice. So FastStream is really just rebranded SBC
> >>> codec (with fixed parameters; without RTP) and in A2DP bluetooth profile
> >>> provides nice bi-directional channels.
> >> 
> >> can you show us at least a few of these channel 65 frames from btmon decoding. If it is via L2CAP fixed PSM, then in theory there needs to be some sort of channel establishment. Or if this via L2CAP fixed CID, then it is essentially unicast connectionless data. Both can be handled via L2CAP sockets, but you need to create sockets for these to receive the data.
> >> 
> >> On a side note, fixed CID 65 and fixed PSM 65 are both Bluetooth SIG reserved values, so seems like this codec is still violating the standard.
> > 
> > Hi! In attachment is btmon dump with codec negotiation, connect, both
> > sink and source data and disconnect. Interesting is that now channel 65
> > is used for both sink and source. Yesterday when I was doing tests I
> > remember that different channel was used for microphone input and audio
> > playback.
> 
> so the Channel: 65 is a CID and is assigned dynamically. They can be different in each direction and by chance you get Source CID: 65 and Destination CID: 65. What I am seeing is that you get TX and RX on that PSM 25 which seems to be the established media channel. This means the file descriptor you already have for sending audio, just read from it and you should be getting the back channel receiving audio. L2CAP channels are always bi-directional.

Interesting. Now I repeated my tests again and channels 77 and 64 are
used (64 for voice microphone). Just in case, btmon output is attached.

I would try to read directly from file descriptor used for sending data
and see if I can easily decode it in pulseaudio. As sbcdec was able to
decode it I hope that there would not be problem with libsbc in
pulseaudio.

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #1.2: btmon2.gz --]
[-- Type: application/gzip, Size: 122644 bytes --]

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: bluez: A2DP backchannel
  2018-07-30 18:25             ` Pali Rohár
@ 2018-07-30 19:39               ` Marcel Holtmann
  2018-07-30 19:53                 ` Pali Rohár
  2018-07-30 19:54                 ` Luiz Augusto von Dentz
  0 siblings, 2 replies; 11+ messages in thread
From: Marcel Holtmann @ 2018-07-30 19:39 UTC (permalink / raw)
  To: Pali Rohár; +Cc: Luiz Augusto von Dentz, linux-bluetooth@vger.kernel.org

Hi Pali,

>>>>>>>> Some vendor A2DP bluetooth codecs like FastStream or aptX Low Latency
>>>>>>>> supports backchannel. Which means that they are bi-directional and in
>>>>>>>> A2DP they supports not only (music) playback, but also receiving
>>>>>>>> backchannel (microphone) voice.
>>>>>>>> 
>>>>>>>> How to establish this bi-directional A2DP transfer with backchannel via
>>>>>>>> bluez daemon?
>>>>>>> 
>>>>>>> There is no such thing as bi-directional in AVDTP, which is a screw up
>>>>>>> from the spec authors,
>>>>>> 
>>>>>> So it means that those vendor A2DP codecs somehow extends AVDTP, right?
>>>>>> I would need to figure out how A2DP devices send voice data... At least
>>>>>> backchannel activation for FastStream is via one bit in codec parameters
>>>>>> like other codec parameters.
>>>>>> 
>>>>>>> luckily we don't have to stick to it since our
>>>>>>> sockets are bi-directional so you can send and receive data at same
>>>>>>> time, though the configuration must be the same in either direction
>>>>>>> otherwise we would have to support transport multiplexing to have
>>>>>>> multiple configuration done using the same channel.
>>>>>> 
>>>>>> So does it mean that I can read from file descriptor received from dbus
>>>>>> which is used for sending encoded A2DP audio samples? And if other side
>>>>>> (e.g device with FastStream or aptX LL vendor codec) send voice via A2DP
>>>>>> then I receive them on that file descriptor?
>>>>> 
>>>>> Now I established A2DP connection with FastStream codec and in btmon I
>>>>> see that my headset started sending some data to channel 65 in this A2DP
>>>>> mode.
>>>>> 
>>>>> So definitely it is possible to send data from headset to computer (that
>>>>> backchannel) in A2DP mode despite what A2DP specification says.
>>>>> 
>>>>> I managed to modify pulseaudio code to start encoding and streaming
>>>>> FastStream data to headset and it is working.
>>>>> 
>>>>> Now the challenge would be how to get those data which headset send to
>>>>> channel 65? Is bluez really sending them via file descriptor which is
>>>>> used for writing from host to headset?
>>>>> 
>>>>> Via btmon I was able to dump data from this channel 65 and via some
>>>>> sed/perl magic I converted received voice data and played it:
>>>>> 
>>>>> $ btmon > /tmp/dump
>>>>> CTRL+C
>>>>> $ grep 'Channel: 65' -A 14 /tmp/dump | grep '^        ' | sed 's/^        //;s/  .*//' | tr ' ' '\n' | perl -ne 'print chr(hex($_))' > /tmp/voice.sbc
>>>>> $ sbcdec -f /tmp/voice.snd /tmp/voice.sbc
>>>>> $ play /tmp/voice.snd
>>>>> 
>>>>> And I heard clear voice. So FastStream is really just rebranded SBC
>>>>> codec (with fixed parameters; without RTP) and in A2DP bluetooth profile
>>>>> provides nice bi-directional channels.
>>>> 
>>>> can you show us at least a few of these channel 65 frames from btmon decoding. If it is via L2CAP fixed PSM, then in theory there needs to be some sort of channel establishment. Or if this via L2CAP fixed CID, then it is essentially unicast connectionless data. Both can be handled via L2CAP sockets, but you need to create sockets for these to receive the data.
>>>> 
>>>> On a side note, fixed CID 65 and fixed PSM 65 are both Bluetooth SIG reserved values, so seems like this codec is still violating the standard.
>>> 
>>> Hi! In attachment is btmon dump with codec negotiation, connect, both
>>> sink and source data and disconnect. Interesting is that now channel 65
>>> is used for both sink and source. Yesterday when I was doing tests I
>>> remember that different channel was used for microphone input and audio
>>> playback.
>> 
>> so the Channel: 65 is a CID and is assigned dynamically. They can be different in each direction and by chance you get Source CID: 65 and Destination CID: 65. What I am seeing is that you get TX and RX on that PSM 25 which seems to be the established media channel. This means the file descriptor you already have for sending audio, just read from it and you should be getting the back channel receiving audio. L2CAP channels are always bi-directional.
> 
> Interesting. Now I repeated my tests again and channels 77 and 64 are
> used (64 for voice microphone). Just in case, btmon output is attached.

that is fine. As I said, different CID numbers are assigned for each direction. They are negotiated when the L2CAP channel is created. That they are the same rarely happens, but it can. Anyhow, the L2CAP socket from the kernel will map CID 64 into recv and CID 77 into send.

> I would try to read directly from file descriptor used for sending data
> and see if I can easily decode it in pulseaudio. As sbcdec was able to
> decode it I hope that there would not be problem with libsbc in
> pulseaudio.

No idea why it would be SBC encoded, but sure. I don’t know enough detail about Fast Stream codec.

Regards

Marcel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: bluez: A2DP backchannel
  2018-07-30 19:39               ` Marcel Holtmann
@ 2018-07-30 19:53                 ` Pali Rohár
  2018-07-30 19:54                 ` Luiz Augusto von Dentz
  1 sibling, 0 replies; 11+ messages in thread
From: Pali Rohár @ 2018-07-30 19:53 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Luiz Augusto von Dentz, linux-bluetooth@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 6194 bytes --]

On Monday 30 July 2018 21:39:09 Marcel Holtmann wrote:
> Hi Pali,
> 
> >>>>>>>> Some vendor A2DP bluetooth codecs like FastStream or aptX Low Latency
> >>>>>>>> supports backchannel. Which means that they are bi-directional and in
> >>>>>>>> A2DP they supports not only (music) playback, but also receiving
> >>>>>>>> backchannel (microphone) voice.
> >>>>>>>> 
> >>>>>>>> How to establish this bi-directional A2DP transfer with backchannel via
> >>>>>>>> bluez daemon?
> >>>>>>> 
> >>>>>>> There is no such thing as bi-directional in AVDTP, which is a screw up
> >>>>>>> from the spec authors,
> >>>>>> 
> >>>>>> So it means that those vendor A2DP codecs somehow extends AVDTP, right?
> >>>>>> I would need to figure out how A2DP devices send voice data... At least
> >>>>>> backchannel activation for FastStream is via one bit in codec parameters
> >>>>>> like other codec parameters.
> >>>>>> 
> >>>>>>> luckily we don't have to stick to it since our
> >>>>>>> sockets are bi-directional so you can send and receive data at same
> >>>>>>> time, though the configuration must be the same in either direction
> >>>>>>> otherwise we would have to support transport multiplexing to have
> >>>>>>> multiple configuration done using the same channel.
> >>>>>> 
> >>>>>> So does it mean that I can read from file descriptor received from dbus
> >>>>>> which is used for sending encoded A2DP audio samples? And if other side
> >>>>>> (e.g device with FastStream or aptX LL vendor codec) send voice via A2DP
> >>>>>> then I receive them on that file descriptor?
> >>>>> 
> >>>>> Now I established A2DP connection with FastStream codec and in btmon I
> >>>>> see that my headset started sending some data to channel 65 in this A2DP
> >>>>> mode.
> >>>>> 
> >>>>> So definitely it is possible to send data from headset to computer (that
> >>>>> backchannel) in A2DP mode despite what A2DP specification says.
> >>>>> 
> >>>>> I managed to modify pulseaudio code to start encoding and streaming
> >>>>> FastStream data to headset and it is working.
> >>>>> 
> >>>>> Now the challenge would be how to get those data which headset send to
> >>>>> channel 65? Is bluez really sending them via file descriptor which is
> >>>>> used for writing from host to headset?
> >>>>> 
> >>>>> Via btmon I was able to dump data from this channel 65 and via some
> >>>>> sed/perl magic I converted received voice data and played it:
> >>>>> 
> >>>>> $ btmon > /tmp/dump
> >>>>> CTRL+C
> >>>>> $ grep 'Channel: 65' -A 14 /tmp/dump | grep '^        ' | sed 's/^        //;s/  .*//' | tr ' ' '\n' | perl -ne 'print chr(hex($_))' > /tmp/voice.sbc
> >>>>> $ sbcdec -f /tmp/voice.snd /tmp/voice.sbc
> >>>>> $ play /tmp/voice.snd
> >>>>> 
> >>>>> And I heard clear voice. So FastStream is really just rebranded SBC
> >>>>> codec (with fixed parameters; without RTP) and in A2DP bluetooth profile
> >>>>> provides nice bi-directional channels.
> >>>> 
> >>>> can you show us at least a few of these channel 65 frames from btmon decoding. If it is via L2CAP fixed PSM, then in theory there needs to be some sort of channel establishment. Or if this via L2CAP fixed CID, then it is essentially unicast connectionless data. Both can be handled via L2CAP sockets, but you need to create sockets for these to receive the data.
> >>>> 
> >>>> On a side note, fixed CID 65 and fixed PSM 65 are both Bluetooth SIG reserved values, so seems like this codec is still violating the standard.
> >>> 
> >>> Hi! In attachment is btmon dump with codec negotiation, connect, both
> >>> sink and source data and disconnect. Interesting is that now channel 65
> >>> is used for both sink and source. Yesterday when I was doing tests I
> >>> remember that different channel was used for microphone input and audio
> >>> playback.
> >> 
> >> so the Channel: 65 is a CID and is assigned dynamically. They can be different in each direction and by chance you get Source CID: 65 and Destination CID: 65. What I am seeing is that you get TX and RX on that PSM 25 which seems to be the established media channel. This means the file descriptor you already have for sending audio, just read from it and you should be getting the back channel receiving audio. L2CAP channels are always bi-directional.
> > 
> > Interesting. Now I repeated my tests again and channels 77 and 64 are
> > used (64 for voice microphone). Just in case, btmon output is attached.
> 
> that is fine. As I said, different CID numbers are assigned for each direction. They are negotiated when the L2CAP channel is created. That they are the same rarely happens, but it can. Anyhow, the L2CAP socket from the kernel will map CID 64 into recv and CID 77 into send.

Ok.

> > I would try to read directly from file descriptor used for sending data
> > and see if I can easily decode it in pulseaudio. As sbcdec was able to
> > decode it I hope that there would not be problem with libsbc in
> > pulseaudio.
> 
> No idea why it would be SBC encoded, but sure. I don’t know enough detail about Fast Stream codec.

From information which I have:

FastStream A2DP codec for audio sink uses SBC codec without RTP wrapping
with following parameters: frequency rate 44.1 kHz or 48 Hz, Block 16,
Sub-bands 8, Joint Stereo, Loudness and Bitpool 29. Data rate is 212
kbps, packet size 72*3+4 = 220. DSP decoders round 71 bytes to 72 (that
is why sbc size in packet is 72 and not 71). FastStream is presented as
low latency A2DP codec; but it is just rebranded SBC codec with fixes
parameters.

Backchannel in FastStream A2DP codec uses SBC codec too with parameters:
frequency rate 16 kHz, Blocks 16, Sub-bands 8, Mono, Loudness, Bitpool
32. Data rate is 72 kbps, packet size 72*3+4 = 220. Again 71 bytes are
rounded to 72 in DSP.

I do not know yet what should be stored on that 72. byte. When I put
there zero byte, my headset is happy and play music without glitches
(This zero byte can be seen also in dumps which I sent). But received
voice data seems to always have different value on that position. So I
guess it could be some checksum...

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: bluez: A2DP backchannel
  2018-07-30 19:39               ` Marcel Holtmann
  2018-07-30 19:53                 ` Pali Rohár
@ 2018-07-30 19:54                 ` Luiz Augusto von Dentz
  1 sibling, 0 replies; 11+ messages in thread
From: Luiz Augusto von Dentz @ 2018-07-30 19:54 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Pali Rohár, linux-bluetooth@vger.kernel.org

Hi Marcel,

On Mon, Jul 30, 2018 at 10:39 PM, Marcel Holtmann <marcel@holtmann.org> wro=
te:
> Hi Pali,
>
>>>>>>>>> Some vendor A2DP bluetooth codecs like FastStream or aptX Low Lat=
ency
>>>>>>>>> supports backchannel. Which means that they are bi-directional an=
d in
>>>>>>>>> A2DP they supports not only (music) playback, but also receiving
>>>>>>>>> backchannel (microphone) voice.
>>>>>>>>>
>>>>>>>>> How to establish this bi-directional A2DP transfer with backchann=
el via
>>>>>>>>> bluez daemon?
>>>>>>>>
>>>>>>>> There is no such thing as bi-directional in AVDTP, which is a scre=
w up
>>>>>>>> from the spec authors,
>>>>>>>
>>>>>>> So it means that those vendor A2DP codecs somehow extends AVDTP, ri=
ght?
>>>>>>> I would need to figure out how A2DP devices send voice data... At l=
east
>>>>>>> backchannel activation for FastStream is via one bit in codec param=
eters
>>>>>>> like other codec parameters.
>>>>>>>
>>>>>>>> luckily we don't have to stick to it since our
>>>>>>>> sockets are bi-directional so you can send and receive data at sam=
e
>>>>>>>> time, though the configuration must be the same in either directio=
n
>>>>>>>> otherwise we would have to support transport multiplexing to have
>>>>>>>> multiple configuration done using the same channel.
>>>>>>>
>>>>>>> So does it mean that I can read from file descriptor received from =
dbus
>>>>>>> which is used for sending encoded A2DP audio samples? And if other =
side
>>>>>>> (e.g device with FastStream or aptX LL vendor codec) send voice via=
 A2DP
>>>>>>> then I receive them on that file descriptor?
>>>>>>
>>>>>> Now I established A2DP connection with FastStream codec and in btmon=
 I
>>>>>> see that my headset started sending some data to channel 65 in this =
A2DP
>>>>>> mode.
>>>>>>
>>>>>> So definitely it is possible to send data from headset to computer (=
that
>>>>>> backchannel) in A2DP mode despite what A2DP specification says.
>>>>>>
>>>>>> I managed to modify pulseaudio code to start encoding and streaming
>>>>>> FastStream data to headset and it is working.
>>>>>>
>>>>>> Now the challenge would be how to get those data which headset send =
to
>>>>>> channel 65? Is bluez really sending them via file descriptor which i=
s
>>>>>> used for writing from host to headset?
>>>>>>
>>>>>> Via btmon I was able to dump data from this channel 65 and via some
>>>>>> sed/perl magic I converted received voice data and played it:
>>>>>>
>>>>>> $ btmon > /tmp/dump
>>>>>> CTRL+C
>>>>>> $ grep 'Channel: 65' -A 14 /tmp/dump | grep '^        ' | sed 's/^  =
      //;s/  .*//' | tr ' ' '\n' | perl -ne 'print chr(hex($_))' > /tmp/voi=
ce.sbc
>>>>>> $ sbcdec -f /tmp/voice.snd /tmp/voice.sbc
>>>>>> $ play /tmp/voice.snd
>>>>>>
>>>>>> And I heard clear voice. So FastStream is really just rebranded SBC
>>>>>> codec (with fixed parameters; without RTP) and in A2DP bluetooth pro=
file
>>>>>> provides nice bi-directional channels.
>>>>>
>>>>> can you show us at least a few of these channel 65 frames from btmon =
decoding. If it is via L2CAP fixed PSM, then in theory there needs to be so=
me sort of channel establishment. Or if this via L2CAP fixed CID, then it i=
s essentially unicast connectionless data. Both can be handled via L2CAP so=
ckets, but you need to create sockets for these to receive the data.
>>>>>
>>>>> On a side note, fixed CID 65 and fixed PSM 65 are both Bluetooth SIG =
reserved values, so seems like this codec is still violating the standard.
>>>>
>>>> Hi! In attachment is btmon dump with codec negotiation, connect, both
>>>> sink and source data and disconnect. Interesting is that now channel 6=
5
>>>> is used for both sink and source. Yesterday when I was doing tests I
>>>> remember that different channel was used for microphone input and audi=
o
>>>> playback.
>>>
>>> so the Channel: 65 is a CID and is assigned dynamically. They can be di=
fferent in each direction and by chance you get Source CID: 65 and Destinat=
ion CID: 65. What I am seeing is that you get TX and RX on that PSM 25 whic=
h seems to be the established media channel. This means the file descriptor=
 you already have for sending audio, just read from it and you should be ge=
tting the back channel receiving audio. L2CAP channels are always bi-direct=
ional.
>>
>> Interesting. Now I repeated my tests again and channels 77 and 64 are
>> used (64 for voice microphone). Just in case, btmon output is attached.
>
> that is fine. As I said, different CID numbers are assigned for each dire=
ction. They are negotiated when the L2CAP channel is created. That they are=
 the same rarely happens, but it can. Anyhow, the L2CAP socket from the ker=
nel will map CID 64 into recv and CID 77 into send.
>
>> I would try to read directly from file descriptor used for sending data
>> and see if I can easily decode it in pulseaudio. As sbcdec was able to
>> decode it I hope that there would not be problem with libsbc in
>> pulseaudio.
>
> No idea why it would be SBC encoded, but sure. I don=E2=80=99t know enoug=
h detail about Fast Stream codec.

It appears Fast Strem uses SBC in both directions, though this is not
'supported' in AVDTP since endpoint can only be source or sink, not
both and having both ways configure would require 2 channels but
apparently they got away with L2CAP being bi-directional. The input
side is most like mSBC so they don't have to configure anything since
mSBC uses fixed parameters.

> Regards
>
> Marcel
>



--=20
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-07-30 19:54 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-11 11:04 bluez: A2DP backchannel Pali Rohár
2018-07-11 13:34 ` Luiz Augusto von Dentz
2018-07-11 14:37   ` Pali Rohár
2018-07-28 19:26     ` Pali Rohár
2018-07-30 11:05       ` Marcel Holtmann
2018-07-30 17:10         ` Pali Rohár
2018-07-30 18:15           ` Marcel Holtmann
2018-07-30 18:25             ` Pali Rohár
2018-07-30 19:39               ` Marcel Holtmann
2018-07-30 19:53                 ` Pali Rohár
2018-07-30 19:54                 ` Luiz Augusto von Dentz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.