Layer 1 – 4
As the DJI Protocol – Packet Structure analysis is based on the DJI’s Wifi-Protocol, the first 42 bytes are related to Layer 1, 2, 3 and 4. As this is common knowledge and can be read up somewhere else, we won’t cover this section in detail. However, we do have some important bytes we would like to mention.
|0x17||8||Protocol Type – We are only interested in UDP packets. Hence, all received IP packets not equal to 0x11 aren’t important to us. It is worth mentioning as the drone and operator not only send UDP, but also ICMP packets.|
|0x1A – 0x33||64||IP-Addresses – Source and Destination IP-Address. The Wifi-Header does contain the sender and receiver as well, but we can already determine whether we deal with a drone or operator packet on layer 3.|
// this section is still work in progress
|0x00 – 0x01||16||Packet-Length – The size of the entire UDP Payload. ((0x01 & 0x0F) << 8) + 0x00|
|0x02 – 0x04||16||Session Identifier – Each time you connect your operator to the drone, a session identifier will be randomly chosen, which will be consistent throughout the entire flight. This theoretically enables to remote control several different drones on one ground station.|
|0x06||8||DUML-Type – The DUML’s content type. For more details see List. 2.|
The DUML-Head (DJI Universal Markup Language) is the start of a valid and processable packet between the drone and operator. The DUML format is consistent throughout several drones and communication protocols. (I.e.: Bluetooth, SDR or Wifi) There might be some minor differences between drones (E.g.: custom delimiters, specific command-sets, etc.) but the core and structure remains the same.
|0x00||8||Delimiter – Indicates the start of a DUML packet. This delimiter depends on the drone. E.g.: 0x55 for Mavic Pro 1, Phantom 3, Phantom 4 or 0xAB for Phantom 1, Phantom 2, Naza M,…|
|0x01 – 0x02||6||Protocol Version|
|0x01 – 0x02||10||Packet-Length – The length of the entire DUML packet; Payload-Header + Payload|
|0x03||8||CRC – Checksum covering 0x00 – 0x02 (See List. 4)|
Let’s imagine that the drone isn’t a unified piece of hardware. Instead, consider a collection of hardware pieces, all self-contained, with an option for intermediate component communication. This aspect exemplifies different source- and destination endpoints for a UDP packet. Thus, the DUML-Body contains all relevant information required to enable intermediate component communication.
|0x00||3||Sender Index – Source component index|
|0x00||5||Sender Type – Source component|
|0x01||3||Receiver Index – Destination component index|
|0x01||5||Receiver Type – Destination component|
|0x02 – 0x03||16||Sequence Counter – As UDP packets may arrive out-of-order, the Sequence Counter is a must have. The Sequence Counter will increment by 1 for each operator-to-drone packet, and for drone-to-operator packets a random value will be chosen to avoid duplicates.|
|0x04||1||Request Type – Either Request 0 or Response 1|
|0x04||3||Acknowledgement – NoAck 000, Before-Execution 010, After-Execution 100|
|0x04||4||Encryption – How the DUML-Tail is encrypted. There are several options available, but none of them will be used for the Wifi-Protocol, as the communication itself has already encryption (WPA2-PSK AES CCM) enabled.|
|0x05||8||Command-Set – The set the command belongs to|
|0x06||8||Command – The command within the Command-Set|
Last, but not least, the DUML-Tail; The DUML-Head and DUML-Body do contain meta-information only. Therefore, the actual command’s content is present within the DUML-Tail.
|0x00 – (n – 2)||n||Command Payload – Most commands carry a specific payload. E.g.: Altitude, Rotation, Velocity, etc. This payload depends on the Command-Set and Command. The length of the payload can be calculated with:|
x = DUML-Head[Packet-Length] n Bytes
a = DUML-Head-Size: 4 Bytes
b = DUML-Body-Size: 7 Bytes
c = DUML-Tail-Size: 2 Bytes
Payload-Length: x – (a + b + c) or in short: (0x01 – 0x02) & 0x3FF) – 13
|(n – 1) – n||16||CRC – Checksum covering DUML-Body and DUML-Tail (See List. 7)|