Mixer and CDJ Startup

Mixer Startup

When the mixer starts up, after it obtains an IP address (or gives up on doing that and self-assigns an address), it sends out what look like a series of packets[1] simply announcing its existence to UDP port 50000 on the broadcast address of the local network.

Numbers in this document

Values within packets, packet lengths, and byte offsets are all shown in hexadecimal in code font. Other numbers are in normal body text font and are decimal.

These have a data length of 25 bytes, appear roughly every 300 milliseconds, and have the following content:

0123456789abcdef5173707431576d4a4f4c0a000010Device Name (padded with 00)200102lenp02
Initial announcement packets from mixer.

Byte 0a (inside the green header section) is shown in bold because its value changes in the different types of packets that devices send, and can be used to tell them apart.

The byte following the device name (at byte 20) seems to always have the value 1 in every kind of packet seen. The next byte is in bold as well because it seems to indicate the structure of the remainder of the packet. The value 02 is followed by a two-byte value lenp that indicates the length of the entire packet (including the preceding header bytes), and followed by the payload. In the case of this kind of packet, the length is 0025, and the payload is the single-byte value 02.

After about three of these packets are sent, another series of three begins. It is not clear what purpose these packets serve, because they are not yet asserting ownership of any device number; perhaps they are used when CDJs are powering up as part of the mechanism the mixer can use to tell them which device number to use based on which network port they are connected to?

In any case, these three packets have the value 00 at byte 0a, a data length of 2c bytes (reflected in lenp), are again sent to UDP port 50000 on the local network broadcast address, at roughly 300 millisecond intervals, and have the following content:

0123456789abcdef5173707431576d4a4f4c00000010Device Name (padded with 00)200102lenpN02MAC address
First-stage mixer device number claim packets.

The value N at byte 24 is 01, 02, or 03, depending on whether this is the first, second, or third time the packet is sent.

After these comes another series of three numbered packets. These appear to be claiming the device number for a particular device, as well as announcing the IP address at which it can be found. They have a data length and lenp value of 32 bytes, and are again sent to UDP port 50000 on the local network broadcast address, at roughly 300 millisecond intervals, with the following content:

0123456789abcdef5173707431576d4a4f4c02000010Device Name (padded with 00)200102lenpIP addressMAC addressDN300201
Second-stage mixer device number claim packets.

I identify these as claiming/identifying the device number because the value D at byte 2e is the same as the device number that the mixer uses to identify itself (21) and the same is true for the corresponding packets seen from my CDJs (they use device numbers 02 and 03, as they are connected to those ports/channels on the mixer).

As with the previous series of three packets, the value N at byte 2f takes on the values 01, 02, and 03 in the three packets.

These are followed by another three packets, perhaps the last stage of claiming the device number, again at 300 millisecond intervals, to the same port 50000. These shorter packets have 2a bytes of data and the content shown here:

0123456789abcdef5173707431576d4a4f4c04000010Device Name (padded with 00)200102lenpDN
Final-stage mixer device number claim packets.

As before the value D at byte 24 is the same as the device number that the mixer uses to identify itself (21) and N at byte 25 takes on the values 01, 02, and 03 in the three packets.

Once those are sent, the mixer seems to settle down and send what looks like a keep-alive packet to retain presence on the network and ownership of its device number, at a less frequent interval. These packets are 36 bytes long, again sent to port 50000 on the local network broadcast address, roughly every second and a half. They have the following content:

0123456789abcdef5173707431576d4a4f4c06000010Device Name (padded with 00)200102lenpD02MAC addressIP address30010000000200
Mixer keep-alive packets.

CDJ Startup

When a CDJ starts up, there are a variety of different paths that can be followed, depending on two different variables:

  • Is the player configured to try to automatically assign its channel number, or to attempt to claim a specific channel?

  • Is the player plugged into a channel-specific Ethernet port on a DJM-2000, or is it on a regular network port?

However, regardless of these details, the initial series of three packets sent are always the same. They are nearly identical to the ones used by the mixer, and broadcast at 300 millisecond intervals as well. The only difference between the figure below and the mixer version is the final byte, which is 01 for the CDJ, and was 02 for the mixer.

0123456789abcdef5173707431576d4a4f4c0a000010Device Name (padded with 00)200102lenp01
Initial announcement packets from CDJ.

Startup in a Generic Port

When not connected to a port that is specifically assigned a mixer channel, the process continues much as was seen for the Mixer startup. The next series of three messages, broadcast to port 50000 at 300 millisecond intervals, are again nearly identical to those from the mixer. The only difference between the following figure and the mixer version is byte 25 (immediately after the packet counter N), which again is 01 for the CDJ, and was 02 for the mixer.

0123456789abcdef5173707431576d4a4f4c00000010Device Name (padded with 00)200102lenpN01MAC address
First-stage CDJ device number claim packets.

Three hundred milliseconds after sending the third such packet with N set to 03, the player moves on to trying to claim an unused device number D. It’s not clear how it picks one, although by this time it has had plenty of time to observe the network to see what other channels are claimed by other devices, and it seems to prefer staying on the same channel that it was using the last time it was powered on as long as that is not currently in use.

It uses packets again nearly identical to the ones the mixer used to claim its device number, broadcast at 300 millisecond intervals on port 50000, but it turns out the value of byte 31 has a meaning we didn’t appreciate until now: It has the value 01 when the CDJ is trying to auto-assign a device number, 02 when it it is trying to claim a specific number. We label this value a for “auto-assign”:

