
/*** <<< INCLUDES [PacketId] >>> ***/

#include <NativeInteger.h>

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

typedef long	 PacketId_t;

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

extern asn_per_constraints_t asn_PER_type_PacketId_constr_1;
extern asn_TYPE_descriptor_t asn_DEF_PacketId;
asn_struct_free_f PacketId_free;
asn_struct_print_f PacketId_print;
asn_constr_check_f PacketId_constraint;
ber_type_decoder_f PacketId_decode_ber;
der_type_encoder_f PacketId_encode_der;
xer_type_decoder_f PacketId_decode_xer;
xer_type_encoder_f PacketId_encode_xer;
per_type_decoder_f PacketId_decode_uper;
per_type_encoder_f PacketId_encode_uper;

/*** <<< CODE [PacketId] >>> ***/

int
PacketId_constraint(const 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 <= 65535)) {
		/* 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 [PacketId] >>> ***/

asn_per_constraints_t asn_PER_type_PacketId_constr_1 CC_NOTUSED = {
	{ APC_CONSTRAINED,	 16,  16,  0,  65535 }	/* (0..65535) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};

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

static const ber_tlv_tag_t asn_DEF_PacketId_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_PacketId = {
	"PacketId",
	"PacketId",
	&asn_OP_NativeInteger,
	asn_DEF_PacketId_tags_1,
	sizeof(asn_DEF_PacketId_tags_1)
		/sizeof(asn_DEF_PacketId_tags_1[0]), /* 1 */
	asn_DEF_PacketId_tags_1,	/* Same as above */
	sizeof(asn_DEF_PacketId_tags_1)
		/sizeof(asn_DEF_PacketId_tags_1[0]), /* 1 */
	{ 0, &asn_PER_type_PacketId_constr_1, PacketId_constraint },
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [Color] >>> ***/

#include <NativeEnumerated.h>

/*** <<< DEPS [Color] >>> ***/

typedef enum Color {
	Color_red	= 0,
	Color_green	= 1,
	Color_blue	= 2
} e_Color;

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

typedef long	 Color_t;

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

extern asn_per_constraints_t asn_PER_type_Color_constr_1;
extern asn_TYPE_descriptor_t asn_DEF_Color;
extern const asn_INTEGER_specifics_t asn_SPC_Color_specs_1;
asn_struct_free_f Color_free;
asn_struct_print_f Color_print;
asn_constr_check_f Color_constraint;
ber_type_decoder_f Color_decode_ber;
der_type_encoder_f Color_encode_der;
xer_type_decoder_f Color_decode_xer;
xer_type_encoder_f Color_encode_xer;
per_type_decoder_f Color_decode_uper;
per_type_encoder_f Color_encode_uper;

/*** <<< CODE [Color] >>> ***/

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

/*** <<< CTDEFS [Color] >>> ***/

asn_per_constraints_t asn_PER_type_Color_constr_1 CC_NOTUSED = {
	{ APC_CONSTRAINED,	 2,  2,  0,  2 }	/* (0..2) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};

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

static const asn_INTEGER_enum_map_t asn_MAP_Color_value2enum_1[] = {
	{ 0,	3,	"red" },
	{ 1,	5,	"green" },
	{ 2,	4,	"blue" }
};
static const unsigned int asn_MAP_Color_enum2value_1[] = {
	2,	/* blue(2) */
	1,	/* green(1) */
	0	/* red(0) */
};
const asn_INTEGER_specifics_t asn_SPC_Color_specs_1 = {
	asn_MAP_Color_value2enum_1,	/* "tag" => N; sorted by tag */
	asn_MAP_Color_enum2value_1,	/* N => "tag"; sorted by N */
	3,	/* Number of elements in the maps */
	0,	/* Enumeration is not extensible */
	1,	/* Strict enumeration */
	0,	/* Native long size */
	0
};
static const ber_tlv_tag_t asn_DEF_Color_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
};
asn_TYPE_descriptor_t asn_DEF_Color = {
	"Color",
	"Color",
	&asn_OP_NativeEnumerated,
	asn_DEF_Color_tags_1,
	sizeof(asn_DEF_Color_tags_1)
		/sizeof(asn_DEF_Color_tags_1[0]), /* 1 */
	asn_DEF_Color_tags_1,	/* Same as above */
	sizeof(asn_DEF_Color_tags_1)
		/sizeof(asn_DEF_Color_tags_1[0]), /* 1 */
	{ 0, &asn_PER_type_Color_constr_1, NativeEnumerated_constraint },
	0, 0,	/* Defined elsewhere */
	&asn_SPC_Color_specs_1	/* Additional specs */
};


/*** <<< INCLUDES [Valid] >>> ***/

#include <NativeEnumerated.h>

/*** <<< DEPS [Valid] >>> ***/

typedef enum Valid {
	Valid_crc_nok	= 0,
	Valid_crc_ok	= 1
} e_Valid;

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

typedef long	 Valid_t;

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

extern asn_per_constraints_t asn_PER_type_Valid_constr_1;
extern asn_TYPE_descriptor_t asn_DEF_Valid;
extern const asn_INTEGER_specifics_t asn_SPC_Valid_specs_1;
asn_struct_free_f Valid_free;
asn_struct_print_f Valid_print;
asn_constr_check_f Valid_constraint;
ber_type_decoder_f Valid_decode_ber;
der_type_encoder_f Valid_encode_der;
xer_type_decoder_f Valid_decode_xer;
xer_type_encoder_f Valid_encode_xer;
per_type_decoder_f Valid_decode_uper;
per_type_encoder_f Valid_encode_uper;

/*** <<< CODE [Valid] >>> ***/

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

/*** <<< CTDEFS [Valid] >>> ***/

asn_per_constraints_t asn_PER_type_Valid_constr_1 CC_NOTUSED = {
	{ APC_CONSTRAINED,	 1,  1,  0,  1 }	/* (0..1) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};

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

static const asn_INTEGER_enum_map_t asn_MAP_Valid_value2enum_1[] = {
	{ 0,	7,	"crc-nok" },
	{ 1,	6,	"crc-ok" }
};
static const unsigned int asn_MAP_Valid_enum2value_1[] = {
	0,	/* crc-nok(0) */
	1	/* crc-ok(1) */
};
const asn_INTEGER_specifics_t asn_SPC_Valid_specs_1 = {
	asn_MAP_Valid_value2enum_1,	/* "tag" => N; sorted by tag */
	asn_MAP_Valid_enum2value_1,	/* N => "tag"; sorted by N */
	2,	/* Number of elements in the maps */
	0,	/* Enumeration is not extensible */
	1,	/* Strict enumeration */
	0,	/* Native long size */
	0
};
static const ber_tlv_tag_t asn_DEF_Valid_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
};
asn_TYPE_descriptor_t asn_DEF_Valid = {
	"Valid",
	"Valid",
	&asn_OP_NativeEnumerated,
	asn_DEF_Valid_tags_1,
	sizeof(asn_DEF_Valid_tags_1)
		/sizeof(asn_DEF_Valid_tags_1[0]), /* 1 */
	asn_DEF_Valid_tags_1,	/* Same as above */
	sizeof(asn_DEF_Valid_tags_1)
		/sizeof(asn_DEF_Valid_tags_1[0]), /* 1 */
	{ 0, &asn_PER_type_Valid_constr_1, NativeEnumerated_constraint },
	0, 0,	/* Defined elsewhere */
	&asn_SPC_Valid_specs_1	/* Additional specs */
};


