2020-12-23 00:35:08

by KeithG

[permalink] [raw]
Subject: Request for help with btmgmt

I am developing a RPi based audio player. We are trying to add
bluetooth capability to this player. We use alsa and not pulse-audio,
so we need a bit more granular info to get it to run. I have written a
script which is designed to be triggered by udev when a BT device is
added or removed. This script will then use bluetoothctl to get the
capabilities of the device and also add or remove it from a dynamic
database list of MACs in redis. I have a simple script working as I
want from the cli. The key command I am using is 'btmgmt con' which is
the only command I have found that tells me what MACs are currently
connected. I can run this command from the command line as root. I can
set the setuid bit of btmgmt and also get it to run as a user (http in
this case). I cannot, ever, get this command to run when triggered
from udev. I get no response and no error.

1) Why is this particular command (query attached BT MACs) not part of
bluetoothctl? Is there a security issue?
2) Why can I not run 'btmgmt con' in a script (bash or php) triggered
by udev when the device is added or removed?
3) is there a 'better way' for me to know what device MAC addresses
are attached? I have not found another simple way to get this info.

What I am doing in the script is: if an audio source is attached, I
want to run a bluealsa-aplay service. When an audio sink is attached,
I want to re-set my audio output to the bluealsa device. If it is not
an audio device, I do not care, but do keep track of what is attached
in my database so that the next time the script runs that it is not
queried and is 'known'.

Thanks for the help.

Keith


2020-12-23 07:56:36

by Barry Byford

[permalink] [raw]
Subject: Re: Request for help with btmgmt

Hello Keith,

On Wed, 23 Dec 2020 at 00:34, KeithG <[email protected]> wrote:
>
> I am developing a RPi based audio player. We are trying to add
> bluetooth capability to this player. We use alsa and not pulse-audio,
> so we need a bit more granular info to get it to run. I have written a
> script which is designed to be triggered by udev when a BT device is
> added or removed. This script will then use bluetoothctl to get the
> capabilities of the device and also add or remove it from a dynamic
> database list of MACs in redis. I have a simple script working as I
> want from the cli. The key command I am using is 'btmgmt con' which is
> the only command I have found that tells me what MACs are currently
> connected. I can run this command from the command line as root. I can
> set the setuid bit of btmgmt and also get it to run as a user (http in
> this case). I cannot, ever, get this command to run when triggered
> from udev. I get no response and no error.
>
> 1) Why is this particular command (query attached BT MACs) not part of
> bluetoothctl? Is there a security issue?
> 2) Why can I not run 'btmgmt con' in a script (bash or php) triggered
> by udev when the device is added or removed?
> 3) is there a 'better way' for me to know what device MAC addresses
> are attached? I have not found another simple way to get this info.
>
> What I am doing in the script is: if an audio source is attached, I
> want to run a bluealsa-aplay service. When an audio sink is attached,
> I want to re-set my audio output to the bluealsa device. If it is not
> an audio device, I do not care, but do keep track of what is attached
> in my database so that the next time the script runs that it is not
> queried and is 'known'.
>
> Thanks for the help.
>
> Keith

I would suggest that the D-Bus API would be a more appropriate way to
get the information you want.

The "get managed objects" functionality is a good way to iterate
through all the devices that BlueZ knows about.
There are examples at:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/bluezutils.py
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/list-devices

The D-Bus API also allows your code to execute callbacks when a device
is added or its connection state changes.
This is done with the InterfacesAdded and PropertiesChanged signals.

If you are going to use Python I would suggest the
https://pypi.org/project/pydbus/ library is a more "Pythonic" set of
D-Bus bindings.

The API is documented at:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc

Regards,
Barry

2020-12-25 20:36:23

by KeithG

[permalink] [raw]
Subject: Re: Request for help with btmgmt

Barry,

Thanks for the help. I will look into it. I fear it may be a bit 'up
hill' for me.

Can you shed any light as to why:
1) bluetoothctl does not have a command to list the currently connected devices?
2) why btmgmt cannot be run except from the command line? Not even
'btmgmt info' can be run from a script. If it runs, I cannot tell as
no output is ever generated and no error is ever listed in the
journal.

Keith

