/*
 * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
 * From ASN.1 module "RANAP-PDU"
 * 	found in "../../asn1/ranap/RANAP-PDU.asn"
 */

#include "RANAP_InformationTransferIndication.h"

static int
memb_informationTransferIndication_ies_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	size_t size;
	
	if(!sptr) {
		_ASN_CTFAIL(app_key, td, sptr,
			"%s: value not given (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
	
	/* Determine the number of elements */
	size = _A_CSEQUENCE_FROM_VOID(sptr)->count;
	
	if((size <= 65535l)) {
		/* Perform validation of the inner elements */
		return td->check_constraints(td, sptr, ctfailcb, app_key);
	} else {
		_ASN_CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

static asn_per_constraints_t asn_PER_type_informationTransferIndication_ies_constr_2 GCC_NOTUSED = {
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	{ APC_CONSTRAINED,	 16,  16,  0l,  65535l }	/* (SIZE(0..65535)) */,
	0, 0	/* No PER value map */
};
static asn_per_constraints_t asn_PER_memb_informationTransferIndication_ies_constr_2 GCC_NOTUSED = {
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	{ APC_CONSTRAINED,	 16,  16,  0l,  65535l }	/* (SIZE(0..65535)) */,
	0, 0	/* No PER value map */
};
static asn_TYPE_member_t asn_MBR_informationTransferIndication_ies_2[] = {
	{ ATF_POINTER, 0, 0,
		-1 /* Ambiguous tag (CHOICE?) */,
		0,
		&asn_DEF_RANAP_IE,
		0,	/* Defer constraints checking to the member type */
		0,	/* No PER visible constraints */
		0,
		""
		},
};
static const ber_tlv_tag_t asn_DEF_informationTransferIndication_ies_tags_2[] = {
	(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static asn_SET_OF_specifics_t asn_SPC_informationTransferIndication_ies_specs_2 = {
	sizeof(struct informationTransferIndication_ies),
	offsetof(struct informationTransferIndication_ies, _asn_ctx),
	0,	/* XER encoding is XMLDelimitedItemList */
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_informationTransferIndication_ies_2 = {
	"informationTransferIndication-ies",
	"informationTransferIndication-ies",
	SEQUENCE_OF_free,
	SEQUENCE_OF_print,
	SEQUENCE_OF_constraint,
	SEQUENCE_OF_decode_ber,
	SEQUENCE_OF_encode_der,
	SEQUENCE_OF_decode_xer,
	SEQUENCE_OF_encode_xer,
	SEQUENCE_OF_decode_uper,
	SEQUENCE_OF_encode_uper,
	SEQUENCE_OF_decode_aper,
	SEQUENCE_OF_encode_aper,
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_informationTransferIndication_ies_tags_2,
	sizeof(asn_DEF_informationTransferIndication_ies_tags_2)
		/sizeof(asn_DEF_informationTransferIndication_ies_tags_2[0]) - 1, /* 1 */
	asn_DEF_informationTransferIndication_ies_tags_2,	/* Same as above */
	sizeof(asn_DEF_informationTransferIndication_ies_tags_2)
		/sizeof(asn_DEF_informationTransferIndication_ies_tags_2[0]), /* 2 */
	&asn_PER_type_informationTransferIndication_ies_constr_2,
	asn_MBR_informationTransferIndication_ies_2,
	1,	/* Single element */
	&asn_SPC_informationTransferIndication_ies_specs_2	/* Additional specs */
};

static asn_TYPE_member_t asn_MBR_RANAP_InformationTransferIndication_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct RANAP_InformationTransferIndication, informationTransferIndication_ies),
		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
		0,
		&asn_DEF_informationTransferIndication_ies_2,
		memb_informationTransferIndication_ies_constraint_1,
		&asn_PER_memb_informationTransferIndication_ies_constr_2,
		0,
		"informationTransferIndication-ies"
		},
};
static const ber_tlv_tag_t asn_DEF_RANAP_InformationTransferIndication_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_RANAP_InformationTransferIndication_tag2el_1[] = {
    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 } /* informationTransferIndication-ies */
};
static asn_SEQUENCE_specifics_t asn_SPC_RANAP_InformationTransferIndication_specs_1 = {
	sizeof(struct RANAP_InformationTransferIndication),
	offsetof(struct RANAP_InformationTransferIndication, _asn_ctx),
	asn_MAP_RANAP_InformationTransferIndication_tag2el_1,
	1,	/* Count of tags in the map */
	0, 0, 0,	/* Optional elements (not needed) */
	0,	/* Start extensions */
	2	/* Stop extensions */
};
asn_TYPE_descriptor_t asn_DEF_RANAP_InformationTransferIndication = {
	"RANAP_InformationTransferIndication",
	"RANAP_InformationTransferIndication",
	SEQUENCE_free,
	SEQUENCE_print,
	SEQUENCE_constraint,
	SEQUENCE_decode_ber,
	SEQUENCE_encode_der,
	SEQUENCE_decode_xer,
	SEQUENCE_encode_xer,
	SEQUENCE_decode_uper,
	SEQUENCE_encode_uper,
	SEQUENCE_decode_aper,
	SEQUENCE_encode_aper,
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_RANAP_InformationTransferIndication_tags_1,
	sizeof(asn_DEF_RANAP_InformationTransferIndication_tags_1)
		/sizeof(asn_DEF_RANAP_InformationTransferIndication_tags_1[0]), /* 1 */
	asn_DEF_RANAP_InformationTransferIndication_tags_1,	/* Same as above */
	sizeof(asn_DEF_RANAP_InformationTransferIndication_tags_1)
		/sizeof(asn_DEF_RANAP_InformationTransferIndication_tags_1[0]), /* 1 */
	0,	/* No PER visible constraints */
	asn_MBR_RANAP_InformationTransferIndication_1,
	1,	/* Elements count */
	&asn_SPC_RANAP_InformationTransferIndication_specs_1	/* Additional specs */
};

