Linux-Bluetooth Archive on lore.kernel.org
 help / color / Atom feed
* Bose QC 35 Battery/ANC Support
@ 2020-10-11  5:00 Peter Mullen
  2020-10-11 10:44 ` Bastien Nocera
  2020-10-12 16:43 ` Luiz Augusto von Dentz
  0 siblings, 2 replies; 6+ messages in thread
From: Peter Mullen @ 2020-10-11  5:00 UTC (permalink / raw)
  To: linux-bluetooth

Hi all,

I've been working on a plugin that adds support for battery level 
reporting and Active Noise Cancelling (ANC) control for the Bose QC 35 
headphones. The patch is nearly ready to go, but because of the 
non-standard way it's implemented I figured it might be necessary to get 
some preliminary feedback on it prior to submission (or to see if it's 
worth submitting).

As a brief overview of device control, the QC35 has a set of additional 
controls operating over rfcomm channel 8 where messages are passed back 
and forth between devices. The messages consist of a 3-byte opcode, a 
1-byte payload length, and N-bytes of payload. There's some more 
information on the specifics here: 
https://blog.davidventura.com.ar/reverse-engineering-the-bose-qc35-bluetooth-protocol.html

As this is a non-standard "profile", there's no profile UUID assigned to 
it which makes adding a profile somewhat more complicated. My solution 
here was to add a profile under the iPod Accessory Protocol (iAP) 
profile UUID which the QC35 lists, and to then filter out devices in the 
profile probe callback based on manufacturer ID, device class, and 
product ID. This isn't ideal as the probe will be called for any device 
listing the iAP UUID, so suggestions for alternative approaches (if 
necessary) are appreciated.

For session state control, I've hooked into the AVDTP state-change 
callback. Again, possibly non-standard but this seemed to be the best 
way to trigger the initiatiation/tearing down of the rfcomm connection.

For battery level integration, I've basically just wrapped the dbus 
interface from the standard GATT battery profile. This has been working 
fine with my DE; the battery level shows immediately after connection 
and updates as the level drops.

For ANC integration, I've added a new dbus interface under 
"org.bluez.Anc1". The interface contains a read-only "Range" property, 
which indicates the number of discrete values the ANC can be set to, and 
a read-write property "Level" which gets/sets the level. This interface 
layout was chosen to be device agnostic, so that ANC support could 
potentially be added for more devices in future.

Let me know if there are any thoughts on this; I can get the patch ready 
and submitted if desired.

Kind regards,
Peter


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

* Re: Bose QC 35 Battery/ANC Support
  2020-10-11  5:00 Bose QC 35 Battery/ANC Support Peter Mullen
@ 2020-10-11 10:44 ` Bastien Nocera
  2020-10-12 16:43 ` Luiz Augusto von Dentz
  1 sibling, 0 replies; 6+ messages in thread
From: Bastien Nocera @ 2020-10-11 10:44 UTC (permalink / raw)
  To: Peter Mullen, linux-bluetooth

On Sat, 2020-10-10 at 22:00 -0700, Peter Mullen wrote:
> For battery level integration, I've basically just wrapped the dbus 
> interface from the standard GATT battery profile. This has been
> working 
> fine with my DE; the battery level shows immediately after connection
> and updates as the level drops.

Glad this works. I'd like to eventually look at the code you have so
far for this functionality, so don't hesitate to share it.

Cheers


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

