Yamaha YAS-207's Bluetooth protocol: basic recon
As explained in the Introductory post, I’m reversing the control interfaces of the Yamaha YAS-207 soundbar.
In this installment I’m doing a basic recon of the Bluetooth part.
And as before with the infrared protocol, my plans were thwarted by reality. If you don’t care about the journey, maybe skip to the next post when it’s available. Or maybe just to the Closing words section.
Figure out the bluetooth protocol used in YAS-207 soundbar’s remote app, the “Home Theater Controller”. Because I want to drive the soundbar from a raspi.
Sniff me some Bluetooth LE… or not
Having an Adafruit’s Bluefruit LE Sniffer1 I thought this part might be easy.
Only to find out that no, YAS-207 doesn’t support BLE. It speaks Bluetooth classic.
I guess reading the Specs page a little bit more carefully would help me avoid this blunder.
Because on the manufacturer’s website it not-so-clearly says:
(Version) Ver. 4.1 + EDR
(Profile) A2DP, SPP
(Audio Codec) SBC, MPEG AAC
It is my fault for interpreting it as BLE and/or Classic.
Moving on, we’ll have to do this some other way.
Now, since sniffing Bluetooth Classic is hard2, this situation got a lot more interesting.
OK, so that was a fail. Let’s at least see what protocols the device speaks:
# hcitool scan Scanning ... C8:84:xx:xx:xx:xx YAS-207 Yamaha # hcitool info C8:84:xx:xx:xx:xx Requesting information ... BD Address: C8:84:xx:xx:xx:xx Device Name: YAS-207 Yamaha LMP Version: 4.2 (0x8) LMP Subversion: 0x30e7 Manufacturer: Cambridge Silicon Radio (10) Features page 0: 0xff 0xff 0x8f 0xfe 0xdb 0xff 0x5b 0x87 <3-slot packets> <5-slot packets> <encryption> <slot offset> <timing accuracy> <role switch> <hold mode> <sniff mode> <park state> <RSSI> <channel quality> <SCO link> <HV2 packets> <HV3 packets> <u-law log> <A-law log> <CVSD> <paging scheme> <power control> <transparent SCO> <broadcast encrypt> <EDR ACL 2 Mbps> <EDR ACL 3 Mbps> <enhanced iscan> <interlaced iscan> <interlaced pscan> <inquiry with RSSI> <extended SCO> <EV4 packets> <EV5 packets> <AFH cap. slave> <AFH class. slave> <LE support> <3-slot EDR ACL> <5-slot EDR ACL> <sniff subrating> <pause encryption> <AFH cap. master> <AFH class. master> <EDR eSCO 2 Mbps> <EDR eSCO 3 Mbps> <3-slot EDR eSCO> <extended inquiry> <LE and BR/EDR> <simple pairing> <encapsulated PDU> <non-flush flag> <LSTO> <inquiry TX power> <EPC> <extended features> Features page 1: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 Features page 2: 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00
So that doesn’t tell me much (not exactly Bluetooth expert, me).
Let’s pair with it and then begin interrogation:
# bluetoothctl pair C8:84:xx:xx:xx:xx Attempting to pair with C8:84:xx:xx:xx:xx [CHG] Device C8:84:xx:xx:xx:xx Connected: yes [CHG] Device C8:84:xx:xx:xx:xx UUIDs: 00000000-deca-fade-deca-deafdecacaff [CHG] Device C8:84:xx:xx:xx:xx UUIDs: 00001000-d102-11e1-9b23-00025b00a5a5 [CHG] Device C8:84:xx:xx:xx:xx UUIDs: 00001101-0000-1000-8000-00805f9b34fb [CHG] Device C8:84:xx:xx:xx:xx UUIDs: 0000110b-0000-1000-8000-00805f9b34fb [CHG] Device C8:84:xx:xx:xx:xx UUIDs: 00001200-0000-1000-8000-00805f9b34fb [CHG] Device C8:84:xx:xx:xx:xx ServicesResolved: yes [CHG] Device C8:84:xx:xx:xx:xx Paired: yes Pairing successful # bluetoothctl info C8:84:xx:xx:xx:xx Device C8:84:xx:xx:xx:xx (public) Name: YAS-207 Yamaha Alias: YAS-207 Yamaha Class: 0x00240428 Icon: audio-card Paired: yes Trusted: yes Blocked: no Connected: no LegacyPairing: no UUID: Vendor specific (00000000-deca-fade-deca-deafdecacaff) UUID: Vendor specific (00001000-d102-11e1-9b23-00025b00a5a5) UUID: Serial Port (00001101-0000-1000-8000-00805f9b34fb) UUID: Audio Sink (0000110b-0000-1000-8000-00805f9b34fb) UUID: PnP Information (00001200-0000-1000-8000-00805f9b34fb)
Now we’re getting somewhere. They weren’t kidding about the serial port
SPP_UUID) and Audio Sink (
But there are multiple other services:
00000000-deca-fade-deca-deafdecacaff= Apple accessory, needed to be auto-recognized by iOS3
00001200-0000-1000-8000-00805f9b34fb= Plug-and-Pray, to have it auto-recognized by others
Let’s dig further:
# sdptool records C8:84:xx:xx:xx:xx Service RecHandle: 0x10000 Service Class ID List: "Audio Sink" (0x110b) Protocol Descriptor List: "L2CAP" (0x0100) PSM: 25 "AVDTP" (0x0019) uint16: 0x0103 Profile Descriptor List: "Advanced Audio" (0x110d) Version: 0x0103 Service RecHandle: 0x10001 Service Class ID List: "PnP Information" (0x1200) Service Name: SUBWOOFER Service Description: Wireless Subwoofer Service Provider: CSR Service RecHandle: 0x10002 Service Class ID List: UUID 128: 00001000-d102-11e1-9b23-00025b00a5a5 Protocol Descriptor List: "L2CAP" (0x0100) PSM: 32769 Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Service Name: Wireless iAP Service RecHandle: 0x10004 Service Class ID List: UUID 128: 00000000-deca-fade-deca-deafdecacaff Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 14 Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Service Name: SPP Dev Service RecHandle: 0x10006 Service Class ID List: "Serial Port" (0x1101) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 1 Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "Serial Port" (0x1101) Version: 0x0102
OK, so the
00001000-d102-11e1-9b23-00025b00a5a5 is a service to support the
wireless subwoofer. Makes sense.
There’s bunch more info to be had using
sdptool records --tree C8:84:xx:xx:xx:xx
but the output is rather long, and mostly boring, so I’ll skip it.
In any case, given the protocols exported, I’m betting that the remote control is done using the serial port.
But to get at it, I’ll have to get the communication dump elsewhere.
Second try: Let’s sniff it using Android
Fortunately, YAS-207 comes not only with an iOS app, but also with an Android app. And even though I’m nearly an Android virgin4 —
Little searching around the ’Net will score you an
*.apk (application archive)
of the “Home Theater Controller” in a jiffy. Wow. Such an (apk)pure experience.
Thus one download of
android-x86_64-7.1-r5.iso later, my VirtualBox was humming
happily with fresh Android 7.1.26, connected to the
VirtWifi wifi :-).
In order to sniff Bluetooth, you become a developer7, and in the “Developer options” enable:
- “Stay awake”
- “Enable Bluetooth HCI snoop log”
- “USB debugging”
and optionally disable “Verify apps over USB”.
And now the fun starts.
On my desktop, it pretty much went thusly:
$ adb connect 22.214.171.124 $ adb install the_home_controller.apk
Then I had the HT Controller app talk to the YAS-207. Successfully, I might add.
But now the question is – where do I get the promised log of all Bluetooth
Turns out, on newer(?) androids the location is mentioned in
$ adb shell grep BtSnoopFileName /etc/bluetooth/bt_stack.conf BtSnoopFileName=/data/misc/bluetooth/logs/btsnoop_hci.log
$ adb shell su -c "'cat /data/misc/bluetooth/logs/btsnoop_hci.log'" > btsnoop_hci.log $ file btsnoop_hci.log btsnoop_hci.log: BTSnoop version 1, HCI UART (H4)
So, yay! We can sniff. And wireshark reads that file natively
In this somewhat lengthy piece8 I’ve done basic recon of the Bluetooth properties of the Yamaha YAS-207 soundbar, as well as some prep work for sniffing the traffic.
Findings so far:
- YAS-207 speaks Bluetooth Classic, not Bluetooth LE.
- The protocol is probably through Serial-over-Bluetooth (SPP), on channel 1.9
- I can dump (sniff) the communication log from Android in
BTSnoop version 1, HCI UART (H4)format.
But I dislike the manualness of this process:
- I would like streaming solution, not one-off done by downloading a file.
- I need to find a way to parse the HCI log somehow.
More on that in next installment(s), watch the yas 207 tag.
I don’t have the hardware; donations of “Ubertooth One” are welcome. :-) ↩
Surprisingly (as you’ll find out below), this is another Serial-over-BT protocol, but we don’t care about it. From what I was able to gather, the communication is guarded by a crypto chip – to separate the deep-pocketed royalty from the plebs. ↩
Never owned an Android phone. Also aside from brief stint with Android Wear never used it much. ↩
I bet you did not expect that punchline. ↩
Build numberbunch of times in
About tablet. ↩
I blame the debug outputs. It for sure can’t be my blundering around due to sheer lack of qualification. ↩
Forgot to mention – had a brief looksie at the BT specs and the A2DP sink isn’t capable of remote control; there’s a different protocol for that. So either it’s the SPP, or Yamaha went the Microsoft way and extended existing protocol with a proprietary addon. Hope it’s the former. ↩