Front-end and Back-end development done within sight of each other
Hacking my Sonos
The previous project of controlling the lights in my living room with REST calls has given me an idea for a home automation project which will probably get written up here over a few more posts. Next step … controlling my sound system! As reverse-engineering practice, I decided to do this without documentation or Google.
My home stereo is hooked up to a Sonos CONNECT, which is an internet audio hub that aggregates all my various Pandora, Spotify and other streaming services. It’s awesome, and just like the Philips Hue lights it is controlled by desktop and mobile apps across your home WiFi network. Because I’m doing this without documentation, first step is to pull out Wireshark, a packet monitoring tool to see what’s going on in the TCP/IP traffic. With a Wireshark recording session active, I clear my Sonos queue, enqueue a playlist from Spotify, and then hit play.
Filtering the recording with the Sonos’ IP address we can see from the above screenshot that the Sonos is controlled with UPnP SOAP messages, so not that much more complicated than the REST and JSON I sent to the Philips Hue. Wireshark exports detailed packet extracts to an XML file type called PDML. I load that file into a text editor and take a look.
The payload of the data is HEX-ified. This makes sense given that the TCP/IP traffic could be binary. Knowing that all the SOAP data is most likely UTF-8 encoded, I’ll just write a quick XQuery to de-hexify the data.
Digging through a bunch of service calls to get album covers etc, there are three important SOAP calls that actually do the work I want to repeat.
SOAP is in general annoying in that the XML payload is actually passed as an escaped string rather than just embedded XML, making it confusing to read and parse. I believe this practice goes back to early XML web service processors doing a horrible job serializing and deserializing the XML just to proxy it around.
BOOM! (source code) I can now play Funk music from qconsole (I’ll spare you the Youtube video until the full project is done)