
/*** <<< INCLUDES [A-noc] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [A-noc] >>> ***/

typedef long	 A_noc_t;

/*** <<< FUNC-DECLS [A-noc] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_A_noc;
asn_struct_free_f A_noc_free;
asn_struct_print_f A_noc_print;
asn_constr_check_f A_noc_constraint;
ber_type_decoder_f A_noc_decode_ber;
der_type_encoder_f A_noc_encode_der;
xer_type_decoder_f A_noc_decode_xer;
xer_type_encoder_f A_noc_encode_xer;
oer_type_decoder_f A_noc_decode_oer;
oer_type_encoder_f A_noc_encode_oer;

/*** <<< CODE [A-noc] >>> ***/

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< STAT-DEFS [A-noc] >>> ***/

static const ber_tlv_tag_t asn_DEF_A_noc_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_A_noc = {
	"A-noc",
	"A-noc",
	&asn_OP_NativeInteger,
	NativeInteger_constraint,
	asn_DEF_A_noc_tags_1,
	sizeof(asn_DEF_A_noc_tags_1)
		/sizeof(asn_DEF_A_noc_tags_1[0]), /* 1 */
	asn_DEF_A_noc_tags_1,	/* Same as above */
	sizeof(asn_DEF_A_noc_tags_1)
		/sizeof(asn_DEF_A_noc_tags_1[0]), /* 1 */
	0,	/* No OER visible constraints */
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [B-0-0] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [B-0-0] >>> ***/

typedef long	 B_0_0_t;

/*** <<< FUNC-DECLS [B-0-0] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_B_0_0;
asn_struct_free_f B_0_0_free;
asn_struct_print_f B_0_0_print;
asn_constr_check_f B_0_0_constraint;
ber_type_decoder_f B_0_0_decode_ber;
der_type_encoder_f B_0_0_encode_der;
xer_type_decoder_f B_0_0_decode_xer;
xer_type_encoder_f B_0_0_encode_xer;
oer_type_decoder_f B_0_0_decode_oer;
oer_type_encoder_f B_0_0_encode_oer;

/*** <<< CODE [B-0-0] >>> ***/

int
B_0_0_constraint(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 == 0)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [B-0-0] >>> ***/

static asn_oer_constraints_t asn_OER_type_B_0_0_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (0..0) */,
	-1};

/*** <<< STAT-DEFS [B-0-0] >>> ***/

static const ber_tlv_tag_t asn_DEF_B_0_0_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_B_0_0 = {
	"B-0-0",
	"B-0-0",
	&asn_OP_NativeInteger,
	B_0_0_constraint,
	asn_DEF_B_0_0_tags_1,
	sizeof(asn_DEF_B_0_0_tags_1)
		/sizeof(asn_DEF_B_0_0_tags_1[0]), /* 1 */
	asn_DEF_B_0_0_tags_1,	/* Same as above */
	sizeof(asn_DEF_B_0_0_tags_1)
		/sizeof(asn_DEF_B_0_0_tags_1[0]), /* 1 */
	&asn_OER_type_B_0_0_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [C-1-2] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [C-1-2] >>> ***/

typedef long	 C_1_2_t;

/*** <<< FUNC-DECLS [C-1-2] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_C_1_2;
asn_struct_free_f C_1_2_free;
asn_struct_print_f C_1_2_print;
asn_constr_check_f C_1_2_constraint;
ber_type_decoder_f C_1_2_decode_ber;
der_type_encoder_f C_1_2_encode_der;
xer_type_decoder_f C_1_2_decode_xer;
xer_type_encoder_f C_1_2_encode_xer;
oer_type_decoder_f C_1_2_decode_oer;
oer_type_encoder_f C_1_2_encode_oer;

/*** <<< CODE [C-1-2] >>> ***/

int
C_1_2_constraint(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 >= 1 && value <= 2)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [C-1-2] >>> ***/

static asn_oer_constraints_t asn_OER_type_C_1_2_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (1..2) */,
	-1};

