VSL Remote Protocol: Step 1

December 16th, 2012
music, sound, tech, vsl1818
I've been working on reverse engineering the protocol for the vsl1818 remote so I can build an android/web client. Here's what I've learned so far.

When you turn on the remote it starts broadcasting it's presence every few seconds over UDP broadcast from port 7071 to port 7071. One of these packets looks like:

  0000  ff ff ff ff ff ff c8 bc  c8 1a 9f 0a 08 00 45 00   ........ ......E.
  0010  00 a6 e1 b2 00 00 40 11  d6 e8 c0 a8 01 04 ff ff   ......@. ........
  0020  ff ff 1b 9f 1b 9f 00 92  86 48 11 00 55 aa 82 00   ........ .H..U...
  0030  00 00 00 00 00 00 00 00  00 00 0a 00 0a 00 52 69   ........ ......Ri
  0040  63 6b d5 73 20 69 50 61  64 00 00 00 00 00 00 00   ck.s iPa d.......
  0050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 43 38   ........ ......C8
  0060  3a 42 43 3a 43 38 3a 31  41 3a 39 46 3a 30 41 00   :BC:C8:1 A:9F:0A.
  0070  69 50 61 64 00 00 00 00  00 00 00 00 00 00 00 00   iPad.... ........
  0080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
  0090  41 42 31 38 31 38 2d 56  53 4c 00 00 00 00 00 00   AB1818-V SL......
  00a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
  00b0  00 00 00 00                                        ....
The data section starts with what seems to be a signature of this protocol: 0x110055aa. We can see the packet includes the name of the device (a slightly garbled "Rick's iPad"), the iPad's mac address, and the kind of host it knows how to talk to ("AB1818-VSL").

The host, VSL, sends out something similar, UDP broadcast from a high port (52740 in this case) to port 7070:

  0000  ff ff ff ff ff ff 10 40  f3 7e 15 6c 08 00 45 00   .......@ .~.l..E.
  0010  00 b6 ec 53 00 00 40 11  cc 2e c0 a8 01 0d ff ff   ...S..@. ........
  0020  ff ff ce 04 1b 9e 00 a2  90 02 11 00 55 aa 92 00   ........ ....U...
  0030  00 00 03 01 02 01 d2 04  00 00 01 00 0a 00 02 01   ........ ........
  0040  41 75 64 69 6f 42 6f 78  20 31 38 31 38 20 56 53   AudioBox  1818 VS
  0050  4c 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   L....... ........
  0060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
  0070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
  0080  31 39 32 2e 31 36 38 2e  31 2e 31 33 00 00 00 00   192.168. 1.13....
  0090  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
  00a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
  00b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
  00c0  00 00 00 00                                        ....
It reports its IP (192.168.1.13) and that it's an AudioBox 1818 VSL.

Once the remote notices that VSL is available, it opens a TCP connection to it on port 7069. When the connection is established it sends something like:

  0000  10 40 f3 7e 15 6c c8 bc  c8 1a 9f 0a 08 00 45 00   .@.~.l.. ......E.
  0010  00 88 d9 9b 40 00 40 06  dd 72 c0 a8 01 04 c0 a8   ....@.@. .r......
  0020  01 0d c8 db 1b 9d e4 04  4f 21 2f 53 72 11 80 18   ........ O!/Sr...
  0030  20 2b 68 6c 00 00 01 01  08 0a a4 fe b6 6f 25 a1    +hl.... .....o%.
  0040  41 7f 11 00 55 aa 4c 00  00 00 03 01 02 01 d2 04   A...U.L. ........
  0050  00 00 03 00 0a 00 43 38  3a 42 43 3a 43 38 3a 31   ......C8 :BC:C8:1
  0060  41 3a 39 46 3a 30 41 00  00 00 00 00 00 00 00 00   A:9F:0A. ........
  0070  00 00 00 00 00 00 41 42  31 38 31 38 2d 56 53 4c   ......AB 1818-VSL
  0080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
  0090  00 00 00 00 00 00                                  ......