On Wed, Dec 23, 2020 at 1:53 AM Barry Byford <[email protected]> wrote:
>
> Hello Keith,
>
> On Wed, 23 Dec 2020 at 00:34, KeithG <[email protected]> wrote:
> >
> > I am developing a RPi based audio player. We are trying to add
> > bluetooth capability to this player. We use alsa and not pulse-audio,
> > so we need a bit more granular info to get it to run. I have written a
> > script which is designed to be triggered by udev when a BT device is
> > added or removed. This script will then use bluetoothctl to get the
> > capabilities of the device and also add or remove it from a dynamic
> > database list of MACs in redis. I have a simple script working as I
> > want from the cli. The key command I am using is 'btmgmt con' which is
> > the only command I have found that tells me what MACs are currently
> > connected. I can run this command from the command line as root. I can
> > set the setuid bit of btmgmt and also get it to run as a user (http in
> > this case). I cannot, ever, get this command to run when triggered
> > from udev. I get no response and no error.
> >
> > 1) Why is this particular command (query attached BT MACs) not part of
> > bluetoothctl? Is there a security issue?
> > 2) Why can I not run 'btmgmt con' in a script (bash or php) triggered
> > by udev when the device is added or removed?
> > 3) is there a 'better way' for me to know what device MAC addresses
> > are attached? I have not found another simple way to get this info.
> >
> > What I am doing in the script is: if an audio source is attached, I
> > want to run a bluealsa-aplay service. When an audio sink is attached,
> > I want to re-set my audio output to the bluealsa device. If it is not
> > an audio device, I do not care, but do keep track of what is attached
> > in my database so that the next time the script runs that it is not
> > queried and is 'known'.
> >
> > Thanks for the help.
> >
> > Keith
>
> I would suggest that the D-Bus API would be a more appropriate way to
> get the information you want.
>
> The "get managed objects" functionality is a good way to iterate
> through all the devices that BlueZ knows about.
> There are examples at:
> https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/bluezutils.py
> https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/list-devices
>
> The D-Bus API also allows your code to execute callbacks when a device
> is added or its connection state changes.
> This is done with the InterfacesAdded and PropertiesChanged signals.
>
> If you are going to use Python I would suggest the
> https://pypi.org/project/pydbus/ library is a more "Pythonic" set of
> D-Bus bindings.
>
> The API is documented at:
> https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc
>
> Regards,
> Barry

2020-12-26 16:32:56

by KeithG

[permalink] [raw]
Subject: Re: Request for help with btmgmt

In further reading, it may be that 'bluetoothctl info' should show all
the information about the BT bus but does not? Is that possible?
If I connect a keyboard, 'bluetoothctl info' shows that keyboard. If I
then connect a phone, 'btmgmt con' shows both connected, but
'bluetoothctl info' only shows the keyboard. This is why I was using
btmgmt. I have looked through the code for BlueZ and it is very
complicated. I was trying to figure out why btmgmt does not report
when run 'non interactively' and have given up. I will start
researching dbus to see if I can work with it that way.

Keith


On Fri, Dec 25, 2020 at 2:32 PM KeithG <[email protected]> wrote:
>
> Barry,
>
> Thanks for the help. I will look into it. I fear it may be a bit 'up
> hill' for me.
>
> Can you shed any light as to why:
> 1) bluetoothctl does not have a command to list the currently connected devices?
> 2) why btmgmt cannot be run except from the command line? Not even
> 'btmgmt info' can be run from a script. If it runs, I cannot tell as
> no output is ever generated and no error is ever listed in the
> journal.
>
> Keith
>
> On Wed, Dec 23, 2020 at 1:53 AM Barry Byford <[email protected]> wrote:
> >
> > Hello Keith,
> >
> > On Wed, 23 Dec 2020 at 00:34, KeithG <[email protected]> wrote:
> > >
> > > I am developing a RPi based audio player. We are trying to add
> > > bluetooth capability to this player. We use alsa and not pulse-audio,
> > > so we need a bit more granular info to get it to run. I have written a
> > > script which is designed to be triggered by udev when a BT device is
> > > added or removed. This script will then use bluetoothctl to get the
> > > capabilities of the device and also add or remove it from a dynamic
> > > database list of MACs in redis. I have a simple script working as I
> > > want from the cli. The key command I am using is 'btmgmt con' which is
> > > the only command I have found that tells me what MACs are currently
> > > connected. I can run this command from the command line as root. I can
> > > set the setuid bit of btmgmt and also get it to run as a user (http in
> > > this case). I cannot, ever, get this command to run when triggered
> > > from udev. I get no response and no error.
> > >
> > > 1) Why is this particular command (query attached BT MACs) not part of
> > > bluetoothctl? Is there a security issue?
> > > 2) Why can I not run 'btmgmt con' in a script (bash or php) triggered
> > > by udev when the device is added or removed?
> > > 3) is there a 'better way' for me to know what device MAC addresses
> > > are attached? I have not found another simple way to get this info.
> > >
> > > What I am doing in the script is: if an audio source is attached, I
> > > want to run a bluealsa-aplay service. When an audio sink is attached,
> > > I want to re-set my audio output to the bluealsa device. If it is not
> > > an audio device, I do not care, but do keep track of what is attached
> > > in my database so that the next time the script runs that it is not
> > > queried and is 'known'.
> > >
> > > Thanks for the help.
> > >
> > > Keith
> >
> > I would suggest that the D-Bus API would be a more appropriate way to
> > get the information you want.
> >
> > The "get managed objects" functionality is a good way to iterate
> > through all the devices that BlueZ knows about.
> > There are examples at:
> > https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/bluezutils.py
> > https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/list-devices
> >
> > The D-Bus API also allows your code to execute callbacks when a device
> > is added or its connection state changes.
> > This is done with the InterfacesAdded and PropertiesChanged signals.
> >
> > If you are going to use Python I would suggest the
> > https://pypi.org/project/pydbus/ library is a more "Pythonic" set of
> > D-Bus bindings.
> >
> > The API is documented at:
> > https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc
> >
> > Regards,
> > Barry