Circular ASN.1 definitions are partially supported

ASN.1 supports circular definitions, but the ASN1Parse operator only partially supports them.

Symptoms

A circular definition is a definition in which an ASN.1 container contains another, and, simultaneously, the second container contains the first. Circular definitions can consist of any combination of SEQUENCE, SET, and CHOICE containers and can have any depth (e.g. A -> B -> C -> D -> E -> A). The following example shows a circular definition in which the ASN.1 container A contains B, and B contains A:


MyModule DEFINITIONS IMPLICIT TAGS ::=
BEGIN

Sample ::= SEQUENCE
{
	data [0] A
}

A ::= SEQUENCE
{
	id [0] INTEGER,
	sub [1] B OPTIONAL,
	...
}

B ::= SEQUENCE
{
	text [0] IA5String,
	back [1] A,
	...
}

END

The following example shows the corresponding SPL type definitions that are generated with the spl-schema-from-asn1 tool from the above ASN.1 structure definition document:


type A = tuple // SEQUENCE
<
	int64 id, // INTEGER, mandatory, non-repeating
	list<B> sub // optional, non-repeating
>;

type B = tuple // SEQUENCE
<
	rstring text, // IA5String, mandatory, non-repeating
	A back // mandatory, non-repeating
>;

type Sample = tuple // SEQUENCE
<
	A data // mandatory, non-repeating
>;

Diagnosing the problem

When you compile an ASN1Parse operator that has the sample type in its output stream, the Streams compiler raises the following error that a circular type definition was found:


Types.spl:7:2: CDISP0022E ERROR: The tuple definition is circular.

Resolving the problem

1. Remove the deepest SPL attribute, which leads to the circular SPL definition. In the sample, "A back" must be removed from type B, resulting in the following type definition. As a result, instances of A below B are lost.


type B = tuple // SEQUENCE
<
	rstring text // IA5String, mandatory, non-repeating
>;

2. If you need circular data, you can receive the complete PDU as XML by using the getXML() custom output function and implementing your own parsing. You would receive a tuple similar to the following example:


{
	data=
	{
		id=10,
		sub=[{text="Bob"}]
	},
	pdu="<Sample><data><id>10</id><sub><text>Bob</text><back><id>20</id></back></sub></data></Sample>"x
}