* Re: Bose QC 35 Battery/ANC Support
  2020-10-11  5:00 Bose QC 35 Battery/ANC Support Peter Mullen
  2020-10-11 10:44 ` Bastien Nocera
@ 2020-10-12 16:43 ` Luiz Augusto von Dentz
  2020-10-14  5:06   ` Peter Mullen
  1 sibling, 1 reply; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2020-10-12 16:43 UTC (permalink / raw)
  To: Peter Mullen; +Cc: linux-bluetooth

Hi Peter,

On Sun, Oct 11, 2020 at 1:04 PM Peter Mullen <omaolaip@tcd.ie> wrote:
>
> Hi all,
>
> I've been working on a plugin that adds support for battery level
> reporting and Active Noise Cancelling (ANC) control for the Bose QC 35
> headphones. The patch is nearly ready to go, but because of the
> non-standard way it's implemented I figured it might be necessary to get
> some preliminary feedback on it prior to submission (or to see if it's
> worth submitting).
>
> As a brief overview of device control, the QC35 has a set of additional
> controls operating over rfcomm channel 8 where messages are passed back
> and forth between devices. The messages consist of a 3-byte opcode, a
> 1-byte payload length, and N-bytes of payload. There's some more
> information on the specifics here:
> https://blog.davidventura.com.ar/reverse-engineering-the-bose-qc35-bluetooth-protocol.html
>
> As this is a non-standard "profile", there's no profile UUID assigned to
> it which makes adding a profile somewhat more complicated. My solution
> here was to add a profile under the iPod Accessory Protocol (iAP)
> profile UUID which the QC35 lists, and to then filter out devices in the
> profile probe callback based on manufacturer ID, device class, and
> product ID. This isn't ideal as the probe will be called for any device
> listing the iAP UUID, so suggestions for alternative approaches (if
> necessary) are appreciated.

We could in possibly add pid/vid to btd_profile that way it can be
probed by pid/vid in addition to UUID, that way one can make a driver
that is specific to a vendor or a product.

> For session state control, I've hooked into the AVDTP state-change
> callback. Again, possibly non-standard but this seemed to be the best
> way to trigger the initiatiation/tearing down of the rfcomm connection.

I would recommend hooking to the btd_service state, like for example
the policy plugin is doing.

> For battery level integration, I've basically just wrapped the dbus
> interface from the standard GATT battery profile. This has been working
> fine with my DE; the battery level shows immediately after connection
> and updates as the level drops.

We had some discussion on weather we should continue using a custom
D-Bus interface or just emulate the battery reports over UHID given
that is probably better integrated with the system.

> For ANC integration, I've added a new dbus interface under
> "org.bluez.Anc1". The interface contains a read-only "Range" property,
> which indicates the number of discrete values the ANC can be set to, and
> a read-write property "Level" which gets/sets the level. This interface
> layout was chosen to be device agnostic, so that ANC support could
> potentially be added for more devices in future.

I'd probably add Bose to the name of the interface if it is bose specific.

> Let me know if there are any thoughts on this; I can get the patch ready
> and submitted if desired.
>
> Kind regards,
> Peter
>


-- 
Luiz Augusto von Dentz

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

* Re: Bose QC 35 Battery/ANC Support
  2020-10-12 16:43 ` Luiz Augusto von Dentz
@ 2020-10-14  5:06   ` Peter Mullen
  2020-10-14 17:15     ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Mullen @ 2020-10-14  5:06 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hi Luiz,

On 2020-10-12 9:43 a.m., Luiz Augusto von Dentz wrote:
> Hi Peter,
> 
> On Sun, Oct 11, 2020 at 1:04 PM Peter Mullen <omaolaip@tcd.ie> wrote:
>>
>> Hi all,
>>
>> I've been working on a plugin that adds support for battery level
>> reporting and Active Noise Cancelling (ANC) control for the Bose QC 35
>> headphones. The patch is nearly ready to go, but because of the
>> non-standard way it's implemented I figured it might be necessary to get
>> some preliminary feedback on it prior to submission (or to see if it's
>> worth submitting).
>>
>> As a brief overview of device control, the QC35 has a set of additional
>> controls operating over rfcomm channel 8 where messages are passed back
>> and forth between devices. The messages consist of a 3-byte opcode, a
>> 1-byte payload length, and N-bytes of payload. There's some more
>> information on the specifics here:
>> https://blog.davidventura.com.ar/reverse-engineering-the-bose-qc35-bluetooth-protocol.html
>>
>> As this is a non-standard "profile", there's no profile UUID assigned to
>> it which makes adding a profile somewhat more complicated. My solution
>> here was to add a profile under the iPod Accessory Protocol (iAP)
>> profile UUID which the QC35 lists, and to then filter out devices in the
>> profile probe callback based on manufacturer ID, device class, and
>> product ID. This isn't ideal as the probe will be called for any device
>> listing the iAP UUID, so suggestions for alternative approaches (if
>> necessary) are appreciated.
> 
> We could in possibly add pid/vid to btd_profile that way it can be
> probed by pid/vid in addition to UUID, that way one can make a driver
> that is specific to a vendor or a product.
Had a go at that this evening as a proof-of-concept; so far it's working
well, so this could be viable. I'll finish it off and test it out properly.

>> For session state control, I've hooked into the AVDTP state-change
>> callback. Again, possibly non-standard but this seemed to be the best
>> way to trigger the initiatiation/tearing down of the rfcomm connection.
> 
> I would recommend hooking to the btd_service state, like for example
> the policy plugin is doing.
I was able to get the plugin working based on the btd_service state cb,
but had a couple of concerns with it, mainly because we'll be receiving
events for all services on all devices, so the filtering of unused
events adds a bit of overhead.
I was also able to use the AVCTP state callback without issue, which may
be better suited than the AVDTP one.

>> For ANC integration, I've added a new dbus interface under
>> "org.bluez.Anc1". The interface contains a read-only "Range" property,
>> which indicates the number of discrete values the ANC can be set to, and
>> a read-write property "Level" which gets/sets the level. This interface
>> layout was chosen to be device agnostic, so that ANC support could
>> potentially be added for more devices in future.
> 
> I'd probably add Bose to the name of the interface if it is bose specific.
While the plugin is Bose specific, I had tried to keep the interface
itself generic so that integration with the DE or similar won't need any
changes if ANC support is added for other devices later.

--
Peter Mullen

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

* Re: Bose QC 35 Battery/ANC Support
  2020-10-14  5:06   ` Peter Mullen
