asn1c icon indicating copy to clipboard operation
asn1c copied to clipboard

Handling choices correctly

Open sandman opened this issue 4 years ago • 0 comments

Hi,

I'm struggling to correctly decode a fairly non-trivial ASN.1 structure which consists of an optional element before a CHOICE:

The ASN.1 definition of said structure:

RSCode::= SEQUENCE{
	layoutComponentId	INTEGER(1..4,...) OPTIONAL,
	code				CHOICE {
		iso14823			ISO14823Code,
		viennaConvention	VcCode, -- see Vienna Convention Annex A
		itisCodes			INTEGER (0..65535), -- see SAE J2540
		anyCatalogue		AnyCatalogue,
		...
	}
}

The generated source by asn1c:

/* Dependencies */
typedef enum RSCode__code_PR {
	RSCode__code_PR_NOTHING,	/* No components present */
	RSCode__code_PR_iso14823,
	RSCode__code_PR_viennaConvention,
	RSCode__code_PR_itisCodes,
	RSCode__code_PR_anyCatalogue
	/* Extensions may appear below */
	
} RSCode__code_PR;

/* RSCode */
typedef struct RSCode {
	long	*layoutComponentId	/* OPTIONAL */;
	struct RSCode__code {
		RSCode__code_PR present;
		union RSCode__code_u {
			ISO14823Code_t	 iso14823;
			VcCode_t	 viennaConvention;
			long	 itisCodes;
			AnyCatalogue_t	 anyCatalogue;
			/*
			 * This type is extensible,
			 * possible extensions are below.
			 */
		} choice;
		
		/* Context for parsing across buffer boundaries */
		asn_struct_ctx_t _asn_ctx;
	} code;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} RSCode_t;

The issue is in the decoding of code which decodes a value 0 incorrectly as viennaConvention instead of iso14823:

Decoding RSCode as SEQUENCE (UPER) (constr_SEQUENCE.c:1098)
  [PER got  1<=689 bits => span 832 +7[8..696]:10 (688) => 0x0] (asn_bit_data.c:139)
Read in presence bitmap for RSCode of 1 bits (0..) (constr_SEQUENCE.c:1121)
  [PER got  1<= 1 bits => span 1 +0[1..1]:00 (0) => 0x0] (asn_bit_data.c:139)
Member RSCode->layoutComponentId is optional, p=0 (1->1) (constr_SEQUENCE.c:1152)
Decoding member "code" in RSCode (constr_SEQUENCE.c:1170)
  [PER got  1<=688 bits => span 833 +8[1..688]:30 (687) => 0x0] (asn_bit_data.c:139)
  [PER got  2<=687 bits => span 835 +8[3..688]:30 (685) => 0x1] (asn_bit_data.c:139)
CHOICE code got index 1 in range 2 (constr_CHOICE.c:872)
Discovered CHOICE code encodes viennaConvention (constr_CHOICE.c:903)

How can I fix this without mucking around with the Schema?

sandman avatar Jul 14 '20 10:07 sandman