一、ADSBsharp

(前言:NativeMethods 原生方法)
主程序(与sdrsharp类似)
可以很容易发现这些文件夹里的程序对应的就是你要使用到的SDR设备,它们也会有简单的硬件配置界面的代码,但是更重要的是,它们的内部都分别有NativeMethods.cs这个文件代码开头都会DllImport,这是用来读入设备对应的.dll文件的(相当于linux中的.so文件,如果是hackrf就相当于在读libhackrf.so),这样就可以在c#里直接调用设备驱动提供的函数接口了。

RTLSDR文件夹中调用的层级结构是:RTLControllerDialog.cs(界面代码)->RTLSDRIO.cs->RtlDevice.cs->NativeMethods.cs->rtlsdr的驱动dll(这个dll是librtlsdr.c及其配套程序在Windows下编译出来的)。

其实,如果是初学者自己写程序的话,完全可以把中间的RTLSDRIO.cs、RtlDevice.cs、NativeMethods合并到界面代码中,直接在界面代码里调硬件驱动的API函数也是可以的。

第三类是纯算法的文件夹,如DNR(语音降噪)、Radio(各类解调算法)。这一类算法代码是SDR的精华,我们会重点讲解。

除这三类之外,还有一些文件夹也挺有意思,比如WavRecorder,主要用于实现录音功能,包括界面和对磁盘的写入代码。Common文件夹实现了一些接口,用于给其它新加入的模块集成,这样程序更加模块化,这样要对这个SDRSharp增加删除一些自定义模块时会更加灵活一些。初学者不需要太关心这个文件夹。

二、AdsbSharp程序解析

(1)

1090ES模式下ADS-B接收机解码系统设计

【作者】 张成龙;
【导师】 张朝柱;
【作者基本信息】 哈尔滨工程大学 , 信息与通信工程, 2015, 硕士

主题思想:

  1. 从硬件获得指定长度的数据,数据是byte*类型(数据范围为(0~2^8=255),因为是AD的量化位数位 8bits),长度readLength = 16 * 1024;
  2. 数据由byte*类型转换成Complex *形式,ptr->Imag = *buf++ * 10 - 1275, ptr->Real = *buf++ * 10 - 1275,(数据范围为(0255)*10-1275=(-1275+1275)), 长度为 readLength/2 = 8 * 1024=8192;
  3. 对数据进行处理;包括:(1)复数转换成模值的平方;(2)判断帧头的位置(即提取前导符);(3)提取帧头后面对应长度的消息(112 bits(长码)或56 bits(短码)对该消息进行提出处理(提取不同的类型和获取ICAO号以及长短码校验等));
  4. 绑定委托输出,作为服务器的发送数据进行输出。

其中第3点对消息的处理由很多技巧:
(1)把每次由复数转换成的当前模值循环存储在一个数组中,数组长度位 帧长加消息位长度 即16+1122=240;
(2)判断当前模值所在数组的下一数据是否是帧头的开始(判断该数据和后面的数据共16位,是否满足帧头校验)(注意: 该数组初值为0,该数组要填充满后才开始,且该数据(帧头首位)与0比较,是否满足对应的帧头要求);
(3)确定帧头的首位位置后,对模值数组数据(112
2个)进行PPM解调,且解调的数据(0或者1,共112个)放在帧数组 _frame[112/8=14](8解调数据个组成_frame数组的一个数据) 中;
(4)然后在根据数据的定义,解码数据帧。此处用到ICAO号作用唯一标识构建字典类型

Dictionary<uint, int> _candidateICAOs 和Dictionary<uint, ulong> _icaos

_candidateICAOs 用来存储ICAO号和对应的飞机航机点数;其中界面中的 confidenceLevel 对应于飞机航迹点数。其中,如果 if (_candidateICAOs.Count > 500000),即存储的飞机数大于5W条,则更新该字典,更新规则是

_candidateICAOs = _candidateICAOs.Where(pair => pair.Value > 1).ToDictionary (pair => pair.Key, pair => pair.Value - 1);

即点数大于1飞机ICAO重新写入(小于2个点的都舍弃),对应的点数值都减去1。 _candidateICAOs的主要作用是用来判断某架飞机(对应的ICAO)的航迹点数是否满足大于等于confidenceLevel,(即点数大于4.用来完成数据的校验),然后才能采取后续操作输出对应的数据帧_frame。

_icaos用来存储ICAO号和当前时间(利用对应的数据量等效于时间,含义即该飞机出现的时间);
//即10秒钟更新一次字典,更新的规则是 把120秒之内的数据重新写入字典,大于120秒的数据则舍弃。时间的控制用数据量来控制。(采样率为OneSecond=2M,120秒对应的采样点数位timeoutTicks = _timeout * OneSecond,_ticks 用来表示总共处理的采样点数)即用来保存120秒之内的飞机 ICAO。主要用来120秒没是否有数据(_icaos.ContainsKey(icao))。满足才能进行后续输出数据帧_frame。

   if (_ticks % (10 * OneSecond) == 0) // Happens every 10sec  达到十秒的数据量时var timeoutTicks = _timeout * OneSecond;// 120s_icaos = _icaos.Where(pair => (int) (_ticks - pair.Value) < timeoutTicks).ToDictionary(pair => pair.Key, pair => pair.Value);

