/// <summary> /// See interface docs. /// </summary> /// <param name="rawMessage"></param> /// <param name="start"></param> /// <param name="signalLevel"></param> /// <param name="isMlat"></param> /// <returns></returns> public ModeSMessage Translate(byte[] rawMessage, int start, int?signalLevel, bool isMlat) { if (Statistics == null) { throw new InvalidOperationException("Statistics must be provided before Translate can do any work"); } ModeSMessage result = null; var messageLength = rawMessage == null ? 0 : rawMessage.Length - start; if (messageLength > 6) { _BitStream.Initialise(rawMessage); _BitStream.Skip(start * 8); var downlinkFormatValue = _BitStream.ReadByte(5); if (downlinkFormatValue >= 24) { downlinkFormatValue = 24; _BitStream.Skip(-3); } bool isLongFrame = true; switch (downlinkFormatValue) { case 16: case 17: case 18: case 19: case 20: case 21: case 24: if (messageLength > 13) { result = new ModeSMessage(); } break; default: isLongFrame = false; result = new ModeSMessage(); break; } if (result != null) { result.SignalLevel = signalLevel; result.IsMlat = isMlat; result.DownlinkFormat = (DownlinkFormat)downlinkFormatValue; switch (result.DownlinkFormat) { case DownlinkFormat.ShortAirToAirSurveillance: DecodeShortAirToAirSurveillance(result); break; // DF0 case DownlinkFormat.SurveillanceAltitudeReply: DecodeSurveillanceAltitudeReply(result); break; // DF4 case DownlinkFormat.SurveillanceIdentityReply: DecodeSurveillanceIdentityReply(result); break; // DF5 case DownlinkFormat.AllCallReply: DecodeAllCallReply(result); break; // DF11 case DownlinkFormat.LongAirToAirSurveillance: DecodeLongAirToAirSurveillance(result); break; // DF16 case DownlinkFormat.ExtendedSquitter: DecodeExtendedSquitter(result); break; // DF17 case DownlinkFormat.ExtendedSquitterNonTransponder: DecodeExtendedSquitterNonTransponder(result); break; // DF18 case DownlinkFormat.MilitaryExtendedSquitter: DecodeMilitaryExtendedSquitter(result); break; // DF19 case DownlinkFormat.CommBAltitudeReply: DecodeCommBAltitudeReply(result); break; // DF20 case DownlinkFormat.CommBIdentityReply: DecodeCommBIdentityReply(result); break; // DF21 case DownlinkFormat.CommD: DecodeCommD(result); break; // DF24 } if (Statistics != null) { Statistics.Lock(r => { ++r.ModeSMessagesReceived; ++r.ModeSDFStatistics[(int)result.DownlinkFormat].MessagesReceived; if (isLongFrame) { ++r.ModeSLongFrameMessagesReceived; } else { ++r.ModeSShortFrameMessagesReceived; } }); } } } return(result); }
public void BitStream_LengthRemaining_Returns_Zero_If_Called_After_Stream_Has_Been_Depleted() { _BitStream.Initialise(new byte[] { 0x0f }); _BitStream.ReadByte(8); Assert.AreEqual(0, _BitStream.LengthRemaining); }
/// <summary> /// See interface docs. /// </summary> /// <param name="modeSMessage"></param> /// <returns></returns> public AdsbMessage Translate(ModeSMessage modeSMessage) { if (Statistics == null) { throw new InvalidOperationException("Statistics must be supplied before Translate can be called"); } AdsbMessage result = null; if (modeSMessage != null && modeSMessage.ExtendedSquitterMessage != null && modeSMessage.ExtendedSquitterMessage.Length == 7) { _BitStream.Initialise(modeSMessage.ExtendedSquitterMessage); result = new AdsbMessage(modeSMessage); if (IsCoarseFormatTisb(result)) { DecodeCoarseTisbAirbornePosition(result); } else { result.Type = _BitStream.ReadByte(5); switch (result.Type) { case 0: DecodeAirbornePosition(result); break; case 1: case 2: case 3: case 4: DecodeIdentification(result); break; case 5: case 6: case 7: case 8: DecodeSurfacePosition(result); break; case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: DecodeAirbornePosition(result); break; case 19: DecodeVelocity(result); break; case 20: case 21: case 22: DecodeAirbornePosition(result); break; case 28: DecodeAircraftStatus(result); break; case 29: DecodeTargetStateAndStatus(result); break; case 31: DecodeAircraftOperationalStatus(result); break; } } if (Statistics != null) { Statistics.Lock(r => { ++r.AdsbCount; ++r.AdsbMessageFormatCount[(int)result.MessageFormat]; ++r.AdsbTypeCount[result.Type]; }); } } return(result); }
/// <summary> /// See interface docs. /// </summary> /// <param name="modeSMessage"></param> /// <returns></returns> public AdsbMessage Translate(ModeSMessage modeSMessage) { AdsbMessage result = null; if (modeSMessage != null && modeSMessage.ExtendedSquitterMessage != null && modeSMessage.ExtendedSquitterMessage.Length == 7) { _BitStream.Initialise(modeSMessage.ExtendedSquitterMessage); result = new AdsbMessage(modeSMessage); result.Type = _BitStream.ReadByte(5); switch (result.Type) { case 0: DecodeAirbornePosition(result); break; case 1: case 2: case 3: case 4: DecodeIdentification(result); break; case 5: case 6: case 7: case 8: DecodeSurfacePosition(result); break; case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: DecodeAirbornePosition(result); break; case 19: DecodeVelocity(result); break; case 20: case 21: case 22: DecodeAirbornePosition(result); break; case 28: DecodeAircraftStatus(result); break; case 29: DecodeTargetStateAndStatus(result); break; case 31: DecodeAircraftOperationalStatus(result); break; } if (_Statistics.Lock != null) { lock (_Statistics.Lock) { ++_Statistics.AdsbCount; ++_Statistics.AdsbMessageFormatCount[(int)result.MessageFormat]; ++_Statistics.AdsbTypeCount[result.Type]; } } } return(result); }
/// <summary> /// See interface docs. /// </summary> /// <param name="rawMessage"></param> /// <param name="start"></param> /// <returns></returns> public ModeSMessage Translate(byte[] rawMessage, int start) { ModeSMessage result = null; var messageLength = rawMessage == null ? 0 : rawMessage.Length - start; if (messageLength > 6) { _BitStream.Initialise(rawMessage); _BitStream.Skip(start * 8); var downlinkFormatValue = _BitStream.ReadByte(5); if (downlinkFormatValue >= 24) { downlinkFormatValue = 24; _BitStream.Skip(-3); } bool isLongFrame = true; switch (downlinkFormatValue) { case 16: case 17: case 18: case 19: case 20: case 21: case 24: if (messageLength > 13) { result = new ModeSMessage(); } break; default: isLongFrame = false; result = new ModeSMessage(); break; } if (result != null) { result.DownlinkFormat = (DownlinkFormat)downlinkFormatValue; switch (result.DownlinkFormat) { case DownlinkFormat.ShortAirToAirSurveillance: DecodeShortAirToAirSurveillance(result); break; // DF0 case DownlinkFormat.SurveillanceAltitudeReply: DecodeSurveillanceAltitudeReply(result); break; // DF4 case DownlinkFormat.SurveillanceIdentityReply: DecodeSurveillanceIdentityReply(result); break; // DF5 case DownlinkFormat.AllCallReply: DecodeAllCallReply(result); break; // DF11 case DownlinkFormat.LongAirToAirSurveillance: DecodeLongAirToAirSurveillance(result); break; // DF16 case DownlinkFormat.ExtendedSquitter: DecodeExtendedSquitter(result); break; // DF17 case DownlinkFormat.ExtendedSquitterNonTransponder: DecodeExtendedSquitterNonTransponder(result); break; // DF18 case DownlinkFormat.MilitaryExtendedSquitter: DecodeMilitaryExtendedSquitter(result); break; // DF19 case DownlinkFormat.CommBAltitudeReply: DecodeCommBAltitudeReply(result); break; // DF20 case DownlinkFormat.CommBIdentityReply: DecodeCommBIdentityReply(result); break; // DF21 case DownlinkFormat.CommD: DecodeCommD(result); break; // DF24 } if (_Statistics.Lock != null) { lock (_Statistics.Lock) { ++_Statistics.ModeSMessagesReceived; ++_Statistics.ModeSDFCount[(int)result.DownlinkFormat]; if (isLongFrame) { ++_Statistics.ModeSLongFrameMessagesReceived; } else { ++_Statistics.ModeSShortFrameMessagesReceived; } } } } } return(result); }