@ 2020-10-14 17:15     ` Luiz Augusto von Dentz
  2020-10-15  3:03       ` Peter Mullen
  0 siblings, 1 reply; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2020-10-14 17:15 UTC (permalink / raw)
  To: Peter Mullen; +Cc: linux-bluetooth

Hi Peter,

On Tue, Oct 13, 2020 at 10:06 PM Peter Mullen <omaolaip@tcd.ie> wrote:
>
> Hi Luiz,
>
> On 2020-10-12 9:43 a.m., Luiz Augusto von Dentz wrote:
> > Hi Peter,
> >
> > On Sun, Oct 11, 2020 at 1:04 PM Peter Mullen <omaolaip@tcd.ie> wrote:
> >>
> >> Hi all,
> >>
> >> I've been working on a plugin that adds support for battery level
> >> reporting and Active Noise Cancelling (ANC) control for the Bose QC 35
> >> headphones. The patch is nearly ready to go, but because of the
> >> non-standard way it's implemented I figured it might be necessary to get
> >> some preliminary feedback on it prior to submission (or to see if it's
> >> worth submitting).
> >>
> >> As a brief overview of device control, the QC35 has a set of additional
> >> controls operating over rfcomm channel 8 where messages are passed back
> >> and forth between devices. The messages consist of a 3-byte opcode, a
> >> 1-byte payload length, and N-bytes of payload. There's some more
> >> information on the specifics here:
> >> https://blog.davidventura.com.ar/reverse-engineering-the-bose-qc35-bluetooth-protocol.html
> >>
> >> As this is a non-standard "profile", there's no profile UUID assigned to
> >> it which makes adding a profile somewhat more complicated. My solution
> >> here was to add a profile under the iPod Accessory Protocol (iAP)
> >> profile UUID which the QC35 lists, and to then filter out devices in the
> >> profile probe callback based on manufacturer ID, device class, and
> >> product ID. This isn't ideal as the probe will be called for any device
> >> listing the iAP UUID, so suggestions for alternative approaches (if
> >> necessary) are appreciated.
> >
> > We could in possibly add pid/vid to btd_profile that way it can be
> > probed by pid/vid in addition to UUID, that way one can make a driver
> > that is specific to a vendor or a product.
> Had a go at that this evening as a proof-of-concept; so far it's working
> well, so this could be viable. I'll finish it off and test it out properly.
>
> >> For session state control, I've hooked into the AVDTP state-change
> >> callback. Again, possibly non-standard but this seemed to be the best
> >> way to trigger the initiatiation/tearing down of the rfcomm connection.
> >
> > I would recommend hooking to the btd_service state, like for example
> > the policy plugin is doing.
> I was able to get the plugin working based on the btd_service state cb,
> but had a couple of concerns with it, mainly because we'll be receiving
> events for all services on all devices, so the filtering of unused
> events adds a bit of overhead.
> I was also able to use the AVCTP state callback without issue, which may
> be better suited than the AVDTP one.

I guess we could add support for subscribing to state changes of a
specific service, that way you don't need to filter anything at the
plugin, how about that?

> >> For ANC integration, I've added a new dbus interface under
> >> "org.bluez.Anc1". The interface contains a read-only "Range" property,
> >> which indicates the number of discrete values the ANC can be set to, and
> >> a read-write property "Level" which gets/sets the level. This interface
> >> layout was chosen to be device agnostic, so that ANC support could
> >> potentially be added for more devices in future.
> >
> > I'd probably add Bose to the name of the interface if it is bose specific.
> While the plugin is Bose specific, I had tried to keep the interface
> itself generic so that integration with the DE or similar won't need any
> changes if ANC support is added for other devices later.
>
> --
> Peter Mullen



-- 
Luiz Augusto von Dentz

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

* Re: Bose QC 35 Battery/ANC Support
  2020-10-14 17:15     ` Luiz Augusto von Dentz
@ 2020-10-15  3:03       ` Peter Mullen
  0 siblings, 0 replies; 6+ messages in thread
From: Peter Mullen @ 2020-10-15  3:03 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hi Luiz,