Again the data section starts with the protocol signature: 0x110055aa. It seems to have the same info it already sent the server (VSL) over UDP, though this time without the name of the iPad.

Then VSL starts sending out a stream of data. I suspect it's first getting the remote caught up, then sending keep-alives and updates. The stream format is:

  [signature] [message length] [message data]
The signature is always [1] 0x110055aa. The message length is a four-byte little endian (least significant byte first) unsigned integer. If you look at the packets above and ignore the headers, you can see they all follow this pattern. For example, the initial TCP packet from the remote to the VSL starts with 0x110055aa, then has 0x4c000000 (which is 76), and then 76 bytes of message before the end of the packet.

The data section of a message always starts with 0x03010201d2040000 (a version number?), followed by a byte that indicates what category the message is. Ones I've seen so far:

2 Status update.
3 The initial connection packet the remote sends to VSL.
4 Some sort of listing of inputs and outputs.
5 Keepalive packet, indicating that nothing has changed.
Each of these message categories has its own format.

Status update

First there's a byte I don't understand that usually increases over successive messages. Examples, taken from a random series of messages:
184 1 186 189 190 191 192 193 194 197 198 15 16 17 18 205 206 208 209 214 216 217 218 219 220 221 222 225 236 237 54 239 240 241 242 60 61 62 247
Then there's a byte that's usually 0x0b but is sometimes 0x0c or 0x00.

Update 2012-12-18: I think these two bytes indicate the control in question. For example, 'bd 0b' is 'aux3' while 'bf 0b' is aux5.

Then there's four bytes that I think might represent a value of a setting, the real content of the message.

Then there's a byte that is 0x00 when the previous four bytes are also all null, and either 0x3e or, usually, 0x3f when those four were set.

Update 2012-12-19: Actually, there are eight bytes after the two for the control. They are the value of the control, as a double.

Following this are up to 10 bytes of ascii text naming a channel. If the name is too short then it's padded with nulls at the end.

After the channel there's a trailer that's always one of:

  0x80e1bf5fff7f00006e2a09000100000070e1bf5fff7f
  0xa0debf5fff7f00001746040001000000e0dfbf5fff7f
  0xc1c70c7ee5d19271000000000000f03f000000c06ddb

I think in messages sent from the remote to VSL it's all nulls, but I need to check.

Update 2012-12-20: I think this trailer is actually junk, and is just whatever happened to get shoved into the fixed length string after the null byte.

Initial Connection

The remote sends its MAC address and the kind of VSL it knows how to talk to. For now I've just been replaying a captured byte sequence, so I don't know if I fully understand it until I see what it does with bytes I generate.

Input/Output Listing

These have two bytes of nulls and then a two byte integer input code. Then 10 bytes of channel-naming ascii (like in status updates) and 38 bytes of nulls.

Keepalive

These ones are easy: 128 bytes of all nulls.

Update 2012-12-22: Actually, I think these are the current levels. One unsigned byte each, 0-255. The first eight are the first eight input channels.


Next step: manipulate VSL on the laptop and figure out what signals mean what.

Update 2012-12-21: I finished.


[1] When I say "always" I mean "always in the data I've dumped so far".

Comment via: google plus, facebook

Recent posts on blogs I like:

Development RCTs Are Good Actually

In defense of trying things out

via Thing of Things March 25, 2024

Clarendon Postmortem

I posted a postmortem of a community I worked to help build, Clarendon, in Cambridge MA, over at Supernuclear.

via Home March 19, 2024

How web bloat impacts users with slow devices

In 2017, we looked at how web bloat affects users with slow connections. Even in the U.S., many users didn't have broadband speeds, making much of the web difficult to use. It's still the case that many users don't have broadband speeds, both …

via Posts on March 16, 2024

more     (via openring)