blob: 5cc89514b58440ffb9451e6475c33ef1896f3ad0 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# mmx150d
Connection monitoring for the beyerdynamic MMX 150 wireless headset dongle.
The daemon watches the headset link state over the dongle's vendor HID
interface and runs shell commands when the headset connects or disconnects.
Typical use: switch the default audio sink between the headset and monitor
speakers as the headset powers on and off.
## Usage
mmx150d status
Prints `connected` or `disconnected`. Exit codes: 0 connected, 1
disconnected, 2 dongle missing or error.
mmx150d daemon [--on-connect CMD] [--on-disconnect CMD] [--interval SECS] [--no-initial]
Hooks run via `sh -c` with output discarded. At startup the daemon fires the
hook matching the current state, unless `--no-initial` is given.
Example, switching the default sink with PipeWire:
mmx150d daemon \
--on-connect 'wpctl set-default <mmx150-sink-id>' \
--on-disconnect 'wpctl set-default <speakers-sink-id>'
Find sink ids with `wpctl status`.
## How it works
The dongle exposes a vendor HID interface (`2e50:0035`). Writing the 61-byte
output report `0x3a` (payload prefix `09 22 01`) makes the dongle answer with
an input report `0x3c`, but only when the headset is linked. A query with no
response within 400 ms therefore means the headset is off or out of range.
The daemon polls this once per interval (default 2 s). A disconnect needs two
consecutive missed polls, so a single dropped radio packet does not cause a
bogus state change.
## Building
Development uses devenv:
devenv shell cargo build
devenv shell cargo test
The binaries land at `target/debug/mmx150d` (status and daemon) and
`target/debug/mmx150-probe` (protocol reverse-engineering tool).
|