/// <summary> /// Translates the bytes for a Mode-S message into a cooked message object and causes a message received event to be raised on the background thread. /// </summary> /// <param name="now"></param> /// <param name="extractedBytes"></param> private void ProcessModeSMessageBytes(DateTime now, ExtractedBytes extractedBytes) { if (extractedBytes.Length == 7 || extractedBytes.Length == 14) { if (extractedBytes.HasParity) { _ModeSParity.StripParity(extractedBytes.Bytes, extractedBytes.Offset, extractedBytes.Length); } try { var modeSMessage = _ModeSMessageTranslator.Translate(extractedBytes.Bytes, extractedBytes.Offset); if (modeSMessage != null) { bool hasPIField = modeSMessage.ParityInterrogatorIdentifier != null; bool isPIWithBadParity = hasPIField && modeSMessage.ParityInterrogatorIdentifier != 0; var adsbMessage = _AdsbMessageTranslator.Translate(modeSMessage); if ((hasPIField || isPIWithBadParity || adsbMessage == null) && _Statistics.Lock != null) { lock (_Statistics.Lock) { if (hasPIField) { ++_Statistics.ModeSWithPIField; } if (isPIWithBadParity) { ++_Statistics.ModeSWithBadParityPIField; } if (adsbMessage == null) { ++_Statistics.ModeSNotAdsbCount; } } } ++TotalMessages; _MessageProcessingAndDispatchQueue.Enqueue(new MessageDispatch() { ModeSMessageEventArgs = new ModeSMessageEventArgs(now, modeSMessage, adsbMessage) }); } } catch (Exception) { ++TotalBadMessages; if (!IgnoreBadMessages) { throw; } } } }
/// <summary> /// Translates the bytes for a Mode-S message into a cooked message object and causes a message received event to be raised on the background thread. /// </summary> /// <param name="now"></param> /// <param name="extractedBytes"></param> private void ProcessModeSMessageBytes(DateTime now, ExtractedBytes extractedBytes) { if (extractedBytes.Length == 7 || extractedBytes.Length == 14) { if (extractedBytes.HasParity) { _ModeSParity.StripParity(extractedBytes.Bytes, extractedBytes.Offset, extractedBytes.Length); } try { var modeSMessage = _ModeSMessageTranslator.Translate(extractedBytes.Bytes, extractedBytes.Offset, extractedBytes.SignalLevel, extractedBytes.IsMlat); if (modeSMessage != null) { bool hasPIField = modeSMessage.ParityInterrogatorIdentifier != null; bool isPIWithBadParity = hasPIField && modeSMessage.ParityInterrogatorIdentifier != 0; var adsbMessage = _AdsbMessageTranslator.Translate(modeSMessage); if ((hasPIField || isPIWithBadParity || adsbMessage == null) && Statistics != null) { Statistics.Lock(r => { if (hasPIField) { ++r.ModeSWithPIField; } if (isPIWithBadParity) { ++r.ModeSWithBadParityPIField; ++r.ModeSDFStatistics[(int)modeSMessage.DownlinkFormat].BadParityPI; } if (adsbMessage == null) { ++r.ModeSNotAdsbCount; } }); } if (adsbMessage != null && modeSMessage.DownlinkFormat == DownlinkFormat.ExtendedSquitterNonTransponder) { if (adsbMessage.TisbIcaoModeAFlag == 0) { switch (modeSMessage.ControlField) { case ControlField.CoarseFormatTisb: case ControlField.FineFormatTisb: modeSMessage.Icao24 = modeSMessage.NonIcao24Address.GetValueOrDefault(); modeSMessage.NonIcao24Address = null; break; } } } ++TotalMessages; _MessageProcessingAndDispatchQueue.Enqueue(new MessageDispatch() { ModeSMessageEventArgs = new ModeSMessageEventArgs(now, modeSMessage, adsbMessage) }); } } catch (Exception) { ++TotalBadMessages; if (!IgnoreBadMessages) { throw; } } } }