Persistent rebus D-Bus client to org.bluealsa (the bluez-alsa
bluealsad daemon), used to learn which A2DP-playback PCMs are ready to
open right now. This is the control-plane half of the Bluetooth-headphone
audio path; the data plane is sendspin opening the ALSA PCM string directly.
pcms/0 returns, for every connected A2DP headset, what a host needs
to open (or surface) its playback PCM:
%{
mac: "AA:BB:CC:DD:EE:FF",
pcm_path: "/org/bluealsa/hci0/dev_.../a2dpsrc/sink",
alsa_string: "bluealsa:DEV=AA:BB:CC:DD:EE:FF,PROFILE=a2dp",
alias: "WH-1000XM4" # org.bluez Device1.Alias, falls back to the MAC
}Connection, not the daemon
This client connects to the system bus (owned by dbus-daemon, the first
child of Bluez), not to bluealsad. So it comes up whether
or not bluealsad has claimed org.bluealsa yet; the GetManagedObjects
call simply errors (→ []) until the daemon is up, and starts returning PCMs
once a headset connects. It survives a bluealsad restart without reconnecting.
PCM enumeration (bluez-alsa v4 API)
PCMs are discovered via the freedesktop ObjectManager at /org/bluealsa
(each connected A2DP playback PCM is an org.bluealsa.PCM1 object), not
the v3 org.bluealsa.Manager1.GetPCMs method — buildroot ships bluez-alsa
4.x, where that method no longer exists (it returns UnknownMethod, which the
error path would silently swallow into []).
Inert off-target / when not started
The Bluez subtree only runs on the BT targets, so on
host/CI this GenServer isn't started. pcms/0 catches the :exit from
calling a non-existent process and returns [], mirroring the exit-safe
pattern used elsewhere in the Bluez layer — callers stay inert.
Enrichment with the device Alias is a best-effort org.bluez
Properties.Get on the same connection (BlueAlsa already proves D-Bus is
reachable); a failed Alias lookup falls back to the MAC, never raises.
Summary
Functions
Returns a specification to start this module under a supervisor.
Connected A2DP-playback PCMs as a list of maps (see the moduledoc). [] when
the daemon is down, no headset is connected, or this client isn't running.
PubSub topic broadcast when the BlueALSA PCM set changes.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec pcms() :: [ %{ mac: String.t(), pcm_path: String.t(), alsa_string: String.t(), alias: String.t() } ]
Connected A2DP-playback PCMs as a list of maps (see the moduledoc). [] when
the daemon is down, no headset is connected, or this client isn't running.
@spec pcms_topic() :: String.t()
PubSub topic broadcast when the BlueALSA PCM set changes.