中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

编解码库使用

  • 编解码库libhiasn1.so,位于“/usr/local/ksl/lib”下。用户可以在编译源码时链接此库,提供用于将用户数据编码成码流,或将码流解码成用户数据的接口。
  • 编解码接口定义头文件,位于“/usr/local/ksl/include/hiasn1/”下,KSL_ASN1相关数据结构和接口定义位于此目录下。

本章节将演示如何使用编译工具使用中解析asn1文件生成的C代码文件,通过调用KSL_ASN1的编解码库接口,实现将已有数据编码成流,及如何将流解码为数据的方法。

  1. “test_demo”目录下新建一个code_test.c文件。
    vim code_test.c
  2. 按“i”进入编辑模式,填写编解码样例代码。
    #include <stdio.h>
    #include <stdbool.h>
    #include <string.h>
    #include "asn_codec.h"
    #include "exports/test/codec_index.h"
    #include "exports/test/codec_interfaces.h"
    
    // 缓冲区大小
    #define BUF_SIZE 128
    
    // 缓冲区
    uint8_t g_buffer[BUF_SIZE];
    
    // 用户数据
    MyType g_userData = {
        .boolType = 0,
        .intType = 10,
        .enumType = MY_TYPE_ENUM_TYPE_B,
        .bitStrType = {.bitCnt = 24, .item = "bit"},
        .octStrType = {.len = 12, .item = "Octet String"},
        .seqOfType = {.cnt = 3,
            .item =
                {
                    -1,
                    0,
                    255,
                }},
        .choiceType = {.choice = MY_TYPE_CHOICE_TYPE_B,
            .u =
                {
                    .b = 1,
                }},
    };
    
    // 编码测试
    bool EncodeTest(const AsnDesc *desc, AsnCodecMethod codecMethod)
    {
        AsnBuf buf = {0};          // 缓冲区结构体
        buf.buf = g_buffer;        // 设置缓冲区
        buf.bufLen = BUF_SIZE;     // 设置缓冲区大小
        AsnCtx ctx = {0};          // 上下文结构体,需要清零
        ctx.buf = &buf;            // 设置缓冲区
        ctx.method = codecMethod;  // 设置编码规则
    
        // 编码
        ssize_t ret = AsnEncode(desc, &g_userData, &ctx);
        if (ret < 0) {
            printf("failed to encoding data, ret: %zd\n", -ret);
            return false;
        }
    
        size_t encodedBytes = (size_t)ret;
        printf("successfully encoded into %zu bytes data\n", encodedBytes);
    
        // 打印编码结果
        printf("encoded: ");
        for (size_t i = 0; i < encodedBytes; ++i) {
            printf("%02X ", g_buffer[i]);
        }
        printf("\n");
    
        return true;
    }
    
    // 解码测试
    bool DecodeTest(const AsnDesc *desc, AsnCodecMethod codecMethod)
    {
        AsnBuf buf = {0};          // 缓冲区结构体
        buf.buf = g_buffer;        // 设置缓冲区
        buf.bufLen = BUF_SIZE;     // 设置缓冲区大小
        AsnCtx ctx = {0};          // 上下文结构体,需要清零
        ctx.buf = &buf;            // 设置缓冲区
        ctx.method = codecMethod;  // 设置编码规则
    
        // 解码
        MyType decoded = {0};
        ssize_t ret = AsnDecode(desc, &decoded, &ctx);
        if (ret < 0) {
            printf("failed to decoding data, ret: %zd\n", -ret);
            return false;
        }
        printf("successfully decoded\n");
    
        // 比较解码结果
        if (memcmp(&decoded, &g_userData, sizeof(MyType)) != 0) {
            printf("decoded result unexpected\n");
            return false;
        }
    
        return true;
    }
    
    int main()
    {
        // 获取结构对应的描述符
        const AsnDesc *desc = CODEC_GET_TEST(CODEC_IDX_TEST_MY_TYPE);
        // 编解码规则
        AsnCodecMethod codecMethod = ASN_BER;
    
        // 编码测试
        if (!EncodeTest(desc, codecMethod)) {
            return 1;
        }
    
        // 解码测试
        if (!DecodeTest(desc, codecMethod)) {
            return 1;
        }
    
        return 0;
    }
    • AsnBuf结构体的缓冲区和缓冲区大小的合法性由用户保证。
    • AsnCtx结构体需先清零,再对buf和method字段赋值。
    • 使用统一的编解码接口AsnEncode、AsnDecode,接口内部通过ctx.method判断编码模式。
    • 编解码接口返回值是ssize_t类型的:
      • 当返回值大于等于0时,表示编码成功,返回已编码字节数或比特数。
      • 当返回值小于0时,表示编码失败,错误码为返回值的绝对值,可在asn_codec_errors.h中找到对应的错误信息。
  3. 按“Esc”键,输入:wq,按“Enter”保存并退出编辑。
  4. 编译运行。
    gcc codec_test.c exports/test/*.c -I/usr/local/ksl/include/hiasn1/ -L/usr/local/ksl/lib/ -Wl,-rpath=/usr/local/ksl/lib/ -lhiasn1 -o codec_test
    ./codec_test