/*
 * Generated by asn1c-0.9.29 (http://lionet.info/asn1c)
 * From ASN.1 module "E2SM-KPM-RC"
 * 	found in "e2sm-kpm-rc.asn"
 * 	`asn1c -fcompound-names -fno-include-deps -findirect-choice -pdu=auto -gen-PER -gen-OER -no-gen-example -D .`
 */

#include "RIC-ControlStyle-Item.h"

#include "RIC-ControlAction-Item.h"
static int
memb_ric_ControlAction_List_constraint_1(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 <= 65535)) {
		/* 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;
	}
}

static asn_oer_constraints_t asn_OER_type_ric_ControlAction_List_constr_4 CC_NOTUSED = {
	{ 0, 0 },
	-1	/* (SIZE(1..65535)) */};
static asn_per_constraints_t asn_PER_type_ric_ControlAction_List_constr_4 CC_NOTUSED = {
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	{ APC_CONSTRAINED,	 16,  16,  1,  65535 }	/* (SIZE(1..65535)) */,
	0, 0	/* No PER value map */
};
static asn_oer_constraints_t asn_OER_memb_ric_ControlAction_List_constr_4 CC_NOTUSED = {
	{ 0, 0 },
	-1	/* (SIZE(1..65535)) */};
static asn_per_constraints_t asn_PER_memb_ric_ControlAction_List_constr_4 CC_NOTUSED = {
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	{ APC_CONSTRAINED,	 16,  16,  1,  65535 }	/* (SIZE(1..65535)) */,
	0, 0	/* No PER value map */
};
static asn_TYPE_member_t asn_MBR_ric_ControlAction_List_4[] = {
	{ ATF_POINTER, 0, 0,
		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
		0,
		&asn_DEF_RIC_ControlAction_Item,
		0,
		{ 0, 0, 0 },
		0, 0, /* No default value */
		""
		},
};
static const ber_tlv_tag_t asn_DEF_ric_ControlAction_List_tags_4[] = {
	(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static asn_SET_OF_specifics_t asn_SPC_ric_ControlAction_List_specs_4 = {
	sizeof(struct RIC_ControlStyle_Item__ric_ControlAction_List),
	offsetof(struct RIC_ControlStyle_Item__ric_ControlAction_List, _asn_ctx),
	0,	/* XER encoding is XMLDelimitedItemList */
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_ric_ControlAction_List_4 = {
	"ric-ControlAction-List",
	"ric-ControlAction-List",
	&asn_OP_SEQUENCE_OF,
	asn_DEF_ric_ControlAction_List_tags_4,
	sizeof(asn_DEF_ric_ControlAction_List_tags_4)
		/sizeof(asn_DEF_ric_ControlAction_List_tags_4[0]) - 1, /* 1 */
	asn_DEF_ric_ControlAction_List_tags_4,	/* Same as above */
	sizeof(asn_DEF_ric_ControlAction_List_tags_4)
		/sizeof(asn_DEF_ric_ControlAction_List_tags_4[0]), /* 2 */
	{ &asn_OER_type_ric_ControlAction_List_constr_4, &asn_PER_type_ric_ControlAction_List_constr_4, SEQUENCE_OF_constraint },
	asn_MBR_ric_ControlAction_List_4,
	1,	/* Single element */
	&asn_SPC_ric_ControlAction_List_specs_4	/* Additional specs */
};

asn_TYPE_member_t asn_MBR_RIC_ControlStyle_Item_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct RIC_ControlStyle_Item, ric_ControlStyle_Type),
		(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
		-1,	/* IMPLICIT tag at current level */
		&asn_DEF_RIC_Style_Type,
		0,
		{ 0, 0, 0 },
		0, 0, /* No default value */
		"ric-ControlStyle-Type"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct RIC_ControlStyle_Item, ric_ControlStyle_Name),
		(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
		-1,	/* IMPLICIT tag at current level */
		&asn_DEF_RIC_Style_Name,
		0,
		{ 0, 0, 0 },
		0, 0, /* No default value */
		"ric-ControlStyle-Name"
		},
	{ ATF_POINTER, 1, offsetof(struct RIC_ControlStyle_Item, ric_ControlAction_List),
		(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
		0,
		&asn_DEF_ric_ControlAction_List_4,
		0,
		{ &asn_OER_memb_ric_ControlAction_List_constr_4, &asn_PER_memb_ric_ControlAction_List_constr_4,  memb_ric_ControlAction_List_constraint_1 },
		0, 0, /* No default value */
		"ric-ControlAction-List"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct RIC_ControlStyle_Item, ric_ControlHeaderFormat_Type),
		(ASN_TAG_CLASS_CONTEXT | (3 << 2)),
		-1,	/* IMPLICIT tag at current level */
		&asn_DEF_RIC_Format_Type,
		0,
		{ 0, 0, 0 },
		0, 0, /* No default value */
		"ric-ControlHeaderFormat-Type"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct RIC_ControlStyle_Item, ric_ControlMessageFormat_Type),
		(ASN_TAG_CLASS_CONTEXT | (4 << 2)),
		-1,	/* IMPLICIT tag at current level */
		&asn_DEF_RIC_Format_Type,
		0,
		{ 0, 0, 0 },
		0, 0, /* No default value */
		"ric-ControlMessageFormat-Type"
		},
};
static const int asn_MAP_RIC_ControlStyle_Item_oms_1[] = { 2 };
static const ber_tlv_tag_t asn_DEF_RIC_ControlStyle_Item_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_RIC_ControlStyle_Item_tag2el_1[] = {
    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* ric-ControlStyle-Type */
    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* ric-ControlStyle-Name */
    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* ric-ControlAction-List */
    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* ric-ControlHeaderFormat-Type */
    { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 } /* ric-ControlMessageFormat-Type */
};
asn_SEQUENCE_specifics_t asn_SPC_RIC_ControlStyle_Item_specs_1 = {
	sizeof(struct RIC_ControlStyle_Item),
	offsetof(struct RIC_ControlStyle_Item, _asn_ctx),
	asn_MAP_RIC_ControlStyle_Item_tag2el_1,
	5,	/* Count of tags in the map */
	asn_MAP_RIC_ControlStyle_Item_oms_1,	/* Optional members */
	1, 0,	/* Root/Additions */
	5,	/* First extension addition */
};
asn_TYPE_descriptor_t asn_DEF_RIC_ControlStyle_Item = {
	"RIC-ControlStyle-Item",
	"RIC-ControlStyle-Item",
	&asn_OP_SEQUENCE,
	asn_DEF_RIC_ControlStyle_Item_tags_1,
	sizeof(asn_DEF_RIC_ControlStyle_Item_tags_1)
		/sizeof(asn_DEF_RIC_ControlStyle_Item_tags_1[0]), /* 1 */
	asn_DEF_RIC_ControlStyle_Item_tags_1,	/* Same as above */
	sizeof(asn_DEF_RIC_ControlStyle_Item_tags_1)
		/sizeof(asn_DEF_RIC_ControlStyle_Item_tags_1[0]), /* 1 */
	{ 0, 0, SEQUENCE_constraint },
	asn_MBR_RIC_ControlStyle_Item_1,
	5,	/* Elements count */
	&asn_SPC_RIC_ControlStyle_Item_specs_1	/* Additional specs */
};

