When we read from some client A, we may end up forwarding a message to other
clients. If we forward to some client B and there is a write error, then
we close B and remove it from the client list. However, if before this happened
A->next == B, then the read loop will still be holding on to a pointer to B,
and we crash.
As it's unpredictable what clients could be closed at what point, the simplest
approach is to retain closed clients in the list until we are at a point where
we know there are no stray pointers on stack, and only then modify the list.
This also simplifies anything that has to loop over clients, as it doesn't need
to worry about the current client being freed under it.
Client disconnection appears as a read of 0 bytes.
Without a test for this, dump1090 continues to poll that client forever.
Also, read() may return EWOULDBLOCK as well as EAGAIN
for "no data right now", so handle that.
I don't know if there is an equivalent Win32 bug here as the Win32
interfaces seem subtly different to vanilla POSIX.
The following test/break can probably be removed if Win32 needs
the same fix.
If we demodulate a message in 2.4MHz mode and it has a bad, uncorrectable CRC,
and --phase-enhance is on, then retry with the other possible phases until
we get a good CRC or run out of phases to try.
This is very expensive in AGC mode (lots of candidates that are not real
messages) but relatively cheap otherwise. It yields another 10% messages.
Also factor out some common stats code to avoid lots more copy/paste.
When replaying recordings, the read files are binary, so the file open
needs to reflect this so that spurious end of file characters aren't
misinterpreted.
Apparently enabling AGC produces samples with quite different characteristics,
and ends up eating a lot more CPU as the previous heuristics would generate a
lot of false positives. Tweaking the parameters and a bit of optimization
seems to bring this back down to usable levels without losing many potential
messages.
For remotely received messages that have a mlat timestamp, we have no
useful way of turning that timestamp into a wallclock timestamp, so
don't try, or we'll just produce wildly wrong results (_days_ in error)
There is a danger in always using relative decoding where possible.
If there is an undetected error in the first pair of messages received,
then global CPR decoding will give a bad position, and subsequent
relative decoding will just walk around near that bad position even
though many error-free pairs of odd/even messages may have been received.
The first pair of position messages also tends to be the most error-prone, as
they are usually received at the extreme edge of receiver range.
(I see this happen at least once a day in practice)
So, instead, prefer to use global decoding when we have sufficiently recent data.
With recent data this should always be as good as relative decoding, and it
avoids getting stuck with bad data for long periods of time. If we don't have
enough recent data for a global solution, fall back to relative decoding.