Change Mode-A/C to Mode-S detection

The original code made an attempt to reconcile a newly arrived ModeA/C
message with every known Mode-S report at the time of detection.
However, the results of matching up Modes A/C and S are only used in the
interactive display routine, and that is only called periodically from
within the BackgroundTasks loop.

Doing the matching on every ModeA/C arrival incurs quite a large CPU
processing load. Moving the matching up routine to the backgroundTasks
loop means that the task is performed muck less frequently and therefore
uses less CPU time.
This commit is contained in:
Malcolm Robb 2013-04-24 23:47:08 +01:00
parent 3dbc0efffc
commit 3766492067

View file

@ -288,7 +288,7 @@ struct modesMessage {
int identity; /* 13 bits identity (Squawk). */ int identity; /* 13 bits identity (Squawk). */
// DF32 ModeA & Mode C // DF32 ModeA & Mode C
int modeC; int modeC; /* Decoded Mode C */
/* Fields used by multiple message types. */ /* Fields used by multiple message types. */
int altitude, unit; int altitude, unit;
@ -1044,7 +1044,7 @@ int ModeAToModeC(unsigned int ModeA )
return ((FiveHundreds * 5) + OneHundreds - 13); return ((FiveHundreds * 5) + OneHundreds - 13);
} }
void decodeModeAMessage(unsigned int ModeA, struct modesMessage *mm) void decodeModeAMessage(struct modesMessage *mm, int ModeA)
{ {
mm->msgtype = 32; // Valid Mode S DF's are DF-00 to DF-31. mm->msgtype = 32; // Valid Mode S DF's are DF-00 to DF-31.
// so use 32 to indicate Mode A/C // so use 32 to indicate Mode A/C
@ -1890,7 +1890,7 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
mm.timestampMsg = Modes.timestampBlk + ((j+1) * 6); mm.timestampMsg = Modes.timestampBlk + ((j+1) * 6);
// Decode the received message // Decode the received message
decodeModeAMessage(ModeA, &mm); decodeModeAMessage(&mm, ModeA);
// Pass data to the next layer // Pass data to the next layer
useModesMessage(&mm); useModesMessage(&mm);
@ -2244,6 +2244,18 @@ void interactiveUpdateAircraftModeA(struct aircraft *a) {
} }
} }
void interactiveUpdateAircraftModeS() {
struct aircraft *a = Modes.aircrafts;
while(a) {
if (a->modeACflags & MODEAC_MSG_FLAG) { // find any fudged ICAO records
a->modeACflags &= ~MODEAC_MSG_MODES_HIT; // clear the hit bit
interactiveUpdateAircraftModeA(a); // and attempt to match them with Mode-S
}
a = a->next;
}
}
/* Always positive MOD operation, used for CPR decoding. */ /* Always positive MOD operation, used for CPR decoding. */
int cprModFunction(int a, int b) { int cprModFunction(int a, int b) {
int res = a % b; int res = a % b;
@ -3014,7 +3026,7 @@ int decodeHexMessage(struct client *c) {
msg[j/2] = (high << 4) | low; msg[j/2] = (high << 4) | low;
} }
if (l < 5) {decodeModeAMessage((uint)((msg[0]<<8) + msg[1]), &mm);} // ModeA or ModeC if (l < 5) {decodeModeAMessage(&mm, ((msg[0] << 8) | msg[1]));} // ModeA or ModeC
else {decodeModesMessage(&mm, msg);} else {decodeModesMessage(&mm, msg);}
useModesMessage(&mm); useModesMessage(&mm);
@ -3311,12 +3323,23 @@ void backgroundTasks(void) {
modesReadFromClients(); modesReadFromClients();
} }
if ( (Modes.aircrafts) && ((mstime() - Modes.interactive_last_update) > MODES_INTERACTIVE_REFRESH_TIME)) { // If Modes.aircrafts is not NULL, remove any stale aircraft
interactiveRemoveStaleAircrafts(); if (Modes.aircrafts)
Modes.interactive_last_update = mstime(); {interactiveRemoveStaleAircrafts();}
// Refresh screen when in interactive mode // Refresh screen when in interactive mode
if (Modes.interactive) if ((Modes.interactive) &&
{interactiveShowData();} ((mstime() - Modes.interactive_last_update) > MODES_INTERACTIVE_REFRESH_TIME) ) {
// Attempt to reconsile any ModeA/C with known Mode-S
// We can't condition on Modes.modeac because ModeA/C could be comming
// in from a raw input port which we can't turn off.
interactiveUpdateAircraftModeS();
// Now display Mode-S and any non-reconsiled Modes-A/C
interactiveShowData();
Modes.interactive_last_update = mstime();
} }
} }