/*** <<< INCLUDES [Packet-List] >>> ***/

#include "UpperLayer-List.h"

/*** <<< TYPE-DECLS [Packet-List] >>> ***/

typedef UpperLayer_List_41P0_t	 Packet_List_t;

/*** <<< FUNC-DECLS [Packet-List] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_Packet_List;
asn_struct_free_f Packet_List_free;
asn_struct_print_f Packet_List_print;
asn_constr_check_f Packet_List_constraint;
ber_type_decoder_f Packet_List_decode_ber;
der_type_encoder_f Packet_List_encode_der;
xer_type_decoder_f Packet_List_decode_xer;
xer_type_encoder_f Packet_List_encode_xer;
per_type_decoder_f Packet_List_decode_uper;
per_type_encoder_f Packet_List_encode_uper;

/*** <<< CODE [Packet-List] >>> ***/

int
Packet_List_constraint(const 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 >= 1 && size <= 256)) {
		/* Perform validation of the inner elements */
		return td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

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

/*** <<< CTDEFS [Packet-List] >>> ***/

static asn_per_constraints_t asn_PER_type_Packet_List_constr_1 CC_NOTUSED = {
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	{ APC_CONSTRAINED,	 8,  8,  1,  256 }	/* (SIZE(1..256)) */,
	0, 0	/* No PER value map */
};

/*** <<< STAT-DEFS [Packet-List] >>> ***/

static const ber_tlv_tag_t asn_DEF_Packet_List_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
asn_TYPE_descriptor_t asn_DEF_Packet_List = {
	"Packet-List",
	"Packet-List",
	&asn_OP_SEQUENCE_OF,
	asn_DEF_Packet_List_tags_1,
	sizeof(asn_DEF_Packet_List_tags_1)
		/sizeof(asn_DEF_Packet_List_tags_1[0]), /* 1 */
	asn_DEF_Packet_List_tags_1,	/* Same as above */
	sizeof(asn_DEF_Packet_List_tags_1)
		/sizeof(asn_DEF_Packet_List_tags_1[0]), /* 1 */
	{ 0, &asn_PER_type_Packet_List_constr_1, Packet_List_constraint },
	asn_MBR_LowerLayer_List_45P0_1,
	1,	/* Single element */
	&asn_SPC_LowerLayer_List_45P0_specs_1	/* Additional specs */
};


/*** <<< INCLUDES [UpperLayer-List] >>> ***/

#include "LowerLayer-List.h"

/*** <<< TYPE-DECLS [UpperLayer-List] >>> ***/

typedef LowerLayer_List_45P0_t	 UpperLayer_List_41P0_t;

/*** <<< FUNC-DECLS [UpperLayer-List] >>> ***/

extern asn_per_constraints_t asn_PER_type_UpperLayer_List_41P0_constr_1;
extern asn_TYPE_descriptor_t asn_DEF_UpperLayer_List_41P0;
asn_struct_free_f UpperLayer_List_41P0_free;
asn_struct_print_f UpperLayer_List_41P0_print;
asn_constr_check_f UpperLayer_List_41P0_constraint;
ber_type_decoder_f UpperLayer_List_41P0_decode_ber;
der_type_encoder_f UpperLayer_List_41P0_encode_der;
xer_type_decoder_f UpperLayer_List_41P0_decode_xer;
xer_type_encoder_f UpperLayer_List_41P0_encode_xer;
per_type_decoder_f UpperLayer_List_41P0_decode_uper;
per_type_encoder_f UpperLayer_List_41P0_encode_uper;

/*** <<< CODE [UpperLayer-List] >>> ***/

int
UpperLayer_List_41P0_constraint(const 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 >= 1 && size <= 256)) {
		/* Perform validation of the inner elements */
		return td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

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

/*** <<< CTDEFS [UpperLayer-List] >>> ***/

asn_per_constraints_t asn_PER_type_UpperLayer_List_41P0_constr_1 CC_NOTUSED = {
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	{ APC_CONSTRAINED,	 8,  8,  1,  256 }	/* (SIZE(1..256)) */,
	0, 0	/* No PER value map */
};

/*** <<< STAT-DEFS [UpperLayer-List] >>> ***/

static const ber_tlv_tag_t asn_DEF_UpperLayer_List_41P0_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
asn_TYPE_descriptor_t asn_DEF_UpperLayer_List_41P0 = {
	"UpperLayer-List",
	"UpperLayer-List",
	&asn_OP_SEQUENCE_OF,
	asn_DEF_UpperLayer_List_41P0_tags_1,
	sizeof(asn_DEF_UpperLayer_List_41P0_tags_1)
		/sizeof(asn_DEF_UpperLayer_List_41P0_tags_1[0]), /* 1 */
	asn_DEF_UpperLayer_List_41P0_tags_1,	/* Same as above */
	sizeof(asn_DEF_UpperLayer_List_41P0_tags_1)
		/sizeof(asn_DEF_UpperLayer_List_41P0_tags_1[0]), /* 1 */
	{ 0, &asn_PER_type_UpperLayer_List_41P0_constr_1, UpperLayer_List_41P0_constraint },
	asn_MBR_LowerLayer_List_45P0_1,
	1,	/* Single element */
	&asn_SPC_LowerLayer_List_45P0_specs_1	/* Additional specs */
};


/*** <<< INCLUDES [LowerLayer-List] >>> ***/

#include <asn_SEQUENCE_OF.h>
#include <constr_SEQUENCE_OF.h>

/*** <<< FWD-DECLS [LowerLayer-List] >>> ***/

struct SinglePacket;

/*** <<< TYPE-DECLS [LowerLayer-List] >>> ***/

typedef struct LowerLayer_List_45P0 {
	A_SEQUENCE_OF(struct SinglePacket) list;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} LowerLayer_List_45P0_t;

/*** <<< FUNC-DECLS [LowerLayer-List] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_LowerLayer_List_45P0;
extern asn_SET_OF_specifics_t asn_SPC_LowerLayer_List_45P0_specs_1;
extern asn_TYPE_member_t asn_MBR_LowerLayer_List_45P0_1[1];
extern asn_per_constraints_t asn_PER_type_LowerLayer_List_45P0_constr_1;

/*** <<< POST-INCLUDE [LowerLayer-List] >>> ***/

#include "SinglePacket.h"

/*** <<< CTDEFS [LowerLayer-List] >>> ***/

asn_per_constraints_t asn_PER_type_LowerLayer_List_45P0_constr_1 CC_NOTUSED = {
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	{ APC_CONSTRAINED,	 8,  8,  1,  256 }	/* (SIZE(1..256)) */,
	0, 0	/* No PER value map */
};

/*** <<< STAT-DEFS [LowerLayer-List] >>> ***/

asn_TYPE_member_t asn_MBR_LowerLayer_List_45P0_1[] = {
	{ ATF_POINTER, 0, 0,
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_SinglePacket_48P0,
		.type_selector = 0,
		{ .oer_constraints = 0, .per_constraints = 0, .general_constraints = 0 },
		0, 0, /* No default value */
		.name = ""
		},
};
static const ber_tlv_tag_t asn_DEF_LowerLayer_List_45P0_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
asn_SET_OF_specifics_t asn_SPC_LowerLayer_List_45P0_specs_1 = {
	sizeof(struct LowerLayer_List_45P0),
	offsetof(struct LowerLayer_List_45P0, _asn_ctx),
	0,	/* XER encoding is XMLDelimitedItemList */
};
asn_TYPE_descriptor_t asn_DEF_LowerLayer_List_45P0 = {
	"LowerLayer-List",
	"LowerLayer-List",
	&asn_OP_SEQUENCE_OF,
	asn_DEF_LowerLayer_List_45P0_tags_1,
	sizeof(asn_DEF_LowerLayer_List_45P0_tags_1)
		/sizeof(asn_DEF_LowerLayer_List_45P0_tags_1[0]), /* 1 */
	asn_DEF_LowerLayer_List_45P0_tags_1,	/* Same as above */
	sizeof(asn_DEF_LowerLayer_List_45P0_tags_1)
		/sizeof(asn_DEF_LowerLayer_List_45P0_tags_1[0]), /* 1 */
	{ 0, &asn_PER_type_LowerLayer_List_45P0_constr_1, SEQUENCE_OF_constraint },
	asn_MBR_LowerLayer_List_45P0_1,
	1,	/* Single element */
	&asn_SPC_LowerLayer_List_45P0_specs_1	/* Additional specs */
};


/*** <<< INCLUDES [SinglePacket] >>> ***/

#include "Packet.h"

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

typedef Packet_51P0_t	 SinglePacket_48P0_t;

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

extern asn_TYPE_descriptor_t asn_DEF_SinglePacket_48P0;
asn_struct_free_f SinglePacket_48P0_free;
asn_struct_print_f SinglePacket_48P0_print;
asn_constr_check_f SinglePacket_48P0_constraint;
ber_type_decoder_f SinglePacket_48P0_decode_ber;
der_type_encoder_f SinglePacket_48P0_encode_der;
xer_type_decoder_f SinglePacket_48P0_decode_xer;
xer_type_encoder_f SinglePacket_48P0_encode_xer;
per_type_decoder_f SinglePacket_48P0_decode_uper;
per_type_encoder_f SinglePacket_48P0_encode_uper;

/*** <<< CODE [SinglePacket] >>> ***/

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

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

static const ber_tlv_tag_t asn_DEF_SinglePacket_48P0_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
asn_TYPE_descriptor_t asn_DEF_SinglePacket_48P0 = {
	"SinglePacket",
	"SinglePacket",
	&asn_OP_SEQUENCE,
	asn_DEF_SinglePacket_48P0_tags_1,
	sizeof(asn_DEF_SinglePacket_48P0_tags_1)
		/sizeof(asn_DEF_SinglePacket_48P0_tags_1[0]), /* 1 */
	asn_DEF_SinglePacket_48P0_tags_1,	/* Same as above */
	sizeof(asn_DEF_SinglePacket_48P0_tags_1)
		/sizeof(asn_DEF_SinglePacket_48P0_tags_1[0]), /* 1 */
	{ 0, 0, SEQUENCE_constraint },
	asn_MBR_Packet_51P0_1,
	3,	/* Elements count */
	&asn_SPC_Packet_51P0_specs_1	/* Additional specs */
};


/*** <<< INCLUDES [Packet] >>> ***/

#include "PacketId.h"
#include "Color.h"
#include <ANY.h>
#include <asn_ioc.h>
#include <OPEN_TYPE.h>
#include <constr_CHOICE.h>
#include <constr_SEQUENCE.h>

/*** <<< DEPS [Packet] >>> ***/

typedef enum value_PR {
	value_PR_NOTHING,	/* No components present */
	
} value_PR;

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

typedef struct Packet_51P0 {
	PacketId_t	 id;
	Color_t	 color;
	struct value {
		value_PR present;
		union Packet_51P0__value_u {
		} choice;
		
		/* Context for parsing across buffer boundaries */
		asn_struct_ctx_t _asn_ctx;
	} value;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} Packet_51P0_t;

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

extern asn_TYPE_descriptor_t asn_DEF_Packet_51P0;
extern asn_SEQUENCE_specifics_t asn_SPC_Packet_51P0_specs_1;
extern asn_TYPE_member_t asn_MBR_Packet_51P0_1[3];

/*** <<< IOC-TABLES [Packet] >>> ***/

static const asn_ioc_cell_t asn_IOS_ClassItem_1_rows[] = {
	
};
static const asn_ioc_set_t asn_IOS_ClassItem_1[] = {
	0, 0, asn_IOS_ClassItem_1_rows
};

/*** <<< CODE [Packet] >>> ***/

static int
memb_id_constraint_1(const 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 <= 65535)) {
		/* 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_color_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr,
			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	
	if(!sptr) {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: value not given (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
	
	
	if(1 /* No applicable constraints whatsoever */) {
		/* Nothing is here. See below */
	}
	
	return td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);
}

static int
memb_value_constraint_1(const asn_TYPE_descriptor_t *td, const void *sptr,
			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	
	if(!sptr) {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: value not given (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
	
	
	if(1 /* No applicable constraints whatsoever */) {
		/* Nothing is here. See below */
	}
	
	return td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);
}


/*** <<< CTDEFS [Packet] >>> ***/

static asn_per_constraints_t asn_PER_memb_id_constr_2 CC_NOTUSED = {
	{ APC_CONSTRAINED,	 16,  16,  0,  65535 }	/* (0..65535) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};
static asn_per_constraints_t asn_PER_memb_color_constr_3 CC_NOTUSED = {
	{ APC_CONSTRAINED,	 2,  2,  0,  2 }	/* (0..2) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};
static asn_per_constraints_t asn_PER_memb_value_constr_4 CC_NOTUSED = {
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};

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

static asn_CHOICE_specifics_t asn_SPC_value_specs_4 = {
	sizeof(struct value),
	offsetof(struct value, _asn_ctx),
	offsetof(struct value, present),
	sizeof(((struct value *)0)->present),
	0,	/* No top level tags */
	0,	/* No tags in the map */
	0, 0,
	.first_extension = -1	/* Extensions start */
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_value_4 = {
	"value",
	"value",
	&asn_OP_OPEN_TYPE,
	0,	/* No effective tags (pointer) */
	0,	/* No effective tags (count) */
	0,	/* No tags (pointer) */
	0,	/* No tags (count) */
	{ 0, 0, OPEN_TYPE_constraint },
	0, 0,	/* No members */
	&asn_SPC_value_specs_4	/* Additional specs */
};

asn_TYPE_member_t asn_MBR_Packet_51P0_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct Packet_51P0, id),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_PacketId,
		.type_selector = 0,
		{ .oer_constraints = 0, .per_constraints = &asn_PER_memb_id_constr_2, .general_constraints =  memb_id_constraint_1 },
		0, 0, /* No default value */
		.name = "id"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct Packet_51P0, color),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_Color,
		.type_selector = 0,
		{ .oer_constraints = 0, .per_constraints = &asn_PER_memb_color_constr_3, .general_constraints =  memb_color_constraint_1 },
		0, 0, /* No default value */
		.name = "color"
		},
	{ ATF_OPEN_TYPE | ATF_NOFLAGS, 0, offsetof(struct Packet_51P0, value),
		.tag = -1 /* Ambiguous tag (ANY?) */,
		.tag_mode = 0,
		.type = &asn_DEF_value_4,
		.type_selector = 0,
		{ .oer_constraints = 0, .per_constraints = &asn_PER_memb_value_constr_4, .general_constraints =  memb_value_constraint_1 },
		0, 0, /* No default value */
		.name = "value"
		},
};
static const ber_tlv_tag_t asn_DEF_Packet_51P0_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_Packet_51P0_tag2el_1[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* id */
    { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 1, 0, 0 } /* color */
};
asn_SEQUENCE_specifics_t asn_SPC_Packet_51P0_specs_1 = {
	sizeof(struct Packet_51P0),
	offsetof(struct Packet_51P0, _asn_ctx),
	.tag2el = asn_MAP_Packet_51P0_tag2el_1,
	.tag2el_count = 2,	/* Count of tags in the map */
	0, 0, 0,	/* Optional elements (not needed) */
	-1,	/* First extension addition */
};
asn_TYPE_descriptor_t asn_DEF_Packet_51P0 = {
	"Packet",
	"Packet",
	&asn_OP_SEQUENCE,
	asn_DEF_Packet_51P0_tags_1,
	sizeof(asn_DEF_Packet_51P0_tags_1)
		/sizeof(asn_DEF_Packet_51P0_tags_1[0]), /* 1 */
	asn_DEF_Packet_51P0_tags_1,	/* Same as above */
	sizeof(asn_DEF_Packet_51P0_tags_1)
		/sizeof(asn_DEF_Packet_51P0_tags_1[0]), /* 1 */
	{ 0, 0, SEQUENCE_constraint },
	asn_MBR_Packet_51P0_1,
	3,	/* Elements count */
	&asn_SPC_Packet_51P0_specs_1	/* Additional specs */
};

