CDJ HID Protocol
Background
Historically, DJ controllers (meaning hardware whose purpose is to communicate with digital DJ Software) have been using MIDI over USB. With increasing complexity, the protocol became a bottleneck for certain applications, causing Hardware-manufacturers to start transmitting data via HID. This allows for comparatively simple mechanisms such as simply serializing the status of controls on the controller into a buffer of fixed format but also creating complex proprietary binary protocols involving data fragmented over multiple HID packets, handshakes, variable-length data, etc.
The PioneerDJ CDJ-2000NXS2 has many different ways to communicate with other devices such as other CDJs or Mixers. One if these methods is using a custom Network Protocol called ProDJLink whose reverse engineering efforts have inspired this project as well.
Protocol primitives
Simple header
Every Packet being sent and received to and from the CDJs shares this common header:
The first byte "deck" uses the more significant nibble to indicate the source/destination deck. It uses 0 for controllers which only have/represent a single deck such as a CDJ and 1-based deck numbers for controllers with multiple decks such as the XDJ-XZ. The "type" byte indicates the type of message being transmitted. This format limits the maximum amount of data transmitted to 62 Bytes which is not sufficient for transmitting larger strings or other binary data such as images. For these purposes, the protocol uses an extended header
Extended Header
Packets with an extended header are able to transmit Bytes (~3.8MB) of data.
L
denotes the number of packets the data following
takes up while I
indicates the index of the packet fragment in the current stream.
Both ushorts encoded in little-endian byte order.
TLV Structure
Some parts of the Protocol utilize a TLV structure:
These TLV structures can occur nested (for example in the handshakes TODO hyperlink)
It seems T
only indirectly describes the actual type of data in the buffer. Instead T
indicates what the data is actually used for, which in turn describes the actual
type of the data.
Thanks
An enormous thanks to James Elliot (@brunchboy) from Deep Symmetry for not only creating bytefield-svg which allowed me to create these awesome bytefield diagrams but also for all of his previous research into the ProDJLink Protocol as well as helping me in the setup of this wiki, using bytefield-svg and supplying me with some USB-Captures of the XDJ-XZ. Also thanks to Ard van Breemen for helping out with his in-depth knowledge of the USB protocol. In addition I also want to thank František Kučera for using my research in his effort to bring Linux Support to the DJM-250MK2 and correcting me in his blogpost.