Exports the Improv GATT application over D-Bus and serves the inbound method calls BlueZ makes against it.
Same export+dispatch shape as Bluez.Agent/Client, scaled to
a small object tree: an app-root ObjectManager, one org.bluez.GattService1,
and five org.bluez.GattCharacteristic1 objects (the Improv
capabilities/current-state/error-state/rpc-command/rpc-result characteristics —
all cleartext, no encrypt flags). Registration calls
GattManager1.RegisterApplication on the adapter; BlueZ then reads the entire
tree once via GetManagedObjects and afterwards calls
ReadValue/WriteValue/StartNotify/StopNotify per characteristic.
Notifications (current-state, error-state, rpc-result progress) are pushed by
emitting org.freedesktop.DBus.Properties.PropertiesChanged on the
characteristic's object path (Bluez.Rebus.emit_signal/2) — but
only after a client has subscribed via StartNotify.
Owns its own rebus connection (separate failure domain, like Gatt).
Inbound rpc-command writes and notify subscriptions are forwarded to the
Improv manager process (:manager option) which drives the state machine.
The tree/props/read logic is pure (managed_objects/2, props_for/3,
read_value/2, introspect_xml/1, permission helpers) and host-tested;
the GenServer is a thin I/O shell over it.
Summary
Functions
Object path the Improv GATT application is rooted at.
Object path for a characteristic role, or nil if unknown.
The exported characteristics in tree order, each a map with :key, :path,
:uuid, and :flags. Pure.
Returns a specification to start this module under a supervisor.
Introspection XML for one exported object path. Pure.
Build the GetManagedObjects reply tree (a{oa{sa{sv}}} payload) from the
current values cache and notifying set. Pure.
Cache a new value for characteristic key and, if a client has subscribed,
push it as a GATT notification. Used for current-state, error-state and
rpc-result updates.
Properties for the object at path: {interface, props_list} or :unknown.
Pure; used by Properties.GetAll/Get and the tree builder.
Read a characteristic value as a list of bytes (the ay body shape), or
{:error, bluez_error_name} for a non-readable / unknown characteristic. Pure.
Register the GATT application with BlueZ (idempotent; runs off-loop).
Unregister the GATT application (idempotent).
Functions
@spec app_root() :: String.t()
Object path the Improv GATT application is rooted at.
Object path for a characteristic role, or nil if unknown.
The exported characteristics in tree order, each a map with :key, :path,
:uuid, and :flags. Pure.
Returns a specification to start this module under a supervisor.
See Supervisor.
Introspection XML for one exported object path. Pure.
Build the GetManagedObjects reply tree (a{oa{sa{sv}}} payload) from the
current values cache and notifying set. Pure.
@spec notify(GenServer.server(), atom(), binary()) :: :ok
Cache a new value for characteristic key and, if a client has subscribed,
push it as a GATT notification. Used for current-state, error-state and
rpc-result updates.
@spec props_for(String.t(), %{required(atom()) => binary()}, MapSet.t()) :: {String.t(), list()} | :unknown
Properties for the object at path: {interface, props_list} or :unknown.
Pure; used by Properties.GetAll/Get and the tree builder.
@spec read_value(String.t(), %{required(atom()) => binary()}) :: {:ok, [byte()]} | {:error, String.t()}
Read a characteristic value as a list of bytes (the ay body shape), or
{:error, bluez_error_name} for a non-readable / unknown characteristic. Pure.
@spec register(GenServer.server()) :: :ok
Register the GATT application with BlueZ (idempotent; runs off-loop).
@spec unregister(GenServer.server()) :: :ok
Unregister the GATT application (idempotent).