asn1c
asn1c copied to clipboard
SEQUENCE OF constrained INTEGER error
test.asn1
TEST
DEFINITIONS IMPLICIT TAGS ::=
BEGIN
TestINT ::= INTEGER (0..4294967295)
TestPDU ::= SEQUENCE {
one [0] SEQUENCE OF INTEGER (0..4294967295),
two [1] INTEGER (0..4294967295),
three [2] TestINT
}
END
Compile:
$ ../asn1c/asn1c -S ../skeletons -pdu=all -no-gen-PER -no-gen-OER -fcompound-names test.asn1
Compile example converter:
$ make -f converter-example.mk
cc -DASN_DISABLE_OER_SUPPORT -DASN_DISABLE_PER_SUPPORT -DASN_PDU_COLLECTION -I. -o TestPDU.o -c TestPDU.c
TestPDU.c:66:4: error: ‘asn_DEF_Member_3’ undeclared here (not in a function); did you mean ‘asn_TYPE_member_t’?
&asn_DEF_Member_3,
^~~~~~~~~~~~~~~~
asn_TYPE_member_t
make: *** [converter-example.mk:23: TestPDU.o] Error 1
TestPDU.c
/*
* Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
* From ASN.1 module "TEST"
* found in "/tmp/asn1/test.asn1"
* `asn1c -S ../skeletons -pdu=all -Wdebug-lexer -Wdebug-parser -Wdebug-fixer -Wdebug-compiler -no-gen-PER -no-gen-OER -fcompound-names`
*/
#include "TestPDU.h"
static int
memb_NativeInteger_constraint_2(const asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
if(!sptr) {
ASN__CTFAIL(app_key, td, sptr,
"%s: value not given (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
/* Constraint check succeeded */
return 0;
}
static int
two_4_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
if(!sptr) {
ASN__CTFAIL(app_key, td, sptr,
"%s: value not given (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
/* Constraint check succeeded */
return 0;
}
/*
* This type is implemented using NativeInteger,
* so here we adjust the DEF accordingly.
*/
static int
memb_two_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
if(!sptr) {
ASN__CTFAIL(app_key, td, sptr,
"%s: value not given (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
/* Constraint check succeeded */
return 0;
}
static asn_TYPE_member_t asn_MBR_one_2[] = {
{ ATF_POINTER, 0, 0,
(ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
0,
&asn_DEF_Member_3,
0,
{ 0, 0, memb_NativeInteger_constraint_2 },
0, 0, /* No default value */
""
},
};
static const ber_tlv_tag_t asn_DEF_one_tags_2[] = {
(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static asn_SET_OF_specifics_t asn_SPC_one_specs_2 = {
sizeof(struct TestPDU__one),
offsetof(struct TestPDU__one, _asn_ctx),
0, /* XER encoding is XMLDelimitedItemList */
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_one_2 = {
"one",
"one",
&asn_OP_SEQUENCE_OF,
asn_DEF_one_tags_2,
sizeof(asn_DEF_one_tags_2)
/sizeof(asn_DEF_one_tags_2[0]) - 1, /* 1 */
asn_DEF_one_tags_2, /* Same as above */
sizeof(asn_DEF_one_tags_2)
/sizeof(asn_DEF_one_tags_2[0]), /* 2 */
{ 0, 0, SEQUENCE_OF_constraint },
asn_MBR_one_2,
1, /* Single element */
&asn_SPC_one_specs_2 /* Additional specs */
};
static const asn_INTEGER_specifics_t asn_SPC_two_specs_4 = {
0, 0, 0, 0, 0,
0, /* Native long size */
1 /* Unsigned representation */
};
static const ber_tlv_tag_t asn_DEF_two_tags_4[] = {
(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_two_4 = {
"two",
"two",
&asn_OP_NativeInteger,
asn_DEF_two_tags_4,
sizeof(asn_DEF_two_tags_4)
/sizeof(asn_DEF_two_tags_4[0]) - 1, /* 1 */
asn_DEF_two_tags_4, /* Same as above */
sizeof(asn_DEF_two_tags_4)
/sizeof(asn_DEF_two_tags_4[0]), /* 2 */
{ 0, 0, two_4_constraint },
0, 0, /* No members */
&asn_SPC_two_specs_4 /* Additional specs */
};
static asn_TYPE_member_t asn_MBR_TestPDU_1[] = {
{ ATF_NOFLAGS, 0, offsetof(struct TestPDU, one),
(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
0,
&asn_DEF_one_2,
0,
{ 0, 0, 0 },
0, 0, /* No default value */
"one"
},
{ ATF_NOFLAGS, 0, offsetof(struct TestPDU, two),
(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
-1, /* IMPLICIT tag at current level */
&asn_DEF_two_4,
0,
{ 0, 0, memb_two_constraint_1 },
0, 0, /* No default value */
"two"
},
{ ATF_NOFLAGS, 0, offsetof(struct TestPDU, three),
(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
-1, /* IMPLICIT tag at current level */
&asn_DEF_TestINT,
0,
{ 0, 0, 0 },
0, 0, /* No default value */
"three"
},
};
static const ber_tlv_tag_t asn_DEF_TestPDU_tags_1[] = {
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_TestPDU_tag2el_1[] = {
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* one */
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* two */
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* three */
};
static asn_SEQUENCE_specifics_t asn_SPC_TestPDU_specs_1 = {
sizeof(struct TestPDU),
offsetof(struct TestPDU, _asn_ctx),
asn_MAP_TestPDU_tag2el_1,
3, /* Count of tags in the map */
0, 0, 0, /* Optional elements (not needed) */
-1, /* First extension addition */
};
asn_TYPE_descriptor_t asn_DEF_TestPDU = {
"TestPDU",
"TestPDU",
&asn_OP_SEQUENCE,
asn_DEF_TestPDU_tags_1,
sizeof(asn_DEF_TestPDU_tags_1)
/sizeof(asn_DEF_TestPDU_tags_1[0]), /* 1 */
asn_DEF_TestPDU_tags_1, /* Same as above */
sizeof(asn_DEF_TestPDU_tags_1)
/sizeof(asn_DEF_TestPDU_tags_1[0]), /* 1 */
{ 0, 0, SEQUENCE_constraint },
asn_MBR_TestPDU_1,
3, /* Elements count */
&asn_SPC_TestPDU_specs_1 /* Additional specs */
};
It seems that SEQUENCE OF
does not like constraints following the type. The previous example works if I create a separate type for SEQUENCE OF.
This doesn't work: SEQUENCE OF INTEGER (0..4294967295)
This works: SEQUENCE OF TestINT
TestINT.c
and TestINT.h
files are present so I assume that asn_DEF_Member_3
should have been generated also.
I noticed this while compiling some ETSI definitions for Lawful Interceptions and fixed the issues by creating explicit types like I mentioned earlier. Not a big deal but this is probably enough to diagnose the problem or at least to be aware of it.
Thank you for reporting this problem. Hopefully we'd be able to find its cause and remedy it.
I'll take a look also when I find the time. It's a huge code base so It might take a while. I have actually created my own asn.1 compiler as part of my pmink repo so I have experience with asn.1/ber/der and all that. I prefer this implementation as it seems mature and I needed a C compatible output (my own asn1c generates C++ classes which at that time seemed like a good idea). Anyway, I will try to contribute as much as possible since I plan on using this fork and help as much as I can. Good work!
Thank you - and yes please do take a look. My hands are pretty full at the moment, and I don't know if other maintainers can pitch in quickly.
@dfranusic ,
When you compile asn1c, you can add CFLAGS=-g
during ./configure
phase to enable debug info for gdb. Based on the hint of your minimal example, this asn_MBR_one_2
was created (or said, printed) after asn_TYPE_member_t
, With a quick grep of code, there are 4 places inside asn1c_C.c
will do the job. Simply add break points at these lines, then you will see the call stack.
v->Identifier
is null because one
does not reference to another type but a plain type definition (? sorry I don't know the definition in ASN.1 word). Currently asn1c
is not able to deal with this kind of construct well.
One example is NBAP. :
cellSetupFDD NBAP-ELEMENTARY-PROCEDURE ::= {
INITIATING MESSAGE CellSetupRequestFDD
SUCCESSFUL OUTCOME CellSetupResponse
UNSUCCESSFUL OUTCOME CellSetupFailure
MESSAGE DISCRIMINATOR common
PROCEDURE ID { procedureCode id-cellSetup, ddMode fdd }
CRITICALITY reject
}
asn1c
is not able to parse { procedureCode id-cellSetup, ddMode fdd }
.
Another example is F1AP :
RRC-Version-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
{ID id-latest-RRC-Version-Enhanced CRITICALITY ignore EXTENSION OCTET STRING (SIZE(3)) PRESENCE optional },
...
}
Previous asn1c
can not handle OCTET STRING (SIZE(3))
well. My tweak in https://github.com/brchiu/asn1c/commit/4e7edb05ac838bdfcc9270f778c1269408823120 just solve part of it to make it works for F1AP rev 15.4.0, but not all.
Wish someone in community can find a better solution.
Hi @brchiu and thanks for the feedback. The problem you're having is related to nested definitions; the one presented in my example is a TYPE constraint issue. I mean, it's easy to tweak the asn.1 definitions to make asn1c happy so I don't see this as a big problem. As soon as I find the time I will start examining the code which is not a trivial task for such a big project. As I mentioned before, asn1 compilers are not a new thing for me and none of the available ones(free or not) are perfect. The point I'm trying to make; as long as we know how to tweak the asn1 files to make them compile, the issue becomes less critical.
Also, my opinion is that asn1 syntax is too liberal and that is the real issue for all of the compilers, including this one. Honesty, nested definitions are just horrible and completely unnecessary.
When I worked on my own compiler I decided to make my life easier and Ignore some of the syntax. One solution to nested definitions (how I would do it) is to extract them and make them top-level(with prefix). This would be done after the parsing stage at the AST level. I'm not saying the solution is perfect but It would make a lot of problems disappear. Another issue I'm constantly having is duplicate definitions. In my own compiler which was written in cpp and generated cpp, I solved it by using namespaces. Unfortunately, C has no namespace support. Again I am returning to my previous suggestion; I manually prefix those duplicates in asn1 files and compiler is happy.
Almost two years now, I see no fix in sight. Your suggestion in https://github.com/mouse07410/asn1c/issues/50#issue-434377177 (to create a separate TestINT
definition of the constrained SEQUENCE OF
, and replace SEQUENCE OF
with it) works well.
Hopefully others who hit this problem, can apply your workaround.
I'm not closing this issue, hoping that somebody might propose a PR to fix it, but I'm not holding my breath. ;-)
Again, thanks for analysis and workaround.
@dfranusic ,
When you compile asn1c, you can add
CFLAGS=-g
during./configure
phase to enable debug info for gdb. Based on the hint of your minimal example, thisasn_MBR_one_2
was created (or said, printed) afterasn_TYPE_member_t
, With a quick grep of code, there are 4 places insideasn1c_C.c
will do the job. Simply add break points at these lines, then you will see the call stack.
v->Identifier
is null becauseone
does not reference to another type but a plain type definition (? sorry I don't know the definition in ASN.1 word). Currentlyasn1c
is not able to deal with this kind of construct well.One example is NBAP. :
cellSetupFDD NBAP-ELEMENTARY-PROCEDURE ::= { INITIATING MESSAGE CellSetupRequestFDD SUCCESSFUL OUTCOME CellSetupResponse UNSUCCESSFUL OUTCOME CellSetupFailure MESSAGE DISCRIMINATOR common PROCEDURE ID { procedureCode id-cellSetup, ddMode fdd } CRITICALITY reject }
asn1c
is not able to parse{ procedureCode id-cellSetup, ddMode fdd }
.Another example is F1AP :
RRC-Version-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { {ID id-latest-RRC-Version-Enhanced CRITICALITY ignore EXTENSION OCTET STRING (SIZE(3)) PRESENCE optional }, ... }
Previous
asn1c
can not handleOCTET STRING (SIZE(3))
well. My tweak in brchiu@4e7edb0 just solve part of it to make it works for F1AP rev 15.4.0, but not all.Wish someone in community can find a better solution.
Resurrecting this thread: I can confirm that
RRC-Version-ExtIEs F1AP-PROTOCOL-EXTENSION ::= {
{ID id-latest-RRC-Version-Enhanced CRITICALITY ignore EXTENSION OCTET STRING (SIZE(3)) PRESENCE optional },
...
}
This change compiles, but when compared to messages generated by commercial test sets it appears that asn1c encodes and decodes differently than those test sets (and wireshark decode). I believe there is something different in how the the size or type bitmap is encoded, but my asn1 is not very strong. An example of encoded bitstream is:
expected: 00010080be000005004e00020000002a0003200258002d400d050054657261564d2d44552d31002c00808a0000002b0080834800021700000004001000010000010802170000000083400400000020410009bf8800004d0027000c1030000001000081ec0002000003020328489200000c240f10000000101000004001a4213401800009a59c32cd7e646e080400030010000820c04200000134b9c32cc89940001c29afbc0090b854070e8041603b0091b3da30a000ab000af0000000c740030f0600
generated:
00010080dd000005004e00020000002a0003200258002d400d050054657261564d2d44552d31002c0080a80000002b0080a14800021700000004001000010000010802170000000083400400000020410009bf8800004d0027000c1030000001000081ec0002000003020328669200000c240f10000000101000004001a4213401800009a59c32cd7e646e080400030010000820c04200000134b9c32cc89940001c29afbc0090b854070e8041603b0091b3da30a048000000000000000000000000000000000000000000000000000000050000ab000bf0000000c74004030f0600
The decoded is
F1 Application Protocol (F1SetupRequest)
F1AP-PDU: initiatingMessage (0)
initiatingMessage
procedureCode: id-F1Setup (1)
criticality: reject (0)
value
F1SetupRequest
protocolIEs: 5 items
Item 0: id-TransactionID
ProtocolIE-Field
id: id-TransactionID (78)
criticality: reject (0)
value
TransactionID: 0
Item 1: id-gNB-DU-ID
ProtocolIE-Field
id: id-gNB-DU-ID (42)
criticality: reject (0)
value
GNB-DU-ID: 600
Item 2: id-gNB-DU-Name
ProtocolIE-Field
id: id-gNB-DU-Name (45)
criticality: ignore (1)
value
GNB-DU-Name: TeraVM-DU-1
Item 3: id-gNB-DU-Served-Cells-List
ProtocolIE-Field
id: id-gNB-DU-Served-Cells-List (44)
criticality: reject (0)
value
GNB-DU-Served-Cells-List: 1 item
Item 0: id-GNB-DU-Served-Cells-Item
ProtocolIE-SingleContainer
id: id-GNB-DU-Served-Cells-Item (43)
criticality: reject (0)
value
GNB-DU-Served-Cells-Item
served-Cell-Information
nRCGI
pLMN-Identity: 021700
Mobile Country Code (MCC): Unassigned (207)
Mobile Network Code (MNC): Unknown (100)
nRCellIdentity: 0000040010 [bit length 36, 4 LSB pad bits, 0000 0000 0000 0000 0000 0100 0000 0000 0001 .... decimal value 16385]
nRPCI: 1
fiveGS-TAC: 1 (0x000001)
servedPLMNs: 1 item
Item 0
ServedPLMNs-Item
pLMN-Identity: 021700
Mobile Country Code (MCC): Unassigned (207)
Mobile Network Code (MNC): Unknown (100)
iE-Extensions: 1 item
Item 0
ProtocolExtensionField
id: 131
criticality: ignore (1)
extensionValue
SliceSupportList: 1 item
Item 0
SliceSupportItem
sNSSAI
sST: 01
nR-Mode-Info: tDD (1)
tDD
nRFreqInfo
nRARFCN: 638856
freqBandListNr: 1 item
Item 0
FreqBandNrItem
freqBandIndicatorNr: 78
supportedSULBandList: 0 items
transmission-Bandwidth
nRSCS: scs30 (1)
nRNRB: nrb106 (14)
measurementTimingConfiguration: 1030000001000081ec000200
MeasurementTimingConfiguration
criticalExtensions: c1 (0)
c1: measTimingConf (0)
measTimingConf
measTiming: 1 item
Item 0
MeasTiming
frequencyAndTiming
carrierFreq: 0
ssbSubcarrierSpacing: kHz15 (0)
ssb-MeasurementTimingConfiguration
periodicityAndOffset: sf20 (2)
sf20: 0
duration: sf1 (0)
ssb-ToMeasure: mediumBitmap (1)
mediumBitmap: 80 [bit length 8, 1000 0000 decimal value 128]
physCellId: 1
gNB-DU-System-Information
mIB-message: 020328
MIB
systemFrameNumber: 00 [bit length 6, 2 LSB pad bits, 0000 00.. decimal value 0]
subCarrierSpacingCommon: scs30or120 (1)
ssb-SubcarrierOffset: 0
dmrs-TypeA-Position: pos2 (0)
pdcch-ConfigSIB1
controlResourceSetZero: 3
searchSpaceZero: 2
cellBarred: notBarred (1)
intraFreqReselection: allowed (0)
spare: 00 [bit length 1, 7 LSB pad bits, 0... .... decimal value 0]
sIB1-message: 9200000c240f10000000101000004001a4213401800009a59c32cd7e646e080400030010…
SIB1
cellSelectionInfo
q-RxLevMin: -140dBm (-70)
cellAccessRelatedInfo
plmn-IdentityInfoList: 1 item
Item 0
PLMN-IdentityInfo
plmn-IdentityList: 1 item
Item 0
PLMN-Identity
mcc: 3 items
Item 0
MCC-MNC-Digit: 2
Item 1
MCC-MNC-Digit: 0
Item 2
MCC-MNC-Digit: 7
mnc: 3 items
Item 0
MCC-MNC-Digit: 1
Item 1
MCC-MNC-Digit: 0
Item 2
MCC-MNC-Digit: 0
trackingAreaCode: 000001 [bit length 24, 0000 0000 0000 0000 0000 0001 decimal value 1]
ranac: 1
cellIdentity: 0000040010 [bit length 36, 4 LSB pad bits, 0000 0000 0000 0000 0000 0100 0000 0000 0001 .... decimal value 16385]
cellReservedForOperatorUse: notReserved (1)
servingCellConfigCommon
downlinkConfigCommon
frequencyInfoDL
frequencyBandList: 1 item
Item 0
NR-MultiBandInfo
freqBandIndicatorNR: 78
offsetToPointA: 6 PRBs
scs-SpecificCarrierList: 1 item
Item 0
SCS-SpecificCarrier
offsetToCarrier: 0
subcarrierSpacing: kHz30 (1)
carrierBandwidth: 106
initialDownlinkBWP
genericParameters
locationAndBandwidth: 28875
subcarrierSpacing: kHz30 (1)
pdcch-ConfigCommon: setup (1)
setup
controlResourceSetZero: 3
searchSpaceZero: 2
commonSearchSpaceList: 1 item
Item 0
SearchSpace
searchSpaceId: 1
controlResourceSetId: 0
monitoringSlotPeriodicityAndOffset: sl1 (0)
sl1: NULL
monitoringSymbolsWithinSlot: 8000 [bit length 14, 2 LSB pad bits, 1000 0000 0000 00.. decimal value 8192]
nrofCandidates
aggregationLevel1: n0 (0)
aggregationLevel2: n6 (6)
aggregationLevel4: n0 (0)
aggregationLevel8: n0 (0)
aggregationLevel16: n0 (0)
searchSpaceType: common (0)
common
dci-Format0-0-AndFormat1-0
searchSpaceSIB1: 0
searchSpaceOtherSystemInformation: 1
pagingSearchSpace: 1
ra-SearchSpace: 1
pdsch-ConfigCommon: setup (1)
setup
bcch-Config
modificationPeriodCoeff: n2 (0)
pcch-Config
defaultPagingCycle: rf128 (2)
nAndPagingFrameOffset: oneT (0)
oneT: NULL
ns: one (2)
uplinkConfigCommon
frequencyInfoUL
scs-SpecificCarrierList: 1 item
Item 0
SCS-SpecificCarrier
offsetToCarrier: 0
subcarrierSpacing: kHz30 (1)
carrierBandwidth: 106
initialUplinkBWP
genericParameters
locationAndBandwidth: 28875
subcarrierSpacing: kHz30 (1)
rach-ConfigCommon: setup (1)
setup
rach-ConfigGeneric
prach-ConfigurationIndex: 202
msg1-FDM: one (0)
msg1-FrequencyStart: 0
zeroCorrelationZoneConfig: 0
preambleReceivedTargetPower: -90 dBm
preambleTransMax: n200 (10)
powerRampingStep: dB2 (1)
ra-ResponseWindow: sl20 (5)
ssb-perRACH-OccasionAndCB-PreamblesPerSSB: one (3)
one: n60 (14)
ra-ContentionResolutionTimer: sf64 (7)
prach-RootSequenceIndex: l139 (1)
l139: 0
msg1-SubcarrierSpacing: kHz30 (1)
restrictedSetConfig: unrestrictedSet (0)
pusch-ConfigCommon: setup (1)
setup
p0-NominalWithGrant: -90 dBm
pucch-ConfigCommon: setup (1)
setup
pucch-ResourceCommon: 0
pucch-GroupHopping: neither (0)
p0-nominal: -90 dBm
timeAlignmentTimerCommon: infinity (7)
ssb-PositionsInBurst
inOneGroup: 80 [bit length 8, 1000 0000 decimal value 128]
ssb-PeriodicityServingCell: ms20 (2)
tdd-UL-DL-ConfigurationCommon
referenceSubcarrierSpacing: kHz30 (1)
pattern1
dl-UL-TransmissionPeriodicity: ms5 (6)
nrofDownlinkSlots: 7
nrofDownlinkSymbols: 6
nrofUplinkSlots: 2
nrofUplinkSymbols: 4
ss-PBCH-BlockPower: -6 dBm
ue-TimersAndConstants
t300: ms2000 (7)
t301: ms1000 (5)
t310: ms1000 (5)
n310: n1 (0)
t311: ms30000 (6)
n311: n1 (0)
t319: ms1000 (5)
Item 4: id-GNB-DU-RRC-Version
ProtocolIE-Field
id: id-GNB-DU-RRC-Version (171)
criticality: reject (0)
value
RRC-Version
latest-RRC-Version: e0 [bit length 3, 5 LSB pad bits, 111. .... decimal value 7]
iE-Extensions: 1 item
Item 0
ProtocolExtensionField
id: 199
criticality: ignore (1)
extensionValue
15.6.0
Reported in https://github.com/vlm/asn1c/issues/456, but I think it's relevant to state here as well.