
/*** <<< INCLUDES [Attribute] >>> ***/

#include <RELATIVE-OID.h>
#include <IA5String.h>
#include <asn_ioc.h>
#include <constr_SEQUENCE.h>

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

typedef struct Attribute {
	RELATIVE_OID_t	 identifier;
	IA5String_t	 siAttributeValue;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} Attribute_t;

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

extern asn_TYPE_descriptor_t asn_DEF_Attribute;

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

static const RELATIVE_OID_t asn_VAL_1_raf = { "not supported", 0 };
static const RELATIVE_OID_t asn_VAL_2_rcf = { "not supported", 0 };
static const asn_ioc_cell_t asn_IOS_Attributes_1_rows[] = {
	{ "&id", aioc__value, &asn_DEF_RELATIVE_OID, &asn_VAL_1_raf },
	{ "&id", aioc__value, &asn_DEF_RELATIVE_OID, &asn_VAL_2_rcf }
};
static const asn_ioc_set_t asn_IOS_Attributes_1[] = {
	2, 1, asn_IOS_Attributes_1_rows
};

/*** <<< CODE [Attribute] >>> ***/

static int
memb_identifier_constraint_1(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);
}


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

static asn_TYPE_member_t asn_MBR_Attribute_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct Attribute, identifier),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (13 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_RELATIVE_OID,
		.type_selector = 0,
		{ .oer_constraints = 0, .per_constraints = 0, .general_constraints =  memb_identifier_constraint_1 },
		.default_value = 0,
		.name = "identifier"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct Attribute, siAttributeValue),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_IA5String,
		.type_selector = 0,
		{ .oer_constraints = 0, .per_constraints = 0, .general_constraints = 0 },
		.default_value = 0,
		.name = "siAttributeValue"
		},
};
static const ber_tlv_tag_t asn_DEF_Attribute_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_Attribute_tag2el_1[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (13 << 2)), 0, 0, 0 }, /* identifier */
    { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)), 1, 0, 0 } /* siAttributeValue */
};
static asn_SEQUENCE_specifics_t asn_SPC_Attribute_specs_1 = {
	sizeof(struct Attribute),
	offsetof(struct Attribute, _asn_ctx),
	.tag2el = asn_MAP_Attribute_tag2el_1,
	.tag2el_count = 2,	/* Count of tags in the map */
	0, 0, 0,	/* Optional elements (not needed) */
	-1,	/* Start extensions */
	-1	/* Stop extensions */
};
asn_TYPE_descriptor_t asn_DEF_Attribute = {
	"Attribute",
	"Attribute",
	&asn_OP_SEQUENCE,
	asn_DEF_Attribute_tags_1,
	sizeof(asn_DEF_Attribute_tags_1)
		/sizeof(asn_DEF_Attribute_tags_1[0]), /* 1 */
	asn_DEF_Attribute_tags_1,	/* Same as above */
	sizeof(asn_DEF_Attribute_tags_1)
		/sizeof(asn_DEF_Attribute_tags_1[0]), /* 1 */
	{ 0, 0, SEQUENCE_constraint },
	asn_MBR_Attribute_1,
	2,	/* Elements count */
	&asn_SPC_Attribute_specs_1	/* Additional specs */
};

