[关闭]
@natsumi 2017-01-13T01:55:53.000000Z 字数 10506 阅读 2000

Eclipse + AsnLab初探~

ASN


参考:

用ASN.1编译工具asn1c生成LTE-RRC消息解码程序
http://blog.csdn.net/peng_yw/article/details/22437251

ASN.1编解码模块在LTE协议栈中的研究与应用
http://wenku.baidu.com/view/cf19440dbb68a98271fefae8.html

【解决】eclipse 装插件长时间卡在 calculating requirements and dependencies
http://qyiyunso.blog.163.com/blog/static/35077686201111101851181/

ASN.1 C运行库用户指导
http://www.asnlab.cn/asncc/asnrt.html


1. AsnLab插件安装

http://www.asnlab.cn/installing.html
这里有安装ASN.1开发工具和可选的ASN.1编译器以及其他ASN.1工具的教程,是在线安装的。
我还是喜欢本地安装~比较快一些

1.1 下载

下载地址http://www.asnlab.cn/downloads.html
需要下载ASN.1 SDK(包含了C、C++、JAVA编译器插件)和相应语言的运行库
我是下了这两个

  • ASN.1 SDK (包含插件)3.14.1
  • asnrt_windows_x86-3.14.15.zip

1.2 安装

  • 解压缩归档文件。
  • 在Eclipse中,选择Help > Install New Software...
  • 在"Work with"中,单击“Add...按钮。出现"Add Repository"对话框。
  • 单击Local,然后选择你解压缩的目录,然后单击OK. 其路径出现在"Location"字段。让"Name"字段为空。
  • 选择你想要的软件组件。
  • 把“Contact all update sites during install to find required software”(寻找指定的软件前先访问所有更新站点)前面的勾去掉(否则会卡住)
  • 单击Next来检查要安装的项目清单,单击Next再次阅读并接受许可协议,然后单击Finish.
  • 当问是否重启时,选择重新启动Eclipse。

安装完成~

1.3 license

没有license的话,ASN.1 文件编译出的C数据结构文件不完整,没法用。
可以到这里申请个试用一个月的
http://www.asnlab.cn/freetrial.php
打开Eclipse,在Windows > Preferences,
复制并粘贴试用License到ASN.1 > [ASN.1 Compiler] > General > Serial Number.

2. .asn==>.c & .h

2.1 生成.asn文件

我需要LTE-RRC的asn规范。但是没有找到。
可以用下面的代码散落在word文档中的asn提取出来
先下载RRC标准,我用的是36331-c50.doc
将文档另存为txt格式,将其命名为36331-c50.txt。
编译运行下面的代码~注意设置argv[1]为txt文件名
vs2013中可通过项目->属性->配置属性->调试->命令参数来设置
运行完成后生成36331-c50.asn

  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. int main(int argc, char* argv[])
  6. {
  7. if (argc != 2)
  8. {
  9. return 1;
  10. }
  11. std::string output_file;
  12. std::string input_file = argv[1];
  13. int pos = input_file.find('.');
  14. if (pos == std::string::npos)
  15. {
  16. output_file = input_file + ".asn";
  17. }
  18. else
  19. {
  20. output_file = input_file.substr(0, pos) + ".asn";
  21. }
  22. std::fstream input;
  23. input.open(input_file.c_str(), std::fstream::in);
  24. if (input.fail() == true)
  25. {
  26. std::cout << "Please check input file is correct !" << std::endl;
  27. return 1;
  28. }
  29. std::fstream output;
  30. output.open(output_file.c_str(), std::fstream::out);
  31. if (output.fail() == true)
  32. {
  33. std::cout << "The output file can not be created here !" << std::endl;
  34. return 1;
  35. }
  36. std::string input_line;
  37. std::vector<std::string > vec_asn;
  38. std::vector<std::string >::iterator itr;
  39. const unsigned long cul_asn_idle = 0x0;
  40. const unsigned long cul_asn_start = 0x1;
  41. unsigned long asn_state = cul_asn_idle;
  42. while (std::getline(input, input_line))
  43. {
  44. if (cul_asn_idle == asn_state)
  45. {
  46. if (input_line.find("-- ASN1START") != std::string::npos)
  47. {
  48. asn_state |= cul_asn_start;
  49. }
  50. continue;
  51. }
  52. if (0 != (cul_asn_start & asn_state))
  53. {
  54. if (input_line.find("-- ASN1STOP") != std::string::npos)
  55. {
  56. asn_state = cul_asn_idle;
  57. }
  58. else
  59. {
  60. vec_asn.push_back(input_line);
  61. }
  62. }
  63. }
  64. for (itr = vec_asn.begin(); itr != vec_asn.end(); ++itr)
  65. {
  66. output << *itr << std::endl;
  67. }
  68. input.close();
  69. output.close();
  70. return 0;
  71. }

