Using the Encoding and Decoding Library
- The encoding and decoding library libhiasn1.so is stored in /usr/local/ksl/lib. You can link this library during source code compilation. It provides interfaces for encoding user data into streams and decoding streams into user data.
- The header file that defines encoding and decoding interfaces is stored in /usr/local/ksl/include/hiasn1/. The data structure and interface definitions related to KSL_ASN1 are stored in this directory.
This section describes how to use the C code file generated by parsing ASN.1 files in Using the Compilation Tool to encode data into streams and decode the streams into data by calling the encoding and decoding interfaces of KSL_ASN1.
- Create a codec_test.c file in test_demo.
1vim codec_test.c - Press i to enter the insert mode and fill in the codec code.
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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
#include <stdio.h> #include <stdbool.h> #include <string.h> #include <assert.h> #include "asn_codec.h" #include "exports/test/codec_index.h" #include "exports/test/codec_interfaces.h" // Buffer size #define BUF_SIZE 64 // Buffer uint8_t g_buffer[BUF_SIZE]; // Encoding test bool EncodeTest(const AsnDesc *desc, AsnCtx *ctx) { // Prepare data to be encoded. OctStrType octStrArr[3] = { { .len = 2, .item = "\x12\x23" }, { .len = 2, .item = "\x45\x56" }, { .len = 2, .item = "\x78\x89" }, }; uint32_t oid[3] = {0, 1, 2}; MyType userData = { .boolType = false, .intType = 10, .enumType = MY_TYPE_ENUM_TYPE_A, .bitStrType = { .item = "\x01\x02\x03" }, .seqOfType = { .cnt = 3, .item = octStrArr }, .choiceType = { .choice = MY_TYPE_CHOICE_TYPE_B, .u = { .b = true, } }, .oidType = { .cnt = 3, .item = oid }, }; // Encoding ssize_t ret = AsnEncode(desc, &userData, ctx); if (ret < 0) { printf("failed to encode, ret: %zd\n", -ret); return false; } size_t encodedBytes = (size_t)(ret + 7) >> 3; printf("successfully encoded into %zu bytes data\n", encodedBytes); // Print the encoding result. printf("encoded: "); for (size_t i = 0; i < encodedBytes; ++i) { printf("%02X ", g_buffer[i]); } printf("\n"); // Verify the encoding result. uint8_t expected[] = "\x05\x00\x01\x02\x03\x03\x80\x12\x23\x80\x45\x56\x80\x78\x89\xC0\x02\x01\x02"; size_t expectedBytes = sizeof(expected) - 1; if (encodedBytes != expectedBytes || memcmp(g_buffer, expected, expectedBytes) != 0) { printf("expected: "); for (size_t j = 0; j < expectedBytes; ++j) { printf("%02X ", expected[j]); } printf("\n"); printf("encoded bytes unexpected\n"); return false; } return true; } // Decoding test void DecodeTest(const AsnDesc *desc, AsnCtx *ctx) { // Decoding MyType decoded = {0}; ssize_t ret = AsnDecode(desc, &decoded, ctx); if (ret < 0) { printf("failed to decode, ret: %zd\n", -ret); return; } printf("successfully decoded\n"); // Verify the decoding result. assert(decoded.boolType == false); assert(decoded.intType == 10); assert(decoded.enumType == MY_TYPE_ENUM_TYPE_A); assert(decoded.bitStrType.item[0] == 0x01); assert(decoded.bitStrType.item[1] == 0x02); assert(decoded.bitStrType.item[2] == 0x03); assert(decoded.seqOfType.cnt == 3); assert(decoded.seqOfType.item[0].len == 2); assert(decoded.seqOfType.item[0].item[0] == 0x12); assert(decoded.seqOfType.item[0].item[1] == 0x23); assert(decoded.seqOfType.item[1].len == 2); assert(decoded.seqOfType.item[1].item[0] == 0x45); assert(decoded.seqOfType.item[1].item[1] == 0x56); assert(decoded.seqOfType.item[2].len == 2); assert(decoded.seqOfType.item[2].item[0] == 0x78); assert(decoded.seqOfType.item[2].item[1] == 0x89); assert(decoded.choiceType.choice == MY_TYPE_CHOICE_TYPE_B); assert(decoded.choiceType.u.b == true); assert(decoded.oidType.cnt == 3); assert(decoded.oidType.item[0] == 0); assert(decoded.oidType.item[1] == 1); assert(decoded.oidType.item[2] == 2); } int main() { // Obtain the descriptor corresponding to the structure. const AsnDesc *desc = CODEC_GET_TEST_DESC(CODEC_IDX_TEST_MY_TYPE); // Obtain the context structure. AsnCtx *ctx = CODEC_GET_TEST_CTX(); AsnBuf buf; // Buffer structure buf.buf = g_buffer; // Set the buffer. buf.bufLen = BUF_SIZE; // Set the buffer size. // Pass the context structure and the buffer structure pointer for initialization. if (!AsnInit(ctx, &buf)) { printf("failed to init\n"); return 1; } // Encoding test if (!EncodeTest(desc, ctx)) { return 1; } // Decoding test DecodeTest(desc, ctx); // Release all internally allocated memory. AsnFree(ctx); return 0; }
- You need to ensure the validity of the buffer and buffer size of the AsnBuf structure.
- Before assigning values to the buf and method fields, you must clear the AsnCtx structure.
- Use the unified encoding and decoding interfaces AsnEncode and AsnDecode. The interfaces use ctx.method to determine the encoding method.
- The return values of the encoding and decoding interfaces are of the ssize_t type.
- If the return value is greater than or equal to 0, the encoding is successful, and the return value indicates the number of encoded bytes or bits.
- If the return value is less than 0, the encoding fails. The error code is the absolute value of the return value, and you can find the corresponding error information in asn_codec_errors.h.
- Press Esc, type :wq!, and press Enter to save the file and exit.
- Compile and run the project.
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
If the execution is successful, information similar to the following will be displayed:
1 2 3
successfully encoded into 19 bytes data encoded: 05 00 01 02 03 03 80 12 23 80 45 56 80 78 89 C0 02 01 02 successfully decoded
Parent topic: Usage Description