asn1编解码小结

最近在做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;
}

其实自己也可以根据需要,写这么个回调函数,比如直接把数据写入文件等等。

以上,结束,自己做个小结,也希望能给他人提供点思路

你可能感兴趣的:(asn1编解码小结)