/*** <<< STAT-DEFS [C-1-2] >>> ***/

static const ber_tlv_tag_t asn_DEF_C_1_2_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_C_1_2 = {
	"C-1-2",
	"C-1-2",
	&asn_OP_NativeInteger,
	C_1_2_constraint,
	asn_DEF_C_1_2_tags_1,
	sizeof(asn_DEF_C_1_2_tags_1)
		/sizeof(asn_DEF_C_1_2_tags_1[0]), /* 1 */
	asn_DEF_C_1_2_tags_1,	/* Same as above */
	sizeof(asn_DEF_C_1_2_tags_1)
		/sizeof(asn_DEF_C_1_2_tags_1[0]), /* 1 */
	&asn_OER_type_C_1_2_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [D-inv] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [D-inv] >>> ***/

typedef long	 D_inv_t;

/*** <<< FUNC-DECLS [D-inv] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_D_inv;
asn_struct_free_f D_inv_free;
asn_struct_print_f D_inv_print;
asn_constr_check_f D_inv_constraint;
ber_type_decoder_f D_inv_decode_ber;
der_type_encoder_f D_inv_encode_der;
xer_type_decoder_f D_inv_decode_xer;
xer_type_encoder_f D_inv_encode_xer;
oer_type_decoder_f D_inv_decode_oer;
oer_type_encoder_f D_inv_encode_oer;

/*** <<< CODE [D-inv] >>> ***/

int
D_inv_constraint(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 >= 0 && value <= 10)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [D-inv] >>> ***/

static asn_oer_constraints_t asn_OER_type_D_inv_constr_1 GCC_NOTUSED = {
	{ 0, 0 },
	-1};

/*** <<< STAT-DEFS [D-inv] >>> ***/

static const ber_tlv_tag_t asn_DEF_D_inv_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_D_inv = {
	"D-inv",
	"D-inv",
	&asn_OP_NativeInteger,
	D_inv_constraint,
	asn_DEF_D_inv_tags_1,
	sizeof(asn_DEF_D_inv_tags_1)
		/sizeof(asn_DEF_D_inv_tags_1[0]), /* 1 */
	asn_DEF_D_inv_tags_1,	/* Same as above */
	sizeof(asn_DEF_D_inv_tags_1)
		/sizeof(asn_DEF_D_inv_tags_1[0]), /* 1 */
	&asn_OER_type_D_inv_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [E-2-5] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [E-2-5] >>> ***/

typedef long	 E_2_5_t;

/*** <<< FUNC-DECLS [E-2-5] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_E_2_5;
asn_struct_free_f E_2_5_free;
asn_struct_print_f E_2_5_print;
asn_constr_check_f E_2_5_constraint;
ber_type_decoder_f E_2_5_decode_ber;
der_type_encoder_f E_2_5_encode_der;
xer_type_decoder_f E_2_5_decode_xer;
xer_type_encoder_f E_2_5_encode_xer;
oer_type_decoder_f E_2_5_decode_oer;
oer_type_encoder_f E_2_5_encode_oer;

/*** <<< CODE [E-2-5] >>> ***/

int
E_2_5_constraint(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 >= 2 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [E-2-5] >>> ***/

static asn_oer_constraints_t asn_OER_type_E_2_5_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (2..5) */,
	-1};

/*** <<< STAT-DEFS [E-2-5] >>> ***/

static const ber_tlv_tag_t asn_DEF_E_2_5_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_E_2_5 = {
	"E-2-5",
	"E-2-5",
	&asn_OP_NativeInteger,
	E_2_5_constraint,
	asn_DEF_E_2_5_tags_1,
	sizeof(asn_DEF_E_2_5_tags_1)
		/sizeof(asn_DEF_E_2_5_tags_1[0]), /* 1 */
	asn_DEF_E_2_5_tags_1,	/* Same as above */
	sizeof(asn_DEF_E_2_5_tags_1)
		/sizeof(asn_DEF_E_2_5_tags_1[0]), /* 1 */
	&asn_OER_type_E_2_5_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [F-inv] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [F-inv] >>> ***/

typedef long	 F_inv_t;

/*** <<< FUNC-DECLS [F-inv] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_F_inv;
asn_struct_free_f F_inv_free;
asn_struct_print_f F_inv_print;
asn_constr_check_f F_inv_constraint;
ber_type_decoder_f F_inv_decode_ber;
der_type_encoder_f F_inv_encode_der;
xer_type_decoder_f F_inv_decode_xer;
xer_type_encoder_f F_inv_encode_xer;
oer_type_decoder_f F_inv_decode_oer;
oer_type_encoder_f F_inv_encode_oer;

/*** <<< CODE [F-inv] >>> ***/

int
F_inv_constraint(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 >= 2 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [F-inv] >>> ***/

static asn_oer_constraints_t asn_OER_type_F_inv_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (0..10) */,
	-1};

/*** <<< STAT-DEFS [F-inv] >>> ***/

static const ber_tlv_tag_t asn_DEF_F_inv_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_F_inv = {
	"F-inv",
	"F-inv",
	&asn_OP_NativeInteger,
	F_inv_constraint,
	asn_DEF_F_inv_tags_1,
	sizeof(asn_DEF_F_inv_tags_1)
		/sizeof(asn_DEF_F_inv_tags_1[0]), /* 1 */
	asn_DEF_F_inv_tags_1,	/* Same as above */
	sizeof(asn_DEF_F_inv_tags_1)
		/sizeof(asn_DEF_F_inv_tags_1[0]), /* 1 */
	&asn_OER_type_F_inv_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [G-3-3] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [G-3-3] >>> ***/

typedef long	 G_3_3_t;

/*** <<< FUNC-DECLS [G-3-3] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_G_3_3;
asn_struct_free_f G_3_3_free;
asn_struct_print_f G_3_3_print;
asn_constr_check_f G_3_3_constraint;
ber_type_decoder_f G_3_3_decode_ber;
der_type_encoder_f G_3_3_encode_der;
xer_type_decoder_f G_3_3_decode_xer;
xer_type_encoder_f G_3_3_encode_xer;
oer_type_decoder_f G_3_3_decode_oer;
oer_type_encoder_f G_3_3_encode_oer;

/*** <<< CODE [G-3-3] >>> ***/

int
G_3_3_constraint(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 == 3)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [G-3-3] >>> ***/

static asn_oer_constraints_t asn_OER_type_G_3_3_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (3..3) */,
	-1};

/*** <<< STAT-DEFS [G-3-3] >>> ***/

static const ber_tlv_tag_t asn_DEF_G_3_3_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_G_3_3 = {
	"G-3-3",
	"G-3-3",
	&asn_OP_NativeInteger,
	G_3_3_constraint,
	asn_DEF_G_3_3_tags_1,
	sizeof(asn_DEF_G_3_3_tags_1)
		/sizeof(asn_DEF_G_3_3_tags_1[0]), /* 1 */
	asn_DEF_G_3_3_tags_1,	/* Same as above */
	sizeof(asn_DEF_G_3_3_tags_1)
		/sizeof(asn_DEF_G_3_3_tags_1[0]), /* 1 */
	&asn_OER_type_G_3_3_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [H-4-5] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [H-4-5] >>> ***/

typedef long	 H_4_5_t;

/*** <<< FUNC-DECLS [H-4-5] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_H_4_5;
asn_struct_free_f H_4_5_free;
asn_struct_print_f H_4_5_print;
asn_constr_check_f H_4_5_constraint;
ber_type_decoder_f H_4_5_decode_ber;
der_type_encoder_f H_4_5_encode_der;
xer_type_decoder_f H_4_5_decode_xer;
xer_type_encoder_f H_4_5_encode_xer;
oer_type_decoder_f H_4_5_decode_oer;
oer_type_encoder_f H_4_5_encode_oer;

/*** <<< CODE [H-4-5] >>> ***/

int
H_4_5_constraint(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 >= 4 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [H-4-5] >>> ***/

static asn_oer_constraints_t asn_OER_type_H_4_5_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (4..5) */,
	-1};

/*** <<< STAT-DEFS [H-4-5] >>> ***/

static const ber_tlv_tag_t asn_DEF_H_4_5_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_H_4_5 = {
	"H-4-5",
	"H-4-5",
	&asn_OP_NativeInteger,
	H_4_5_constraint,
	asn_DEF_H_4_5_tags_1,
	sizeof(asn_DEF_H_4_5_tags_1)
		/sizeof(asn_DEF_H_4_5_tags_1[0]), /* 1 */
	asn_DEF_H_4_5_tags_1,	/* Same as above */
	sizeof(asn_DEF_H_4_5_tags_1)
		/sizeof(asn_DEF_H_4_5_tags_1[0]), /* 1 */
	&asn_OER_type_H_4_5_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [I-1-5] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [I-1-5] >>> ***/

typedef long	 I_1_5_t;

/*** <<< FUNC-DECLS [I-1-5] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_I_1_5;
asn_struct_free_f I_1_5_free;
asn_struct_print_f I_1_5_print;
asn_constr_check_f I_1_5_constraint;
ber_type_decoder_f I_1_5_decode_ber;
der_type_encoder_f I_1_5_encode_der;
xer_type_decoder_f I_1_5_decode_xer;
xer_type_encoder_f I_1_5_encode_xer;
oer_type_decoder_f I_1_5_decode_oer;
oer_type_encoder_f I_1_5_encode_oer;

/*** <<< CODE [I-1-5] >>> ***/

int
I_1_5_constraint(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 >= 1 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [I-1-5] >>> ***/

static asn_oer_constraints_t asn_OER_type_I_1_5_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (1..5) */,
	-1};

/*** <<< STAT-DEFS [I-1-5] >>> ***/

static const ber_tlv_tag_t asn_DEF_I_1_5_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_I_1_5 = {
	"I-1-5",
	"I-1-5",
	&asn_OP_NativeInteger,
	I_1_5_constraint,
	asn_DEF_I_1_5_tags_1,
	sizeof(asn_DEF_I_1_5_tags_1)
		/sizeof(asn_DEF_I_1_5_tags_1[0]), /* 1 */
	asn_DEF_I_1_5_tags_1,	/* Same as above */
	sizeof(asn_DEF_I_1_5_tags_1)
		/sizeof(asn_DEF_I_1_5_tags_1[0]), /* 1 */
	&asn_OER_type_I_1_5_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [J-4-5] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [J-4-5] >>> ***/

typedef long	 J_4_5_t;

/*** <<< FUNC-DECLS [J-4-5] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_J_4_5;
asn_struct_free_f J_4_5_free;
asn_struct_print_f J_4_5_print;
asn_constr_check_f J_4_5_constraint;
ber_type_decoder_f J_4_5_decode_ber;
der_type_encoder_f J_4_5_encode_der;
xer_type_decoder_f J_4_5_decode_xer;
xer_type_encoder_f J_4_5_encode_xer;
oer_type_decoder_f J_4_5_decode_oer;
oer_type_encoder_f J_4_5_encode_oer;

/*** <<< CODE [J-4-5] >>> ***/

int
J_4_5_constraint(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 >= 4 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [J-4-5] >>> ***/

static asn_oer_constraints_t asn_OER_type_J_4_5_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (4..5) */,
	-1};

/*** <<< STAT-DEFS [J-4-5] >>> ***/

static const ber_tlv_tag_t asn_DEF_J_4_5_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_J_4_5 = {
	"J-4-5",
	"J-4-5",
	&asn_OP_NativeInteger,
	J_4_5_constraint,
	asn_DEF_J_4_5_tags_1,
	sizeof(asn_DEF_J_4_5_tags_1)
		/sizeof(asn_DEF_J_4_5_tags_1[0]), /* 1 */
	asn_DEF_J_4_5_tags_1,	/* Same as above */
	sizeof(asn_DEF_J_4_5_tags_1)
		/sizeof(asn_DEF_J_4_5_tags_1[0]), /* 1 */
	&asn_OER_type_J_4_5_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [K-1-4] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [K-1-4] >>> ***/

typedef long	 K_1_4_t;

/*** <<< FUNC-DECLS [K-1-4] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_K_1_4;
asn_struct_free_f K_1_4_free;
asn_struct_print_f K_1_4_print;
asn_constr_check_f K_1_4_constraint;
ber_type_decoder_f K_1_4_decode_ber;
der_type_encoder_f K_1_4_encode_der;
xer_type_decoder_f K_1_4_decode_xer;
xer_type_encoder_f K_1_4_encode_xer;
oer_type_decoder_f K_1_4_decode_oer;
oer_type_encoder_f K_1_4_encode_oer;

/*** <<< CODE [K-1-4] >>> ***/

int
K_1_4_constraint(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 >= 1 && value <= 4)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [K-1-4] >>> ***/

static asn_oer_constraints_t asn_OER_type_K_1_4_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (1..4) */,
	-1};

/*** <<< STAT-DEFS [K-1-4] >>> ***/

static const ber_tlv_tag_t asn_DEF_K_1_4_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_K_1_4 = {
	"K-1-4",
	"K-1-4",
	&asn_OP_NativeInteger,
	K_1_4_constraint,
	asn_DEF_K_1_4_tags_1,
	sizeof(asn_DEF_K_1_4_tags_1)
		/sizeof(asn_DEF_K_1_4_tags_1[0]), /* 1 */
	asn_DEF_K_1_4_tags_1,	/* Same as above */
	sizeof(asn_DEF_K_1_4_tags_1)
		/sizeof(asn_DEF_K_1_4_tags_1[0]), /* 1 */
	&asn_OER_type_K_1_4_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [L-0-5] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [L-0-5] >>> ***/

typedef long	 L_0_5_t;

/*** <<< FUNC-DECLS [L-0-5] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_L_0_5;
asn_struct_free_f L_0_5_free;
asn_struct_print_f L_0_5_print;
asn_constr_check_f L_0_5_constraint;
ber_type_decoder_f L_0_5_decode_ber;
der_type_encoder_f L_0_5_encode_der;
xer_type_decoder_f L_0_5_decode_xer;
xer_type_encoder_f L_0_5_encode_xer;
oer_type_decoder_f L_0_5_decode_oer;
oer_type_encoder_f L_0_5_encode_oer;

/*** <<< CODE [L-0-5] >>> ***/

int
L_0_5_constraint(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 == 0) || (value == 5))) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [L-0-5] >>> ***/

static asn_oer_constraints_t asn_OER_type_L_0_5_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (0..5) */,
	-1};

/*** <<< STAT-DEFS [L-0-5] >>> ***/

static const ber_tlv_tag_t asn_DEF_L_0_5_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_L_0_5 = {
	"L-0-5",
	"L-0-5",
	&asn_OP_NativeInteger,
	L_0_5_constraint,
	asn_DEF_L_0_5_tags_1,
	sizeof(asn_DEF_L_0_5_tags_1)
		/sizeof(asn_DEF_L_0_5_tags_1[0]), /* 1 */
	asn_DEF_L_0_5_tags_1,	/* Same as above */
	sizeof(asn_DEF_L_0_5_tags_1)
		/sizeof(asn_DEF_L_0_5_tags_1[0]), /* 1 */
	&asn_OER_type_L_0_5_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [M-inv] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [M-inv] >>> ***/

typedef long	 M_inv_t;

/*** <<< FUNC-DECLS [M-inv] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_M_inv;
asn_struct_free_f M_inv_free;
asn_struct_print_f M_inv_print;
asn_constr_check_f M_inv_constraint;
ber_type_decoder_f M_inv_decode_ber;
der_type_encoder_f M_inv_encode_der;
xer_type_decoder_f M_inv_decode_xer;
xer_type_encoder_f M_inv_encode_xer;
oer_type_decoder_f M_inv_decode_oer;
oer_type_encoder_f M_inv_encode_oer;

/*** <<< CODE [M-inv] >>> ***/

int
M_inv_constraint(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 >= 0 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [M-inv] >>> ***/

static asn_oer_constraints_t asn_OER_type_M_inv_constr_1 GCC_NOTUSED = {
	{ 0, 0 },
	-1};

/*** <<< STAT-DEFS [M-inv] >>> ***/

static const ber_tlv_tag_t asn_DEF_M_inv_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_M_inv = {
	"M-inv",
	"M-inv",
	&asn_OP_NativeInteger,
	M_inv_constraint,
	asn_DEF_M_inv_tags_1,
	sizeof(asn_DEF_M_inv_tags_1)
		/sizeof(asn_DEF_M_inv_tags_1[0]), /* 1 */
	asn_DEF_M_inv_tags_1,	/* Same as above */
	sizeof(asn_DEF_M_inv_tags_1)
		/sizeof(asn_DEF_M_inv_tags_1[0]), /* 1 */
	&asn_OER_type_M_inv_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [N-0-5] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [N-0-5] >>> ***/

typedef long	 N_0_5_t;

/*** <<< FUNC-DECLS [N-0-5] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_N_0_5;
asn_struct_free_f N_0_5_free;
asn_struct_print_f N_0_5_print;
asn_constr_check_f N_0_5_constraint;
ber_type_decoder_f N_0_5_decode_ber;
der_type_encoder_f N_0_5_encode_der;
xer_type_decoder_f N_0_5_decode_xer;
xer_type_encoder_f N_0_5_encode_xer;
oer_type_decoder_f N_0_5_decode_oer;
oer_type_encoder_f N_0_5_encode_oer;

/*** <<< CODE [N-0-5] >>> ***/

int
N_0_5_constraint(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 >= 0 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [N-0-5] >>> ***/

static asn_oer_constraints_t asn_OER_type_N_0_5_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (0..5) */,
	-1};

/*** <<< STAT-DEFS [N-0-5] >>> ***/

static const ber_tlv_tag_t asn_DEF_N_0_5_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_N_0_5 = {
	"N-0-5",
	"N-0-5",
	&asn_OP_NativeInteger,
	N_0_5_constraint,
	asn_DEF_N_0_5_tags_1,
	sizeof(asn_DEF_N_0_5_tags_1)
		/sizeof(asn_DEF_N_0_5_tags_1[0]), /* 1 */
	asn_DEF_N_0_5_tags_1,	/* Same as above */
	sizeof(asn_DEF_N_0_5_tags_1)
		/sizeof(asn_DEF_N_0_5_tags_1[0]), /* 1 */
	&asn_OER_type_N_0_5_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [O-inv] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [O-inv] >>> ***/

typedef long	 O_inv_t;

/*** <<< FUNC-DECLS [O-inv] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_O_inv;
asn_struct_free_f O_inv_free;
asn_struct_print_f O_inv_print;
asn_constr_check_f O_inv_constraint;
ber_type_decoder_f O_inv_decode_ber;
der_type_encoder_f O_inv_encode_der;
xer_type_decoder_f O_inv_decode_xer;
xer_type_encoder_f O_inv_encode_xer;
oer_type_decoder_f O_inv_decode_oer;
oer_type_encoder_f O_inv_encode_oer;

/*** <<< CODE [O-inv] >>> ***/

int
O_inv_constraint(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 >= 0 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [O-inv] >>> ***/

static asn_oer_constraints_t asn_OER_type_O_inv_constr_1 GCC_NOTUSED = {
	{ 0, 0 },
	-1};

/*** <<< STAT-DEFS [O-inv] >>> ***/

static const ber_tlv_tag_t asn_DEF_O_inv_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_O_inv = {
	"O-inv",
	"O-inv",
	&asn_OP_NativeInteger,
	O_inv_constraint,
	asn_DEF_O_inv_tags_1,
	sizeof(asn_DEF_O_inv_tags_1)
		/sizeof(asn_DEF_O_inv_tags_1[0]), /* 1 */
	asn_DEF_O_inv_tags_1,	/* Same as above */
	sizeof(asn_DEF_O_inv_tags_1)
		/sizeof(asn_DEF_O_inv_tags_1[0]), /* 1 */
	&asn_OER_type_O_inv_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [EConstr] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [EConstr] >>> ***/

typedef long	 EConstr_t;

/*** <<< FUNC-DECLS [EConstr] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_EConstr;
asn_struct_free_f EConstr_free;
asn_struct_print_f EConstr_print;
asn_constr_check_f EConstr_constraint;
ber_type_decoder_f EConstr_decode_ber;
der_type_encoder_f EConstr_encode_der;
xer_type_decoder_f EConstr_decode_xer;
xer_type_encoder_f EConstr_encode_xer;
oer_type_decoder_f EConstr_decode_oer;
oer_type_encoder_f EConstr_encode_oer;

/*** <<< CODE [EConstr] >>> ***/

int
EConstr_constraint(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 >= 1 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [EConstr] >>> ***/

static asn_oer_constraints_t asn_OER_type_EConstr_constr_1 GCC_NOTUSED = {
	{ 0, 0 },
	-1};

/*** <<< STAT-DEFS [EConstr] >>> ***/

static const ber_tlv_tag_t asn_DEF_EConstr_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_EConstr = {
	"EConstr",
	"EConstr",
	&asn_OP_NativeInteger,
	EConstr_constraint,
	asn_DEF_EConstr_tags_1,
	sizeof(asn_DEF_EConstr_tags_1)
		/sizeof(asn_DEF_EConstr_tags_1[0]), /* 1 */
	asn_DEF_EConstr_tags_1,	/* Same as above */
	sizeof(asn_DEF_EConstr_tags_1)
		/sizeof(asn_DEF_EConstr_tags_1[0]), /* 1 */
	&asn_OER_type_EConstr_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [FConstr] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [FConstr] >>> ***/

typedef long	 FConstr_t;

/*** <<< FUNC-DECLS [FConstr] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_FConstr;
asn_struct_free_f FConstr_free;
asn_struct_print_f FConstr_print;
asn_constr_check_f FConstr_constraint;
ber_type_decoder_f FConstr_decode_ber;
der_type_encoder_f FConstr_encode_der;
xer_type_decoder_f FConstr_decode_xer;
xer_type_encoder_f FConstr_encode_xer;
oer_type_decoder_f FConstr_decode_oer;
oer_type_encoder_f FConstr_encode_oer;

/*** <<< CODE [FConstr] >>> ***/

int
FConstr_constraint(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 >= 0 && value <= 4)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [FConstr] >>> ***/

static asn_oer_constraints_t asn_OER_type_FConstr_constr_1 GCC_NOTUSED = {
	{ 1, 1 }	/* (0..4) */,
	-1};

/*** <<< STAT-DEFS [FConstr] >>> ***/

static const ber_tlv_tag_t asn_DEF_FConstr_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_FConstr = {
	"FConstr",
	"FConstr",
	&asn_OP_NativeInteger,
	FConstr_constraint,
	asn_DEF_FConstr_tags_1,
	sizeof(asn_DEF_FConstr_tags_1)
		/sizeof(asn_DEF_FConstr_tags_1[0]), /* 1 */
	asn_DEF_FConstr_tags_1,	/* Same as above */
	sizeof(asn_DEF_FConstr_tags_1)
		/sizeof(asn_DEF_FConstr_tags_1[0]), /* 1 */
	&asn_OER_type_FConstr_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};