利用CRC对数据进行校验,无错误返回 0(共112bits 信息位88bits, 校验位 112-88=24bits)

// CRC码计算及校验原理的最通俗诠释 https://blog.csdn.net/xianjuke008/article/details/109026335?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_utm_term~default-0.pc_relevant_baidujshouduan&spm=1001.2101.3001.4242private static uint GetLongFrameParity(byte[] frame){// frame的大小位 112bits,其中校验位 24bits  信息位 112-24=88bits,利用移位法实现多项式的相除(异或)var data = (uint)(frame[0] << 24) | (uint)(frame[1] << 16) | (uint)(frame[2] << 8) | frame[3];var data1 = (uint)(frame[4] << 24) | (uint)(frame[5] << 16) | (uint)(frame[6] << 8) | frame[7];var data2 = (uint)(frame[8] << 24) | (uint)(frame[9] << 16) | (uint)(frame[10] << 8);//补充形成32bitsfor (var i = 0; i < 88; i++){if ((data & 0x80000000) != 0)//判断 data 首位是否位 1{data ^= Polynomial;// 与生成多项式 异或}data <<= 1; // 左移 1bit,后面补 0if ((data1 & 0x80000000) != 0){data |= 1; // 最后一bit 与1 或}data1 <<= 1; // 左移 1bitif ((data2 & 0x80000000) != 0){data1 |= 1;}data2 <<= 1;}var result0 = (byte)(data >> 24);// 取出前 8bitsvar result1 = (byte)((data >> 16) & 0xff);// 取出中间 8bits,关键是byte为8bits 对数据进行截断处理 只取8bitsvar result2 = (byte)((data >> 8) & 0xff); // 取出中间靠后 8bits// 验证与检验位的是否相等var sum = (uint) ((result0 ^ frame[11]) << 16) | (uint) ((result1 ^ frame[12]) << 8) | (uint)(result2 ^ frame[13]);return sum;}

