/*
 * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
 * From ASN.1 module "HNBAP-PDU"
 * 	found in "../../asn1/hnbap/HNBAP-PDU.asn"
 * 	`asn1c -gen-PER`
 */

#include <osmocom/hnbap/RelocationComplete.h>

static int
memb_relocationComplete_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_relocationComplete_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_relocationComplete_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_relocationComplete_ies_2[] = {
	{ ATF_POINTER, 0, 0,
		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
		0,
		&asn_DEF_IE,
		0,	/* Defer constraints checking to the member type */
		0,	/* No PER visible constraints */
		0,
		""
		},
};
static const ber_tlv_tag_t asn_DEF_relocationComplete_ies_tags_2[] = {
	(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static asn_SET_OF_specifics_t asn_SPC_relocationComplete_ies_specs_2 = {
	sizeof(struct relocationComplete_ies),
	offsetof(struct relocationComplete_ies, _asn_ctx),
	0,	/* XER encoding is XMLDelimitedItemList */
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_relocationComplete_ies_2 = {
	"relocationComplete-ies",
	"relocationComplete-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_relocationComplete_ies_tags_2,
	sizeof(asn_DEF_relocationComplete_ies_tags_2)
		/sizeof(asn_DEF_relocationComplete_ies_tags_2[0]) - 1, /* 1 */
	asn_DEF_relocationComplete_ies_tags_2,	/* Same as above */
	sizeof(asn_DEF_relocationComplete_ies_tags_2)
		/sizeof(asn_DEF_relocationComplete_ies_tags_2[0]), /* 2 */
	&asn_PER_type_relocationComplete_ies_constr_2,
	asn_MBR_relocationComplete_ies_2,
	1,	/* Single element */
	&asn_SPC_relocationComplete_ies_specs_2	/* Additional specs */
};

static asn_TYPE_member_t asn_MBR_RelocationComplete_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct RelocationComplete, relocationComplete_ies),
		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
		0,
		&asn_DEF_relocationComplete_ies_2,
		memb_relocationComplete_ies_constraint_1,
		&asn_PER_memb_relocationComplete_ies_constr_2,
		0,
		"relocationComplete-ies"
		},
};
static const ber_tlv_tag_t asn_DEF_RelocationComplete_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_RelocationComplete_tag2el_1[] = {
    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 } /* relocationComplete-ies */
};
static asn_SEQUENCE_specifics_t asn_SPC_RelocationComplete_specs_1 = {
	sizeof(struct RelocationComplete),
	offsetof(struct RelocationComplete, _asn_ctx),
	asn_MAP_RelocationComplete_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_RelocationComplete = {
	"RelocationComplete",
	"RelocationComplete",
	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_RelocationComplete_tags_1,
	sizeof(asn_DEF_RelocationComplete_tags_1)
		/sizeof(asn_DEF_RelocationComplete_tags_1[0]), /* 1 */
	asn_DEF_RelocationComplete_tags_1,	/* Same as above */
	sizeof(asn_DEF_RelocationComplete_tags_1)
		/sizeof(asn_DEF_RelocationComplete_tags_1[0]), /* 1 */
	0,	/* No PER visible constraints */
	asn_MBR_RelocationComplete_1,
	1,	/* Elements count */
	&asn_SPC_RelocationComplete_specs_1	/* Additional specs */
};

