Jump to content

Sample C code for decoding 9.x UDP Packets

Ben Russell

Recommended Posts

This code will decode a 9.x UDP packet.

It will automatically detect the need to do byte-swapping.

There is some Objective-C syntax mixed in.

It uses lots of square brackets. "[ ]".

Substitute your own code as needed.

void OnReceiveCore(char *pp, uint iPacketSize){

//dynamically adapts.
static int iPowerPC_Host = 0;

int iCompoundPacketCount = (iPacketSize - 5) / 36;

//printf("rx packet size: %i - compound: %i\n", iPacketSize, iCompoundPacketCount);

    int    itmp=0;

float payload[8];

        //if( iPacketSize == 41 ){
            //radio and nav frequency setting packets, also the ap heading packet.

                //we now have the packet in the packet[] var
                //DATAxXXXXaaaaBBBBccccDDDDeeeeFFFFggggHHHH  <- 41 bytes.
                //XXXX      = int, packet index
                //aaaa-HHHH = data payload, floats

                    //packet pData;               
                    int iPacketIndex = 0;
                    int bo=5; //byte offset

for( int iPacketX=0; iPacketX < iCompoundPacketCount; iPacketX++ ){
//extrac the packet index number id int
memcpy(&itmp, pp+bo, 4);

//if the value is absurdly large we have a PPC big endian packet
if( itmp > 1024 ){
iPowerPC_Host = 1;
iPowerPC_Host = 0;

if( iPowerPC_Host ){
iPacketIndex = ntohl(itmp);
memcpy(payload, pp+bo, 32);

for( int x=0; x<8; x++ ){
bswapf( &(payload[x]) );

iPacketIndex = (itmp);
memcpy(payload, pp+bo, 32);

//printf("index: %i\n", iPacketIndex);


//03 - speeds
//kias - vind
//keas - vind
//ktas - vtrue
//ktgs - vtrue
//mph - vind
//mphas - vtrue
//mphgs - vtrue

//04 - mach VVI g-load
//mach - ratio
//vvi - fpm
//gload - normal
//gload - axial
//gload - side

//12 - wing sweep / thrust vec
//sweep - 1,deg
//sweep - 2,deg
//sweep - h,deg
//vect - ratio
//sweep - ratio
//incid - ratio
//dihed - ratio
//retra - ratio

case 13:
//13 - trim/flap/slat/s-brakes
//trim - elev
//trim - ail
//trim - rudder
//flap handle
//flap position
//slat ratio
//spbrk handle
//spbrk position

if( payload[7] >= 0.5f ){
[glViewC setSpeedBrake:1.f];
[glViewC setSpeedBrake:0.f];


//14 - gear and brakes
//wbrak - part
//lbrak - part
//rbrak - part

//V9.21 Pitch Packet
case 18:
//printf("pitch: %.3f, roll: %.3f\n", payload[0], payload[1] );
[glViewC setPitch:payload[0]];
[glViewC setRoll:payload[1]];
//hding true
//hding mag
//mag comp
//mavar deg

case 19:
//19 - AoA, side slip, paths
[glViewC setAlpha:payload[0]];//alpha
[glViewC setBeta:payload[1]];//beta

//20 - lat lon altitude
//alt ftmsl
//alt ftagl
//alt ind
//lat south
//lat west

//26 - throttle actual
//throttle per engine

//41 - N1
//n1 pct per engine

//62 - fuel weights
//fuel weight per tank

//63 - payload weights and cg
//empty weight
//cg ftref

case 67:
//67 - gear deployment
//gear rat per strut
if( payload[0] >= 1.0f ){
[glViewC setGear:1.f];
[glViewC setGear:0.f];

//117 - weapon stats
//hdng delta
//pitch delta
//R d/sec
//Q d/sec
//rudd ratio
//elev ration
//V kts
//dis ft

                            //unkown packet type, never expected, dont do anything. -shrug-
                    } // end of switch(iPacketIndex)

        }//end packet loop

} // end OnReceiveCore(...)

Link to comment
Share on other sites

These are the byte-swapping functions.

The core code originally came from Austin.

They are more useful than htonl() and ntohl() as they do not attempt to be "smart" they simply swap the data you feed them.

void rev_byte_order4(char* retval) // reverse byte-order for least/most signifigant-byte-first,
{ // which is done differently on Mac and IBM...
        char* add=retval; char b1=*(add); add++; // This works as long as both platforms are IEEE, and
          char b2=*(add); add++; // the values passed in are FOUR BYTES (32 bits)... this
          char b3=*(add); add++; // includes FLOATS and LONGS, NOT SHORTS OR DOUBLEsS
          char b4=*(add);

         add=retval; *add=b4; add++;
          *add=b3; add++;
          *add=b2; add++;
void bswapi(int *pint){
    char tmpb[4];
    memcpy(tmpb, pint, 4);
    memcpy(pint, tmpb, 4);

void bswapf(float *pf){
    char tmpb[4];
    memcpy(tmpb, pf, 4);
    memcpy(pf, tmpb, 4);


Link to comment
Share on other sites

  • 2 months later...


I don't get the reason why rev_byte_order4 is done this way, the following code compiles in 8 instructions instead of 19 and is about four times faster.


void rev_byte_order4(char* retval)
char Temp;
Temp = retval[0];
retval[0] = retval[3];
retval[3] = Temp;
Temp = retval[1];
retval[1] = retval[2];
retval[2] = Temp;

Edit : If you have a bunch of them to swap (multiple of 4), and you define some platform specific vector implementation of rev_byte_order4, then this one on PC compiles in 6 instructions and is even faster :

void rev_byte_order4_4(char* retval)
static const long Shuffler = _MM_SHUFFLE(0,1,2,3);
__m128 vFour32a,vFour32b;

vFour32a = _mm_loadu_ps((float*)retval); // vFour32a = a3 a2 a1 a0
vFour32b = _mm_movehl_ps(vFour32a,vFour32a); // vFour32b = a3 a2 a3 a2
vFour32a = _mm_movelh_ps(vFour32a,vFour32a); // vFour32a = a1 a0 a1 a0
vFour32a = _mm_shuffle_ps(vFour32b,vFour32a,Shuffler); // vFour32a = a0 a1 a2 a3


Link to comment
Share on other sites

  • 5 years later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...