private void ExtractAltitudeCode(ModeSMessage reply) { reply.Altitude = _BitStream.ReadUInt16(13); reply.AltitudeIsMetric = (reply.Altitude & 0x40) != 0; if (!reply.AltitudeIsMetric.Value) { int?decodedAltitude = ((reply.Altitude & 0x1F80) >> 2) | ((reply.Altitude & 0x20) >> 1) | (reply.Altitude & 0x0f); if ((reply.Altitude & 0x10) != 0) { decodedAltitude = ModeSAltitudeConversion.CalculateBinaryAltitude(decodedAltitude.Value); } else { decodedAltitude = ModeSAltitudeConversion.LookupGillhamAltitude(decodedAltitude.Value); } reply.Altitude = decodedAltitude; } }
public void BitStream_ReadUInt16_Throws_If_Reading_Less_Than_One_Or_More_Than_16_Bits() { for (int i = -2; i < 18; ++i) { _BitStream.Initialise(new byte[] { 0x00, 0x00 }); bool expectException = i < 1 || i > 16; bool sawException = false; try { _BitStream.ReadUInt16(i); } catch (ArgumentOutOfRangeException) { sawException = true; } Assert.AreEqual(expectException, sawException, "ReadUInt16 did not behave correctly when asked to read {0} bits", i); } }
/// <summary> /// Decodes an airborne position message. /// </summary> /// <param name="message"></param> private void DecodeAirbornePosition(AdsbMessage message) { message.MessageFormat = message.Type == 0 ? MessageFormat.NoPositionInformation : MessageFormat.AirbornePosition; var subMessage = message.AirbornePosition = new AirbornePositionMessage(); subMessage.SurveillanceStatus = (SurveillanceStatus)_BitStream.ReadByte(2); if (message.Type == 0) { _BitStream.Skip(1); } else { subMessage.NicB = (byte)(_BitStream.ReadBit() ? 2 : 0); } var rawAltitude = _BitStream.ReadUInt16(12); var acCode = ((rawAltitude & 0xfe0) >> 1) | (rawAltitude & 0x0f); int?altitude = null; if ((rawAltitude & 0x10) != 0) { altitude = ModeSAltitudeConversion.CalculateBinaryAltitude(acCode); } else { altitude = ModeSAltitudeConversion.LookupGillhamAltitude(acCode); } if (message.Type < 20) { subMessage.BarometricAltitude = altitude; } else { subMessage.GeometricAltitude = altitude; } subMessage.PositionTimeIsExact = _BitStream.ReadBit(); subMessage.CompactPosition = ExtractCprCoordinate(message, 17); }
/// <summary> /// Decodes a coarse format TIS-B airborne position message. /// </summary> /// <param name="message"></param> private void DecodeCoarseTisbAirbornePosition(AdsbMessage message) { message.MessageFormat = MessageFormat.CoarseTisbAirbornePosition; var subMessage = message.CoarseTisbAirbornePosition = new CoarseTisbAirbornePosition(); message.TisbIcaoModeAFlag = _BitStream.ReadByte(1); subMessage.SurveillanceStatus = (SurveillanceStatus)_BitStream.ReadByte(2); subMessage.ServiceVolumeID = _BitStream.ReadByte(4); var rawAltitude = _BitStream.ReadUInt16(12); var acCode = ((rawAltitude & 0xfe0) >> 1) | (rawAltitude & 0x0f); if ((rawAltitude & 0x10) != 0) { subMessage.BarometricAltitude = ModeSAltitudeConversion.CalculateBinaryAltitude(acCode); } else { subMessage.BarometricAltitude = ModeSAltitudeConversion.LookupGillhamAltitude(acCode); } var groundTrackValid = _BitStream.ReadBit(); var groundTrack = _BitStream.ReadByte(5); var groundSpeed = _BitStream.ReadByte(6); if (groundTrackValid) { subMessage.GroundTrack = (double)groundTrack * 11.25; } subMessage.GroundSpeed = (double)groundSpeed * 16.0; subMessage.CompactPosition = ExtractCprCoordinate(message, 12, ignoreMessageType: true); }