/*
 * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
 * From ASN.1 module "X2AP-IEs"
 * 	found in "Spec/e2_and_x2-combined-and-minimized.asn1"
 * 	`asn1c -pdu=auto -fincludes-quoted -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example`
 */

#include "NRFreqInfo.h"

#include "SULInformation.h"
#include "ProtocolExtensionContainer.h"
#include "FreqBandNrItem.h"
static int
memb_nRARFCN_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr,
			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	long value;
	
	if(!sptr) {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: value not given (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
	
	value = *(const long *)sptr;
	
	if((value >= 0 && value <= 3279165)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

static int
memb_freqBandListNr_constraint_1(const 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 >= 1 && size <= 32)) {
		/* Perform validation of the inner elements */
		return td->encoding_constraints.general_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_freqBandListNr_constr_3 CC_NOTUSED = {
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	{ APC_CONSTRAINED,	 5,  5,  1,  32 }	/* (SIZE(1..32)) */,
	0, 0	/* No PER value map */
};
static asn_per_constraints_t asn_PER_memb_nRARFCN_constr_2 CC_NOTUSED = {
	{ APC_CONSTRAINED,	 22, -1,  0,  3279165 }	/* (0..3279165) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};
static asn_per_constraints_t asn_PER_memb_freqBandListNr_constr_3 CC_NOTUSED = {
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	{ APC_CONSTRAINED,	 5,  5,  1,  32 }	/* (SIZE(1..32)) */,
	0, 0	/* No PER value map */
};
static asn_TYPE_member_t asn_MBR_freqBandListNr_3[] = {
	{ ATF_POINTER, 0, 0,
		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
		0,
		&asn_DEF_FreqBandNrItem,
		0,
		{ 0, 0, 0 },
		0, 0, /* No default value */
		""
		},
};
static const ber_tlv_tag_t asn_DEF_freqBandListNr_tags_3[] = {
	(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static asn_SET_OF_specifics_t asn_SPC_freqBandListNr_specs_3 = {
	sizeof(struct NRFreqInfo__freqBandListNr),
	offsetof(struct NRFreqInfo__freqBandListNr, _asn_ctx),
	0,	/* XER encoding is XMLDelimitedItemList */
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_freqBandListNr_3 = {
	"freqBandListNr",
	"freqBandListNr",
	&asn_OP_SEQUENCE_OF,
	asn_DEF_freqBandListNr_tags_3,
	sizeof(asn_DEF_freqBandListNr_tags_3)
		/sizeof(asn_DEF_freqBandListNr_tags_3[0]) - 1, /* 1 */
	asn_DEF_freqBandListNr_tags_3,	/* Same as above */
	sizeof(asn_DEF_freqBandListNr_tags_3)
		/sizeof(asn_DEF_freqBandListNr_tags_3[0]), /* 2 */
	{ 0, &asn_PER_type_freqBandListNr_constr_3, SEQUENCE_OF_constraint },
	asn_MBR_freqBandListNr_3,
	1,	/* Single element */
	&asn_SPC_freqBandListNr_specs_3	/* Additional specs */
};

asn_TYPE_member_t asn_MBR_NRFreqInfo_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct NRFreqInfo, nRARFCN),
		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
		-1,	/* IMPLICIT tag at current level */
		&asn_DEF_NativeInteger,
		0,
		{ 0, &asn_PER_memb_nRARFCN_constr_2,  memb_nRARFCN_constraint_1 },
		0, 0, /* No default value */
		"nRARFCN"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct NRFreqInfo, freqBandListNr),
		(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
		0,
		&asn_DEF_freqBandListNr_3,
		0,
		{ 0, &asn_PER_memb_freqBandListNr_constr_3,  memb_freqBandListNr_constraint_1 },
		0, 0, /* No default value */
		"freqBandListNr"
		},
	{ ATF_POINTER, 2, offsetof(struct NRFreqInfo, sULInformation),
		(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
		-1,	/* IMPLICIT tag at current level */
		&asn_DEF_SULInformation,
		0,
		{ 0, 0, 0 },
		0, 0, /* No default value */
		"sULInformation"
		},
	{ ATF_POINTER, 1, offsetof(struct NRFreqInfo, iE_Extensions),
		(ASN_TAG_CLASS_CONTEXT | (3 << 2)),
		-1,	/* IMPLICIT tag at current level */
		&asn_DEF_ProtocolExtensionContainer_8858P52,
		0,
		{ 0, 0, 0 },
		0, 0, /* No default value */
		"iE-Extensions"
		},
};
static const int asn_MAP_NRFreqInfo_oms_1[] = { 2, 3 };
static const ber_tlv_tag_t asn_DEF_NRFreqInfo_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_NRFreqInfo_tag2el_1[] = {
    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* nRARFCN */
    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* freqBandListNr */
    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* sULInformation */
    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 } /* iE-Extensions */
};
asn_SEQUENCE_specifics_t asn_SPC_NRFreqInfo_specs_1 = {
	sizeof(struct NRFreqInfo),
	offsetof(struct NRFreqInfo, _asn_ctx),
	asn_MAP_NRFreqInfo_tag2el_1,
	4,	/* Count of tags in the map */
	asn_MAP_NRFreqInfo_oms_1,	/* Optional members */
	2, 0,	/* Root/Additions */
	4,	/* First extension addition */
};
asn_TYPE_descriptor_t asn_DEF_NRFreqInfo = {
	"NRFreqInfo",
	"NRFreqInfo",
	&asn_OP_SEQUENCE,
	asn_DEF_NRFreqInfo_tags_1,
	sizeof(asn_DEF_NRFreqInfo_tags_1)
		/sizeof(asn_DEF_NRFreqInfo_tags_1[0]), /* 1 */
	asn_DEF_NRFreqInfo_tags_1,	/* Same as above */
	sizeof(asn_DEF_NRFreqInfo_tags_1)
		/sizeof(asn_DEF_NRFreqInfo_tags_1[0]), /* 1 */
	{ 0, 0, SEQUENCE_constraint },
	asn_MBR_NRFreqInfo_1,
	4,	/* Elements count */
	&asn_SPC_NRFreqInfo_specs_1	/* Additional specs */
};

