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

#include "Access-stratum-release-indicator.h"

int
Access_stratum_release_indicator_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	/* Replace with underlying type checker */
	td->check_constraints = asn_DEF_NativeEnumerated.check_constraints;
	return td->check_constraints(td, sptr, ctfailcb, app_key);
}

/*
 * This type is implemented using NativeEnumerated,
 * so here we adjust the DEF accordingly.
 */
static void
Access_stratum_release_indicator_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
	td->free_struct    = asn_DEF_NativeEnumerated.free_struct;
	td->print_struct   = asn_DEF_NativeEnumerated.print_struct;
	td->check_constraints = asn_DEF_NativeEnumerated.check_constraints;
	td->ber_decoder    = asn_DEF_NativeEnumerated.ber_decoder;
	td->der_encoder    = asn_DEF_NativeEnumerated.der_encoder;
	td->xer_decoder    = asn_DEF_NativeEnumerated.xer_decoder;
	td->xer_encoder    = asn_DEF_NativeEnumerated.xer_encoder;
	td->uper_decoder   = asn_DEF_NativeEnumerated.uper_decoder;
	td->uper_encoder   = asn_DEF_NativeEnumerated.uper_encoder;
	td->aper_decoder   = asn_DEF_NativeEnumerated.aper_decoder;
	td->aper_encoder   = asn_DEF_NativeEnumerated.aper_encoder;
	if(!td->per_constraints)
		td->per_constraints = asn_DEF_NativeEnumerated.per_constraints;
	td->elements       = asn_DEF_NativeEnumerated.elements;
	td->elements_count = asn_DEF_NativeEnumerated.elements_count;
     /* td->specifics      = asn_DEF_NativeEnumerated.specifics;	// Defined explicitly */
}

void
Access_stratum_release_indicator_free(asn_TYPE_descriptor_t *td,
		void *struct_ptr, int contents_only) {
	Access_stratum_release_indicator_1_inherit_TYPE_descriptor(td);
	td->free_struct(td, struct_ptr, contents_only);
}

int
Access_stratum_release_indicator_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
	Access_stratum_release_indicator_1_inherit_TYPE_descriptor(td);
	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
}

asn_dec_rval_t
Access_stratum_release_indicator_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
		void **structure, const void *bufptr, size_t size, int tag_mode) {
	Access_stratum_release_indicator_1_inherit_TYPE_descriptor(td);
	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
}

asn_enc_rval_t
Access_stratum_release_indicator_encode_der(asn_TYPE_descriptor_t *td,
		void *structure, int tag_mode, ber_tlv_tag_t tag,
		asn_app_consume_bytes_f *cb, void *app_key) {
	Access_stratum_release_indicator_1_inherit_TYPE_descriptor(td);
	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
}

asn_dec_rval_t
Access_stratum_release_indicator_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
	Access_stratum_release_indicator_1_inherit_TYPE_descriptor(td);
	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
}

asn_enc_rval_t
Access_stratum_release_indicator_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
		int ilevel, enum xer_encoder_flags_e flags,
		asn_app_consume_bytes_f *cb, void *app_key) {
	Access_stratum_release_indicator_1_inherit_TYPE_descriptor(td);
	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
}

asn_dec_rval_t
Access_stratum_release_indicator_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
		asn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) {
	Access_stratum_release_indicator_1_inherit_TYPE_descriptor(td);
	return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data);
}

asn_enc_rval_t
Access_stratum_release_indicator_encode_uper(asn_TYPE_descriptor_t *td,
		asn_per_constraints_t *constraints,
		void *structure, asn_per_outp_t *per_out) {
	Access_stratum_release_indicator_1_inherit_TYPE_descriptor(td);
	return td->uper_encoder(td, constraints, structure, per_out);
}

asn_enc_rval_t
Access_stratum_release_indicator_encode_aper(asn_TYPE_descriptor_t *td,
		asn_per_constraints_t *constraints,
		void *structure, asn_per_outp_t *per_out) {
	Access_stratum_release_indicator_1_inherit_TYPE_descriptor(td);
	return td->aper_encoder(td, constraints, structure, per_out);
}

asn_dec_rval_t
Access_stratum_release_indicator_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
		asn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) {
	Access_stratum_release_indicator_1_inherit_TYPE_descriptor(td);
	return td->aper_decoder(opt_codec_ctx, td, constraints, structure, per_data);
}

static asn_per_constraints_t asn_PER_type_Access_stratum_release_indicator_constr_1 GCC_NOTUSED = {
	{ APC_CONSTRAINED | APC_EXTENSIBLE,  3,  3,  0l,  5l }	/* (0..5,...) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};
static const asn_INTEGER_enum_map_t asn_MAP_Access_stratum_release_indicator_value2enum_1[] = {
	{ 0,	3,	"r99" },
	{ 1,	5,	"rel-4" },
	{ 2,	5,	"rel-5" },
	{ 3,	5,	"rel-6" },
	{ 4,	5,	"rel-7" },
	{ 5,	16,	"rel-8-and-beyond" }
	/* This list is extensible */
};
static const unsigned int asn_MAP_Access_stratum_release_indicator_enum2value_1[] = {
	0,	/* r99(0) */
	1,	/* rel-4(1) */
	2,	/* rel-5(2) */
	3,	/* rel-6(3) */
	4,	/* rel-7(4) */
	5	/* rel-8-and-beyond(5) */
	/* This list is extensible */
};
static const asn_INTEGER_specifics_t asn_SPC_Access_stratum_release_indicator_specs_1 = {
	asn_MAP_Access_stratum_release_indicator_value2enum_1,	/* "tag" => N; sorted by tag */
	asn_MAP_Access_stratum_release_indicator_enum2value_1,	/* N => "tag"; sorted by N */
	6,	/* Number of elements in the maps */
	7,	/* Extensions before this member */
	1,	/* Strict enumeration */
	0,	/* Native long size */
	0
};
static const ber_tlv_tag_t asn_DEF_Access_stratum_release_indicator_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
};
asn_TYPE_descriptor_t asn_DEF_Access_stratum_release_indicator = {
	"Access-stratum-release-indicator",
	"Access-stratum-release-indicator",
	Access_stratum_release_indicator_free,
	Access_stratum_release_indicator_print,
	Access_stratum_release_indicator_constraint,
	Access_stratum_release_indicator_decode_ber,
	Access_stratum_release_indicator_encode_der,
	Access_stratum_release_indicator_decode_xer,
	Access_stratum_release_indicator_encode_xer,
	Access_stratum_release_indicator_decode_uper,
	Access_stratum_release_indicator_encode_uper,
	Access_stratum_release_indicator_decode_aper,
	Access_stratum_release_indicator_encode_aper,
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_Access_stratum_release_indicator_tags_1,
	sizeof(asn_DEF_Access_stratum_release_indicator_tags_1)
		/sizeof(asn_DEF_Access_stratum_release_indicator_tags_1[0]), /* 1 */
	asn_DEF_Access_stratum_release_indicator_tags_1,	/* Same as above */
	sizeof(asn_DEF_Access_stratum_release_indicator_tags_1)
		/sizeof(asn_DEF_Access_stratum_release_indicator_tags_1[0]), /* 1 */
	&asn_PER_type_Access_stratum_release_indicator_constr_1,
	0, 0,	/* Defined elsewhere */
	&asn_SPC_Access_stratum_release_indicator_specs_1	/* Additional specs */
};