On 2020-10-14 10:15 a.m., Luiz Augusto von Dentz wrote:
> Hi Peter,
> 
> On Tue, Oct 13, 2020 at 10:06 PM Peter Mullen <omaolaip@tcd.ie> wrote:
>>
>> Hi Luiz,
>>
>> On 2020-10-12 9:43 a.m., Luiz Augusto von Dentz wrote:
>>> Hi Peter,
>>>
>>> On Sun, Oct 11, 2020 at 1:04 PM Peter Mullen <omaolaip@tcd.ie> wrote:
>>>>
>>>> Hi all,
>>>>
>>>> I've been working on a plugin that adds support for battery level
>>>> reporting and Active Noise Cancelling (ANC) control for the Bose QC 35
>>>> headphones. The patch is nearly ready to go, but because of the
>>>> non-standard way it's implemented I figured it might be necessary to get
>>>> some preliminary feedback on it prior to submission (or to see if it's
>>>> worth submitting).
>>>>
>>>> As a brief overview of device control, the QC35 has a set of additional
>>>> controls operating over rfcomm channel 8 where messages are passed back
>>>> and forth between devices. The messages consist of a 3-byte opcode, a
>>>> 1-byte payload length, and N-bytes of payload. There's some more
>>>> information on the specifics here:
>>>> https://blog.davidventura.com.ar/reverse-engineering-the-bose-qc35-bluetooth-protocol.html
>>>>
>>>> As this is a non-standard "profile", there's no profile UUID assigned to
>>>> it which makes adding a profile somewhat more complicated. My solution
>>>> here was to add a profile under the iPod Accessory Protocol (iAP)
>>>> profile UUID which the QC35 lists, and to then filter out devices in the
>>>> profile probe callback based on manufacturer ID, device class, and
>>>> product ID. This isn't ideal as the probe will be called for any device
>>>> listing the iAP UUID, so suggestions for alternative approaches (if
>>>> necessary) are appreciated.
>>>
>>> We could in possibly add pid/vid to btd_profile that way it can be
>>> probed by pid/vid in addition to UUID, that way one can make a driver
>>> that is specific to a vendor or a product.
>> Had a go at that this evening as a proof-of-concept; so far it's working
>> well, so this could be viable. I'll finish it off and test it out properly.
>>
>>>> For session state control, I've hooked into the AVDTP state-change
>>>> callback. Again, possibly non-standard but this seemed to be the best
>>>> way to trigger the initiatiation/tearing down of the rfcomm connection.
>>>
>>> I would recommend hooking to the btd_service state, like for example
>>> the policy plugin is doing.
>> I was able to get the plugin working based on the btd_service state cb,
>> but had a couple of concerns with it, mainly because we'll be receiving
>> events for all services on all devices, so the filtering of unused
>> events adds a bit of overhead.
>> I was also able to use the AVCTP state callback without issue, which may
>> be better suited than the AVDTP one.
> 
> I guess we could add support for subscribing to state changes of a
> specific service, that way you don't need to filter anything at the
> plugin, how about that?

Had a look into this, but since the state callback is being registered
during profile-probe, we're not guaranteed that the other services will
have been created yet, so we won't be able to specify which service we
want to subscribe to.
I've removed the AVDTP/AVCTP state callback hook anyway, and switched
over to the existing service-state cb; after moving things around the
overhead turned out to be pretty low, so I'll get it all tidied up and
submit a patch in a couple of days (pending any further feedback).

>>>> For ANC integration, I've added a new dbus interface under
>>>> "org.bluez.Anc1". The interface contains a read-only "Range" property,
>>>> which indicates the number of discrete values the ANC can be set to, and
>>>> a read-write property "Level" which gets/sets the level. This interface
>>>> layout was chosen to be device agnostic, so that ANC support could
>>>> potentially be added for more devices in future.
>>>
>>> I'd probably add Bose to the name of the interface if it is bose specific.
>> While the plugin is Bose specific, I had tried to keep the interface
>> itself generic so that integration with the DE or similar won't need any
>> changes if ANC support is added for other devices later.
>>
>> --
>> Peter Mullen
> 
> 
> 

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

end of thread, back to index

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-11  5:00 Bose QC 35 Battery/ANC Support Peter Mullen
2020-10-11 10:44 ` Bastien Nocera
2020-10-12 16:43 ` Luiz Augusto von Dentz
2020-10-14  5:06   ` Peter Mullen
2020-10-14 17:15     ` Luiz Augusto von Dentz
2020-10-15  3:03       ` Peter Mullen

Linux-Bluetooth Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-bluetooth/0 linux-bluetooth/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-bluetooth linux-bluetooth/ https://lore.kernel.org/linux-bluetooth \
		linux-bluetooth@vger.kernel.org
	public-inbox-index linux-bluetooth

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-bluetooth


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git