Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Circular headers dependency compiling XnAP or E1AP #78

Open
gatopeich opened this issue Jun 28, 2021 · 9 comments
Open

Circular headers dependency compiling XnAP or E1AP #78

gatopeich opened this issue Jun 28, 2021 · 9 comments

Comments

@gatopeich
Copy link

gatopeich commented Jun 28, 2021

I am getting circular header dependency in XnAP v15.10, trying all combinations of -fno-include-deps, -fcompound, etc.

For example:

$ asn1c -fcompound-names -fincludes-quoted -fno-include-deps -funnamed-unions -no-gen-example -no-gen-BER -no-gen-OER -no-gen-UPER

$ gcc -std=c99 -D_GNU_SOURCE -fPIC -DPIC -Wall -Werror -Wfatal-errors -Wno-error=narrowing -Wno-unused -Wno-error=array-bounds -Wno-error=misleading-indentation -I. -DASN_DISABLE_BER_SUPPORT -DASN_DISABLE_OER_SUPPORT -DASN_DISABLE_UPER_SUPPORT ServedCells-ToModify-E-UTRA.c
In file included from ProtocolIE-Field.h:25:0,
                 from ProtocolIE-Single-Container.h:15,
                 from ServedCellInformation-E-UTRA-ModeInfo.h:17,
                 from ServedCellInformation-E-UTRA.h:19,
                 from ServedCells-ToModify-E-UTRA-Item.h:16,
                 from ServedCells-ToModify-E-UTRA.c:10:
Cause.h:44:3: error: unknown type name ‘ProtocolIE_Single_Container_6337P7_t’
   ProtocolIE_Single_Container_6337P7_t  choice_extension;
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated due to -Wfatal-errors.

$ grep ProtocolIE_Single_Container_6337P7_t *.h
Cause.h:                ProtocolIE_Single_Container_6337P7_t     choice_extension;
ProtocolIE-Single-Container.h:typedef Cause_ExtIEs_t     ProtocolIE_Single_Container_6337P7_t;

Compilation is impossible because the type ProtocolIE_Single_Container_6337P7_t is defined in ProtocolIE-Single-Container.h which requires Cause.h which requires the other header.

I avoided similar issues in the past by tweaking include order but cannot find an easy/generic way here.

The spec:
xnap-v15.10.asn.gz

@gatopeich
Copy link
Author

Note I am open to C++ tricks if that helps!

@mouse07410
Copy link
Owner

What happens if you (a) do not set -fno-include-deps and (b) manually re-order the include order?

Re. an easy way to re-order - make a header file my_headers.h that includes every other needed header file in the right order, and include just my_headers.h?

@gatopeich
Copy link
Author

What happens if you (a) do not set -fno-include-deps and (b) manually re-order the include order?

I get similar error in different places. With other specs (not this big) I had better luck with -fno-include-deps. In this case I am still trying both...

Re. an easy way to re-order - make a header file my_headers.h that includes every other needed header file in the right order, and include just my_headers.h?

Thanks I will try that...

@gatopeich
Copy link
Author

The problem might be due to use of choice-extension ProtocolIE-SingleContainer

Cause ::= CHOICE {
	radioNetwork		CauseRadioNetwork,
	transport			CauseTransport,
	protocol			CauseProtocol,
	misc				CauseMisc,
	choice-extension	ProtocolIE-SingleContainer	{{Cause-ExtIEs}}
}

Cause-ExtIEs E1AP-PROTOCOL-IES ::= {
	...
}

In all cases but one, the choice-extension leads to an empty type like Cause-ExtIEs
(I ignore the meaning of E1AP-PROTOCOL-IES there)

@gatopeich
Copy link
Author

I isolated "choice-extension" and it does not seem the issue.

The problem is in the generation and internal ordering of "ProtocolIE-Field.h", which contains a lot of inter-dependent structs and includes.

I am trying to sort it out manually...

@gatopeich
Copy link
Author

gatopeich commented Jun 30, 2021

Here is a workaround:

  1. Identify all "choice-extension" types.
$ grep choice-extension e1ap-v15.08.asn
choice-extension ProtocolIE-SingleContainer {{ResetType-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{System-BearerContextSetupRequest-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{System-BearerContextSetupResponse-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{System-BearerContextModificationRequest-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{System-BearerContextModificationResponse-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{System-BearerContextModificationRequired-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{System-BearerContextModificationConfirm-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{System-GNB-CU-UP-CounterCheckRequest-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{ActivityInformation-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{Cause-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{CP-TNL-Information-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{QoS-Characteristics-ExtIEs}}
choice-extension ProtocolIE-SingleContainer {{UP-TNL-Information-ExtIEs}}
  1. Convert their typedef to #define inside ProtocolIE-SingleContainer.h, and place them before #include "ProtocolIE-Field.h"
  2. Sort their #includes inside ProtocolIE-Field.h so that each one appears just after the struct #defined in step 1.
    e.g.:
/* ProtocolIE-Field */
typedef struct ResetType_ExtIEs {
	ProtocolIE_ID_t	 id;
	Criticality_t	 criticality;
	struct ResetType_ExtIEs__value {
		ResetType_ExtIEs__value_PR present;
		union {
		};
		
		/* Context for parsing across buffer boundaries */
		asn_struct_ctx_t _asn_ctx;
	} value;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} ResetType_ExtIEs_t;
#include   "ResetType.h" // <=== HERE! this header needs the struct above defined, and provides ResetType_t required below

Note: with -findirect-choice, ResetType_t could simply be forward declared, but I don't think this would be a general solution and the anonymous union is much better than a list of pointers IMO.

Here is the E1AP spec used to produce this code and the workaround: e1ap-v15.08.asn.gz

@mouse07410
Copy link
Owner

I might add that asn1c is not great at dealing with Extensible types., which many (semi-competent!) standards really abuse.

Thank you for the workaround - it will help others.

@gatopeich
Copy link
Author

gatopeich commented Jun 30, 2021

I might add that asn1c is not great at dealing with Extensible types., which many (semi-competent!) standards really abuse.

Absolutely, and in these specs I am finding a lot of such abuse... All but one of these extensions were empty!

Thank you for the workaround - it will help others.

BTW thank you for maintaining this fork which not only supports APER but also contains fixes very relevant for 5G R&D.
I just wish I had more time to contribute!

@gatopeich gatopeich changed the title Circular headers dependency compiling XnAP Circular headers dependency compiling XnAP or E1AP Jun 30, 2021
@mouse07410
Copy link
Owner

I just wish I had more time to contribute!

Same here. :-(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants