最近在做asn1针对 车用通信的asn集进行编解码,比如bsm,spat,map等等,
网上找了不少资料,我是从这里下载asn1c-0.9.28.tar.gz的,http://lionet.info/asn1c/download.html
具体编译等步骤是参考这位大神的:https://blog.csdn.net/hunzhangzui9837/article/details/85282923
按以上操作,基本能满足需求,本人需要的是uper编解码,使用asnc -gen-PER *.asn生成.c .h即可。
下面简单说下我遇到的坑:
1.已有一份bsm的已编码数据,原以为数据没问题,然后,死活解不对;一度尝试研究per,uper,ber编解码规则
主要参考链接:https://blog.csdn.net/weixin_43408952/article/details/87453261
https://blog.csdn.net/qq_33336155/article/details/54563449
等等,甚至还怀疑过asn1c-0.9.28.tar.gz这个工具有bug,还想着找“FFASN1 Compiler”来尝试下,但是,但是,这位大神的源码就是找到不从哪里下载,也不知道怎么联系他,加梯子也没发现有可下载的资源,只是找到了一个ffasn1dump,但是这玩意对我无用啊,哪位兄弟姐妹能提供份ffasn1 compiler,不胜感激;后来经过逐个字节分析,发现原来是bsm数据不对,将前面的4个bit的数据去除,即可正确解码。
2.编码后产生很多多余的数据,我用的是uper编码,代码如下
memset(sendbuf, 0, sizeof(sendbuf));
ec = uper_encode_to_buffer(&asn_DEF_BasicSafetyMessage, msg, sendbuf, 512);
if (ec.encoded == -1)
{
fprintf(stderr,
"Could not encode MessageFrame (at %s)\n",
ec.failed_type ? ec.failed_type->name : "unknown");
exit(65); /* better, EX_DATAERR */
}
else
{
fprintf(stderr, "Created %s with PER encoded MessageFrame ec.encoded[%d]\n",
"", ec.encoded);
}
for (int i = 0; i < ec.encoded; i++)
{
printf("%02x ", sendbuf[i]);
}
原因出在我是以ec.encoded作为编码出的最后长度,其实,这是大错特错,这个长度一般会很大于实际编码了的数据长度;
我们应该用per_encoder.c里面的encode_to_buffer_cb这个函数来拿最后的编码数据,如下
static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
enc_to_buf_arg *arg = (enc_to_buf_arg *)key;
if(arg->left < size)
return -1; /* Data exceeds the available buffer size */
memcpy(arg->buffer, buffer, size);
arg->buffer = ((char *)arg->buffer) + size;
arg->left -= size;
printf("encode_to_buffer_cb:\n");
for (int i = 0; i < size; i++)
{
printf("%02x", *((unsigned char *)buffer + i));
}
printf("\n");
return 0;
}
其实自己也可以根据需要,写这么个回调函数,比如直接把数据写入文件等等。
以上,结束,自己做个小结,也希望能给他人提供点思路