0123456789abcdef5173707431576d4a4f4c02000010Device Name (padded with 00)200102lenpIP addressMAC addressDN3001a
Second-stage CDJ device number claim packets.

After sending the third such packet, with N set to 03, the player moves to the final stage of claiming its device number D, broadcasting packets at 300 millisecond intervals on port 50000, and this series is completely identical to the ones the mixer used:

0123456789abcdef5173707431576d4a4f4c04000010Device Name (padded with 00)200102lenpDN
Final-stage CDJ device number claim packets.
When the CDJ is configured to use a specific device number, it sends only one packet in this series, and then moves on to the next stage. When set to auto-assign, it sends all three like the mixer did.

And just like the mixer, after sending the final such packet, the CDJ is done starting up, and settles down to broadcasting keep-alive packets on port 50000 at a less frequent interval:

0123456789abcdef5173707431576d4a4f4c06000010Device Name (padded with 00)200102lenpD01MAC addressIP address30010000000100
CDJ keep-alive packets.

As seems to usually be the case when comparing mixer and CDJ packets sent to port 50000, the difference between this and the mixer version is that byte 25 (following the device number D) has the value 01 rather than 02, and the same is true of the second-to-last byte in each of the packets. (Byte 34 is 01 here and and 02 in the mixer version.)

Startup in a Channel-Specific Port

When connected to an Ethernet port that belongs to a specific mixer channel, the mixer will inform the player what channel it is supposed to use. Even if the player is configured to try to use a specific channel number, the mixer overrides this and the player accepts the device number assigned by the mixer.

After broadcasting the three initial announcement packets, the CDJ broadcasts the first of its first stage device number claim packets as usual. But this process is immediately pre-empted by the mixer sending a 2f-byte packet directly to port 50000 on that player, telling the player that the mixer is going to assign it a device number:

0123456789abcdef5173707431576d4a4f4c01000010Device Name (padded with 00)200102lenpIP addressMAC address01
Mixer device number assignment intention packet.

(As always, the device name and IP and MAC addresses in this packet are those of the device that sends it, in this case the mixer.)

Immediately upon receipt of this packet, the CDJ responds by sending a 32-byte packet directly to port 50000 on the mixer acknowledging that it is ready to be assigned a device number. This packet is a slight variation on the normal second stage device number claim packet: in addition to being sent directly to the mixer rather than being broadcast, it has a value of 01 instead of 00 at byte 0b immediately after the packet type. It also reports a value of 00 for D at byte 2e:

0123456789abcdef5173707431576d4a4f4c02010010Device Name (padded with 00)200102lenpIP addressMAC address00N3001a
CDJ device number request packet.

This packet does contain an a value indicating whether or not the player is trying to auto-assign a device number, but that has no effect. Regardless of the value of a, the mixer immediately responds to this packet by telling the CDJ what channel number (D) it is plugged into by sending a 27-byte packet directly to port 50000 on the player:

0123456789abcdef5173707431576d4a4f4c03010010Device Name (padded with 00)200102lenpDN00
CDJ device number assignment packet.

Notice that once again the byte immediately after the packet type, byte 0b, has the value 01 rather than the 00 that we normaly see.

At this point the player accepts the device number assigned by D in the above packet, and broadcasts a single final-stage claim packet to inform the other players of this assignment, with N set to 01.

Perhaps in response to this broadcast, the mixer sends one last 26-byte packet directly to port 50000 on the CDJ:

0123456789abcdef5173707431576d4a4f4c05000010Device Name (padded with 00)200102lenpD01
CDJ device number assignment finished packet.

In this packet, the D value is the mixer’s own device number, 21.

At this point, rather than sending the remainder of the series of final stage claim packets, the CDJ immediately transitions to broadcasting keep-alive packets.

Channel Conflicts

When a player tries to lay claim to a device number that is already in use by another player, the existing player defends its channel by sending a 29-byte packet like this one to port 50000 on the new player:

0123456789abcdef5173707431576d4a4f4c08000010Device Name (padded with 00)200102lenpDIP address
Channel conflict packet.

When a player receives such a packet it gives up on trying to claim channel D.

XDJ-XZ Limitations

When an XDJ-XZ is acting as the mixer, this protocol mostly works as described above, as long as you connect to one of its ports assigned to Channel 3 or Channel 4. However, it does not send the “assignment finished” packet which short-circuits the final stage claim packet series.

More fundamentally, there seems to have been no effort made to properly support devices which plug into the network anywhere else, and thus reach the XDJ-XZ via the laptop/network port. When connected to that port, regardless of what device number the player is trying to claim, the XDJ-XZ will send it an “assignment intention” packet telling it to go ahead and use that number, even if the number was zero. Even worse, it does that even if the number was 1 or 2, which the XDJ-XZ is already using for its two decks. Further, it will not even send channel conflict packets to attempt to defend its own device numbers, so implementations that don’t watch carefully for devices using particular numbers before claiming them can end up in a bad state when plugged into the laptop port.

Even actual Pioneer hardware has issues picking device numbers when plugged into the laptop port, though, so this is clearly not a situation that was envisioned or supported.


1. The packet capture used for the first version of this analysis can be found at https://github.com/deep-symmetry/dysentery/raw/master/doc/assets/powerup.pcapng