In 2008, we introduced a new method of generating table constraint code in ASN1C. The initial approach was documented in the white paper "ASN1C C/C++ Code Generation for 3GPP and LTE Specifications". Since then, this approach has evolved to be used with other types of ASN.1 specifications that make use of table constraints such as those used in the security (PKIX, CMS) and legacy telecom (MAP) domains.
Along the way, it was discovered that the way tag constants were generated in C for these specifications was problematic in some cases. In order to make the names unique, sequential numbers were embedded in the names. This allowed reasonably short compact identifiers to be created, but the problem was that if new items were added, these numbers were subject to change which forced users into possibly having to update their application code.
The new approach, currently available in ASN1C v6.3 via the undocumented -fqtvalue (fully qualified T value) option, does away with the sequential numbers. When this is used, the format of a tag constant is as follows:
T_<ModuleName>_<ObjectSetName>_<identifier>
where <ModuleName> is the name of the ASN.1 module in which the declaration exists, <ObjectSetName> is the name of the ASN.1 object set, and <identifier> is a unique identifier which could either be the object name (if named objects were used in the object set) or the name of the unique identifier (if the object set declaration is inline).
This is best illustrated by means of an example. In the white paper, code generation of the HandoverProtocol IE field in the S1AP LTE protocol is discussed. The HandoverRequiredIEs information object set contains a set of information objects defined inline as follows:
HandoverRequiredIEs S1AP-PROTOCOL-IES ::= { { ID id-MME-UE-S1AP-ID CRITICALITY reject TYPE MME-UE-S1AP-ID PRESENCE mandatory } | { ID id-HandoverType CRITICALITY reject TYPE HandoverType PRESENCE mandatory } | ...
From this, with ASN1C v6.3.4, a tag constant enumerated type set in the following form was generated:
typedef enum { T4_UNDEF_, T4__HandoverRequiredIEs_1, T4__HandoverRequiredIEs_2, ...
In this case, the number 4 following the initial 'T' and the number at the end were arbitrary identifiers based on the position of the declaration within the specification. If anything changed, these numbers were subject to change.
If -fqtvalue is added to the ASN1C command line, the format of the constants changes:
typedef enum { T_S1AP_PDU_Contents_HandoverRequiredIEs_UNDEF_, T_S1AP_PDU_Contents_HandoverRequiredIEs_1, T_S1AP_PDU_Contents_HandoverRequiredIEs_2, ...
In this case, the format is improved because the arbitrary number '4' following the initial T has been replaced with the containing module name. However, the identifier used at the end is still a sequential number describing the position within the object set.
In ASN1C v6.4 (due out for release in early 2011), the format is further improved to do away with the numeric identifiers all together:
typedef enum { T_S1AP_PDU_Contents_HandoverRequiredIEs_UNDEF_, T_S1AP_PDU_Contents_HandoverRequiredIEs_id_MME_UE_S1AP_ID, T_S1AP_PDU_Contents_HandoverRequiredIEs_id_HandoverType, ...
In this case, the unique ID value defined within the corresponding information object class is used to identify each entry.
As can be seen, a downside of this new convention is that the names can get very long. For this reason, a new configuration command - alias - will be available to map ASN.1 names to names that should be used in the code. An example from the S1AP API is as follows:
<asn1config> <module name="S1AP-PDU-Descriptions"> <alias asn1name="S1AP-ELEMENTARY-PROCEDURES" codename="SEP"/> <alias asn1name="S1AP-ELEMENTARY-PROCEDURES-CLASS-1" codename="SEPC1"/> <alias asn1name="S1AP-ELEMENTARY-PROCEDURES-CLASS-2" codename="SEPC2"/> <codename>S1PDUDescr</codename> </module> <module name="S1AP-PDU-Contents"> <codename>S1PDUCont</codename> </module> </asn1config>
In this case, relatively long names in the specification are mapped to short names for use in the code. The example above is as follows if this configuration file is used:
typedef enum { T_S1PDUCont_HandoverRequiredIEs_UNDEF_, T_S1PDUCont_HandoverRequiredIEs_id_MME_UE_S1AP_ID, T_S1PDUCont_HandoverRequiredIEs_id_HandoverType, ...
The module name used in the constant has been shortened to S1PDUCont from S1AP_PDU_Contents.
Note that in ASN1C v6.4, this will become the default naming convention. A backward compatibility option will need to be used to use the older form.