/*
 * 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_GA-UncertaintyEllipse.h"

static int
memb_uncertaintySemi_major_constraint_1(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 >= 0l && value <= 127l)) {
		/* 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_uncertaintySemi_minor_constraint_1(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 >= 0l && value <= 127l)) {
		/* 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_orientationOfMajorAxis_constraint_1(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 >= 0l && value <= 179l)) {
		/* Constraint check succeeded */
		return 0;
	} 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_memb_uncertaintySemi_major_constr_2 GCC_NOTUSED = {
	{ APC_CONSTRAINED,	 7,  7,  0l,  127l }	/* (0..127) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};
static asn_per_constraints_t asn_PER_memb_uncertaintySemi_minor_constr_3 GCC_NOTUSED = {
	{ APC_CONSTRAINED,	 7,  7,  0l,  127l }	/* (0..127) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};
static asn_per_constraints_t asn_PER_memb_orientationOfMajorAxis_constr_4 GCC_NOTUSED = {
	{ APC_CONSTRAINED,	 8,  8,  0l,  179l }	/* (0..179) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};
static asn_TYPE_member_t asn_MBR_RANAP_GA_UncertaintyEllipse_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct RANAP_GA_UncertaintyEllipse, uncertaintySemi_major),
		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
		-1,	/* IMPLICIT tag at current level */
		&asn_DEF_NativeInteger,
		memb_uncertaintySemi_major_constraint_1,
		&asn_PER_memb_uncertaintySemi_major_constr_2,
		0,
		"uncertaintySemi-major"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct RANAP_GA_UncertaintyEllipse, uncertaintySemi_minor),
		(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
		-1,	/* IMPLICIT tag at current level */
		&asn_DEF_NativeInteger,
		memb_uncertaintySemi_minor_constraint_1,
		&asn_PER_memb_uncertaintySemi_minor_constr_3,
		0,
		"uncertaintySemi-minor"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct RANAP_GA_UncertaintyEllipse, orientationOfMajorAxis),
		(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
		-1,	/* IMPLICIT tag at current level */
		&asn_DEF_NativeInteger,
		memb_orientationOfMajorAxis_constraint_1,
		&asn_PER_memb_orientationOfMajorAxis_constr_4,
		0,
		"orientationOfMajorAxis"
		},
};
static const ber_tlv_tag_t asn_DEF_RANAP_GA_UncertaintyEllipse_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_RANAP_GA_UncertaintyEllipse_tag2el_1[] = {
    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* uncertaintySemi-major */
    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* uncertaintySemi-minor */
    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* orientationOfMajorAxis */
};
static asn_SEQUENCE_specifics_t asn_SPC_RANAP_GA_UncertaintyEllipse_specs_1 = {
	sizeof(struct RANAP_GA_UncertaintyEllipse),
	offsetof(struct RANAP_GA_UncertaintyEllipse, _asn_ctx),
	asn_MAP_RANAP_GA_UncertaintyEllipse_tag2el_1,
	3,	/* Count of tags in the map */
	0, 0, 0,	/* Optional elements (not needed) */
	2,	/* Start extensions */
	4	/* Stop extensions */
};
asn_TYPE_descriptor_t asn_DEF_RANAP_GA_UncertaintyEllipse = {
	"RANAP_GA-UncertaintyEllipse",
	"RANAP_GA-UncertaintyEllipse",
	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_RANAP_GA_UncertaintyEllipse_tags_1,
	sizeof(asn_DEF_RANAP_GA_UncertaintyEllipse_tags_1)
		/sizeof(asn_DEF_RANAP_GA_UncertaintyEllipse_tags_1[0]), /* 1 */
	asn_DEF_RANAP_GA_UncertaintyEllipse_tags_1,	/* Same as above */
	sizeof(asn_DEF_RANAP_GA_UncertaintyEllipse_tags_1)
		/sizeof(asn_DEF_RANAP_GA_UncertaintyEllipse_tags_1[0]), /* 1 */
	0,	/* No PER visible constraints */
	asn_MBR_RANAP_GA_UncertaintyEllipse_1,
	3,	/* Elements count */
	&asn_SPC_RANAP_GA_UncertaintyEllipse_specs_1	/* Additional specs */
};

