最近接触了一个小项目,使用C++对cat021(0.26)报文进行解析。刚开始没有头绪,之后在参考了CSDN博主TimiWang的文章:https://blog.csdn.net/wangtingming/article/details/52400656(十分感谢)和阅读了英文文档之后,磕磕绊绊完成了这个小项目。在此,做一个小结。
1:预备知识
cat021报文格式(布局):

说明:
数据类型(cat)=021,占1个字节,表示数据块含有ADSB报文。
长度标志(LEN)占2个字节,表示整个数据块的总长度(包括cat和LEN字段)占有的字节数。
FSPEC表示字段说明(标志位所在)。
注:详细的报文解释说明请查阅官方文档。http://www.eurocontrol.int/publications/cat021-automatic-dependent-surveillance-broadcast-ads-b-messages-part-12

2:核心程序编写
首先声明并定义了两个类对解析数据进行封装保护。

class DatagramUap
{
private:int frn,len;std::string dataitemname;//数据名std::string dataitemNum;//数据编号std::vector<BYTE>databytes;//解析之后每个数据项对应的字节存放处(容器)
public:void setFrn(int value3){len=value3;}int getfrn(){return frn;}void setLen(int value4){len=value4;}int getLen(){return len;}void setDataitemname(std::string value5){dataitemname=value5;}std::string& getDataitemname(){return dataitemname;}void setDataitemNum(std::string value6){dataitemNum=value6;}std::string& getDataitemNum(){return dataitemNum;}void setDatabytes(std::vector<BYTE> value){databytes=value;}std::vector<BYTE> getDatabytes(){return databytes;}
}
class DataBlock
{
private:int cat,len;std::<DatagramUap> dataitem;
public:void setCat(int value1){cat=value1;}int getCat(){return cat;}void setLen(int value2){len=value2;}int getLen(){return len;}void setDataitem(std::list<DatagramUap> v1){dataitem=v1;}std::list<DatagramUap> getDataitem(){return dataitem;}
}

接下来开始编写数据包解析函数:

DataBlock DataParser(BYTE datas[])
{int cat=0;//初始化int len=0;std::vector<BYTE> fspecbytes;//创建一个空的容器BYTE temp[4];//创建临时数组DataBlock datablock;for(auto i=0;i<1;++i){temp[i]=data[i];}cat=temp1[0];for(auto i=0;i<sizeof(temp1);++i){temp1[i]=0;//重置数组,每个元素置零}for(auto i=0;i<2;++i}{temp1[i]=datas[i+1];}BYTE c;c=temp1[0];temp1[0]=temp1[1];temp1[1]=c;len=temp1[0];//LEN占两个字节,一般后一个字节即可表示数据总长度for(auto i=0;i<sizeof(temp1);++i) {temp[i]=0;}fspecbytes=getFspecBytes(datas);//获取标志符所占字节std::list<DatagramUap> dataitems=DatagramParser(fspecbytes,len,datas);//解析出数据项的实体列表datablock.setCat(cat);datalock.setLen(len);datablock.setDataitem(dataitem);return datablock;
}

上述程序中,在对cat和LEN进行对应分析之后,紧接着开始对标示符所占字节数进行分析。

//解析出标志符所占字节
std::vector<BYTE> getFspecBytes(BYTE datas[])
{int count=3;std::vector<BYTE> fspecbytes;//定义一个空容器//如果下一个字节是标识符while(IsMoreFspec(datas[count])){++count;}//确定标识符字节数std::vector<BYTE> lhs(count-2);fspecbytes=lhs;for(auto i=0;i<(count-2);++i){fspecbytes[i]=datas[i+3];}return fspecbytes;
}//判断下一个字节是否是符号字节
bool IsMoreFspec(BYTE temp)
{bool ismore=false;BYTE tempbytes[4];temp<<=7;//按位左移7位temp>>=7;tempbytes[0]=temp;if(0==tempbytes[0]) {ismore=false;}else{ismore=true;}return ismore;
}

而后再解析出数据项的实体列表

