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

编解码库使用

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

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

  1. “test_demo”目录下新建一个code_test.c文件。
    1
    vim code_test.c
    
  2. 按“i”进入编辑模式,填写编解码样例代码。
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    #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. 编译运行。
    1
    2
    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