/*
 * 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/TNLUpdateResponse.h>

static int
memb_tnlUpdateResponse_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_tnlUpdateResponse_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_tnlUpdateResponse_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_tnlUpdateResponse_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_tnlUpdateResponse_ies_tags_2[] = {
	(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static asn_SET_OF_specifics_t asn_SPC_tnlUpdateResponse_ies_specs_2 = {
	sizeof(struct tnlUpdateResponse_ies),
	offsetof(struct tnlUpdateResponse_ies, _asn_ctx),
	0,	/* XER encoding is XMLDelimitedItemList */
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_tnlUpdateResponse_ies_2 = {
	"tnlUpdateResponse-ies",
	"tnlUpdateResponse-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_tnlUpdateResponse_ies_tags_2,
	sizeof(asn_DEF_tnlUpdateResponse_ies_tags_2)
		/sizeof(asn_DEF_tnlUpdateResponse_ies_tags_2[0]) - 1, /* 1 */
	asn_DEF_tnlUpdateResponse_ies_tags_2,	/* Same as above */
	sizeof(asn_DEF_tnlUpdateResponse_ies_tags_2)
		/sizeof(asn_DEF_tnlUpdateResponse_ies_tags_2[0]), /* 2 */
	&asn_PER_type_tnlUpdateResponse_ies_constr_2,
	asn_MBR_tnlUpdateResponse_ies_2,
	1,	/* Single element */
	&asn_SPC_tnlUpdateResponse_ies_specs_2	/* Additional specs */
};

static asn_TYPE_member_t asn_MBR_TNLUpdateResponse_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct TNLUpdateResponse, tnlUpdateResponse_ies),
		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
		0,
		&asn_DEF_tnlUpdateResponse_ies_2,
		memb_tnlUpdateResponse_ies_constraint_1,
		&asn_PER_memb_tnlUpdateResponse_ies_constr_2,
		0,
		"tnlUpdateResponse-ies"
		},
};
static const ber_tlv_tag_t asn_DEF_TNLUpdateResponse_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_TNLUpdateResponse_tag2el_1[] = {
    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 } /* tnlUpdateResponse-ies */
};
static asn_SEQUENCE_specifics_t asn_SPC_TNLUpdateResponse_specs_1 = {
	sizeof(struct TNLUpdateResponse),
	offsetof(struct TNLUpdateResponse, _asn_ctx),
	asn_MAP_TNLUpdateResponse_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_TNLUpdateResponse = {
	"TNLUpdateResponse",
	"TNLUpdateResponse",
	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_TNLUpdateResponse_tags_1,
	sizeof(asn_DEF_TNLUpdateResponse_tags_1)
		/sizeof(asn_DEF_TNLUpdateResponse_tags_1[0]), /* 1 */
	asn_DEF_TNLUpdateResponse_tags_1,	/* Same as above */
	sizeof(asn_DEF_TNLUpdateResponse_tags_1)
		/sizeof(asn_DEF_TNLUpdateResponse_tags_1[0]), /* 1 */
	0,	/* No PER visible constraints */
	asn_MBR_TNLUpdateResponse_1,
	1,	/* Elements count */
	&asn_SPC_TNLUpdateResponse_specs_1	/* Additional specs */
};