## 程序解析(数据传输流程:从两头往中间过度)private static readonly uint _readLength = 16 * 1024;//每次处理的数据量(1) NativeMethods.rtlsdr_read_async(_dev, _rtlCallback, (IntPtr) _gcHandle, 0, _readLength);_rtlCallback=RtlSdrSamplesAvailable;(2) private static void RtlSdrSamplesAvailable(byte* buf, uint len, IntPtr ctx);(3) private void ComplexSamplesAvailable(Complex* buffer, int length);//数据长度已经变为 _readLength/2=8*1024=8192(4) SamplesAvailable(this, _eventArgs);实现由byte*类型的数据到 Complex*类型的数据,由三个参数变成两个参数。输出 (this, _eventArgs)参数。(this没有意义,SamplesAvailable 是 public delegate void SamplesAvailableDelegate(object sender, SamplesAvailableEventArgs e)类型的事件)
(5)该委托事件绑定的函数是
_rtlDevice.SamplesAvailable += rtlDevice_SamplesAvailable;
(6)对应的实现函数为:
private void rtlDevice_SamplesAvailable(object sender, SamplesAvailableEventArgs e){_callback(this, e.Buffer, e.Length);}
(7)_callback是该委托的实例化 public unsafe delegate void SamplesReadyDelegate(object sender, Complex *data, int length);(8)   _callback = callback;
callback是 委托类型 (SamplesReadyDelegate callback);
(9)_callback  的类型来自于 _rtlDevice.Start(rtl_SamplesAvailable);的输入函数rtl_SamplesAvailable;#region Samples Callbackprivate void rtl_SamplesAvailable(object sender, Complex* buf, int length){for (var i = 0; i < length; i++){//length=8192=8*1024var real = buf[i].Real;var imag = buf[i].Imag;var mag = real * real + imag * imag;_decoder.ProcessSample(mag);}}#endregion(10)后续的解码public void ProcessSample(int mag){_ticks++;if (_ticks % (10 * OneSecond) == 0) // Happens every 10sec  十秒处理更新一次{var timeoutTicks = _timeout * OneSecond;//只刷新保存不同飞机的 最近 120S 的数据,最近120秒的飞机进行保存,即只保存最近120S的飞机ICAO_icaos = _icaos.Where(pair => (int) (_ticks - pair.Value) < timeoutTicks).ToDictionary(pair => pair.Key, pair => pair.Value);}if (_reset){_icaos.Clear();_candidateICAOs.Clear();_reset = false;}_candidate[_candidateHead] = mag;//每次处理的数据点都放在数组_candidate[16+112*8],循环填充,长度不变_candidateHead = (_candidateHead + 1) % _candidate.Length;//校验下个数据是否是帧头(数据处理的很有技巧性NB)if (IsPreambleValid()){ReadData();}}(11)解码后输出对应的满足条件的数据帧
FrameReceived(_frame, frameBitLength / 8);
(12)完成数据的传输导出_decoder.FrameReceived += delegate(byte[] frame, int length){ Interlocked.Increment(ref _frameCount);                                              _frameSink.FrameReady(frame, length); };
// 帧头校验public bool IsPreambleValid(){var lastOne = 0;var lastZero = 0;var queuePtr = _candidateHead;for (var i = 0 ; i < _preamble.Length ; i++){var mag = _candidate[queuePtr];queuePtr = (queuePtr + 1) % _candidate.Length;if (_preamble[i] == 1){if (mag > lastZero){lastOne = mag;}else{return false;}}else{if (mag < lastOne){lastZero = mag;}else{return false;}}}return true;}
// 数据解调 即 PPM(脉冲编码调制解码)private void ReadData(){var queuePtr = (_candidateHead + PreambleLengthBits) % _candidate.Length;Array.Clear(_frame, 0, _frame.Length);var frameBitLength = 0;var lastMag = 0f;var lastAvg = 0f;for (var i = 0; i < LongFrameLengthBits * 2; i++){var mag = (float) _candidate[queuePtr];queuePtr = (queuePtr + 1) % _candidate.Length;if (i % 2 != 0){//if (i == frameBitLength * 2 - 1 && _frame[0] == 0x5d && _frame[1] == 0x3c && _frame[2] == 0x4d && _frame[3] == 0xd2)//{//    Console.WriteLine("Ba333");//}var avg = (mag + lastMag) * 0.5f;if (lastAvg > 0f){var correction = -CorrectionFactor * (avg - lastAvg) / avg;if (correction > 0){mag += correction;avg = (mag + lastMag) * 0.5f;}}lastAvg = avg;var bit = lastMag > mag ? 1 : 0;var frameBitPosition = i / 2;if (bit == 1){var index = frameBitPosition / 8;var shift = 7 - (frameBitPosition % 8);_frame[index] += (byte) (1 << shift);}if (frameBitPosition == 7){if (_frame[0] == 0){return;}var df = (_frame[0] >> 3) & 0x1f;frameBitLength = df >= 16 ? LongFrameLengthBits : ShortFrameLengthBits;}#region 已经运行到该数据帧的末端,形成完整的一帧if (frameBitLength > 0 && frameBitPosition == frameBitLength - 1){var length = frameBitLength / 8;if (_frame[length - 1] == 0 && _frame[length - 2] == 0 && _frame[length - 3] == 0){return;}var icao = GetICAOAddress(_frame);var df = (_frame[0] >> 3) & 0x1f;if (df == 17 || df == 18){if (GetLongFrameParity(_frame) != 0){UpdateConfidenceList(icao);return;}}else if (df == 11){if (GetShortFrameParity(_frame) != 0){UpdateConfidenceList(icao);return;}}else if (!_icaos.ContainsKey(icao)){if (!UpdateConfidenceList(icao)){return;}}_icaos[icao] = _ticks;_candidateICAOs.Remove(icao);if (FrameReceived != null){FrameReceived(_frame, frameBitLength / 8);//数据委托输出 绑定函数输出}return;}//#endregion}lastMag = mag;}}

