【问题标题】:How add a message optional parts in the ASN.1 generated C codes如何在 ASN.1 生成的 C 代码中添加消息可选部分
【发布时间】:2026-02-15 20:55:01
【问题描述】:

我使用来自libosmo-asn1-map 的C 代码来获得GSM_MAP 协议的实现。然后我尝试编码一个 “发送身份验证信息”消息。正如3GPP TS 29.002 中提到的,此消息包含一些强制性部分(例如'imsi')和一些可选部分(例如'requestingNodeType')。

/* SendAuthenticationInfoArg */
typedef struct SendAuthenticationInfoArg {
    IMSI_t   imsi;
    NumberOfRequestedVectors_t   numberOfRequestedVectors;
    NULL_t  *segmentationProhibited /* OPTIONAL */;
    NULL_t  *immediateResponsePreferred /* OPTIONAL */;
    struct Re_synchronisationInfo   *re_synchronisationInfo /* OPTIONAL */;
    struct ExtensionContainer   *extensionContainer /* OPTIONAL */;
    /*
     * This type is extensible,
     * possible extensions are below.
     */
    RequestingNodeType_t    *requestingNodeType /* OPTIONAL */;
    PLMN_Id_t   *requestingPLMN_Id  /* OPTIONAL */;
    NumberOfRequestedVectors_t  *numberOfRequestedAdditional_Vectors    /* OPTIONAL */;
    NULL_t  *additionalVectorsAreForEPS /* OPTIONAL */;

    /* Context for parsing across buffer boundaries */
    asn_struct_ctx_t _asn_ctx;
} SendAuthenticationInfoArg_t;

我使用了以下受 osmo-tcap-map 项目启发的 C 代码。

SendAuthenticationInfoArg_t ula;
memset(&ula, 0, sizeof(ula));

ASN1Common::OCTET_STRING_fromRevVal(&ula.imsi, 202015604083166);
ula.requestingNodeType = 0;
ula.numberOfRequestedVectors = 5;    
xer_fprint(stdout, &asn_DEF_SendAuthenticationInfoArg, &ula);

但 XER 输出中没有可选部分,而 'requestingNodeType' 已被初始化:

<SendAuthenticationInfoArg>
    <imsi>02 02 51 06 04 38 61 F6</imsi>
    <numberOfRequestedVectors>5</numberOfRequestedVectors>
</SendAuthenticationInfoArg>

如何启用可选部分(即在消息中添加“requestingNodeType”)?

【问题讨论】:

    标签: c asn.1


    【解决方案1】:

    requestingNodeTypenumberOfRequestedVectors 都是指针

    RequestingNodeType_t    *requestingNodeType /* OPTIONAL */;
    PLMN_Id_t   *requestingPLMN_Id  /* OPTIONAL */;
    NumberOfRequestedVectors_t  *numberOfRequestedAdditional_Vectors    /* OPTIONAL */;
    NULL_t  *additionalVectorsAreForEPS /* OPTIONAL */;
    

    所以你首先需要分配它们,它应该是这样的

    ula.requestingNodeType = malloc(sizeof(RequestingNodeType_t));
    asn_long2INTEGER(ula.requestingNodeType, RequestingNodeType_vlr);
    

    RequestingNodeType_t 的 typedef'd 为 ENUMERATED_t,即 typedef'd 为 INTEGER_t,这就是为什么我们不能直接分配值,而是使用 asn_long2INTEGER

    ula.numberOfRequestedVectors = malloc(sizeof(NumberOfRequestedVectors_t));
    *ula.numberOfRequestedVectors = 5;
    

    NumberOfRequestedVectors_t 的类型定义为long,所以这里我们可以直接赋值

    【讨论】: