如何使用 asn1c 生成的代码解码 MAP 调用消息

How to decode MAP Invoke messages using asn1c generated code

我正在使用 asn1c 根据 MA​​P 协议规范生成的 c 代码(即相应的 ASN1 文件)。请考虑以下示例代码:

// A real byte stream of a MAP message:
unsigned char packet_bytes[] = {
  0xa2, 0x60, 0x02, 0x01, 0x00, 0x30, 0x5b, 0x02,
  0x01, 0x38, 0xa3, 0x56, 0xa1, 0x54, 0x30, 0x52,
  0x04, 0x10, 0x7a, 0x0e, 0x1f, 0xef, 0x73, 0x77,
  0xbe, 0xb0, 0x9d, 0x6f, 0x23, 0x13, 0xfb, 0xc2,
  0x32, 0xa6, 0x04, 0x08, 0x65, 0xda, 0x19, 0x1e,
  0x18, 0x4b, 0x04, 0x99, 0x04, 0x10, 0x47, 0xe1,
  0x36, 0x82, 0xe9, 0xb3, 0xf3, 0x54, 0x76, 0x67,
  0x1d, 0xe4, 0xed, 0x25, 0xc8, 0x76, 0x04, 0x10,
  0x37, 0x1d, 0x80, 0x82, 0xde, 0xec, 0x70, 0x51,
  0xc6, 0xcd, 0x08, 0xc9, 0x30, 0x64, 0xc6, 0x54,
  0x04, 0x10, 0x82, 0xbc, 0x2d, 0xdb, 0x1d, 0x92,
  0x82, 0x34, 0x55, 0xbc, 0xeb, 0x87, 0x72, 0xf3,
  0x90, 0xce
};


// Initializing ...
MAP_Component_t _pdu, *pdu = &_pdu;
memset(pdu, 0, sizeof(*pdu));

// Decoding:
asn_dec_rval_t dec_ret = ber_decode(NULL, &asn_DEF_MAP_Component, (void **) &pdu, MAP_packet_bytes, sizeof(MAP_packet_bytes));

invokeIdopCode 参数被真实地检测到,解析器给我们一个名为 invokeParameters 的缓冲区,它是 ANY 类型。

GSM Mobile Application
    Component: invoke (1)
        invoke
            invokeID: -70
            opCode: localValue (0)
            invokeParameters: ....

问题是如何解码(解析)invokeParameters?

GSM Mobile Application
    Component: returnResultLast (2)
        returnResultLast
            invokeID: 0
            resultretres
                opCode: localValue (0)
                    localValue: sendAuthenticationInfo (56)
                authenticationSetList: quintupletList (1)
                    quintupletList: 1 item
                        AuthenticationQuintuplet
                            rand: 7a0e1fef7377beb09d6f2313fbc232a6
                            xres: 65da191e184b0499
                            ck: 47e13682e9b3f35476671de4ed25c876
                            ik: 371d8082deec7051c6cd08c93064c654
                            autn: 82bc2ddb1d92823455bceb8772f390ce

The invokeId and opCode parameters are truely detected, and the parser gives us a buffer named as invokeParameters which is of type ANY.

The question is how to decode (parse) invokeParameters?

您需要使用适当的类型(取决于操作代码)和 ANY 缓冲区的内容来调用 ber_decode。来自 ANY.h

typedef struct ANY {
    uint8_t *buf;   /* BER-encoded ANY contents */
    int size;   /* Size of the above buffer */

    asn_struct_ctx_t _asn_ctx;  /* Parsing across buffer boundaries */
} ANY_t;

在你的情况下应该是这样的

SendAuthenticationInfoArg_t _sai, *sai = &_sai;
memset(sai, 0, sizeof(*sai));

asn_dec_rval_t dec_ret = ber_decode(NULL,
                                    &asn_DEF_SendAuthenticationInfoArg, 
                                    (void **) &sai, 
                                    _pdu.invoke.invokeparameter->buf,
                                    _pdu.invoke.invokeparameter->size);