```csharp
//获取ICAO 号,数据帧的第1 2 3 字节public static uint GetICAOAddress(byte[] frame){uint icao;var df = (frame[0] >> 3) & 0x1f;if (df == 11 || df == 17 || df == 18){icao = (uint) (frame[1] << 16) | (uint) (frame[2] << 8) | frame[3];}else{icao = df >= 16 ? GetLongFrameParity(frame) : GetShortFrameParity(frame);if (icao == 0){icao = (uint) (frame[1] << 16) | (uint) (frame[2] << 8) | frame[3];}}return icao;}
//完成长帧校验 112bits,输出是否为 0private static uint GetLongFrameParity(byte[] frame){var data = (uint)(frame[0] << 24) | (uint)(frame[1] << 16) | (uint)(frame[2] << 8) | frame[3];var data1 = (uint)(frame[4] << 24) | (uint)(frame[5] << 16) | (uint)(frame[6] << 8) | frame[7];var data2 = (uint)(frame[8] << 24) | (uint)(frame[9] << 16) | (uint)(frame[10] << 8);for (var i = 0; i < 88; i++){if ((data & 0x80000000) != 0)//(与操作运算符) data 的首字节是否为 1{data ^= Polynomial;//异或}data <<= 1;//左移1位  data =data<< 1;if ((data1 & 0x80000000) != 0){data |= 1;//或}data1 <<= 1;if ((data2 & 0x80000000) != 0){data1 |= 1;}data2 <<= 1;}var result0 = (byte)(data >> 24);var result1 = (byte)((data >> 16) & 0xff);var result2 = (byte)((data >> 8) & 0xff);var sum = (uint) ((result0 ^ frame[11]) << 16) | (uint) ((result1 ^ frame[12]) << 8) | (uint)(result2 ^ frame[13]);return sum;}

// 有MainForm程序进入接收数据程序
(1) class MainForm 下有startBtn_Click事件
(2)StartDecoding方法,包括建立数据服务器和接收数据部分;
(3)接收数据并处理部分包括:
RtlSdrIO _rtlDevice = new RtlSdrIO(); // RtlSdrIO:Start进入硬件接收数据程序和rtl_SamplesAvailable数据的解析
_rtlDevice.Start(rtl_SamplesAvailable);//
private void rtl_SamplesAvailable(object sender, Complex* buf, int length) { _decoder.ProcessSample(mag);}//进入对数据的解析
//函数原型为:RtlSdrIO :
public void Start(SamplesReadyDelegate callback);

public unsafe delegate void SamplesReadyDelegate(object sender, Complex *data, int length);
private SamplesReadyDelegate _callback;
由三参数转换成两个参数(为事件,为后续委托绑定奠定基础)

private void rtlDevice_SamplesAvailable(object sender, SamplesAvailableEventArgs e)
{
_callback(this, e.Buffer, e.Length);
}

// Start执行相应的接收数据线程,从硬件获取数据
class RtlDevice: _worker = new Thread(StreamProc);
NativeMethods.rtlsdr_read_async(_dev, _rtlCallback, (IntPtr) _gcHandle, 0, _readLength);
_rtlCallback:
private static readonly RtlSdrReadAsyncDelegate _rtlCallback = RtlSdrSamplesAvailable;
private static void RtlSdrSamplesAvailable(byte* buf, uint len, IntPtr ctx){ instance.ComplexSamplesAvailable(instance._iqPtr, instance._iqBuffer.Length);};// 完成由byte* buf转换成Complex* buf类型,其中是两个参数
private void ComplexSamplesAvailable(Complex* buffer, int length)
{
if (SamplesAvailable != null)
{
_eventArgs.Buffer = buffer;
_eventArgs.Length = length;
SamplesAvailable(this, _eventArgs);//复数到事件的转换
}
}
public event SamplesAvailableDelegate SamplesAvailable;
public delegate void SamplesAvailableDelegate(object sender, SamplesAvailableEventArgs e);
上述是完成由硬件接收数据到事件函数的转换;

   从硬件获取处理后的处理:(1)获取的是复数,转换成模值;(2)放在一个数组里面_candidate[16+112*2=240];循环填充对应的模值(3) 首先判断帧头的存在及其位置     (4)找出帧头后,对后面的信息进行解码 (PPM解码规则:数据由高到低为1,由低到高为0),码元(bit)个数为112(长码)或56(短码).(5)   数据解码到最后一帧完成后 委托输出 FrameReceived(_frame, frameBitLength / 8);(6)对接收到的数据帧变成字符串进行转发处理var sb = new StringBuilder();sb.Append("*");for (var i = 0; i < actualLength; i++){sb.Append(string.Format("{0:X2}", frame[i]));}sb.Append(";\r\n");
// AdsbReader的数据输出 不同的端口输出不同的格式,
#781A23,B10ZK   ,34.769943,112.475561,2700,115.4,351.03,0,2021-07-25 21:17:28.675,$
#781038,CHB6265 ,35.677826,113.727379,24025,419.5,58.85,0,2021-07-25 21:17:30.134,$
#7818A2,CDC8980 ,34.860901,112.082800,28275,454.7,58.58,0,2021-07-25 21:17:30.310,$
#780450,CCA1307 ,34.978867,112.481895,40725,492.2,196.89,0,2021-07-25 21:17:30.401,$#7804D4,CBJ5810 ,35.284973,112.620621,29425,487.9,203.04,0,2021-07-25 21:17:30.302,$
#780E93,KNA8246 ,35.333176,112.639618,27100,461.0,238.48,-64,2021-07-25 21:17:31.154,$
#781038,CHB6265 ,35.679428,113.730640,24025,419.5,58.85,0,2021-07-25 21:17:31.249,$#781BA8,CES6386 ,35.014526,112.002140,29350,487.4,238.59,0,2021-07-25 21:17:24.048,$#781A23,B10ZK   ,34.771317,112.475225,2700,115.7,347.52,0,2021-07-25 21:17:31.351,$
#7804D4,CBJ5810 ,35.284103,112.620220,29425,487.9,203.04,0,2021-07-25 21:17:30.770,$
#7807F0,B9587   ,34.909149,112.366090,3425,109.2,183.67,-64,2021-07-25 21:17:29.401,$
#780450,CCA1307 ,34.974426,112.480213,40725,492.2,196.89,0,2021-07-25 21:17:32.097,$
$DISERVER:CLIENT:VATSIM FSD V3.09:abcdef@N:CDG4804:0343:1:34.76376:112.52982:26600:413:156:0$CRCDG4804:CLIENT:RN:B738 B-5516::1
@N:CDG4804:0343:1:34.76376:112.52982:26600:413:156:0
$CRCDG4804:CLIENT:RN:B738 B-5516::1
@N:B10ZK:0000:1:34.77072:112.36547:2400:103:2616:0
$CRB10ZK:CLIENT:RN: ::1
#PCSERVER:CLIENT:CCP:TA:B10ZK:2000
@N:B10ZK:0000:1:34.77072:112.36547:2400:103:2616:0
$CRB10ZK:CLIENT:RN: ::1
#PCSERVER:CLIENT:CCP:TA:B10ZK:2000
@N:B9587:0000:1:34.80050:112.35958:2925:111:2092:0
$CRB9587:CLIENT:RN: ::1
#PCSERVER:CLIENT:CCP:TA:B9587:2600
@N:B9587:0000:1:34.80050:112.35958:2925:111:2092:0
$CRB9587:CLIENT:RN: ::1
#PCSERVER:CLIENT:CCP:TA:B9587:2600
@N:CDC8980:7057:1:35.09238:112.54807:26600:453:668:0
$CRCDC8980:CLIENT:RN:A20N B-30DN::1
#PCSERVER:CLIENT:CCP:TA:CDC8980:26600
@N:CDC8980:7057:1:35.09238:112.54807:26600:453:668:0
$CRCDC8980:CLIENT:RN:A20N B-30DN::1
#PCSERVER:CLIENT:CCP:TA:CDC8980:26600
@N:CCA1356:4521:1:35.09459:112.47282:33100:436:656:0
$CRCCA1356:CLIENT:RN:A321 B-6385::1
@N:CCA1356:4521:1:35.09459:112.47282:33100:436:656:0
$CRCCA1356:CLIENT:RN:A321 B-6385::1
@N:KNA8246:2154:1:35.10030:112.17155:26075:461:2704:0
$CRKNA8246:CLIENT:RN:B738 B-6492::1
#PCSERVER:CLIENT:CCP:TA:KNA8246:27600
@N:KNA8246:2154:1:35.10030:112.17155:26075:461:2704:0
$CRKNA8246:CLIENT:RN:B738 B-6492::1
#PCSERVER:CLIENT:CCP:TA:KNA8246:27600
@N:CBJ5810:0020:1:34.83270:112.42904:30150:484:2204:0
$CRCBJ5810:CLIENT:RN:A319 B-6178::1
@N:CBJ5810:0020:1:34.83270:112.42904:30150:484:2204:0
$CRCBJ5810:CLIENT:RN:A319 B-6178::1
@N:CES7878:3777:1:35.86389:113.70902:23600:437:2704:0
$CRCES7878:CLIENT:RN:B738 B-5647::1
@N:CES7878:3777:1:35.86389:113.70902:23600:437:2704:0
$CRCES7878:CLIENT:RN:B738 B-5647::1
@N:CHB6265:5350:1:35.88782:114.15520:22600:420:656:0
$CRCHB6265:CLIENT:RN:A320 B-8642::1
@N:CHB6265:5350:1:35.88782:114.15520:22600:420:656:0
$CRCHB6265:CLIENT:RN:A320 B-8642::1
*930CF31B0CE038043E67FE6700FF;
*930CF30B8CE03C040E27FE6700FF;
*8D780C90F82100020049B8F4676E;
*8D780490F83100020049B8F4676E;
*019D9827698736947EF93FE3DBDA;
*019C98276987BEC47EE11FE3C3DA;
*CD3807F0EB0D97F8013C00E9481A;
*C53C03F0EB0593FC019E006D6C1A;
*8D780993F81320060049B8E1C767;
*8D780993F813A006004998E1C767;
*8E5801CD9910010CD12CC4E6EE40;
*8E5801CD99100104D02CC4F6EE40;
*02E615350E88BEEFE006041F3524;
*02E615350E88BE7C0007C41FB124;
*5D7BB13026597A371F07F3E183F7;
*5D7BB13026597A071F07F3E183F7;
*9C10B1D75E021F1A80C8A7FFCEE0;
*C410B1D75E021F1A80C8A7FFEEE0;
*5D78087C6A03229FFF3B801DE00F;
// AdsbSharp数据输出 TcpIP: 47806
*5D7809939EEAFB;
*8D78059F9941751C00045A7FB967;
*8D7809B29944A8B9A80C6286BC95;
*5D78087C6A0323;
*8D78099399102C8C502002C20F7B;
*80E1971D58B9D36822A22E07676E;
*80E19130588B0339AC7FBB0EF52C;
*5D78059FD6F8A1;
*8D78087C588B0339AC7FBBB71E5A;
*80E18EB05877035A3C9A6A33B857;
*8D780C905877035A3C9A6AC82822;
*8D7807E15829732D1A9FF5CC891E;
*8D78098D9910290C902486713C20;
*8D7807E1F81320060049B8774EF7;
*8D780C9099095B1A580432BECBA9;
*8D78059F9941751C00045A7FB967;
*505D470001169F;
*8D7809B258B9D367FEA227A14DC2;
*8D7809B29944A8B9A80C61795487;
*8D78098D5819333ADC9B7E93F129;
*80E1971D58B9D367FEA2276F44C0;
*02E61534F17CB7;
*8D78087CEA340858013C08A7DDAE;
*02E19534294154;
*0200049BEFBB53;
*8D78099399102A8C7020028D4DF6;
*0200049BEFBB53;
*8D78087C588B06D6ABE0762C989B;
*8D7807E1582976CA39FFFB7F196E;
*8C78098A210B9DF3E60820FADC99;
*8D7807E1210B9D77C208208DE853;
*8C78098A396FB717C9DEFAF88027;
*8D78087CF82300030049B8A5829D;
*8D78087C99097E1D3804435E33D1;
*8D7818EE5827C30B309E27FD28A6;
*5D7809939EEAFB;
*8D7807E1EA0D97F8013C00E9481A;
*8C7809FB3EB9B7197DE17938E9AC;
*5C7809FBB72514;
*5D78087C6A0323;
*02E1971DCB13AC;
*8D78059F58AB4703C605539B5BAA;
*8D7809B29944A7B9A80C6297DE8F;
*5D780C90573969;
*5D78059FD6F8A1;
*8D7809939910288C7020028B586A;
*8D7807E1582976CA3A00009211A4;
*8D7807E199107E02300405CF3E5D;
*8D78087C588B0339D87FDF90F5D3;
*8D78028C250C3074D72DE009BAF8;
*8D7807F49910778590100519B71E;
*8D780C9099095B1A380432714FD2;
*020005961E04E7;
*02E61130C97F62;
*8D780C90E11B9000000000A0691E;
*8D7809B258B9D367B4A21AA02221;
*8D78098D210B9DF4CE0820DD739E;
*8D78059F9941751C00085A37E367;
*167E6505D47000;
*8D7807F499107685D00C0538C782;
*8D78087C588B06D6D9E09A20FC38;
*8D780C905877035A789A9B8FD1B5;
*8D7807E1582976CA3C0007413806;
*8D780C9099095B1A380432714FD2;
*8D780C90F82100020049B8F4676E;
*8D78087C99097E1D3804435E33D1;
*8D78059F9941751C00085A37E367;
*8D78059F58AB4367D4A59742DE1F;
*5D78098D9E5E62;
*5D7809939EEAFB;
*02E19130114281;
*02E1971DCB13AC;
*0200049BEFBB53;
*20001130179ACB;
*80E19130588B06D6EDE0AA375F1B;
*8D7809B29944A5B9C80C625E4F68;
*8D78087C588B033A0680031674DA;
*5D780C90573969;
*8D78098D5819433AFC9B8440031F;
*8D7807E199107F019004051F4BE2;
*8D780C905877035A909AB03AAAA5;
*8D7809939910258C90240281993A;
*8D78087C99097E1D3804435E33D1;
*A00012B4B8D80030A40000C36CE0;
*8D780C9099095B1A380432714FD2;
*8D78059F9941751C00085A37E367;
*167E6505D47000;
*8D78028CEA38E858013C086720CB;
*8D78087CE104A500000000A1D2FC;
*8D78098D9910290C902486713C20;
*8D7809B2200D33B6D76C20E234B9;
*A0001130B3F80030A400001E1C3F;
*A0001130968A452CE02C002152B8;
*8D78098D581946D7E9FB9D4F861B;
*8D7807E15829732D20A013A00B19;
*8D7807E199107F015004057FB71D;
*02E19534294154;
*06410135F7CAD5;
*8D7807E1F81320060049B8774EF7;
*A8001303FFF2A1367FFCE6DB5173;
*5D7809939EEAFB;
*8D78087C99097E1D3004433091D9;
*A0001534969A1B2FA02C01FDC79E;
*8D780993EA0D97F8013C007FC18A;
*02E61534F17CB7;
*8D78059F58AB4367FAA5B7443808;
*800003145819433B0C9B870A7C4A;
*8D780C9099095B1A380432714FD2;
*8D78059F9941751C00085A37E367;
*8D7809B258B9D3670CA1FD543E09;
*2000171DCDCBE6;
*02E1971DCB13AC;
*5D7807E1C815E8;
*5D7809B260DF42;
*A0001534FFF2A1367FFCE67B47EE;
*A0001534969A1B2FA054012FBF85;
*8D78087CEA340858013C08A7DDAE;
*5D78098D9E5E62;
*5D78059FD6F8A1;
*8D7807E15829732D20A0185F9367;
*5D7809B260DF42;
*8D78087C588B06D71FE0D3BB0317;
*02E18EB0ACD42D;
*8C78098AF9114106624938662F56;
*02E61130C97F62;
*5D780C90573969;
*A0001534C0A8002FDC00001FA921;
*A0001534FFF2A1367FFCE67B47EE;
*A000171DC680002FF0000025E5DE;
*A0000F37FFDA9D347FFCCF1F1E6C;
*A0001534969A1B2FA01401533797;
*A000171DFC58DD3D7FCCE5F1D4C8;
*A000171DC789FD303FE400C447AC;
*8D7809939910228C90240288AD50;
*8D78087C99097E1D3004433091D9;
*8D780C905877035ABE9AD63FEBFF;
*8D78087CF82300030049B8A5829D;
*8D7809B258B9D702FA01E9B0F245;
*8D780C9099095B1A380432714FD2;
*8D78098D9910280C9024867236EE;
*8D78059F58AB47042E05A9064372;
*8D7807E15829732D22A01DBBF7DA;

(一)查验可用设备

(二)配置设备及界面参数

(三)响应按钮单击事件

(1)完成服务器端的设定,以便于完成数据的发送

(2)接收从硬件端口传送的数据

//— RtlSdrIO _rtlDevice = new RtlSdrIO();
public void Start(SamplesReadyDelegate callback);
_rtlDevice.Start(rtl_SamplesAvailable);

(3)对接收的数据及进行解析

接收的数据:

*8D78144899096B1BB0043F0530C7;
*8D781448588B06E5E5E78692DA93;
*8D78144899096B1BB0043F0530C7;
*8D781448E109B1000000000F2EC5;
*02E19534294224;
*02E19130115EB5;
*5D781448C3987D;
*02E61534F17FC7;
*8D781448EA340864B13C08FF688E;
*02E19534294224;
*200011301786FF;
*8D78144899096B1BB0043F0530C7;
*5D7806EFC64C29;
*02E19534294224;
*8D78144899096B1BB0043F0530C7;
*8D781448588B0349908747820B1C;
*8D7806EF58AB435A36979B4C562C;
*5D781448C3987D;
*A000113010030A80F5000029264E;
*A0001130B3F80030A8000047F307;
*A000113080529D353FFCE1C49761;
*A0001130963A4D2D600C005ED5C5;
*02E19130115EB5;
*5D7806EFC64C29;
*8D78144899096B1BB0043F0530C7;
*02E19130115EB5;
*A0001534966A192FA024005B200E;
*A0001130B3F80030A8000047F307;
*8D781448588B0349BE876B84A551;
*02E19130115EB5;
*8D7806EF58AB46F6BFF7EAFB97C1;
*02E61130C96356;
*02E19130115EB5;
*A0001130B3F80030A8000047F307;
*8D78144899096B1BB0043F0530C7;
*280009B1DFDEA7;
*5D7806EFC64C29;
*8D781448F82300060049B83B479F;
*02E19534294224;
*02E19534294624;
*A0001534C0A8002F8C0000481613;
*A000153480329F34FFFCE302C738;

三、dump 1090的使用

dump1090.exe --device-index 1 --interactive --net  --net-beast
dump1090.exe  --interactive*5d780d585dc125;CRC: 5dc125 (ok)DF 11: All Call Reply.Capability : Level 2+3+4 (DF0,4,5,11,20,21,24,code7 - is on airborne)ICAO Address: 780d58*8d780d58587176d9e653a62b36c3;CRC: 2b36c3 (ok)DF 17: ADS-B message.Capability : 5 (Level 2+3+4 (DF0,4,5,11,20,21,24,code7 - is on airborne))ICAO Address : 780d58Extended Squitter Type: 11Extended Squitter Sub : 0Extended Squitter Name: Airborne Position (Baro Altitude)F flag : oddT flag : non-UTCAltitude : 21575 feetLatitude : 93427 (not decoded)Longitude: 21414 (not decoded)*8d780d589940a131488c2c5ec41c;CRC: 5ec41c (ok)DF 17: ADS-B message.Capability : 5 (Level 2+3+4 (DF0,4,5,11,20,21,24,code7 - is on airborne))ICAO Address : 780d58Extended Squitter Type: 19Extended Squitter Sub : 1Extended Squitter Name: Airborne VelocityEW direction : 0EW velocity : 161NS direction : 0NS velocity : 394Vertical rate src : 0Vertical rate sign: 1Vertical rate : 35*8d780d4b588f8358c0f3c89d206f;CRC: 9d206f (ok)DF 17: ADS-B message.Capability : 5 (Level 2+3+4 (DF0,4,5,11,20,21,24,code7 - is on airborne))ICAO Address : 780d4bExtended Squitter Type: 11Extended Squitter Sub : 0Extended Squitter Name: Airborne Position (Baro Altitude)F flag : evenT flag : non-UTCAltitude : 27600 feetLatitude : 109664 (not decoded)Longitude: 62408 (not decoded)

四、

主程序

ADSBsharp程序解析相关推荐

  1. linux 可执行文件_linux中ELF二进制程序解析

    0. 简介 在Linux系统的可执行文件(ELF文件)中,开头是一个文件头,用来描述程序的布局,整个文件的属性等信息,包括文件是否可执行.静态还是动态链接及入口地址等信息:如下图所示: 程序文件中包含 ...

  2. 微信小程序PHP文件建在哪里,微信小程序解析H5文件方法

    经常有网友问怎么让微信小程序解析H5文件或者类似封装H5网页到APP里面?我一开始觉得这是不可能的,因为官方的解答是这样的: 每一个小程序页面是由同路径下同名的四个不同后缀文件的组成,如:index. ...

  3. 【C++教程】03.第一个程序解析

    第三章 第一个程序解析 前言 第一个程序也即是如何显示字符串"HelloWorld!",这是大多数程序员都走过的路.别提第一次成功编译时,我有多高兴,所以如果你还没编译成功,不要气 ...

  4. 库卡机器人CELL程序解析

    KUKA机器人  CELL程序 解析及注释 &ACCESS RVP &REL 4 &COMMENT HANDLER on external automatic DEF  CEL ...

  5. 逆波兰式 java_Java 实现《编译原理》中间代码生成 -逆波兰式生成与计算 - 程序解析...

    Java 实现<编译原理>中间代码生成 -逆波兰式生成与计算 - 程序解析 编译原理学习笔记 (一)逆波兰式是什么? 逆波兰式(Reverse Polish notation,RPN,或逆 ...

  6. MOOS程序解析记录(6)pLogger

    MOOS程序解析记录(6)pLogger 最近在使用数据记录的时候,发现了自己对于PLogger并不是很熟悉,很多语法规则并不是很懂,于是便升起了记录一下该模块的心思,虽然这个模块并不能算多重要,但是 ...

  7. MOOS程序解析记录(7)pMarinePID解析

    MOOS程序解析记录(7)pMarinePID解析 花了一天多的时间,对pMarinePID的源码进行了阅读,这里做一个分析记录,为后面改进控制算法做好基础. 前言 pMarinePID应用程序实现了 ...

  8. 常州abb机器人编程_ABB机器人编程程序解析

    ?ABB 机器人编程 1 程序解析: 1 .此程序是典型的 ABB 机器人官方编程思路与方法,分为主程序,初始化例行程序和轨迹程序. 2 .思路清晰,结构编排明确,方便使用者阅读. %%% ??VER ...

  9. 常州abb机器人编程_最新ABB机器人编程程序解析

    ABB 机器人编程 1 程序解析: 1 .此程序是典型的 ABB 机器人官方编程思路与方法,分为主程序,初始化例行程序和轨迹程序. 2 .思路清晰,结构编排明确,方便使用者阅读. %%% VERSIO ...

最新文章

  1. 资源管理器方法访问FTP服务
  2. 设计模式--解析器(Interpreter)模式
  3. 免费计算机维修基础教程,《计算机组装与维修基础教程》第1课:计算机基础知识.ppt...
  4. vba 字典_VBA中字典的基础概念及调用方法
  5. dateformat 返回类型_SpringBoot返回date日期格式化
  6. geoTools学习笔记001---(简介)
  7. Observable与Observer
  8. 我们为什么需要SDN?---致新人
  9. AD7124源码 兼容AD7124-4/8 代码都经过验证 有验证的项目PCB图
  10. 黑马程序员-学习日志-文件的合并
  11. 计算机表格快捷键,EXCEL表格所有的快捷键《excel一键到底 快捷键》
  12. Android的虚拟设备的缩写,Android虚拟设备的英语缩写是
  13. 软件资格证考试——初级程序员
  14. 《痞子衡嵌入式半月刊》 第 56 期
  15. 人物志 | 美团技术委员会前端通道主席洪磊:爱折腾的斜杠青年
  16. python中frame用法_Python实例之wxpython中Frame使用方法
  17. 关于小米电视不能访问电脑共享文件的解决方案之一
  18. java怎么定义一维数组_Java定义一个一维数组有哪几种方法
  19. 基于jeecgboot的支持flowable的排它网关之后的会签功能(二)
  20. 防火墙是什么,其作用是什么?

热门文章

  1. android调用webXml 查询发车站和到达站查询火车时刻表
  2. 教你玩转ps-刘青-专题视频课程
  3. MES设备管理的四大重要功能,速来了解
  4. 西门子1200连接安川伺服的心得
  5. 天宝R10不开机/天宝接收机不进系统/天宝R10的常见故障
  6. Nutz实现主键自增
  7. 系统调用recv的实现
  8. 公安视频监控系统建设存在问题及系统规划思路简析
  9. QQ可以直接在微信登陆了
  10. 关闭hp打印机 cd_打开和关闭CD托盘