opened
dfranusic
username_0
**test.asn1**
```asn
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:
```sh
$ ../asn1c/asn1c -S ../skeletons -pdu=all -print-constraints -Wdebug-lexer -Wdebug-parser -Wdebug-fixer -Wdebug-compiler -no-gen-PER -no-gen-OER -fcompound-names test.asn1
```
Compile example converter:
```sh
$ 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**
```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.
SEQUENCE OF constrained INTEGER error
issue
created
mouse07410
username_1
Thank you for reporting this problem. Hopefully we'd be able to find its cause and remedy it.
comment
created
dfranusic
username_0
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 my @username_0/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)
comment
created
mouse07410
username_1
Thank you - and yes please do take a look. My hands are pretty full at the moment, and u don't know if other maintainers can pitch in quickly.
comment
created
brchiu
username_2
@username_0 ,

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.

![call_stack_of_problem_venue](https://user-images.githubusercontent.com/6227912/57172719-4677a600-6e56-11e9-9f85-1c9f05d3efe5.png)
 
`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/username_2/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.
comment
created
dfranusic
username_0
Hi @username_2 and thanks for the feedback. The problem you're having ia 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. Like I mentined before, I worked on an asn1 compiler before and none of the available conpilers(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.
comment
created
mouse07410
username_1
Almost two years now, I see no fix in sight. Your suggestion in https://github.com/username_1/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.
comment