p.s. windows eclipse+asnlab会说生成的asn文件的796行"OPTIONAL"后面少了个逗号,加上就好了(可是感觉这里不该有逗号吧= =)。
(后来换了asn1c,就不报错了)

2.2 用eclipse生成.c和.h

按照ASN.1 C编译器使用入门里面的步骤

36331-c50.asn中其实有5个module,编译生成的5个和module同名的文件夹。

关于编码规则 ber per 。。。看这里
http://zh.wikipedia.org/wiki/ASN.1

注意,RRC是PER unaligned方式编码,所以要设置“Encoding Rules”
project-->properties-->Encoding Rules-->PER勾上~~
设置“Encoding Rules”

3. 引用运行库

对于下载的运行库,我从网上找到了两种引用方法
自动引用的成功了。。步骤如下

LIB手工引用步骤:

  1. 将 MyLib.h 和 MyLib.lib 文件拷贝到工程目录下。
  2. 包含头文件:#include “MyLib.h”
  3. 指定与静态库一起连接:#pragma comment(lib,”MyLib.h”)

LIB自动引用步骤: 亲测有效^^

  1. 将 MyLib.h 和 MyLib.lib文件拷贝到工程目录(工程名/工程名/)下。
  2. 选择项目->属性->连接器->输入->附加依赖项:输入要加载的 Lib 文件名。
  3. 包含头文件:#include "MyLib.h"
    (因为需引用运行库头文件的文件都在工程名/工程名/Module名,所以应修改路径#include "../asnrt.h"

4. VS2013调试中的问题

4.1 "Cannot find or open the PDB file"

报错一堆如下~

  1. 'Word2Asn.exe' (Win32): Loaded 'E:\visual studio 2013\Projects\Word2Asn\Debug\Word2Asn.exe'. Symbols loaded.
  2. 'Word2Asn.exe' (Win32): Loaded 'C:\Windows\System32\ntdll.dll'. Cannot find or open the PDB file.
  3. 'Word2Asn.exe' (Win32): Loaded 'C:\Windows\System32\kernel32.dll'. Cannot find or open the PDB file.
  4. 'Word2Asn.exe' (Win32): Loaded 'C:\Windows\System32\KernelBase.dll'. Cannot find or open the PDB file.
  5. 'Word2Asn.exe' (Win32): Loaded 'C:\Windows\System32\msvcp120d.dll'. Cannot find or open the PDB file.
  6. 'Word2Asn.exe' (Win32): Loaded 'C:\Windows\System32\msvcr120d.dll'. Cannot find or open the PDB file.
  7. The program '[7748] Word2Asn.exe' has exited with code 1 (0x1).

把"Microsoft Symbol Servers"勾上(Tools -> Options -> Debugging -> Symbols). 解决~

4.2 asnlab生成的代码有问题

有些结构体数组赋值时缺少","造成VS2013语法错误
选中“使用正则表达式”,对当前工程的文件用替换功能加上逗号~~~
替换

4.3 链接错误还没搞定

链接错误==

5. 换linux试试 = =|||

5.1 和上面差不多的准备工作

装eclipse(官网下载、解压)
装asnlab插件过程同上
doc-->txt-->asn-->.c&.h过程同上
生成的代码仍然存在4.2中的问题,使用替换修正

5.2 下载运行库

http://www.asnlab.cn/downloads.html
下载linux版本的运行库
我的64位是asnrt_linux_x64-3.14.15.zip

5.3 makefile初体验~

按照ASN.1 C编译器使用入门里面写的

在类Unix平台上,我们提供的C语言静态库的ASN.1 C运行库(.a归档)。 参照以下简化的说明使用(您可能更倾向使用make):

  • 下载ASN.1 C运行库包到任意目录并解压该包。
    复制C静态库(.a归档)和头文件到ASN.1 C编译器编译产生的文件的目录。
  • 在该目录下编译产生的所有代码:
    $ gcc -c *.c
  • 连接 .o 文件和运行库, 比如:
    $ gcc -o test *.o -L. -lasnrt
  • 如果没有错误信息, 则可以运行:
    $ ./test

自制makefile

  1. run: test
  2. @ ./$?
  3. test: *.c
  4. gcc -c *.c
  5. gcc -o test *.o -L. -lasnrt
  6. onlytest:test.c *.o
  7. gcc -c test.c
  8. gcc -o test *.o -L. -lasnrt
  9. clean:
  10. rm -f *.o

5.4 测试代码

  1. //test.c
  2. #include "stdio.h"
  3. #include "stdlib.h"
  4. #include "stdarg.h"
  5. #include "BCCH_DL_SCH_Message.h"
  6. int main(void) {
  7. struct BCCH_DL_SCH_Message my_SIB;
  8. struct SystemInformationBlockType1 sib1;
  9. struct SystemInformationBlockType2 sib2;
  10. struct SystemInformationBlockType3 sib3;
  11. struct SystemInformationBlockType4 sib4;
  12. struct SystemInformationBlockType5 sib5;
  13. struct InterFreqCarrierFreqInfo temp;
  14. int table_windowlen[] ={1,2,5,10,15,20,40};
  15. int table_siPeri[] = {8,16,32,64,128,256,512};
  16. int i,j,k,looptime,x=0,a =0,SFNmod=0;
  17. int si_WindowLength = 0,tdd_Config_subfrmAssignment,tdd_Config_SsubfrmPattern,num_SI = 0,num_SIBType[32] = {0},si_peri[32] = {0},SIBType[32][32]={{0}};//sib1
  18. int highSpeedFlag, prach_ConfigIdx, prach_FreqOffset, zeroCorrelationZoneConfig;//prach
  19. int delta_PUCCH_shift = 0,N_PUCCH1 = 0, N_cs1 = 0, N_rb2 = 0;//pucch
  20. int flag_SI[5] = {0},flag_sib[18]={0};//flag
  21. int num_interFreqCell = 0,CellId_interFreq[16] = {0}; //parameter for sib4
  22. int num_interFreqCarrier = 0, ARFCN_interFreq[8] = {0}; //parameter for sib5
  23. int SFN_num = 0,subfrm = 0;
  24. int arr1[]={112,81,128,1,2,0,0,9,160,8,3,89,66,130,6,32,136,187,0,113,126,141}; //SIB1
  25. int arr2[]={0,128,27,88,223,95,90,176,96,48,134,150,228,48,1,4,1,36,2,113,126,141,82,72,64,1,194,16,12,0,76,64};//SI1
  26. int arr3[]={0,137,20,14,120,22,240,37,224,99,193,71,129,175,24,172,148,62,43,86,0,91,94,178,81,192,173,88,1,109,120,64};//SI2
  27. for(looptime=0;looptime<3;looptime++){
  28. //ASN.1 decode
  29. AsnBuffer* buffer = alloc_buffer(32, true, UNALIGNED_PACKED_ENCODING_RULES);
  30. switch(looptime){
  31. case 0:
  32. for(i=0;i<32;i++){
  33. buffer->array[i] = (char)arr1[i];
  34. }
  35. // flag_sib[1] = 1;
  36. SFN_num = 0;
  37. subfrm = 5;
  38. break;
  39. case 1:
  40. for(i=0;i<32;i++){
  41. buffer->array[i] = (char)arr2[i];
  42. }
  43. // flag_SI[1] = 1;
  44. SFN_num = 0;
  45. subfrm = 0;
  46. break;
  47. case 2:
  48. for(i=0;i<32;i++){
  49. buffer->array[i] = (char)arr3[i];
  50. }
  51. // flag_SI[2] = 1;
  52. SFN_num = 1;
  53. subfrm = 0;
  54. break;
  55. default:
  56. printf("error\n");
  57. break;
  58. }
  59. decode_BCCH_DL_SCH_Message(buffer, &my_SIB);
  60. if(SFN_num%2 ==0 && subfrm == 5 ){ //for sib1
  61. flag_sib[1] = 1;
  62. }
  63. for(i=0;i<num_SI;i++)
  64. {
  65. x = i*si_WindowLength;
  66. a = x%10;
  67. SFNmod = x/10;
  68. if(SFN_num%si_peri[i] ==SFNmod && subfrm == a )//for SI
  69. {
  70. flag_SI[i+1] = 1;
  71. }
  72. }
  73. for(k=1;k<5;k++){
  74. if(flag_SI[k]){
  75. flag_SI[k] = 0;
  76. if(k==1)
  77. flag_sib[2] = 1;
  78. for(i=0;i<num_SIBType[k-1];i++){
  79. j = SIBType[k-1][i];
  80. flag_sib[j+3] = 1;
  81. }
  82. }
  83. }
  84. if(flag_sib[1]){ //sib1
  85. flag_sib[1] = 0;
  86. printf("**************************SIB1*******************************\n");
  87. sib1 = my_SIB.message.value.c1.value.systemInformationBlockType1;
  88. si_WindowLength = table_windowlen[sib1.si_WindowLength];//look up the windowlength table
  89. tdd_Config_subfrmAssignment = sib1.tdd_Config->subframeAssignment;
  90. tdd_Config_SsubfrmPattern = sib1.tdd_Config->specialSubframePatterns;
  91. num_SI = sib1.schedulingInfoList.size;
  92. for(j=0;j<num_SI;j++){
  93. si_peri[j] = table_siPeri[sib1.schedulingInfoList.elements[j].si_Periodicity];//SI1 sib2 Periodicity
  94. printf("periodicity of SI%d is %d\n",(j+1),si_peri[j]);
  95. num_SIBType[j] = sib1.schedulingInfoList.elements[j].sib_MappingInfo.size;
  96. if(j==0)
  97. printf("\tSI1 include sibType2\n");
  98. else{//xietianrui
  99. for(k=0;k<num_SIBType[j];k++){
  100. SIBType[j][k] = sib1.schedulingInfoList.elements[j].sib_MappingInfo.elements[k];//index of SIB-Type
  101. printf("\tSI%d include sibType%d\n",(j+1),SIBType[j][k]+3);
  102. }
  103. }
  104. }
  105. }
  106. else //SI
  107. {
  108. // sib2 pucch,prach para
  109. if(flag_sib[2]){
  110. flag_sib[2] = 0;
  111. printf("**************************SIB2*******************************\n");
  112. sib2 = my_SIB.message.value.c1.value.systemInformation.criticalExtensions.value.systemInformation_r8.sib_TypeAndInfo.elements[0].value.sib2;
  113. //parameter for pucch
  114. delta_PUCCH_shift = sib2.radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift+1;
  115. N_rb2 = sib2.radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI;
  116. N_cs1 = sib2.radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN;
  117. N_PUCCH1 = sib2.radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN;
  118. printf("parameter for PUCCH\n");
  119. printf("\tdelta_PUCCH_shift is %d\n",delta_PUCCH_shift);
  120. printf("\tN_rb2 is %d\n",N_rb2);
  121. printf("\tN_cs1 is %d\n",N_cs1);
  122. printf("\tN_PUCCH1 is %d\n",N_PUCCH1);
  123. //parameter for prach
  124. highSpeedFlag = sib2.radioResourceConfigCommon.prach_Config.prach_ConfigInfo.highSpeedFlag;
  125. prach_ConfigIdx = sib2.radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_ConfigIndex;
  126. prach_FreqOffset = sib2.radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset;
  127. zeroCorrelationZoneConfig = sib2.radioResourceConfigCommon.prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig;
  128. printf("parameter for PRACH\n");
  129. printf("\thighSpeedFlag is %d\n",highSpeedFlag);
  130. printf("\tprach_ConfigIdx is %d\n",prach_ConfigIdx);
  131. printf("\tprach_FreqOffset is %d\n",prach_FreqOffset);
  132. printf("\tzeroCorrelationZoneConfig is %d\n",zeroCorrelationZoneConfig);
  133. }
  134. // sib4 cellid
  135. if(flag_sib[4]){
  136. flag_sib[4] = 0;
  137. printf("**************************SIB4*******************************\n");
  138. sib4 = my_SIB.message.value.c1.value.systemInformation.criticalExtensions.value.systemInformation_r8.sib_TypeAndInfo.elements[0].value.sib4;
  139. num_interFreqCell = sib4.intraFreqNeighCellList->size;
  140. for(j=0;j<num_interFreqCell;j++)
  141. {
  142. CellId_interFreq[j] = sib4.intraFreqNeighCellList->elements[j].physCellId;
  143. printf("phyCellId of intraFreq is %d\n",CellId_interFreq[j]);
  144. }
  145. }
  146. // sib5 Freq
  147. if(flag_sib[5]){
  148. flag_sib[5] = 0;
  149. printf("**************************SIB5*******************************\n");
  150. sib5 = my_SIB.message.value.c1.value.systemInformation.criticalExtensions.value.systemInformation_r8.sib_TypeAndInfo.elements[1].value.sib5;
  151. num_interFreqCarrier = sib5.interFreqCarrierFreqList.size;
  152. for(j=0;j<num_interFreqCarrier;j++)
  153. {
  154. ARFCN_interFreq[j] = sib5.interFreqCarrierFreqList.elements[j].dl_CarrierFreq;
  155. printf("ARFCN of intraFreq is %d\n",ARFCN_interFreq[j]);
  156. }
  157. }
  158. }//END of SI
  159. free_buffer(buffer);
  160. }//END of bcch_dl_sch_message(looptime)
  161. system("PAUSE");
  162. return 0;
  163. }

6. Ubuntu + Eclipse + Asnlab成功~

测试的目录结构大概是酱紫的~

  1. asnlab_rrc_test
  2. |_EUTRA-RRC-Definitions
  3. | |_Asnlab生成的EUTRA-RRC-Definitions Module的.c & .h
  4. | |_test.c
  5. | |_makefile
  6. |_asnrt.h
  7. |_libasnrt.a

make命令编译运行~
解析测试结果

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注