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

#include "RANAP_AlternativeRABConfigurationRequest.h"

int
RANAP_AlternativeRABConfigurationRequest_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
RANAP_AlternativeRABConfigurationRequest_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
RANAP_AlternativeRABConfigurationRequest_free(asn_TYPE_descriptor_t *td,
		void *struct_ptr, int contents_only) {
	RANAP_AlternativeRABConfigurationRequest_1_inherit_TYPE_descriptor(td);
	td->free_struct(td, struct_ptr, contents_only);
}

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

asn_dec_rval_t
RANAP_AlternativeRABConfigurationRequest_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) {
	RANAP_AlternativeRABConfigurationRequest_1_inherit_TYPE_descriptor(td);
	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
}

asn_enc_rval_t
RANAP_AlternativeRABConfigurationRequest_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) {
	RANAP_AlternativeRABConfigurationRequest_1_inherit_TYPE_descriptor(td);
	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
}

asn_dec_rval_t
RANAP_AlternativeRABConfigurationRequest_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) {
	RANAP_AlternativeRABConfigurationRequest_1_inherit_TYPE_descriptor(td);
	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
}

asn_enc_rval_t
RANAP_AlternativeRABConfigurationRequest_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) {
	RANAP_AlternativeRABConfigurationRequest_1_inherit_TYPE_descriptor(td);
	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
}

asn_dec_rval_t
RANAP_AlternativeRABConfigurationRequest_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) {
	RANAP_AlternativeRABConfigurationRequest_1_inherit_TYPE_descriptor(td);
	return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data);
}

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

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

asn_dec_rval_t
RANAP_AlternativeRABConfigurationRequest_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) {
	RANAP_AlternativeRABConfigurationRequest_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_RANAP_AlternativeRABConfigurationRequest_constr_1 GCC_NOTUSED = {
	{ APC_CONSTRAINED | APC_EXTENSIBLE,  0,  0,  0l,  0l }	/* (0..0,...) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};
static const asn_INTEGER_enum_map_t asn_MAP_RANAP_AlternativeRABConfigurationRequest_value2enum_1[] = {
	{ 0,	39,	"alternative-RAB-configuration-Requested" }
	/* This list is extensible */
};
static const unsigned int asn_MAP_RANAP_AlternativeRABConfigurationRequest_enum2value_1[] = {
	0	/* alternative-RAB-configuration-Requested(0) */
	/* This list is extensible */
};
static const asn_INTEGER_specifics_t asn_SPC_RANAP_AlternativeRABConfigurationRequest_specs_1 = {
	asn_MAP_RANAP_AlternativeRABConfigurationRequest_value2enum_1,	/* "tag" => N; sorted by tag */
	asn_MAP_RANAP_AlternativeRABConfigurationRequest_enum2value_1,	/* N => "tag"; sorted by N */
	1,	/* Number of elements in the maps */
	2,	/* Extensions before this member */
	1,	/* Strict enumeration */
	0,	/* Native long size */
	0
};
static const ber_tlv_tag_t asn_DEF_RANAP_AlternativeRABConfigurationRequest_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
};
asn_TYPE_descriptor_t asn_DEF_RANAP_AlternativeRABConfigurationRequest = {
	"RANAP_AlternativeRABConfigurationRequest",
	"RANAP_AlternativeRABConfigurationRequest",
	RANAP_AlternativeRABConfigurationRequest_free,
	RANAP_AlternativeRABConfigurationRequest_print,
	RANAP_AlternativeRABConfigurationRequest_constraint,
	RANAP_AlternativeRABConfigurationRequest_decode_ber,
	RANAP_AlternativeRABConfigurationRequest_encode_der,
	RANAP_AlternativeRABConfigurationRequest_decode_xer,
	RANAP_AlternativeRABConfigurationRequest_encode_xer,
	RANAP_AlternativeRABConfigurationRequest_decode_uper,
	RANAP_AlternativeRABConfigurationRequest_encode_uper,
	RANAP_AlternativeRABConfigurationRequest_decode_aper,
	RANAP_AlternativeRABConfigurationRequest_encode_aper,
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_RANAP_AlternativeRABConfigurationRequest_tags_1,
	sizeof(asn_DEF_RANAP_AlternativeRABConfigurationRequest_tags_1)
		/sizeof(asn_DEF_RANAP_AlternativeRABConfigurationRequest_tags_1[0]), /* 1 */
	asn_DEF_RANAP_AlternativeRABConfigurationRequest_tags_1,	/* Same as above */
	sizeof(asn_DEF_RANAP_AlternativeRABConfigurationRequest_tags_1)
		/sizeof(asn_DEF_RANAP_AlternativeRABConfigurationRequest_tags_1[0]), /* 1 */
	&asn_PER_type_RANAP_AlternativeRABConfigurationRequest_constr_1,
	0, 0,	/* Defined elsewhere */
	&asn_SPC_RANAP_AlternativeRABConfigurationRequest_specs_1	/* Additional specs */
};

