How to extract the interrogator ID from a DF11 message? I've written a class which decodes raw Mode S messages.  Whilst browsing the ICAO specs the other day I noticed that the Interrogator ID is sent back in the DF11 message.

I thought that it would be a fun exercise to determine where in my coverage area interrogations from particular radar installations can be seen.

But I'm having a really hard time figuring out how to extract the interrogator ID.

For this DF11 message:

5D406FDB0D62DD

I've got the following:

Binary: 01011101010000000110111111011011000011010110001011011101
Integer Words:
    [0] =&gt; 93
    [1] =&gt; 64
    [2] =&gt; 111
    [3] =&gt; 219
    [4] =&gt; 13
    [5] =&gt; 98
    [6] =&gt; 221

 CA: 5
 AA: 4222939
 Address: 406FDB
 Parity: 255
 Residual: 0


As the Residual value is 0 I know that this is a valid DF11 message and the address checks out as well.

From the ICAO spec:

"The code used in downlink PI field generation shall be formed by a sequence of 24 bits (a1, a2,..., a24), where the first 17 bits are ZEROs, the next three bits are a replica of the code label (CL) field (3.1.2.5.2.1.3) and the last four bits are a replica of the interrogator code (IC) field (3.1.2.5.2.1.2)."

In that case I would expect the end of the last three integer words (4,5 and 6) to be mostly 0's but they aren't.

I've gone through the documentation numerous times but just can't see how to get the II and SL codes out of Parity value ?

I'm calculating the Parity value by doing the following:

$this-&gt;_pi = $this-&gt;_int[4] | $this-&gt;_int[5] | $this-&gt;_int[6];


where | in PHP is the OR operator.  Is this my mistake ?
Your calculation of $this-&gt;_pi just ORs the three parity bytes together, 
which certainly doesn't make any sense.  I'm not sure what you hope to get out of that. Even XORing them together wouldn't seem to serve any purpose.



Addressing and checksumming in the Mode S protocol work in a funky way, in order to save bits. The last 3 bytes of a message are constructed as a CRC checksum (which Annex 10 calls "parity") of the first 4/11 bytes, XORed with an address for the "conversation" the message is part of. When you receive a message you're supposed to calculate the raw CRC on your own and then XOR it out of the bytes. What is left is the address, and by comparing it to addresses you're interested in you can see if the message was for you, or alternatively either garbled or for someone else.

In the basic Mode S interrogation protocol, this "address" is just the airframe address, and the checksum-xor-address field is named AP.  For uplink messages, transponders know what their own address are, of course -- and for downlink, radars know which addresses they have interrogated recently.

In a few other cases, the "address" is the "interrogator identifier", and the checksum-xor-address field is named PI.

For DF11, the transponder knows which II to put into its replies because it gets them out of the all-call message, and the radar knows which II corresponds to its own all-calls, so it can recognize those responses.

Finally, in squitter where the transponder sends a downlink message without being prompted by an uplink message, it sets the "address" to 0.



If you have been decoding ADS-B broadcasts, you're listening for squitter -- so you can identify them as the ones where the CRC you compute equals the PI field in the message (because XORing 0 into the CRC doesn't change it). Everything with a different address will look like checksum failures to your code.

Since the DF11 message you're showing does match the cheksum, it must be DF11 squitter. There are plenty of those to hear; TCAS depends on everyone sending them continually.

In order to find DF11 messages with a nonzero interrogator identifier you should look for messages where the last three bytes after you've XORed out the CRC do begin with 17 zeros but then have at least some of the remaining 7 bits nonzero.