std::list<DatagramUap> DatagramParser(std::vector<BYTE> fspecbytes,int len,BYTE datas[])
{int count=0;std::list<DatagramUap> dataitems;std::list<DatagramUap>::iterator iter;int rhs=fspecbytes.size();while(count<rhs){int index=7;while(index>0){std::vector<BYTE> tempbytes(rhs);for(auto i=0;i<rhs;++i){tempbytes[i]=fspecbytes[i];}tempbytes[count]<<=7-index;tempbytes[count]>>=7;BYTE temp2[4];temp2[0]=tempbytes[count];if(temp2[0]!=0){DatagramUap datagramuap=InitDatagram(count,index);dataitems.push_back(datagramuap);//依次从列尾增加元素}index--;}++count;}int currentbytenum=0;std::vector<BYTE> databytes(len-3-rhs);for(auto i=0;i<(len-3-rhs);++i){databytes[i]=datas[i+3+rhs];}//遍历容器,封装数据for(iter=dataitems.begin();iter!=dataitems.end();iter++){int temp5=(*iter).getLen();std::vector<BYTE> bytes(temp5);for(auto i=0;i<temp5;++i){bytes[i]=databytes[i+currentbytenum];}(*iter).setDatabytes(bytes);//将每一项数据段对应字节存入容器中封装起来currentbytenum+=(*iter).getLen();}
return dataitems;
}
//根据位置确定数据项
//参数解释:count——标识符字节中的第几个字节;index——字节第几位
DatagramUap InitDatagram(int count,int index)
{DatagramUap datagram;switch(count){case 0:Datagram0(index,datagram);break;case 1:Datagram1(index,datagram);break;case 2:Datagram2(index,datagram);break;case 3:Datagram3(index,datagram);break;case 4:Datagram4(index,datagram);break;case 5:Datagram5(index,datagram);break;case 6:Datagram6(index,datagram);break;}return datagram;
}
//符合条件时,初始化对象
void Datagram0(int index,DatagramUap& datagram)
{switch(index){case 7:datagram.setDataitemname("数据源识别");//设置数据项名datagram.setDataitemNum("1021/010");//设置数据项参考编号datagram.setFrn(1);//设置字段参考编号datagram.setLen(2);//设置该数据段对应字节的字节数break;case 6:datagram.setDataitemname("目标报告描述符");datagram.setDataitemNum("1021/040");datagram.setFrn(2);datagram.setLen(2);break;case 5:datagram.setDataitemname("日时间");datagram.setDataitemNum("1021/030");datagram.setFrn(3);datagram.setLen(3);break;case 4:datagram.setDataitemname("在WGS-84坐标中的位置");datagram.setDataitemNum("1021/130");datagram.setFrn(4);datagram.setLen(8);break;case 3:datagram.setDataitemname("目标地址");datagram.setDataitemNum("1021/080");datagram.setFrn(5);datagram.setLen(3);break;case 2:datagram.setDataitemname("几何高度");datagram.setDataitemNum("1021/140");datagram.setFrn(6);datagram.setLen(2);break;case 1:datagram.setDataitemname("品质因素");datagram.setDataitemNum("1021/090");datagram.setFrn(7);datagram.setLen(2);break;}
}

//在此只列出部分对应函数。
对于完整的代码,请下载底部文件查阅。

int main()
{//测试数据BYTE temp[] = { 0x15,0x00,0x32,0xff,0xa1,0xdb,0x86,0xff,0xff,0x01,0x21,0x2d,0x15,0xa3,0x00,0x3f,0xa2,0xb3,0x01,0x45,0x0b,0xc8,0x89,0x91,0xa7,0x03,0xb4,0x00,0x07,0x48,0x00,0xea,0x00,0x9a,0x03,0x3a,0xcd,0xf6,0x34,0x40,0x71,0xe3,0x1d,0xe0,0x00,0x00,0x00,0x05,0x8f,0xb0};DataBlock datalock = DataParser(temp);list<DatagramUap>::iterator iter0;list<DatagramUap> temp0;temp0=datalock.getDataitem();int i = 1;for (iter0 = temp0.begin(); iter0 != temp0.end(); iter0++){//int i = 1;cout << "第" << std::dec<<i << "个数据。" << endl;cout << "数据条款名:"<< (*iter0).getDataitemname().c_str() << endl;cout << "数据编号:" << (*iter0).getDataitemNum().c_str() << endl;string num = (*iter0).getDataitemNum();vector<BYTE> temp10 = (*iter0).getDatabytes();//加入条件判断,符合则输出数据项对应的值if (num =="1021/010")//注意相等的表示{DataSourceIdentifiction(temp10);}else if (num == "1021/020"){EmitterCategory(temp10);}else if (num == "1021/030"){TimeOfDay(temp10);}else if (num == "1021/032"){TimeofDayAccuracy(temp10);}else if (num == "1021/040"){Target(temp10);}else if (num == "1021/070"){Mode3_ACodeinOctalRepresentation(temp10);}else if (num == "1021/080"){TargetAddress(temp10);}else if (num == "1021/090"){FigureOfMerit(temp10);}else if (num == "1021/095"){VelocityAccuracy(temp10);}else if (num == "1021/110"){}else if (num == "1021/130"){PositionWGS_84(temp10);}else if (num == "1021/131"){SignalAmplitude(temp10);}else if (num == "1021/140"){GeometricAltitude(temp10);}else if (num == "1021/145"){FlightLevel(temp10);}else if (num == "1021/146"){IntermediateStateSelectedAltitude(temp10);}else if (num == "1021/148"){FinalStateSelectedAltitude(temp10);}else if (num == "1021/157"){GeometricVerticalRate(temp10);}else if (num == "1021/160"){GroundVector(temp10);}else if (num == "1021/170"){TargetIdentification(temp10);}else if (num == "1021/200"){TargetStatus(temp10);}else if (num == "1021/210"){LinkTechnologyIndicator(temp10);}++i;}return 0;
}

对于该版本的报文的常规数据段解析方式在附件中有指出,在本文中没有讲述。

最后,欢迎大家讨论指正,不足之处请一定指出,谢谢。

链接如下:https://download.csdn.net/download/qingfengleerge/10581608

C++实现cat021(0.26版)报文解析相关推荐

  1. android 6.0 官方下载6,解析工具app v6.0安卓版下载-解析工具app v6.0安卓版官方下载 v6.5_手机乐园...

    软件简介 有了这个工具,不论是一些有水印的短视频还是付费音乐这里都可以轻松解析出来,十分便捷,别人的作品也可以轻松据为己有,水印一键轻松解除,而且操作起来基本上没有任何难度,听歌过程中遇到的一些需要收 ...

  2. 8583报文解析1.0

    8583报文解析1.0 文章目录 8583报文解析1.0 一.规则 1.1:域规范简表 1.2:规范说明 1.2.1: 报文头 1.2.2: 操作类型 1.2.3: 位图:有效域明细 1.2.4:域规 ...

  3. DLT645-2007 规约 电表 报文解析

    注:本文为转载 转载地址:https://wenku.baidu.com/view/cc10838283d049649b66580d.html DLT645-2007 规约 常见报文解析 //2012 ...

  4. 超30万字的中台实战100讲2.0最终版(建议收藏!)

    共3510字|阅读用时5分钟 目录V2.0终版迭代内容: 增加最近更新的中台系列文章至本目录: 根据最新热点修订并调整部分未更新内容方向: 目录V1.1迭代内容: 增加最近更新的中台系列文章至本目录: ...

  5. 20201217-IP报文解析

    20201215-IP报文解析 {1}报文结构 ![图片.png](https://img-blog.csdnimg.cn/img_convert/718558a49aa5479c6049e1ea7f ...

  6. 8583 报文解析过程

    一. 全局概述 1. <多渠道平台接入接口规范>这个标准规定了各种接入端(主要包括直联多渠道平台的终端, 包括这里主要关注的POS机)与中国银联多渠道平台之间进行联机交易时使用的报文接口, ...

  7. 动网php_动网论坛PHP增强版(动网论坛PHP2.0++官方下载)V2.0官方版下载 - 下载吧...

    开拓的力量,前进的方向,经历了一个冬的孕育,动网PHP2.0++正式版在我们团队的精心培养下,顺利与大家见面了.动网论坛PHP增强版此次正式版,一如既往的延续了PHP2.0++的创新功能,在新功能的基 ...

  8. Spark Release 2.0.0发版概序

    Spark2.0在2016年7月26日发布,因为工作中经常用到,所以对它关注比较多,正好今天"提前"下班,所以抽空翻译一下spark2.0发版概述,简单的介绍一下spark2.0的 ...

  9. 支付宝钱包接口开发包2.0标准版接入与使用规则

    接入与使用规则 支付宝钱包支付接口开发包 2.0 标准版 附录文档 版本号:1.3 支付宝(中国)网络技术有限公司 版权所有 支付宝钱包支付接口开发包 2.0 标准版附录文档 目录 1 文档说明... ...

最新文章

  1. java cxf服务端代码_【JAVA】 cxf 生成 webservice 服务端代码
  2. Linux-NFS原理介绍
  3. 浅析如何才能提高网站的信息交互能力?
  4. ab压力测试(了解ab工具,实验对网页进行测试)
  5. 面试必备Linux基础知识
  6. 超大超长图片居中显示且放大缩小无影响
  7. Android重力感应实现方式简介
  8. git常用命令及手动关联git本地和远端仓库
  9. npm ERR! Cannot read property ‘resolve‘ of undefined
  10. 2011最新笔记本、一体机显卡性能排行
  11. 完整的连接器设计手册_特斯拉的高压连接器
  12. rman异机恢复 Linux _RAC至Win_Single Instance note
  13. 《富爸爸穷爸爸》--读书笔记(5)-2020
  14. 显卡使用信息nvidia-smi命令
  15. 栖霞牌王是怎样炼成的——利用django实现网页版千秋戏(1)
  16. Java技术之AQS详解
  17. phpspreadsheet使用导出excel
  18. [转]多模匹配算法与dictmatch实现
  19. bitnamigitlab_bitnami gitlab 安装
  20. 【工具类】Themeleaf 模板中 strings 的常用方法整理

热门文章

  1. 录取通知书玩出新花样,西工大加入AR技术
  2. 东北大学计算机技术录取名单,东北大学2020年硕士研究生招生考试拟录取结果查询...
  3. 国际电话应该由谁来玩
  4. 分享下我的圣诞树,Merry Christmas
  5. 智能优化算法:骑手优化算法-附代码
  6. VIVO语音助手控制ESP8266点灯
  7. SAP MDG —— 更好地理解你的数据变更
  8. 数据库练习题第二篇(附答案)
  9. MySQL计算结束时间和开始时间的差值,并统计差值
  10. 磁感应强度B、磁场强度H、矢量磁位A的study