Checks / tests (ubuntu-latest, 3.11) (push) Canceled after 0s
Checks / tests (ubuntu-latest, 3.14) (push) Canceled after 0s
Checks / tests (windows-latest, 3.11) (push) Canceled after 0s
Checks / tests (windows-latest, 3.14) (push) Canceled after 0s
Checks / package (push) Canceled after 0s
108 lines
4.7 KiB
Markdown
108 lines
4.7 KiB
Markdown
# Samsung control protocol notes
|
||
|
||
These original interoperability notes describe observations from an MX-T40 and
|
||
analysis of the Android Sound Tower app version 0.0.80. Vendor application code
|
||
and firmware are not included. The working desktop transport is BLE; the iOS
|
||
app's internal transport/framework has not been established.
|
||
|
||
## BLE endpoints
|
||
|
||
| Role | UUID |
|
||
| --- | --- |
|
||
| Samsung service | `0000ffa0-0000-1000-8000-00805f9b34fb` |
|
||
| Write, with response | `0000ffa1-0000-1000-8000-00805f9b34fb` |
|
||
| Notify | `0000ffa2-0000-1000-8000-00805f9b34fb` |
|
||
|
||
Subscribe before sending the connection request. Commands currently exposed by
|
||
the GUI fit within 20 bytes; no larger-command fragmentation scheme is claimed.
|
||
The speaker also exposes a separate Qualcomm service with UUID
|
||
`00001100-d102-11e1-9b23-00025b00a5a5`, which this controller does not use.
|
||
|
||
MX-T40 model advertisements include FE40/FF40; the Android discovery code also
|
||
maps FE41/FF41 to T40 names. An advertisement UUID identifies discovery, not
|
||
necessarily a writable control service.
|
||
|
||
## Framing
|
||
|
||
```text
|
||
00 BB TYPE SEQUENCE LENGTH_HI LENGTH_LO PAYLOAD... CHECKSUM
|
||
```
|
||
|
||
Type 0 is an acknowledgment; type 1 carries data. Length counts payload bytes
|
||
only, in big-endian order. Outgoing sequence numbers cycle 1–127, matching the
|
||
Android app's signed-byte rollover. Incoming notifications use a separate
|
||
sequence counter, observed above 127 as well.
|
||
|
||
Outgoing checksums sum type, sequence, both length bytes, and payload, modulo
|
||
256. Incoming packets have several observed checksum variants:
|
||
|
||
- Connection/source reports: sum excluding type.
|
||
- Sound reports: sum including type.
|
||
- Lighting reports `51 03 MODE`: captured packets match a checksum calculated
|
||
as though MODE were 1, across Ambient/Dance/Star/Lover/Off observations.
|
||
- Play/pause echoes `70 11`: the two captured replies similarly match a key
|
||
slot of 1. This compatibility rule is scoped to that specific payload.
|
||
|
||
Why the firmware emits these variants is unknown. Strict decoding recognizes
|
||
these observed rules. BLE uses advisory mode, retaining structurally framed
|
||
packets with unfamiliar checksums and flagging them in the activity log. This
|
||
is compatibility behavior, not a cryptographic integrity guarantee.
|
||
|
||
## Handshake
|
||
|
||
1. Send payload `01`.
|
||
2. Receive ACK and connection information beginning `02`.
|
||
3. Send payload `04` (link complete).
|
||
4. Receive the ACK matching that outgoing sequence; only then enable controls.
|
||
5. Query source (`32`) and EQ (`42 03`).
|
||
|
||
The captured connection info contains model byte `34` and source IDs
|
||
`01 02 04 05`: Bluetooth, USB 1, AUX 1, AUX 2. The two bytes following the initial
|
||
`02` are interpreted by the Android app as protocol version.
|
||
|
||
## Payloads
|
||
|
||
Numbers below are hexadecimal unless explicitly called decimal.
|
||
|
||
| Action | Payload |
|
||
| --- | --- |
|
||
| Remote key | `70 KEY` |
|
||
| Select source | `30 SOURCE` |
|
||
| Query source | `32` |
|
||
| Set sound option | `40 TYPE OPTION VALUE EXTRA` |
|
||
| Query sound option | `42 TYPE` |
|
||
| Set system option | `50 TYPE VALUE` |
|
||
| Query system option | `52 TYPE` |
|
||
| Set RGB color | `60 02 RED GREEN BLUE` |
|
||
|
||
Sound TYPE: volume=1, subwoofer=2, EQ=3, bass=4, DJ=5, tempo=6, mute=7.
|
||
For the implemented EQ/bass controls OPTION and EXTRA are zero.
|
||
Sound replies use `41 TYPE VALUE VALUE2`, a different layout from writes.
|
||
|
||
EQ values (decimal): Party=1, Standard=2, Hip-hop=3, EDM=4, Rock=5, Latin=6,
|
||
House=7, Reggae=8. Bass values: on=0, off=1. Mute reports: on=1, off=2.
|
||
|
||
System TYPE=3 controls lighting. Mode values (decimal): Off=0, Ambient=1,
|
||
Party=2, Dance=3, Thunder=4, Star=5, Lover=6, Color=7. Reply: `51 03 MODE`.
|
||
The speaker displays COLOR when the owner chooses an RGB color. The desktop
|
||
queries lighting mode after RGB writes rather than treating ACK as mode proof.
|
||
|
||
Remote keys: volume up=`0F`, volume down=`10`, play/pause=`11`, mute=`14`.
|
||
A reply `70 11` is a button-event echo, not an absolute playing/paused state.
|
||
|
||
## Additional app commands, untested here
|
||
|
||
The app defines grouping `05 TYPE CONTROL`, USB playback/browsing/status and
|
||
repeat controls, DJ selection/levels, tempo, and Bluetooth multi-connect state.
|
||
See FEATURES.md for the distinction between discovered and verified behavior.
|
||
Do not infer arbitrary EQ-band access from the firmware configuration schema.
|
||
|
||
## Evidence and limits
|
||
|
||
Tests contain small, independently captured packet fixtures: connection info,
|
||
ACKs, source/EQ replies, lighting checksum variants, and play/pause echoes. Real
|
||
Bluetooth addresses are replaced with synthetic ones. Physical verification
|
||
covers one MX-T40 on Windows; other models, firmware versions, and platforms
|
||
remain unverified. RFCOMM channel 1 worked initially but later failed repeatedly;
|
||
no general explanation or guaranteed workaround has been established.
|