#region Header /* This file is part of PacketDotNet PacketDotNet is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PacketDotNet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with PacketDotNet. If not, see . */ /* * Copyright 2011 David Thedens */ #endregion Header using System; using System.Collections.Generic; using System.IO; using System.Text; namespace PacketDotNet { namespace Ieee80211 { /// /// Contains information specific to 802.3 packets. /// public class Ppi802_3 : PpiField { /// /// 802.3 specific extension flags. /// [Flags] public enum StandardFlags : uint { /// /// FCS is present at the end of the packet /// FcsPresent = 1 } /// /// Flags for errors detected at the time the packet was captured. /// [Flags] public enum ErrorFlags : uint { /// /// The frames FCS is invalid. /// InvalidFcs = 1, /// /// The frame has a sequence error. /// SequenceError = 2, /// /// The frame has a symbol error. /// SymbolError = 4, /// /// The frame has a data error. /// DataError = 8 } #region Properties /// Type of the field public override PpiFieldType FieldType { get { return PpiFieldType.Ppi802_3; } } /// /// Gets the length of the field data. /// /// /// The length. /// public override int Length { get {return 8; } } /// /// Gets or sets the standard 802.2 flags. /// /// /// The standard flags. /// public StandardFlags Flags { get; set; } /// /// Gets or sets the 802.3 error flags. /// /// /// The error flags. /// public ErrorFlags Errors { get; set; } /// /// Gets the field bytes. This doesn't include the PPI field header. /// /// /// The bytes. /// public override byte[] Bytes { get { MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); writer.Write((uint)Flags); writer.Write((uint)Errors); return ms.ToArray(); } } #endregion Properties #region Constructors /// /// Initializes a new instance of the class from the /// provided stream. /// /// /// The position of the BinaryReader's underlying stream will be advanced to the end /// of the PPI field. /// /// /// The stream the field will be read from /// public Ppi802_3(BinaryReader br) { Flags = (StandardFlags) br.ReadUInt32(); Errors = (ErrorFlags) br.ReadUInt32(); } /// /// Initializes a new instance of the class. /// /// /// Standard Flags. /// /// /// Error Flags. /// public Ppi802_3(StandardFlags Flags, ErrorFlags Errors) { this.Flags = Flags; this.Errors = Errors; } /// /// Initializes a new instance of the class. /// public Ppi802_3() { } #endregion Constructors } /// /// The PPI Aggregation field is used to identify which physical interface a frame was collected on /// when multiple capture interfaces are in use. /// public class PpiAggregation : PpiField { #region Properties /// Type of the field public override PpiFieldType FieldType { get { return PpiFieldType.PpiAggregation;} } /// /// Gets the length of the field data. /// /// /// The length. /// public override int Length { get {return 4; } } /// /// Zero-based index of the physical interface the packet was captured from. /// /// /// The interface id. /// public uint InterfaceId { get; set; } /// /// Gets the field bytes. This doesn't include the PPI field header. /// /// /// The bytes. /// public override byte[] Bytes { get { return BitConverter.GetBytes(InterfaceId); } } #endregion Properties #region Constructors /// /// Initializes a new instance of the class from the /// provided stream. /// /// /// The position of the BinaryReader's underlying stream will be advanced to the end /// of the PPI field. /// /// /// The stream the field will be read from /// public PpiAggregation (BinaryReader br) { InterfaceId = br.ReadUInt32(); } /// /// Initializes a new instance of the class. /// /// /// The interface id. /// public PpiAggregation(uint InterfaceId) { this.InterfaceId = InterfaceId; } /// /// Initializes a new instance of the class. /// public PpiAggregation () { } #endregion Constructors } /// /// The PPI Capture Info field has been assigned a PPI field type but currently has no defined /// field body. /// public class PpiCaptureInfo : PpiField { #region Properties /// Type of the field public override PpiFieldType FieldType { get { return PpiFieldType.PpiCaptureInfo;} } /// /// Gets the length of the field data. /// /// /// The length. /// public override int Length { get { return 0; } } /// /// Gets the field bytes. This doesn't include the PPI field header. /// /// /// The bytes. /// public override byte[] Bytes { get { return new byte[0]; } } #endregion Properties #region Constructors /// /// Initializes a new instance of the class from the /// provided stream. /// /// /// The position of the BinaryReader's underlying stream will be advanced to the end /// of the PPI field. /// /// /// The stream the field will be read from /// public PpiCaptureInfo (BinaryReader br) { } /// /// Initializes a new instance of the class. /// public PpiCaptureInfo() { } #endregion Constructors } /// /// The PPI Common field contains fields common to all 802.11 specifications. /// This field is loosely based on the Radio Tap header format. /// public class PpiCommon : PpiField { /// /// Common 802.11 flags. /// [Flags] public enum CommonFlags : ushort { /// /// Defines whether or not an FCS is included at the end of the encapsulated 802.11 frame. /// FcsIncludedInFrame = 0x1, /// /// If set the TSF-timer is in milliseconds, if not set the TSF-timer is in microseconds /// TimerSynchFunctionInUse = 0x2, /// /// Indicates that the FCS on the encapsulated 802.11 frame is invalid /// FailedFcsCheck = 0x4, /// /// Indicates that there was some type of physical error when receiving the packet. /// PhysicalError = 0x8 } #region Properties /// Type of the field public override PpiFieldType FieldType { get { return PpiFieldType.PpiCommon;} } /// /// Gets the length of the field data. /// /// /// The length. /// public override int Length { get { return 20; } } /// /// Radiotap-formatted channel flags. /// public RadioTapChannelFlags ChannelFlags { get; set; } /// /// Radiotap-formatted channel frequency, in MHz. 0 indicates an invalid value. /// /// /// The channel frequency. /// public UInt16 ChannelFrequency { get; set; } /// /// The common flags. /// public CommonFlags Flags { get; set; } /// /// Data rate in multiples of 500 Kbps. 0 indicates an invalid value. /// /// /// The data rate. /// public double Rate { get; set; } /// /// Gets or sets the TSF timer. /// /// /// The TSF Timer value. /// public UInt64 TSFTimer { get; set; } /// /// Gets or sets the Frequency-hopping spread spectrum (FHSS) hopset /// /// /// The FHSS hopset. /// public Byte FhssHopset { get; set; } /// /// Gets or sets the Frequency-hopping spread spectrum (FHSS) pattern. /// /// /// The FHSS pattern. /// public Byte FhssPattern { get; set; } /// /// Gets or sets the RF signal power at antenna. /// /// /// The antenna signal power. /// public SByte AntennaSignalPower { get; set; } /// /// Gets or sets the RF signal noise at antenna /// /// /// The antenna signal noise. /// public SByte AntennaSignalNoise { get; set; } /// /// Gets the field bytes. This doesn't include the PPI field header. /// /// /// The bytes. /// public override byte[] Bytes { get { MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); writer.Write(TSFTimer); writer.Write((ushort)Flags); writer.Write((ushort)(Rate * 2)); writer.Write(ChannelFrequency); writer.Write((ushort)ChannelFlags); writer.Write(FhssHopset); writer.Write(FhssPattern); writer.Write(AntennaSignalPower); writer.Write(AntennaSignalNoise); return ms.ToArray(); } } #endregion Properties #region Constructors /// /// Initializes a new instance of the class from the /// provided stream. /// /// /// The position of the BinaryReader's underlying stream will be advanced to the end /// of the PPI field. /// /// /// The stream the field will be read from /// public PpiCommon (BinaryReader br) { TSFTimer = br.ReadUInt64 (); Flags = (CommonFlags)br.ReadUInt16 (); Rate = 0.5f * br.ReadUInt16 (); ChannelFrequency = br.ReadUInt16 (); ChannelFlags = (RadioTapChannelFlags) br.ReadUInt16 (); FhssHopset = br.ReadByte (); FhssPattern = br.ReadByte (); AntennaSignalPower = br.ReadSByte(); AntennaSignalNoise = br.ReadSByte(); } /// /// Initializes a new instance of the class. /// AntennaSignalPower and AntennaSignalNoise are both set to their minimum value of -128. /// public PpiCommon () { AntennaSignalPower = -128; AntennaSignalNoise = -128; } #endregion Constructors } /// /// Abstract class for all PPI fields /// public abstract class PpiField { #region Properties /// Type of the field public abstract PpiFieldType FieldType { get; } /// /// Gets the length of the field data. /// /// /// The length. /// public abstract int Length { get; } /// /// Gets the field bytes. This doesn't include the PPI field header. /// /// /// The bytes. /// public abstract byte[] Bytes { get; } #endregion Properties #region Public Methods /// /// Parse a PPI indicated by type, from a given BinaryReader /// /// /// A /// /// /// A /// /// /// The maximum number of bytes that the field to be parsed can encompass. /// /// /// A /// public static PpiField Parse (int fieldType, BinaryReader br, ushort fieldLength) { var type = (PpiFieldType)fieldType; switch (type) { case PpiFieldType.PpiReserved0: return new PpiUnknown (fieldType, br, fieldLength); case PpiFieldType.PpiReserved1: return new PpiUnknown (fieldType, br, fieldLength); case PpiFieldType.PpiCommon: return new PpiCommon (br); case PpiFieldType.PpiMacExtensions: return new PpiMacExtensions (br); case PpiFieldType.PpiMacPhy: return new PpiMacPhy (br); case PpiFieldType.PpiSpectrum: return new PpiSpectrum (br); case PpiFieldType.PpiProcessInfo: return new PpiProcessInfo (br); case PpiFieldType.PpiCaptureInfo: return new PpiCaptureInfo (br); case PpiFieldType.PpiAggregation: return new PpiAggregation (br); case PpiFieldType.Ppi802_3: return new Ppi802_3 (br); default: return new PpiUnknown (fieldType, br, fieldLength); } } #endregion Public Methods } /// /// 802.11n MAC Extension flags. /// public enum PpiMacExtensionFlags : uint { /// /// Indicates the use of Greenfield (or HT) mode. In greenfield mode support for 802.11 a/b/g devices is sacrificed for /// increased efficiency. /// GreenField = 0x1, /// /// Indicates the High Throughput (HT) mode. If not set channel width is 20MHz, if set it is 40MHz. /// HtIndicator = 0x2, /// /// Indicates the use of a Short Guard Interval (SGI). /// RxSgi = 0x4, /// /// Indicates the use of HT Duplicate mode. /// DuplicateRx = 0x8, /// /// Indicates the use of MPDU aggregation. /// Aggregate = 0x10, /// /// Indicates the presence of more aggregate frames. /// MoreAggregates = 0x20, /// /// Indicates there was a CRC error in the A-MPDU delimiter after this frame. /// AggregateDelimiterCrc = 0x40 } /// /// The 802.11n MAC Extension field contains radio information specific to 802.11n. /// public class PpiMacExtensions : PpiField { #region Properties /// Type of the field public override PpiFieldType FieldType { get { return PpiFieldType.PpiMacExtensions;} } /// /// Gets the length of the field data. /// /// /// The length. /// public override int Length { get { return 12; } } /// /// Gets or sets the 802.11n MAC extension flags. /// /// /// The flags. /// public PpiMacExtensionFlags Flags { get; set; } /// /// Gets or sets the A-MPDU identifier. /// /// /// the A-MPDU id. /// public uint AMpduId { get; set; } /// /// Gets or sets the number of zero-length pad delimiters /// /// /// The delimiter count. /// public byte DelimiterCount { get; set; } /// /// Gets the field bytes. This doesn't include the PPI field header. /// /// /// The bytes. /// public override byte[] Bytes { get { MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); writer.Write((uint) Flags); writer.Write(AMpduId); writer.Write(DelimiterCount); writer.Write(new byte[3]); return ms.ToArray(); } } #endregion Properties #region Constructors /// /// Initializes a new instance of the class from the /// provided stream. /// /// /// The position of the BinaryReader's underlying stream will be advanced to the end /// of the PPI field. /// /// /// The stream the field will be read from /// public PpiMacExtensions (BinaryReader br) { Flags = (PpiMacExtensionFlags) br.ReadUInt32(); AMpduId = br.ReadUInt32(); DelimiterCount = br.ReadByte(); } /// /// Initializes a new instance of the class. /// public PpiMacExtensions () { } #endregion Constructors } /// /// The 802.11n MAC + PHY Extension field contains radio information specific to 802.11n. /// public class PpiMacPhy : PpiField { #region Properties /// Type of the field public override PpiFieldType FieldType { get { return PpiFieldType.PpiMacPhy;} } /// /// Gets the length of the field data. /// /// /// The length. /// public override int Length { get { return 48; } } /// /// Gets or sets the 802.11n MAC extension flags. /// /// /// The flags. /// public PpiMacExtensionFlags Flags { get; set; } /// /// Gets or sets the A-MPDU identifier. /// /// /// the A-MPDU id. /// public uint AMpduId { get; set; } /// /// Gets or sets the number of zero-length pad delimiters /// /// /// The delimiter count. /// public byte DelimiterCount { get; set; } /// /// Gets or sets the modulation coding scheme. /// /// /// The modulation coding scheme. /// public byte ModulationCodingScheme { get; set; } /// /// Gets or sets the number of spatial streams. /// /// /// The spatial stream count. /// public byte SpatialStreamCount { get; set; } /// /// Gets or sets the combined Received Signal Strength Indication (RSSI) value /// from all the active antennas and channels. /// /// /// The combined RSSI. /// public byte RssiCombined { get; set; } /// /// Gets or sets the Received Signal Strength Indication (RSSI) value for the antenna 0, control channel. /// /// /// The antenna 0 RSSI value. /// public byte RssiAntenna0Control { get; set; } /// /// Gets or sets the Received Signal Strength Indication (RSSI) value for the antenna 1, control channel. /// /// /// The antenna 1 control channel RSSI value. /// public byte RssiAntenna1Control { get; set; } /// /// Gets or sets the Received Signal Strength Indication (RSSI) value for the antenna 2, control channel. /// /// /// The antenna 2 control channel RSSI value. /// public byte RssiAntenna2Control { get; set; } /// /// Gets or sets the Received Signal Strength Indication (RSSI) value for the antenna 3, control channel. /// /// /// The antenna 3 control channel RSSI value. /// public byte RssiAntenna3Control { get; set; } /// /// Gets or sets the Received Signal Strength Indication (RSSI) value for the antenna 0, extension channel /// /// /// The antenna 0 extension channel RSSI value. /// public byte RssiAntenna0Ext { get; set; } /// /// Gets or sets the Received Signal Strength Indication (RSSI) value for the antenna 1, extension channel /// /// /// The antenna 1 extension channel RSSI value. /// public byte RssiAntenna1Ext { get; set; } /// /// Gets or sets the Received Signal Strength Indication (RSSI) value for the antenna 2, extension channel /// /// /// The antenna 2 extension channel RSSI value. /// public byte RssiAntenna2Ext { get; set; } /// /// Gets or sets the Received Signal Strength Indication (RSSI) value for the antenna 3, extension channel /// /// /// The antenna 3 extension channel RSSI value. /// public byte RssiAntenna3Ext { get; set; } /// /// Gets or sets the extension channel frequency. /// /// /// The extension channel frequency. /// public ushort ExtensionChannelFrequency { get; set; } /// /// Gets or sets the extension channel flags. /// /// /// The extension channel flags. /// public RadioTapChannelFlags ExtensionChannelFlags { get; set; } /// /// Gets or sets the RF signal power at antenna 0. /// /// /// The signal power. /// public byte DBmAntenna0SignalPower { get; set; } /// /// Gets or sets the RF signal noise at antenna 0. /// /// /// The signal noise. /// public byte DBmAntenna0SignalNoise { get; set; } /// /// Gets or sets the RF signal power at antenna 1. /// /// /// The signal power. /// public byte DBmAntenna1SignalPower { get; set; } /// /// Gets or sets the RF signal noise at antenna 1. /// /// /// The signal noise. /// public byte DBmAntenna1SignalNoise { get; set; } /// /// Gets or sets the RF signal power at antenna 2. /// /// /// The signal power. /// public byte DBmAntenna2SignalPower { get; set; } /// /// Gets or sets the RF signal noise at antenna 2. /// /// /// The signal noise. /// public byte DBmAntenna2SignalNoise { get; set; } /// /// Gets or sets the RF signal power at antenna 3. /// /// /// The signal power. /// public byte DBmAntenna3SignalPower { get; set; } /// /// Gets or sets the RF signal noise at antenna 3. /// /// /// The signal noise. /// public byte DBmAntenna3SignalNoise { get; set; } /// /// Gets or sets the error vector magnitude for Chain 0. /// /// /// The error vector magnitude. /// public uint ErrorVectorMagnitude0 { get; set; } /// /// Gets or sets the error vector magnitude for Chain 1. /// /// /// The error vector magnitude. /// public uint ErrorVectorMagnitude1 { get; set; } /// /// Gets or sets the error vector magnitude for Chain 2. /// /// /// The error vector magnitude. /// public uint ErrorVectorMagnitude2 { get; set; } /// /// Gets or sets the error vector magnitude for Chain 3. /// /// /// The error vector magnitude. /// public uint ErrorVectorMagnitude3 { get; set; } /// /// Gets the field bytes. This doesn't include the PPI field header. /// /// /// The bytes. /// public override byte[] Bytes { get { MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); writer.Write(AMpduId); writer.Write(DelimiterCount); writer.Write(ModulationCodingScheme); writer.Write(SpatialStreamCount); writer.Write(RssiCombined); writer.Write(RssiAntenna0Control); writer.Write(RssiAntenna1Control); writer.Write(RssiAntenna2Control); writer.Write(RssiAntenna3Control); writer.Write(RssiAntenna0Ext); writer.Write(RssiAntenna1Ext); writer.Write(RssiAntenna2Ext); writer.Write(RssiAntenna3Ext); writer.Write(ExtensionChannelFrequency); writer.Write((ushort)ExtensionChannelFlags); writer.Write(DBmAntenna0SignalPower); writer.Write(DBmAntenna0SignalNoise); writer.Write(DBmAntenna1SignalPower); writer.Write(DBmAntenna1SignalNoise); writer.Write(DBmAntenna2SignalPower); writer.Write(DBmAntenna2SignalNoise); writer.Write(DBmAntenna3SignalPower); writer.Write(DBmAntenna3SignalNoise); writer.Write(ErrorVectorMagnitude0); writer.Write(ErrorVectorMagnitude1); writer.Write(ErrorVectorMagnitude2); writer.Write(ErrorVectorMagnitude3); return ms.ToArray(); } } #endregion Properties #region Constructors /// /// Initializes a new instance of the class from the /// provided stream. /// /// /// The position of the BinaryReader's underlying stream will be advanced to the end /// of the PPI field. /// /// /// The stream the field will be read from /// public PpiMacPhy (BinaryReader br) { AMpduId = br.ReadUInt32(); DelimiterCount = br.ReadByte(); ModulationCodingScheme = br.ReadByte(); SpatialStreamCount = br.ReadByte(); RssiCombined = br.ReadByte(); RssiAntenna0Control = br.ReadByte(); RssiAntenna1Control = br.ReadByte(); RssiAntenna2Control = br.ReadByte(); RssiAntenna3Control = br.ReadByte(); RssiAntenna0Ext = br.ReadByte(); RssiAntenna1Ext = br.ReadByte(); RssiAntenna2Ext = br.ReadByte(); RssiAntenna3Ext = br.ReadByte(); ExtensionChannelFrequency = br.ReadUInt16(); ExtensionChannelFlags = (RadioTapChannelFlags) br.ReadUInt16(); DBmAntenna0SignalPower = br.ReadByte(); DBmAntenna0SignalNoise = br.ReadByte(); DBmAntenna1SignalPower = br.ReadByte(); DBmAntenna1SignalNoise = br.ReadByte(); DBmAntenna2SignalPower = br.ReadByte(); DBmAntenna2SignalNoise = br.ReadByte(); DBmAntenna3SignalPower = br.ReadByte(); DBmAntenna3SignalNoise = br.ReadByte(); ErrorVectorMagnitude0 = br.ReadUInt32(); ErrorVectorMagnitude1 = br.ReadUInt32(); ErrorVectorMagnitude2 = br.ReadUInt32(); ErrorVectorMagnitude3 = br.ReadUInt32(); } /// /// Initializes a new instance of the class. /// public PpiMacPhy () { } #endregion Constructors } /// /// PPI process info field. /// public class PpiProcessInfo : PpiField { #region Properties /// Type of the field public override PpiFieldType FieldType { get { return PpiFieldType.PpiProcessInfo;} } /// /// Gets the length of the field data. /// /// /// The length. /// public override int Length { get { var processLength = (String.IsNullOrEmpty(ProcessPath)) ? 0 : Encoding.UTF8.GetByteCount(ProcessPath); var userLength = (String.IsNullOrEmpty(UserName)) ? 0 : Encoding.UTF8.GetByteCount(UserName); var groupLength = (String.IsNullOrEmpty(GroupName)) ? 0 : Encoding.UTF8.GetByteCount(GroupName); return 19 + processLength + userLength + groupLength; } } /// /// Gets or sets the process identifier. /// /// /// The process identifier. /// public uint ProcessId { get; set; } /// /// Gets or sets the thread identifier. /// /// /// The thread identifier. /// public uint ThreadId { get; set; } /// /// Gets or sets the process path. /// /// /// The process path. /// public String ProcessPath { get; set; } /// /// Gets or sets the user identifier. /// /// /// The user identifier. /// public uint UserId { get; set; } /// /// Gets or sets the user name. /// /// /// The user name. /// public String UserName { get; set; } /// /// Gets or sets the group identifier. /// /// /// The group identifier. /// public uint GroupId { get; set; } /// /// Gets or sets the group name. /// /// /// The group name. /// public String GroupName { get; set; } /// /// Gets the field bytes. This doesn't include the PPI field header. /// /// /// The bytes. /// public override byte[] Bytes { get { MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); writer.Write(ProcessId); writer.Write(ThreadId); var pathBytes = Encoding.UTF8.GetBytes(ProcessPath ?? String.Empty); writer.Write((byte)pathBytes.Length); writer.Write(pathBytes); writer.Write(UserId); var userBytes = Encoding.UTF8.GetBytes(UserName ?? String.Empty); writer.Write((byte)userBytes.Length); writer.Write(userBytes); writer.Write(GroupId); var groupBytes = Encoding.UTF8.GetBytes(GroupName ?? String.Empty); writer.Write((byte)groupBytes.Length); writer.Write(groupBytes); return ms.ToArray(); } } #endregion Properties #region Constructors /// /// Initializes a new instance of the class from the /// provided stream. /// /// /// The position of the BinaryReader's underlying stream will be advanced to the end /// of the PPI field. /// /// /// The stream the field will be read from /// public PpiProcessInfo (BinaryReader br) { ProcessId = br.ReadUInt32(); ThreadId = br.ReadUInt32(); var pathLength = br.ReadByte(); ProcessPath = Encoding.UTF8.GetString(br.ReadBytes(pathLength)); UserId = br.ReadUInt32(); var userLength = br.ReadByte(); UserName = Encoding.UTF8.GetString(br.ReadBytes(userLength)); GroupId = br.ReadUInt32(); var groupLength = br.ReadByte(); GroupName = Encoding.UTF8.GetString(br.ReadBytes(groupLength)); } /// /// Initializes a new instance of the class. /// public PpiProcessInfo () { } #endregion Constructors } /// /// The PpiUnknown field class can be used to represent any field types not /// currently supported by PacketDotNet. Any unsupported field types encountered during /// parsing will be stored as PpiUnknown fields. /// public class PpiUnknown : PpiField { private PpiFieldType fieldType; #region Properties /// Type of the field public override PpiFieldType FieldType{ get { return fieldType; } } /// /// Gets the length of the field data. /// /// /// The length. /// public override int Length { get { return Bytes.Length; } } /// /// Gets the field bytes. This doesn't include the PPI field header. /// /// /// The bytes. /// public override byte[] Bytes { get { return UnknownBytes; } } /// /// Gets or sets the field data. /// /// /// The fields values bytes. /// public byte[] UnknownBytes { get; set; } #endregion Properties #region Constructors /// /// Initializes a new instance of the class from the /// provided stream. /// /// /// The position of the BinaryReader's underlying stream will be advanced to the end /// of the PPI field. /// /// /// The PPI field type number /// /// /// The stream the field will be read from /// /// /// The number of bytes the unknown field contains. /// public PpiUnknown (int typeNumber, BinaryReader br, int length) { fieldType = (PpiFieldType) typeNumber; UnknownBytes = br.ReadBytes(length); } /// /// Initializes a new instance of the class. /// /// /// The PPI field type number. /// public PpiUnknown (int typeNumber) { fieldType = (PpiFieldType)typeNumber; } /// /// Initializes a new instance of the class. /// /// /// The PPI field type number. /// /// /// The field data. /// public PpiUnknown (int typeNumber, byte[] UnknownBytes) { fieldType = (PpiFieldType)typeNumber; this.UnknownBytes = UnknownBytes; } #endregion Constructors } /// /// The PPI Spectrum field is intended to be compatible with the sweep records /// returned by the Wi-Spy spectrum analyzer. /// public class PpiSpectrum : PpiField { #region Properties /// Type of the field public override PpiFieldType FieldType { get { return PpiFieldType.PpiSpectrum;} } /// /// Gets the length of the field data. /// /// /// The length. /// public override int Length { get { return 20 + SamplesData.Length; } } /// /// Gets or sets the starting frequency in kHz. /// /// /// The starting frequency. /// public uint StartingFrequency { get; set; } /// /// Gets or sets the resolution of each sample in Hz. /// /// /// The resolution in Hz. /// public uint Resolution { get; set; } /// /// Gets or sets the amplitude offset (in 0.001 dBm) /// /// /// The amplitude offset. /// public uint AmplitudeOffset { get; set; } /// /// Gets or sets the amplitude resolution (in .001 dBm) /// /// /// The amplitude resolution. /// public uint AmplitudeResolution { get; set; } /// /// Gets or sets the maximum raw RSSI value reported by the device. /// /// /// The maximum rssi. /// public ushort MaximumRssi { get; set; } /// /// Gets or sets the data samples. /// /// /// The data samples. /// public byte[] SamplesData { get; set;} /// /// Gets the field bytes. This doesn't include the PPI field header. /// /// /// The bytes. /// public override byte[] Bytes { get { MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); writer.Write(StartingFrequency); writer.Write(Resolution); writer.Write(AmplitudeOffset); writer.Write(AmplitudeResolution); writer.Write(MaximumRssi); writer.Write((ushort) SamplesData.Length); writer.Write(SamplesData); return ms.ToArray(); } } #endregion Properties #region Constructors /// /// Initializes a new instance of the class from the /// provided stream. /// /// /// The position of the BinaryReader's underlying stream will be advanced to the end /// of the PPI field. /// /// /// The stream the field will be read from /// public PpiSpectrum (BinaryReader br) { StartingFrequency = br.ReadUInt32(); Resolution = br.ReadUInt32(); AmplitudeOffset = br.ReadUInt32(); AmplitudeResolution = br.ReadUInt32(); MaximumRssi = br.ReadUInt16(); var samplesLength = br.ReadUInt16(); SamplesData = br.ReadBytes(samplesLength); } /// /// Initializes a new instance of the class. /// public PpiSpectrum () { } #endregion Constructors } } }