// This C++ source file was generated by the TTCN-3 compiler
// of the TTCN-3 Test Executor version CRL 113 200/6 R6A
// for Lénárd Nagy (elnrnag@elx78355y6x) on Thu Oct 24 10:29:40 2019

// Copyright (c) 2000-2019 Ericsson Telecom AB

// Do not edit this file unless you know what you are doing.

/* Including header files */

#include "IsobusCMMessageTypes.hh"

namespace IsobusCMMessageTypes {

/* Prototypes of static functions */

static void pre_init_module();
static void post_init_module();

/* Literal string constants */

static const unsigned char os_0_octets[] = { 16 },
os_1_octets[] = { 17 },
os_2_octets[] = { 19 },
os_3_octets[] = { 32 },
os_5_octets[] = { 33 },
os_6_octets[] = { 34 },
os_7_octets[] = { 35 },
os_4_octets[] = { 255 };
static const OCTETSTRING os_0(1, os_0_octets),
os_1(1, os_1_octets),
os_2(1, os_2_octets),
os_3(1, os_3_octets),
os_5(1, os_5_octets),
os_6(1, os_6_octets),
os_7(1, os_7_octets),
os_4(1, os_4_octets);
static const unsigned char module_checksum[] = { 0xf5, 0x67, 0x02, 0xbc, 0x33, 0x07, 0xbc, 0xd1, 0x80, 0xb3, 0xef, 0x1b, 0x59, 0x25, 0x7c, 0x3f };

/* Global variable definitions */

const TTCN_RAWdescriptor_t SEQ__NO_raw_ = {8,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       SEQ__NO_xer_ = { {"SEQ_NO>\n", "SEQ_NO>\n"}, {8, 8}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t SEQ__NO_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t SEQ__NO_descr_ = { "@IsobusCMMessageTypes.SEQ_NO", &INTEGER_ber_, &SEQ__NO_raw_, &INTEGER_text_, &SEQ__NO_xer_, &INTEGER_json_, &SEQ__NO_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t NUMBER__OF__PACKETS_raw_ = {8,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       NUMBER__OF__PACKETS_xer_ = { {"NUMBER_OF_PACKETS>\n", "NUMBER_OF_PACKETS>\n"}, {19, 19}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t NUMBER__OF__PACKETS_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t NUMBER__OF__PACKETS_descr_ = { "@IsobusCMMessageTypes.NUMBER_OF_PACKETS", &INTEGER_ber_, &NUMBER__OF__PACKETS_raw_, &INTEGER_text_, &NUMBER__OF__PACKETS_xer_, &INTEGER_json_, &NUMBER__OF__PACKETS_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       Ctrl_xer_ = { {"Ctrl>\n", "Ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int Ctrl_oer_ext_arr_[0] = {};
const int Ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t Ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, Ctrl_oer_ext_arr_, 0, Ctrl_oer_p_};
const TTCN_Typedescriptor_t Ctrl_descr_ = { "@IsobusCMMessageTypes.Ctrl", &OCTETSTRING_ber_, &General__Types::OCT1_raw_, &OCTETSTRING_text_, &Ctrl_xer_, &OCTETSTRING_json_, &Ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t RequestToSend_ctrl_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       RequestToSend_ctrl_xer_ = { {"ctrl>\n", "ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int RequestToSend_ctrl_oer_ext_arr_[0] = {};
const int RequestToSend_ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t RequestToSend_ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, RequestToSend_ctrl_oer_ext_arr_, 0, RequestToSend_ctrl_oer_p_};
const TTCN_Typedescriptor_t RequestToSend_ctrl_descr_ = { "@IsobusCMMessageTypes.RequestToSend.ctrl", &OCTETSTRING_ber_, &RequestToSend_ctrl_raw_, &OCTETSTRING_text_, &RequestToSend_ctrl_xer_, &OCTETSTRING_json_, &RequestToSend_ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       RequestToSend_msgSizeInBytes_xer_ = { {"msgSizeInBytes>\n", "msgSizeInBytes>\n"}, {16, 16}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t RequestToSend_msgSizeInBytes_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t RequestToSend_msgSizeInBytes_descr_ = { "@IsobusCMMessageTypes.RequestToSend.msgSizeInBytes", &INTEGER_ber_, &IsobusMessageTypes::INT2_raw_, &INTEGER_text_, &RequestToSend_msgSizeInBytes_xer_, &INTEGER_json_, &RequestToSend_msgSizeInBytes_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       RequestToSend_totalNumberOfPackets_xer_ = { {"totalNumberOfPackets>\n", "totalNumberOfPackets>\n"}, {22, 22}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t RequestToSend_totalNumberOfPackets_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t RequestToSend_totalNumberOfPackets_descr_ = { "@IsobusCMMessageTypes.RequestToSend.totalNumberOfPackets", &INTEGER_ber_, &NUMBER__OF__PACKETS_raw_, &INTEGER_text_, &RequestToSend_totalNumberOfPackets_xer_, &INTEGER_json_, &RequestToSend_totalNumberOfPackets_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       RequestToSend_maxNoOfPacketsInResponseToCTS_xer_ = { {"maxNoOfPacketsInResponseToCTS>\n", "maxNoOfPacketsInResponseToCTS>\n"}, {31, 31}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t RequestToSend_maxNoOfPacketsInResponseToCTS_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t RequestToSend_maxNoOfPacketsInResponseToCTS_descr_ = { "@IsobusCMMessageTypes.RequestToSend.maxNoOfPacketsInResponseToCTS", &INTEGER_ber_, &General__Types::INT1_raw_, &INTEGER_text_, &RequestToSend_maxNoOfPacketsInResponseToCTS_xer_, &INTEGER_json_, &RequestToSend_maxNoOfPacketsInResponseToCTS_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       RequestToSend_pgnOfMultiPacketMessage_xer_ = { {"pgnOfMultiPacketMessage>\n", "pgnOfMultiPacketMessage>\n"}, {25, 25}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t RequestToSend_pgnOfMultiPacketMessage_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t RequestToSend_pgnOfMultiPacketMessage_descr_ = { "@IsobusCMMessageTypes.RequestToSend.pgnOfMultiPacketMessage", &INTEGER_ber_, &IsobusMessageTypes::INT24nb_raw_, &INTEGER_text_, &RequestToSend_pgnOfMultiPacketMessage_xer_, &INTEGER_json_, &RequestToSend_pgnOfMultiPacketMessage_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t RequestToSend_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for RequestToSend
const TTCN_Typedescriptor_t RequestToSend_descr_ = { "@IsobusCMMessageTypes.RequestToSend", NULL, &RequestToSend_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ClearToSend_ctrl_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ClearToSend_ctrl_xer_ = { {"ctrl>\n", "ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ClearToSend_ctrl_oer_ext_arr_[0] = {};
const int ClearToSend_ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t ClearToSend_ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ClearToSend_ctrl_oer_ext_arr_, 0, ClearToSend_ctrl_oer_p_};
const TTCN_Typedescriptor_t ClearToSend_ctrl_descr_ = { "@IsobusCMMessageTypes.ClearToSend.ctrl", &OCTETSTRING_ber_, &ClearToSend_ctrl_raw_, &OCTETSTRING_text_, &ClearToSend_ctrl_xer_, &OCTETSTRING_json_, &ClearToSend_ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ClearToSend_totalNumberOfPackets_xer_ = { {"totalNumberOfPackets>\n", "totalNumberOfPackets>\n"}, {22, 22}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ClearToSend_totalNumberOfPackets_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ClearToSend_totalNumberOfPackets_descr_ = { "@IsobusCMMessageTypes.ClearToSend.totalNumberOfPackets", &INTEGER_ber_, &NUMBER__OF__PACKETS_raw_, &INTEGER_text_, &ClearToSend_totalNumberOfPackets_xer_, &INTEGER_json_, &ClearToSend_totalNumberOfPackets_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ClearToSend_nextPacketNumber_xer_ = { {"nextPacketNumber>\n", "nextPacketNumber>\n"}, {18, 18}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ClearToSend_nextPacketNumber_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ClearToSend_nextPacketNumber_descr_ = { "@IsobusCMMessageTypes.ClearToSend.nextPacketNumber", &INTEGER_ber_, &General__Types::INT1_raw_, &INTEGER_text_, &ClearToSend_nextPacketNumber_xer_, &INTEGER_json_, &ClearToSend_nextPacketNumber_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ClearToSend_reserved4_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ClearToSend_reserved4_xer_ = { {"reserved4>\n", "reserved4>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ClearToSend_reserved4_oer_ext_arr_[0] = {};
const int ClearToSend_reserved4_oer_p_[0] = {};
const TTCN_OERdescriptor_t ClearToSend_reserved4_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ClearToSend_reserved4_oer_ext_arr_, 0, ClearToSend_reserved4_oer_p_};
const TTCN_Typedescriptor_t ClearToSend_reserved4_descr_ = { "@IsobusCMMessageTypes.ClearToSend.reserved4", &OCTETSTRING_ber_, &ClearToSend_reserved4_raw_, &OCTETSTRING_text_, &ClearToSend_reserved4_xer_, &OCTETSTRING_json_, &ClearToSend_reserved4_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ClearToSend_reserved5_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ClearToSend_reserved5_xer_ = { {"reserved5>\n", "reserved5>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ClearToSend_reserved5_oer_ext_arr_[0] = {};
const int ClearToSend_reserved5_oer_p_[0] = {};
const TTCN_OERdescriptor_t ClearToSend_reserved5_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ClearToSend_reserved5_oer_ext_arr_, 0, ClearToSend_reserved5_oer_p_};
const TTCN_Typedescriptor_t ClearToSend_reserved5_descr_ = { "@IsobusCMMessageTypes.ClearToSend.reserved5", &OCTETSTRING_ber_, &ClearToSend_reserved5_raw_, &OCTETSTRING_text_, &ClearToSend_reserved5_xer_, &OCTETSTRING_json_, &ClearToSend_reserved5_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ClearToSend_pgnOfMultiPacketMessage_xer_ = { {"pgnOfMultiPacketMessage>\n", "pgnOfMultiPacketMessage>\n"}, {25, 25}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ClearToSend_pgnOfMultiPacketMessage_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ClearToSend_pgnOfMultiPacketMessage_descr_ = { "@IsobusCMMessageTypes.ClearToSend.pgnOfMultiPacketMessage", &INTEGER_ber_, &IsobusMessageTypes::INT24nb_raw_, &INTEGER_text_, &ClearToSend_pgnOfMultiPacketMessage_xer_, &INTEGER_json_, &ClearToSend_pgnOfMultiPacketMessage_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ClearToSend_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for ClearToSend
const TTCN_Typedescriptor_t ClearToSend_descr_ = { "@IsobusCMMessageTypes.ClearToSend", NULL, &ClearToSend_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t EndOfMessageAcknowledgement_ctrl_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       EndOfMessageAcknowledgement_ctrl_xer_ = { {"ctrl>\n", "ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int EndOfMessageAcknowledgement_ctrl_oer_ext_arr_[0] = {};
const int EndOfMessageAcknowledgement_ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t EndOfMessageAcknowledgement_ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, EndOfMessageAcknowledgement_ctrl_oer_ext_arr_, 0, EndOfMessageAcknowledgement_ctrl_oer_p_};
const TTCN_Typedescriptor_t EndOfMessageAcknowledgement_ctrl_descr_ = { "@IsobusCMMessageTypes.EndOfMessageAcknowledgement.ctrl", &OCTETSTRING_ber_, &EndOfMessageAcknowledgement_ctrl_raw_, &OCTETSTRING_text_, &EndOfMessageAcknowledgement_ctrl_xer_, &OCTETSTRING_json_, &EndOfMessageAcknowledgement_ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       EndOfMessageAcknowledgement_msgSizeInByte_xer_ = { {"msgSizeInByte>\n", "msgSizeInByte>\n"}, {15, 15}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t EndOfMessageAcknowledgement_msgSizeInByte_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t EndOfMessageAcknowledgement_msgSizeInByte_descr_ = { "@IsobusCMMessageTypes.EndOfMessageAcknowledgement.msgSizeInByte", &INTEGER_ber_, &IsobusMessageTypes::INT2_raw_, &INTEGER_text_, &EndOfMessageAcknowledgement_msgSizeInByte_xer_, &INTEGER_json_, &EndOfMessageAcknowledgement_msgSizeInByte_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       EndOfMessageAcknowledgement_totalNumberOfPackets_xer_ = { {"totalNumberOfPackets>\n", "totalNumberOfPackets>\n"}, {22, 22}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t EndOfMessageAcknowledgement_totalNumberOfPackets_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t EndOfMessageAcknowledgement_totalNumberOfPackets_descr_ = { "@IsobusCMMessageTypes.EndOfMessageAcknowledgement.totalNumberOfPackets", &INTEGER_ber_, &NUMBER__OF__PACKETS_raw_, &INTEGER_text_, &EndOfMessageAcknowledgement_totalNumberOfPackets_xer_, &INTEGER_json_, &EndOfMessageAcknowledgement_totalNumberOfPackets_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t EndOfMessageAcknowledgement_reserved5_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       EndOfMessageAcknowledgement_reserved5_xer_ = { {"reserved5>\n", "reserved5>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int EndOfMessageAcknowledgement_reserved5_oer_ext_arr_[0] = {};
const int EndOfMessageAcknowledgement_reserved5_oer_p_[0] = {};
const TTCN_OERdescriptor_t EndOfMessageAcknowledgement_reserved5_oer_ = { -1, TRUE, 1, FALSE, 0, 0, EndOfMessageAcknowledgement_reserved5_oer_ext_arr_, 0, EndOfMessageAcknowledgement_reserved5_oer_p_};
const TTCN_Typedescriptor_t EndOfMessageAcknowledgement_reserved5_descr_ = { "@IsobusCMMessageTypes.EndOfMessageAcknowledgement.reserved5", &OCTETSTRING_ber_, &EndOfMessageAcknowledgement_reserved5_raw_, &OCTETSTRING_text_, &EndOfMessageAcknowledgement_reserved5_xer_, &OCTETSTRING_json_, &EndOfMessageAcknowledgement_reserved5_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       EndOfMessageAcknowledgement_pgnOfMultiPacketMessage_xer_ = { {"pgnOfMultiPacketMessage>\n", "pgnOfMultiPacketMessage>\n"}, {25, 25}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t EndOfMessageAcknowledgement_pgnOfMultiPacketMessage_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t EndOfMessageAcknowledgement_pgnOfMultiPacketMessage_descr_ = { "@IsobusCMMessageTypes.EndOfMessageAcknowledgement.pgnOfMultiPacketMessage", &INTEGER_ber_, &IsobusMessageTypes::INT24nb_raw_, &INTEGER_text_, &EndOfMessageAcknowledgement_pgnOfMultiPacketMessage_xer_, &INTEGER_json_, &EndOfMessageAcknowledgement_pgnOfMultiPacketMessage_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t EndOfMessageAcknowledgement_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for EndOfMessageAcknowledgement
const TTCN_Typedescriptor_t EndOfMessageAcknowledgement_descr_ = { "@IsobusCMMessageTypes.EndOfMessageAcknowledgement", NULL, &EndOfMessageAcknowledgement_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t e__ConnectionAbort__AbortReason_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,8,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for e__ConnectionAbort__AbortReason
const TTCN_Typedescriptor_t e__ConnectionAbort__AbortReason_descr_ = { "@IsobusCMMessageTypes.e_ConnectionAbort_AbortReason", NULL, &e__ConnectionAbort__AbortReason_raw_, NULL, NULL, &ENUMERATED_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ConnectionAbort_ctrl_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ConnectionAbort_ctrl_xer_ = { {"ctrl>\n", "ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ConnectionAbort_ctrl_oer_ext_arr_[0] = {};
const int ConnectionAbort_ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t ConnectionAbort_ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ConnectionAbort_ctrl_oer_ext_arr_, 0, ConnectionAbort_ctrl_oer_p_};
const TTCN_Typedescriptor_t ConnectionAbort_ctrl_descr_ = { "@IsobusCMMessageTypes.ConnectionAbort.ctrl", &OCTETSTRING_ber_, &ConnectionAbort_ctrl_raw_, &OCTETSTRING_text_, &ConnectionAbort_ctrl_xer_, &OCTETSTRING_json_, &ConnectionAbort_ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ConnectionAbort_reserved3_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ConnectionAbort_reserved3_xer_ = { {"reserved3>\n", "reserved3>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ConnectionAbort_reserved3_oer_ext_arr_[0] = {};
const int ConnectionAbort_reserved3_oer_p_[0] = {};
const TTCN_OERdescriptor_t ConnectionAbort_reserved3_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ConnectionAbort_reserved3_oer_ext_arr_, 0, ConnectionAbort_reserved3_oer_p_};
const TTCN_Typedescriptor_t ConnectionAbort_reserved3_descr_ = { "@IsobusCMMessageTypes.ConnectionAbort.reserved3", &OCTETSTRING_ber_, &ConnectionAbort_reserved3_raw_, &OCTETSTRING_text_, &ConnectionAbort_reserved3_xer_, &OCTETSTRING_json_, &ConnectionAbort_reserved3_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ConnectionAbort_reserved4_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ConnectionAbort_reserved4_xer_ = { {"reserved4>\n", "reserved4>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ConnectionAbort_reserved4_oer_ext_arr_[0] = {};
const int ConnectionAbort_reserved4_oer_p_[0] = {};
const TTCN_OERdescriptor_t ConnectionAbort_reserved4_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ConnectionAbort_reserved4_oer_ext_arr_, 0, ConnectionAbort_reserved4_oer_p_};
const TTCN_Typedescriptor_t ConnectionAbort_reserved4_descr_ = { "@IsobusCMMessageTypes.ConnectionAbort.reserved4", &OCTETSTRING_ber_, &ConnectionAbort_reserved4_raw_, &OCTETSTRING_text_, &ConnectionAbort_reserved4_xer_, &OCTETSTRING_json_, &ConnectionAbort_reserved4_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ConnectionAbort_reserved5_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ConnectionAbort_reserved5_xer_ = { {"reserved5>\n", "reserved5>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ConnectionAbort_reserved5_oer_ext_arr_[0] = {};
const int ConnectionAbort_reserved5_oer_p_[0] = {};
const TTCN_OERdescriptor_t ConnectionAbort_reserved5_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ConnectionAbort_reserved5_oer_ext_arr_, 0, ConnectionAbort_reserved5_oer_p_};
const TTCN_Typedescriptor_t ConnectionAbort_reserved5_descr_ = { "@IsobusCMMessageTypes.ConnectionAbort.reserved5", &OCTETSTRING_ber_, &ConnectionAbort_reserved5_raw_, &OCTETSTRING_text_, &ConnectionAbort_reserved5_xer_, &OCTETSTRING_json_, &ConnectionAbort_reserved5_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ConnectionAbort_pgnOfMultiPacketMessage_xer_ = { {"pgnOfMultiPacketMessage>\n", "pgnOfMultiPacketMessage>\n"}, {25, 25}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ConnectionAbort_pgnOfMultiPacketMessage_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ConnectionAbort_pgnOfMultiPacketMessage_descr_ = { "@IsobusCMMessageTypes.ConnectionAbort.pgnOfMultiPacketMessage", &INTEGER_ber_, &IsobusMessageTypes::INT24nb_raw_, &INTEGER_text_, &ConnectionAbort_pgnOfMultiPacketMessage_xer_, &INTEGER_json_, &ConnectionAbort_pgnOfMultiPacketMessage_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ConnectionAbort_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for ConnectionAbort
const TTCN_Typedescriptor_t ConnectionAbort_descr_ = { "@IsobusCMMessageTypes.ConnectionAbort", NULL, &ConnectionAbort_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t BroadcastAnnounce_ctrl_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       BroadcastAnnounce_ctrl_xer_ = { {"ctrl>\n", "ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int BroadcastAnnounce_ctrl_oer_ext_arr_[0] = {};
const int BroadcastAnnounce_ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t BroadcastAnnounce_ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, BroadcastAnnounce_ctrl_oer_ext_arr_, 0, BroadcastAnnounce_ctrl_oer_p_};
const TTCN_Typedescriptor_t BroadcastAnnounce_ctrl_descr_ = { "@IsobusCMMessageTypes.BroadcastAnnounce.ctrl", &OCTETSTRING_ber_, &BroadcastAnnounce_ctrl_raw_, &OCTETSTRING_text_, &BroadcastAnnounce_ctrl_xer_, &OCTETSTRING_json_, &BroadcastAnnounce_ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       BroadcastAnnounce_msgSizeInByte_xer_ = { {"msgSizeInByte>\n", "msgSizeInByte>\n"}, {15, 15}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t BroadcastAnnounce_msgSizeInByte_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t BroadcastAnnounce_msgSizeInByte_descr_ = { "@IsobusCMMessageTypes.BroadcastAnnounce.msgSizeInByte", &INTEGER_ber_, &IsobusMessageTypes::INT2_raw_, &INTEGER_text_, &BroadcastAnnounce_msgSizeInByte_xer_, &INTEGER_json_, &BroadcastAnnounce_msgSizeInByte_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       BroadcastAnnounce_totalNumberOfPackets_xer_ = { {"totalNumberOfPackets>\n", "totalNumberOfPackets>\n"}, {22, 22}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t BroadcastAnnounce_totalNumberOfPackets_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t BroadcastAnnounce_totalNumberOfPackets_descr_ = { "@IsobusCMMessageTypes.BroadcastAnnounce.totalNumberOfPackets", &INTEGER_ber_, &NUMBER__OF__PACKETS_raw_, &INTEGER_text_, &BroadcastAnnounce_totalNumberOfPackets_xer_, &INTEGER_json_, &BroadcastAnnounce_totalNumberOfPackets_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t BroadcastAnnounce_reserved5_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       BroadcastAnnounce_reserved5_xer_ = { {"reserved5>\n", "reserved5>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int BroadcastAnnounce_reserved5_oer_ext_arr_[0] = {};
const int BroadcastAnnounce_reserved5_oer_p_[0] = {};
const TTCN_OERdescriptor_t BroadcastAnnounce_reserved5_oer_ = { -1, TRUE, 1, FALSE, 0, 0, BroadcastAnnounce_reserved5_oer_ext_arr_, 0, BroadcastAnnounce_reserved5_oer_p_};
const TTCN_Typedescriptor_t BroadcastAnnounce_reserved5_descr_ = { "@IsobusCMMessageTypes.BroadcastAnnounce.reserved5", &OCTETSTRING_ber_, &BroadcastAnnounce_reserved5_raw_, &OCTETSTRING_text_, &BroadcastAnnounce_reserved5_xer_, &OCTETSTRING_json_, &BroadcastAnnounce_reserved5_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       BroadcastAnnounce_pgnOfMultiPacketMessage_xer_ = { {"pgnOfMultiPacketMessage>\n", "pgnOfMultiPacketMessage>\n"}, {25, 25}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t BroadcastAnnounce_pgnOfMultiPacketMessage_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t BroadcastAnnounce_pgnOfMultiPacketMessage_descr_ = { "@IsobusCMMessageTypes.BroadcastAnnounce.pgnOfMultiPacketMessage", &INTEGER_ber_, &IsobusMessageTypes::INT24nb_raw_, &INTEGER_text_, &BroadcastAnnounce_pgnOfMultiPacketMessage_xer_, &INTEGER_json_, &BroadcastAnnounce_pgnOfMultiPacketMessage_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t BroadcastAnnounce_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for BroadcastAnnounce
const TTCN_Typedescriptor_t BroadcastAnnounce_descr_ = { "@IsobusCMMessageTypes.BroadcastAnnounce", NULL, &BroadcastAnnounce_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t TP__CM_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for TP__CM
const TTCN_Typedescriptor_t TP__CM_descr_ = { "@IsobusCMMessageTypes.TP_CM", NULL, &TP__CM_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ETP__MSG__SIZE_raw_ = {32,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ETP__MSG__SIZE_xer_ = { {"ETP_MSG_SIZE>\n", "ETP_MSG_SIZE>\n"}, {14, 14}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ETP__MSG__SIZE_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ETP__MSG__SIZE_descr_ = { "@IsobusCMMessageTypes.ETP_MSG_SIZE", &INTEGER_ber_, &ETP__MSG__SIZE_raw_, &INTEGER_text_, &ETP__MSG__SIZE_xer_, &INTEGER_json_, &ETP__MSG__SIZE_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageRequestToSend_ctrl_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ExtendedMessageRequestToSend_ctrl_xer_ = { {"ctrl>\n", "ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ExtendedMessageRequestToSend_ctrl_oer_ext_arr_[0] = {};
const int ExtendedMessageRequestToSend_ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t ExtendedMessageRequestToSend_ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ExtendedMessageRequestToSend_ctrl_oer_ext_arr_, 0, ExtendedMessageRequestToSend_ctrl_oer_p_};
const TTCN_Typedescriptor_t ExtendedMessageRequestToSend_ctrl_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageRequestToSend.ctrl", &OCTETSTRING_ber_, &ExtendedMessageRequestToSend_ctrl_raw_, &OCTETSTRING_text_, &ExtendedMessageRequestToSend_ctrl_xer_, &OCTETSTRING_json_, &ExtendedMessageRequestToSend_ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageRequestToSend_msgSizeInBytes_xer_ = { {"msgSizeInBytes>\n", "msgSizeInBytes>\n"}, {16, 16}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageRequestToSend_msgSizeInBytes_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageRequestToSend_msgSizeInBytes_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageRequestToSend.msgSizeInBytes", &INTEGER_ber_, &ETP__MSG__SIZE_raw_, &INTEGER_text_, &ExtendedMessageRequestToSend_msgSizeInBytes_xer_, &INTEGER_json_, &ExtendedMessageRequestToSend_msgSizeInBytes_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageRequestToSend_pgnOfExtendedPacketedMessage_xer_ = { {"pgnOfExtendedPacketedMessage>\n", "pgnOfExtendedPacketedMessage>\n"}, {30, 30}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageRequestToSend_pgnOfExtendedPacketedMessage_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageRequestToSend_pgnOfExtendedPacketedMessage_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageRequestToSend.pgnOfExtendedPacketedMessage", &INTEGER_ber_, &IsobusMessageTypes::INT24nb_raw_, &INTEGER_text_, &ExtendedMessageRequestToSend_pgnOfExtendedPacketedMessage_xer_, &INTEGER_json_, &ExtendedMessageRequestToSend_pgnOfExtendedPacketedMessage_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageRequestToSend_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for ExtendedMessageRequestToSend
const TTCN_Typedescriptor_t ExtendedMessageRequestToSend_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageRequestToSend", NULL, &ExtendedMessageRequestToSend_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ETP__NextPacketNumberToSend_raw_ = {32,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ETP__NextPacketNumberToSend_xer_ = { {"ETP_NextPacketNumberToSend>\n", "ETP_NextPacketNumberToSend>\n"}, {28, 28}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ETP__NextPacketNumberToSend_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ETP__NextPacketNumberToSend_descr_ = { "@IsobusCMMessageTypes.ETP_NextPacketNumberToSend", &INTEGER_ber_, &ETP__NextPacketNumberToSend_raw_, &INTEGER_text_, &ETP__NextPacketNumberToSend_xer_, &INTEGER_json_, &ETP__NextPacketNumberToSend_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageClearToSend_ctrl_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ExtendedMessageClearToSend_ctrl_xer_ = { {"ctrl>\n", "ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ExtendedMessageClearToSend_ctrl_oer_ext_arr_[0] = {};
const int ExtendedMessageClearToSend_ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t ExtendedMessageClearToSend_ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ExtendedMessageClearToSend_ctrl_oer_ext_arr_, 0, ExtendedMessageClearToSend_ctrl_oer_p_};
const TTCN_Typedescriptor_t ExtendedMessageClearToSend_ctrl_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageClearToSend.ctrl", &OCTETSTRING_ber_, &ExtendedMessageClearToSend_ctrl_raw_, &OCTETSTRING_text_, &ExtendedMessageClearToSend_ctrl_xer_, &OCTETSTRING_json_, &ExtendedMessageClearToSend_ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageClearToSend_NumberOfPacketsToSend_xer_ = { {"NumberOfPacketsToSend>\n", "NumberOfPacketsToSend>\n"}, {23, 23}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageClearToSend_NumberOfPacketsToSend_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageClearToSend_NumberOfPacketsToSend_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageClearToSend.NumberOfPacketsToSend", &INTEGER_ber_, &General__Types::INT1_raw_, &INTEGER_text_, &ExtendedMessageClearToSend_NumberOfPacketsToSend_xer_, &INTEGER_json_, &ExtendedMessageClearToSend_NumberOfPacketsToSend_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageClearToSend_nextPacketNumberToSend_xer_ = { {"nextPacketNumberToSend>\n", "nextPacketNumberToSend>\n"}, {24, 24}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageClearToSend_nextPacketNumberToSend_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageClearToSend_nextPacketNumberToSend_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageClearToSend.nextPacketNumberToSend", &INTEGER_ber_, &ETP__NextPacketNumberToSend_raw_, &INTEGER_text_, &ExtendedMessageClearToSend_nextPacketNumberToSend_xer_, &INTEGER_json_, &ExtendedMessageClearToSend_nextPacketNumberToSend_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageClearToSend_pgnOfExtendedPacketedMessage_xer_ = { {"pgnOfExtendedPacketedMessage>\n", "pgnOfExtendedPacketedMessage>\n"}, {30, 30}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageClearToSend_pgnOfExtendedPacketedMessage_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageClearToSend_pgnOfExtendedPacketedMessage_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageClearToSend.pgnOfExtendedPacketedMessage", &INTEGER_ber_, &IsobusMessageTypes::INT24nb_raw_, &INTEGER_text_, &ExtendedMessageClearToSend_pgnOfExtendedPacketedMessage_xer_, &INTEGER_json_, &ExtendedMessageClearToSend_pgnOfExtendedPacketedMessage_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageClearToSend_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for ExtendedMessageClearToSend
const TTCN_Typedescriptor_t ExtendedMessageClearToSend_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageClearToSend", NULL, &ExtendedMessageClearToSend_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ETP__NoPacketForOffset_raw_ = {8,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ETP__NoPacketForOffset_xer_ = { {"ETP_NoPacketForOffset>\n", "ETP_NoPacketForOffset>\n"}, {23, 23}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ETP__NoPacketForOffset_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ETP__NoPacketForOffset_descr_ = { "@IsobusCMMessageTypes.ETP_NoPacketForOffset", &INTEGER_ber_, &ETP__NoPacketForOffset_raw_, &INTEGER_text_, &ETP__NoPacketForOffset_xer_, &INTEGER_json_, &ETP__NoPacketForOffset_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageDataPacketOffset_ctrl_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ExtendedMessageDataPacketOffset_ctrl_xer_ = { {"ctrl>\n", "ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ExtendedMessageDataPacketOffset_ctrl_oer_ext_arr_[0] = {};
const int ExtendedMessageDataPacketOffset_ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t ExtendedMessageDataPacketOffset_ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ExtendedMessageDataPacketOffset_ctrl_oer_ext_arr_, 0, ExtendedMessageDataPacketOffset_ctrl_oer_p_};
const TTCN_Typedescriptor_t ExtendedMessageDataPacketOffset_ctrl_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.ctrl", &OCTETSTRING_ber_, &ExtendedMessageDataPacketOffset_ctrl_raw_, &OCTETSTRING_text_, &ExtendedMessageDataPacketOffset_ctrl_xer_, &OCTETSTRING_json_, &ExtendedMessageDataPacketOffset_ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageDataPacketOffset_numberOfPacketsToWhichToApplyTheOffset_xer_ = { {"numberOfPacketsToWhichToApplyTheOffset>\n", "numberOfPacketsToWhichToApplyTheOffset>\n"}, {40, 40}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageDataPacketOffset_numberOfPacketsToWhichToApplyTheOffset_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageDataPacketOffset_numberOfPacketsToWhichToApplyTheOffset_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.numberOfPacketsToWhichToApplyTheOffset", &INTEGER_ber_, &ETP__NoPacketForOffset_raw_, &INTEGER_text_, &ExtendedMessageDataPacketOffset_numberOfPacketsToWhichToApplyTheOffset_xer_, &INTEGER_json_, &ExtendedMessageDataPacketOffset_numberOfPacketsToWhichToApplyTheOffset_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageDataPacketOffset_totalNumberOfPackets_xer_ = { {"totalNumberOfPackets>\n", "totalNumberOfPackets>\n"}, {22, 22}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageDataPacketOffset_totalNumberOfPackets_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageDataPacketOffset_totalNumberOfPackets_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.totalNumberOfPackets", &INTEGER_ber_, &NUMBER__OF__PACKETS_raw_, &INTEGER_text_, &ExtendedMessageDataPacketOffset_totalNumberOfPackets_xer_, &INTEGER_json_, &ExtendedMessageDataPacketOffset_totalNumberOfPackets_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageDataPacketOffset_dataPacketOffset_xer_ = { {"dataPacketOffset>\n", "dataPacketOffset>\n"}, {18, 18}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageDataPacketOffset_dataPacketOffset_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageDataPacketOffset_dataPacketOffset_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.dataPacketOffset", &INTEGER_ber_, &ETP__NextPacketNumberToSend_raw_, &INTEGER_text_, &ExtendedMessageDataPacketOffset_dataPacketOffset_xer_, &INTEGER_json_, &ExtendedMessageDataPacketOffset_dataPacketOffset_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageDataPacketOffset_pgnOfExtendedPacketedMessage_xer_ = { {"pgnOfExtendedPacketedMessage>\n", "pgnOfExtendedPacketedMessage>\n"}, {30, 30}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageDataPacketOffset_pgnOfExtendedPacketedMessage_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageDataPacketOffset_pgnOfExtendedPacketedMessage_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.pgnOfExtendedPacketedMessage", &INTEGER_ber_, &IsobusMessageTypes::INT24nb_raw_, &INTEGER_text_, &ExtendedMessageDataPacketOffset_pgnOfExtendedPacketedMessage_xer_, &INTEGER_json_, &ExtendedMessageDataPacketOffset_pgnOfExtendedPacketedMessage_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageDataPacketOffset_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for ExtendedMessageDataPacketOffset
const TTCN_Typedescriptor_t ExtendedMessageDataPacketOffset_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset", NULL, &ExtendedMessageDataPacketOffset_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageEndOfMessageAcknowledgement_ctrl_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ExtendedMessageEndOfMessageAcknowledgement_ctrl_xer_ = { {"ctrl>\n", "ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ExtendedMessageEndOfMessageAcknowledgement_ctrl_oer_ext_arr_[0] = {};
const int ExtendedMessageEndOfMessageAcknowledgement_ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t ExtendedMessageEndOfMessageAcknowledgement_ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ExtendedMessageEndOfMessageAcknowledgement_ctrl_oer_ext_arr_, 0, ExtendedMessageEndOfMessageAcknowledgement_ctrl_oer_p_};
const TTCN_Typedescriptor_t ExtendedMessageEndOfMessageAcknowledgement_ctrl_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.ctrl", &OCTETSTRING_ber_, &ExtendedMessageEndOfMessageAcknowledgement_ctrl_raw_, &OCTETSTRING_text_, &ExtendedMessageEndOfMessageAcknowledgement_ctrl_xer_, &OCTETSTRING_json_, &ExtendedMessageEndOfMessageAcknowledgement_ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageEndOfMessageAcknowledgement_numberOfBytesTransferred_xer_ = { {"numberOfBytesTransferred>\n", "numberOfBytesTransferred>\n"}, {26, 26}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageEndOfMessageAcknowledgement_numberOfBytesTransferred_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageEndOfMessageAcknowledgement_numberOfBytesTransferred_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.numberOfBytesTransferred", &INTEGER_ber_, &ETP__MSG__SIZE_raw_, &INTEGER_text_, &ExtendedMessageEndOfMessageAcknowledgement_numberOfBytesTransferred_xer_, &INTEGER_json_, &ExtendedMessageEndOfMessageAcknowledgement_numberOfBytesTransferred_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageEndOfMessageAcknowledgement_pgnOfExtendedPacketedMessage_xer_ = { {"pgnOfExtendedPacketedMessage>\n", "pgnOfExtendedPacketedMessage>\n"}, {30, 30}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageEndOfMessageAcknowledgement_pgnOfExtendedPacketedMessage_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageEndOfMessageAcknowledgement_pgnOfExtendedPacketedMessage_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.pgnOfExtendedPacketedMessage", &INTEGER_ber_, &IsobusMessageTypes::INT24nb_raw_, &INTEGER_text_, &ExtendedMessageEndOfMessageAcknowledgement_pgnOfExtendedPacketedMessage_xer_, &INTEGER_json_, &ExtendedMessageEndOfMessageAcknowledgement_pgnOfExtendedPacketedMessage_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageEndOfMessageAcknowledgement_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for ExtendedMessageEndOfMessageAcknowledgement
const TTCN_Typedescriptor_t ExtendedMessageEndOfMessageAcknowledgement_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement", NULL, &ExtendedMessageEndOfMessageAcknowledgement_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t e__ETP__ConnectionAbort__AbortReason_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,8,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for e__ETP__ConnectionAbort__AbortReason
const TTCN_Typedescriptor_t e__ETP__ConnectionAbort__AbortReason_descr_ = { "@IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason", NULL, &e__ETP__ConnectionAbort__AbortReason_raw_, NULL, NULL, &ENUMERATED_json_, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageConnectionAbort_ctrl_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ExtendedMessageConnectionAbort_ctrl_xer_ = { {"ctrl>\n", "ctrl>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ExtendedMessageConnectionAbort_ctrl_oer_ext_arr_[0] = {};
const int ExtendedMessageConnectionAbort_ctrl_oer_p_[0] = {};
const TTCN_OERdescriptor_t ExtendedMessageConnectionAbort_ctrl_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ExtendedMessageConnectionAbort_ctrl_oer_ext_arr_, 0, ExtendedMessageConnectionAbort_ctrl_oer_p_};
const TTCN_Typedescriptor_t ExtendedMessageConnectionAbort_ctrl_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort.ctrl", &OCTETSTRING_ber_, &ExtendedMessageConnectionAbort_ctrl_raw_, &OCTETSTRING_text_, &ExtendedMessageConnectionAbort_ctrl_xer_, &OCTETSTRING_json_, &ExtendedMessageConnectionAbort_ctrl_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageConnectionAbort_reserved3_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ExtendedMessageConnectionAbort_reserved3_xer_ = { {"reserved3>\n", "reserved3>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ExtendedMessageConnectionAbort_reserved3_oer_ext_arr_[0] = {};
const int ExtendedMessageConnectionAbort_reserved3_oer_p_[0] = {};
const TTCN_OERdescriptor_t ExtendedMessageConnectionAbort_reserved3_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ExtendedMessageConnectionAbort_reserved3_oer_ext_arr_, 0, ExtendedMessageConnectionAbort_reserved3_oer_p_};
const TTCN_Typedescriptor_t ExtendedMessageConnectionAbort_reserved3_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort.reserved3", &OCTETSTRING_ber_, &ExtendedMessageConnectionAbort_reserved3_raw_, &OCTETSTRING_text_, &ExtendedMessageConnectionAbort_reserved3_xer_, &OCTETSTRING_json_, &ExtendedMessageConnectionAbort_reserved3_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageConnectionAbort_reserved4_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ExtendedMessageConnectionAbort_reserved4_xer_ = { {"reserved4>\n", "reserved4>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ExtendedMessageConnectionAbort_reserved4_oer_ext_arr_[0] = {};
const int ExtendedMessageConnectionAbort_reserved4_oer_p_[0] = {};
const TTCN_OERdescriptor_t ExtendedMessageConnectionAbort_reserved4_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ExtendedMessageConnectionAbort_reserved4_oer_ext_arr_, 0, ExtendedMessageConnectionAbort_reserved4_oer_p_};
const TTCN_Typedescriptor_t ExtendedMessageConnectionAbort_reserved4_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort.reserved4", &OCTETSTRING_ber_, &ExtendedMessageConnectionAbort_reserved4_raw_, &OCTETSTRING_text_, &ExtendedMessageConnectionAbort_reserved4_xer_, &OCTETSTRING_json_, &ExtendedMessageConnectionAbort_reserved4_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageConnectionAbort_reserved5_raw_ = {8,SG_NO,ORDER_LSB,ORDER_MSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
const XERdescriptor_t       ExtendedMessageConnectionAbort_reserved5_xer_ = { {"reserved5>\n", "reserved5>\n"}, {11, 11}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ExtendedMessageConnectionAbort_reserved5_oer_ext_arr_[0] = {};
const int ExtendedMessageConnectionAbort_reserved5_oer_p_[0] = {};
const TTCN_OERdescriptor_t ExtendedMessageConnectionAbort_reserved5_oer_ = { -1, TRUE, 1, FALSE, 0, 0, ExtendedMessageConnectionAbort_reserved5_oer_ext_arr_, 0, ExtendedMessageConnectionAbort_reserved5_oer_p_};
const TTCN_Typedescriptor_t ExtendedMessageConnectionAbort_reserved5_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort.reserved5", &OCTETSTRING_ber_, &ExtendedMessageConnectionAbort_reserved5_raw_, &OCTETSTRING_text_, &ExtendedMessageConnectionAbort_reserved5_xer_, &OCTETSTRING_json_, &ExtendedMessageConnectionAbort_reserved5_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ExtendedMessageConnectionAbort_pgnOfExtendedPacketedMessage_xer_ = { {"pgnOfExtendedPacketedMessage>\n", "pgnOfExtendedPacketedMessage>\n"}, {30, 30}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ExtendedMessageConnectionAbort_pgnOfExtendedPacketedMessage_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ExtendedMessageConnectionAbort_pgnOfExtendedPacketedMessage_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort.pgnOfExtendedPacketedMessage", &INTEGER_ber_, &IsobusMessageTypes::INT24nb_raw_, &INTEGER_text_, &ExtendedMessageConnectionAbort_pgnOfExtendedPacketedMessage_xer_, &INTEGER_json_, &ExtendedMessageConnectionAbort_pgnOfExtendedPacketedMessage_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ExtendedMessageConnectionAbort_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for ExtendedMessageConnectionAbort
const TTCN_Typedescriptor_t ExtendedMessageConnectionAbort_descr_ = { "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort", NULL, &ExtendedMessageConnectionAbort_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ETP__CM_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for ETP__CM
const TTCN_Typedescriptor_t ETP__CM_descr_ = { "@IsobusCMMessageTypes.ETP_CM", NULL, &ETP__CM_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       TP__DT_seq__no_xer_ = { {"seq_no>\n", "seq_no>\n"}, {8, 8}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t TP__DT_seq__no_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t TP__DT_seq__no_descr_ = { "@IsobusCMMessageTypes.TP_DT.seq_no", &INTEGER_ber_, &SEQ__NO_raw_, &INTEGER_text_, &TP__DT_seq__no_xer_, &INTEGER_json_, &TP__DT_seq__no_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       TP__DT_data_xer_ = { {"data>\n", "data>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int TP__DT_data_oer_ext_arr_[0] = {};
const int TP__DT_data_oer_p_[0] = {};
const TTCN_OERdescriptor_t TP__DT_data_oer_ = { -1, TRUE, 7, FALSE, 0, 0, TP__DT_data_oer_ext_arr_, 0, TP__DT_data_oer_p_};
const TTCN_Typedescriptor_t TP__DT_data_descr_ = { "@IsobusCMMessageTypes.TP_DT.data", &OCTETSTRING_ber_, &General__Types::OCT7_raw_, &OCTETSTRING_text_, &TP__DT_data_xer_, &OCTETSTRING_json_, &TP__DT_data_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t TP__DT_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for TP__DT
const TTCN_Typedescriptor_t TP__DT_descr_ = { "@IsobusCMMessageTypes.TP_DT", NULL, &TP__DT_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ETP__DT_seq__no_xer_ = { {"seq_no>\n", "seq_no>\n"}, {8, 8}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const TTCN_OERdescriptor_t ETP__DT_seq__no_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };
const TTCN_Typedescriptor_t ETP__DT_seq__no_descr_ = { "@IsobusCMMessageTypes.ETP_DT.seq_no", &INTEGER_ber_, &SEQ__NO_raw_, &INTEGER_text_, &ETP__DT_seq__no_xer_, &INTEGER_json_, &ETP__DT_seq__no_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const XERdescriptor_t       ETP__DT_data_xer_ = { {"data>\n", "data>\n"}, {6, 6}, 0 |FORM_UNQUALIFIED, WHITESPACE_PRESERVE,  NULL, &module_object, -1, 0, NULL, NULL, -1, XSD_NONE };
const int ETP__DT_data_oer_ext_arr_[0] = {};
const int ETP__DT_data_oer_p_[0] = {};
const TTCN_OERdescriptor_t ETP__DT_data_oer_ = { -1, TRUE, 7, FALSE, 0, 0, ETP__DT_data_oer_ext_arr_, 0, ETP__DT_data_oer_p_};
const TTCN_Typedescriptor_t ETP__DT_data_descr_ = { "@IsobusCMMessageTypes.ETP_DT.data", &OCTETSTRING_ber_, &General__Types::OCT7_raw_, &OCTETSTRING_text_, &ETP__DT_data_xer_, &OCTETSTRING_json_, &ETP__DT_data_oer_, NULL, TTCN_Typedescriptor_t::DONTCARE };
const TTCN_RAWdescriptor_t ETP__DT_raw_ = {0,SG_NO,ORDER_LSB,ORDER_LSB,ORDER_LSB,ORDER_LSB,EXT_BIT_NO,ORDER_LSB,ORDER_LSB,TOP_BIT_INHERITED,0,0,0,8,0,NULL,-1,CharCoding::UNKNOWN,NULL,false};
// No XER for ETP__DT
const TTCN_Typedescriptor_t ETP__DT_descr_ = { "@IsobusCMMessageTypes.ETP_DT", NULL, &ETP__DT_raw_, NULL, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE };
TTCN_Module module_object("IsobusCMMessageTypes", __DATE__, __TIME__, module_checksum, pre_init_module, NULL, 0U, 4294967295U, 4294967295U, 4294967295U, NULL, 0LU, 0, post_init_module, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

static const RuntimeVersionChecker ver_checker(  current_runtime_version.requires_major_version_6,
  current_runtime_version.requires_minor_version_6,
  current_runtime_version.requires_patch_level_0,  current_runtime_version.requires_runtime_1);

/* Member functions of C++ classes */

RequestToSend::RequestToSend()
{
}

RequestToSend::RequestToSend(const OCTETSTRING& par_ctrl,
    const INTEGER& par_msgSizeInBytes,
    const INTEGER& par_totalNumberOfPackets,
    const INTEGER& par_maxNoOfPacketsInResponseToCTS,
    const INTEGER& par_pgnOfMultiPacketMessage)
  :   field_ctrl(par_ctrl),
  field_msgSizeInBytes(par_msgSizeInBytes),
  field_totalNumberOfPackets(par_totalNumberOfPackets),
  field_maxNoOfPacketsInResponseToCTS(par_maxNoOfPacketsInResponseToCTS),
  field_pgnOfMultiPacketMessage(par_pgnOfMultiPacketMessage)
{
}

RequestToSend::RequestToSend(const RequestToSend& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.RequestToSend.");
if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
else field_ctrl.clean_up();
if (other_value.msgSizeInBytes().is_bound()) field_msgSizeInBytes = other_value.msgSizeInBytes();
else field_msgSizeInBytes.clean_up();
if (other_value.totalNumberOfPackets().is_bound()) field_totalNumberOfPackets = other_value.totalNumberOfPackets();
else field_totalNumberOfPackets.clean_up();
if (other_value.maxNoOfPacketsInResponseToCTS().is_bound()) field_maxNoOfPacketsInResponseToCTS = other_value.maxNoOfPacketsInResponseToCTS();
else field_maxNoOfPacketsInResponseToCTS.clean_up();
if (other_value.pgnOfMultiPacketMessage().is_bound()) field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
else field_pgnOfMultiPacketMessage.clean_up();
}

void RequestToSend::clean_up()
{
field_ctrl.clean_up();
field_msgSizeInBytes.clean_up();
field_totalNumberOfPackets.clean_up();
field_maxNoOfPacketsInResponseToCTS.clean_up();
field_pgnOfMultiPacketMessage.clean_up();
}

const TTCN_Typedescriptor_t* RequestToSend::get_descriptor() const { return &RequestToSend_descr_; }
RequestToSend& RequestToSend::operator=(const RequestToSend& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.RequestToSend.");
  if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
  else field_ctrl.clean_up();
  if (other_value.msgSizeInBytes().is_bound()) field_msgSizeInBytes = other_value.msgSizeInBytes();
  else field_msgSizeInBytes.clean_up();
  if (other_value.totalNumberOfPackets().is_bound()) field_totalNumberOfPackets = other_value.totalNumberOfPackets();
  else field_totalNumberOfPackets.clean_up();
  if (other_value.maxNoOfPacketsInResponseToCTS().is_bound()) field_maxNoOfPacketsInResponseToCTS = other_value.maxNoOfPacketsInResponseToCTS();
  else field_maxNoOfPacketsInResponseToCTS.clean_up();
  if (other_value.pgnOfMultiPacketMessage().is_bound()) field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
  else field_pgnOfMultiPacketMessage.clean_up();
}
return *this;
}

boolean RequestToSend::operator==(const RequestToSend& other_value) const
{
return field_ctrl==other_value.field_ctrl
  && field_msgSizeInBytes==other_value.field_msgSizeInBytes
  && field_totalNumberOfPackets==other_value.field_totalNumberOfPackets
  && field_maxNoOfPacketsInResponseToCTS==other_value.field_maxNoOfPacketsInResponseToCTS
  && field_pgnOfMultiPacketMessage==other_value.field_pgnOfMultiPacketMessage;
}

boolean RequestToSend::is_bound() const
{
return (field_ctrl.is_bound())
  || (field_msgSizeInBytes.is_bound())
  || (field_totalNumberOfPackets.is_bound())
  || (field_maxNoOfPacketsInResponseToCTS.is_bound())
  || (field_pgnOfMultiPacketMessage.is_bound());
}
boolean RequestToSend::is_value() const
{
return field_ctrl.is_value()
  && field_msgSizeInBytes.is_value()
  && field_totalNumberOfPackets.is_value()
  && field_maxNoOfPacketsInResponseToCTS.is_value()
  && field_pgnOfMultiPacketMessage.is_value();
}
void RequestToSend::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ctrl := ");
field_ctrl.log();
TTCN_Logger::log_event_str(", msgSizeInBytes := ");
field_msgSizeInBytes.log();
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
field_totalNumberOfPackets.log();
TTCN_Logger::log_event_str(", maxNoOfPacketsInResponseToCTS := ");
field_maxNoOfPacketsInResponseToCTS.log();
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
field_pgnOfMultiPacketMessage.log();
TTCN_Logger::log_event_str(" }");
}

void RequestToSend::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (5<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.RequestToSend has 5 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) msgSizeInBytes().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) totalNumberOfPackets().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) maxNoOfPacketsInResponseToCTS().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) pgnOfMultiPacketMessage().set_param(*param.get_elem(4));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "msgSizeInBytes")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          msgSizeInBytes().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "totalNumberOfPackets")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          totalNumberOfPackets().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "maxNoOfPacketsInResponseToCTS")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          maxNoOfPacketsInResponseToCTS().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfMultiPacketMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfMultiPacketMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.RequestToSend: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.RequestToSend");
  }
}

void RequestToSend::set_implicit_omit()
{
if (ctrl().is_bound()) ctrl().set_implicit_omit();
if (msgSizeInBytes().is_bound()) msgSizeInBytes().set_implicit_omit();
if (totalNumberOfPackets().is_bound()) totalNumberOfPackets().set_implicit_omit();
if (maxNoOfPacketsInResponseToCTS().is_bound()) maxNoOfPacketsInResponseToCTS().set_implicit_omit();
if (pgnOfMultiPacketMessage().is_bound()) pgnOfMultiPacketMessage().set_implicit_omit();
}

void RequestToSend::encode_text(Text_Buf& text_buf) const
{
field_ctrl.encode_text(text_buf);
field_msgSizeInBytes.encode_text(text_buf);
field_totalNumberOfPackets.encode_text(text_buf);
field_maxNoOfPacketsInResponseToCTS.encode_text(text_buf);
field_pgnOfMultiPacketMessage.encode_text(text_buf);
}

void RequestToSend::decode_text(Text_Buf& text_buf)
{
field_ctrl.decode_text(text_buf);
field_msgSizeInBytes.decode_text(text_buf);
field_totalNumberOfPackets.decode_text(text_buf);
field_maxNoOfPacketsInResponseToCTS.decode_text(text_buf);
field_pgnOfMultiPacketMessage.decode_text(text_buf);
}

void RequestToSend::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void RequestToSend::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int RequestToSend::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, RequestToSend_ctrl_descr_.raw->forceomit);
  decoded_field_length = field_ctrl.RAW_decode(RequestToSend_ctrl_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, IsobusMessageTypes::INT2_descr_.raw->forceomit);
  decoded_field_length = field_msgSizeInBytes.RAW_decode(IsobusMessageTypes::INT2_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, NUMBER__OF__PACKETS_descr_.raw->forceomit);
  decoded_field_length = field_totalNumberOfPackets.RAW_decode(NUMBER__OF__PACKETS_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_3_force_omit(3, force_omit, General__Types::INT1_descr_.raw->forceomit);
  decoded_field_length = field_maxNoOfPacketsInResponseToCTS.RAW_decode(General__Types::INT1_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_3_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_4_force_omit(4, force_omit, IsobusMessageTypes::PGN_descr_.raw->forceomit);
  decoded_field_length = field_pgnOfMultiPacketMessage.RAW_decode(IsobusMessageTypes::PGN_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_4_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int RequestToSend::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 5;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(5);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, RequestToSend_ctrl_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, IsobusMessageTypes::INT2_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, NUMBER__OF__PACKETS_descr_.raw);
  myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 3, General__Types::INT1_descr_.raw);
  myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 4, IsobusMessageTypes::PGN_descr_.raw);
  encoded_length += field_ctrl.RAW_encode(RequestToSend_ctrl_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_msgSizeInBytes.RAW_encode(IsobusMessageTypes::INT2_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_totalNumberOfPackets.RAW_encode(NUMBER__OF__PACKETS_descr_, *myleaf.body.node.nodes[2]);
  encoded_length += field_maxNoOfPacketsInResponseToCTS.RAW_encode(General__Types::INT1_descr_, *myleaf.body.node.nodes[3]);
  encoded_length += field_pgnOfMultiPacketMessage.RAW_encode(IsobusMessageTypes::PGN_descr_, *myleaf.body.node.nodes[4]);
  return myleaf.length = encoded_length;
}

struct RequestToSend_template::single_value_struct {
OCTETSTRING_template field_ctrl;
INTEGER_template field_msgSizeInBytes;
INTEGER_template field_totalNumberOfPackets;
INTEGER_template field_maxNoOfPacketsInResponseToCTS;
INTEGER_template field_pgnOfMultiPacketMessage;
};

void RequestToSend_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_ctrl = ANY_VALUE;
single_value->field_msgSizeInBytes = ANY_VALUE;
single_value->field_totalNumberOfPackets = ANY_VALUE;
single_value->field_maxNoOfPacketsInResponseToCTS = ANY_VALUE;
single_value->field_pgnOfMultiPacketMessage = ANY_VALUE;
}
}
}

void RequestToSend_template::copy_value(const RequestToSend& other_value)
{
single_value = new single_value_struct;
if (other_value.ctrl().is_bound()) {
  single_value->field_ctrl = other_value.ctrl();
} else {
  single_value->field_ctrl.clean_up();
}
if (other_value.msgSizeInBytes().is_bound()) {
  single_value->field_msgSizeInBytes = other_value.msgSizeInBytes();
} else {
  single_value->field_msgSizeInBytes.clean_up();
}
if (other_value.totalNumberOfPackets().is_bound()) {
  single_value->field_totalNumberOfPackets = other_value.totalNumberOfPackets();
} else {
  single_value->field_totalNumberOfPackets.clean_up();
}
if (other_value.maxNoOfPacketsInResponseToCTS().is_bound()) {
  single_value->field_maxNoOfPacketsInResponseToCTS = other_value.maxNoOfPacketsInResponseToCTS();
} else {
  single_value->field_maxNoOfPacketsInResponseToCTS.clean_up();
}
if (other_value.pgnOfMultiPacketMessage().is_bound()) {
  single_value->field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
} else {
  single_value->field_pgnOfMultiPacketMessage.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void RequestToSend_template::copy_template(const RequestToSend_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ctrl().get_selection()) {
single_value->field_ctrl = other_value.ctrl();
} else {
single_value->field_ctrl.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.msgSizeInBytes().get_selection()) {
single_value->field_msgSizeInBytes = other_value.msgSizeInBytes();
} else {
single_value->field_msgSizeInBytes.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.totalNumberOfPackets().get_selection()) {
single_value->field_totalNumberOfPackets = other_value.totalNumberOfPackets();
} else {
single_value->field_totalNumberOfPackets.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.maxNoOfPacketsInResponseToCTS().get_selection()) {
single_value->field_maxNoOfPacketsInResponseToCTS = other_value.maxNoOfPacketsInResponseToCTS();
} else {
single_value->field_maxNoOfPacketsInResponseToCTS.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pgnOfMultiPacketMessage().get_selection()) {
single_value->field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
} else {
single_value->field_pgnOfMultiPacketMessage.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new RequestToSend_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.RequestToSend.");
break;
}
set_selection(other_value);
}

RequestToSend_template::RequestToSend_template()
{
}

RequestToSend_template::RequestToSend_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

RequestToSend_template::RequestToSend_template(const RequestToSend& other_value)
{
copy_value(other_value);
}

RequestToSend_template::RequestToSend_template(const OPTIONAL<RequestToSend>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const RequestToSend&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.RequestToSend from an unbound optional field.");
}
}

RequestToSend_template::RequestToSend_template(const RequestToSend_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

RequestToSend_template::~RequestToSend_template()
{
clean_up();
}

RequestToSend_template& RequestToSend_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

RequestToSend_template& RequestToSend_template::operator=(const RequestToSend& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

RequestToSend_template& RequestToSend_template::operator=(const OPTIONAL<RequestToSend>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const RequestToSend&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.RequestToSend.");
}
return *this;
}

RequestToSend_template& RequestToSend_template::operator=(const RequestToSend_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean RequestToSend_template::match(const RequestToSend& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.ctrl().is_bound()) return FALSE;
if(!single_value->field_ctrl.match(other_value.ctrl(), legacy))return FALSE;
if(!other_value.msgSizeInBytes().is_bound()) return FALSE;
if(!single_value->field_msgSizeInBytes.match(other_value.msgSizeInBytes(), legacy))return FALSE;
if(!other_value.totalNumberOfPackets().is_bound()) return FALSE;
if(!single_value->field_totalNumberOfPackets.match(other_value.totalNumberOfPackets(), legacy))return FALSE;
if(!other_value.maxNoOfPacketsInResponseToCTS().is_bound()) return FALSE;
if(!single_value->field_maxNoOfPacketsInResponseToCTS.match(other_value.maxNoOfPacketsInResponseToCTS(), legacy))return FALSE;
if(!other_value.pgnOfMultiPacketMessage().is_bound()) return FALSE;
if(!single_value->field_pgnOfMultiPacketMessage.match(other_value.pgnOfMultiPacketMessage(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.RequestToSend.");
}
return FALSE;
}

boolean RequestToSend_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_ctrl.is_bound()

 ||single_value->field_msgSizeInBytes.is_bound()

 ||single_value->field_totalNumberOfPackets.is_bound()

 ||single_value->field_maxNoOfPacketsInResponseToCTS.is_bound()

 ||single_value->field_pgnOfMultiPacketMessage.is_bound()
;
}

boolean RequestToSend_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ctrl.is_value()
 &&single_value->field_msgSizeInBytes.is_value()
 &&single_value->field_totalNumberOfPackets.is_value()
 &&single_value->field_maxNoOfPacketsInResponseToCTS.is_value()
 &&single_value->field_pgnOfMultiPacketMessage.is_value();
}

void RequestToSend_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

RequestToSend RequestToSend_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.RequestToSend.");
RequestToSend ret_val;
if (single_value->field_ctrl.is_bound()) {
ret_val.ctrl() = single_value->field_ctrl.valueof();
}
if (single_value->field_msgSizeInBytes.is_bound()) {
ret_val.msgSizeInBytes() = single_value->field_msgSizeInBytes.valueof();
}
if (single_value->field_totalNumberOfPackets.is_bound()) {
ret_val.totalNumberOfPackets() = single_value->field_totalNumberOfPackets.valueof();
}
if (single_value->field_maxNoOfPacketsInResponseToCTS.is_bound()) {
ret_val.maxNoOfPacketsInResponseToCTS() = single_value->field_maxNoOfPacketsInResponseToCTS.valueof();
}
if (single_value->field_pgnOfMultiPacketMessage.is_bound()) {
ret_val.pgnOfMultiPacketMessage() = single_value->field_pgnOfMultiPacketMessage.valueof();
}
return ret_val;
}

void RequestToSend_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.RequestToSend.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new RequestToSend_template[list_length];
}

RequestToSend_template& RequestToSend_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.RequestToSend.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.RequestToSend.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& RequestToSend_template::ctrl()
{
set_specific();
return single_value->field_ctrl;
}

const OCTETSTRING_template& RequestToSend_template::ctrl() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ctrl of a non-specific template of type @IsobusCMMessageTypes.RequestToSend.");
return single_value->field_ctrl;
}

INTEGER_template& RequestToSend_template::msgSizeInBytes()
{
set_specific();
return single_value->field_msgSizeInBytes;
}

const INTEGER_template& RequestToSend_template::msgSizeInBytes() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field msgSizeInBytes of a non-specific template of type @IsobusCMMessageTypes.RequestToSend.");
return single_value->field_msgSizeInBytes;
}

INTEGER_template& RequestToSend_template::totalNumberOfPackets()
{
set_specific();
return single_value->field_totalNumberOfPackets;
}

const INTEGER_template& RequestToSend_template::totalNumberOfPackets() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field totalNumberOfPackets of a non-specific template of type @IsobusCMMessageTypes.RequestToSend.");
return single_value->field_totalNumberOfPackets;
}

INTEGER_template& RequestToSend_template::maxNoOfPacketsInResponseToCTS()
{
set_specific();
return single_value->field_maxNoOfPacketsInResponseToCTS;
}

const INTEGER_template& RequestToSend_template::maxNoOfPacketsInResponseToCTS() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field maxNoOfPacketsInResponseToCTS of a non-specific template of type @IsobusCMMessageTypes.RequestToSend.");
return single_value->field_maxNoOfPacketsInResponseToCTS;
}

INTEGER_template& RequestToSend_template::pgnOfMultiPacketMessage()
{
set_specific();
return single_value->field_pgnOfMultiPacketMessage;
}

const INTEGER_template& RequestToSend_template::pgnOfMultiPacketMessage() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pgnOfMultiPacketMessage of a non-specific template of type @IsobusCMMessageTypes.RequestToSend.");
return single_value->field_pgnOfMultiPacketMessage;
}

int RequestToSend_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.RequestToSend which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 5;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.RequestToSend containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.RequestToSend containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.RequestToSend containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.RequestToSend containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.RequestToSend containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.RequestToSend.");
  }
  return 0;
}

void RequestToSend_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log();
TTCN_Logger::log_event_str(", msgSizeInBytes := ");
single_value->field_msgSizeInBytes.log();
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
single_value->field_totalNumberOfPackets.log();
TTCN_Logger::log_event_str(", maxNoOfPacketsInResponseToCTS := ");
single_value->field_maxNoOfPacketsInResponseToCTS.log();
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
single_value->field_pgnOfMultiPacketMessage.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void RequestToSend_template::log_match(const RequestToSend& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_ctrl.match(match_value.ctrl(), legacy)){
TTCN_Logger::log_logmatch_info(".ctrl");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_msgSizeInBytes.match(match_value.msgSizeInBytes(), legacy)){
TTCN_Logger::log_logmatch_info(".msgSizeInBytes");
single_value->field_msgSizeInBytes.log_match(match_value.msgSizeInBytes(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_totalNumberOfPackets.match(match_value.totalNumberOfPackets(), legacy)){
TTCN_Logger::log_logmatch_info(".totalNumberOfPackets");
single_value->field_totalNumberOfPackets.log_match(match_value.totalNumberOfPackets(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_maxNoOfPacketsInResponseToCTS.match(match_value.maxNoOfPacketsInResponseToCTS(), legacy)){
TTCN_Logger::log_logmatch_info(".maxNoOfPacketsInResponseToCTS");
single_value->field_maxNoOfPacketsInResponseToCTS.log_match(match_value.maxNoOfPacketsInResponseToCTS(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pgnOfMultiPacketMessage.match(match_value.pgnOfMultiPacketMessage(), legacy)){
TTCN_Logger::log_logmatch_info(".pgnOfMultiPacketMessage");
single_value->field_pgnOfMultiPacketMessage.log_match(match_value.pgnOfMultiPacketMessage(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::log_event_str(", msgSizeInBytes := ");
single_value->field_msgSizeInBytes.log_match(match_value.msgSizeInBytes(), legacy);
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
single_value->field_totalNumberOfPackets.log_match(match_value.totalNumberOfPackets(), legacy);
TTCN_Logger::log_event_str(", maxNoOfPacketsInResponseToCTS := ");
single_value->field_maxNoOfPacketsInResponseToCTS.log_match(match_value.maxNoOfPacketsInResponseToCTS(), legacy);
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
single_value->field_pgnOfMultiPacketMessage.log_match(match_value.pgnOfMultiPacketMessage(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void RequestToSend_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ctrl.encode_text(text_buf);
single_value->field_msgSizeInBytes.encode_text(text_buf);
single_value->field_totalNumberOfPackets.encode_text(text_buf);
single_value->field_maxNoOfPacketsInResponseToCTS.encode_text(text_buf);
single_value->field_pgnOfMultiPacketMessage.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.RequestToSend.");
}
}

void RequestToSend_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_ctrl.decode_text(text_buf);
single_value->field_msgSizeInBytes.decode_text(text_buf);
single_value->field_totalNumberOfPackets.decode_text(text_buf);
single_value->field_maxNoOfPacketsInResponseToCTS.decode_text(text_buf);
single_value->field_pgnOfMultiPacketMessage.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new RequestToSend_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.RequestToSend.");
}
}

void RequestToSend_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    RequestToSend_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (5<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.RequestToSend has 5 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) msgSizeInBytes().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) totalNumberOfPackets().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) maxNoOfPacketsInResponseToCTS().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) pgnOfMultiPacketMessage().set_param(*param.get_elem(4));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "msgSizeInBytes")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          msgSizeInBytes().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "totalNumberOfPackets")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          totalNumberOfPackets().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "maxNoOfPacketsInResponseToCTS")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          maxNoOfPacketsInResponseToCTS().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfMultiPacketMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfMultiPacketMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.RequestToSend: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.RequestToSend");
  }
  is_ifpresent = param.get_ifpresent();
}

void RequestToSend_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_ctrl.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.RequestToSend");
single_value->field_msgSizeInBytes.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.RequestToSend");
single_value->field_totalNumberOfPackets.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.RequestToSend");
single_value->field_maxNoOfPacketsInResponseToCTS.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.RequestToSend");
single_value->field_pgnOfMultiPacketMessage.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.RequestToSend");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.RequestToSend");
}

boolean RequestToSend_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean RequestToSend_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

ClearToSend::ClearToSend()
{
}

ClearToSend::ClearToSend(const OCTETSTRING& par_ctrl,
    const INTEGER& par_totalNumberOfPackets,
    const INTEGER& par_nextPacketNumber,
    const OCTETSTRING& par_reserved4,
    const OCTETSTRING& par_reserved5,
    const INTEGER& par_pgnOfMultiPacketMessage)
  :   field_ctrl(par_ctrl),
  field_totalNumberOfPackets(par_totalNumberOfPackets),
  field_nextPacketNumber(par_nextPacketNumber),
  field_reserved4(par_reserved4),
  field_reserved5(par_reserved5),
  field_pgnOfMultiPacketMessage(par_pgnOfMultiPacketMessage)
{
}

ClearToSend::ClearToSend(const ClearToSend& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.ClearToSend.");
if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
else field_ctrl.clean_up();
if (other_value.totalNumberOfPackets().is_bound()) field_totalNumberOfPackets = other_value.totalNumberOfPackets();
else field_totalNumberOfPackets.clean_up();
if (other_value.nextPacketNumber().is_bound()) field_nextPacketNumber = other_value.nextPacketNumber();
else field_nextPacketNumber.clean_up();
if (other_value.reserved4().is_bound()) field_reserved4 = other_value.reserved4();
else field_reserved4.clean_up();
if (other_value.reserved5().is_bound()) field_reserved5 = other_value.reserved5();
else field_reserved5.clean_up();
if (other_value.pgnOfMultiPacketMessage().is_bound()) field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
else field_pgnOfMultiPacketMessage.clean_up();
}

void ClearToSend::clean_up()
{
field_ctrl.clean_up();
field_totalNumberOfPackets.clean_up();
field_nextPacketNumber.clean_up();
field_reserved4.clean_up();
field_reserved5.clean_up();
field_pgnOfMultiPacketMessage.clean_up();
}

const TTCN_Typedescriptor_t* ClearToSend::get_descriptor() const { return &ClearToSend_descr_; }
ClearToSend& ClearToSend::operator=(const ClearToSend& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.ClearToSend.");
  if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
  else field_ctrl.clean_up();
  if (other_value.totalNumberOfPackets().is_bound()) field_totalNumberOfPackets = other_value.totalNumberOfPackets();
  else field_totalNumberOfPackets.clean_up();
  if (other_value.nextPacketNumber().is_bound()) field_nextPacketNumber = other_value.nextPacketNumber();
  else field_nextPacketNumber.clean_up();
  if (other_value.reserved4().is_bound()) field_reserved4 = other_value.reserved4();
  else field_reserved4.clean_up();
  if (other_value.reserved5().is_bound()) field_reserved5 = other_value.reserved5();
  else field_reserved5.clean_up();
  if (other_value.pgnOfMultiPacketMessage().is_bound()) field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
  else field_pgnOfMultiPacketMessage.clean_up();
}
return *this;
}

boolean ClearToSend::operator==(const ClearToSend& other_value) const
{
return field_ctrl==other_value.field_ctrl
  && field_totalNumberOfPackets==other_value.field_totalNumberOfPackets
  && field_nextPacketNumber==other_value.field_nextPacketNumber
  && field_reserved4==other_value.field_reserved4
  && field_reserved5==other_value.field_reserved5
  && field_pgnOfMultiPacketMessage==other_value.field_pgnOfMultiPacketMessage;
}

boolean ClearToSend::is_bound() const
{
return (field_ctrl.is_bound())
  || (field_totalNumberOfPackets.is_bound())
  || (field_nextPacketNumber.is_bound())
  || (field_reserved4.is_bound())
  || (field_reserved5.is_bound())
  || (field_pgnOfMultiPacketMessage.is_bound());
}
boolean ClearToSend::is_value() const
{
return field_ctrl.is_value()
  && field_totalNumberOfPackets.is_value()
  && field_nextPacketNumber.is_value()
  && field_reserved4.is_value()
  && field_reserved5.is_value()
  && field_pgnOfMultiPacketMessage.is_value();
}
void ClearToSend::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ctrl := ");
field_ctrl.log();
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
field_totalNumberOfPackets.log();
TTCN_Logger::log_event_str(", nextPacketNumber := ");
field_nextPacketNumber.log();
TTCN_Logger::log_event_str(", reserved4 := ");
field_reserved4.log();
TTCN_Logger::log_event_str(", reserved5 := ");
field_reserved5.log();
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
field_pgnOfMultiPacketMessage.log();
TTCN_Logger::log_event_str(" }");
}

void ClearToSend::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (6<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.ClearToSend has 6 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) totalNumberOfPackets().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) nextPacketNumber().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) reserved4().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) reserved5().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) pgnOfMultiPacketMessage().set_param(*param.get_elem(5));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "totalNumberOfPackets")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          totalNumberOfPackets().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "nextPacketNumber")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          nextPacketNumber().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved4")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved4().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved5")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved5().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfMultiPacketMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfMultiPacketMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ClearToSend: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.ClearToSend");
  }
}

void ClearToSend::set_implicit_omit()
{
if (ctrl().is_bound()) ctrl().set_implicit_omit();
if (totalNumberOfPackets().is_bound()) totalNumberOfPackets().set_implicit_omit();
if (nextPacketNumber().is_bound()) nextPacketNumber().set_implicit_omit();
if (reserved4().is_bound()) reserved4().set_implicit_omit();
if (reserved5().is_bound()) reserved5().set_implicit_omit();
if (pgnOfMultiPacketMessage().is_bound()) pgnOfMultiPacketMessage().set_implicit_omit();
}

void ClearToSend::encode_text(Text_Buf& text_buf) const
{
field_ctrl.encode_text(text_buf);
field_totalNumberOfPackets.encode_text(text_buf);
field_nextPacketNumber.encode_text(text_buf);
field_reserved4.encode_text(text_buf);
field_reserved5.encode_text(text_buf);
field_pgnOfMultiPacketMessage.encode_text(text_buf);
}

void ClearToSend::decode_text(Text_Buf& text_buf)
{
field_ctrl.decode_text(text_buf);
field_totalNumberOfPackets.decode_text(text_buf);
field_nextPacketNumber.decode_text(text_buf);
field_reserved4.decode_text(text_buf);
field_reserved5.decode_text(text_buf);
field_pgnOfMultiPacketMessage.decode_text(text_buf);
}

void ClearToSend::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void ClearToSend::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int ClearToSend::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, ClearToSend_ctrl_descr_.raw->forceomit);
  decoded_field_length = field_ctrl.RAW_decode(ClearToSend_ctrl_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, NUMBER__OF__PACKETS_descr_.raw->forceomit);
  decoded_field_length = field_totalNumberOfPackets.RAW_decode(NUMBER__OF__PACKETS_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, General__Types::INT1_descr_.raw->forceomit);
  decoded_field_length = field_nextPacketNumber.RAW_decode(General__Types::INT1_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_3_force_omit(3, force_omit, ClearToSend_reserved4_descr_.raw->forceomit);
  decoded_field_length = field_reserved4.RAW_decode(ClearToSend_reserved4_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_3_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_4_force_omit(4, force_omit, ClearToSend_reserved5_descr_.raw->forceomit);
  decoded_field_length = field_reserved5.RAW_decode(ClearToSend_reserved5_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_4_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_5_force_omit(5, force_omit, IsobusMessageTypes::PGN_descr_.raw->forceomit);
  decoded_field_length = field_pgnOfMultiPacketMessage.RAW_decode(IsobusMessageTypes::PGN_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_5_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int ClearToSend::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 6;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(6);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, ClearToSend_ctrl_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, NUMBER__OF__PACKETS_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, General__Types::INT1_descr_.raw);
  myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 3, ClearToSend_reserved4_descr_.raw);
  myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 4, ClearToSend_reserved5_descr_.raw);
  myleaf.body.node.nodes[5] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 5, IsobusMessageTypes::PGN_descr_.raw);
  encoded_length += field_ctrl.RAW_encode(ClearToSend_ctrl_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_totalNumberOfPackets.RAW_encode(NUMBER__OF__PACKETS_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_nextPacketNumber.RAW_encode(General__Types::INT1_descr_, *myleaf.body.node.nodes[2]);
  encoded_length += field_reserved4.RAW_encode(ClearToSend_reserved4_descr_, *myleaf.body.node.nodes[3]);
  encoded_length += field_reserved5.RAW_encode(ClearToSend_reserved5_descr_, *myleaf.body.node.nodes[4]);
  encoded_length += field_pgnOfMultiPacketMessage.RAW_encode(IsobusMessageTypes::PGN_descr_, *myleaf.body.node.nodes[5]);
  return myleaf.length = encoded_length;
}

struct ClearToSend_template::single_value_struct {
OCTETSTRING_template field_ctrl;
INTEGER_template field_totalNumberOfPackets;
INTEGER_template field_nextPacketNumber;
OCTETSTRING_template field_reserved4;
OCTETSTRING_template field_reserved5;
INTEGER_template field_pgnOfMultiPacketMessage;
};

void ClearToSend_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_ctrl = ANY_VALUE;
single_value->field_totalNumberOfPackets = ANY_VALUE;
single_value->field_nextPacketNumber = ANY_VALUE;
single_value->field_reserved4 = ANY_VALUE;
single_value->field_reserved5 = ANY_VALUE;
single_value->field_pgnOfMultiPacketMessage = ANY_VALUE;
}
}
}

void ClearToSend_template::copy_value(const ClearToSend& other_value)
{
single_value = new single_value_struct;
if (other_value.ctrl().is_bound()) {
  single_value->field_ctrl = other_value.ctrl();
} else {
  single_value->field_ctrl.clean_up();
}
if (other_value.totalNumberOfPackets().is_bound()) {
  single_value->field_totalNumberOfPackets = other_value.totalNumberOfPackets();
} else {
  single_value->field_totalNumberOfPackets.clean_up();
}
if (other_value.nextPacketNumber().is_bound()) {
  single_value->field_nextPacketNumber = other_value.nextPacketNumber();
} else {
  single_value->field_nextPacketNumber.clean_up();
}
if (other_value.reserved4().is_bound()) {
  single_value->field_reserved4 = other_value.reserved4();
} else {
  single_value->field_reserved4.clean_up();
}
if (other_value.reserved5().is_bound()) {
  single_value->field_reserved5 = other_value.reserved5();
} else {
  single_value->field_reserved5.clean_up();
}
if (other_value.pgnOfMultiPacketMessage().is_bound()) {
  single_value->field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
} else {
  single_value->field_pgnOfMultiPacketMessage.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void ClearToSend_template::copy_template(const ClearToSend_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ctrl().get_selection()) {
single_value->field_ctrl = other_value.ctrl();
} else {
single_value->field_ctrl.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.totalNumberOfPackets().get_selection()) {
single_value->field_totalNumberOfPackets = other_value.totalNumberOfPackets();
} else {
single_value->field_totalNumberOfPackets.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.nextPacketNumber().get_selection()) {
single_value->field_nextPacketNumber = other_value.nextPacketNumber();
} else {
single_value->field_nextPacketNumber.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.reserved4().get_selection()) {
single_value->field_reserved4 = other_value.reserved4();
} else {
single_value->field_reserved4.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.reserved5().get_selection()) {
single_value->field_reserved5 = other_value.reserved5();
} else {
single_value->field_reserved5.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pgnOfMultiPacketMessage().get_selection()) {
single_value->field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
} else {
single_value->field_pgnOfMultiPacketMessage.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new ClearToSend_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.ClearToSend.");
break;
}
set_selection(other_value);
}

ClearToSend_template::ClearToSend_template()
{
}

ClearToSend_template::ClearToSend_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

ClearToSend_template::ClearToSend_template(const ClearToSend& other_value)
{
copy_value(other_value);
}

ClearToSend_template::ClearToSend_template(const OPTIONAL<ClearToSend>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ClearToSend&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.ClearToSend from an unbound optional field.");
}
}

ClearToSend_template::ClearToSend_template(const ClearToSend_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

ClearToSend_template::~ClearToSend_template()
{
clean_up();
}

ClearToSend_template& ClearToSend_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

ClearToSend_template& ClearToSend_template::operator=(const ClearToSend& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

ClearToSend_template& ClearToSend_template::operator=(const OPTIONAL<ClearToSend>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ClearToSend&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.ClearToSend.");
}
return *this;
}

ClearToSend_template& ClearToSend_template::operator=(const ClearToSend_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean ClearToSend_template::match(const ClearToSend& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.ctrl().is_bound()) return FALSE;
if(!single_value->field_ctrl.match(other_value.ctrl(), legacy))return FALSE;
if(!other_value.totalNumberOfPackets().is_bound()) return FALSE;
if(!single_value->field_totalNumberOfPackets.match(other_value.totalNumberOfPackets(), legacy))return FALSE;
if(!other_value.nextPacketNumber().is_bound()) return FALSE;
if(!single_value->field_nextPacketNumber.match(other_value.nextPacketNumber(), legacy))return FALSE;
if(!other_value.reserved4().is_bound()) return FALSE;
if(!single_value->field_reserved4.match(other_value.reserved4(), legacy))return FALSE;
if(!other_value.reserved5().is_bound()) return FALSE;
if(!single_value->field_reserved5.match(other_value.reserved5(), legacy))return FALSE;
if(!other_value.pgnOfMultiPacketMessage().is_bound()) return FALSE;
if(!single_value->field_pgnOfMultiPacketMessage.match(other_value.pgnOfMultiPacketMessage(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.ClearToSend.");
}
return FALSE;
}

boolean ClearToSend_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_ctrl.is_bound()

 ||single_value->field_totalNumberOfPackets.is_bound()

 ||single_value->field_nextPacketNumber.is_bound()

 ||single_value->field_reserved4.is_bound()

 ||single_value->field_reserved5.is_bound()

 ||single_value->field_pgnOfMultiPacketMessage.is_bound()
;
}

boolean ClearToSend_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ctrl.is_value()
 &&single_value->field_totalNumberOfPackets.is_value()
 &&single_value->field_nextPacketNumber.is_value()
 &&single_value->field_reserved4.is_value()
 &&single_value->field_reserved5.is_value()
 &&single_value->field_pgnOfMultiPacketMessage.is_value();
}

void ClearToSend_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

ClearToSend ClearToSend_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.ClearToSend.");
ClearToSend ret_val;
if (single_value->field_ctrl.is_bound()) {
ret_val.ctrl() = single_value->field_ctrl.valueof();
}
if (single_value->field_totalNumberOfPackets.is_bound()) {
ret_val.totalNumberOfPackets() = single_value->field_totalNumberOfPackets.valueof();
}
if (single_value->field_nextPacketNumber.is_bound()) {
ret_val.nextPacketNumber() = single_value->field_nextPacketNumber.valueof();
}
if (single_value->field_reserved4.is_bound()) {
ret_val.reserved4() = single_value->field_reserved4.valueof();
}
if (single_value->field_reserved5.is_bound()) {
ret_val.reserved5() = single_value->field_reserved5.valueof();
}
if (single_value->field_pgnOfMultiPacketMessage.is_bound()) {
ret_val.pgnOfMultiPacketMessage() = single_value->field_pgnOfMultiPacketMessage.valueof();
}
return ret_val;
}

void ClearToSend_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.ClearToSend.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new ClearToSend_template[list_length];
}

ClearToSend_template& ClearToSend_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.ClearToSend.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.ClearToSend.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& ClearToSend_template::ctrl()
{
set_specific();
return single_value->field_ctrl;
}

const OCTETSTRING_template& ClearToSend_template::ctrl() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ctrl of a non-specific template of type @IsobusCMMessageTypes.ClearToSend.");
return single_value->field_ctrl;
}

INTEGER_template& ClearToSend_template::totalNumberOfPackets()
{
set_specific();
return single_value->field_totalNumberOfPackets;
}

const INTEGER_template& ClearToSend_template::totalNumberOfPackets() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field totalNumberOfPackets of a non-specific template of type @IsobusCMMessageTypes.ClearToSend.");
return single_value->field_totalNumberOfPackets;
}

INTEGER_template& ClearToSend_template::nextPacketNumber()
{
set_specific();
return single_value->field_nextPacketNumber;
}

const INTEGER_template& ClearToSend_template::nextPacketNumber() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field nextPacketNumber of a non-specific template of type @IsobusCMMessageTypes.ClearToSend.");
return single_value->field_nextPacketNumber;
}

OCTETSTRING_template& ClearToSend_template::reserved4()
{
set_specific();
return single_value->field_reserved4;
}

const OCTETSTRING_template& ClearToSend_template::reserved4() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field reserved4 of a non-specific template of type @IsobusCMMessageTypes.ClearToSend.");
return single_value->field_reserved4;
}

OCTETSTRING_template& ClearToSend_template::reserved5()
{
set_specific();
return single_value->field_reserved5;
}

const OCTETSTRING_template& ClearToSend_template::reserved5() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field reserved5 of a non-specific template of type @IsobusCMMessageTypes.ClearToSend.");
return single_value->field_reserved5;
}

INTEGER_template& ClearToSend_template::pgnOfMultiPacketMessage()
{
set_specific();
return single_value->field_pgnOfMultiPacketMessage;
}

const INTEGER_template& ClearToSend_template::pgnOfMultiPacketMessage() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pgnOfMultiPacketMessage of a non-specific template of type @IsobusCMMessageTypes.ClearToSend.");
return single_value->field_pgnOfMultiPacketMessage;
}

int ClearToSend_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ClearToSend which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 6;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ClearToSend containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ClearToSend containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ClearToSend containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ClearToSend containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ClearToSend containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.ClearToSend.");
  }
  return 0;
}

void ClearToSend_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log();
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
single_value->field_totalNumberOfPackets.log();
TTCN_Logger::log_event_str(", nextPacketNumber := ");
single_value->field_nextPacketNumber.log();
TTCN_Logger::log_event_str(", reserved4 := ");
single_value->field_reserved4.log();
TTCN_Logger::log_event_str(", reserved5 := ");
single_value->field_reserved5.log();
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
single_value->field_pgnOfMultiPacketMessage.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void ClearToSend_template::log_match(const ClearToSend& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_ctrl.match(match_value.ctrl(), legacy)){
TTCN_Logger::log_logmatch_info(".ctrl");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_totalNumberOfPackets.match(match_value.totalNumberOfPackets(), legacy)){
TTCN_Logger::log_logmatch_info(".totalNumberOfPackets");
single_value->field_totalNumberOfPackets.log_match(match_value.totalNumberOfPackets(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_nextPacketNumber.match(match_value.nextPacketNumber(), legacy)){
TTCN_Logger::log_logmatch_info(".nextPacketNumber");
single_value->field_nextPacketNumber.log_match(match_value.nextPacketNumber(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_reserved4.match(match_value.reserved4(), legacy)){
TTCN_Logger::log_logmatch_info(".reserved4");
single_value->field_reserved4.log_match(match_value.reserved4(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_reserved5.match(match_value.reserved5(), legacy)){
TTCN_Logger::log_logmatch_info(".reserved5");
single_value->field_reserved5.log_match(match_value.reserved5(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pgnOfMultiPacketMessage.match(match_value.pgnOfMultiPacketMessage(), legacy)){
TTCN_Logger::log_logmatch_info(".pgnOfMultiPacketMessage");
single_value->field_pgnOfMultiPacketMessage.log_match(match_value.pgnOfMultiPacketMessage(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
single_value->field_totalNumberOfPackets.log_match(match_value.totalNumberOfPackets(), legacy);
TTCN_Logger::log_event_str(", nextPacketNumber := ");
single_value->field_nextPacketNumber.log_match(match_value.nextPacketNumber(), legacy);
TTCN_Logger::log_event_str(", reserved4 := ");
single_value->field_reserved4.log_match(match_value.reserved4(), legacy);
TTCN_Logger::log_event_str(", reserved5 := ");
single_value->field_reserved5.log_match(match_value.reserved5(), legacy);
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
single_value->field_pgnOfMultiPacketMessage.log_match(match_value.pgnOfMultiPacketMessage(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void ClearToSend_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ctrl.encode_text(text_buf);
single_value->field_totalNumberOfPackets.encode_text(text_buf);
single_value->field_nextPacketNumber.encode_text(text_buf);
single_value->field_reserved4.encode_text(text_buf);
single_value->field_reserved5.encode_text(text_buf);
single_value->field_pgnOfMultiPacketMessage.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.ClearToSend.");
}
}

void ClearToSend_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_ctrl.decode_text(text_buf);
single_value->field_totalNumberOfPackets.decode_text(text_buf);
single_value->field_nextPacketNumber.decode_text(text_buf);
single_value->field_reserved4.decode_text(text_buf);
single_value->field_reserved5.decode_text(text_buf);
single_value->field_pgnOfMultiPacketMessage.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new ClearToSend_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.ClearToSend.");
}
}

void ClearToSend_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    ClearToSend_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (6<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.ClearToSend has 6 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) totalNumberOfPackets().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) nextPacketNumber().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) reserved4().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) reserved5().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) pgnOfMultiPacketMessage().set_param(*param.get_elem(5));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "totalNumberOfPackets")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          totalNumberOfPackets().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "nextPacketNumber")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          nextPacketNumber().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved4")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved4().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved5")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved5().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfMultiPacketMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfMultiPacketMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ClearToSend: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.ClearToSend");
  }
  is_ifpresent = param.get_ifpresent();
}

void ClearToSend_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_ctrl.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ClearToSend");
single_value->field_totalNumberOfPackets.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ClearToSend");
single_value->field_nextPacketNumber.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ClearToSend");
single_value->field_reserved4.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ClearToSend");
single_value->field_reserved5.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ClearToSend");
single_value->field_pgnOfMultiPacketMessage.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ClearToSend");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.ClearToSend");
}

boolean ClearToSend_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean ClearToSend_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

EndOfMessageAcknowledgement::EndOfMessageAcknowledgement()
{
}

EndOfMessageAcknowledgement::EndOfMessageAcknowledgement(const OCTETSTRING& par_ctrl,
    const INTEGER& par_msgSizeInByte,
    const INTEGER& par_totalNumberOfPackets,
    const OCTETSTRING& par_reserved5,
    const INTEGER& par_pgnOfMultiPacketMessage)
  :   field_ctrl(par_ctrl),
  field_msgSizeInByte(par_msgSizeInByte),
  field_totalNumberOfPackets(par_totalNumberOfPackets),
  field_reserved5(par_reserved5),
  field_pgnOfMultiPacketMessage(par_pgnOfMultiPacketMessage)
{
}

EndOfMessageAcknowledgement::EndOfMessageAcknowledgement(const EndOfMessageAcknowledgement& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
else field_ctrl.clean_up();
if (other_value.msgSizeInByte().is_bound()) field_msgSizeInByte = other_value.msgSizeInByte();
else field_msgSizeInByte.clean_up();
if (other_value.totalNumberOfPackets().is_bound()) field_totalNumberOfPackets = other_value.totalNumberOfPackets();
else field_totalNumberOfPackets.clean_up();
if (other_value.reserved5().is_bound()) field_reserved5 = other_value.reserved5();
else field_reserved5.clean_up();
if (other_value.pgnOfMultiPacketMessage().is_bound()) field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
else field_pgnOfMultiPacketMessage.clean_up();
}

void EndOfMessageAcknowledgement::clean_up()
{
field_ctrl.clean_up();
field_msgSizeInByte.clean_up();
field_totalNumberOfPackets.clean_up();
field_reserved5.clean_up();
field_pgnOfMultiPacketMessage.clean_up();
}

const TTCN_Typedescriptor_t* EndOfMessageAcknowledgement::get_descriptor() const { return &EndOfMessageAcknowledgement_descr_; }
EndOfMessageAcknowledgement& EndOfMessageAcknowledgement::operator=(const EndOfMessageAcknowledgement& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
  if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
  else field_ctrl.clean_up();
  if (other_value.msgSizeInByte().is_bound()) field_msgSizeInByte = other_value.msgSizeInByte();
  else field_msgSizeInByte.clean_up();
  if (other_value.totalNumberOfPackets().is_bound()) field_totalNumberOfPackets = other_value.totalNumberOfPackets();
  else field_totalNumberOfPackets.clean_up();
  if (other_value.reserved5().is_bound()) field_reserved5 = other_value.reserved5();
  else field_reserved5.clean_up();
  if (other_value.pgnOfMultiPacketMessage().is_bound()) field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
  else field_pgnOfMultiPacketMessage.clean_up();
}
return *this;
}

boolean EndOfMessageAcknowledgement::operator==(const EndOfMessageAcknowledgement& other_value) const
{
return field_ctrl==other_value.field_ctrl
  && field_msgSizeInByte==other_value.field_msgSizeInByte
  && field_totalNumberOfPackets==other_value.field_totalNumberOfPackets
  && field_reserved5==other_value.field_reserved5
  && field_pgnOfMultiPacketMessage==other_value.field_pgnOfMultiPacketMessage;
}

boolean EndOfMessageAcknowledgement::is_bound() const
{
return (field_ctrl.is_bound())
  || (field_msgSizeInByte.is_bound())
  || (field_totalNumberOfPackets.is_bound())
  || (field_reserved5.is_bound())
  || (field_pgnOfMultiPacketMessage.is_bound());
}
boolean EndOfMessageAcknowledgement::is_value() const
{
return field_ctrl.is_value()
  && field_msgSizeInByte.is_value()
  && field_totalNumberOfPackets.is_value()
  && field_reserved5.is_value()
  && field_pgnOfMultiPacketMessage.is_value();
}
void EndOfMessageAcknowledgement::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ctrl := ");
field_ctrl.log();
TTCN_Logger::log_event_str(", msgSizeInByte := ");
field_msgSizeInByte.log();
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
field_totalNumberOfPackets.log();
TTCN_Logger::log_event_str(", reserved5 := ");
field_reserved5.log();
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
field_pgnOfMultiPacketMessage.log();
TTCN_Logger::log_event_str(" }");
}

void EndOfMessageAcknowledgement::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (5<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement has 5 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) msgSizeInByte().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) totalNumberOfPackets().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) reserved5().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) pgnOfMultiPacketMessage().set_param(*param.get_elem(4));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "msgSizeInByte")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          msgSizeInByte().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "totalNumberOfPackets")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          totalNumberOfPackets().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved5")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved5().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfMultiPacketMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfMultiPacketMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.EndOfMessageAcknowledgement: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.EndOfMessageAcknowledgement");
  }
}

void EndOfMessageAcknowledgement::set_implicit_omit()
{
if (ctrl().is_bound()) ctrl().set_implicit_omit();
if (msgSizeInByte().is_bound()) msgSizeInByte().set_implicit_omit();
if (totalNumberOfPackets().is_bound()) totalNumberOfPackets().set_implicit_omit();
if (reserved5().is_bound()) reserved5().set_implicit_omit();
if (pgnOfMultiPacketMessage().is_bound()) pgnOfMultiPacketMessage().set_implicit_omit();
}

void EndOfMessageAcknowledgement::encode_text(Text_Buf& text_buf) const
{
field_ctrl.encode_text(text_buf);
field_msgSizeInByte.encode_text(text_buf);
field_totalNumberOfPackets.encode_text(text_buf);
field_reserved5.encode_text(text_buf);
field_pgnOfMultiPacketMessage.encode_text(text_buf);
}

void EndOfMessageAcknowledgement::decode_text(Text_Buf& text_buf)
{
field_ctrl.decode_text(text_buf);
field_msgSizeInByte.decode_text(text_buf);
field_totalNumberOfPackets.decode_text(text_buf);
field_reserved5.decode_text(text_buf);
field_pgnOfMultiPacketMessage.decode_text(text_buf);
}

void EndOfMessageAcknowledgement::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void EndOfMessageAcknowledgement::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int EndOfMessageAcknowledgement::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, EndOfMessageAcknowledgement_ctrl_descr_.raw->forceomit);
  decoded_field_length = field_ctrl.RAW_decode(EndOfMessageAcknowledgement_ctrl_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, IsobusMessageTypes::INT2_descr_.raw->forceomit);
  decoded_field_length = field_msgSizeInByte.RAW_decode(IsobusMessageTypes::INT2_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, NUMBER__OF__PACKETS_descr_.raw->forceomit);
  decoded_field_length = field_totalNumberOfPackets.RAW_decode(NUMBER__OF__PACKETS_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_3_force_omit(3, force_omit, EndOfMessageAcknowledgement_reserved5_descr_.raw->forceomit);
  decoded_field_length = field_reserved5.RAW_decode(EndOfMessageAcknowledgement_reserved5_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_3_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_4_force_omit(4, force_omit, IsobusMessageTypes::PGN_descr_.raw->forceomit);
  decoded_field_length = field_pgnOfMultiPacketMessage.RAW_decode(IsobusMessageTypes::PGN_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_4_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int EndOfMessageAcknowledgement::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 5;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(5);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, EndOfMessageAcknowledgement_ctrl_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, IsobusMessageTypes::INT2_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, NUMBER__OF__PACKETS_descr_.raw);
  myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 3, EndOfMessageAcknowledgement_reserved5_descr_.raw);
  myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 4, IsobusMessageTypes::PGN_descr_.raw);
  encoded_length += field_ctrl.RAW_encode(EndOfMessageAcknowledgement_ctrl_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_msgSizeInByte.RAW_encode(IsobusMessageTypes::INT2_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_totalNumberOfPackets.RAW_encode(NUMBER__OF__PACKETS_descr_, *myleaf.body.node.nodes[2]);
  encoded_length += field_reserved5.RAW_encode(EndOfMessageAcknowledgement_reserved5_descr_, *myleaf.body.node.nodes[3]);
  encoded_length += field_pgnOfMultiPacketMessage.RAW_encode(IsobusMessageTypes::PGN_descr_, *myleaf.body.node.nodes[4]);
  return myleaf.length = encoded_length;
}

struct EndOfMessageAcknowledgement_template::single_value_struct {
OCTETSTRING_template field_ctrl;
INTEGER_template field_msgSizeInByte;
INTEGER_template field_totalNumberOfPackets;
OCTETSTRING_template field_reserved5;
INTEGER_template field_pgnOfMultiPacketMessage;
};

void EndOfMessageAcknowledgement_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_ctrl = ANY_VALUE;
single_value->field_msgSizeInByte = ANY_VALUE;
single_value->field_totalNumberOfPackets = ANY_VALUE;
single_value->field_reserved5 = ANY_VALUE;
single_value->field_pgnOfMultiPacketMessage = ANY_VALUE;
}
}
}

void EndOfMessageAcknowledgement_template::copy_value(const EndOfMessageAcknowledgement& other_value)
{
single_value = new single_value_struct;
if (other_value.ctrl().is_bound()) {
  single_value->field_ctrl = other_value.ctrl();
} else {
  single_value->field_ctrl.clean_up();
}
if (other_value.msgSizeInByte().is_bound()) {
  single_value->field_msgSizeInByte = other_value.msgSizeInByte();
} else {
  single_value->field_msgSizeInByte.clean_up();
}
if (other_value.totalNumberOfPackets().is_bound()) {
  single_value->field_totalNumberOfPackets = other_value.totalNumberOfPackets();
} else {
  single_value->field_totalNumberOfPackets.clean_up();
}
if (other_value.reserved5().is_bound()) {
  single_value->field_reserved5 = other_value.reserved5();
} else {
  single_value->field_reserved5.clean_up();
}
if (other_value.pgnOfMultiPacketMessage().is_bound()) {
  single_value->field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
} else {
  single_value->field_pgnOfMultiPacketMessage.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void EndOfMessageAcknowledgement_template::copy_template(const EndOfMessageAcknowledgement_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ctrl().get_selection()) {
single_value->field_ctrl = other_value.ctrl();
} else {
single_value->field_ctrl.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.msgSizeInByte().get_selection()) {
single_value->field_msgSizeInByte = other_value.msgSizeInByte();
} else {
single_value->field_msgSizeInByte.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.totalNumberOfPackets().get_selection()) {
single_value->field_totalNumberOfPackets = other_value.totalNumberOfPackets();
} else {
single_value->field_totalNumberOfPackets.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.reserved5().get_selection()) {
single_value->field_reserved5 = other_value.reserved5();
} else {
single_value->field_reserved5.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pgnOfMultiPacketMessage().get_selection()) {
single_value->field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
} else {
single_value->field_pgnOfMultiPacketMessage.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new EndOfMessageAcknowledgement_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
break;
}
set_selection(other_value);
}

EndOfMessageAcknowledgement_template::EndOfMessageAcknowledgement_template()
{
}

EndOfMessageAcknowledgement_template::EndOfMessageAcknowledgement_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

EndOfMessageAcknowledgement_template::EndOfMessageAcknowledgement_template(const EndOfMessageAcknowledgement& other_value)
{
copy_value(other_value);
}

EndOfMessageAcknowledgement_template::EndOfMessageAcknowledgement_template(const OPTIONAL<EndOfMessageAcknowledgement>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const EndOfMessageAcknowledgement&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement from an unbound optional field.");
}
}

EndOfMessageAcknowledgement_template::EndOfMessageAcknowledgement_template(const EndOfMessageAcknowledgement_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

EndOfMessageAcknowledgement_template::~EndOfMessageAcknowledgement_template()
{
clean_up();
}

EndOfMessageAcknowledgement_template& EndOfMessageAcknowledgement_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

EndOfMessageAcknowledgement_template& EndOfMessageAcknowledgement_template::operator=(const EndOfMessageAcknowledgement& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

EndOfMessageAcknowledgement_template& EndOfMessageAcknowledgement_template::operator=(const OPTIONAL<EndOfMessageAcknowledgement>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const EndOfMessageAcknowledgement&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
}
return *this;
}

EndOfMessageAcknowledgement_template& EndOfMessageAcknowledgement_template::operator=(const EndOfMessageAcknowledgement_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean EndOfMessageAcknowledgement_template::match(const EndOfMessageAcknowledgement& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.ctrl().is_bound()) return FALSE;
if(!single_value->field_ctrl.match(other_value.ctrl(), legacy))return FALSE;
if(!other_value.msgSizeInByte().is_bound()) return FALSE;
if(!single_value->field_msgSizeInByte.match(other_value.msgSizeInByte(), legacy))return FALSE;
if(!other_value.totalNumberOfPackets().is_bound()) return FALSE;
if(!single_value->field_totalNumberOfPackets.match(other_value.totalNumberOfPackets(), legacy))return FALSE;
if(!other_value.reserved5().is_bound()) return FALSE;
if(!single_value->field_reserved5.match(other_value.reserved5(), legacy))return FALSE;
if(!other_value.pgnOfMultiPacketMessage().is_bound()) return FALSE;
if(!single_value->field_pgnOfMultiPacketMessage.match(other_value.pgnOfMultiPacketMessage(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
}
return FALSE;
}

boolean EndOfMessageAcknowledgement_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_ctrl.is_bound()

 ||single_value->field_msgSizeInByte.is_bound()

 ||single_value->field_totalNumberOfPackets.is_bound()

 ||single_value->field_reserved5.is_bound()

 ||single_value->field_pgnOfMultiPacketMessage.is_bound()
;
}

boolean EndOfMessageAcknowledgement_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ctrl.is_value()
 &&single_value->field_msgSizeInByte.is_value()
 &&single_value->field_totalNumberOfPackets.is_value()
 &&single_value->field_reserved5.is_value()
 &&single_value->field_pgnOfMultiPacketMessage.is_value();
}

void EndOfMessageAcknowledgement_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

EndOfMessageAcknowledgement EndOfMessageAcknowledgement_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
EndOfMessageAcknowledgement ret_val;
if (single_value->field_ctrl.is_bound()) {
ret_val.ctrl() = single_value->field_ctrl.valueof();
}
if (single_value->field_msgSizeInByte.is_bound()) {
ret_val.msgSizeInByte() = single_value->field_msgSizeInByte.valueof();
}
if (single_value->field_totalNumberOfPackets.is_bound()) {
ret_val.totalNumberOfPackets() = single_value->field_totalNumberOfPackets.valueof();
}
if (single_value->field_reserved5.is_bound()) {
ret_val.reserved5() = single_value->field_reserved5.valueof();
}
if (single_value->field_pgnOfMultiPacketMessage.is_bound()) {
ret_val.pgnOfMultiPacketMessage() = single_value->field_pgnOfMultiPacketMessage.valueof();
}
return ret_val;
}

void EndOfMessageAcknowledgement_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new EndOfMessageAcknowledgement_template[list_length];
}

EndOfMessageAcknowledgement_template& EndOfMessageAcknowledgement_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& EndOfMessageAcknowledgement_template::ctrl()
{
set_specific();
return single_value->field_ctrl;
}

const OCTETSTRING_template& EndOfMessageAcknowledgement_template::ctrl() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ctrl of a non-specific template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
return single_value->field_ctrl;
}

INTEGER_template& EndOfMessageAcknowledgement_template::msgSizeInByte()
{
set_specific();
return single_value->field_msgSizeInByte;
}

const INTEGER_template& EndOfMessageAcknowledgement_template::msgSizeInByte() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field msgSizeInByte of a non-specific template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
return single_value->field_msgSizeInByte;
}

INTEGER_template& EndOfMessageAcknowledgement_template::totalNumberOfPackets()
{
set_specific();
return single_value->field_totalNumberOfPackets;
}

const INTEGER_template& EndOfMessageAcknowledgement_template::totalNumberOfPackets() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field totalNumberOfPackets of a non-specific template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
return single_value->field_totalNumberOfPackets;
}

OCTETSTRING_template& EndOfMessageAcknowledgement_template::reserved5()
{
set_specific();
return single_value->field_reserved5;
}

const OCTETSTRING_template& EndOfMessageAcknowledgement_template::reserved5() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field reserved5 of a non-specific template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
return single_value->field_reserved5;
}

INTEGER_template& EndOfMessageAcknowledgement_template::pgnOfMultiPacketMessage()
{
set_specific();
return single_value->field_pgnOfMultiPacketMessage;
}

const INTEGER_template& EndOfMessageAcknowledgement_template::pgnOfMultiPacketMessage() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pgnOfMultiPacketMessage of a non-specific template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
return single_value->field_pgnOfMultiPacketMessage;
}

int EndOfMessageAcknowledgement_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 5;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
  }
  return 0;
}

void EndOfMessageAcknowledgement_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log();
TTCN_Logger::log_event_str(", msgSizeInByte := ");
single_value->field_msgSizeInByte.log();
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
single_value->field_totalNumberOfPackets.log();
TTCN_Logger::log_event_str(", reserved5 := ");
single_value->field_reserved5.log();
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
single_value->field_pgnOfMultiPacketMessage.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void EndOfMessageAcknowledgement_template::log_match(const EndOfMessageAcknowledgement& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_ctrl.match(match_value.ctrl(), legacy)){
TTCN_Logger::log_logmatch_info(".ctrl");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_msgSizeInByte.match(match_value.msgSizeInByte(), legacy)){
TTCN_Logger::log_logmatch_info(".msgSizeInByte");
single_value->field_msgSizeInByte.log_match(match_value.msgSizeInByte(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_totalNumberOfPackets.match(match_value.totalNumberOfPackets(), legacy)){
TTCN_Logger::log_logmatch_info(".totalNumberOfPackets");
single_value->field_totalNumberOfPackets.log_match(match_value.totalNumberOfPackets(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_reserved5.match(match_value.reserved5(), legacy)){
TTCN_Logger::log_logmatch_info(".reserved5");
single_value->field_reserved5.log_match(match_value.reserved5(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pgnOfMultiPacketMessage.match(match_value.pgnOfMultiPacketMessage(), legacy)){
TTCN_Logger::log_logmatch_info(".pgnOfMultiPacketMessage");
single_value->field_pgnOfMultiPacketMessage.log_match(match_value.pgnOfMultiPacketMessage(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::log_event_str(", msgSizeInByte := ");
single_value->field_msgSizeInByte.log_match(match_value.msgSizeInByte(), legacy);
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
single_value->field_totalNumberOfPackets.log_match(match_value.totalNumberOfPackets(), legacy);
TTCN_Logger::log_event_str(", reserved5 := ");
single_value->field_reserved5.log_match(match_value.reserved5(), legacy);
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
single_value->field_pgnOfMultiPacketMessage.log_match(match_value.pgnOfMultiPacketMessage(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void EndOfMessageAcknowledgement_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ctrl.encode_text(text_buf);
single_value->field_msgSizeInByte.encode_text(text_buf);
single_value->field_totalNumberOfPackets.encode_text(text_buf);
single_value->field_reserved5.encode_text(text_buf);
single_value->field_pgnOfMultiPacketMessage.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
}
}

void EndOfMessageAcknowledgement_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_ctrl.decode_text(text_buf);
single_value->field_msgSizeInByte.decode_text(text_buf);
single_value->field_totalNumberOfPackets.decode_text(text_buf);
single_value->field_reserved5.decode_text(text_buf);
single_value->field_pgnOfMultiPacketMessage.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new EndOfMessageAcknowledgement_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement.");
}
}

void EndOfMessageAcknowledgement_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    EndOfMessageAcknowledgement_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (5<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.EndOfMessageAcknowledgement has 5 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) msgSizeInByte().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) totalNumberOfPackets().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) reserved5().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) pgnOfMultiPacketMessage().set_param(*param.get_elem(4));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "msgSizeInByte")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          msgSizeInByte().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "totalNumberOfPackets")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          totalNumberOfPackets().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved5")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved5().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfMultiPacketMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfMultiPacketMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.EndOfMessageAcknowledgement: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.EndOfMessageAcknowledgement");
  }
  is_ifpresent = param.get_ifpresent();
}

void EndOfMessageAcknowledgement_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_ctrl.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.EndOfMessageAcknowledgement");
single_value->field_msgSizeInByte.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.EndOfMessageAcknowledgement");
single_value->field_totalNumberOfPackets.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.EndOfMessageAcknowledgement");
single_value->field_reserved5.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.EndOfMessageAcknowledgement");
single_value->field_pgnOfMultiPacketMessage.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.EndOfMessageAcknowledgement");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.EndOfMessageAcknowledgement");
}

boolean EndOfMessageAcknowledgement_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean EndOfMessageAcknowledgement_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

e__ConnectionAbort__AbortReason::e__ConnectionAbort__AbortReason()
{
enum_value = UNBOUND_VALUE;
}

e__ConnectionAbort__AbortReason::e__ConnectionAbort__AbortReason(int other_value)
{
if (!is_valid_enum(other_value)) TTCN_error("Initializing a variable of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason with invalid numeric value %d.", other_value);
enum_value = (enum_type)other_value;
}

e__ConnectionAbort__AbortReason::e__ConnectionAbort__AbortReason(enum_type other_value)
{
enum_value = other_value;
}

e__ConnectionAbort__AbortReason::e__ConnectionAbort__AbortReason(const e__ConnectionAbort__AbortReason& other_value)
: Base_Type()
{
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("Copying an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
enum_value = other_value.enum_value;
}

e__ConnectionAbort__AbortReason& e__ConnectionAbort__AbortReason::operator=(int other_value)
{
if (!is_valid_enum(other_value)) TTCN_error("Assigning unknown numeric value %d to a variable of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.", other_value);
enum_value = (enum_type)other_value;
return *this;
}

e__ConnectionAbort__AbortReason& e__ConnectionAbort__AbortReason::operator=(enum_type other_value)
{
enum_value = other_value;
return *this;
}

e__ConnectionAbort__AbortReason& e__ConnectionAbort__AbortReason::operator=(const e__ConnectionAbort__AbortReason& other_value)
{
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("Assignment of an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
enum_value = other_value.enum_value;
return *this;
}

boolean e__ConnectionAbort__AbortReason::operator==(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
return enum_value == other_value;
}

boolean e__ConnectionAbort__AbortReason::operator==(const e__ConnectionAbort__AbortReason& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
return enum_value == other_value.enum_value;
}

boolean e__ConnectionAbort__AbortReason::operator<(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
return enum_value < other_value;
}

boolean e__ConnectionAbort__AbortReason::operator<(const e__ConnectionAbort__AbortReason& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
return enum_value < other_value.enum_value;
}

boolean e__ConnectionAbort__AbortReason::operator>(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
return enum_value > other_value;
}

boolean e__ConnectionAbort__AbortReason::operator>(const e__ConnectionAbort__AbortReason& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
return enum_value > other_value.enum_value;
}

const char *e__ConnectionAbort__AbortReason::enum_to_str(enum_type enum_par)
{
switch (enum_par) {
case alreadyInOneOrMoreConnectionManagedSessionsAndCannotSupportAnother: return "alreadyInOneOrMoreConnectionManagedSessionsAndCannotSupportAnother";
case systemResourcesWereNeededForAnotherTaskSoThisConnectionManagedSessionWasTerminated: return "systemResourcesWereNeededForAnotherTaskSoThisConnectionManagedSessionWasTerminated";
case aTimeoutOccurredAndThisIsTheConnectionAbortToCloseTheSession: return "aTimeoutOccurredAndThisIsTheConnectionAbortToCloseTheSession";
case cts__MessagesReceivedWhenDataTransferIsInProgress: return "cts_MessagesReceivedWhenDataTransferIsInProgress";
case maximumRetransmitRequestLimitReached: return "maximumRetransmitRequestLimitReached";
case unexpectedDataTransferPacket: return "unexpectedDataTransferPacket";
case badSequenceNumber: return "badSequenceNumber";
case duplicateSequenceNumber: return "duplicateSequenceNumber";
case iso__11783__7__error__code__251: return "iso_11783_7_error_code_251";
case iso__11783__7__error__code__252: return "iso_11783_7_error_code_252";
case iso__11783__7__error__code__253: return "iso_11783_7_error_code_253";
case iso__11783__7__error__code__254: return "iso_11783_7_error_code_254";
case iso__11783__7__error__code__255: return "iso_11783_7_error_code_255";
default: return "<unknown>";
}
}

e__ConnectionAbort__AbortReason::enum_type e__ConnectionAbort__AbortReason::str_to_enum(const char *str_par)
{
if (!strcmp(str_par, "alreadyInOneOrMoreConnectionManagedSessionsAndCannotSupportAnother")) return alreadyInOneOrMoreConnectionManagedSessionsAndCannotSupportAnother;
else if (!strcmp(str_par, "systemResourcesWereNeededForAnotherTaskSoThisConnectionManagedSessionWasTerminated")) return systemResourcesWereNeededForAnotherTaskSoThisConnectionManagedSessionWasTerminated;
else if (!strcmp(str_par, "aTimeoutOccurredAndThisIsTheConnectionAbortToCloseTheSession")) return aTimeoutOccurredAndThisIsTheConnectionAbortToCloseTheSession;
else if (!strcmp(str_par, "cts_MessagesReceivedWhenDataTransferIsInProgress")) return cts__MessagesReceivedWhenDataTransferIsInProgress;
else if (!strcmp(str_par, "maximumRetransmitRequestLimitReached")) return maximumRetransmitRequestLimitReached;
else if (!strcmp(str_par, "unexpectedDataTransferPacket")) return unexpectedDataTransferPacket;
else if (!strcmp(str_par, "badSequenceNumber")) return badSequenceNumber;
else if (!strcmp(str_par, "duplicateSequenceNumber")) return duplicateSequenceNumber;
else if (!strcmp(str_par, "iso_11783_7_error_code_251")) return iso__11783__7__error__code__251;
else if (!strcmp(str_par, "iso_11783_7_error_code_252")) return iso__11783__7__error__code__252;
else if (!strcmp(str_par, "iso_11783_7_error_code_253")) return iso__11783__7__error__code__253;
else if (!strcmp(str_par, "iso_11783_7_error_code_254")) return iso__11783__7__error__code__254;
else if (!strcmp(str_par, "iso_11783_7_error_code_255")) return iso__11783__7__error__code__255;
else return UNKNOWN_VALUE;
}

boolean e__ConnectionAbort__AbortReason::is_valid_enum(int int_par)
{
switch (int_par) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 251:
case 252:
case 253:
case 254:
case 255:
return TRUE;
default:
return FALSE;
}
}

int e__ConnectionAbort__AbortReason::enum2int(enum_type enum_par)
{
if (enum_par==UNBOUND_VALUE || enum_par==UNKNOWN_VALUE) TTCN_error("The argument of function enum2int() is an %s value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par;
}

int e__ConnectionAbort__AbortReason::enum2int(const e__ConnectionAbort__AbortReason& enum_par)
{
if (enum_par.enum_value==UNBOUND_VALUE || enum_par.enum_value==UNKNOWN_VALUE) TTCN_error("The argument of function enum2int() is an %s value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par.enum_value;
}

void e__ConnectionAbort__AbortReason::int2enum(int int_val)
{
if (!is_valid_enum(int_val)) TTCN_error("Assigning invalid numeric value %d to a variable of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.", int_val);
enum_value = (enum_type)int_val;
}

e__ConnectionAbort__AbortReason::operator e__ConnectionAbort__AbortReason::enum_type() const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("Using the value of an unbound variable of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
return enum_value;
}

void e__ConnectionAbort__AbortReason::log() const
{
if (enum_value != UNBOUND_VALUE) TTCN_Logger::log_event_enum(enum_to_str(enum_value), enum_value);
else TTCN_Logger::log_event_unbound();
}

void e__ConnectionAbort__AbortReason::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "enumerated value");
  if (param.get_type()!=Module_Param::MP_Enumerated) param.type_error("enumerated value", "@IsobusCMMessageTypes.e_ConnectionAbort_AbortReason");
  enum_value = str_to_enum(param.get_enumerated());
  if (!is_valid_enum(enum_value)) {
    param.error("Invalid enumerated value for type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
  }
}

void e__ConnectionAbort__AbortReason::encode_text(Text_Buf& text_buf) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("Text encoder: Encoding an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
text_buf.push_int(enum_value);
}

void e__ConnectionAbort__AbortReason::decode_text(Text_Buf& text_buf)
{
enum_value = (enum_type)text_buf.pull_int().get_val();
if (!is_valid_enum(enum_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.", enum_value);
}

void e__ConnectionAbort__AbortReason::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(TRUE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void e__ConnectionAbort__AbortReason::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int e__ConnectionAbort__AbortReason::RAW_decode(const TTCN_Typedescriptor_t& p_td,TTCN_Buffer& p_buf,int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit*)
{
  int decoded_value = 0;
  int decoded_length = RAW_decode_enum_type(p_td, p_buf, limit, top_bit_ord, decoded_value, 8, no_err);
  if (decoded_length < 0) return decoded_length;
  if (is_valid_enum(decoded_value)) enum_value = (enum_type)decoded_value;
  else {
    if(no_err){
     return -1;
    } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_ENC_ENUM, "Invalid enum value '%d' for '%s': ",decoded_value, p_td.name);
    enum_value = UNKNOWN_VALUE;
    }
  }
  return decoded_length;
}

int e__ConnectionAbort__AbortReason::RAW_encode(const TTCN_Typedescriptor_t& p_td, RAW_enc_tree& myleaf) const
{
  return RAW_encode_enum_type(p_td, myleaf, (int)enum_value, 8);
}

void e__ConnectionAbort__AbortReason_template::copy_template(const e__ConnectionAbort__AbortReason_template& other_value)
{
set_selection(other_value);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = other_value.single_value;
break;
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new e__ConnectionAbort__AbortReason_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
}
}

e__ConnectionAbort__AbortReason_template::e__ConnectionAbort__AbortReason_template()
{
}

e__ConnectionAbort__AbortReason_template::e__ConnectionAbort__AbortReason_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

e__ConnectionAbort__AbortReason_template::e__ConnectionAbort__AbortReason_template(int other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (!e__ConnectionAbort__AbortReason::is_valid_enum(other_value)) TTCN_error("Initializing a template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason with unknown numeric value %d.", other_value);
single_value = (e__ConnectionAbort__AbortReason::enum_type)other_value;
}

e__ConnectionAbort__AbortReason_template::e__ConnectionAbort__AbortReason_template(e__ConnectionAbort__AbortReason::enum_type other_value)
 : Base_Template(SPECIFIC_VALUE)
{
single_value = other_value;
}

e__ConnectionAbort__AbortReason_template::e__ConnectionAbort__AbortReason_template(const e__ConnectionAbort__AbortReason& other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (other_value.enum_value == e__ConnectionAbort__AbortReason::UNBOUND_VALUE) TTCN_error("Creating a template from an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
single_value = other_value.enum_value;
}

e__ConnectionAbort__AbortReason_template::e__ConnectionAbort__AbortReason_template(const OPTIONAL<e__ConnectionAbort__AbortReason>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (e__ConnectionAbort__AbortReason::enum_type)(const e__ConnectionAbort__AbortReason&)other_value;
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason from an unbound optional field.");
}
}

e__ConnectionAbort__AbortReason_template::e__ConnectionAbort__AbortReason_template(const e__ConnectionAbort__AbortReason_template& other_value)
 : Base_Template()
{
copy_template(other_value);
}

e__ConnectionAbort__AbortReason_template::~e__ConnectionAbort__AbortReason_template()
{
clean_up();
}

boolean e__ConnectionAbort__AbortReason_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
return TRUE;
}

boolean e__ConnectionAbort__AbortReason_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value != e__ConnectionAbort__AbortReason::UNBOUND_VALUE;
}

void e__ConnectionAbort__AbortReason_template::clean_up()
{
if (template_selection == VALUE_LIST || template_selection == COMPLEMENTED_LIST) delete [] value_list.list_value;
template_selection = UNINITIALIZED_TEMPLATE;
}

e__ConnectionAbort__AbortReason_template& e__ConnectionAbort__AbortReason_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

e__ConnectionAbort__AbortReason_template& e__ConnectionAbort__AbortReason_template::operator=(int other_value)
{
if (!e__ConnectionAbort__AbortReason::is_valid_enum(other_value)) TTCN_warning("Assigning unknown numeric value %d to a template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.", other_value);
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = (e__ConnectionAbort__AbortReason::enum_type)other_value;
return *this;
}

e__ConnectionAbort__AbortReason_template& e__ConnectionAbort__AbortReason_template::operator=(e__ConnectionAbort__AbortReason::enum_type other_value)
{
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = other_value;
return *this;
}

e__ConnectionAbort__AbortReason_template& e__ConnectionAbort__AbortReason_template::operator=(const e__ConnectionAbort__AbortReason& other_value)
{
if (other_value.enum_value == e__ConnectionAbort__AbortReason::UNBOUND_VALUE) TTCN_error("Assignment of an unbound value of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason to a template.");
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = other_value.enum_value;
return *this;
}

e__ConnectionAbort__AbortReason_template& e__ConnectionAbort__AbortReason_template::operator=(const OPTIONAL<e__ConnectionAbort__AbortReason>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (e__ConnectionAbort__AbortReason::enum_type)(const e__ConnectionAbort__AbortReason&)other_value;
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
}
return *this;
}

e__ConnectionAbort__AbortReason_template& e__ConnectionAbort__AbortReason_template::operator=(const e__ConnectionAbort__AbortReason_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean e__ConnectionAbort__AbortReason_template::match(e__ConnectionAbort__AbortReason::enum_type other_value, boolean) const
{
switch (template_selection) {
case SPECIFIC_VALUE:
return single_value == other_value;
case OMIT_VALUE:
return FALSE;
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
}
return FALSE;
}

boolean e__ConnectionAbort__AbortReason_template::match(const e__ConnectionAbort__AbortReason& other_value, boolean) const
{
if (other_value.enum_value == e__ConnectionAbort__AbortReason::UNBOUND_VALUE) TTCN_error("Matching a template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason with an unbound value.");
return match(other_value.enum_value);
}

e__ConnectionAbort__AbortReason::enum_type e__ConnectionAbort__AbortReason_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) TTCN_error("Performing a valueof or send operation on a non-specific template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
return single_value;
}

void e__ConnectionAbort__AbortReason_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) TTCN_error("Setting an invalid list type for a template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new e__ConnectionAbort__AbortReason_template[list_length];
}

e__ConnectionAbort__AbortReason_template& e__ConnectionAbort__AbortReason_template::list_item(unsigned int list_index)
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST) TTCN_error("Accessing a list element in a non-list template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
if (list_index >= value_list.n_values) TTCN_error("Index overflow in a value list template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
return value_list.list_value[list_index];
}

void e__ConnectionAbort__AbortReason_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_enum(e__ConnectionAbort__AbortReason::enum_to_str(single_value), single_value);
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[elem_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void e__ConnectionAbort__AbortReason_template::log_match(const e__ConnectionAbort__AbortReason& match_value, boolean) const
{
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}

void e__ConnectionAbort__AbortReason_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
text_buf.push_int(single_value);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++)
value_list.list_value[elem_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
}
}

void e__ConnectionAbort__AbortReason_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = (e__ConnectionAbort__AbortReason::enum_type)text_buf.pull_int().get_val();
if (!e__ConnectionAbort__AbortReason::is_valid_enum(single_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for a template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.", single_value);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new e__ConnectionAbort__AbortReason_template[value_list.n_values];
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++)
value_list.list_value[elem_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received for a template of enumerated type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
}
}

boolean e__ConnectionAbort__AbortReason_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean e__ConnectionAbort__AbortReason_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int i=0; i<value_list.n_values; i++)
if (value_list.list_value[i].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void e__ConnectionAbort__AbortReason_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "enumerated template");
  Module_Param_Ptr m_p = &param;
  switch (m_p->get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    e__ConnectionAbort__AbortReason_template new_temp;
    new_temp.set_type(m_p->get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, m_p->get_size());
    for (size_t p_i=0; p_i<m_p->get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*m_p->get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Enumerated: {
    e__ConnectionAbort__AbortReason::enum_type enum_val = e__ConnectionAbort__AbortReason::str_to_enum(m_p->get_enumerated());
    if (!e__ConnectionAbort__AbortReason::is_valid_enum(enum_val)) {
      param.error("Invalid enumerated value for type @IsobusCMMessageTypes.e_ConnectionAbort_AbortReason.");
    }
    *this = enum_val;
  } break;
  default:
    param.type_error("enumerated template", "@IsobusCMMessageTypes.e_ConnectionAbort_AbortReason");
  }
  is_ifpresent = param.get_ifpresent();
}

void e__ConnectionAbort__AbortReason_template::check_restriction(template_res t_res, const char* t_name,
boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_VALUE:
if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
break;
case TR_OMIT:
if (!is_ifpresent && (template_selection==OMIT_VALUE || template_selection==SPECIFIC_VALUE)) return;
break;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.e_ConnectionAbort_AbortReason");
}

ConnectionAbort::ConnectionAbort()
{
}

ConnectionAbort::ConnectionAbort(const OCTETSTRING& par_ctrl,
    const e__ConnectionAbort__AbortReason& par_connectionAbortReason,
    const OCTETSTRING& par_reserved3,
    const OCTETSTRING& par_reserved4,
    const OCTETSTRING& par_reserved5,
    const INTEGER& par_pgnOfMultiPacketMessage)
  :   field_ctrl(par_ctrl),
  field_connectionAbortReason(par_connectionAbortReason),
  field_reserved3(par_reserved3),
  field_reserved4(par_reserved4),
  field_reserved5(par_reserved5),
  field_pgnOfMultiPacketMessage(par_pgnOfMultiPacketMessage)
{
}

ConnectionAbort::ConnectionAbort(const ConnectionAbort& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.ConnectionAbort.");
if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
else field_ctrl.clean_up();
if (other_value.connectionAbortReason().is_bound()) field_connectionAbortReason = other_value.connectionAbortReason();
else field_connectionAbortReason.clean_up();
if (other_value.reserved3().is_bound()) field_reserved3 = other_value.reserved3();
else field_reserved3.clean_up();
if (other_value.reserved4().is_bound()) field_reserved4 = other_value.reserved4();
else field_reserved4.clean_up();
if (other_value.reserved5().is_bound()) field_reserved5 = other_value.reserved5();
else field_reserved5.clean_up();
if (other_value.pgnOfMultiPacketMessage().is_bound()) field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
else field_pgnOfMultiPacketMessage.clean_up();
}

void ConnectionAbort::clean_up()
{
field_ctrl.clean_up();
field_connectionAbortReason.clean_up();
field_reserved3.clean_up();
field_reserved4.clean_up();
field_reserved5.clean_up();
field_pgnOfMultiPacketMessage.clean_up();
}

const TTCN_Typedescriptor_t* ConnectionAbort::get_descriptor() const { return &ConnectionAbort_descr_; }
ConnectionAbort& ConnectionAbort::operator=(const ConnectionAbort& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.ConnectionAbort.");
  if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
  else field_ctrl.clean_up();
  if (other_value.connectionAbortReason().is_bound()) field_connectionAbortReason = other_value.connectionAbortReason();
  else field_connectionAbortReason.clean_up();
  if (other_value.reserved3().is_bound()) field_reserved3 = other_value.reserved3();
  else field_reserved3.clean_up();
  if (other_value.reserved4().is_bound()) field_reserved4 = other_value.reserved4();
  else field_reserved4.clean_up();
  if (other_value.reserved5().is_bound()) field_reserved5 = other_value.reserved5();
  else field_reserved5.clean_up();
  if (other_value.pgnOfMultiPacketMessage().is_bound()) field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
  else field_pgnOfMultiPacketMessage.clean_up();
}
return *this;
}

boolean ConnectionAbort::operator==(const ConnectionAbort& other_value) const
{
return field_ctrl==other_value.field_ctrl
  && field_connectionAbortReason==other_value.field_connectionAbortReason
  && field_reserved3==other_value.field_reserved3
  && field_reserved4==other_value.field_reserved4
  && field_reserved5==other_value.field_reserved5
  && field_pgnOfMultiPacketMessage==other_value.field_pgnOfMultiPacketMessage;
}

boolean ConnectionAbort::is_bound() const
{
return (field_ctrl.is_bound())
  || (field_connectionAbortReason.is_bound())
  || (field_reserved3.is_bound())
  || (field_reserved4.is_bound())
  || (field_reserved5.is_bound())
  || (field_pgnOfMultiPacketMessage.is_bound());
}
boolean ConnectionAbort::is_value() const
{
return field_ctrl.is_value()
  && field_connectionAbortReason.is_value()
  && field_reserved3.is_value()
  && field_reserved4.is_value()
  && field_reserved5.is_value()
  && field_pgnOfMultiPacketMessage.is_value();
}
void ConnectionAbort::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ctrl := ");
field_ctrl.log();
TTCN_Logger::log_event_str(", connectionAbortReason := ");
field_connectionAbortReason.log();
TTCN_Logger::log_event_str(", reserved3 := ");
field_reserved3.log();
TTCN_Logger::log_event_str(", reserved4 := ");
field_reserved4.log();
TTCN_Logger::log_event_str(", reserved5 := ");
field_reserved5.log();
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
field_pgnOfMultiPacketMessage.log();
TTCN_Logger::log_event_str(" }");
}

void ConnectionAbort::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (6<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.ConnectionAbort has 6 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) connectionAbortReason().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) reserved3().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) reserved4().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) reserved5().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) pgnOfMultiPacketMessage().set_param(*param.get_elem(5));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "connectionAbortReason")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          connectionAbortReason().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved3")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved3().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved4")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved4().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved5")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved5().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfMultiPacketMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfMultiPacketMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ConnectionAbort: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.ConnectionAbort");
  }
}

void ConnectionAbort::set_implicit_omit()
{
if (ctrl().is_bound()) ctrl().set_implicit_omit();
if (connectionAbortReason().is_bound()) connectionAbortReason().set_implicit_omit();
if (reserved3().is_bound()) reserved3().set_implicit_omit();
if (reserved4().is_bound()) reserved4().set_implicit_omit();
if (reserved5().is_bound()) reserved5().set_implicit_omit();
if (pgnOfMultiPacketMessage().is_bound()) pgnOfMultiPacketMessage().set_implicit_omit();
}

void ConnectionAbort::encode_text(Text_Buf& text_buf) const
{
field_ctrl.encode_text(text_buf);
field_connectionAbortReason.encode_text(text_buf);
field_reserved3.encode_text(text_buf);
field_reserved4.encode_text(text_buf);
field_reserved5.encode_text(text_buf);
field_pgnOfMultiPacketMessage.encode_text(text_buf);
}

void ConnectionAbort::decode_text(Text_Buf& text_buf)
{
field_ctrl.decode_text(text_buf);
field_connectionAbortReason.decode_text(text_buf);
field_reserved3.decode_text(text_buf);
field_reserved4.decode_text(text_buf);
field_reserved5.decode_text(text_buf);
field_pgnOfMultiPacketMessage.decode_text(text_buf);
}

void ConnectionAbort::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void ConnectionAbort::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int ConnectionAbort::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, ConnectionAbort_ctrl_descr_.raw->forceomit);
  decoded_field_length = field_ctrl.RAW_decode(ConnectionAbort_ctrl_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, e__ConnectionAbort__AbortReason_descr_.raw->forceomit);
  decoded_field_length = field_connectionAbortReason.RAW_decode(e__ConnectionAbort__AbortReason_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, ConnectionAbort_reserved3_descr_.raw->forceomit);
  decoded_field_length = field_reserved3.RAW_decode(ConnectionAbort_reserved3_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_3_force_omit(3, force_omit, ConnectionAbort_reserved4_descr_.raw->forceomit);
  decoded_field_length = field_reserved4.RAW_decode(ConnectionAbort_reserved4_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_3_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_4_force_omit(4, force_omit, ConnectionAbort_reserved5_descr_.raw->forceomit);
  decoded_field_length = field_reserved5.RAW_decode(ConnectionAbort_reserved5_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_4_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_5_force_omit(5, force_omit, IsobusMessageTypes::PGN_descr_.raw->forceomit);
  decoded_field_length = field_pgnOfMultiPacketMessage.RAW_decode(IsobusMessageTypes::PGN_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_5_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int ConnectionAbort::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 6;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(6);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, ConnectionAbort_ctrl_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, e__ConnectionAbort__AbortReason_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, ConnectionAbort_reserved3_descr_.raw);
  myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 3, ConnectionAbort_reserved4_descr_.raw);
  myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 4, ConnectionAbort_reserved5_descr_.raw);
  myleaf.body.node.nodes[5] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 5, IsobusMessageTypes::PGN_descr_.raw);
  encoded_length += field_ctrl.RAW_encode(ConnectionAbort_ctrl_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_connectionAbortReason.RAW_encode(e__ConnectionAbort__AbortReason_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_reserved3.RAW_encode(ConnectionAbort_reserved3_descr_, *myleaf.body.node.nodes[2]);
  encoded_length += field_reserved4.RAW_encode(ConnectionAbort_reserved4_descr_, *myleaf.body.node.nodes[3]);
  encoded_length += field_reserved5.RAW_encode(ConnectionAbort_reserved5_descr_, *myleaf.body.node.nodes[4]);
  encoded_length += field_pgnOfMultiPacketMessage.RAW_encode(IsobusMessageTypes::PGN_descr_, *myleaf.body.node.nodes[5]);
  return myleaf.length = encoded_length;
}

struct ConnectionAbort_template::single_value_struct {
OCTETSTRING_template field_ctrl;
e__ConnectionAbort__AbortReason_template field_connectionAbortReason;
OCTETSTRING_template field_reserved3;
OCTETSTRING_template field_reserved4;
OCTETSTRING_template field_reserved5;
INTEGER_template field_pgnOfMultiPacketMessage;
};

void ConnectionAbort_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_ctrl = ANY_VALUE;
single_value->field_connectionAbortReason = ANY_VALUE;
single_value->field_reserved3 = ANY_VALUE;
single_value->field_reserved4 = ANY_VALUE;
single_value->field_reserved5 = ANY_VALUE;
single_value->field_pgnOfMultiPacketMessage = ANY_VALUE;
}
}
}

void ConnectionAbort_template::copy_value(const ConnectionAbort& other_value)
{
single_value = new single_value_struct;
if (other_value.ctrl().is_bound()) {
  single_value->field_ctrl = other_value.ctrl();
} else {
  single_value->field_ctrl.clean_up();
}
if (other_value.connectionAbortReason().is_bound()) {
  single_value->field_connectionAbortReason = other_value.connectionAbortReason();
} else {
  single_value->field_connectionAbortReason.clean_up();
}
if (other_value.reserved3().is_bound()) {
  single_value->field_reserved3 = other_value.reserved3();
} else {
  single_value->field_reserved3.clean_up();
}
if (other_value.reserved4().is_bound()) {
  single_value->field_reserved4 = other_value.reserved4();
} else {
  single_value->field_reserved4.clean_up();
}
if (other_value.reserved5().is_bound()) {
  single_value->field_reserved5 = other_value.reserved5();
} else {
  single_value->field_reserved5.clean_up();
}
if (other_value.pgnOfMultiPacketMessage().is_bound()) {
  single_value->field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
} else {
  single_value->field_pgnOfMultiPacketMessage.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void ConnectionAbort_template::copy_template(const ConnectionAbort_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ctrl().get_selection()) {
single_value->field_ctrl = other_value.ctrl();
} else {
single_value->field_ctrl.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.connectionAbortReason().get_selection()) {
single_value->field_connectionAbortReason = other_value.connectionAbortReason();
} else {
single_value->field_connectionAbortReason.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.reserved3().get_selection()) {
single_value->field_reserved3 = other_value.reserved3();
} else {
single_value->field_reserved3.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.reserved4().get_selection()) {
single_value->field_reserved4 = other_value.reserved4();
} else {
single_value->field_reserved4.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.reserved5().get_selection()) {
single_value->field_reserved5 = other_value.reserved5();
} else {
single_value->field_reserved5.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pgnOfMultiPacketMessage().get_selection()) {
single_value->field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
} else {
single_value->field_pgnOfMultiPacketMessage.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new ConnectionAbort_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.ConnectionAbort.");
break;
}
set_selection(other_value);
}

ConnectionAbort_template::ConnectionAbort_template()
{
}

ConnectionAbort_template::ConnectionAbort_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

ConnectionAbort_template::ConnectionAbort_template(const ConnectionAbort& other_value)
{
copy_value(other_value);
}

ConnectionAbort_template::ConnectionAbort_template(const OPTIONAL<ConnectionAbort>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ConnectionAbort&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.ConnectionAbort from an unbound optional field.");
}
}

ConnectionAbort_template::ConnectionAbort_template(const ConnectionAbort_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

ConnectionAbort_template::~ConnectionAbort_template()
{
clean_up();
}

ConnectionAbort_template& ConnectionAbort_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

ConnectionAbort_template& ConnectionAbort_template::operator=(const ConnectionAbort& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

ConnectionAbort_template& ConnectionAbort_template::operator=(const OPTIONAL<ConnectionAbort>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ConnectionAbort&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.ConnectionAbort.");
}
return *this;
}

ConnectionAbort_template& ConnectionAbort_template::operator=(const ConnectionAbort_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean ConnectionAbort_template::match(const ConnectionAbort& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.ctrl().is_bound()) return FALSE;
if(!single_value->field_ctrl.match(other_value.ctrl(), legacy))return FALSE;
if(!other_value.connectionAbortReason().is_bound()) return FALSE;
if(!single_value->field_connectionAbortReason.match(other_value.connectionAbortReason(), legacy))return FALSE;
if(!other_value.reserved3().is_bound()) return FALSE;
if(!single_value->field_reserved3.match(other_value.reserved3(), legacy))return FALSE;
if(!other_value.reserved4().is_bound()) return FALSE;
if(!single_value->field_reserved4.match(other_value.reserved4(), legacy))return FALSE;
if(!other_value.reserved5().is_bound()) return FALSE;
if(!single_value->field_reserved5.match(other_value.reserved5(), legacy))return FALSE;
if(!other_value.pgnOfMultiPacketMessage().is_bound()) return FALSE;
if(!single_value->field_pgnOfMultiPacketMessage.match(other_value.pgnOfMultiPacketMessage(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.ConnectionAbort.");
}
return FALSE;
}

boolean ConnectionAbort_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_ctrl.is_bound()

 ||single_value->field_connectionAbortReason.is_bound()

 ||single_value->field_reserved3.is_bound()

 ||single_value->field_reserved4.is_bound()

 ||single_value->field_reserved5.is_bound()

 ||single_value->field_pgnOfMultiPacketMessage.is_bound()
;
}

boolean ConnectionAbort_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ctrl.is_value()
 &&single_value->field_connectionAbortReason.is_value()
 &&single_value->field_reserved3.is_value()
 &&single_value->field_reserved4.is_value()
 &&single_value->field_reserved5.is_value()
 &&single_value->field_pgnOfMultiPacketMessage.is_value();
}

void ConnectionAbort_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

ConnectionAbort ConnectionAbort_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.ConnectionAbort.");
ConnectionAbort ret_val;
if (single_value->field_ctrl.is_bound()) {
ret_val.ctrl() = single_value->field_ctrl.valueof();
}
if (single_value->field_connectionAbortReason.is_bound()) {
ret_val.connectionAbortReason() = single_value->field_connectionAbortReason.valueof();
}
if (single_value->field_reserved3.is_bound()) {
ret_val.reserved3() = single_value->field_reserved3.valueof();
}
if (single_value->field_reserved4.is_bound()) {
ret_val.reserved4() = single_value->field_reserved4.valueof();
}
if (single_value->field_reserved5.is_bound()) {
ret_val.reserved5() = single_value->field_reserved5.valueof();
}
if (single_value->field_pgnOfMultiPacketMessage.is_bound()) {
ret_val.pgnOfMultiPacketMessage() = single_value->field_pgnOfMultiPacketMessage.valueof();
}
return ret_val;
}

void ConnectionAbort_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.ConnectionAbort.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new ConnectionAbort_template[list_length];
}

ConnectionAbort_template& ConnectionAbort_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.ConnectionAbort.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.ConnectionAbort.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& ConnectionAbort_template::ctrl()
{
set_specific();
return single_value->field_ctrl;
}

const OCTETSTRING_template& ConnectionAbort_template::ctrl() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ctrl of a non-specific template of type @IsobusCMMessageTypes.ConnectionAbort.");
return single_value->field_ctrl;
}

e__ConnectionAbort__AbortReason_template& ConnectionAbort_template::connectionAbortReason()
{
set_specific();
return single_value->field_connectionAbortReason;
}

const e__ConnectionAbort__AbortReason_template& ConnectionAbort_template::connectionAbortReason() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field connectionAbortReason of a non-specific template of type @IsobusCMMessageTypes.ConnectionAbort.");
return single_value->field_connectionAbortReason;
}

OCTETSTRING_template& ConnectionAbort_template::reserved3()
{
set_specific();
return single_value->field_reserved3;
}

const OCTETSTRING_template& ConnectionAbort_template::reserved3() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field reserved3 of a non-specific template of type @IsobusCMMessageTypes.ConnectionAbort.");
return single_value->field_reserved3;
}

OCTETSTRING_template& ConnectionAbort_template::reserved4()
{
set_specific();
return single_value->field_reserved4;
}

const OCTETSTRING_template& ConnectionAbort_template::reserved4() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field reserved4 of a non-specific template of type @IsobusCMMessageTypes.ConnectionAbort.");
return single_value->field_reserved4;
}

OCTETSTRING_template& ConnectionAbort_template::reserved5()
{
set_specific();
return single_value->field_reserved5;
}

const OCTETSTRING_template& ConnectionAbort_template::reserved5() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field reserved5 of a non-specific template of type @IsobusCMMessageTypes.ConnectionAbort.");
return single_value->field_reserved5;
}

INTEGER_template& ConnectionAbort_template::pgnOfMultiPacketMessage()
{
set_specific();
return single_value->field_pgnOfMultiPacketMessage;
}

const INTEGER_template& ConnectionAbort_template::pgnOfMultiPacketMessage() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pgnOfMultiPacketMessage of a non-specific template of type @IsobusCMMessageTypes.ConnectionAbort.");
return single_value->field_pgnOfMultiPacketMessage;
}

int ConnectionAbort_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ConnectionAbort which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 6;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ConnectionAbort containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ConnectionAbort containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ConnectionAbort containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ConnectionAbort containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ConnectionAbort containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.ConnectionAbort.");
  }
  return 0;
}

void ConnectionAbort_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log();
TTCN_Logger::log_event_str(", connectionAbortReason := ");
single_value->field_connectionAbortReason.log();
TTCN_Logger::log_event_str(", reserved3 := ");
single_value->field_reserved3.log();
TTCN_Logger::log_event_str(", reserved4 := ");
single_value->field_reserved4.log();
TTCN_Logger::log_event_str(", reserved5 := ");
single_value->field_reserved5.log();
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
single_value->field_pgnOfMultiPacketMessage.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void ConnectionAbort_template::log_match(const ConnectionAbort& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_ctrl.match(match_value.ctrl(), legacy)){
TTCN_Logger::log_logmatch_info(".ctrl");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_connectionAbortReason.match(match_value.connectionAbortReason(), legacy)){
TTCN_Logger::log_logmatch_info(".connectionAbortReason");
single_value->field_connectionAbortReason.log_match(match_value.connectionAbortReason(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_reserved3.match(match_value.reserved3(), legacy)){
TTCN_Logger::log_logmatch_info(".reserved3");
single_value->field_reserved3.log_match(match_value.reserved3(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_reserved4.match(match_value.reserved4(), legacy)){
TTCN_Logger::log_logmatch_info(".reserved4");
single_value->field_reserved4.log_match(match_value.reserved4(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_reserved5.match(match_value.reserved5(), legacy)){
TTCN_Logger::log_logmatch_info(".reserved5");
single_value->field_reserved5.log_match(match_value.reserved5(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pgnOfMultiPacketMessage.match(match_value.pgnOfMultiPacketMessage(), legacy)){
TTCN_Logger::log_logmatch_info(".pgnOfMultiPacketMessage");
single_value->field_pgnOfMultiPacketMessage.log_match(match_value.pgnOfMultiPacketMessage(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::log_event_str(", connectionAbortReason := ");
single_value->field_connectionAbortReason.log_match(match_value.connectionAbortReason(), legacy);
TTCN_Logger::log_event_str(", reserved3 := ");
single_value->field_reserved3.log_match(match_value.reserved3(), legacy);
TTCN_Logger::log_event_str(", reserved4 := ");
single_value->field_reserved4.log_match(match_value.reserved4(), legacy);
TTCN_Logger::log_event_str(", reserved5 := ");
single_value->field_reserved5.log_match(match_value.reserved5(), legacy);
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
single_value->field_pgnOfMultiPacketMessage.log_match(match_value.pgnOfMultiPacketMessage(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void ConnectionAbort_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ctrl.encode_text(text_buf);
single_value->field_connectionAbortReason.encode_text(text_buf);
single_value->field_reserved3.encode_text(text_buf);
single_value->field_reserved4.encode_text(text_buf);
single_value->field_reserved5.encode_text(text_buf);
single_value->field_pgnOfMultiPacketMessage.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.ConnectionAbort.");
}
}

void ConnectionAbort_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_ctrl.decode_text(text_buf);
single_value->field_connectionAbortReason.decode_text(text_buf);
single_value->field_reserved3.decode_text(text_buf);
single_value->field_reserved4.decode_text(text_buf);
single_value->field_reserved5.decode_text(text_buf);
single_value->field_pgnOfMultiPacketMessage.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new ConnectionAbort_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.ConnectionAbort.");
}
}

void ConnectionAbort_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    ConnectionAbort_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (6<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.ConnectionAbort has 6 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) connectionAbortReason().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) reserved3().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) reserved4().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) reserved5().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) pgnOfMultiPacketMessage().set_param(*param.get_elem(5));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "connectionAbortReason")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          connectionAbortReason().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved3")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved3().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved4")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved4().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved5")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved5().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfMultiPacketMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfMultiPacketMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ConnectionAbort: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.ConnectionAbort");
  }
  is_ifpresent = param.get_ifpresent();
}

void ConnectionAbort_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_ctrl.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ConnectionAbort");
single_value->field_connectionAbortReason.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ConnectionAbort");
single_value->field_reserved3.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ConnectionAbort");
single_value->field_reserved4.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ConnectionAbort");
single_value->field_reserved5.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ConnectionAbort");
single_value->field_pgnOfMultiPacketMessage.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ConnectionAbort");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.ConnectionAbort");
}

boolean ConnectionAbort_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean ConnectionAbort_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

BroadcastAnnounce::BroadcastAnnounce()
{
}

BroadcastAnnounce::BroadcastAnnounce(const OCTETSTRING& par_ctrl,
    const INTEGER& par_msgSizeInByte,
    const INTEGER& par_totalNumberOfPackets,
    const OCTETSTRING& par_reserved5,
    const INTEGER& par_pgnOfMultiPacketMessage)
  :   field_ctrl(par_ctrl),
  field_msgSizeInByte(par_msgSizeInByte),
  field_totalNumberOfPackets(par_totalNumberOfPackets),
  field_reserved5(par_reserved5),
  field_pgnOfMultiPacketMessage(par_pgnOfMultiPacketMessage)
{
}

BroadcastAnnounce::BroadcastAnnounce(const BroadcastAnnounce& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.BroadcastAnnounce.");
if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
else field_ctrl.clean_up();
if (other_value.msgSizeInByte().is_bound()) field_msgSizeInByte = other_value.msgSizeInByte();
else field_msgSizeInByte.clean_up();
if (other_value.totalNumberOfPackets().is_bound()) field_totalNumberOfPackets = other_value.totalNumberOfPackets();
else field_totalNumberOfPackets.clean_up();
if (other_value.reserved5().is_bound()) field_reserved5 = other_value.reserved5();
else field_reserved5.clean_up();
if (other_value.pgnOfMultiPacketMessage().is_bound()) field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
else field_pgnOfMultiPacketMessage.clean_up();
}

void BroadcastAnnounce::clean_up()
{
field_ctrl.clean_up();
field_msgSizeInByte.clean_up();
field_totalNumberOfPackets.clean_up();
field_reserved5.clean_up();
field_pgnOfMultiPacketMessage.clean_up();
}

const TTCN_Typedescriptor_t* BroadcastAnnounce::get_descriptor() const { return &BroadcastAnnounce_descr_; }
BroadcastAnnounce& BroadcastAnnounce::operator=(const BroadcastAnnounce& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.BroadcastAnnounce.");
  if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
  else field_ctrl.clean_up();
  if (other_value.msgSizeInByte().is_bound()) field_msgSizeInByte = other_value.msgSizeInByte();
  else field_msgSizeInByte.clean_up();
  if (other_value.totalNumberOfPackets().is_bound()) field_totalNumberOfPackets = other_value.totalNumberOfPackets();
  else field_totalNumberOfPackets.clean_up();
  if (other_value.reserved5().is_bound()) field_reserved5 = other_value.reserved5();
  else field_reserved5.clean_up();
  if (other_value.pgnOfMultiPacketMessage().is_bound()) field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
  else field_pgnOfMultiPacketMessage.clean_up();
}
return *this;
}

boolean BroadcastAnnounce::operator==(const BroadcastAnnounce& other_value) const
{
return field_ctrl==other_value.field_ctrl
  && field_msgSizeInByte==other_value.field_msgSizeInByte
  && field_totalNumberOfPackets==other_value.field_totalNumberOfPackets
  && field_reserved5==other_value.field_reserved5
  && field_pgnOfMultiPacketMessage==other_value.field_pgnOfMultiPacketMessage;
}

boolean BroadcastAnnounce::is_bound() const
{
return (field_ctrl.is_bound())
  || (field_msgSizeInByte.is_bound())
  || (field_totalNumberOfPackets.is_bound())
  || (field_reserved5.is_bound())
  || (field_pgnOfMultiPacketMessage.is_bound());
}
boolean BroadcastAnnounce::is_value() const
{
return field_ctrl.is_value()
  && field_msgSizeInByte.is_value()
  && field_totalNumberOfPackets.is_value()
  && field_reserved5.is_value()
  && field_pgnOfMultiPacketMessage.is_value();
}
void BroadcastAnnounce::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ctrl := ");
field_ctrl.log();
TTCN_Logger::log_event_str(", msgSizeInByte := ");
field_msgSizeInByte.log();
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
field_totalNumberOfPackets.log();
TTCN_Logger::log_event_str(", reserved5 := ");
field_reserved5.log();
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
field_pgnOfMultiPacketMessage.log();
TTCN_Logger::log_event_str(" }");
}

void BroadcastAnnounce::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (5<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.BroadcastAnnounce has 5 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) msgSizeInByte().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) totalNumberOfPackets().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) reserved5().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) pgnOfMultiPacketMessage().set_param(*param.get_elem(4));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "msgSizeInByte")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          msgSizeInByte().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "totalNumberOfPackets")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          totalNumberOfPackets().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved5")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved5().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfMultiPacketMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfMultiPacketMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.BroadcastAnnounce: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.BroadcastAnnounce");
  }
}

void BroadcastAnnounce::set_implicit_omit()
{
if (ctrl().is_bound()) ctrl().set_implicit_omit();
if (msgSizeInByte().is_bound()) msgSizeInByte().set_implicit_omit();
if (totalNumberOfPackets().is_bound()) totalNumberOfPackets().set_implicit_omit();
if (reserved5().is_bound()) reserved5().set_implicit_omit();
if (pgnOfMultiPacketMessage().is_bound()) pgnOfMultiPacketMessage().set_implicit_omit();
}

void BroadcastAnnounce::encode_text(Text_Buf& text_buf) const
{
field_ctrl.encode_text(text_buf);
field_msgSizeInByte.encode_text(text_buf);
field_totalNumberOfPackets.encode_text(text_buf);
field_reserved5.encode_text(text_buf);
field_pgnOfMultiPacketMessage.encode_text(text_buf);
}

void BroadcastAnnounce::decode_text(Text_Buf& text_buf)
{
field_ctrl.decode_text(text_buf);
field_msgSizeInByte.decode_text(text_buf);
field_totalNumberOfPackets.decode_text(text_buf);
field_reserved5.decode_text(text_buf);
field_pgnOfMultiPacketMessage.decode_text(text_buf);
}

void BroadcastAnnounce::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void BroadcastAnnounce::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int BroadcastAnnounce::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, BroadcastAnnounce_ctrl_descr_.raw->forceomit);
  decoded_field_length = field_ctrl.RAW_decode(BroadcastAnnounce_ctrl_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, IsobusMessageTypes::INT2_descr_.raw->forceomit);
  decoded_field_length = field_msgSizeInByte.RAW_decode(IsobusMessageTypes::INT2_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, NUMBER__OF__PACKETS_descr_.raw->forceomit);
  decoded_field_length = field_totalNumberOfPackets.RAW_decode(NUMBER__OF__PACKETS_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_3_force_omit(3, force_omit, BroadcastAnnounce_reserved5_descr_.raw->forceomit);
  decoded_field_length = field_reserved5.RAW_decode(BroadcastAnnounce_reserved5_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_3_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_4_force_omit(4, force_omit, IsobusMessageTypes::PGN_descr_.raw->forceomit);
  decoded_field_length = field_pgnOfMultiPacketMessage.RAW_decode(IsobusMessageTypes::PGN_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_4_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int BroadcastAnnounce::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 5;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(5);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, BroadcastAnnounce_ctrl_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, IsobusMessageTypes::INT2_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, NUMBER__OF__PACKETS_descr_.raw);
  myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 3, BroadcastAnnounce_reserved5_descr_.raw);
  myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 4, IsobusMessageTypes::PGN_descr_.raw);
  encoded_length += field_ctrl.RAW_encode(BroadcastAnnounce_ctrl_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_msgSizeInByte.RAW_encode(IsobusMessageTypes::INT2_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_totalNumberOfPackets.RAW_encode(NUMBER__OF__PACKETS_descr_, *myleaf.body.node.nodes[2]);
  encoded_length += field_reserved5.RAW_encode(BroadcastAnnounce_reserved5_descr_, *myleaf.body.node.nodes[3]);
  encoded_length += field_pgnOfMultiPacketMessage.RAW_encode(IsobusMessageTypes::PGN_descr_, *myleaf.body.node.nodes[4]);
  return myleaf.length = encoded_length;
}

struct BroadcastAnnounce_template::single_value_struct {
OCTETSTRING_template field_ctrl;
INTEGER_template field_msgSizeInByte;
INTEGER_template field_totalNumberOfPackets;
OCTETSTRING_template field_reserved5;
INTEGER_template field_pgnOfMultiPacketMessage;
};

void BroadcastAnnounce_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_ctrl = ANY_VALUE;
single_value->field_msgSizeInByte = ANY_VALUE;
single_value->field_totalNumberOfPackets = ANY_VALUE;
single_value->field_reserved5 = ANY_VALUE;
single_value->field_pgnOfMultiPacketMessage = ANY_VALUE;
}
}
}

void BroadcastAnnounce_template::copy_value(const BroadcastAnnounce& other_value)
{
single_value = new single_value_struct;
if (other_value.ctrl().is_bound()) {
  single_value->field_ctrl = other_value.ctrl();
} else {
  single_value->field_ctrl.clean_up();
}
if (other_value.msgSizeInByte().is_bound()) {
  single_value->field_msgSizeInByte = other_value.msgSizeInByte();
} else {
  single_value->field_msgSizeInByte.clean_up();
}
if (other_value.totalNumberOfPackets().is_bound()) {
  single_value->field_totalNumberOfPackets = other_value.totalNumberOfPackets();
} else {
  single_value->field_totalNumberOfPackets.clean_up();
}
if (other_value.reserved5().is_bound()) {
  single_value->field_reserved5 = other_value.reserved5();
} else {
  single_value->field_reserved5.clean_up();
}
if (other_value.pgnOfMultiPacketMessage().is_bound()) {
  single_value->field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
} else {
  single_value->field_pgnOfMultiPacketMessage.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void BroadcastAnnounce_template::copy_template(const BroadcastAnnounce_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ctrl().get_selection()) {
single_value->field_ctrl = other_value.ctrl();
} else {
single_value->field_ctrl.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.msgSizeInByte().get_selection()) {
single_value->field_msgSizeInByte = other_value.msgSizeInByte();
} else {
single_value->field_msgSizeInByte.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.totalNumberOfPackets().get_selection()) {
single_value->field_totalNumberOfPackets = other_value.totalNumberOfPackets();
} else {
single_value->field_totalNumberOfPackets.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.reserved5().get_selection()) {
single_value->field_reserved5 = other_value.reserved5();
} else {
single_value->field_reserved5.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pgnOfMultiPacketMessage().get_selection()) {
single_value->field_pgnOfMultiPacketMessage = other_value.pgnOfMultiPacketMessage();
} else {
single_value->field_pgnOfMultiPacketMessage.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new BroadcastAnnounce_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
break;
}
set_selection(other_value);
}

BroadcastAnnounce_template::BroadcastAnnounce_template()
{
}

BroadcastAnnounce_template::BroadcastAnnounce_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

BroadcastAnnounce_template::BroadcastAnnounce_template(const BroadcastAnnounce& other_value)
{
copy_value(other_value);
}

BroadcastAnnounce_template::BroadcastAnnounce_template(const OPTIONAL<BroadcastAnnounce>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const BroadcastAnnounce&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.BroadcastAnnounce from an unbound optional field.");
}
}

BroadcastAnnounce_template::BroadcastAnnounce_template(const BroadcastAnnounce_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

BroadcastAnnounce_template::~BroadcastAnnounce_template()
{
clean_up();
}

BroadcastAnnounce_template& BroadcastAnnounce_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

BroadcastAnnounce_template& BroadcastAnnounce_template::operator=(const BroadcastAnnounce& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

BroadcastAnnounce_template& BroadcastAnnounce_template::operator=(const OPTIONAL<BroadcastAnnounce>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const BroadcastAnnounce&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
}
return *this;
}

BroadcastAnnounce_template& BroadcastAnnounce_template::operator=(const BroadcastAnnounce_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean BroadcastAnnounce_template::match(const BroadcastAnnounce& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.ctrl().is_bound()) return FALSE;
if(!single_value->field_ctrl.match(other_value.ctrl(), legacy))return FALSE;
if(!other_value.msgSizeInByte().is_bound()) return FALSE;
if(!single_value->field_msgSizeInByte.match(other_value.msgSizeInByte(), legacy))return FALSE;
if(!other_value.totalNumberOfPackets().is_bound()) return FALSE;
if(!single_value->field_totalNumberOfPackets.match(other_value.totalNumberOfPackets(), legacy))return FALSE;
if(!other_value.reserved5().is_bound()) return FALSE;
if(!single_value->field_reserved5.match(other_value.reserved5(), legacy))return FALSE;
if(!other_value.pgnOfMultiPacketMessage().is_bound()) return FALSE;
if(!single_value->field_pgnOfMultiPacketMessage.match(other_value.pgnOfMultiPacketMessage(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
}
return FALSE;
}

boolean BroadcastAnnounce_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_ctrl.is_bound()

 ||single_value->field_msgSizeInByte.is_bound()

 ||single_value->field_totalNumberOfPackets.is_bound()

 ||single_value->field_reserved5.is_bound()

 ||single_value->field_pgnOfMultiPacketMessage.is_bound()
;
}

boolean BroadcastAnnounce_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ctrl.is_value()
 &&single_value->field_msgSizeInByte.is_value()
 &&single_value->field_totalNumberOfPackets.is_value()
 &&single_value->field_reserved5.is_value()
 &&single_value->field_pgnOfMultiPacketMessage.is_value();
}

void BroadcastAnnounce_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

BroadcastAnnounce BroadcastAnnounce_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
BroadcastAnnounce ret_val;
if (single_value->field_ctrl.is_bound()) {
ret_val.ctrl() = single_value->field_ctrl.valueof();
}
if (single_value->field_msgSizeInByte.is_bound()) {
ret_val.msgSizeInByte() = single_value->field_msgSizeInByte.valueof();
}
if (single_value->field_totalNumberOfPackets.is_bound()) {
ret_val.totalNumberOfPackets() = single_value->field_totalNumberOfPackets.valueof();
}
if (single_value->field_reserved5.is_bound()) {
ret_val.reserved5() = single_value->field_reserved5.valueof();
}
if (single_value->field_pgnOfMultiPacketMessage.is_bound()) {
ret_val.pgnOfMultiPacketMessage() = single_value->field_pgnOfMultiPacketMessage.valueof();
}
return ret_val;
}

void BroadcastAnnounce_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new BroadcastAnnounce_template[list_length];
}

BroadcastAnnounce_template& BroadcastAnnounce_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& BroadcastAnnounce_template::ctrl()
{
set_specific();
return single_value->field_ctrl;
}

const OCTETSTRING_template& BroadcastAnnounce_template::ctrl() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ctrl of a non-specific template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
return single_value->field_ctrl;
}

INTEGER_template& BroadcastAnnounce_template::msgSizeInByte()
{
set_specific();
return single_value->field_msgSizeInByte;
}

const INTEGER_template& BroadcastAnnounce_template::msgSizeInByte() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field msgSizeInByte of a non-specific template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
return single_value->field_msgSizeInByte;
}

INTEGER_template& BroadcastAnnounce_template::totalNumberOfPackets()
{
set_specific();
return single_value->field_totalNumberOfPackets;
}

const INTEGER_template& BroadcastAnnounce_template::totalNumberOfPackets() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field totalNumberOfPackets of a non-specific template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
return single_value->field_totalNumberOfPackets;
}

OCTETSTRING_template& BroadcastAnnounce_template::reserved5()
{
set_specific();
return single_value->field_reserved5;
}

const OCTETSTRING_template& BroadcastAnnounce_template::reserved5() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field reserved5 of a non-specific template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
return single_value->field_reserved5;
}

INTEGER_template& BroadcastAnnounce_template::pgnOfMultiPacketMessage()
{
set_specific();
return single_value->field_pgnOfMultiPacketMessage;
}

const INTEGER_template& BroadcastAnnounce_template::pgnOfMultiPacketMessage() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pgnOfMultiPacketMessage of a non-specific template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
return single_value->field_pgnOfMultiPacketMessage;
}

int BroadcastAnnounce_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.BroadcastAnnounce which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 5;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.BroadcastAnnounce containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.BroadcastAnnounce containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.BroadcastAnnounce containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.BroadcastAnnounce containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.BroadcastAnnounce containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
  }
  return 0;
}

void BroadcastAnnounce_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log();
TTCN_Logger::log_event_str(", msgSizeInByte := ");
single_value->field_msgSizeInByte.log();
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
single_value->field_totalNumberOfPackets.log();
TTCN_Logger::log_event_str(", reserved5 := ");
single_value->field_reserved5.log();
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
single_value->field_pgnOfMultiPacketMessage.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void BroadcastAnnounce_template::log_match(const BroadcastAnnounce& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_ctrl.match(match_value.ctrl(), legacy)){
TTCN_Logger::log_logmatch_info(".ctrl");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_msgSizeInByte.match(match_value.msgSizeInByte(), legacy)){
TTCN_Logger::log_logmatch_info(".msgSizeInByte");
single_value->field_msgSizeInByte.log_match(match_value.msgSizeInByte(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_totalNumberOfPackets.match(match_value.totalNumberOfPackets(), legacy)){
TTCN_Logger::log_logmatch_info(".totalNumberOfPackets");
single_value->field_totalNumberOfPackets.log_match(match_value.totalNumberOfPackets(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_reserved5.match(match_value.reserved5(), legacy)){
TTCN_Logger::log_logmatch_info(".reserved5");
single_value->field_reserved5.log_match(match_value.reserved5(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pgnOfMultiPacketMessage.match(match_value.pgnOfMultiPacketMessage(), legacy)){
TTCN_Logger::log_logmatch_info(".pgnOfMultiPacketMessage");
single_value->field_pgnOfMultiPacketMessage.log_match(match_value.pgnOfMultiPacketMessage(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::log_event_str(", msgSizeInByte := ");
single_value->field_msgSizeInByte.log_match(match_value.msgSizeInByte(), legacy);
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
single_value->field_totalNumberOfPackets.log_match(match_value.totalNumberOfPackets(), legacy);
TTCN_Logger::log_event_str(", reserved5 := ");
single_value->field_reserved5.log_match(match_value.reserved5(), legacy);
TTCN_Logger::log_event_str(", pgnOfMultiPacketMessage := ");
single_value->field_pgnOfMultiPacketMessage.log_match(match_value.pgnOfMultiPacketMessage(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void BroadcastAnnounce_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ctrl.encode_text(text_buf);
single_value->field_msgSizeInByte.encode_text(text_buf);
single_value->field_totalNumberOfPackets.encode_text(text_buf);
single_value->field_reserved5.encode_text(text_buf);
single_value->field_pgnOfMultiPacketMessage.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
}
}

void BroadcastAnnounce_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_ctrl.decode_text(text_buf);
single_value->field_msgSizeInByte.decode_text(text_buf);
single_value->field_totalNumberOfPackets.decode_text(text_buf);
single_value->field_reserved5.decode_text(text_buf);
single_value->field_pgnOfMultiPacketMessage.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new BroadcastAnnounce_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.BroadcastAnnounce.");
}
}

void BroadcastAnnounce_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    BroadcastAnnounce_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (5<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.BroadcastAnnounce has 5 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) msgSizeInByte().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) totalNumberOfPackets().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) reserved5().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) pgnOfMultiPacketMessage().set_param(*param.get_elem(4));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "msgSizeInByte")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          msgSizeInByte().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "totalNumberOfPackets")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          totalNumberOfPackets().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved5")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved5().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfMultiPacketMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfMultiPacketMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.BroadcastAnnounce: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.BroadcastAnnounce");
  }
  is_ifpresent = param.get_ifpresent();
}

void BroadcastAnnounce_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_ctrl.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.BroadcastAnnounce");
single_value->field_msgSizeInByte.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.BroadcastAnnounce");
single_value->field_totalNumberOfPackets.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.BroadcastAnnounce");
single_value->field_reserved5.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.BroadcastAnnounce");
single_value->field_pgnOfMultiPacketMessage.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.BroadcastAnnounce");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.BroadcastAnnounce");
}

boolean BroadcastAnnounce_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean BroadcastAnnounce_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void TP__CM::copy_value(const TP__CM& other_value)
{
switch (other_value.union_selection) {
case ALT_requestToSend:
field_requestToSend = new RequestToSend(*other_value.field_requestToSend);
break;
case ALT_clearToSend:
field_clearToSend = new ClearToSend(*other_value.field_clearToSend);
break;
case ALT_endOfMessageAcknowledgement:
field_endOfMessageAcknowledgement = new EndOfMessageAcknowledgement(*other_value.field_endOfMessageAcknowledgement);
break;
case ALT_broadcastAnnounce:
field_broadcastAnnounce = new BroadcastAnnounce(*other_value.field_broadcastAnnounce);
break;
case ALT_connectionAbort:
field_connectionAbort = new ConnectionAbort(*other_value.field_connectionAbort);
break;
default:
TTCN_error("Assignment of an unbound union value of type @IsobusCMMessageTypes.TP_CM.");
}
union_selection = other_value.union_selection;
}

TP__CM::TP__CM()
{
union_selection = UNBOUND_VALUE;
}

TP__CM::TP__CM(const TP__CM& other_value)
: Base_Type(){
copy_value(other_value);
}

TP__CM::~TP__CM()
{
clean_up();
}

TP__CM& TP__CM::operator=(const TP__CM& other_value)
{
if (this != &other_value) {
clean_up();
copy_value(other_value);
}
return *this;
}

boolean TP__CM::operator==(const TP__CM& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @IsobusCMMessageTypes.TP_CM.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @IsobusCMMessageTypes.TP_CM.");
if (union_selection != other_value.union_selection) return FALSE;
switch (union_selection) {
case ALT_requestToSend:
return *field_requestToSend == *other_value.field_requestToSend;
case ALT_clearToSend:
return *field_clearToSend == *other_value.field_clearToSend;
case ALT_endOfMessageAcknowledgement:
return *field_endOfMessageAcknowledgement == *other_value.field_endOfMessageAcknowledgement;
case ALT_broadcastAnnounce:
return *field_broadcastAnnounce == *other_value.field_broadcastAnnounce;
case ALT_connectionAbort:
return *field_connectionAbort == *other_value.field_connectionAbort;
default:
return FALSE;
}
}

RequestToSend& TP__CM::requestToSend()
{
if (union_selection != ALT_requestToSend) {
clean_up();
field_requestToSend = new RequestToSend;
union_selection = ALT_requestToSend;
}
return *field_requestToSend;
}

const RequestToSend& TP__CM::requestToSend() const
{
if (union_selection != ALT_requestToSend) TTCN_error("Using non-selected field requestToSend in a value of union type @IsobusCMMessageTypes.TP_CM.");
return *field_requestToSend;
}

ClearToSend& TP__CM::clearToSend()
{
if (union_selection != ALT_clearToSend) {
clean_up();
field_clearToSend = new ClearToSend;
union_selection = ALT_clearToSend;
}
return *field_clearToSend;
}

const ClearToSend& TP__CM::clearToSend() const
{
if (union_selection != ALT_clearToSend) TTCN_error("Using non-selected field clearToSend in a value of union type @IsobusCMMessageTypes.TP_CM.");
return *field_clearToSend;
}

EndOfMessageAcknowledgement& TP__CM::endOfMessageAcknowledgement()
{
if (union_selection != ALT_endOfMessageAcknowledgement) {
clean_up();
field_endOfMessageAcknowledgement = new EndOfMessageAcknowledgement;
union_selection = ALT_endOfMessageAcknowledgement;
}
return *field_endOfMessageAcknowledgement;
}

const EndOfMessageAcknowledgement& TP__CM::endOfMessageAcknowledgement() const
{
if (union_selection != ALT_endOfMessageAcknowledgement) TTCN_error("Using non-selected field endOfMessageAcknowledgement in a value of union type @IsobusCMMessageTypes.TP_CM.");
return *field_endOfMessageAcknowledgement;
}

BroadcastAnnounce& TP__CM::broadcastAnnounce()
{
if (union_selection != ALT_broadcastAnnounce) {
clean_up();
field_broadcastAnnounce = new BroadcastAnnounce;
union_selection = ALT_broadcastAnnounce;
}
return *field_broadcastAnnounce;
}

const BroadcastAnnounce& TP__CM::broadcastAnnounce() const
{
if (union_selection != ALT_broadcastAnnounce) TTCN_error("Using non-selected field broadcastAnnounce in a value of union type @IsobusCMMessageTypes.TP_CM.");
return *field_broadcastAnnounce;
}

ConnectionAbort& TP__CM::connectionAbort()
{
if (union_selection != ALT_connectionAbort) {
clean_up();
field_connectionAbort = new ConnectionAbort;
union_selection = ALT_connectionAbort;
}
return *field_connectionAbort;
}

const ConnectionAbort& TP__CM::connectionAbort() const
{
if (union_selection != ALT_connectionAbort) TTCN_error("Using non-selected field connectionAbort in a value of union type @IsobusCMMessageTypes.TP_CM.");
return *field_connectionAbort;
}

boolean TP__CM::ischosen(union_selection_type checked_selection) const
{
if (checked_selection == UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @IsobusCMMessageTypes.TP_CM.");
return union_selection == checked_selection;
}

boolean TP__CM::is_bound() const
{
  return union_selection != UNBOUND_VALUE;
}

boolean TP__CM::is_value() const
{
switch (union_selection) {
case UNBOUND_VALUE: return FALSE;
case ALT_requestToSend: return field_requestToSend->is_value();
case ALT_clearToSend: return field_clearToSend->is_value();
case ALT_endOfMessageAcknowledgement: return field_endOfMessageAcknowledgement->is_value();
case ALT_broadcastAnnounce: return field_broadcastAnnounce->is_value();
case ALT_connectionAbort: return field_connectionAbort->is_value();
default: TTCN_error("Invalid selection in union is_bound");}
}

void TP__CM::clean_up()
{
switch (union_selection) {
case ALT_requestToSend:
  delete field_requestToSend;
  break;
case ALT_clearToSend:
  delete field_clearToSend;
  break;
case ALT_endOfMessageAcknowledgement:
  delete field_endOfMessageAcknowledgement;
  break;
case ALT_broadcastAnnounce:
  delete field_broadcastAnnounce;
  break;
case ALT_connectionAbort:
  delete field_connectionAbort;
  break;
default:
  break;
}
union_selection = UNBOUND_VALUE;
}

void TP__CM::log() const
{
switch (union_selection) {
case ALT_requestToSend:
TTCN_Logger::log_event_str("{ requestToSend := ");
field_requestToSend->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_clearToSend:
TTCN_Logger::log_event_str("{ clearToSend := ");
field_clearToSend->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_endOfMessageAcknowledgement:
TTCN_Logger::log_event_str("{ endOfMessageAcknowledgement := ");
field_endOfMessageAcknowledgement->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_broadcastAnnounce:
TTCN_Logger::log_event_str("{ broadcastAnnounce := ");
field_broadcastAnnounce->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_connectionAbort:
TTCN_Logger::log_event_str("{ connectionAbort := ");
field_connectionAbort->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_unbound();
}
}

void TP__CM::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "union value");
  Module_Param_Ptr m_p = &param;
  if (m_p->get_type()==Module_Param::MP_Value_List && m_p->get_size()==0) return;
  if (m_p->get_type()!=Module_Param::MP_Assignment_List) {
    param.error("union value with field name was expected");
  }
  Module_Param* mp_last = m_p->get_elem(m_p->get_size()-1);
  char* last_name = mp_last->get_id()->get_name();
  if (!strcmp(last_name, "requestToSend")) {
    requestToSend().set_param(*mp_last);
    if (!requestToSend().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "clearToSend")) {
    clearToSend().set_param(*mp_last);
    if (!clearToSend().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "endOfMessageAcknowledgement")) {
    endOfMessageAcknowledgement().set_param(*mp_last);
    if (!endOfMessageAcknowledgement().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "broadcastAnnounce")) {
    broadcastAnnounce().set_param(*mp_last);
    if (!broadcastAnnounce().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "connectionAbort")) {
    connectionAbort().set_param(*mp_last);
    if (!connectionAbort().is_bound()) clean_up();
    return;
  }
  mp_last->error("Field %s does not exist in type @IsobusCMMessageTypes.TP_CM.", last_name);
}

void TP__CM::set_implicit_omit()
{
switch (union_selection) {
case ALT_requestToSend:
field_requestToSend->set_implicit_omit(); break;
case ALT_clearToSend:
field_clearToSend->set_implicit_omit(); break;
case ALT_endOfMessageAcknowledgement:
field_endOfMessageAcknowledgement->set_implicit_omit(); break;
case ALT_broadcastAnnounce:
field_broadcastAnnounce->set_implicit_omit(); break;
case ALT_connectionAbort:
field_connectionAbort->set_implicit_omit(); break;
default: break;
}
}

void TP__CM::encode_text(Text_Buf& text_buf) const
{
text_buf.push_int(union_selection);
switch (union_selection) {
case ALT_requestToSend:
field_requestToSend->encode_text(text_buf);
break;
case ALT_clearToSend:
field_clearToSend->encode_text(text_buf);
break;
case ALT_endOfMessageAcknowledgement:
field_endOfMessageAcknowledgement->encode_text(text_buf);
break;
case ALT_broadcastAnnounce:
field_broadcastAnnounce->encode_text(text_buf);
break;
case ALT_connectionAbort:
field_connectionAbort->encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an unbound value of union type @IsobusCMMessageTypes.TP_CM.");
}
}

void TP__CM::decode_text(Text_Buf& text_buf)
{
switch ((union_selection_type)text_buf.pull_int().get_val()) {
case ALT_requestToSend:
requestToSend().decode_text(text_buf);
break;
case ALT_clearToSend:
clearToSend().decode_text(text_buf);
break;
case ALT_endOfMessageAcknowledgement:
endOfMessageAcknowledgement().decode_text(text_buf);
break;
case ALT_broadcastAnnounce:
broadcastAnnounce().decode_text(text_buf);
break;
case ALT_connectionAbort:
connectionAbort().decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for type @IsobusCMMessageTypes.TP_CM.");
}
}

void TP__CM::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(TRUE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void TP__CM::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int TP__CM::RAW_decode(
const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, 
raw_order_t top_bit_ord, boolean no_err, int sel_field, boolean, const RAW_Force_Omit* force_omit)
{
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  int decoded_length=0;
  int starting_pos=p_buf.get_pos_bit();
  if(sel_field!=-1){
    switch(sel_field){
    case 0: {
      RAW_Force_Omit field_force_omit(0, force_omit, RequestToSend_descr_.raw->forceomit);
      decoded_length = requestToSend().RAW_decode(RequestToSend_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 1: {
      RAW_Force_Omit field_force_omit(1, force_omit, ClearToSend_descr_.raw->forceomit);
      decoded_length = clearToSend().RAW_decode(ClearToSend_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 2: {
      RAW_Force_Omit field_force_omit(2, force_omit, EndOfMessageAcknowledgement_descr_.raw->forceomit);
      decoded_length = endOfMessageAcknowledgement().RAW_decode(EndOfMessageAcknowledgement_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 3: {
      RAW_Force_Omit field_force_omit(3, force_omit, BroadcastAnnounce_descr_.raw->forceomit);
      decoded_length = broadcastAnnounce().RAW_decode(BroadcastAnnounce_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 4: {
      RAW_Force_Omit field_force_omit(4, force_omit, ConnectionAbort_descr_.raw->forceomit);
      decoded_length = connectionAbort().RAW_decode(ConnectionAbort_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    default: break;
    }
    return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
  } else {
    boolean already_failed = FALSE;
    already_failed = FALSE;
    if (!already_failed) {
      OCTETSTRING temporal_0;
      int decoded_0_length;
      p_buf.set_pos_bit(starting_pos + 0);
      decoded_0_length = temporal_0.RAW_decode(RequestToSend_ctrl_descr_, p_buf, limit, top_bit_ord, TRUE);
      if (decoded_0_length > 0) {
        if (temporal_0 ==  os_0) {
          p_buf.set_pos_bit(starting_pos);
          RAW_Force_Omit field_force_omit(0, force_omit, RequestToSend_descr_.raw->forceomit);
          decoded_length = requestToSend().RAW_decode(RequestToSend_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_force_omit);
          if (decoded_length > 0) {
             if ((*field_requestToSend).ctrl() ==  os_0) {
               return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
             }else already_failed = TRUE;
          }
        }
      }
    }
    already_failed = FALSE;
    if (!already_failed) {
      OCTETSTRING temporal_1;
      int decoded_1_length;
      p_buf.set_pos_bit(starting_pos + 0);
      decoded_1_length = temporal_1.RAW_decode(ClearToSend_ctrl_descr_, p_buf, limit, top_bit_ord, TRUE);
      if (decoded_1_length > 0) {
        if (temporal_1 ==  os_1) {
          p_buf.set_pos_bit(starting_pos);
          RAW_Force_Omit field_force_omit(1, force_omit, ClearToSend_descr_.raw->forceomit);
          decoded_length = clearToSend().RAW_decode(ClearToSend_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_force_omit);
          if (decoded_length > 0) {
             if ((*field_clearToSend).ctrl() ==  os_1) {
               return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
             }else already_failed = TRUE;
          }
        }
      }
    }
    already_failed = FALSE;
    if (!already_failed) {
      OCTETSTRING temporal_2;
      int decoded_2_length;
      p_buf.set_pos_bit(starting_pos + 0);
      decoded_2_length = temporal_2.RAW_decode(EndOfMessageAcknowledgement_ctrl_descr_, p_buf, limit, top_bit_ord, TRUE);
      if (decoded_2_length > 0) {
        if (temporal_2 ==  os_2) {
          p_buf.set_pos_bit(starting_pos);
          RAW_Force_Omit field_force_omit(2, force_omit, EndOfMessageAcknowledgement_descr_.raw->forceomit);
          decoded_length = endOfMessageAcknowledgement().RAW_decode(EndOfMessageAcknowledgement_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_force_omit);
          if (decoded_length > 0) {
             if ((*field_endOfMessageAcknowledgement).ctrl() ==  os_2) {
               return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
             }else already_failed = TRUE;
          }
        }
      }
    }
    already_failed = FALSE;
    if (!already_failed) {
      OCTETSTRING temporal_3;
      int decoded_3_length;
      p_buf.set_pos_bit(starting_pos + 0);
      decoded_3_length = temporal_3.RAW_decode(BroadcastAnnounce_ctrl_descr_, p_buf, limit, top_bit_ord, TRUE);
      if (decoded_3_length > 0) {
        if (temporal_3 ==  os_3) {
          p_buf.set_pos_bit(starting_pos);
          RAW_Force_Omit field_force_omit(3, force_omit, BroadcastAnnounce_descr_.raw->forceomit);
          decoded_length = broadcastAnnounce().RAW_decode(BroadcastAnnounce_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_force_omit);
          if (decoded_length > 0) {
             if ((*field_broadcastAnnounce).ctrl() ==  os_3) {
               return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
             }else already_failed = TRUE;
          }
        }
      }
    }
    already_failed = FALSE;
    if (!already_failed) {
      OCTETSTRING temporal_4;
      int decoded_4_length;
      p_buf.set_pos_bit(starting_pos + 0);
      decoded_4_length = temporal_4.RAW_decode(ConnectionAbort_ctrl_descr_, p_buf, limit, top_bit_ord, TRUE);
      if (decoded_4_length > 0) {
        if (temporal_4 ==  os_4) {
          p_buf.set_pos_bit(starting_pos);
          RAW_Force_Omit field_force_omit(4, force_omit, ConnectionAbort_descr_.raw->forceomit);
          decoded_length = connectionAbort().RAW_decode(ConnectionAbort_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_force_omit);
          if (decoded_length > 0) {
             if ((*field_connectionAbort).ctrl() ==  os_4) {
               return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
             }else already_failed = TRUE;
          }
        }
      }
    }
 }
 clean_up();
 return -1;
}

int TP__CM::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const
{
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 5;  myleaf.body.node.nodes = init_nodes_of_enc_tree(5);
  memset(myleaf.body.node.nodes, 0, 5 * sizeof(RAW_enc_tree *));
  switch (union_selection) {
  case ALT_requestToSend:
    myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 0, RequestToSend_descr_.raw);
    encoded_length = field_requestToSend->RAW_encode(RequestToSend_descr_, *myleaf.body.node.nodes[0]);
    myleaf.body.node.nodes[0]->coding_descr = &RequestToSend_descr_;
    if ((*field_requestToSend).ctrl() !=  os_0) {
  RAW_enc_tree* temp_leaf;
  {
  RAW_enc_tr_pos pr_pos0;
  pr_pos0.level=myleaf.curr_pos.level+2;
  int new_pos0[]={0,0};
  pr_pos0.pos=init_new_tree_pos(myleaf.curr_pos,2,new_pos0);
  temp_leaf = myleaf.get_node(pr_pos0);
  if(temp_leaf != NULL){
   os_0.RAW_encode(RequestToSend_ctrl_descr_,*temp_leaf);
  } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  }
  free_tree_pos(pr_pos0.pos);
  }
    }
    break;
  case ALT_clearToSend:
    myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 1, ClearToSend_descr_.raw);
    encoded_length = field_clearToSend->RAW_encode(ClearToSend_descr_, *myleaf.body.node.nodes[1]);
    myleaf.body.node.nodes[1]->coding_descr = &ClearToSend_descr_;
    if ((*field_clearToSend).ctrl() !=  os_1) {
  RAW_enc_tree* temp_leaf;
  {
  RAW_enc_tr_pos pr_pos0;
  pr_pos0.level=myleaf.curr_pos.level+2;
  int new_pos0[]={1,0};
  pr_pos0.pos=init_new_tree_pos(myleaf.curr_pos,2,new_pos0);
  temp_leaf = myleaf.get_node(pr_pos0);
  if(temp_leaf != NULL){
   os_1.RAW_encode(ClearToSend_ctrl_descr_,*temp_leaf);
  } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  }
  free_tree_pos(pr_pos0.pos);
  }
    }
    break;
  case ALT_endOfMessageAcknowledgement:
    myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 2, EndOfMessageAcknowledgement_descr_.raw);
    encoded_length = field_endOfMessageAcknowledgement->RAW_encode(EndOfMessageAcknowledgement_descr_, *myleaf.body.node.nodes[2]);
    myleaf.body.node.nodes[2]->coding_descr = &EndOfMessageAcknowledgement_descr_;
    if ((*field_endOfMessageAcknowledgement).ctrl() !=  os_2) {
  RAW_enc_tree* temp_leaf;
  {
  RAW_enc_tr_pos pr_pos0;
  pr_pos0.level=myleaf.curr_pos.level+2;
  int new_pos0[]={2,0};
  pr_pos0.pos=init_new_tree_pos(myleaf.curr_pos,2,new_pos0);
  temp_leaf = myleaf.get_node(pr_pos0);
  if(temp_leaf != NULL){
   os_2.RAW_encode(EndOfMessageAcknowledgement_ctrl_descr_,*temp_leaf);
  } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  }
  free_tree_pos(pr_pos0.pos);
  }
    }
    break;
  case ALT_broadcastAnnounce:
    myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 3, BroadcastAnnounce_descr_.raw);
    encoded_length = field_broadcastAnnounce->RAW_encode(BroadcastAnnounce_descr_, *myleaf.body.node.nodes[3]);
    myleaf.body.node.nodes[3]->coding_descr = &BroadcastAnnounce_descr_;
    if ((*field_broadcastAnnounce).ctrl() !=  os_3) {
  RAW_enc_tree* temp_leaf;
  {
  RAW_enc_tr_pos pr_pos0;
  pr_pos0.level=myleaf.curr_pos.level+2;
  int new_pos0[]={3,0};
  pr_pos0.pos=init_new_tree_pos(myleaf.curr_pos,2,new_pos0);
  temp_leaf = myleaf.get_node(pr_pos0);
  if(temp_leaf != NULL){
   os_3.RAW_encode(BroadcastAnnounce_ctrl_descr_,*temp_leaf);
  } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  }
  free_tree_pos(pr_pos0.pos);
  }
    }
    break;
  case ALT_connectionAbort:
    myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 4, ConnectionAbort_descr_.raw);
    encoded_length = field_connectionAbort->RAW_encode(ConnectionAbort_descr_, *myleaf.body.node.nodes[4]);
    myleaf.body.node.nodes[4]->coding_descr = &ConnectionAbort_descr_;
    if ((*field_connectionAbort).ctrl() !=  os_4) {
  RAW_enc_tree* temp_leaf;
  {
  RAW_enc_tr_pos pr_pos0;
  pr_pos0.level=myleaf.curr_pos.level+2;
  int new_pos0[]={4,0};
  pr_pos0.pos=init_new_tree_pos(myleaf.curr_pos,2,new_pos0);
  temp_leaf = myleaf.get_node(pr_pos0);
  if(temp_leaf != NULL){
   os_4.RAW_encode(ConnectionAbort_ctrl_descr_,*temp_leaf);
  } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  }
  free_tree_pos(pr_pos0.pos);
  }
    }
    break;
  default:
    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  }
  return encoded_length;
}

void TP__CM_template::copy_value(const TP__CM& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case TP__CM::ALT_requestToSend:
single_value.field_requestToSend = new RequestToSend_template(other_value.requestToSend());
break;
case TP__CM::ALT_clearToSend:
single_value.field_clearToSend = new ClearToSend_template(other_value.clearToSend());
break;
case TP__CM::ALT_endOfMessageAcknowledgement:
single_value.field_endOfMessageAcknowledgement = new EndOfMessageAcknowledgement_template(other_value.endOfMessageAcknowledgement());
break;
case TP__CM::ALT_broadcastAnnounce:
single_value.field_broadcastAnnounce = new BroadcastAnnounce_template(other_value.broadcastAnnounce());
break;
case TP__CM::ALT_connectionAbort:
single_value.field_connectionAbort = new ConnectionAbort_template(other_value.connectionAbort());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @IsobusCMMessageTypes.TP_CM.");
}
set_selection(SPECIFIC_VALUE);
}

void TP__CM_template::copy_template(const TP__CM_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value.union_selection = other_value.single_value.union_selection;
switch (single_value.union_selection) {
case TP__CM::ALT_requestToSend:
single_value.field_requestToSend = new RequestToSend_template(*other_value.single_value.field_requestToSend);
break;
case TP__CM::ALT_clearToSend:
single_value.field_clearToSend = new ClearToSend_template(*other_value.single_value.field_clearToSend);
break;
case TP__CM::ALT_endOfMessageAcknowledgement:
single_value.field_endOfMessageAcknowledgement = new EndOfMessageAcknowledgement_template(*other_value.single_value.field_endOfMessageAcknowledgement);
break;
case TP__CM::ALT_broadcastAnnounce:
single_value.field_broadcastAnnounce = new BroadcastAnnounce_template(*other_value.single_value.field_broadcastAnnounce);
break;
case TP__CM::ALT_connectionAbort:
single_value.field_connectionAbort = new ConnectionAbort_template(*other_value.single_value.field_connectionAbort);
break;
default:
TTCN_error("Internal error: Invalid union selector in a specific value when copying a template of type @IsobusCMMessageTypes.TP_CM.");
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new TP__CM_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized template of union type @IsobusCMMessageTypes.TP_CM.");
}
set_selection(other_value);
}

TP__CM_template::TP__CM_template()
{
}

TP__CM_template::TP__CM_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

TP__CM_template::TP__CM_template(const TP__CM& other_value)
{
copy_value(other_value);
}

TP__CM_template::TP__CM_template(const OPTIONAL<TP__CM>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const TP__CM&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of union type @IsobusCMMessageTypes.TP_CM from an unbound optional field.");
}
}

TP__CM_template::TP__CM_template(const TP__CM_template& other_value)
: Base_Template(){
copy_template(other_value);
}

TP__CM_template::~TP__CM_template()
{
clean_up();
}

void TP__CM_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case TP__CM::ALT_requestToSend:
delete single_value.field_requestToSend;
break;
case TP__CM::ALT_clearToSend:
delete single_value.field_clearToSend;
break;
case TP__CM::ALT_endOfMessageAcknowledgement:
delete single_value.field_endOfMessageAcknowledgement;
break;
case TP__CM::ALT_broadcastAnnounce:
delete single_value.field_broadcastAnnounce;
break;
case TP__CM::ALT_connectionAbort:
delete single_value.field_connectionAbort;
default:
break;
}
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

TP__CM_template& TP__CM_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

TP__CM_template& TP__CM_template::operator=(const TP__CM& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

TP__CM_template& TP__CM_template::operator=(const OPTIONAL<TP__CM>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const TP__CM&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of union type @IsobusCMMessageTypes.TP_CM.");
}
return *this;
}

TP__CM_template& TP__CM_template::operator=(const TP__CM_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean TP__CM_template::match(const TP__CM& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
{
TP__CM::union_selection_type value_selection = other_value.get_selection();
if (value_selection == TP__CM::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case TP__CM::ALT_requestToSend:
return single_value.field_requestToSend->match(other_value.requestToSend(), legacy);
case TP__CM::ALT_clearToSend:
return single_value.field_clearToSend->match(other_value.clearToSend(), legacy);
case TP__CM::ALT_endOfMessageAcknowledgement:
return single_value.field_endOfMessageAcknowledgement->match(other_value.endOfMessageAcknowledgement(), legacy);
case TP__CM::ALT_broadcastAnnounce:
return single_value.field_broadcastAnnounce->match(other_value.broadcastAnnounce(), legacy);
case TP__CM::ALT_connectionAbort:
return single_value.field_connectionAbort->match(other_value.connectionAbort(), legacy);
default:
TTCN_error("Internal error: Invalid selector in a specific value when matching a template of union type @IsobusCMMessageTypes.TP_CM.");
}
}
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error ("Matching an uninitialized template of union type @IsobusCMMessageTypes.TP_CM.");
}
return FALSE;
}

boolean TP__CM_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case TP__CM::ALT_requestToSend:
return single_value.field_requestToSend->is_value();
case TP__CM::ALT_clearToSend:
return single_value.field_clearToSend->is_value();
case TP__CM::ALT_endOfMessageAcknowledgement:
return single_value.field_endOfMessageAcknowledgement->is_value();
case TP__CM::ALT_broadcastAnnounce:
return single_value.field_broadcastAnnounce->is_value();
case TP__CM::ALT_connectionAbort:
return single_value.field_connectionAbort->is_value();
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing is_value operation on a template of union type @IsobusCMMessageTypes.TP_CM.");
}
}

TP__CM TP__CM_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of union type @IsobusCMMessageTypes.TP_CM.");
TP__CM ret_val;
switch (single_value.union_selection) {
case TP__CM::ALT_requestToSend:
ret_val.requestToSend() = single_value.field_requestToSend->valueof();
break;
case TP__CM::ALT_clearToSend:
ret_val.clearToSend() = single_value.field_clearToSend->valueof();
break;
case TP__CM::ALT_endOfMessageAcknowledgement:
ret_val.endOfMessageAcknowledgement() = single_value.field_endOfMessageAcknowledgement->valueof();
break;
case TP__CM::ALT_broadcastAnnounce:
ret_val.broadcastAnnounce() = single_value.field_broadcastAnnounce->valueof();
break;
case TP__CM::ALT_connectionAbort:
ret_val.connectionAbort() = single_value.field_connectionAbort->valueof();
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing valueof operation on a template of union type @IsobusCMMessageTypes.TP_CM.");
}
return ret_val;
}

TP__CM_template& TP__CM_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST) TTCN_error("Internal error: Accessing a list element of a non-list template of union type @IsobusCMMessageTypes.TP_CM.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of union type @IsobusCMMessageTypes.TP_CM.");
return value_list.list_value[list_index];
}
void TP__CM_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) TTCN_error ("Internal error: Setting an invalid list for a template of union type @IsobusCMMessageTypes.TP_CM.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new TP__CM_template[list_length];
}

RequestToSend_template& TP__CM_template::requestToSend()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != TP__CM::ALT_requestToSend) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_requestToSend = new RequestToSend_template(ANY_VALUE);
else single_value.field_requestToSend = new RequestToSend_template;
single_value.union_selection = TP__CM::ALT_requestToSend;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_requestToSend;
}

const RequestToSend_template& TP__CM_template::requestToSend() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field requestToSend in a non-specific template of union type @IsobusCMMessageTypes.TP_CM.");
if (single_value.union_selection != TP__CM::ALT_requestToSend) TTCN_error("Accessing non-selected field requestToSend in a template of union type @IsobusCMMessageTypes.TP_CM.");
return *single_value.field_requestToSend;
}

ClearToSend_template& TP__CM_template::clearToSend()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != TP__CM::ALT_clearToSend) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_clearToSend = new ClearToSend_template(ANY_VALUE);
else single_value.field_clearToSend = new ClearToSend_template;
single_value.union_selection = TP__CM::ALT_clearToSend;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_clearToSend;
}

const ClearToSend_template& TP__CM_template::clearToSend() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field clearToSend in a non-specific template of union type @IsobusCMMessageTypes.TP_CM.");
if (single_value.union_selection != TP__CM::ALT_clearToSend) TTCN_error("Accessing non-selected field clearToSend in a template of union type @IsobusCMMessageTypes.TP_CM.");
return *single_value.field_clearToSend;
}

EndOfMessageAcknowledgement_template& TP__CM_template::endOfMessageAcknowledgement()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != TP__CM::ALT_endOfMessageAcknowledgement) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_endOfMessageAcknowledgement = new EndOfMessageAcknowledgement_template(ANY_VALUE);
else single_value.field_endOfMessageAcknowledgement = new EndOfMessageAcknowledgement_template;
single_value.union_selection = TP__CM::ALT_endOfMessageAcknowledgement;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_endOfMessageAcknowledgement;
}

const EndOfMessageAcknowledgement_template& TP__CM_template::endOfMessageAcknowledgement() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field endOfMessageAcknowledgement in a non-specific template of union type @IsobusCMMessageTypes.TP_CM.");
if (single_value.union_selection != TP__CM::ALT_endOfMessageAcknowledgement) TTCN_error("Accessing non-selected field endOfMessageAcknowledgement in a template of union type @IsobusCMMessageTypes.TP_CM.");
return *single_value.field_endOfMessageAcknowledgement;
}

BroadcastAnnounce_template& TP__CM_template::broadcastAnnounce()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != TP__CM::ALT_broadcastAnnounce) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_broadcastAnnounce = new BroadcastAnnounce_template(ANY_VALUE);
else single_value.field_broadcastAnnounce = new BroadcastAnnounce_template;
single_value.union_selection = TP__CM::ALT_broadcastAnnounce;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_broadcastAnnounce;
}

const BroadcastAnnounce_template& TP__CM_template::broadcastAnnounce() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field broadcastAnnounce in a non-specific template of union type @IsobusCMMessageTypes.TP_CM.");
if (single_value.union_selection != TP__CM::ALT_broadcastAnnounce) TTCN_error("Accessing non-selected field broadcastAnnounce in a template of union type @IsobusCMMessageTypes.TP_CM.");
return *single_value.field_broadcastAnnounce;
}

ConnectionAbort_template& TP__CM_template::connectionAbort()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != TP__CM::ALT_connectionAbort) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_connectionAbort = new ConnectionAbort_template(ANY_VALUE);
else single_value.field_connectionAbort = new ConnectionAbort_template;
single_value.union_selection = TP__CM::ALT_connectionAbort;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_connectionAbort;
}

const ConnectionAbort_template& TP__CM_template::connectionAbort() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field connectionAbort in a non-specific template of union type @IsobusCMMessageTypes.TP_CM.");
if (single_value.union_selection != TP__CM::ALT_connectionAbort) TTCN_error("Accessing non-selected field connectionAbort in a template of union type @IsobusCMMessageTypes.TP_CM.");
return *single_value.field_connectionAbort;
}

boolean TP__CM_template::ischosen(TP__CM::union_selection_type checked_selection) const
{
if (checked_selection == TP__CM::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @IsobusCMMessageTypes.TP_CM.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == TP__CM::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @IsobusCMMessageTypes.TP_CM.");
return single_value.union_selection == checked_selection;
case VALUE_LIST:
{
if (value_list.n_values < 1)
TTCN_error("Internal error: Performing ischosen() operation on a template of union type @IsobusCMMessageTypes.TP_CM containing an empty list.");
boolean ret_val = value_list.list_value[0].ischosen(checked_selection);
for (unsigned int list_count = 1; ret_val == TRUE && list_count < value_list.n_values; list_count++) {
ret_val = value_list.list_value[list_count].ischosen(checked_selection);
}
return ret_val;
}
default:
return FALSE;
}
return FALSE;
}

void TP__CM_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case TP__CM::ALT_requestToSend:
TTCN_Logger::log_event_str("{ requestToSend := ");
single_value.field_requestToSend->log();
TTCN_Logger::log_event_str(" }");
break;
case TP__CM::ALT_clearToSend:
TTCN_Logger::log_event_str("{ clearToSend := ");
single_value.field_clearToSend->log();
TTCN_Logger::log_event_str(" }");
break;
case TP__CM::ALT_endOfMessageAcknowledgement:
TTCN_Logger::log_event_str("{ endOfMessageAcknowledgement := ");
single_value.field_endOfMessageAcknowledgement->log();
TTCN_Logger::log_event_str(" }");
break;
case TP__CM::ALT_broadcastAnnounce:
TTCN_Logger::log_event_str("{ broadcastAnnounce := ");
single_value.field_broadcastAnnounce->log();
TTCN_Logger::log_event_str(" }");
break;
case TP__CM::ALT_connectionAbort:
TTCN_Logger::log_event_str("{ connectionAbort := ");
single_value.field_connectionAbort->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_str("<invalid selector>");
}
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void TP__CM_template::log_match(const TP__CM& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity() && match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
return;
}
if (template_selection == SPECIFIC_VALUE && single_value.union_selection == match_value.get_selection()) {
switch (single_value.union_selection) {
case TP__CM::ALT_requestToSend:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".requestToSend");
single_value.field_requestToSend->log_match(match_value.requestToSend(), legacy);
} else {
TTCN_Logger::log_event_str("{ requestToSend := ");
single_value.field_requestToSend->log_match(match_value.requestToSend(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case TP__CM::ALT_clearToSend:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".clearToSend");
single_value.field_clearToSend->log_match(match_value.clearToSend(), legacy);
} else {
TTCN_Logger::log_event_str("{ clearToSend := ");
single_value.field_clearToSend->log_match(match_value.clearToSend(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case TP__CM::ALT_endOfMessageAcknowledgement:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".endOfMessageAcknowledgement");
single_value.field_endOfMessageAcknowledgement->log_match(match_value.endOfMessageAcknowledgement(), legacy);
} else {
TTCN_Logger::log_event_str("{ endOfMessageAcknowledgement := ");
single_value.field_endOfMessageAcknowledgement->log_match(match_value.endOfMessageAcknowledgement(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case TP__CM::ALT_broadcastAnnounce:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".broadcastAnnounce");
single_value.field_broadcastAnnounce->log_match(match_value.broadcastAnnounce(), legacy);
} else {
TTCN_Logger::log_event_str("{ broadcastAnnounce := ");
single_value.field_broadcastAnnounce->log_match(match_value.broadcastAnnounce(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case TP__CM::ALT_connectionAbort:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".connectionAbort");
single_value.field_connectionAbort->log_match(match_value.connectionAbort(), legacy);
} else {
TTCN_Logger::log_event_str("{ connectionAbort := ");
single_value.field_connectionAbort->log_match(match_value.connectionAbort(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
default:
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str("<invalid selector>");
}
} else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void TP__CM_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
text_buf.push_int(single_value.union_selection);
switch (single_value.union_selection) {
case TP__CM::ALT_requestToSend:
single_value.field_requestToSend->encode_text(text_buf);
break;
case TP__CM::ALT_clearToSend:
single_value.field_clearToSend->encode_text(text_buf);
break;
case TP__CM::ALT_endOfMessageAcknowledgement:
single_value.field_endOfMessageAcknowledgement->encode_text(text_buf);
break;
case TP__CM::ALT_broadcastAnnounce:
single_value.field_broadcastAnnounce->encode_text(text_buf);
break;
case TP__CM::ALT_connectionAbort:
single_value.field_connectionAbort->encode_text(text_buf);
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when encoding a template of union type @IsobusCMMessageTypes.TP_CM.");
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized template of type @IsobusCMMessageTypes.TP_CM.");
}
}

void TP__CM_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
{
single_value.union_selection = TP__CM::UNBOUND_VALUE;
TP__CM::union_selection_type new_selection = (TP__CM::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case TP__CM::ALT_requestToSend:
single_value.field_requestToSend = new RequestToSend_template;
single_value.field_requestToSend->decode_text(text_buf);
break;
case TP__CM::ALT_clearToSend:
single_value.field_clearToSend = new ClearToSend_template;
single_value.field_clearToSend->decode_text(text_buf);
break;
case TP__CM::ALT_endOfMessageAcknowledgement:
single_value.field_endOfMessageAcknowledgement = new EndOfMessageAcknowledgement_template;
single_value.field_endOfMessageAcknowledgement->decode_text(text_buf);
break;
case TP__CM::ALT_broadcastAnnounce:
single_value.field_broadcastAnnounce = new BroadcastAnnounce_template;
single_value.field_broadcastAnnounce->decode_text(text_buf);
break;
case TP__CM::ALT_connectionAbort:
single_value.field_connectionAbort = new ConnectionAbort_template;
single_value.field_connectionAbort->decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for a template of type @IsobusCMMessageTypes.TP_CM.");
}
single_value.union_selection = new_selection;
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new TP__CM_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized selector was received in a template of type @IsobusCMMessageTypes.TP_CM.");
}
}

boolean TP__CM_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean TP__CM_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int v_idx=0; v_idx<value_list.n_values; v_idx++)
if (value_list.list_value[v_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void TP__CM_template::set_param(Module_Param& param)
{
  if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&
      param.get_id()->next_name()) {
    char* param_field = param.get_id()->get_current_name();
    if (param_field[0] >= '0' && param_field[0] <= '9') {
      param.error("Unexpected array index in module parameter, expected a valid field"
        " name for union template type `@IsobusCMMessageTypes.TP_CM'");
    }
    if (strcmp("requestToSend", param_field) == 0) {
      requestToSend().set_param(param);
      return;
    } else if (strcmp("clearToSend", param_field) == 0) {
      clearToSend().set_param(param);
      return;
    } else if (strcmp("endOfMessageAcknowledgement", param_field) == 0) {
      endOfMessageAcknowledgement().set_param(param);
      return;
    } else if (strcmp("broadcastAnnounce", param_field) == 0) {
      broadcastAnnounce().set_param(param);
      return;
    } else if (strcmp("connectionAbort", param_field) == 0) {
      connectionAbort().set_param(param);
      return;
    } else param.error("Field `%s' not found in union template type `@IsobusCMMessageTypes.TP_CM'", param_field);
  }
  param.basic_check(Module_Param::BC_TEMPLATE, "union template");
  Module_Param_Ptr m_p = &param;
  switch (m_p->get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    TP__CM_template new_temp;
    new_temp.set_type(m_p->get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, m_p->get_size());
    for (size_t p_i=0; p_i<m_p->get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*m_p->get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (m_p->get_size()==0) break;
    param.type_error("union template", "@IsobusCMMessageTypes.TP_CM");
    break;
  case Module_Param::MP_Assignment_List: {
    Module_Param* mp_last = m_p->get_elem(m_p->get_size()-1);
    char* last_name = mp_last->get_id()->get_name();
    if (!strcmp(last_name, "requestToSend")) {
      requestToSend().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "clearToSend")) {
      clearToSend().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "endOfMessageAcknowledgement")) {
      endOfMessageAcknowledgement().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "broadcastAnnounce")) {
      broadcastAnnounce().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "connectionAbort")) {
      connectionAbort().set_param(*mp_last);
      break;
    }
    mp_last->error("Field %s does not exist in type @IsobusCMMessageTypes.TP_CM.", last_name);
  } break;
  default:
    param.type_error("union template", "@IsobusCMMessageTypes.TP_CM");
  }
  is_ifpresent = param.get_ifpresent();
}

void TP__CM_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
switch (single_value.union_selection) {
case TP__CM::ALT_requestToSend:
single_value.field_requestToSend->check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.TP_CM");
return;
case TP__CM::ALT_clearToSend:
single_value.field_clearToSend->check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.TP_CM");
return;
case TP__CM::ALT_endOfMessageAcknowledgement:
single_value.field_endOfMessageAcknowledgement->check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.TP_CM");
return;
case TP__CM::ALT_broadcastAnnounce:
single_value.field_broadcastAnnounce->check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.TP_CM");
return;
case TP__CM::ALT_connectionAbort:
single_value.field_connectionAbort->check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.TP_CM");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @IsobusCMMessageTypes.TP_CM.");
}
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.TP_CM");
}

ExtendedMessageRequestToSend::ExtendedMessageRequestToSend()
{
}

ExtendedMessageRequestToSend::ExtendedMessageRequestToSend(const OCTETSTRING& par_ctrl,
    const INTEGER& par_msgSizeInBytes,
    const INTEGER& par_pgnOfExtendedPacketedMessage)
  :   field_ctrl(par_ctrl),
  field_msgSizeInBytes(par_msgSizeInBytes),
  field_pgnOfExtendedPacketedMessage(par_pgnOfExtendedPacketedMessage)
{
}

ExtendedMessageRequestToSend::ExtendedMessageRequestToSend(const ExtendedMessageRequestToSend& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
else field_ctrl.clean_up();
if (other_value.msgSizeInBytes().is_bound()) field_msgSizeInBytes = other_value.msgSizeInBytes();
else field_msgSizeInBytes.clean_up();
if (other_value.pgnOfExtendedPacketedMessage().is_bound()) field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
else field_pgnOfExtendedPacketedMessage.clean_up();
}

void ExtendedMessageRequestToSend::clean_up()
{
field_ctrl.clean_up();
field_msgSizeInBytes.clean_up();
field_pgnOfExtendedPacketedMessage.clean_up();
}

const TTCN_Typedescriptor_t* ExtendedMessageRequestToSend::get_descriptor() const { return &ExtendedMessageRequestToSend_descr_; }
ExtendedMessageRequestToSend& ExtendedMessageRequestToSend::operator=(const ExtendedMessageRequestToSend& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
  if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
  else field_ctrl.clean_up();
  if (other_value.msgSizeInBytes().is_bound()) field_msgSizeInBytes = other_value.msgSizeInBytes();
  else field_msgSizeInBytes.clean_up();
  if (other_value.pgnOfExtendedPacketedMessage().is_bound()) field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
  else field_pgnOfExtendedPacketedMessage.clean_up();
}
return *this;
}

boolean ExtendedMessageRequestToSend::operator==(const ExtendedMessageRequestToSend& other_value) const
{
return field_ctrl==other_value.field_ctrl
  && field_msgSizeInBytes==other_value.field_msgSizeInBytes
  && field_pgnOfExtendedPacketedMessage==other_value.field_pgnOfExtendedPacketedMessage;
}

boolean ExtendedMessageRequestToSend::is_bound() const
{
return (field_ctrl.is_bound())
  || (field_msgSizeInBytes.is_bound())
  || (field_pgnOfExtendedPacketedMessage.is_bound());
}
boolean ExtendedMessageRequestToSend::is_value() const
{
return field_ctrl.is_value()
  && field_msgSizeInBytes.is_value()
  && field_pgnOfExtendedPacketedMessage.is_value();
}
void ExtendedMessageRequestToSend::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ctrl := ");
field_ctrl.log();
TTCN_Logger::log_event_str(", msgSizeInBytes := ");
field_msgSizeInBytes.log();
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
field_pgnOfExtendedPacketedMessage.log();
TTCN_Logger::log_event_str(" }");
}

void ExtendedMessageRequestToSend::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (3<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend has 3 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) msgSizeInBytes().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) pgnOfExtendedPacketedMessage().set_param(*param.get_elem(2));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "msgSizeInBytes")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          msgSizeInBytes().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfExtendedPacketedMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfExtendedPacketedMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ExtendedMessageRequestToSend: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.ExtendedMessageRequestToSend");
  }
}

void ExtendedMessageRequestToSend::set_implicit_omit()
{
if (ctrl().is_bound()) ctrl().set_implicit_omit();
if (msgSizeInBytes().is_bound()) msgSizeInBytes().set_implicit_omit();
if (pgnOfExtendedPacketedMessage().is_bound()) pgnOfExtendedPacketedMessage().set_implicit_omit();
}

void ExtendedMessageRequestToSend::encode_text(Text_Buf& text_buf) const
{
field_ctrl.encode_text(text_buf);
field_msgSizeInBytes.encode_text(text_buf);
field_pgnOfExtendedPacketedMessage.encode_text(text_buf);
}

void ExtendedMessageRequestToSend::decode_text(Text_Buf& text_buf)
{
field_ctrl.decode_text(text_buf);
field_msgSizeInBytes.decode_text(text_buf);
field_pgnOfExtendedPacketedMessage.decode_text(text_buf);
}

void ExtendedMessageRequestToSend::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void ExtendedMessageRequestToSend::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int ExtendedMessageRequestToSend::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, ExtendedMessageRequestToSend_ctrl_descr_.raw->forceomit);
  decoded_field_length = field_ctrl.RAW_decode(ExtendedMessageRequestToSend_ctrl_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, ETP__MSG__SIZE_descr_.raw->forceomit);
  decoded_field_length = field_msgSizeInBytes.RAW_decode(ETP__MSG__SIZE_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, IsobusMessageTypes::PGN_descr_.raw->forceomit);
  decoded_field_length = field_pgnOfExtendedPacketedMessage.RAW_decode(IsobusMessageTypes::PGN_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int ExtendedMessageRequestToSend::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 3;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(3);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, ExtendedMessageRequestToSend_ctrl_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, ETP__MSG__SIZE_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, IsobusMessageTypes::PGN_descr_.raw);
  encoded_length += field_ctrl.RAW_encode(ExtendedMessageRequestToSend_ctrl_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_msgSizeInBytes.RAW_encode(ETP__MSG__SIZE_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_pgnOfExtendedPacketedMessage.RAW_encode(IsobusMessageTypes::PGN_descr_, *myleaf.body.node.nodes[2]);
  return myleaf.length = encoded_length;
}

struct ExtendedMessageRequestToSend_template::single_value_struct {
OCTETSTRING_template field_ctrl;
INTEGER_template field_msgSizeInBytes;
INTEGER_template field_pgnOfExtendedPacketedMessage;
};

void ExtendedMessageRequestToSend_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_ctrl = ANY_VALUE;
single_value->field_msgSizeInBytes = ANY_VALUE;
single_value->field_pgnOfExtendedPacketedMessage = ANY_VALUE;
}
}
}

void ExtendedMessageRequestToSend_template::copy_value(const ExtendedMessageRequestToSend& other_value)
{
single_value = new single_value_struct;
if (other_value.ctrl().is_bound()) {
  single_value->field_ctrl = other_value.ctrl();
} else {
  single_value->field_ctrl.clean_up();
}
if (other_value.msgSizeInBytes().is_bound()) {
  single_value->field_msgSizeInBytes = other_value.msgSizeInBytes();
} else {
  single_value->field_msgSizeInBytes.clean_up();
}
if (other_value.pgnOfExtendedPacketedMessage().is_bound()) {
  single_value->field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
} else {
  single_value->field_pgnOfExtendedPacketedMessage.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void ExtendedMessageRequestToSend_template::copy_template(const ExtendedMessageRequestToSend_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ctrl().get_selection()) {
single_value->field_ctrl = other_value.ctrl();
} else {
single_value->field_ctrl.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.msgSizeInBytes().get_selection()) {
single_value->field_msgSizeInBytes = other_value.msgSizeInBytes();
} else {
single_value->field_msgSizeInBytes.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pgnOfExtendedPacketedMessage().get_selection()) {
single_value->field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
} else {
single_value->field_pgnOfExtendedPacketedMessage.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new ExtendedMessageRequestToSend_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
break;
}
set_selection(other_value);
}

ExtendedMessageRequestToSend_template::ExtendedMessageRequestToSend_template()
{
}

ExtendedMessageRequestToSend_template::ExtendedMessageRequestToSend_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

ExtendedMessageRequestToSend_template::ExtendedMessageRequestToSend_template(const ExtendedMessageRequestToSend& other_value)
{
copy_value(other_value);
}

ExtendedMessageRequestToSend_template::ExtendedMessageRequestToSend_template(const OPTIONAL<ExtendedMessageRequestToSend>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ExtendedMessageRequestToSend&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend from an unbound optional field.");
}
}

ExtendedMessageRequestToSend_template::ExtendedMessageRequestToSend_template(const ExtendedMessageRequestToSend_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

ExtendedMessageRequestToSend_template::~ExtendedMessageRequestToSend_template()
{
clean_up();
}

ExtendedMessageRequestToSend_template& ExtendedMessageRequestToSend_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

ExtendedMessageRequestToSend_template& ExtendedMessageRequestToSend_template::operator=(const ExtendedMessageRequestToSend& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

ExtendedMessageRequestToSend_template& ExtendedMessageRequestToSend_template::operator=(const OPTIONAL<ExtendedMessageRequestToSend>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ExtendedMessageRequestToSend&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
}
return *this;
}

ExtendedMessageRequestToSend_template& ExtendedMessageRequestToSend_template::operator=(const ExtendedMessageRequestToSend_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean ExtendedMessageRequestToSend_template::match(const ExtendedMessageRequestToSend& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.ctrl().is_bound()) return FALSE;
if(!single_value->field_ctrl.match(other_value.ctrl(), legacy))return FALSE;
if(!other_value.msgSizeInBytes().is_bound()) return FALSE;
if(!single_value->field_msgSizeInBytes.match(other_value.msgSizeInBytes(), legacy))return FALSE;
if(!other_value.pgnOfExtendedPacketedMessage().is_bound()) return FALSE;
if(!single_value->field_pgnOfExtendedPacketedMessage.match(other_value.pgnOfExtendedPacketedMessage(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
}
return FALSE;
}

boolean ExtendedMessageRequestToSend_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_ctrl.is_bound()

 ||single_value->field_msgSizeInBytes.is_bound()

 ||single_value->field_pgnOfExtendedPacketedMessage.is_bound()
;
}

boolean ExtendedMessageRequestToSend_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ctrl.is_value()
 &&single_value->field_msgSizeInBytes.is_value()
 &&single_value->field_pgnOfExtendedPacketedMessage.is_value();
}

void ExtendedMessageRequestToSend_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

ExtendedMessageRequestToSend ExtendedMessageRequestToSend_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
ExtendedMessageRequestToSend ret_val;
if (single_value->field_ctrl.is_bound()) {
ret_val.ctrl() = single_value->field_ctrl.valueof();
}
if (single_value->field_msgSizeInBytes.is_bound()) {
ret_val.msgSizeInBytes() = single_value->field_msgSizeInBytes.valueof();
}
if (single_value->field_pgnOfExtendedPacketedMessage.is_bound()) {
ret_val.pgnOfExtendedPacketedMessage() = single_value->field_pgnOfExtendedPacketedMessage.valueof();
}
return ret_val;
}

void ExtendedMessageRequestToSend_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new ExtendedMessageRequestToSend_template[list_length];
}

ExtendedMessageRequestToSend_template& ExtendedMessageRequestToSend_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& ExtendedMessageRequestToSend_template::ctrl()
{
set_specific();
return single_value->field_ctrl;
}

const OCTETSTRING_template& ExtendedMessageRequestToSend_template::ctrl() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ctrl of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
return single_value->field_ctrl;
}

INTEGER_template& ExtendedMessageRequestToSend_template::msgSizeInBytes()
{
set_specific();
return single_value->field_msgSizeInBytes;
}

const INTEGER_template& ExtendedMessageRequestToSend_template::msgSizeInBytes() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field msgSizeInBytes of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
return single_value->field_msgSizeInBytes;
}

INTEGER_template& ExtendedMessageRequestToSend_template::pgnOfExtendedPacketedMessage()
{
set_specific();
return single_value->field_pgnOfExtendedPacketedMessage;
}

const INTEGER_template& ExtendedMessageRequestToSend_template::pgnOfExtendedPacketedMessage() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pgnOfExtendedPacketedMessage of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
return single_value->field_pgnOfExtendedPacketedMessage;
}

int ExtendedMessageRequestToSend_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 3;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
  }
  return 0;
}

void ExtendedMessageRequestToSend_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log();
TTCN_Logger::log_event_str(", msgSizeInBytes := ");
single_value->field_msgSizeInBytes.log();
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
single_value->field_pgnOfExtendedPacketedMessage.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void ExtendedMessageRequestToSend_template::log_match(const ExtendedMessageRequestToSend& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_ctrl.match(match_value.ctrl(), legacy)){
TTCN_Logger::log_logmatch_info(".ctrl");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_msgSizeInBytes.match(match_value.msgSizeInBytes(), legacy)){
TTCN_Logger::log_logmatch_info(".msgSizeInBytes");
single_value->field_msgSizeInBytes.log_match(match_value.msgSizeInBytes(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pgnOfExtendedPacketedMessage.match(match_value.pgnOfExtendedPacketedMessage(), legacy)){
TTCN_Logger::log_logmatch_info(".pgnOfExtendedPacketedMessage");
single_value->field_pgnOfExtendedPacketedMessage.log_match(match_value.pgnOfExtendedPacketedMessage(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::log_event_str(", msgSizeInBytes := ");
single_value->field_msgSizeInBytes.log_match(match_value.msgSizeInBytes(), legacy);
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
single_value->field_pgnOfExtendedPacketedMessage.log_match(match_value.pgnOfExtendedPacketedMessage(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void ExtendedMessageRequestToSend_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ctrl.encode_text(text_buf);
single_value->field_msgSizeInBytes.encode_text(text_buf);
single_value->field_pgnOfExtendedPacketedMessage.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
}
}

void ExtendedMessageRequestToSend_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_ctrl.decode_text(text_buf);
single_value->field_msgSizeInBytes.decode_text(text_buf);
single_value->field_pgnOfExtendedPacketedMessage.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new ExtendedMessageRequestToSend_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend.");
}
}

void ExtendedMessageRequestToSend_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    ExtendedMessageRequestToSend_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (3<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.ExtendedMessageRequestToSend has 3 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) msgSizeInBytes().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) pgnOfExtendedPacketedMessage().set_param(*param.get_elem(2));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "msgSizeInBytes")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          msgSizeInBytes().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfExtendedPacketedMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfExtendedPacketedMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ExtendedMessageRequestToSend: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.ExtendedMessageRequestToSend");
  }
  is_ifpresent = param.get_ifpresent();
}

void ExtendedMessageRequestToSend_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_ctrl.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageRequestToSend");
single_value->field_msgSizeInBytes.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageRequestToSend");
single_value->field_pgnOfExtendedPacketedMessage.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageRequestToSend");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageRequestToSend");
}

boolean ExtendedMessageRequestToSend_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean ExtendedMessageRequestToSend_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

ExtendedMessageClearToSend::ExtendedMessageClearToSend()
{
}

ExtendedMessageClearToSend::ExtendedMessageClearToSend(const OCTETSTRING& par_ctrl,
    const INTEGER& par_NumberOfPacketsToSend,
    const INTEGER& par_nextPacketNumberToSend,
    const INTEGER& par_pgnOfExtendedPacketedMessage)
  :   field_ctrl(par_ctrl),
  field_NumberOfPacketsToSend(par_NumberOfPacketsToSend),
  field_nextPacketNumberToSend(par_nextPacketNumberToSend),
  field_pgnOfExtendedPacketedMessage(par_pgnOfExtendedPacketedMessage)
{
}

ExtendedMessageClearToSend::ExtendedMessageClearToSend(const ExtendedMessageClearToSend& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
else field_ctrl.clean_up();
if (other_value.NumberOfPacketsToSend().is_bound()) field_NumberOfPacketsToSend = other_value.NumberOfPacketsToSend();
else field_NumberOfPacketsToSend.clean_up();
if (other_value.nextPacketNumberToSend().is_bound()) field_nextPacketNumberToSend = other_value.nextPacketNumberToSend();
else field_nextPacketNumberToSend.clean_up();
if (other_value.pgnOfExtendedPacketedMessage().is_bound()) field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
else field_pgnOfExtendedPacketedMessage.clean_up();
}

void ExtendedMessageClearToSend::clean_up()
{
field_ctrl.clean_up();
field_NumberOfPacketsToSend.clean_up();
field_nextPacketNumberToSend.clean_up();
field_pgnOfExtendedPacketedMessage.clean_up();
}

const TTCN_Typedescriptor_t* ExtendedMessageClearToSend::get_descriptor() const { return &ExtendedMessageClearToSend_descr_; }
ExtendedMessageClearToSend& ExtendedMessageClearToSend::operator=(const ExtendedMessageClearToSend& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
  if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
  else field_ctrl.clean_up();
  if (other_value.NumberOfPacketsToSend().is_bound()) field_NumberOfPacketsToSend = other_value.NumberOfPacketsToSend();
  else field_NumberOfPacketsToSend.clean_up();
  if (other_value.nextPacketNumberToSend().is_bound()) field_nextPacketNumberToSend = other_value.nextPacketNumberToSend();
  else field_nextPacketNumberToSend.clean_up();
  if (other_value.pgnOfExtendedPacketedMessage().is_bound()) field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
  else field_pgnOfExtendedPacketedMessage.clean_up();
}
return *this;
}

boolean ExtendedMessageClearToSend::operator==(const ExtendedMessageClearToSend& other_value) const
{
return field_ctrl==other_value.field_ctrl
  && field_NumberOfPacketsToSend==other_value.field_NumberOfPacketsToSend
  && field_nextPacketNumberToSend==other_value.field_nextPacketNumberToSend
  && field_pgnOfExtendedPacketedMessage==other_value.field_pgnOfExtendedPacketedMessage;
}

boolean ExtendedMessageClearToSend::is_bound() const
{
return (field_ctrl.is_bound())
  || (field_NumberOfPacketsToSend.is_bound())
  || (field_nextPacketNumberToSend.is_bound())
  || (field_pgnOfExtendedPacketedMessage.is_bound());
}
boolean ExtendedMessageClearToSend::is_value() const
{
return field_ctrl.is_value()
  && field_NumberOfPacketsToSend.is_value()
  && field_nextPacketNumberToSend.is_value()
  && field_pgnOfExtendedPacketedMessage.is_value();
}
void ExtendedMessageClearToSend::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ctrl := ");
field_ctrl.log();
TTCN_Logger::log_event_str(", NumberOfPacketsToSend := ");
field_NumberOfPacketsToSend.log();
TTCN_Logger::log_event_str(", nextPacketNumberToSend := ");
field_nextPacketNumberToSend.log();
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
field_pgnOfExtendedPacketedMessage.log();
TTCN_Logger::log_event_str(" }");
}

void ExtendedMessageClearToSend::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (4<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.ExtendedMessageClearToSend has 4 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) NumberOfPacketsToSend().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) nextPacketNumberToSend().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) pgnOfExtendedPacketedMessage().set_param(*param.get_elem(3));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "NumberOfPacketsToSend")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          NumberOfPacketsToSend().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "nextPacketNumberToSend")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          nextPacketNumberToSend().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfExtendedPacketedMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfExtendedPacketedMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ExtendedMessageClearToSend: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.ExtendedMessageClearToSend");
  }
}

void ExtendedMessageClearToSend::set_implicit_omit()
{
if (ctrl().is_bound()) ctrl().set_implicit_omit();
if (NumberOfPacketsToSend().is_bound()) NumberOfPacketsToSend().set_implicit_omit();
if (nextPacketNumberToSend().is_bound()) nextPacketNumberToSend().set_implicit_omit();
if (pgnOfExtendedPacketedMessage().is_bound()) pgnOfExtendedPacketedMessage().set_implicit_omit();
}

void ExtendedMessageClearToSend::encode_text(Text_Buf& text_buf) const
{
field_ctrl.encode_text(text_buf);
field_NumberOfPacketsToSend.encode_text(text_buf);
field_nextPacketNumberToSend.encode_text(text_buf);
field_pgnOfExtendedPacketedMessage.encode_text(text_buf);
}

void ExtendedMessageClearToSend::decode_text(Text_Buf& text_buf)
{
field_ctrl.decode_text(text_buf);
field_NumberOfPacketsToSend.decode_text(text_buf);
field_nextPacketNumberToSend.decode_text(text_buf);
field_pgnOfExtendedPacketedMessage.decode_text(text_buf);
}

void ExtendedMessageClearToSend::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void ExtendedMessageClearToSend::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int ExtendedMessageClearToSend::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, ExtendedMessageClearToSend_ctrl_descr_.raw->forceomit);
  decoded_field_length = field_ctrl.RAW_decode(ExtendedMessageClearToSend_ctrl_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, General__Types::INT1_descr_.raw->forceomit);
  decoded_field_length = field_NumberOfPacketsToSend.RAW_decode(General__Types::INT1_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, ETP__NextPacketNumberToSend_descr_.raw->forceomit);
  decoded_field_length = field_nextPacketNumberToSend.RAW_decode(ETP__NextPacketNumberToSend_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_3_force_omit(3, force_omit, IsobusMessageTypes::PGN_descr_.raw->forceomit);
  decoded_field_length = field_pgnOfExtendedPacketedMessage.RAW_decode(IsobusMessageTypes::PGN_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_3_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int ExtendedMessageClearToSend::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 4;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(4);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, ExtendedMessageClearToSend_ctrl_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, General__Types::INT1_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, ETP__NextPacketNumberToSend_descr_.raw);
  myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 3, IsobusMessageTypes::PGN_descr_.raw);
  encoded_length += field_ctrl.RAW_encode(ExtendedMessageClearToSend_ctrl_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_NumberOfPacketsToSend.RAW_encode(General__Types::INT1_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_nextPacketNumberToSend.RAW_encode(ETP__NextPacketNumberToSend_descr_, *myleaf.body.node.nodes[2]);
  encoded_length += field_pgnOfExtendedPacketedMessage.RAW_encode(IsobusMessageTypes::PGN_descr_, *myleaf.body.node.nodes[3]);
  return myleaf.length = encoded_length;
}

struct ExtendedMessageClearToSend_template::single_value_struct {
OCTETSTRING_template field_ctrl;
INTEGER_template field_NumberOfPacketsToSend;
INTEGER_template field_nextPacketNumberToSend;
INTEGER_template field_pgnOfExtendedPacketedMessage;
};

void ExtendedMessageClearToSend_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_ctrl = ANY_VALUE;
single_value->field_NumberOfPacketsToSend = ANY_VALUE;
single_value->field_nextPacketNumberToSend = ANY_VALUE;
single_value->field_pgnOfExtendedPacketedMessage = ANY_VALUE;
}
}
}

void ExtendedMessageClearToSend_template::copy_value(const ExtendedMessageClearToSend& other_value)
{
single_value = new single_value_struct;
if (other_value.ctrl().is_bound()) {
  single_value->field_ctrl = other_value.ctrl();
} else {
  single_value->field_ctrl.clean_up();
}
if (other_value.NumberOfPacketsToSend().is_bound()) {
  single_value->field_NumberOfPacketsToSend = other_value.NumberOfPacketsToSend();
} else {
  single_value->field_NumberOfPacketsToSend.clean_up();
}
if (other_value.nextPacketNumberToSend().is_bound()) {
  single_value->field_nextPacketNumberToSend = other_value.nextPacketNumberToSend();
} else {
  single_value->field_nextPacketNumberToSend.clean_up();
}
if (other_value.pgnOfExtendedPacketedMessage().is_bound()) {
  single_value->field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
} else {
  single_value->field_pgnOfExtendedPacketedMessage.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void ExtendedMessageClearToSend_template::copy_template(const ExtendedMessageClearToSend_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ctrl().get_selection()) {
single_value->field_ctrl = other_value.ctrl();
} else {
single_value->field_ctrl.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.NumberOfPacketsToSend().get_selection()) {
single_value->field_NumberOfPacketsToSend = other_value.NumberOfPacketsToSend();
} else {
single_value->field_NumberOfPacketsToSend.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.nextPacketNumberToSend().get_selection()) {
single_value->field_nextPacketNumberToSend = other_value.nextPacketNumberToSend();
} else {
single_value->field_nextPacketNumberToSend.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pgnOfExtendedPacketedMessage().get_selection()) {
single_value->field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
} else {
single_value->field_pgnOfExtendedPacketedMessage.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new ExtendedMessageClearToSend_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
break;
}
set_selection(other_value);
}

ExtendedMessageClearToSend_template::ExtendedMessageClearToSend_template()
{
}

ExtendedMessageClearToSend_template::ExtendedMessageClearToSend_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

ExtendedMessageClearToSend_template::ExtendedMessageClearToSend_template(const ExtendedMessageClearToSend& other_value)
{
copy_value(other_value);
}

ExtendedMessageClearToSend_template::ExtendedMessageClearToSend_template(const OPTIONAL<ExtendedMessageClearToSend>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ExtendedMessageClearToSend&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend from an unbound optional field.");
}
}

ExtendedMessageClearToSend_template::ExtendedMessageClearToSend_template(const ExtendedMessageClearToSend_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

ExtendedMessageClearToSend_template::~ExtendedMessageClearToSend_template()
{
clean_up();
}

ExtendedMessageClearToSend_template& ExtendedMessageClearToSend_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

ExtendedMessageClearToSend_template& ExtendedMessageClearToSend_template::operator=(const ExtendedMessageClearToSend& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

ExtendedMessageClearToSend_template& ExtendedMessageClearToSend_template::operator=(const OPTIONAL<ExtendedMessageClearToSend>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ExtendedMessageClearToSend&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
}
return *this;
}

ExtendedMessageClearToSend_template& ExtendedMessageClearToSend_template::operator=(const ExtendedMessageClearToSend_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean ExtendedMessageClearToSend_template::match(const ExtendedMessageClearToSend& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.ctrl().is_bound()) return FALSE;
if(!single_value->field_ctrl.match(other_value.ctrl(), legacy))return FALSE;
if(!other_value.NumberOfPacketsToSend().is_bound()) return FALSE;
if(!single_value->field_NumberOfPacketsToSend.match(other_value.NumberOfPacketsToSend(), legacy))return FALSE;
if(!other_value.nextPacketNumberToSend().is_bound()) return FALSE;
if(!single_value->field_nextPacketNumberToSend.match(other_value.nextPacketNumberToSend(), legacy))return FALSE;
if(!other_value.pgnOfExtendedPacketedMessage().is_bound()) return FALSE;
if(!single_value->field_pgnOfExtendedPacketedMessage.match(other_value.pgnOfExtendedPacketedMessage(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
}
return FALSE;
}

boolean ExtendedMessageClearToSend_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_ctrl.is_bound()

 ||single_value->field_NumberOfPacketsToSend.is_bound()

 ||single_value->field_nextPacketNumberToSend.is_bound()

 ||single_value->field_pgnOfExtendedPacketedMessage.is_bound()
;
}

boolean ExtendedMessageClearToSend_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ctrl.is_value()
 &&single_value->field_NumberOfPacketsToSend.is_value()
 &&single_value->field_nextPacketNumberToSend.is_value()
 &&single_value->field_pgnOfExtendedPacketedMessage.is_value();
}

void ExtendedMessageClearToSend_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

ExtendedMessageClearToSend ExtendedMessageClearToSend_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
ExtendedMessageClearToSend ret_val;
if (single_value->field_ctrl.is_bound()) {
ret_val.ctrl() = single_value->field_ctrl.valueof();
}
if (single_value->field_NumberOfPacketsToSend.is_bound()) {
ret_val.NumberOfPacketsToSend() = single_value->field_NumberOfPacketsToSend.valueof();
}
if (single_value->field_nextPacketNumberToSend.is_bound()) {
ret_val.nextPacketNumberToSend() = single_value->field_nextPacketNumberToSend.valueof();
}
if (single_value->field_pgnOfExtendedPacketedMessage.is_bound()) {
ret_val.pgnOfExtendedPacketedMessage() = single_value->field_pgnOfExtendedPacketedMessage.valueof();
}
return ret_val;
}

void ExtendedMessageClearToSend_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new ExtendedMessageClearToSend_template[list_length];
}

ExtendedMessageClearToSend_template& ExtendedMessageClearToSend_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& ExtendedMessageClearToSend_template::ctrl()
{
set_specific();
return single_value->field_ctrl;
}

const OCTETSTRING_template& ExtendedMessageClearToSend_template::ctrl() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ctrl of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
return single_value->field_ctrl;
}

INTEGER_template& ExtendedMessageClearToSend_template::NumberOfPacketsToSend()
{
set_specific();
return single_value->field_NumberOfPacketsToSend;
}

const INTEGER_template& ExtendedMessageClearToSend_template::NumberOfPacketsToSend() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field NumberOfPacketsToSend of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
return single_value->field_NumberOfPacketsToSend;
}

INTEGER_template& ExtendedMessageClearToSend_template::nextPacketNumberToSend()
{
set_specific();
return single_value->field_nextPacketNumberToSend;
}

const INTEGER_template& ExtendedMessageClearToSend_template::nextPacketNumberToSend() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field nextPacketNumberToSend of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
return single_value->field_nextPacketNumberToSend;
}

INTEGER_template& ExtendedMessageClearToSend_template::pgnOfExtendedPacketedMessage()
{
set_specific();
return single_value->field_pgnOfExtendedPacketedMessage;
}

const INTEGER_template& ExtendedMessageClearToSend_template::pgnOfExtendedPacketedMessage() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pgnOfExtendedPacketedMessage of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
return single_value->field_pgnOfExtendedPacketedMessage;
}

int ExtendedMessageClearToSend_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 4;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
  }
  return 0;
}

void ExtendedMessageClearToSend_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log();
TTCN_Logger::log_event_str(", NumberOfPacketsToSend := ");
single_value->field_NumberOfPacketsToSend.log();
TTCN_Logger::log_event_str(", nextPacketNumberToSend := ");
single_value->field_nextPacketNumberToSend.log();
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
single_value->field_pgnOfExtendedPacketedMessage.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void ExtendedMessageClearToSend_template::log_match(const ExtendedMessageClearToSend& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_ctrl.match(match_value.ctrl(), legacy)){
TTCN_Logger::log_logmatch_info(".ctrl");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_NumberOfPacketsToSend.match(match_value.NumberOfPacketsToSend(), legacy)){
TTCN_Logger::log_logmatch_info(".NumberOfPacketsToSend");
single_value->field_NumberOfPacketsToSend.log_match(match_value.NumberOfPacketsToSend(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_nextPacketNumberToSend.match(match_value.nextPacketNumberToSend(), legacy)){
TTCN_Logger::log_logmatch_info(".nextPacketNumberToSend");
single_value->field_nextPacketNumberToSend.log_match(match_value.nextPacketNumberToSend(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pgnOfExtendedPacketedMessage.match(match_value.pgnOfExtendedPacketedMessage(), legacy)){
TTCN_Logger::log_logmatch_info(".pgnOfExtendedPacketedMessage");
single_value->field_pgnOfExtendedPacketedMessage.log_match(match_value.pgnOfExtendedPacketedMessage(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::log_event_str(", NumberOfPacketsToSend := ");
single_value->field_NumberOfPacketsToSend.log_match(match_value.NumberOfPacketsToSend(), legacy);
TTCN_Logger::log_event_str(", nextPacketNumberToSend := ");
single_value->field_nextPacketNumberToSend.log_match(match_value.nextPacketNumberToSend(), legacy);
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
single_value->field_pgnOfExtendedPacketedMessage.log_match(match_value.pgnOfExtendedPacketedMessage(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void ExtendedMessageClearToSend_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ctrl.encode_text(text_buf);
single_value->field_NumberOfPacketsToSend.encode_text(text_buf);
single_value->field_nextPacketNumberToSend.encode_text(text_buf);
single_value->field_pgnOfExtendedPacketedMessage.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
}
}

void ExtendedMessageClearToSend_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_ctrl.decode_text(text_buf);
single_value->field_NumberOfPacketsToSend.decode_text(text_buf);
single_value->field_nextPacketNumberToSend.decode_text(text_buf);
single_value->field_pgnOfExtendedPacketedMessage.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new ExtendedMessageClearToSend_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend.");
}
}

void ExtendedMessageClearToSend_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    ExtendedMessageClearToSend_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (4<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.ExtendedMessageClearToSend has 4 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) NumberOfPacketsToSend().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) nextPacketNumberToSend().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) pgnOfExtendedPacketedMessage().set_param(*param.get_elem(3));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "NumberOfPacketsToSend")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          NumberOfPacketsToSend().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "nextPacketNumberToSend")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          nextPacketNumberToSend().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfExtendedPacketedMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfExtendedPacketedMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ExtendedMessageClearToSend: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.ExtendedMessageClearToSend");
  }
  is_ifpresent = param.get_ifpresent();
}

void ExtendedMessageClearToSend_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_ctrl.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageClearToSend");
single_value->field_NumberOfPacketsToSend.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageClearToSend");
single_value->field_nextPacketNumberToSend.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageClearToSend");
single_value->field_pgnOfExtendedPacketedMessage.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageClearToSend");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageClearToSend");
}

boolean ExtendedMessageClearToSend_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean ExtendedMessageClearToSend_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

ExtendedMessageDataPacketOffset::ExtendedMessageDataPacketOffset()
{
}

ExtendedMessageDataPacketOffset::ExtendedMessageDataPacketOffset(const OCTETSTRING& par_ctrl,
    const INTEGER& par_numberOfPacketsToWhichToApplyTheOffset,
    const INTEGER& par_totalNumberOfPackets,
    const INTEGER& par_dataPacketOffset,
    const INTEGER& par_pgnOfExtendedPacketedMessage)
  :   field_ctrl(par_ctrl),
  field_numberOfPacketsToWhichToApplyTheOffset(par_numberOfPacketsToWhichToApplyTheOffset),
  field_totalNumberOfPackets(par_totalNumberOfPackets),
  field_dataPacketOffset(par_dataPacketOffset),
  field_pgnOfExtendedPacketedMessage(par_pgnOfExtendedPacketedMessage)
{
}

ExtendedMessageDataPacketOffset::ExtendedMessageDataPacketOffset(const ExtendedMessageDataPacketOffset& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
else field_ctrl.clean_up();
if (other_value.numberOfPacketsToWhichToApplyTheOffset().is_bound()) field_numberOfPacketsToWhichToApplyTheOffset = other_value.numberOfPacketsToWhichToApplyTheOffset();
else field_numberOfPacketsToWhichToApplyTheOffset.clean_up();
if (other_value.totalNumberOfPackets().is_bound()) field_totalNumberOfPackets = other_value.totalNumberOfPackets();
else field_totalNumberOfPackets.clean_up();
if (other_value.dataPacketOffset().is_bound()) field_dataPacketOffset = other_value.dataPacketOffset();
else field_dataPacketOffset.clean_up();
if (other_value.pgnOfExtendedPacketedMessage().is_bound()) field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
else field_pgnOfExtendedPacketedMessage.clean_up();
}

void ExtendedMessageDataPacketOffset::clean_up()
{
field_ctrl.clean_up();
field_numberOfPacketsToWhichToApplyTheOffset.clean_up();
field_totalNumberOfPackets.clean_up();
field_dataPacketOffset.clean_up();
field_pgnOfExtendedPacketedMessage.clean_up();
}

const TTCN_Typedescriptor_t* ExtendedMessageDataPacketOffset::get_descriptor() const { return &ExtendedMessageDataPacketOffset_descr_; }
ExtendedMessageDataPacketOffset& ExtendedMessageDataPacketOffset::operator=(const ExtendedMessageDataPacketOffset& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
  if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
  else field_ctrl.clean_up();
  if (other_value.numberOfPacketsToWhichToApplyTheOffset().is_bound()) field_numberOfPacketsToWhichToApplyTheOffset = other_value.numberOfPacketsToWhichToApplyTheOffset();
  else field_numberOfPacketsToWhichToApplyTheOffset.clean_up();
  if (other_value.totalNumberOfPackets().is_bound()) field_totalNumberOfPackets = other_value.totalNumberOfPackets();
  else field_totalNumberOfPackets.clean_up();
  if (other_value.dataPacketOffset().is_bound()) field_dataPacketOffset = other_value.dataPacketOffset();
  else field_dataPacketOffset.clean_up();
  if (other_value.pgnOfExtendedPacketedMessage().is_bound()) field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
  else field_pgnOfExtendedPacketedMessage.clean_up();
}
return *this;
}

boolean ExtendedMessageDataPacketOffset::operator==(const ExtendedMessageDataPacketOffset& other_value) const
{
return field_ctrl==other_value.field_ctrl
  && field_numberOfPacketsToWhichToApplyTheOffset==other_value.field_numberOfPacketsToWhichToApplyTheOffset
  && field_totalNumberOfPackets==other_value.field_totalNumberOfPackets
  && field_dataPacketOffset==other_value.field_dataPacketOffset
  && field_pgnOfExtendedPacketedMessage==other_value.field_pgnOfExtendedPacketedMessage;
}

boolean ExtendedMessageDataPacketOffset::is_bound() const
{
return (field_ctrl.is_bound())
  || (field_numberOfPacketsToWhichToApplyTheOffset.is_bound())
  || (field_totalNumberOfPackets.is_bound())
  || (field_dataPacketOffset.is_bound())
  || (field_pgnOfExtendedPacketedMessage.is_bound());
}
boolean ExtendedMessageDataPacketOffset::is_value() const
{
return field_ctrl.is_value()
  && field_numberOfPacketsToWhichToApplyTheOffset.is_value()
  && field_totalNumberOfPackets.is_value()
  && field_dataPacketOffset.is_value()
  && field_pgnOfExtendedPacketedMessage.is_value();
}
void ExtendedMessageDataPacketOffset::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ctrl := ");
field_ctrl.log();
TTCN_Logger::log_event_str(", numberOfPacketsToWhichToApplyTheOffset := ");
field_numberOfPacketsToWhichToApplyTheOffset.log();
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
field_totalNumberOfPackets.log();
TTCN_Logger::log_event_str(", dataPacketOffset := ");
field_dataPacketOffset.log();
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
field_pgnOfExtendedPacketedMessage.log();
TTCN_Logger::log_event_str(" }");
}

void ExtendedMessageDataPacketOffset::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (5<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset has 5 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) numberOfPacketsToWhichToApplyTheOffset().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) totalNumberOfPackets().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) dataPacketOffset().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) pgnOfExtendedPacketedMessage().set_param(*param.get_elem(4));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "numberOfPacketsToWhichToApplyTheOffset")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          numberOfPacketsToWhichToApplyTheOffset().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "totalNumberOfPackets")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          totalNumberOfPackets().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "dataPacketOffset")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          dataPacketOffset().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfExtendedPacketedMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfExtendedPacketedMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset");
  }
}

void ExtendedMessageDataPacketOffset::set_implicit_omit()
{
if (ctrl().is_bound()) ctrl().set_implicit_omit();
if (numberOfPacketsToWhichToApplyTheOffset().is_bound()) numberOfPacketsToWhichToApplyTheOffset().set_implicit_omit();
if (totalNumberOfPackets().is_bound()) totalNumberOfPackets().set_implicit_omit();
if (dataPacketOffset().is_bound()) dataPacketOffset().set_implicit_omit();
if (pgnOfExtendedPacketedMessage().is_bound()) pgnOfExtendedPacketedMessage().set_implicit_omit();
}

void ExtendedMessageDataPacketOffset::encode_text(Text_Buf& text_buf) const
{
field_ctrl.encode_text(text_buf);
field_numberOfPacketsToWhichToApplyTheOffset.encode_text(text_buf);
field_totalNumberOfPackets.encode_text(text_buf);
field_dataPacketOffset.encode_text(text_buf);
field_pgnOfExtendedPacketedMessage.encode_text(text_buf);
}

void ExtendedMessageDataPacketOffset::decode_text(Text_Buf& text_buf)
{
field_ctrl.decode_text(text_buf);
field_numberOfPacketsToWhichToApplyTheOffset.decode_text(text_buf);
field_totalNumberOfPackets.decode_text(text_buf);
field_dataPacketOffset.decode_text(text_buf);
field_pgnOfExtendedPacketedMessage.decode_text(text_buf);
}

void ExtendedMessageDataPacketOffset::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void ExtendedMessageDataPacketOffset::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int ExtendedMessageDataPacketOffset::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, ExtendedMessageDataPacketOffset_ctrl_descr_.raw->forceomit);
  decoded_field_length = field_ctrl.RAW_decode(ExtendedMessageDataPacketOffset_ctrl_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, ETP__NoPacketForOffset_descr_.raw->forceomit);
  decoded_field_length = field_numberOfPacketsToWhichToApplyTheOffset.RAW_decode(ETP__NoPacketForOffset_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, NUMBER__OF__PACKETS_descr_.raw->forceomit);
  decoded_field_length = field_totalNumberOfPackets.RAW_decode(NUMBER__OF__PACKETS_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_3_force_omit(3, force_omit, ETP__NextPacketNumberToSend_descr_.raw->forceomit);
  decoded_field_length = field_dataPacketOffset.RAW_decode(ETP__NextPacketNumberToSend_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_3_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_4_force_omit(4, force_omit, IsobusMessageTypes::PGN_descr_.raw->forceomit);
  decoded_field_length = field_pgnOfExtendedPacketedMessage.RAW_decode(IsobusMessageTypes::PGN_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_4_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int ExtendedMessageDataPacketOffset::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 5;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(5);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, ExtendedMessageDataPacketOffset_ctrl_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, ETP__NoPacketForOffset_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, NUMBER__OF__PACKETS_descr_.raw);
  myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 3, ETP__NextPacketNumberToSend_descr_.raw);
  myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 4, IsobusMessageTypes::PGN_descr_.raw);
  encoded_length += field_ctrl.RAW_encode(ExtendedMessageDataPacketOffset_ctrl_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_numberOfPacketsToWhichToApplyTheOffset.RAW_encode(ETP__NoPacketForOffset_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_totalNumberOfPackets.RAW_encode(NUMBER__OF__PACKETS_descr_, *myleaf.body.node.nodes[2]);
  encoded_length += field_dataPacketOffset.RAW_encode(ETP__NextPacketNumberToSend_descr_, *myleaf.body.node.nodes[3]);
  encoded_length += field_pgnOfExtendedPacketedMessage.RAW_encode(IsobusMessageTypes::PGN_descr_, *myleaf.body.node.nodes[4]);
  return myleaf.length = encoded_length;
}

struct ExtendedMessageDataPacketOffset_template::single_value_struct {
OCTETSTRING_template field_ctrl;
INTEGER_template field_numberOfPacketsToWhichToApplyTheOffset;
INTEGER_template field_totalNumberOfPackets;
INTEGER_template field_dataPacketOffset;
INTEGER_template field_pgnOfExtendedPacketedMessage;
};

void ExtendedMessageDataPacketOffset_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_ctrl = ANY_VALUE;
single_value->field_numberOfPacketsToWhichToApplyTheOffset = ANY_VALUE;
single_value->field_totalNumberOfPackets = ANY_VALUE;
single_value->field_dataPacketOffset = ANY_VALUE;
single_value->field_pgnOfExtendedPacketedMessage = ANY_VALUE;
}
}
}

void ExtendedMessageDataPacketOffset_template::copy_value(const ExtendedMessageDataPacketOffset& other_value)
{
single_value = new single_value_struct;
if (other_value.ctrl().is_bound()) {
  single_value->field_ctrl = other_value.ctrl();
} else {
  single_value->field_ctrl.clean_up();
}
if (other_value.numberOfPacketsToWhichToApplyTheOffset().is_bound()) {
  single_value->field_numberOfPacketsToWhichToApplyTheOffset = other_value.numberOfPacketsToWhichToApplyTheOffset();
} else {
  single_value->field_numberOfPacketsToWhichToApplyTheOffset.clean_up();
}
if (other_value.totalNumberOfPackets().is_bound()) {
  single_value->field_totalNumberOfPackets = other_value.totalNumberOfPackets();
} else {
  single_value->field_totalNumberOfPackets.clean_up();
}
if (other_value.dataPacketOffset().is_bound()) {
  single_value->field_dataPacketOffset = other_value.dataPacketOffset();
} else {
  single_value->field_dataPacketOffset.clean_up();
}
if (other_value.pgnOfExtendedPacketedMessage().is_bound()) {
  single_value->field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
} else {
  single_value->field_pgnOfExtendedPacketedMessage.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void ExtendedMessageDataPacketOffset_template::copy_template(const ExtendedMessageDataPacketOffset_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ctrl().get_selection()) {
single_value->field_ctrl = other_value.ctrl();
} else {
single_value->field_ctrl.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.numberOfPacketsToWhichToApplyTheOffset().get_selection()) {
single_value->field_numberOfPacketsToWhichToApplyTheOffset = other_value.numberOfPacketsToWhichToApplyTheOffset();
} else {
single_value->field_numberOfPacketsToWhichToApplyTheOffset.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.totalNumberOfPackets().get_selection()) {
single_value->field_totalNumberOfPackets = other_value.totalNumberOfPackets();
} else {
single_value->field_totalNumberOfPackets.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.dataPacketOffset().get_selection()) {
single_value->field_dataPacketOffset = other_value.dataPacketOffset();
} else {
single_value->field_dataPacketOffset.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pgnOfExtendedPacketedMessage().get_selection()) {
single_value->field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
} else {
single_value->field_pgnOfExtendedPacketedMessage.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new ExtendedMessageDataPacketOffset_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
break;
}
set_selection(other_value);
}

ExtendedMessageDataPacketOffset_template::ExtendedMessageDataPacketOffset_template()
{
}

ExtendedMessageDataPacketOffset_template::ExtendedMessageDataPacketOffset_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

ExtendedMessageDataPacketOffset_template::ExtendedMessageDataPacketOffset_template(const ExtendedMessageDataPacketOffset& other_value)
{
copy_value(other_value);
}

ExtendedMessageDataPacketOffset_template::ExtendedMessageDataPacketOffset_template(const OPTIONAL<ExtendedMessageDataPacketOffset>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ExtendedMessageDataPacketOffset&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset from an unbound optional field.");
}
}

ExtendedMessageDataPacketOffset_template::ExtendedMessageDataPacketOffset_template(const ExtendedMessageDataPacketOffset_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

ExtendedMessageDataPacketOffset_template::~ExtendedMessageDataPacketOffset_template()
{
clean_up();
}

ExtendedMessageDataPacketOffset_template& ExtendedMessageDataPacketOffset_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

ExtendedMessageDataPacketOffset_template& ExtendedMessageDataPacketOffset_template::operator=(const ExtendedMessageDataPacketOffset& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

ExtendedMessageDataPacketOffset_template& ExtendedMessageDataPacketOffset_template::operator=(const OPTIONAL<ExtendedMessageDataPacketOffset>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ExtendedMessageDataPacketOffset&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
}
return *this;
}

ExtendedMessageDataPacketOffset_template& ExtendedMessageDataPacketOffset_template::operator=(const ExtendedMessageDataPacketOffset_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean ExtendedMessageDataPacketOffset_template::match(const ExtendedMessageDataPacketOffset& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.ctrl().is_bound()) return FALSE;
if(!single_value->field_ctrl.match(other_value.ctrl(), legacy))return FALSE;
if(!other_value.numberOfPacketsToWhichToApplyTheOffset().is_bound()) return FALSE;
if(!single_value->field_numberOfPacketsToWhichToApplyTheOffset.match(other_value.numberOfPacketsToWhichToApplyTheOffset(), legacy))return FALSE;
if(!other_value.totalNumberOfPackets().is_bound()) return FALSE;
if(!single_value->field_totalNumberOfPackets.match(other_value.totalNumberOfPackets(), legacy))return FALSE;
if(!other_value.dataPacketOffset().is_bound()) return FALSE;
if(!single_value->field_dataPacketOffset.match(other_value.dataPacketOffset(), legacy))return FALSE;
if(!other_value.pgnOfExtendedPacketedMessage().is_bound()) return FALSE;
if(!single_value->field_pgnOfExtendedPacketedMessage.match(other_value.pgnOfExtendedPacketedMessage(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
}
return FALSE;
}

boolean ExtendedMessageDataPacketOffset_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_ctrl.is_bound()

 ||single_value->field_numberOfPacketsToWhichToApplyTheOffset.is_bound()

 ||single_value->field_totalNumberOfPackets.is_bound()

 ||single_value->field_dataPacketOffset.is_bound()

 ||single_value->field_pgnOfExtendedPacketedMessage.is_bound()
;
}

boolean ExtendedMessageDataPacketOffset_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ctrl.is_value()
 &&single_value->field_numberOfPacketsToWhichToApplyTheOffset.is_value()
 &&single_value->field_totalNumberOfPackets.is_value()
 &&single_value->field_dataPacketOffset.is_value()
 &&single_value->field_pgnOfExtendedPacketedMessage.is_value();
}

void ExtendedMessageDataPacketOffset_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

ExtendedMessageDataPacketOffset ExtendedMessageDataPacketOffset_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
ExtendedMessageDataPacketOffset ret_val;
if (single_value->field_ctrl.is_bound()) {
ret_val.ctrl() = single_value->field_ctrl.valueof();
}
if (single_value->field_numberOfPacketsToWhichToApplyTheOffset.is_bound()) {
ret_val.numberOfPacketsToWhichToApplyTheOffset() = single_value->field_numberOfPacketsToWhichToApplyTheOffset.valueof();
}
if (single_value->field_totalNumberOfPackets.is_bound()) {
ret_val.totalNumberOfPackets() = single_value->field_totalNumberOfPackets.valueof();
}
if (single_value->field_dataPacketOffset.is_bound()) {
ret_val.dataPacketOffset() = single_value->field_dataPacketOffset.valueof();
}
if (single_value->field_pgnOfExtendedPacketedMessage.is_bound()) {
ret_val.pgnOfExtendedPacketedMessage() = single_value->field_pgnOfExtendedPacketedMessage.valueof();
}
return ret_val;
}

void ExtendedMessageDataPacketOffset_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new ExtendedMessageDataPacketOffset_template[list_length];
}

ExtendedMessageDataPacketOffset_template& ExtendedMessageDataPacketOffset_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& ExtendedMessageDataPacketOffset_template::ctrl()
{
set_specific();
return single_value->field_ctrl;
}

const OCTETSTRING_template& ExtendedMessageDataPacketOffset_template::ctrl() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ctrl of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
return single_value->field_ctrl;
}

INTEGER_template& ExtendedMessageDataPacketOffset_template::numberOfPacketsToWhichToApplyTheOffset()
{
set_specific();
return single_value->field_numberOfPacketsToWhichToApplyTheOffset;
}

const INTEGER_template& ExtendedMessageDataPacketOffset_template::numberOfPacketsToWhichToApplyTheOffset() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field numberOfPacketsToWhichToApplyTheOffset of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
return single_value->field_numberOfPacketsToWhichToApplyTheOffset;
}

INTEGER_template& ExtendedMessageDataPacketOffset_template::totalNumberOfPackets()
{
set_specific();
return single_value->field_totalNumberOfPackets;
}

const INTEGER_template& ExtendedMessageDataPacketOffset_template::totalNumberOfPackets() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field totalNumberOfPackets of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
return single_value->field_totalNumberOfPackets;
}

INTEGER_template& ExtendedMessageDataPacketOffset_template::dataPacketOffset()
{
set_specific();
return single_value->field_dataPacketOffset;
}

const INTEGER_template& ExtendedMessageDataPacketOffset_template::dataPacketOffset() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field dataPacketOffset of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
return single_value->field_dataPacketOffset;
}

INTEGER_template& ExtendedMessageDataPacketOffset_template::pgnOfExtendedPacketedMessage()
{
set_specific();
return single_value->field_pgnOfExtendedPacketedMessage;
}

const INTEGER_template& ExtendedMessageDataPacketOffset_template::pgnOfExtendedPacketedMessage() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pgnOfExtendedPacketedMessage of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
return single_value->field_pgnOfExtendedPacketedMessage;
}

int ExtendedMessageDataPacketOffset_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 5;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
  }
  return 0;
}

void ExtendedMessageDataPacketOffset_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log();
TTCN_Logger::log_event_str(", numberOfPacketsToWhichToApplyTheOffset := ");
single_value->field_numberOfPacketsToWhichToApplyTheOffset.log();
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
single_value->field_totalNumberOfPackets.log();
TTCN_Logger::log_event_str(", dataPacketOffset := ");
single_value->field_dataPacketOffset.log();
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
single_value->field_pgnOfExtendedPacketedMessage.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void ExtendedMessageDataPacketOffset_template::log_match(const ExtendedMessageDataPacketOffset& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_ctrl.match(match_value.ctrl(), legacy)){
TTCN_Logger::log_logmatch_info(".ctrl");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_numberOfPacketsToWhichToApplyTheOffset.match(match_value.numberOfPacketsToWhichToApplyTheOffset(), legacy)){
TTCN_Logger::log_logmatch_info(".numberOfPacketsToWhichToApplyTheOffset");
single_value->field_numberOfPacketsToWhichToApplyTheOffset.log_match(match_value.numberOfPacketsToWhichToApplyTheOffset(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_totalNumberOfPackets.match(match_value.totalNumberOfPackets(), legacy)){
TTCN_Logger::log_logmatch_info(".totalNumberOfPackets");
single_value->field_totalNumberOfPackets.log_match(match_value.totalNumberOfPackets(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_dataPacketOffset.match(match_value.dataPacketOffset(), legacy)){
TTCN_Logger::log_logmatch_info(".dataPacketOffset");
single_value->field_dataPacketOffset.log_match(match_value.dataPacketOffset(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pgnOfExtendedPacketedMessage.match(match_value.pgnOfExtendedPacketedMessage(), legacy)){
TTCN_Logger::log_logmatch_info(".pgnOfExtendedPacketedMessage");
single_value->field_pgnOfExtendedPacketedMessage.log_match(match_value.pgnOfExtendedPacketedMessage(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::log_event_str(", numberOfPacketsToWhichToApplyTheOffset := ");
single_value->field_numberOfPacketsToWhichToApplyTheOffset.log_match(match_value.numberOfPacketsToWhichToApplyTheOffset(), legacy);
TTCN_Logger::log_event_str(", totalNumberOfPackets := ");
single_value->field_totalNumberOfPackets.log_match(match_value.totalNumberOfPackets(), legacy);
TTCN_Logger::log_event_str(", dataPacketOffset := ");
single_value->field_dataPacketOffset.log_match(match_value.dataPacketOffset(), legacy);
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
single_value->field_pgnOfExtendedPacketedMessage.log_match(match_value.pgnOfExtendedPacketedMessage(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void ExtendedMessageDataPacketOffset_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ctrl.encode_text(text_buf);
single_value->field_numberOfPacketsToWhichToApplyTheOffset.encode_text(text_buf);
single_value->field_totalNumberOfPackets.encode_text(text_buf);
single_value->field_dataPacketOffset.encode_text(text_buf);
single_value->field_pgnOfExtendedPacketedMessage.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
}
}

void ExtendedMessageDataPacketOffset_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_ctrl.decode_text(text_buf);
single_value->field_numberOfPacketsToWhichToApplyTheOffset.decode_text(text_buf);
single_value->field_totalNumberOfPackets.decode_text(text_buf);
single_value->field_dataPacketOffset.decode_text(text_buf);
single_value->field_pgnOfExtendedPacketedMessage.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new ExtendedMessageDataPacketOffset_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset.");
}
}

void ExtendedMessageDataPacketOffset_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    ExtendedMessageDataPacketOffset_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (5<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset has 5 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) numberOfPacketsToWhichToApplyTheOffset().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) totalNumberOfPackets().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) dataPacketOffset().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) pgnOfExtendedPacketedMessage().set_param(*param.get_elem(4));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "numberOfPacketsToWhichToApplyTheOffset")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          numberOfPacketsToWhichToApplyTheOffset().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "totalNumberOfPackets")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          totalNumberOfPackets().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "dataPacketOffset")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          dataPacketOffset().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfExtendedPacketedMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfExtendedPacketedMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ExtendedMessageDataPacketOffset: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset");
  }
  is_ifpresent = param.get_ifpresent();
}

void ExtendedMessageDataPacketOffset_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_ctrl.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset");
single_value->field_numberOfPacketsToWhichToApplyTheOffset.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset");
single_value->field_totalNumberOfPackets.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset");
single_value->field_dataPacketOffset.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset");
single_value->field_pgnOfExtendedPacketedMessage.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageDataPacketOffset");
}

boolean ExtendedMessageDataPacketOffset_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean ExtendedMessageDataPacketOffset_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

ExtendedMessageEndOfMessageAcknowledgement::ExtendedMessageEndOfMessageAcknowledgement()
{
}

ExtendedMessageEndOfMessageAcknowledgement::ExtendedMessageEndOfMessageAcknowledgement(const OCTETSTRING& par_ctrl,
    const INTEGER& par_numberOfBytesTransferred,
    const INTEGER& par_pgnOfExtendedPacketedMessage)
  :   field_ctrl(par_ctrl),
  field_numberOfBytesTransferred(par_numberOfBytesTransferred),
  field_pgnOfExtendedPacketedMessage(par_pgnOfExtendedPacketedMessage)
{
}

ExtendedMessageEndOfMessageAcknowledgement::ExtendedMessageEndOfMessageAcknowledgement(const ExtendedMessageEndOfMessageAcknowledgement& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
else field_ctrl.clean_up();
if (other_value.numberOfBytesTransferred().is_bound()) field_numberOfBytesTransferred = other_value.numberOfBytesTransferred();
else field_numberOfBytesTransferred.clean_up();
if (other_value.pgnOfExtendedPacketedMessage().is_bound()) field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
else field_pgnOfExtendedPacketedMessage.clean_up();
}

void ExtendedMessageEndOfMessageAcknowledgement::clean_up()
{
field_ctrl.clean_up();
field_numberOfBytesTransferred.clean_up();
field_pgnOfExtendedPacketedMessage.clean_up();
}

const TTCN_Typedescriptor_t* ExtendedMessageEndOfMessageAcknowledgement::get_descriptor() const { return &ExtendedMessageEndOfMessageAcknowledgement_descr_; }
ExtendedMessageEndOfMessageAcknowledgement& ExtendedMessageEndOfMessageAcknowledgement::operator=(const ExtendedMessageEndOfMessageAcknowledgement& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
  if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
  else field_ctrl.clean_up();
  if (other_value.numberOfBytesTransferred().is_bound()) field_numberOfBytesTransferred = other_value.numberOfBytesTransferred();
  else field_numberOfBytesTransferred.clean_up();
  if (other_value.pgnOfExtendedPacketedMessage().is_bound()) field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
  else field_pgnOfExtendedPacketedMessage.clean_up();
}
return *this;
}

boolean ExtendedMessageEndOfMessageAcknowledgement::operator==(const ExtendedMessageEndOfMessageAcknowledgement& other_value) const
{
return field_ctrl==other_value.field_ctrl
  && field_numberOfBytesTransferred==other_value.field_numberOfBytesTransferred
  && field_pgnOfExtendedPacketedMessage==other_value.field_pgnOfExtendedPacketedMessage;
}

boolean ExtendedMessageEndOfMessageAcknowledgement::is_bound() const
{
return (field_ctrl.is_bound())
  || (field_numberOfBytesTransferred.is_bound())
  || (field_pgnOfExtendedPacketedMessage.is_bound());
}
boolean ExtendedMessageEndOfMessageAcknowledgement::is_value() const
{
return field_ctrl.is_value()
  && field_numberOfBytesTransferred.is_value()
  && field_pgnOfExtendedPacketedMessage.is_value();
}
void ExtendedMessageEndOfMessageAcknowledgement::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ctrl := ");
field_ctrl.log();
TTCN_Logger::log_event_str(", numberOfBytesTransferred := ");
field_numberOfBytesTransferred.log();
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
field_pgnOfExtendedPacketedMessage.log();
TTCN_Logger::log_event_str(" }");
}

void ExtendedMessageEndOfMessageAcknowledgement::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (3<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement has 3 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) numberOfBytesTransferred().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) pgnOfExtendedPacketedMessage().set_param(*param.get_elem(2));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "numberOfBytesTransferred")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          numberOfBytesTransferred().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfExtendedPacketedMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfExtendedPacketedMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement");
  }
}

void ExtendedMessageEndOfMessageAcknowledgement::set_implicit_omit()
{
if (ctrl().is_bound()) ctrl().set_implicit_omit();
if (numberOfBytesTransferred().is_bound()) numberOfBytesTransferred().set_implicit_omit();
if (pgnOfExtendedPacketedMessage().is_bound()) pgnOfExtendedPacketedMessage().set_implicit_omit();
}

void ExtendedMessageEndOfMessageAcknowledgement::encode_text(Text_Buf& text_buf) const
{
field_ctrl.encode_text(text_buf);
field_numberOfBytesTransferred.encode_text(text_buf);
field_pgnOfExtendedPacketedMessage.encode_text(text_buf);
}

void ExtendedMessageEndOfMessageAcknowledgement::decode_text(Text_Buf& text_buf)
{
field_ctrl.decode_text(text_buf);
field_numberOfBytesTransferred.decode_text(text_buf);
field_pgnOfExtendedPacketedMessage.decode_text(text_buf);
}

void ExtendedMessageEndOfMessageAcknowledgement::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void ExtendedMessageEndOfMessageAcknowledgement::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int ExtendedMessageEndOfMessageAcknowledgement::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, ExtendedMessageEndOfMessageAcknowledgement_ctrl_descr_.raw->forceomit);
  decoded_field_length = field_ctrl.RAW_decode(ExtendedMessageEndOfMessageAcknowledgement_ctrl_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, ETP__MSG__SIZE_descr_.raw->forceomit);
  decoded_field_length = field_numberOfBytesTransferred.RAW_decode(ETP__MSG__SIZE_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, IsobusMessageTypes::PGN_descr_.raw->forceomit);
  decoded_field_length = field_pgnOfExtendedPacketedMessage.RAW_decode(IsobusMessageTypes::PGN_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int ExtendedMessageEndOfMessageAcknowledgement::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 3;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(3);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, ExtendedMessageEndOfMessageAcknowledgement_ctrl_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, ETP__MSG__SIZE_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, IsobusMessageTypes::PGN_descr_.raw);
  encoded_length += field_ctrl.RAW_encode(ExtendedMessageEndOfMessageAcknowledgement_ctrl_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_numberOfBytesTransferred.RAW_encode(ETP__MSG__SIZE_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_pgnOfExtendedPacketedMessage.RAW_encode(IsobusMessageTypes::PGN_descr_, *myleaf.body.node.nodes[2]);
  return myleaf.length = encoded_length;
}

struct ExtendedMessageEndOfMessageAcknowledgement_template::single_value_struct {
OCTETSTRING_template field_ctrl;
INTEGER_template field_numberOfBytesTransferred;
INTEGER_template field_pgnOfExtendedPacketedMessage;
};

void ExtendedMessageEndOfMessageAcknowledgement_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_ctrl = ANY_VALUE;
single_value->field_numberOfBytesTransferred = ANY_VALUE;
single_value->field_pgnOfExtendedPacketedMessage = ANY_VALUE;
}
}
}

void ExtendedMessageEndOfMessageAcknowledgement_template::copy_value(const ExtendedMessageEndOfMessageAcknowledgement& other_value)
{
single_value = new single_value_struct;
if (other_value.ctrl().is_bound()) {
  single_value->field_ctrl = other_value.ctrl();
} else {
  single_value->field_ctrl.clean_up();
}
if (other_value.numberOfBytesTransferred().is_bound()) {
  single_value->field_numberOfBytesTransferred = other_value.numberOfBytesTransferred();
} else {
  single_value->field_numberOfBytesTransferred.clean_up();
}
if (other_value.pgnOfExtendedPacketedMessage().is_bound()) {
  single_value->field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
} else {
  single_value->field_pgnOfExtendedPacketedMessage.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void ExtendedMessageEndOfMessageAcknowledgement_template::copy_template(const ExtendedMessageEndOfMessageAcknowledgement_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ctrl().get_selection()) {
single_value->field_ctrl = other_value.ctrl();
} else {
single_value->field_ctrl.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.numberOfBytesTransferred().get_selection()) {
single_value->field_numberOfBytesTransferred = other_value.numberOfBytesTransferred();
} else {
single_value->field_numberOfBytesTransferred.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pgnOfExtendedPacketedMessage().get_selection()) {
single_value->field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
} else {
single_value->field_pgnOfExtendedPacketedMessage.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new ExtendedMessageEndOfMessageAcknowledgement_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
break;
}
set_selection(other_value);
}

ExtendedMessageEndOfMessageAcknowledgement_template::ExtendedMessageEndOfMessageAcknowledgement_template()
{
}

ExtendedMessageEndOfMessageAcknowledgement_template::ExtendedMessageEndOfMessageAcknowledgement_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

ExtendedMessageEndOfMessageAcknowledgement_template::ExtendedMessageEndOfMessageAcknowledgement_template(const ExtendedMessageEndOfMessageAcknowledgement& other_value)
{
copy_value(other_value);
}

ExtendedMessageEndOfMessageAcknowledgement_template::ExtendedMessageEndOfMessageAcknowledgement_template(const OPTIONAL<ExtendedMessageEndOfMessageAcknowledgement>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ExtendedMessageEndOfMessageAcknowledgement&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement from an unbound optional field.");
}
}

ExtendedMessageEndOfMessageAcknowledgement_template::ExtendedMessageEndOfMessageAcknowledgement_template(const ExtendedMessageEndOfMessageAcknowledgement_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

ExtendedMessageEndOfMessageAcknowledgement_template::~ExtendedMessageEndOfMessageAcknowledgement_template()
{
clean_up();
}

ExtendedMessageEndOfMessageAcknowledgement_template& ExtendedMessageEndOfMessageAcknowledgement_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

ExtendedMessageEndOfMessageAcknowledgement_template& ExtendedMessageEndOfMessageAcknowledgement_template::operator=(const ExtendedMessageEndOfMessageAcknowledgement& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

ExtendedMessageEndOfMessageAcknowledgement_template& ExtendedMessageEndOfMessageAcknowledgement_template::operator=(const OPTIONAL<ExtendedMessageEndOfMessageAcknowledgement>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ExtendedMessageEndOfMessageAcknowledgement&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
}
return *this;
}

ExtendedMessageEndOfMessageAcknowledgement_template& ExtendedMessageEndOfMessageAcknowledgement_template::operator=(const ExtendedMessageEndOfMessageAcknowledgement_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean ExtendedMessageEndOfMessageAcknowledgement_template::match(const ExtendedMessageEndOfMessageAcknowledgement& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.ctrl().is_bound()) return FALSE;
if(!single_value->field_ctrl.match(other_value.ctrl(), legacy))return FALSE;
if(!other_value.numberOfBytesTransferred().is_bound()) return FALSE;
if(!single_value->field_numberOfBytesTransferred.match(other_value.numberOfBytesTransferred(), legacy))return FALSE;
if(!other_value.pgnOfExtendedPacketedMessage().is_bound()) return FALSE;
if(!single_value->field_pgnOfExtendedPacketedMessage.match(other_value.pgnOfExtendedPacketedMessage(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
}
return FALSE;
}

boolean ExtendedMessageEndOfMessageAcknowledgement_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_ctrl.is_bound()

 ||single_value->field_numberOfBytesTransferred.is_bound()

 ||single_value->field_pgnOfExtendedPacketedMessage.is_bound()
;
}

boolean ExtendedMessageEndOfMessageAcknowledgement_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ctrl.is_value()
 &&single_value->field_numberOfBytesTransferred.is_value()
 &&single_value->field_pgnOfExtendedPacketedMessage.is_value();
}

void ExtendedMessageEndOfMessageAcknowledgement_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

ExtendedMessageEndOfMessageAcknowledgement ExtendedMessageEndOfMessageAcknowledgement_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
ExtendedMessageEndOfMessageAcknowledgement ret_val;
if (single_value->field_ctrl.is_bound()) {
ret_val.ctrl() = single_value->field_ctrl.valueof();
}
if (single_value->field_numberOfBytesTransferred.is_bound()) {
ret_val.numberOfBytesTransferred() = single_value->field_numberOfBytesTransferred.valueof();
}
if (single_value->field_pgnOfExtendedPacketedMessage.is_bound()) {
ret_val.pgnOfExtendedPacketedMessage() = single_value->field_pgnOfExtendedPacketedMessage.valueof();
}
return ret_val;
}

void ExtendedMessageEndOfMessageAcknowledgement_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new ExtendedMessageEndOfMessageAcknowledgement_template[list_length];
}

ExtendedMessageEndOfMessageAcknowledgement_template& ExtendedMessageEndOfMessageAcknowledgement_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& ExtendedMessageEndOfMessageAcknowledgement_template::ctrl()
{
set_specific();
return single_value->field_ctrl;
}

const OCTETSTRING_template& ExtendedMessageEndOfMessageAcknowledgement_template::ctrl() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ctrl of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
return single_value->field_ctrl;
}

INTEGER_template& ExtendedMessageEndOfMessageAcknowledgement_template::numberOfBytesTransferred()
{
set_specific();
return single_value->field_numberOfBytesTransferred;
}

const INTEGER_template& ExtendedMessageEndOfMessageAcknowledgement_template::numberOfBytesTransferred() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field numberOfBytesTransferred of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
return single_value->field_numberOfBytesTransferred;
}

INTEGER_template& ExtendedMessageEndOfMessageAcknowledgement_template::pgnOfExtendedPacketedMessage()
{
set_specific();
return single_value->field_pgnOfExtendedPacketedMessage;
}

const INTEGER_template& ExtendedMessageEndOfMessageAcknowledgement_template::pgnOfExtendedPacketedMessage() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pgnOfExtendedPacketedMessage of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
return single_value->field_pgnOfExtendedPacketedMessage;
}

int ExtendedMessageEndOfMessageAcknowledgement_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 3;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
  }
  return 0;
}

void ExtendedMessageEndOfMessageAcknowledgement_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log();
TTCN_Logger::log_event_str(", numberOfBytesTransferred := ");
single_value->field_numberOfBytesTransferred.log();
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
single_value->field_pgnOfExtendedPacketedMessage.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void ExtendedMessageEndOfMessageAcknowledgement_template::log_match(const ExtendedMessageEndOfMessageAcknowledgement& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_ctrl.match(match_value.ctrl(), legacy)){
TTCN_Logger::log_logmatch_info(".ctrl");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_numberOfBytesTransferred.match(match_value.numberOfBytesTransferred(), legacy)){
TTCN_Logger::log_logmatch_info(".numberOfBytesTransferred");
single_value->field_numberOfBytesTransferred.log_match(match_value.numberOfBytesTransferred(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pgnOfExtendedPacketedMessage.match(match_value.pgnOfExtendedPacketedMessage(), legacy)){
TTCN_Logger::log_logmatch_info(".pgnOfExtendedPacketedMessage");
single_value->field_pgnOfExtendedPacketedMessage.log_match(match_value.pgnOfExtendedPacketedMessage(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::log_event_str(", numberOfBytesTransferred := ");
single_value->field_numberOfBytesTransferred.log_match(match_value.numberOfBytesTransferred(), legacy);
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
single_value->field_pgnOfExtendedPacketedMessage.log_match(match_value.pgnOfExtendedPacketedMessage(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void ExtendedMessageEndOfMessageAcknowledgement_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ctrl.encode_text(text_buf);
single_value->field_numberOfBytesTransferred.encode_text(text_buf);
single_value->field_pgnOfExtendedPacketedMessage.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
}
}

void ExtendedMessageEndOfMessageAcknowledgement_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_ctrl.decode_text(text_buf);
single_value->field_numberOfBytesTransferred.decode_text(text_buf);
single_value->field_pgnOfExtendedPacketedMessage.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new ExtendedMessageEndOfMessageAcknowledgement_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement.");
}
}

void ExtendedMessageEndOfMessageAcknowledgement_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    ExtendedMessageEndOfMessageAcknowledgement_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (3<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement has 3 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) numberOfBytesTransferred().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) pgnOfExtendedPacketedMessage().set_param(*param.get_elem(2));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "numberOfBytesTransferred")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          numberOfBytesTransferred().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfExtendedPacketedMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfExtendedPacketedMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement");
  }
  is_ifpresent = param.get_ifpresent();
}

void ExtendedMessageEndOfMessageAcknowledgement_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_ctrl.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement");
single_value->field_numberOfBytesTransferred.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement");
single_value->field_pgnOfExtendedPacketedMessage.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageEndOfMessageAcknowledgement");
}

boolean ExtendedMessageEndOfMessageAcknowledgement_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean ExtendedMessageEndOfMessageAcknowledgement_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

e__ETP__ConnectionAbort__AbortReason::e__ETP__ConnectionAbort__AbortReason()
{
enum_value = UNBOUND_VALUE;
}

e__ETP__ConnectionAbort__AbortReason::e__ETP__ConnectionAbort__AbortReason(int other_value)
{
if (!is_valid_enum(other_value)) TTCN_error("Initializing a variable of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason with invalid numeric value %d.", other_value);
enum_value = (enum_type)other_value;
}

e__ETP__ConnectionAbort__AbortReason::e__ETP__ConnectionAbort__AbortReason(enum_type other_value)
{
enum_value = other_value;
}

e__ETP__ConnectionAbort__AbortReason::e__ETP__ConnectionAbort__AbortReason(const e__ETP__ConnectionAbort__AbortReason& other_value)
: Base_Type()
{
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("Copying an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
enum_value = other_value.enum_value;
}

e__ETP__ConnectionAbort__AbortReason& e__ETP__ConnectionAbort__AbortReason::operator=(int other_value)
{
if (!is_valid_enum(other_value)) TTCN_error("Assigning unknown numeric value %d to a variable of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.", other_value);
enum_value = (enum_type)other_value;
return *this;
}

e__ETP__ConnectionAbort__AbortReason& e__ETP__ConnectionAbort__AbortReason::operator=(enum_type other_value)
{
enum_value = other_value;
return *this;
}

e__ETP__ConnectionAbort__AbortReason& e__ETP__ConnectionAbort__AbortReason::operator=(const e__ETP__ConnectionAbort__AbortReason& other_value)
{
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("Assignment of an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
enum_value = other_value.enum_value;
return *this;
}

boolean e__ETP__ConnectionAbort__AbortReason::operator==(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
return enum_value == other_value;
}

boolean e__ETP__ConnectionAbort__AbortReason::operator==(const e__ETP__ConnectionAbort__AbortReason& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
return enum_value == other_value.enum_value;
}

boolean e__ETP__ConnectionAbort__AbortReason::operator<(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
return enum_value < other_value;
}

boolean e__ETP__ConnectionAbort__AbortReason::operator<(const e__ETP__ConnectionAbort__AbortReason& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
return enum_value < other_value.enum_value;
}

boolean e__ETP__ConnectionAbort__AbortReason::operator>(enum_type other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
return enum_value > other_value;
}

boolean e__ETP__ConnectionAbort__AbortReason::operator>(const e__ETP__ConnectionAbort__AbortReason& other_value) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
if (other_value.enum_value == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
return enum_value > other_value.enum_value;
}

const char *e__ETP__ConnectionAbort__AbortReason::enum_to_str(enum_type enum_par)
{
switch (enum_par) {
case alreadyInOneOrMoreConnectionManagedSessionsAndCannotSupportAnother: return "alreadyInOneOrMoreConnectionManagedSessionsAndCannotSupportAnother";
case systemResourcesWereNeededForAnotherTaskSoThisConnectionManagedSessionWasTerminated: return "systemResourcesWereNeededForAnotherTaskSoThisConnectionManagedSessionWasTerminated";
case aTimeoutOccurredAndThisIsTheConnectionAbortToCloseTheSession: return "aTimeoutOccurredAndThisIsTheConnectionAbortToCloseTheSession";
case cts__MessagesReceivedWhenDataTransferIsInProgress: return "cts_MessagesReceivedWhenDataTransferIsInProgress";
case maximumRetransmitRequestLimitReached: return "maximumRetransmitRequestLimitReached";
case unexpectedDataTransferPacket: return "unexpectedDataTransferPacket";
case badSequenceNumber: return "badSequenceNumber";
case duplicateSequenceNumber: return "duplicateSequenceNumber";
case unexpectedEDPO__Packet: return "unexpectedEDPO_Packet";
case unexpectedEDPO__PGN: return "unexpectedEDPO_PGN";
case edpo__numberOfPacketsIsGreaterThanCTS: return "edpo_numberOfPacketsIsGreaterThanCTS";
case badEDPO__Offset: return "badEDPO_Offset";
case unexpectedECTS__PGN: return "unexpectedECTS_PGN";
case ECTS__requestedPacketsExceedsMessageSize: return "ECTS_requestedPacketsExceedsMessageSize";
case iso__11783__7__error__code__251: return "iso_11783_7_error_code_251";
case iso__11783__7__error__code__252: return "iso_11783_7_error_code_252";
case iso__11783__7__error__code__253: return "iso_11783_7_error_code_253";
case iso__11783__7__error__code__254: return "iso_11783_7_error_code_254";
case iso__11783__7__error__code__255: return "iso_11783_7_error_code_255";
default: return "<unknown>";
}
}

e__ETP__ConnectionAbort__AbortReason::enum_type e__ETP__ConnectionAbort__AbortReason::str_to_enum(const char *str_par)
{
if (!strcmp(str_par, "alreadyInOneOrMoreConnectionManagedSessionsAndCannotSupportAnother")) return alreadyInOneOrMoreConnectionManagedSessionsAndCannotSupportAnother;
else if (!strcmp(str_par, "systemResourcesWereNeededForAnotherTaskSoThisConnectionManagedSessionWasTerminated")) return systemResourcesWereNeededForAnotherTaskSoThisConnectionManagedSessionWasTerminated;
else if (!strcmp(str_par, "aTimeoutOccurredAndThisIsTheConnectionAbortToCloseTheSession")) return aTimeoutOccurredAndThisIsTheConnectionAbortToCloseTheSession;
else if (!strcmp(str_par, "cts_MessagesReceivedWhenDataTransferIsInProgress")) return cts__MessagesReceivedWhenDataTransferIsInProgress;
else if (!strcmp(str_par, "maximumRetransmitRequestLimitReached")) return maximumRetransmitRequestLimitReached;
else if (!strcmp(str_par, "unexpectedDataTransferPacket")) return unexpectedDataTransferPacket;
else if (!strcmp(str_par, "badSequenceNumber")) return badSequenceNumber;
else if (!strcmp(str_par, "duplicateSequenceNumber")) return duplicateSequenceNumber;
else if (!strcmp(str_par, "unexpectedEDPO_Packet")) return unexpectedEDPO__Packet;
else if (!strcmp(str_par, "unexpectedEDPO_PGN")) return unexpectedEDPO__PGN;
else if (!strcmp(str_par, "edpo_numberOfPacketsIsGreaterThanCTS")) return edpo__numberOfPacketsIsGreaterThanCTS;
else if (!strcmp(str_par, "badEDPO_Offset")) return badEDPO__Offset;
else if (!strcmp(str_par, "unexpectedECTS_PGN")) return unexpectedECTS__PGN;
else if (!strcmp(str_par, "ECTS_requestedPacketsExceedsMessageSize")) return ECTS__requestedPacketsExceedsMessageSize;
else if (!strcmp(str_par, "iso_11783_7_error_code_251")) return iso__11783__7__error__code__251;
else if (!strcmp(str_par, "iso_11783_7_error_code_252")) return iso__11783__7__error__code__252;
else if (!strcmp(str_par, "iso_11783_7_error_code_253")) return iso__11783__7__error__code__253;
else if (!strcmp(str_par, "iso_11783_7_error_code_254")) return iso__11783__7__error__code__254;
else if (!strcmp(str_par, "iso_11783_7_error_code_255")) return iso__11783__7__error__code__255;
else return UNKNOWN_VALUE;
}

boolean e__ETP__ConnectionAbort__AbortReason::is_valid_enum(int int_par)
{
switch (int_par) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 14:
case 15:
case 251:
case 252:
case 253:
case 254:
case 255:
return TRUE;
default:
return FALSE;
}
}

int e__ETP__ConnectionAbort__AbortReason::enum2int(enum_type enum_par)
{
if (enum_par==UNBOUND_VALUE || enum_par==UNKNOWN_VALUE) TTCN_error("The argument of function enum2int() is an %s value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par;
}

int e__ETP__ConnectionAbort__AbortReason::enum2int(const e__ETP__ConnectionAbort__AbortReason& enum_par)
{
if (enum_par.enum_value==UNBOUND_VALUE || enum_par.enum_value==UNKNOWN_VALUE) TTCN_error("The argument of function enum2int() is an %s value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.", enum_par==UNBOUND_VALUE?"unbound":"invalid");
return enum_par.enum_value;
}

void e__ETP__ConnectionAbort__AbortReason::int2enum(int int_val)
{
if (!is_valid_enum(int_val)) TTCN_error("Assigning invalid numeric value %d to a variable of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.", int_val);
enum_value = (enum_type)int_val;
}

e__ETP__ConnectionAbort__AbortReason::operator e__ETP__ConnectionAbort__AbortReason::enum_type() const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("Using the value of an unbound variable of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
return enum_value;
}

void e__ETP__ConnectionAbort__AbortReason::log() const
{
if (enum_value != UNBOUND_VALUE) TTCN_Logger::log_event_enum(enum_to_str(enum_value), enum_value);
else TTCN_Logger::log_event_unbound();
}

void e__ETP__ConnectionAbort__AbortReason::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "enumerated value");
  if (param.get_type()!=Module_Param::MP_Enumerated) param.type_error("enumerated value", "@IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason");
  enum_value = str_to_enum(param.get_enumerated());
  if (!is_valid_enum(enum_value)) {
    param.error("Invalid enumerated value for type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
  }
}

void e__ETP__ConnectionAbort__AbortReason::encode_text(Text_Buf& text_buf) const
{
if (enum_value == UNBOUND_VALUE) TTCN_error("Text encoder: Encoding an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
text_buf.push_int(enum_value);
}

void e__ETP__ConnectionAbort__AbortReason::decode_text(Text_Buf& text_buf)
{
enum_value = (enum_type)text_buf.pull_int().get_val();
if (!is_valid_enum(enum_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.", enum_value);
}

void e__ETP__ConnectionAbort__AbortReason::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(TRUE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void e__ETP__ConnectionAbort__AbortReason::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int e__ETP__ConnectionAbort__AbortReason::RAW_decode(const TTCN_Typedescriptor_t& p_td,TTCN_Buffer& p_buf,int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit*)
{
  int decoded_value = 0;
  int decoded_length = RAW_decode_enum_type(p_td, p_buf, limit, top_bit_ord, decoded_value, 8, no_err);
  if (decoded_length < 0) return decoded_length;
  if (is_valid_enum(decoded_value)) enum_value = (enum_type)decoded_value;
  else {
    if(no_err){
     return -1;
    } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_ENC_ENUM, "Invalid enum value '%d' for '%s': ",decoded_value, p_td.name);
    enum_value = UNKNOWN_VALUE;
    }
  }
  return decoded_length;
}

int e__ETP__ConnectionAbort__AbortReason::RAW_encode(const TTCN_Typedescriptor_t& p_td, RAW_enc_tree& myleaf) const
{
  return RAW_encode_enum_type(p_td, myleaf, (int)enum_value, 8);
}

void e__ETP__ConnectionAbort__AbortReason_template::copy_template(const e__ETP__ConnectionAbort__AbortReason_template& other_value)
{
set_selection(other_value);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = other_value.single_value;
break;
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new e__ETP__ConnectionAbort__AbortReason_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
}
}

e__ETP__ConnectionAbort__AbortReason_template::e__ETP__ConnectionAbort__AbortReason_template()
{
}

e__ETP__ConnectionAbort__AbortReason_template::e__ETP__ConnectionAbort__AbortReason_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

e__ETP__ConnectionAbort__AbortReason_template::e__ETP__ConnectionAbort__AbortReason_template(int other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (!e__ETP__ConnectionAbort__AbortReason::is_valid_enum(other_value)) TTCN_error("Initializing a template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason with unknown numeric value %d.", other_value);
single_value = (e__ETP__ConnectionAbort__AbortReason::enum_type)other_value;
}

e__ETP__ConnectionAbort__AbortReason_template::e__ETP__ConnectionAbort__AbortReason_template(e__ETP__ConnectionAbort__AbortReason::enum_type other_value)
 : Base_Template(SPECIFIC_VALUE)
{
single_value = other_value;
}

e__ETP__ConnectionAbort__AbortReason_template::e__ETP__ConnectionAbort__AbortReason_template(const e__ETP__ConnectionAbort__AbortReason& other_value)
 : Base_Template(SPECIFIC_VALUE)
{
if (other_value.enum_value == e__ETP__ConnectionAbort__AbortReason::UNBOUND_VALUE) TTCN_error("Creating a template from an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
single_value = other_value.enum_value;
}

e__ETP__ConnectionAbort__AbortReason_template::e__ETP__ConnectionAbort__AbortReason_template(const OPTIONAL<e__ETP__ConnectionAbort__AbortReason>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (e__ETP__ConnectionAbort__AbortReason::enum_type)(const e__ETP__ConnectionAbort__AbortReason&)other_value;
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason from an unbound optional field.");
}
}

e__ETP__ConnectionAbort__AbortReason_template::e__ETP__ConnectionAbort__AbortReason_template(const e__ETP__ConnectionAbort__AbortReason_template& other_value)
 : Base_Template()
{
copy_template(other_value);
}

e__ETP__ConnectionAbort__AbortReason_template::~e__ETP__ConnectionAbort__AbortReason_template()
{
clean_up();
}

boolean e__ETP__ConnectionAbort__AbortReason_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
return TRUE;
}

boolean e__ETP__ConnectionAbort__AbortReason_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value != e__ETP__ConnectionAbort__AbortReason::UNBOUND_VALUE;
}

void e__ETP__ConnectionAbort__AbortReason_template::clean_up()
{
if (template_selection == VALUE_LIST || template_selection == COMPLEMENTED_LIST) delete [] value_list.list_value;
template_selection = UNINITIALIZED_TEMPLATE;
}

e__ETP__ConnectionAbort__AbortReason_template& e__ETP__ConnectionAbort__AbortReason_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

e__ETP__ConnectionAbort__AbortReason_template& e__ETP__ConnectionAbort__AbortReason_template::operator=(int other_value)
{
if (!e__ETP__ConnectionAbort__AbortReason::is_valid_enum(other_value)) TTCN_warning("Assigning unknown numeric value %d to a template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.", other_value);
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = (e__ETP__ConnectionAbort__AbortReason::enum_type)other_value;
return *this;
}

e__ETP__ConnectionAbort__AbortReason_template& e__ETP__ConnectionAbort__AbortReason_template::operator=(e__ETP__ConnectionAbort__AbortReason::enum_type other_value)
{
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = other_value;
return *this;
}

e__ETP__ConnectionAbort__AbortReason_template& e__ETP__ConnectionAbort__AbortReason_template::operator=(const e__ETP__ConnectionAbort__AbortReason& other_value)
{
if (other_value.enum_value == e__ETP__ConnectionAbort__AbortReason::UNBOUND_VALUE) TTCN_error("Assignment of an unbound value of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason to a template.");
clean_up();
set_selection(SPECIFIC_VALUE);
single_value = other_value.enum_value;
return *this;
}

e__ETP__ConnectionAbort__AbortReason_template& e__ETP__ConnectionAbort__AbortReason_template::operator=(const OPTIONAL<e__ETP__ConnectionAbort__AbortReason>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
set_selection(SPECIFIC_VALUE);
single_value = (e__ETP__ConnectionAbort__AbortReason::enum_type)(const e__ETP__ConnectionAbort__AbortReason&)other_value;
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
}
return *this;
}

e__ETP__ConnectionAbort__AbortReason_template& e__ETP__ConnectionAbort__AbortReason_template::operator=(const e__ETP__ConnectionAbort__AbortReason_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean e__ETP__ConnectionAbort__AbortReason_template::match(e__ETP__ConnectionAbort__AbortReason::enum_type other_value, boolean) const
{
switch (template_selection) {
case SPECIFIC_VALUE:
return single_value == other_value;
case OMIT_VALUE:
return FALSE;
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
}
return FALSE;
}

boolean e__ETP__ConnectionAbort__AbortReason_template::match(const e__ETP__ConnectionAbort__AbortReason& other_value, boolean) const
{
if (other_value.enum_value == e__ETP__ConnectionAbort__AbortReason::UNBOUND_VALUE) TTCN_error("Matching a template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason with an unbound value.");
return match(other_value.enum_value);
}

e__ETP__ConnectionAbort__AbortReason::enum_type e__ETP__ConnectionAbort__AbortReason_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) TTCN_error("Performing a valueof or send operation on a non-specific template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
return single_value;
}

void e__ETP__ConnectionAbort__AbortReason_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) TTCN_error("Setting an invalid list type for a template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new e__ETP__ConnectionAbort__AbortReason_template[list_length];
}

e__ETP__ConnectionAbort__AbortReason_template& e__ETP__ConnectionAbort__AbortReason_template::list_item(unsigned int list_index)
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST) TTCN_error("Accessing a list element in a non-list template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
if (list_index >= value_list.n_values) TTCN_error("Index overflow in a value list template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
return value_list.list_value[list_index];
}

void e__ETP__ConnectionAbort__AbortReason_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_enum(e__ETP__ConnectionAbort__AbortReason::enum_to_str(single_value), single_value);
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++) {
if (elem_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[elem_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void e__ETP__ConnectionAbort__AbortReason_template::log_match(const e__ETP__ConnectionAbort__AbortReason& match_value, boolean) const
{
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}

void e__ETP__ConnectionAbort__AbortReason_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
text_buf.push_int(single_value);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++)
value_list.list_value[elem_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
}
}

void e__ETP__ConnectionAbort__AbortReason_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = (e__ETP__ConnectionAbort__AbortReason::enum_type)text_buf.pull_int().get_val();
if (!e__ETP__ConnectionAbort__AbortReason::is_valid_enum(single_value)) TTCN_error("Text decoder: Unknown numeric value %d was received for a template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.", single_value);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new e__ETP__ConnectionAbort__AbortReason_template[value_list.n_values];
for (unsigned int elem_count = 0; elem_count < value_list.n_values; elem_count++)
value_list.list_value[elem_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received for a template of enumerated type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
}
}

boolean e__ETP__ConnectionAbort__AbortReason_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean e__ETP__ConnectionAbort__AbortReason_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int i=0; i<value_list.n_values; i++)
if (value_list.list_value[i].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void e__ETP__ConnectionAbort__AbortReason_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "enumerated template");
  Module_Param_Ptr m_p = &param;
  switch (m_p->get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    e__ETP__ConnectionAbort__AbortReason_template new_temp;
    new_temp.set_type(m_p->get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, m_p->get_size());
    for (size_t p_i=0; p_i<m_p->get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*m_p->get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Enumerated: {
    e__ETP__ConnectionAbort__AbortReason::enum_type enum_val = e__ETP__ConnectionAbort__AbortReason::str_to_enum(m_p->get_enumerated());
    if (!e__ETP__ConnectionAbort__AbortReason::is_valid_enum(enum_val)) {
      param.error("Invalid enumerated value for type @IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason.");
    }
    *this = enum_val;
  } break;
  default:
    param.type_error("enumerated template", "@IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason");
  }
  is_ifpresent = param.get_ifpresent();
}

void e__ETP__ConnectionAbort__AbortReason_template::check_restriction(template_res t_res, const char* t_name,
boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_VALUE:
if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
break;
case TR_OMIT:
if (!is_ifpresent && (template_selection==OMIT_VALUE || template_selection==SPECIFIC_VALUE)) return;
break;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.e_ETP_ConnectionAbort_AbortReason");
}

ExtendedMessageConnectionAbort::ExtendedMessageConnectionAbort()
{
}

ExtendedMessageConnectionAbort::ExtendedMessageConnectionAbort(const OCTETSTRING& par_ctrl,
    const e__ETP__ConnectionAbort__AbortReason& par_connectionAbortReason,
    const OCTETSTRING& par_reserved3,
    const OCTETSTRING& par_reserved4,
    const OCTETSTRING& par_reserved5,
    const INTEGER& par_pgnOfExtendedPacketedMessage)
  :   field_ctrl(par_ctrl),
  field_connectionAbortReason(par_connectionAbortReason),
  field_reserved3(par_reserved3),
  field_reserved4(par_reserved4),
  field_reserved5(par_reserved5),
  field_pgnOfExtendedPacketedMessage(par_pgnOfExtendedPacketedMessage)
{
}

ExtendedMessageConnectionAbort::ExtendedMessageConnectionAbort(const ExtendedMessageConnectionAbort& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
else field_ctrl.clean_up();
if (other_value.connectionAbortReason().is_bound()) field_connectionAbortReason = other_value.connectionAbortReason();
else field_connectionAbortReason.clean_up();
if (other_value.reserved3().is_bound()) field_reserved3 = other_value.reserved3();
else field_reserved3.clean_up();
if (other_value.reserved4().is_bound()) field_reserved4 = other_value.reserved4();
else field_reserved4.clean_up();
if (other_value.reserved5().is_bound()) field_reserved5 = other_value.reserved5();
else field_reserved5.clean_up();
if (other_value.pgnOfExtendedPacketedMessage().is_bound()) field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
else field_pgnOfExtendedPacketedMessage.clean_up();
}

void ExtendedMessageConnectionAbort::clean_up()
{
field_ctrl.clean_up();
field_connectionAbortReason.clean_up();
field_reserved3.clean_up();
field_reserved4.clean_up();
field_reserved5.clean_up();
field_pgnOfExtendedPacketedMessage.clean_up();
}

const TTCN_Typedescriptor_t* ExtendedMessageConnectionAbort::get_descriptor() const { return &ExtendedMessageConnectionAbort_descr_; }
ExtendedMessageConnectionAbort& ExtendedMessageConnectionAbort::operator=(const ExtendedMessageConnectionAbort& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
  if (other_value.ctrl().is_bound()) field_ctrl = other_value.ctrl();
  else field_ctrl.clean_up();
  if (other_value.connectionAbortReason().is_bound()) field_connectionAbortReason = other_value.connectionAbortReason();
  else field_connectionAbortReason.clean_up();
  if (other_value.reserved3().is_bound()) field_reserved3 = other_value.reserved3();
  else field_reserved3.clean_up();
  if (other_value.reserved4().is_bound()) field_reserved4 = other_value.reserved4();
  else field_reserved4.clean_up();
  if (other_value.reserved5().is_bound()) field_reserved5 = other_value.reserved5();
  else field_reserved5.clean_up();
  if (other_value.pgnOfExtendedPacketedMessage().is_bound()) field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
  else field_pgnOfExtendedPacketedMessage.clean_up();
}
return *this;
}

boolean ExtendedMessageConnectionAbort::operator==(const ExtendedMessageConnectionAbort& other_value) const
{
return field_ctrl==other_value.field_ctrl
  && field_connectionAbortReason==other_value.field_connectionAbortReason
  && field_reserved3==other_value.field_reserved3
  && field_reserved4==other_value.field_reserved4
  && field_reserved5==other_value.field_reserved5
  && field_pgnOfExtendedPacketedMessage==other_value.field_pgnOfExtendedPacketedMessage;
}

boolean ExtendedMessageConnectionAbort::is_bound() const
{
return (field_ctrl.is_bound())
  || (field_connectionAbortReason.is_bound())
  || (field_reserved3.is_bound())
  || (field_reserved4.is_bound())
  || (field_reserved5.is_bound())
  || (field_pgnOfExtendedPacketedMessage.is_bound());
}
boolean ExtendedMessageConnectionAbort::is_value() const
{
return field_ctrl.is_value()
  && field_connectionAbortReason.is_value()
  && field_reserved3.is_value()
  && field_reserved4.is_value()
  && field_reserved5.is_value()
  && field_pgnOfExtendedPacketedMessage.is_value();
}
void ExtendedMessageConnectionAbort::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ ctrl := ");
field_ctrl.log();
TTCN_Logger::log_event_str(", connectionAbortReason := ");
field_connectionAbortReason.log();
TTCN_Logger::log_event_str(", reserved3 := ");
field_reserved3.log();
TTCN_Logger::log_event_str(", reserved4 := ");
field_reserved4.log();
TTCN_Logger::log_event_str(", reserved5 := ");
field_reserved5.log();
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
field_pgnOfExtendedPacketedMessage.log();
TTCN_Logger::log_event_str(" }");
}

void ExtendedMessageConnectionAbort::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (6<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort has 6 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) connectionAbortReason().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) reserved3().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) reserved4().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) reserved5().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) pgnOfExtendedPacketedMessage().set_param(*param.get_elem(5));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "connectionAbortReason")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          connectionAbortReason().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved3")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved3().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved4")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved4().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved5")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved5().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfExtendedPacketedMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfExtendedPacketedMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort");
  }
}

void ExtendedMessageConnectionAbort::set_implicit_omit()
{
if (ctrl().is_bound()) ctrl().set_implicit_omit();
if (connectionAbortReason().is_bound()) connectionAbortReason().set_implicit_omit();
if (reserved3().is_bound()) reserved3().set_implicit_omit();
if (reserved4().is_bound()) reserved4().set_implicit_omit();
if (reserved5().is_bound()) reserved5().set_implicit_omit();
if (pgnOfExtendedPacketedMessage().is_bound()) pgnOfExtendedPacketedMessage().set_implicit_omit();
}

void ExtendedMessageConnectionAbort::encode_text(Text_Buf& text_buf) const
{
field_ctrl.encode_text(text_buf);
field_connectionAbortReason.encode_text(text_buf);
field_reserved3.encode_text(text_buf);
field_reserved4.encode_text(text_buf);
field_reserved5.encode_text(text_buf);
field_pgnOfExtendedPacketedMessage.encode_text(text_buf);
}

void ExtendedMessageConnectionAbort::decode_text(Text_Buf& text_buf)
{
field_ctrl.decode_text(text_buf);
field_connectionAbortReason.decode_text(text_buf);
field_reserved3.decode_text(text_buf);
field_reserved4.decode_text(text_buf);
field_reserved5.decode_text(text_buf);
field_pgnOfExtendedPacketedMessage.decode_text(text_buf);
}

void ExtendedMessageConnectionAbort::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void ExtendedMessageConnectionAbort::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int ExtendedMessageConnectionAbort::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, ExtendedMessageConnectionAbort_ctrl_descr_.raw->forceomit);
  decoded_field_length = field_ctrl.RAW_decode(ExtendedMessageConnectionAbort_ctrl_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, e__ETP__ConnectionAbort__AbortReason_descr_.raw->forceomit);
  decoded_field_length = field_connectionAbortReason.RAW_decode(e__ETP__ConnectionAbort__AbortReason_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_2_force_omit(2, force_omit, ExtendedMessageConnectionAbort_reserved3_descr_.raw->forceomit);
  decoded_field_length = field_reserved3.RAW_decode(ExtendedMessageConnectionAbort_reserved3_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_2_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_3_force_omit(3, force_omit, ExtendedMessageConnectionAbort_reserved4_descr_.raw->forceomit);
  decoded_field_length = field_reserved4.RAW_decode(ExtendedMessageConnectionAbort_reserved4_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_3_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_4_force_omit(4, force_omit, ExtendedMessageConnectionAbort_reserved5_descr_.raw->forceomit);
  decoded_field_length = field_reserved5.RAW_decode(ExtendedMessageConnectionAbort_reserved5_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_4_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_5_force_omit(5, force_omit, IsobusMessageTypes::PGN_descr_.raw->forceomit);
  decoded_field_length = field_pgnOfExtendedPacketedMessage.RAW_decode(IsobusMessageTypes::PGN_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_5_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int ExtendedMessageConnectionAbort::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 6;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(6);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, ExtendedMessageConnectionAbort_ctrl_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, e__ETP__ConnectionAbort__AbortReason_descr_.raw);
  myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 2, ExtendedMessageConnectionAbort_reserved3_descr_.raw);
  myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 3, ExtendedMessageConnectionAbort_reserved4_descr_.raw);
  myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 4, ExtendedMessageConnectionAbort_reserved5_descr_.raw);
  myleaf.body.node.nodes[5] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 5, IsobusMessageTypes::PGN_descr_.raw);
  encoded_length += field_ctrl.RAW_encode(ExtendedMessageConnectionAbort_ctrl_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_connectionAbortReason.RAW_encode(e__ETP__ConnectionAbort__AbortReason_descr_, *myleaf.body.node.nodes[1]);
  encoded_length += field_reserved3.RAW_encode(ExtendedMessageConnectionAbort_reserved3_descr_, *myleaf.body.node.nodes[2]);
  encoded_length += field_reserved4.RAW_encode(ExtendedMessageConnectionAbort_reserved4_descr_, *myleaf.body.node.nodes[3]);
  encoded_length += field_reserved5.RAW_encode(ExtendedMessageConnectionAbort_reserved5_descr_, *myleaf.body.node.nodes[4]);
  encoded_length += field_pgnOfExtendedPacketedMessage.RAW_encode(IsobusMessageTypes::PGN_descr_, *myleaf.body.node.nodes[5]);
  return myleaf.length = encoded_length;
}

struct ExtendedMessageConnectionAbort_template::single_value_struct {
OCTETSTRING_template field_ctrl;
e__ETP__ConnectionAbort__AbortReason_template field_connectionAbortReason;
OCTETSTRING_template field_reserved3;
OCTETSTRING_template field_reserved4;
OCTETSTRING_template field_reserved5;
INTEGER_template field_pgnOfExtendedPacketedMessage;
};

void ExtendedMessageConnectionAbort_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_ctrl = ANY_VALUE;
single_value->field_connectionAbortReason = ANY_VALUE;
single_value->field_reserved3 = ANY_VALUE;
single_value->field_reserved4 = ANY_VALUE;
single_value->field_reserved5 = ANY_VALUE;
single_value->field_pgnOfExtendedPacketedMessage = ANY_VALUE;
}
}
}

void ExtendedMessageConnectionAbort_template::copy_value(const ExtendedMessageConnectionAbort& other_value)
{
single_value = new single_value_struct;
if (other_value.ctrl().is_bound()) {
  single_value->field_ctrl = other_value.ctrl();
} else {
  single_value->field_ctrl.clean_up();
}
if (other_value.connectionAbortReason().is_bound()) {
  single_value->field_connectionAbortReason = other_value.connectionAbortReason();
} else {
  single_value->field_connectionAbortReason.clean_up();
}
if (other_value.reserved3().is_bound()) {
  single_value->field_reserved3 = other_value.reserved3();
} else {
  single_value->field_reserved3.clean_up();
}
if (other_value.reserved4().is_bound()) {
  single_value->field_reserved4 = other_value.reserved4();
} else {
  single_value->field_reserved4.clean_up();
}
if (other_value.reserved5().is_bound()) {
  single_value->field_reserved5 = other_value.reserved5();
} else {
  single_value->field_reserved5.clean_up();
}
if (other_value.pgnOfExtendedPacketedMessage().is_bound()) {
  single_value->field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
} else {
  single_value->field_pgnOfExtendedPacketedMessage.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void ExtendedMessageConnectionAbort_template::copy_template(const ExtendedMessageConnectionAbort_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.ctrl().get_selection()) {
single_value->field_ctrl = other_value.ctrl();
} else {
single_value->field_ctrl.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.connectionAbortReason().get_selection()) {
single_value->field_connectionAbortReason = other_value.connectionAbortReason();
} else {
single_value->field_connectionAbortReason.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.reserved3().get_selection()) {
single_value->field_reserved3 = other_value.reserved3();
} else {
single_value->field_reserved3.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.reserved4().get_selection()) {
single_value->field_reserved4 = other_value.reserved4();
} else {
single_value->field_reserved4.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.reserved5().get_selection()) {
single_value->field_reserved5 = other_value.reserved5();
} else {
single_value->field_reserved5.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.pgnOfExtendedPacketedMessage().get_selection()) {
single_value->field_pgnOfExtendedPacketedMessage = other_value.pgnOfExtendedPacketedMessage();
} else {
single_value->field_pgnOfExtendedPacketedMessage.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new ExtendedMessageConnectionAbort_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
break;
}
set_selection(other_value);
}

ExtendedMessageConnectionAbort_template::ExtendedMessageConnectionAbort_template()
{
}

ExtendedMessageConnectionAbort_template::ExtendedMessageConnectionAbort_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

ExtendedMessageConnectionAbort_template::ExtendedMessageConnectionAbort_template(const ExtendedMessageConnectionAbort& other_value)
{
copy_value(other_value);
}

ExtendedMessageConnectionAbort_template::ExtendedMessageConnectionAbort_template(const OPTIONAL<ExtendedMessageConnectionAbort>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ExtendedMessageConnectionAbort&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort from an unbound optional field.");
}
}

ExtendedMessageConnectionAbort_template::ExtendedMessageConnectionAbort_template(const ExtendedMessageConnectionAbort_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

ExtendedMessageConnectionAbort_template::~ExtendedMessageConnectionAbort_template()
{
clean_up();
}

ExtendedMessageConnectionAbort_template& ExtendedMessageConnectionAbort_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

ExtendedMessageConnectionAbort_template& ExtendedMessageConnectionAbort_template::operator=(const ExtendedMessageConnectionAbort& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

ExtendedMessageConnectionAbort_template& ExtendedMessageConnectionAbort_template::operator=(const OPTIONAL<ExtendedMessageConnectionAbort>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ExtendedMessageConnectionAbort&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
}
return *this;
}

ExtendedMessageConnectionAbort_template& ExtendedMessageConnectionAbort_template::operator=(const ExtendedMessageConnectionAbort_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean ExtendedMessageConnectionAbort_template::match(const ExtendedMessageConnectionAbort& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.ctrl().is_bound()) return FALSE;
if(!single_value->field_ctrl.match(other_value.ctrl(), legacy))return FALSE;
if(!other_value.connectionAbortReason().is_bound()) return FALSE;
if(!single_value->field_connectionAbortReason.match(other_value.connectionAbortReason(), legacy))return FALSE;
if(!other_value.reserved3().is_bound()) return FALSE;
if(!single_value->field_reserved3.match(other_value.reserved3(), legacy))return FALSE;
if(!other_value.reserved4().is_bound()) return FALSE;
if(!single_value->field_reserved4.match(other_value.reserved4(), legacy))return FALSE;
if(!other_value.reserved5().is_bound()) return FALSE;
if(!single_value->field_reserved5.match(other_value.reserved5(), legacy))return FALSE;
if(!other_value.pgnOfExtendedPacketedMessage().is_bound()) return FALSE;
if(!single_value->field_pgnOfExtendedPacketedMessage.match(other_value.pgnOfExtendedPacketedMessage(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
}
return FALSE;
}

boolean ExtendedMessageConnectionAbort_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_ctrl.is_bound()

 ||single_value->field_connectionAbortReason.is_bound()

 ||single_value->field_reserved3.is_bound()

 ||single_value->field_reserved4.is_bound()

 ||single_value->field_reserved5.is_bound()

 ||single_value->field_pgnOfExtendedPacketedMessage.is_bound()
;
}

boolean ExtendedMessageConnectionAbort_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_ctrl.is_value()
 &&single_value->field_connectionAbortReason.is_value()
 &&single_value->field_reserved3.is_value()
 &&single_value->field_reserved4.is_value()
 &&single_value->field_reserved5.is_value()
 &&single_value->field_pgnOfExtendedPacketedMessage.is_value();
}

void ExtendedMessageConnectionAbort_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

ExtendedMessageConnectionAbort ExtendedMessageConnectionAbort_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
ExtendedMessageConnectionAbort ret_val;
if (single_value->field_ctrl.is_bound()) {
ret_val.ctrl() = single_value->field_ctrl.valueof();
}
if (single_value->field_connectionAbortReason.is_bound()) {
ret_val.connectionAbortReason() = single_value->field_connectionAbortReason.valueof();
}
if (single_value->field_reserved3.is_bound()) {
ret_val.reserved3() = single_value->field_reserved3.valueof();
}
if (single_value->field_reserved4.is_bound()) {
ret_val.reserved4() = single_value->field_reserved4.valueof();
}
if (single_value->field_reserved5.is_bound()) {
ret_val.reserved5() = single_value->field_reserved5.valueof();
}
if (single_value->field_pgnOfExtendedPacketedMessage.is_bound()) {
ret_val.pgnOfExtendedPacketedMessage() = single_value->field_pgnOfExtendedPacketedMessage.valueof();
}
return ret_val;
}

void ExtendedMessageConnectionAbort_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new ExtendedMessageConnectionAbort_template[list_length];
}

ExtendedMessageConnectionAbort_template& ExtendedMessageConnectionAbort_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
return value_list.list_value[list_index];
}

OCTETSTRING_template& ExtendedMessageConnectionAbort_template::ctrl()
{
set_specific();
return single_value->field_ctrl;
}

const OCTETSTRING_template& ExtendedMessageConnectionAbort_template::ctrl() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field ctrl of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
return single_value->field_ctrl;
}

e__ETP__ConnectionAbort__AbortReason_template& ExtendedMessageConnectionAbort_template::connectionAbortReason()
{
set_specific();
return single_value->field_connectionAbortReason;
}

const e__ETP__ConnectionAbort__AbortReason_template& ExtendedMessageConnectionAbort_template::connectionAbortReason() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field connectionAbortReason of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
return single_value->field_connectionAbortReason;
}

OCTETSTRING_template& ExtendedMessageConnectionAbort_template::reserved3()
{
set_specific();
return single_value->field_reserved3;
}

const OCTETSTRING_template& ExtendedMessageConnectionAbort_template::reserved3() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field reserved3 of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
return single_value->field_reserved3;
}

OCTETSTRING_template& ExtendedMessageConnectionAbort_template::reserved4()
{
set_specific();
return single_value->field_reserved4;
}

const OCTETSTRING_template& ExtendedMessageConnectionAbort_template::reserved4() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field reserved4 of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
return single_value->field_reserved4;
}

OCTETSTRING_template& ExtendedMessageConnectionAbort_template::reserved5()
{
set_specific();
return single_value->field_reserved5;
}

const OCTETSTRING_template& ExtendedMessageConnectionAbort_template::reserved5() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field reserved5 of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
return single_value->field_reserved5;
}

INTEGER_template& ExtendedMessageConnectionAbort_template::pgnOfExtendedPacketedMessage()
{
set_specific();
return single_value->field_pgnOfExtendedPacketedMessage;
}

const INTEGER_template& ExtendedMessageConnectionAbort_template::pgnOfExtendedPacketedMessage() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field pgnOfExtendedPacketedMessage of a non-specific template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
return single_value->field_pgnOfExtendedPacketedMessage;
}

int ExtendedMessageConnectionAbort_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 6;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
  }
  return 0;
}

void ExtendedMessageConnectionAbort_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log();
TTCN_Logger::log_event_str(", connectionAbortReason := ");
single_value->field_connectionAbortReason.log();
TTCN_Logger::log_event_str(", reserved3 := ");
single_value->field_reserved3.log();
TTCN_Logger::log_event_str(", reserved4 := ");
single_value->field_reserved4.log();
TTCN_Logger::log_event_str(", reserved5 := ");
single_value->field_reserved5.log();
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
single_value->field_pgnOfExtendedPacketedMessage.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void ExtendedMessageConnectionAbort_template::log_match(const ExtendedMessageConnectionAbort& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_ctrl.match(match_value.ctrl(), legacy)){
TTCN_Logger::log_logmatch_info(".ctrl");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_connectionAbortReason.match(match_value.connectionAbortReason(), legacy)){
TTCN_Logger::log_logmatch_info(".connectionAbortReason");
single_value->field_connectionAbortReason.log_match(match_value.connectionAbortReason(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_reserved3.match(match_value.reserved3(), legacy)){
TTCN_Logger::log_logmatch_info(".reserved3");
single_value->field_reserved3.log_match(match_value.reserved3(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_reserved4.match(match_value.reserved4(), legacy)){
TTCN_Logger::log_logmatch_info(".reserved4");
single_value->field_reserved4.log_match(match_value.reserved4(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_reserved5.match(match_value.reserved5(), legacy)){
TTCN_Logger::log_logmatch_info(".reserved5");
single_value->field_reserved5.log_match(match_value.reserved5(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_pgnOfExtendedPacketedMessage.match(match_value.pgnOfExtendedPacketedMessage(), legacy)){
TTCN_Logger::log_logmatch_info(".pgnOfExtendedPacketedMessage");
single_value->field_pgnOfExtendedPacketedMessage.log_match(match_value.pgnOfExtendedPacketedMessage(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ ctrl := ");
single_value->field_ctrl.log_match(match_value.ctrl(), legacy);
TTCN_Logger::log_event_str(", connectionAbortReason := ");
single_value->field_connectionAbortReason.log_match(match_value.connectionAbortReason(), legacy);
TTCN_Logger::log_event_str(", reserved3 := ");
single_value->field_reserved3.log_match(match_value.reserved3(), legacy);
TTCN_Logger::log_event_str(", reserved4 := ");
single_value->field_reserved4.log_match(match_value.reserved4(), legacy);
TTCN_Logger::log_event_str(", reserved5 := ");
single_value->field_reserved5.log_match(match_value.reserved5(), legacy);
TTCN_Logger::log_event_str(", pgnOfExtendedPacketedMessage := ");
single_value->field_pgnOfExtendedPacketedMessage.log_match(match_value.pgnOfExtendedPacketedMessage(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void ExtendedMessageConnectionAbort_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_ctrl.encode_text(text_buf);
single_value->field_connectionAbortReason.encode_text(text_buf);
single_value->field_reserved3.encode_text(text_buf);
single_value->field_reserved4.encode_text(text_buf);
single_value->field_reserved5.encode_text(text_buf);
single_value->field_pgnOfExtendedPacketedMessage.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
}
}

void ExtendedMessageConnectionAbort_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_ctrl.decode_text(text_buf);
single_value->field_connectionAbortReason.decode_text(text_buf);
single_value->field_reserved3.decode_text(text_buf);
single_value->field_reserved4.decode_text(text_buf);
single_value->field_reserved5.decode_text(text_buf);
single_value->field_pgnOfExtendedPacketedMessage.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new ExtendedMessageConnectionAbort_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort.");
}
}

void ExtendedMessageConnectionAbort_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    ExtendedMessageConnectionAbort_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (6<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort has 6 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) ctrl().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) connectionAbortReason().set_param(*param.get_elem(1));
    if (param.get_size()>2 && param.get_elem(2)->get_type()!=Module_Param::MP_NotUsed) reserved3().set_param(*param.get_elem(2));
    if (param.get_size()>3 && param.get_elem(3)->get_type()!=Module_Param::MP_NotUsed) reserved4().set_param(*param.get_elem(3));
    if (param.get_size()>4 && param.get_elem(4)->get_type()!=Module_Param::MP_NotUsed) reserved5().set_param(*param.get_elem(4));
    if (param.get_size()>5 && param.get_elem(5)->get_type()!=Module_Param::MP_NotUsed) pgnOfExtendedPacketedMessage().set_param(*param.get_elem(5));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "ctrl")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          ctrl().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "connectionAbortReason")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          connectionAbortReason().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved3")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved3().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved4")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved4().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "reserved5")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          reserved5().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "pgnOfExtendedPacketedMessage")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          pgnOfExtendedPacketedMessage().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ExtendedMessageConnectionAbort: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort");
  }
  is_ifpresent = param.get_ifpresent();
}

void ExtendedMessageConnectionAbort_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_ctrl.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort");
single_value->field_connectionAbortReason.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort");
single_value->field_reserved3.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort");
single_value->field_reserved4.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort");
single_value->field_reserved5.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort");
single_value->field_pgnOfExtendedPacketedMessage.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.ExtendedMessageConnectionAbort");
}

boolean ExtendedMessageConnectionAbort_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean ExtendedMessageConnectionAbort_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void ETP__CM::copy_value(const ETP__CM& other_value)
{
switch (other_value.union_selection) {
case ALT_extendedMessageRequestToSend:
field_extendedMessageRequestToSend = new ExtendedMessageRequestToSend(*other_value.field_extendedMessageRequestToSend);
break;
case ALT_extendedMessageClearToSend:
field_extendedMessageClearToSend = new ExtendedMessageClearToSend(*other_value.field_extendedMessageClearToSend);
break;
case ALT_extendedMessageDataPacketOffset:
field_extendedMessageDataPacketOffset = new ExtendedMessageDataPacketOffset(*other_value.field_extendedMessageDataPacketOffset);
break;
case ALT_extendedMessageEndOfMessageAcknowledgement:
field_extendedMessageEndOfMessageAcknowledgement = new ExtendedMessageEndOfMessageAcknowledgement(*other_value.field_extendedMessageEndOfMessageAcknowledgement);
break;
case ALT_extendedMessageConnectionAbort:
field_extendedMessageConnectionAbort = new ExtendedMessageConnectionAbort(*other_value.field_extendedMessageConnectionAbort);
break;
default:
TTCN_error("Assignment of an unbound union value of type @IsobusCMMessageTypes.ETP_CM.");
}
union_selection = other_value.union_selection;
}

ETP__CM::ETP__CM()
{
union_selection = UNBOUND_VALUE;
}

ETP__CM::ETP__CM(const ETP__CM& other_value)
: Base_Type(){
copy_value(other_value);
}

ETP__CM::~ETP__CM()
{
clean_up();
}

ETP__CM& ETP__CM::operator=(const ETP__CM& other_value)
{
if (this != &other_value) {
clean_up();
copy_value(other_value);
}
return *this;
}

boolean ETP__CM::operator==(const ETP__CM& other_value) const
{
if (union_selection == UNBOUND_VALUE) TTCN_error("The left operand of comparison is an unbound value of union type @IsobusCMMessageTypes.ETP_CM.");
if (other_value.union_selection == UNBOUND_VALUE) TTCN_error("The right operand of comparison is an unbound value of union type @IsobusCMMessageTypes.ETP_CM.");
if (union_selection != other_value.union_selection) return FALSE;
switch (union_selection) {
case ALT_extendedMessageRequestToSend:
return *field_extendedMessageRequestToSend == *other_value.field_extendedMessageRequestToSend;
case ALT_extendedMessageClearToSend:
return *field_extendedMessageClearToSend == *other_value.field_extendedMessageClearToSend;
case ALT_extendedMessageDataPacketOffset:
return *field_extendedMessageDataPacketOffset == *other_value.field_extendedMessageDataPacketOffset;
case ALT_extendedMessageEndOfMessageAcknowledgement:
return *field_extendedMessageEndOfMessageAcknowledgement == *other_value.field_extendedMessageEndOfMessageAcknowledgement;
case ALT_extendedMessageConnectionAbort:
return *field_extendedMessageConnectionAbort == *other_value.field_extendedMessageConnectionAbort;
default:
return FALSE;
}
}

ExtendedMessageRequestToSend& ETP__CM::extendedMessageRequestToSend()
{
if (union_selection != ALT_extendedMessageRequestToSend) {
clean_up();
field_extendedMessageRequestToSend = new ExtendedMessageRequestToSend;
union_selection = ALT_extendedMessageRequestToSend;
}
return *field_extendedMessageRequestToSend;
}

const ExtendedMessageRequestToSend& ETP__CM::extendedMessageRequestToSend() const
{
if (union_selection != ALT_extendedMessageRequestToSend) TTCN_error("Using non-selected field extendedMessageRequestToSend in a value of union type @IsobusCMMessageTypes.ETP_CM.");
return *field_extendedMessageRequestToSend;
}

ExtendedMessageClearToSend& ETP__CM::extendedMessageClearToSend()
{
if (union_selection != ALT_extendedMessageClearToSend) {
clean_up();
field_extendedMessageClearToSend = new ExtendedMessageClearToSend;
union_selection = ALT_extendedMessageClearToSend;
}
return *field_extendedMessageClearToSend;
}

const ExtendedMessageClearToSend& ETP__CM::extendedMessageClearToSend() const
{
if (union_selection != ALT_extendedMessageClearToSend) TTCN_error("Using non-selected field extendedMessageClearToSend in a value of union type @IsobusCMMessageTypes.ETP_CM.");
return *field_extendedMessageClearToSend;
}

ExtendedMessageDataPacketOffset& ETP__CM::extendedMessageDataPacketOffset()
{
if (union_selection != ALT_extendedMessageDataPacketOffset) {
clean_up();
field_extendedMessageDataPacketOffset = new ExtendedMessageDataPacketOffset;
union_selection = ALT_extendedMessageDataPacketOffset;
}
return *field_extendedMessageDataPacketOffset;
}

const ExtendedMessageDataPacketOffset& ETP__CM::extendedMessageDataPacketOffset() const
{
if (union_selection != ALT_extendedMessageDataPacketOffset) TTCN_error("Using non-selected field extendedMessageDataPacketOffset in a value of union type @IsobusCMMessageTypes.ETP_CM.");
return *field_extendedMessageDataPacketOffset;
}

ExtendedMessageEndOfMessageAcknowledgement& ETP__CM::extendedMessageEndOfMessageAcknowledgement()
{
if (union_selection != ALT_extendedMessageEndOfMessageAcknowledgement) {
clean_up();
field_extendedMessageEndOfMessageAcknowledgement = new ExtendedMessageEndOfMessageAcknowledgement;
union_selection = ALT_extendedMessageEndOfMessageAcknowledgement;
}
return *field_extendedMessageEndOfMessageAcknowledgement;
}

const ExtendedMessageEndOfMessageAcknowledgement& ETP__CM::extendedMessageEndOfMessageAcknowledgement() const
{
if (union_selection != ALT_extendedMessageEndOfMessageAcknowledgement) TTCN_error("Using non-selected field extendedMessageEndOfMessageAcknowledgement in a value of union type @IsobusCMMessageTypes.ETP_CM.");
return *field_extendedMessageEndOfMessageAcknowledgement;
}

ExtendedMessageConnectionAbort& ETP__CM::extendedMessageConnectionAbort()
{
if (union_selection != ALT_extendedMessageConnectionAbort) {
clean_up();
field_extendedMessageConnectionAbort = new ExtendedMessageConnectionAbort;
union_selection = ALT_extendedMessageConnectionAbort;
}
return *field_extendedMessageConnectionAbort;
}

const ExtendedMessageConnectionAbort& ETP__CM::extendedMessageConnectionAbort() const
{
if (union_selection != ALT_extendedMessageConnectionAbort) TTCN_error("Using non-selected field extendedMessageConnectionAbort in a value of union type @IsobusCMMessageTypes.ETP_CM.");
return *field_extendedMessageConnectionAbort;
}

boolean ETP__CM::ischosen(union_selection_type checked_selection) const
{
if (checked_selection == UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @IsobusCMMessageTypes.ETP_CM.");
return union_selection == checked_selection;
}

boolean ETP__CM::is_bound() const
{
  return union_selection != UNBOUND_VALUE;
}

boolean ETP__CM::is_value() const
{
switch (union_selection) {
case UNBOUND_VALUE: return FALSE;
case ALT_extendedMessageRequestToSend: return field_extendedMessageRequestToSend->is_value();
case ALT_extendedMessageClearToSend: return field_extendedMessageClearToSend->is_value();
case ALT_extendedMessageDataPacketOffset: return field_extendedMessageDataPacketOffset->is_value();
case ALT_extendedMessageEndOfMessageAcknowledgement: return field_extendedMessageEndOfMessageAcknowledgement->is_value();
case ALT_extendedMessageConnectionAbort: return field_extendedMessageConnectionAbort->is_value();
default: TTCN_error("Invalid selection in union is_bound");}
}

void ETP__CM::clean_up()
{
switch (union_selection) {
case ALT_extendedMessageRequestToSend:
  delete field_extendedMessageRequestToSend;
  break;
case ALT_extendedMessageClearToSend:
  delete field_extendedMessageClearToSend;
  break;
case ALT_extendedMessageDataPacketOffset:
  delete field_extendedMessageDataPacketOffset;
  break;
case ALT_extendedMessageEndOfMessageAcknowledgement:
  delete field_extendedMessageEndOfMessageAcknowledgement;
  break;
case ALT_extendedMessageConnectionAbort:
  delete field_extendedMessageConnectionAbort;
  break;
default:
  break;
}
union_selection = UNBOUND_VALUE;
}

void ETP__CM::log() const
{
switch (union_selection) {
case ALT_extendedMessageRequestToSend:
TTCN_Logger::log_event_str("{ extendedMessageRequestToSend := ");
field_extendedMessageRequestToSend->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_extendedMessageClearToSend:
TTCN_Logger::log_event_str("{ extendedMessageClearToSend := ");
field_extendedMessageClearToSend->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_extendedMessageDataPacketOffset:
TTCN_Logger::log_event_str("{ extendedMessageDataPacketOffset := ");
field_extendedMessageDataPacketOffset->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_extendedMessageEndOfMessageAcknowledgement:
TTCN_Logger::log_event_str("{ extendedMessageEndOfMessageAcknowledgement := ");
field_extendedMessageEndOfMessageAcknowledgement->log();
TTCN_Logger::log_event_str(" }");
break;
case ALT_extendedMessageConnectionAbort:
TTCN_Logger::log_event_str("{ extendedMessageConnectionAbort := ");
field_extendedMessageConnectionAbort->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_unbound();
}
}

void ETP__CM::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "union value");
  Module_Param_Ptr m_p = &param;
  if (m_p->get_type()==Module_Param::MP_Value_List && m_p->get_size()==0) return;
  if (m_p->get_type()!=Module_Param::MP_Assignment_List) {
    param.error("union value with field name was expected");
  }
  Module_Param* mp_last = m_p->get_elem(m_p->get_size()-1);
  char* last_name = mp_last->get_id()->get_name();
  if (!strcmp(last_name, "extendedMessageRequestToSend")) {
    extendedMessageRequestToSend().set_param(*mp_last);
    if (!extendedMessageRequestToSend().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "extendedMessageClearToSend")) {
    extendedMessageClearToSend().set_param(*mp_last);
    if (!extendedMessageClearToSend().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "extendedMessageDataPacketOffset")) {
    extendedMessageDataPacketOffset().set_param(*mp_last);
    if (!extendedMessageDataPacketOffset().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "extendedMessageEndOfMessageAcknowledgement")) {
    extendedMessageEndOfMessageAcknowledgement().set_param(*mp_last);
    if (!extendedMessageEndOfMessageAcknowledgement().is_bound()) clean_up();
    return;
  }
  if (!strcmp(last_name, "extendedMessageConnectionAbort")) {
    extendedMessageConnectionAbort().set_param(*mp_last);
    if (!extendedMessageConnectionAbort().is_bound()) clean_up();
    return;
  }
  mp_last->error("Field %s does not exist in type @IsobusCMMessageTypes.ETP_CM.", last_name);
}

void ETP__CM::set_implicit_omit()
{
switch (union_selection) {
case ALT_extendedMessageRequestToSend:
field_extendedMessageRequestToSend->set_implicit_omit(); break;
case ALT_extendedMessageClearToSend:
field_extendedMessageClearToSend->set_implicit_omit(); break;
case ALT_extendedMessageDataPacketOffset:
field_extendedMessageDataPacketOffset->set_implicit_omit(); break;
case ALT_extendedMessageEndOfMessageAcknowledgement:
field_extendedMessageEndOfMessageAcknowledgement->set_implicit_omit(); break;
case ALT_extendedMessageConnectionAbort:
field_extendedMessageConnectionAbort->set_implicit_omit(); break;
default: break;
}
}

void ETP__CM::encode_text(Text_Buf& text_buf) const
{
text_buf.push_int(union_selection);
switch (union_selection) {
case ALT_extendedMessageRequestToSend:
field_extendedMessageRequestToSend->encode_text(text_buf);
break;
case ALT_extendedMessageClearToSend:
field_extendedMessageClearToSend->encode_text(text_buf);
break;
case ALT_extendedMessageDataPacketOffset:
field_extendedMessageDataPacketOffset->encode_text(text_buf);
break;
case ALT_extendedMessageEndOfMessageAcknowledgement:
field_extendedMessageEndOfMessageAcknowledgement->encode_text(text_buf);
break;
case ALT_extendedMessageConnectionAbort:
field_extendedMessageConnectionAbort->encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an unbound value of union type @IsobusCMMessageTypes.ETP_CM.");
}
}

void ETP__CM::decode_text(Text_Buf& text_buf)
{
switch ((union_selection_type)text_buf.pull_int().get_val()) {
case ALT_extendedMessageRequestToSend:
extendedMessageRequestToSend().decode_text(text_buf);
break;
case ALT_extendedMessageClearToSend:
extendedMessageClearToSend().decode_text(text_buf);
break;
case ALT_extendedMessageDataPacketOffset:
extendedMessageDataPacketOffset().decode_text(text_buf);
break;
case ALT_extendedMessageEndOfMessageAcknowledgement:
extendedMessageEndOfMessageAcknowledgement().decode_text(text_buf);
break;
case ALT_extendedMessageConnectionAbort:
extendedMessageConnectionAbort().decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for type @IsobusCMMessageTypes.ETP_CM.");
}
}

void ETP__CM::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(TRUE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void ETP__CM::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int ETP__CM::RAW_decode(
const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, 
raw_order_t top_bit_ord, boolean no_err, int sel_field, boolean, const RAW_Force_Omit* force_omit)
{
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  int decoded_length=0;
  int starting_pos=p_buf.get_pos_bit();
  if(sel_field!=-1){
    switch(sel_field){
    case 0: {
      RAW_Force_Omit field_force_omit(0, force_omit, ExtendedMessageRequestToSend_descr_.raw->forceomit);
      decoded_length = extendedMessageRequestToSend().RAW_decode(ExtendedMessageRequestToSend_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 1: {
      RAW_Force_Omit field_force_omit(1, force_omit, ExtendedMessageClearToSend_descr_.raw->forceomit);
      decoded_length = extendedMessageClearToSend().RAW_decode(ExtendedMessageClearToSend_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 2: {
      RAW_Force_Omit field_force_omit(2, force_omit, ExtendedMessageDataPacketOffset_descr_.raw->forceomit);
      decoded_length = extendedMessageDataPacketOffset().RAW_decode(ExtendedMessageDataPacketOffset_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 3: {
      RAW_Force_Omit field_force_omit(3, force_omit, ExtendedMessageEndOfMessageAcknowledgement_descr_.raw->forceomit);
      decoded_length = extendedMessageEndOfMessageAcknowledgement().RAW_decode(ExtendedMessageEndOfMessageAcknowledgement_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    case 4: {
      RAW_Force_Omit field_force_omit(4, force_omit, ExtendedMessageConnectionAbort_descr_.raw->forceomit);
      decoded_length = extendedMessageConnectionAbort().RAW_decode(ExtendedMessageConnectionAbort_descr_, p_buf, limit, top_bit_ord, no_err, -1, TRUE, &field_force_omit);
      break; }
    default: break;
    }
    return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
  } else {
    boolean already_failed = FALSE;
    already_failed = FALSE;
    if (!already_failed) {
      OCTETSTRING temporal_0;
      int decoded_0_length;
      p_buf.set_pos_bit(starting_pos + 0);
      decoded_0_length = temporal_0.RAW_decode(ExtendedMessageRequestToSend_ctrl_descr_, p_buf, limit, top_bit_ord, TRUE);
      if (decoded_0_length > 0) {
        if (temporal_0 ==  os_3) {
          p_buf.set_pos_bit(starting_pos);
          RAW_Force_Omit field_force_omit(0, force_omit, ExtendedMessageRequestToSend_descr_.raw->forceomit);
          decoded_length = extendedMessageRequestToSend().RAW_decode(ExtendedMessageRequestToSend_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_force_omit);
          if (decoded_length > 0) {
             if ((*field_extendedMessageRequestToSend).ctrl() ==  os_3) {
               return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
             }else already_failed = TRUE;
          }
        }
      }
    }
    already_failed = FALSE;
    if (!already_failed) {
      OCTETSTRING temporal_1;
      int decoded_1_length;
      p_buf.set_pos_bit(starting_pos + 0);
      decoded_1_length = temporal_1.RAW_decode(ExtendedMessageClearToSend_ctrl_descr_, p_buf, limit, top_bit_ord, TRUE);
      if (decoded_1_length > 0) {
        if (temporal_1 ==  os_5) {
          p_buf.set_pos_bit(starting_pos);
          RAW_Force_Omit field_force_omit(1, force_omit, ExtendedMessageClearToSend_descr_.raw->forceomit);
          decoded_length = extendedMessageClearToSend().RAW_decode(ExtendedMessageClearToSend_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_force_omit);
          if (decoded_length > 0) {
             if ((*field_extendedMessageClearToSend).ctrl() ==  os_5) {
               return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
             }else already_failed = TRUE;
          }
        }
      }
    }
    already_failed = FALSE;
    if (!already_failed) {
      OCTETSTRING temporal_2;
      int decoded_2_length;
      p_buf.set_pos_bit(starting_pos + 0);
      decoded_2_length = temporal_2.RAW_decode(ExtendedMessageDataPacketOffset_ctrl_descr_, p_buf, limit, top_bit_ord, TRUE);
      if (decoded_2_length > 0) {
        if (temporal_2 ==  os_6) {
          p_buf.set_pos_bit(starting_pos);
          RAW_Force_Omit field_force_omit(2, force_omit, ExtendedMessageDataPacketOffset_descr_.raw->forceomit);
          decoded_length = extendedMessageDataPacketOffset().RAW_decode(ExtendedMessageDataPacketOffset_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_force_omit);
          if (decoded_length > 0) {
             if ((*field_extendedMessageDataPacketOffset).ctrl() ==  os_6) {
               return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
             }else already_failed = TRUE;
          }
        }
      }
    }
    already_failed = FALSE;
    if (!already_failed) {
      OCTETSTRING temporal_3;
      int decoded_3_length;
      p_buf.set_pos_bit(starting_pos + 0);
      decoded_3_length = temporal_3.RAW_decode(ExtendedMessageEndOfMessageAcknowledgement_ctrl_descr_, p_buf, limit, top_bit_ord, TRUE);
      if (decoded_3_length > 0) {
        if (temporal_3 ==  os_7) {
          p_buf.set_pos_bit(starting_pos);
          RAW_Force_Omit field_force_omit(3, force_omit, ExtendedMessageEndOfMessageAcknowledgement_descr_.raw->forceomit);
          decoded_length = extendedMessageEndOfMessageAcknowledgement().RAW_decode(ExtendedMessageEndOfMessageAcknowledgement_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_force_omit);
          if (decoded_length > 0) {
             if ((*field_extendedMessageEndOfMessageAcknowledgement).ctrl() ==  os_7) {
               return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
             }else already_failed = TRUE;
          }
        }
      }
    }
    already_failed = FALSE;
    if (!already_failed) {
      OCTETSTRING temporal_4;
      int decoded_4_length;
      p_buf.set_pos_bit(starting_pos + 0);
      decoded_4_length = temporal_4.RAW_decode(ExtendedMessageConnectionAbort_ctrl_descr_, p_buf, limit, top_bit_ord, TRUE);
      if (decoded_4_length > 0) {
        if (temporal_4 ==  os_4) {
          p_buf.set_pos_bit(starting_pos);
          RAW_Force_Omit field_force_omit(4, force_omit, ExtendedMessageConnectionAbort_descr_.raw->forceomit);
          decoded_length = extendedMessageConnectionAbort().RAW_decode(ExtendedMessageConnectionAbort_descr_, p_buf, limit, top_bit_ord, TRUE, -1, TRUE, &field_force_omit);
          if (decoded_length > 0) {
             if ((*field_extendedMessageConnectionAbort).ctrl() ==  os_4) {
               return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;
             }else already_failed = TRUE;
          }
        }
      }
    }
 }
 clean_up();
 return -1;
}

int ETP__CM::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const
{
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 5;  myleaf.body.node.nodes = init_nodes_of_enc_tree(5);
  memset(myleaf.body.node.nodes, 0, 5 * sizeof(RAW_enc_tree *));
  switch (union_selection) {
  case ALT_extendedMessageRequestToSend:
    myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 0, ExtendedMessageRequestToSend_descr_.raw);
    encoded_length = field_extendedMessageRequestToSend->RAW_encode(ExtendedMessageRequestToSend_descr_, *myleaf.body.node.nodes[0]);
    myleaf.body.node.nodes[0]->coding_descr = &ExtendedMessageRequestToSend_descr_;
    if ((*field_extendedMessageRequestToSend).ctrl() !=  os_3) {
  RAW_enc_tree* temp_leaf;
  {
  RAW_enc_tr_pos pr_pos0;
  pr_pos0.level=myleaf.curr_pos.level+2;
  int new_pos0[]={0,0};
  pr_pos0.pos=init_new_tree_pos(myleaf.curr_pos,2,new_pos0);
  temp_leaf = myleaf.get_node(pr_pos0);
  if(temp_leaf != NULL){
   os_3.RAW_encode(ExtendedMessageRequestToSend_ctrl_descr_,*temp_leaf);
  } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  }
  free_tree_pos(pr_pos0.pos);
  }
    }
    break;
  case ALT_extendedMessageClearToSend:
    myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 1, ExtendedMessageClearToSend_descr_.raw);
    encoded_length = field_extendedMessageClearToSend->RAW_encode(ExtendedMessageClearToSend_descr_, *myleaf.body.node.nodes[1]);
    myleaf.body.node.nodes[1]->coding_descr = &ExtendedMessageClearToSend_descr_;
    if ((*field_extendedMessageClearToSend).ctrl() !=  os_5) {
  RAW_enc_tree* temp_leaf;
  {
  RAW_enc_tr_pos pr_pos0;
  pr_pos0.level=myleaf.curr_pos.level+2;
  int new_pos0[]={1,0};
  pr_pos0.pos=init_new_tree_pos(myleaf.curr_pos,2,new_pos0);
  temp_leaf = myleaf.get_node(pr_pos0);
  if(temp_leaf != NULL){
   os_5.RAW_encode(ExtendedMessageClearToSend_ctrl_descr_,*temp_leaf);
  } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  }
  free_tree_pos(pr_pos0.pos);
  }
    }
    break;
  case ALT_extendedMessageDataPacketOffset:
    myleaf.body.node.nodes[2] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 2, ExtendedMessageDataPacketOffset_descr_.raw);
    encoded_length = field_extendedMessageDataPacketOffset->RAW_encode(ExtendedMessageDataPacketOffset_descr_, *myleaf.body.node.nodes[2]);
    myleaf.body.node.nodes[2]->coding_descr = &ExtendedMessageDataPacketOffset_descr_;
    if ((*field_extendedMessageDataPacketOffset).ctrl() !=  os_6) {
  RAW_enc_tree* temp_leaf;
  {
  RAW_enc_tr_pos pr_pos0;
  pr_pos0.level=myleaf.curr_pos.level+2;
  int new_pos0[]={2,0};
  pr_pos0.pos=init_new_tree_pos(myleaf.curr_pos,2,new_pos0);
  temp_leaf = myleaf.get_node(pr_pos0);
  if(temp_leaf != NULL){
   os_6.RAW_encode(ExtendedMessageDataPacketOffset_ctrl_descr_,*temp_leaf);
  } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  }
  free_tree_pos(pr_pos0.pos);
  }
    }
    break;
  case ALT_extendedMessageEndOfMessageAcknowledgement:
    myleaf.body.node.nodes[3] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 3, ExtendedMessageEndOfMessageAcknowledgement_descr_.raw);
    encoded_length = field_extendedMessageEndOfMessageAcknowledgement->RAW_encode(ExtendedMessageEndOfMessageAcknowledgement_descr_, *myleaf.body.node.nodes[3]);
    myleaf.body.node.nodes[3]->coding_descr = &ExtendedMessageEndOfMessageAcknowledgement_descr_;
    if ((*field_extendedMessageEndOfMessageAcknowledgement).ctrl() !=  os_7) {
  RAW_enc_tree* temp_leaf;
  {
  RAW_enc_tr_pos pr_pos0;
  pr_pos0.level=myleaf.curr_pos.level+2;
  int new_pos0[]={3,0};
  pr_pos0.pos=init_new_tree_pos(myleaf.curr_pos,2,new_pos0);
  temp_leaf = myleaf.get_node(pr_pos0);
  if(temp_leaf != NULL){
   os_7.RAW_encode(ExtendedMessageEndOfMessageAcknowledgement_ctrl_descr_,*temp_leaf);
  } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  }
  free_tree_pos(pr_pos0.pos);
  }
    }
    break;
  case ALT_extendedMessageConnectionAbort:
    myleaf.body.node.nodes[4] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, 4, ExtendedMessageConnectionAbort_descr_.raw);
    encoded_length = field_extendedMessageConnectionAbort->RAW_encode(ExtendedMessageConnectionAbort_descr_, *myleaf.body.node.nodes[4]);
    myleaf.body.node.nodes[4]->coding_descr = &ExtendedMessageConnectionAbort_descr_;
    if ((*field_extendedMessageConnectionAbort).ctrl() !=  os_4) {
  RAW_enc_tree* temp_leaf;
  {
  RAW_enc_tr_pos pr_pos0;
  pr_pos0.level=myleaf.curr_pos.level+2;
  int new_pos0[]={4,0};
  pr_pos0.pos=init_new_tree_pos(myleaf.curr_pos,2,new_pos0);
  temp_leaf = myleaf.get_node(pr_pos0);
  if(temp_leaf != NULL){
   os_4.RAW_encode(ExtendedMessageConnectionAbort_ctrl_descr_,*temp_leaf);
  } else {
    TTCN_EncDec_ErrorContext::error
      (TTCN_EncDec::ET_OMITTED_TAG, "Encoding a tagged, but omitted value.");
  }
  free_tree_pos(pr_pos0.pos);
  }
    }
    break;
  default:
    TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  }
  return encoded_length;
}

void ETP__CM_template::copy_value(const ETP__CM& other_value)
{
single_value.union_selection = other_value.get_selection();
switch (single_value.union_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
single_value.field_extendedMessageRequestToSend = new ExtendedMessageRequestToSend_template(other_value.extendedMessageRequestToSend());
break;
case ETP__CM::ALT_extendedMessageClearToSend:
single_value.field_extendedMessageClearToSend = new ExtendedMessageClearToSend_template(other_value.extendedMessageClearToSend());
break;
case ETP__CM::ALT_extendedMessageDataPacketOffset:
single_value.field_extendedMessageDataPacketOffset = new ExtendedMessageDataPacketOffset_template(other_value.extendedMessageDataPacketOffset());
break;
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
single_value.field_extendedMessageEndOfMessageAcknowledgement = new ExtendedMessageEndOfMessageAcknowledgement_template(other_value.extendedMessageEndOfMessageAcknowledgement());
break;
case ETP__CM::ALT_extendedMessageConnectionAbort:
single_value.field_extendedMessageConnectionAbort = new ExtendedMessageConnectionAbort_template(other_value.extendedMessageConnectionAbort());
break;
default:
TTCN_error("Initializing a template with an unbound value of type @IsobusCMMessageTypes.ETP_CM.");
}
set_selection(SPECIFIC_VALUE);
}

void ETP__CM_template::copy_template(const ETP__CM_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value.union_selection = other_value.single_value.union_selection;
switch (single_value.union_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
single_value.field_extendedMessageRequestToSend = new ExtendedMessageRequestToSend_template(*other_value.single_value.field_extendedMessageRequestToSend);
break;
case ETP__CM::ALT_extendedMessageClearToSend:
single_value.field_extendedMessageClearToSend = new ExtendedMessageClearToSend_template(*other_value.single_value.field_extendedMessageClearToSend);
break;
case ETP__CM::ALT_extendedMessageDataPacketOffset:
single_value.field_extendedMessageDataPacketOffset = new ExtendedMessageDataPacketOffset_template(*other_value.single_value.field_extendedMessageDataPacketOffset);
break;
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
single_value.field_extendedMessageEndOfMessageAcknowledgement = new ExtendedMessageEndOfMessageAcknowledgement_template(*other_value.single_value.field_extendedMessageEndOfMessageAcknowledgement);
break;
case ETP__CM::ALT_extendedMessageConnectionAbort:
single_value.field_extendedMessageConnectionAbort = new ExtendedMessageConnectionAbort_template(*other_value.single_value.field_extendedMessageConnectionAbort);
break;
default:
TTCN_error("Internal error: Invalid union selector in a specific value when copying a template of type @IsobusCMMessageTypes.ETP_CM.");
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new ETP__CM_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized template of union type @IsobusCMMessageTypes.ETP_CM.");
}
set_selection(other_value);
}

ETP__CM_template::ETP__CM_template()
{
}

ETP__CM_template::ETP__CM_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

ETP__CM_template::ETP__CM_template(const ETP__CM& other_value)
{
copy_value(other_value);
}

ETP__CM_template::ETP__CM_template(const OPTIONAL<ETP__CM>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ETP__CM&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of union type @IsobusCMMessageTypes.ETP_CM from an unbound optional field.");
}
}

ETP__CM_template::ETP__CM_template(const ETP__CM_template& other_value)
: Base_Template(){
copy_template(other_value);
}

ETP__CM_template::~ETP__CM_template()
{
clean_up();
}

void ETP__CM_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
delete single_value.field_extendedMessageRequestToSend;
break;
case ETP__CM::ALT_extendedMessageClearToSend:
delete single_value.field_extendedMessageClearToSend;
break;
case ETP__CM::ALT_extendedMessageDataPacketOffset:
delete single_value.field_extendedMessageDataPacketOffset;
break;
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
delete single_value.field_extendedMessageEndOfMessageAcknowledgement;
break;
case ETP__CM::ALT_extendedMessageConnectionAbort:
delete single_value.field_extendedMessageConnectionAbort;
default:
break;
}
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

ETP__CM_template& ETP__CM_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

ETP__CM_template& ETP__CM_template::operator=(const ETP__CM& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

ETP__CM_template& ETP__CM_template::operator=(const OPTIONAL<ETP__CM>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ETP__CM&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of union type @IsobusCMMessageTypes.ETP_CM.");
}
return *this;
}

ETP__CM_template& ETP__CM_template::operator=(const ETP__CM_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean ETP__CM_template::match(const ETP__CM& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
{
ETP__CM::union_selection_type value_selection = other_value.get_selection();
if (value_selection == ETP__CM::UNBOUND_VALUE) return FALSE;
if (value_selection != single_value.union_selection) return FALSE;
switch (value_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
return single_value.field_extendedMessageRequestToSend->match(other_value.extendedMessageRequestToSend(), legacy);
case ETP__CM::ALT_extendedMessageClearToSend:
return single_value.field_extendedMessageClearToSend->match(other_value.extendedMessageClearToSend(), legacy);
case ETP__CM::ALT_extendedMessageDataPacketOffset:
return single_value.field_extendedMessageDataPacketOffset->match(other_value.extendedMessageDataPacketOffset(), legacy);
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
return single_value.field_extendedMessageEndOfMessageAcknowledgement->match(other_value.extendedMessageEndOfMessageAcknowledgement(), legacy);
case ETP__CM::ALT_extendedMessageConnectionAbort:
return single_value.field_extendedMessageConnectionAbort->match(other_value.extendedMessageConnectionAbort(), legacy);
default:
TTCN_error("Internal error: Invalid selector in a specific value when matching a template of union type @IsobusCMMessageTypes.ETP_CM.");
}
}
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error ("Matching an uninitialized template of union type @IsobusCMMessageTypes.ETP_CM.");
}
return FALSE;
}

boolean ETP__CM_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
switch (single_value.union_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
return single_value.field_extendedMessageRequestToSend->is_value();
case ETP__CM::ALT_extendedMessageClearToSend:
return single_value.field_extendedMessageClearToSend->is_value();
case ETP__CM::ALT_extendedMessageDataPacketOffset:
return single_value.field_extendedMessageDataPacketOffset->is_value();
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
return single_value.field_extendedMessageEndOfMessageAcknowledgement->is_value();
case ETP__CM::ALT_extendedMessageConnectionAbort:
return single_value.field_extendedMessageConnectionAbort->is_value();
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing is_value operation on a template of union type @IsobusCMMessageTypes.ETP_CM.");
}
}

ETP__CM ETP__CM_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of union type @IsobusCMMessageTypes.ETP_CM.");
ETP__CM ret_val;
switch (single_value.union_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
ret_val.extendedMessageRequestToSend() = single_value.field_extendedMessageRequestToSend->valueof();
break;
case ETP__CM::ALT_extendedMessageClearToSend:
ret_val.extendedMessageClearToSend() = single_value.field_extendedMessageClearToSend->valueof();
break;
case ETP__CM::ALT_extendedMessageDataPacketOffset:
ret_val.extendedMessageDataPacketOffset() = single_value.field_extendedMessageDataPacketOffset->valueof();
break;
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
ret_val.extendedMessageEndOfMessageAcknowledgement() = single_value.field_extendedMessageEndOfMessageAcknowledgement->valueof();
break;
case ETP__CM::ALT_extendedMessageConnectionAbort:
ret_val.extendedMessageConnectionAbort() = single_value.field_extendedMessageConnectionAbort->valueof();
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing valueof operation on a template of union type @IsobusCMMessageTypes.ETP_CM.");
}
return ret_val;
}

ETP__CM_template& ETP__CM_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST) TTCN_error("Internal error: Accessing a list element of a non-list template of union type @IsobusCMMessageTypes.ETP_CM.");
if (list_index >= value_list.n_values) TTCN_error("Internal error: Index overflow in a value list template of union type @IsobusCMMessageTypes.ETP_CM.");
return value_list.list_value[list_index];
}
void ETP__CM_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) TTCN_error ("Internal error: Setting an invalid list for a template of union type @IsobusCMMessageTypes.ETP_CM.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new ETP__CM_template[list_length];
}

ExtendedMessageRequestToSend_template& ETP__CM_template::extendedMessageRequestToSend()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != ETP__CM::ALT_extendedMessageRequestToSend) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_extendedMessageRequestToSend = new ExtendedMessageRequestToSend_template(ANY_VALUE);
else single_value.field_extendedMessageRequestToSend = new ExtendedMessageRequestToSend_template;
single_value.union_selection = ETP__CM::ALT_extendedMessageRequestToSend;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_extendedMessageRequestToSend;
}

const ExtendedMessageRequestToSend_template& ETP__CM_template::extendedMessageRequestToSend() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field extendedMessageRequestToSend in a non-specific template of union type @IsobusCMMessageTypes.ETP_CM.");
if (single_value.union_selection != ETP__CM::ALT_extendedMessageRequestToSend) TTCN_error("Accessing non-selected field extendedMessageRequestToSend in a template of union type @IsobusCMMessageTypes.ETP_CM.");
return *single_value.field_extendedMessageRequestToSend;
}

ExtendedMessageClearToSend_template& ETP__CM_template::extendedMessageClearToSend()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != ETP__CM::ALT_extendedMessageClearToSend) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_extendedMessageClearToSend = new ExtendedMessageClearToSend_template(ANY_VALUE);
else single_value.field_extendedMessageClearToSend = new ExtendedMessageClearToSend_template;
single_value.union_selection = ETP__CM::ALT_extendedMessageClearToSend;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_extendedMessageClearToSend;
}

const ExtendedMessageClearToSend_template& ETP__CM_template::extendedMessageClearToSend() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field extendedMessageClearToSend in a non-specific template of union type @IsobusCMMessageTypes.ETP_CM.");
if (single_value.union_selection != ETP__CM::ALT_extendedMessageClearToSend) TTCN_error("Accessing non-selected field extendedMessageClearToSend in a template of union type @IsobusCMMessageTypes.ETP_CM.");
return *single_value.field_extendedMessageClearToSend;
}

ExtendedMessageDataPacketOffset_template& ETP__CM_template::extendedMessageDataPacketOffset()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != ETP__CM::ALT_extendedMessageDataPacketOffset) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_extendedMessageDataPacketOffset = new ExtendedMessageDataPacketOffset_template(ANY_VALUE);
else single_value.field_extendedMessageDataPacketOffset = new ExtendedMessageDataPacketOffset_template;
single_value.union_selection = ETP__CM::ALT_extendedMessageDataPacketOffset;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_extendedMessageDataPacketOffset;
}

const ExtendedMessageDataPacketOffset_template& ETP__CM_template::extendedMessageDataPacketOffset() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field extendedMessageDataPacketOffset in a non-specific template of union type @IsobusCMMessageTypes.ETP_CM.");
if (single_value.union_selection != ETP__CM::ALT_extendedMessageDataPacketOffset) TTCN_error("Accessing non-selected field extendedMessageDataPacketOffset in a template of union type @IsobusCMMessageTypes.ETP_CM.");
return *single_value.field_extendedMessageDataPacketOffset;
}

ExtendedMessageEndOfMessageAcknowledgement_template& ETP__CM_template::extendedMessageEndOfMessageAcknowledgement()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_extendedMessageEndOfMessageAcknowledgement = new ExtendedMessageEndOfMessageAcknowledgement_template(ANY_VALUE);
else single_value.field_extendedMessageEndOfMessageAcknowledgement = new ExtendedMessageEndOfMessageAcknowledgement_template;
single_value.union_selection = ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_extendedMessageEndOfMessageAcknowledgement;
}

const ExtendedMessageEndOfMessageAcknowledgement_template& ETP__CM_template::extendedMessageEndOfMessageAcknowledgement() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field extendedMessageEndOfMessageAcknowledgement in a non-specific template of union type @IsobusCMMessageTypes.ETP_CM.");
if (single_value.union_selection != ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement) TTCN_error("Accessing non-selected field extendedMessageEndOfMessageAcknowledgement in a template of union type @IsobusCMMessageTypes.ETP_CM.");
return *single_value.field_extendedMessageEndOfMessageAcknowledgement;
}

ExtendedMessageConnectionAbort_template& ETP__CM_template::extendedMessageConnectionAbort()
{
if (template_selection != SPECIFIC_VALUE || single_value.union_selection != ETP__CM::ALT_extendedMessageConnectionAbort) {
template_sel old_selection = template_selection;
clean_up();
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) single_value.field_extendedMessageConnectionAbort = new ExtendedMessageConnectionAbort_template(ANY_VALUE);
else single_value.field_extendedMessageConnectionAbort = new ExtendedMessageConnectionAbort_template;
single_value.union_selection = ETP__CM::ALT_extendedMessageConnectionAbort;
set_selection(SPECIFIC_VALUE);
}
return *single_value.field_extendedMessageConnectionAbort;
}

const ExtendedMessageConnectionAbort_template& ETP__CM_template::extendedMessageConnectionAbort() const
{
if (template_selection != SPECIFIC_VALUE) TTCN_error("Accessing field extendedMessageConnectionAbort in a non-specific template of union type @IsobusCMMessageTypes.ETP_CM.");
if (single_value.union_selection != ETP__CM::ALT_extendedMessageConnectionAbort) TTCN_error("Accessing non-selected field extendedMessageConnectionAbort in a template of union type @IsobusCMMessageTypes.ETP_CM.");
return *single_value.field_extendedMessageConnectionAbort;
}

boolean ETP__CM_template::ischosen(ETP__CM::union_selection_type checked_selection) const
{
if (checked_selection == ETP__CM::UNBOUND_VALUE) TTCN_error("Internal error: Performing ischosen() operation on an invalid field of union type @IsobusCMMessageTypes.ETP_CM.");
switch (template_selection) {
case SPECIFIC_VALUE:
if (single_value.union_selection == ETP__CM::UNBOUND_VALUE) TTCN_error("Internal error: Invalid selector in a specific value when performing ischosen() operation on a template of union type @IsobusCMMessageTypes.ETP_CM.");
return single_value.union_selection == checked_selection;
case VALUE_LIST:
{
if (value_list.n_values < 1)
TTCN_error("Internal error: Performing ischosen() operation on a template of union type @IsobusCMMessageTypes.ETP_CM containing an empty list.");
boolean ret_val = value_list.list_value[0].ischosen(checked_selection);
for (unsigned int list_count = 1; ret_val == TRUE && list_count < value_list.n_values; list_count++) {
ret_val = value_list.list_value[list_count].ischosen(checked_selection);
}
return ret_val;
}
default:
return FALSE;
}
return FALSE;
}

void ETP__CM_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
switch (single_value.union_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
TTCN_Logger::log_event_str("{ extendedMessageRequestToSend := ");
single_value.field_extendedMessageRequestToSend->log();
TTCN_Logger::log_event_str(" }");
break;
case ETP__CM::ALT_extendedMessageClearToSend:
TTCN_Logger::log_event_str("{ extendedMessageClearToSend := ");
single_value.field_extendedMessageClearToSend->log();
TTCN_Logger::log_event_str(" }");
break;
case ETP__CM::ALT_extendedMessageDataPacketOffset:
TTCN_Logger::log_event_str("{ extendedMessageDataPacketOffset := ");
single_value.field_extendedMessageDataPacketOffset->log();
TTCN_Logger::log_event_str(" }");
break;
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
TTCN_Logger::log_event_str("{ extendedMessageEndOfMessageAcknowledgement := ");
single_value.field_extendedMessageEndOfMessageAcknowledgement->log();
TTCN_Logger::log_event_str(" }");
break;
case ETP__CM::ALT_extendedMessageConnectionAbort:
TTCN_Logger::log_event_str("{ extendedMessageConnectionAbort := ");
single_value.field_extendedMessageConnectionAbort->log();
TTCN_Logger::log_event_str(" }");
break;
default:
TTCN_Logger::log_event_str("<invalid selector>");
}
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void ETP__CM_template::log_match(const ETP__CM& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity() && match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
return;
}
if (template_selection == SPECIFIC_VALUE && single_value.union_selection == match_value.get_selection()) {
switch (single_value.union_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".extendedMessageRequestToSend");
single_value.field_extendedMessageRequestToSend->log_match(match_value.extendedMessageRequestToSend(), legacy);
} else {
TTCN_Logger::log_event_str("{ extendedMessageRequestToSend := ");
single_value.field_extendedMessageRequestToSend->log_match(match_value.extendedMessageRequestToSend(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case ETP__CM::ALT_extendedMessageClearToSend:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".extendedMessageClearToSend");
single_value.field_extendedMessageClearToSend->log_match(match_value.extendedMessageClearToSend(), legacy);
} else {
TTCN_Logger::log_event_str("{ extendedMessageClearToSend := ");
single_value.field_extendedMessageClearToSend->log_match(match_value.extendedMessageClearToSend(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case ETP__CM::ALT_extendedMessageDataPacketOffset:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".extendedMessageDataPacketOffset");
single_value.field_extendedMessageDataPacketOffset->log_match(match_value.extendedMessageDataPacketOffset(), legacy);
} else {
TTCN_Logger::log_event_str("{ extendedMessageDataPacketOffset := ");
single_value.field_extendedMessageDataPacketOffset->log_match(match_value.extendedMessageDataPacketOffset(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".extendedMessageEndOfMessageAcknowledgement");
single_value.field_extendedMessageEndOfMessageAcknowledgement->log_match(match_value.extendedMessageEndOfMessageAcknowledgement(), legacy);
} else {
TTCN_Logger::log_event_str("{ extendedMessageEndOfMessageAcknowledgement := ");
single_value.field_extendedMessageEndOfMessageAcknowledgement->log_match(match_value.extendedMessageEndOfMessageAcknowledgement(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
case ETP__CM::ALT_extendedMessageConnectionAbort:
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
TTCN_Logger::log_logmatch_info(".extendedMessageConnectionAbort");
single_value.field_extendedMessageConnectionAbort->log_match(match_value.extendedMessageConnectionAbort(), legacy);
} else {
TTCN_Logger::log_event_str("{ extendedMessageConnectionAbort := ");
single_value.field_extendedMessageConnectionAbort->log_match(match_value.extendedMessageConnectionAbort(), legacy);
TTCN_Logger::log_event_str(" }");
}
break;
default:
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str("<invalid selector>");
}
} else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void ETP__CM_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
text_buf.push_int(single_value.union_selection);
switch (single_value.union_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
single_value.field_extendedMessageRequestToSend->encode_text(text_buf);
break;
case ETP__CM::ALT_extendedMessageClearToSend:
single_value.field_extendedMessageClearToSend->encode_text(text_buf);
break;
case ETP__CM::ALT_extendedMessageDataPacketOffset:
single_value.field_extendedMessageDataPacketOffset->encode_text(text_buf);
break;
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
single_value.field_extendedMessageEndOfMessageAcknowledgement->encode_text(text_buf);
break;
case ETP__CM::ALT_extendedMessageConnectionAbort:
single_value.field_extendedMessageConnectionAbort->encode_text(text_buf);
break;
default:
TTCN_error("Internal error: Invalid selector in a specific value when encoding a template of union type @IsobusCMMessageTypes.ETP_CM.");
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized template of type @IsobusCMMessageTypes.ETP_CM.");
}
}

void ETP__CM_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
{
single_value.union_selection = ETP__CM::UNBOUND_VALUE;
ETP__CM::union_selection_type new_selection = (ETP__CM::union_selection_type)text_buf.pull_int().get_val();
switch (new_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
single_value.field_extendedMessageRequestToSend = new ExtendedMessageRequestToSend_template;
single_value.field_extendedMessageRequestToSend->decode_text(text_buf);
break;
case ETP__CM::ALT_extendedMessageClearToSend:
single_value.field_extendedMessageClearToSend = new ExtendedMessageClearToSend_template;
single_value.field_extendedMessageClearToSend->decode_text(text_buf);
break;
case ETP__CM::ALT_extendedMessageDataPacketOffset:
single_value.field_extendedMessageDataPacketOffset = new ExtendedMessageDataPacketOffset_template;
single_value.field_extendedMessageDataPacketOffset->decode_text(text_buf);
break;
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
single_value.field_extendedMessageEndOfMessageAcknowledgement = new ExtendedMessageEndOfMessageAcknowledgement_template;
single_value.field_extendedMessageEndOfMessageAcknowledgement->decode_text(text_buf);
break;
case ETP__CM::ALT_extendedMessageConnectionAbort:
single_value.field_extendedMessageConnectionAbort = new ExtendedMessageConnectionAbort_template;
single_value.field_extendedMessageConnectionAbort->decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized union selector was received for a template of type @IsobusCMMessageTypes.ETP_CM.");
}
single_value.union_selection = new_selection;
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new ETP__CM_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: Unrecognized selector was received in a template of type @IsobusCMMessageTypes.ETP_CM.");
}
}

boolean ETP__CM_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean ETP__CM_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int v_idx=0; v_idx<value_list.n_values; v_idx++)
if (value_list.list_value[v_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

void ETP__CM_template::set_param(Module_Param& param)
{
  if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&
      param.get_id()->next_name()) {
    char* param_field = param.get_id()->get_current_name();
    if (param_field[0] >= '0' && param_field[0] <= '9') {
      param.error("Unexpected array index in module parameter, expected a valid field"
        " name for union template type `@IsobusCMMessageTypes.ETP_CM'");
    }
    if (strcmp("extendedMessageRequestToSend", param_field) == 0) {
      extendedMessageRequestToSend().set_param(param);
      return;
    } else if (strcmp("extendedMessageClearToSend", param_field) == 0) {
      extendedMessageClearToSend().set_param(param);
      return;
    } else if (strcmp("extendedMessageDataPacketOffset", param_field) == 0) {
      extendedMessageDataPacketOffset().set_param(param);
      return;
    } else if (strcmp("extendedMessageEndOfMessageAcknowledgement", param_field) == 0) {
      extendedMessageEndOfMessageAcknowledgement().set_param(param);
      return;
    } else if (strcmp("extendedMessageConnectionAbort", param_field) == 0) {
      extendedMessageConnectionAbort().set_param(param);
      return;
    } else param.error("Field `%s' not found in union template type `@IsobusCMMessageTypes.ETP_CM'", param_field);
  }
  param.basic_check(Module_Param::BC_TEMPLATE, "union template");
  Module_Param_Ptr m_p = &param;
  switch (m_p->get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    ETP__CM_template new_temp;
    new_temp.set_type(m_p->get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, m_p->get_size());
    for (size_t p_i=0; p_i<m_p->get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*m_p->get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (m_p->get_size()==0) break;
    param.type_error("union template", "@IsobusCMMessageTypes.ETP_CM");
    break;
  case Module_Param::MP_Assignment_List: {
    Module_Param* mp_last = m_p->get_elem(m_p->get_size()-1);
    char* last_name = mp_last->get_id()->get_name();
    if (!strcmp(last_name, "extendedMessageRequestToSend")) {
      extendedMessageRequestToSend().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "extendedMessageClearToSend")) {
      extendedMessageClearToSend().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "extendedMessageDataPacketOffset")) {
      extendedMessageDataPacketOffset().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "extendedMessageEndOfMessageAcknowledgement")) {
      extendedMessageEndOfMessageAcknowledgement().set_param(*mp_last);
      break;
    }
    if (!strcmp(last_name, "extendedMessageConnectionAbort")) {
      extendedMessageConnectionAbort().set_param(*mp_last);
      break;
    }
    mp_last->error("Field %s does not exist in type @IsobusCMMessageTypes.ETP_CM.", last_name);
  } break;
  default:
    param.type_error("union template", "@IsobusCMMessageTypes.ETP_CM");
  }
  is_ifpresent = param.get_ifpresent();
}

void ETP__CM_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
switch (single_value.union_selection) {
case ETP__CM::ALT_extendedMessageRequestToSend:
single_value.field_extendedMessageRequestToSend->check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ETP_CM");
return;
case ETP__CM::ALT_extendedMessageClearToSend:
single_value.field_extendedMessageClearToSend->check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ETP_CM");
return;
case ETP__CM::ALT_extendedMessageDataPacketOffset:
single_value.field_extendedMessageDataPacketOffset->check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ETP_CM");
return;
case ETP__CM::ALT_extendedMessageEndOfMessageAcknowledgement:
single_value.field_extendedMessageEndOfMessageAcknowledgement->check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ETP_CM");
return;
case ETP__CM::ALT_extendedMessageConnectionAbort:
single_value.field_extendedMessageConnectionAbort->check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ETP_CM");
return;
default:
TTCN_error("Internal error: Invalid selector in a specific value when performing check_restriction operation on a template of union type @IsobusCMMessageTypes.ETP_CM.");
}
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.ETP_CM");
}

TP__DT::TP__DT()
{
}

TP__DT::TP__DT(const INTEGER& par_seq__no,
    const OCTETSTRING& par_data)
  :   field_seq__no(par_seq__no),
  field_data(par_data)
{
}

TP__DT::TP__DT(const TP__DT& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.TP_DT.");
if (other_value.seq__no().is_bound()) field_seq__no = other_value.seq__no();
else field_seq__no.clean_up();
if (other_value.data().is_bound()) field_data = other_value.data();
else field_data.clean_up();
}

void TP__DT::clean_up()
{
field_seq__no.clean_up();
field_data.clean_up();
}

const TTCN_Typedescriptor_t* TP__DT::get_descriptor() const { return &TP__DT_descr_; }
TP__DT& TP__DT::operator=(const TP__DT& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.TP_DT.");
  if (other_value.seq__no().is_bound()) field_seq__no = other_value.seq__no();
  else field_seq__no.clean_up();
  if (other_value.data().is_bound()) field_data = other_value.data();
  else field_data.clean_up();
}
return *this;
}

boolean TP__DT::operator==(const TP__DT& other_value) const
{
return field_seq__no==other_value.field_seq__no
  && field_data==other_value.field_data;
}

boolean TP__DT::is_bound() const
{
return (field_seq__no.is_bound())
  || (field_data.is_bound());
}
boolean TP__DT::is_value() const
{
return field_seq__no.is_value()
  && field_data.is_value();
}
void TP__DT::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ seq_no := ");
field_seq__no.log();
TTCN_Logger::log_event_str(", data := ");
field_data.log();
TTCN_Logger::log_event_str(" }");
}

void TP__DT::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (2<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.TP_DT has 2 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) seq__no().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) data().set_param(*param.get_elem(1));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "seq_no")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          seq__no().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "data")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          data().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.TP_DT: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.TP_DT");
  }
}

void TP__DT::set_implicit_omit()
{
if (seq__no().is_bound()) seq__no().set_implicit_omit();
if (data().is_bound()) data().set_implicit_omit();
}

void TP__DT::encode_text(Text_Buf& text_buf) const
{
field_seq__no.encode_text(text_buf);
field_data.encode_text(text_buf);
}

void TP__DT::decode_text(Text_Buf& text_buf)
{
field_seq__no.decode_text(text_buf);
field_data.decode_text(text_buf);
}

void TP__DT::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void TP__DT::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int TP__DT::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, SEQ__NO_descr_.raw->forceomit);
  decoded_field_length = field_seq__no.RAW_decode(SEQ__NO_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, General__Types::OCT7_descr_.raw->forceomit);
  decoded_field_length = field_data.RAW_decode(General__Types::OCT7_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int TP__DT::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 2;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(2);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, SEQ__NO_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, General__Types::OCT7_descr_.raw);
  encoded_length += field_seq__no.RAW_encode(SEQ__NO_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_data.RAW_encode(General__Types::OCT7_descr_, *myleaf.body.node.nodes[1]);
  return myleaf.length = encoded_length;
}

struct TP__DT_template::single_value_struct {
INTEGER_template field_seq__no;
OCTETSTRING_template field_data;
};

void TP__DT_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_seq__no = ANY_VALUE;
single_value->field_data = ANY_VALUE;
}
}
}

void TP__DT_template::copy_value(const TP__DT& other_value)
{
single_value = new single_value_struct;
if (other_value.seq__no().is_bound()) {
  single_value->field_seq__no = other_value.seq__no();
} else {
  single_value->field_seq__no.clean_up();
}
if (other_value.data().is_bound()) {
  single_value->field_data = other_value.data();
} else {
  single_value->field_data.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void TP__DT_template::copy_template(const TP__DT_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.seq__no().get_selection()) {
single_value->field_seq__no = other_value.seq__no();
} else {
single_value->field_seq__no.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.data().get_selection()) {
single_value->field_data = other_value.data();
} else {
single_value->field_data.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new TP__DT_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.TP_DT.");
break;
}
set_selection(other_value);
}

TP__DT_template::TP__DT_template()
{
}

TP__DT_template::TP__DT_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

TP__DT_template::TP__DT_template(const TP__DT& other_value)
{
copy_value(other_value);
}

TP__DT_template::TP__DT_template(const OPTIONAL<TP__DT>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const TP__DT&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.TP_DT from an unbound optional field.");
}
}

TP__DT_template::TP__DT_template(const TP__DT_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

TP__DT_template::~TP__DT_template()
{
clean_up();
}

TP__DT_template& TP__DT_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

TP__DT_template& TP__DT_template::operator=(const TP__DT& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

TP__DT_template& TP__DT_template::operator=(const OPTIONAL<TP__DT>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const TP__DT&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.TP_DT.");
}
return *this;
}

TP__DT_template& TP__DT_template::operator=(const TP__DT_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean TP__DT_template::match(const TP__DT& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.seq__no().is_bound()) return FALSE;
if(!single_value->field_seq__no.match(other_value.seq__no(), legacy))return FALSE;
if(!other_value.data().is_bound()) return FALSE;
if(!single_value->field_data.match(other_value.data(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.TP_DT.");
}
return FALSE;
}

boolean TP__DT_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_seq__no.is_bound()

 ||single_value->field_data.is_bound()
;
}

boolean TP__DT_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_seq__no.is_value()
 &&single_value->field_data.is_value();
}

void TP__DT_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

TP__DT TP__DT_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.TP_DT.");
TP__DT ret_val;
if (single_value->field_seq__no.is_bound()) {
ret_val.seq__no() = single_value->field_seq__no.valueof();
}
if (single_value->field_data.is_bound()) {
ret_val.data() = single_value->field_data.valueof();
}
return ret_val;
}

void TP__DT_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.TP_DT.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new TP__DT_template[list_length];
}

TP__DT_template& TP__DT_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.TP_DT.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.TP_DT.");
return value_list.list_value[list_index];
}

INTEGER_template& TP__DT_template::seq__no()
{
set_specific();
return single_value->field_seq__no;
}

const INTEGER_template& TP__DT_template::seq__no() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field seq_no of a non-specific template of type @IsobusCMMessageTypes.TP_DT.");
return single_value->field_seq__no;
}

OCTETSTRING_template& TP__DT_template::data()
{
set_specific();
return single_value->field_data;
}

const OCTETSTRING_template& TP__DT_template::data() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field data of a non-specific template of type @IsobusCMMessageTypes.TP_DT.");
return single_value->field_data;
}

int TP__DT_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.TP_DT which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 2;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.TP_DT containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.TP_DT containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.TP_DT containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.TP_DT containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.TP_DT containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.TP_DT.");
  }
  return 0;
}

void TP__DT_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ seq_no := ");
single_value->field_seq__no.log();
TTCN_Logger::log_event_str(", data := ");
single_value->field_data.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void TP__DT_template::log_match(const TP__DT& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_seq__no.match(match_value.seq__no(), legacy)){
TTCN_Logger::log_logmatch_info(".seq_no");
single_value->field_seq__no.log_match(match_value.seq__no(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_data.match(match_value.data(), legacy)){
TTCN_Logger::log_logmatch_info(".data");
single_value->field_data.log_match(match_value.data(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ seq_no := ");
single_value->field_seq__no.log_match(match_value.seq__no(), legacy);
TTCN_Logger::log_event_str(", data := ");
single_value->field_data.log_match(match_value.data(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void TP__DT_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_seq__no.encode_text(text_buf);
single_value->field_data.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.TP_DT.");
}
}

void TP__DT_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_seq__no.decode_text(text_buf);
single_value->field_data.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new TP__DT_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.TP_DT.");
}
}

void TP__DT_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    TP__DT_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (2<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.TP_DT has 2 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) seq__no().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) data().set_param(*param.get_elem(1));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "seq_no")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          seq__no().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "data")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          data().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.TP_DT: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.TP_DT");
  }
  is_ifpresent = param.get_ifpresent();
}

void TP__DT_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_seq__no.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.TP_DT");
single_value->field_data.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.TP_DT");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.TP_DT");
}

boolean TP__DT_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean TP__DT_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}

ETP__DT::ETP__DT()
{
}

ETP__DT::ETP__DT(const INTEGER& par_seq__no,
    const OCTETSTRING& par_data)
  :   field_seq__no(par_seq__no),
  field_data(par_data)
{
}

ETP__DT::ETP__DT(const ETP__DT& other_value)
{
if(!other_value.is_bound()) TTCN_error("Copying an unbound value of type @IsobusCMMessageTypes.ETP_DT.");
if (other_value.seq__no().is_bound()) field_seq__no = other_value.seq__no();
else field_seq__no.clean_up();
if (other_value.data().is_bound()) field_data = other_value.data();
else field_data.clean_up();
}

void ETP__DT::clean_up()
{
field_seq__no.clean_up();
field_data.clean_up();
}

const TTCN_Typedescriptor_t* ETP__DT::get_descriptor() const { return &ETP__DT_descr_; }
ETP__DT& ETP__DT::operator=(const ETP__DT& other_value)
{
if (this != &other_value) {
  if(!other_value.is_bound()) TTCN_error("Assignment of an unbound value of type @IsobusCMMessageTypes.ETP_DT.");
  if (other_value.seq__no().is_bound()) field_seq__no = other_value.seq__no();
  else field_seq__no.clean_up();
  if (other_value.data().is_bound()) field_data = other_value.data();
  else field_data.clean_up();
}
return *this;
}

boolean ETP__DT::operator==(const ETP__DT& other_value) const
{
return field_seq__no==other_value.field_seq__no
  && field_data==other_value.field_data;
}

boolean ETP__DT::is_bound() const
{
return (field_seq__no.is_bound())
  || (field_data.is_bound());
}
boolean ETP__DT::is_value() const
{
return field_seq__no.is_value()
  && field_data.is_value();
}
void ETP__DT::log() const
{
if (!is_bound()) {
TTCN_Logger::log_event_unbound();
return;
}
TTCN_Logger::log_event_str("{ seq_no := ");
field_seq__no.log();
TTCN_Logger::log_event_str(", data := ");
field_data.log();
TTCN_Logger::log_event_str(" }");
}

void ETP__DT::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_VALUE, "record value");
  switch (param.get_type()) {
  case Module_Param::MP_Value_List:
    if (2<param.get_size()) {
      param.error("record value of type @IsobusCMMessageTypes.ETP_DT has 2 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) seq__no().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) data().set_param(*param.get_elem(1));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "seq_no")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          seq__no().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "data")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          data().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ETP_DT: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record value", "@IsobusCMMessageTypes.ETP_DT");
  }
}

void ETP__DT::set_implicit_omit()
{
if (seq__no().is_bound()) seq__no().set_implicit_omit();
if (data().is_bound()) data().set_implicit_omit();
}

void ETP__DT::encode_text(Text_Buf& text_buf) const
{
field_seq__no.encode_text(text_buf);
field_data.encode_text(text_buf);
}

void ETP__DT::decode_text(Text_Buf& text_buf)
{
field_seq__no.decode_text(text_buf);
field_data.decode_text(text_buf);
}

void ETP__DT::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
    unsigned BER_coding=va_arg(pvar, unsigned);
    BER_encode_chk_coding(BER_coding);
    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
    tlv->put_in_buffer(p_buf);
    ASN_BER_TLV_t::destruct(tlv);
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    RAW_enc_tr_pos rp;
    rp.level=0;
    rp.pos=NULL;
    RAW_enc_tree root(FALSE, NULL, &rp, 1, p_td.raw);
    RAW_encode(p_td, root);
    root.put_to_buf(p_buf);
    break;}
  case TTCN_EncDec::CT_TEXT: {
    TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
      ("No TEXT descriptor available for type '%s'.", p_td.name);
    TEXT_encode(p_td,p_buf);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);
    p_buf.put_c('\n');
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok(va_arg(pvar, int) != 0);
    JSON_encode(p_td, tok);
    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-encoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
    OER_encode(p_td, p_buf);
    break;}
  default:
    TTCN_error("Unknown coding method requested to encode type '%s'", p_td.name);
  }
  va_end(pvar);
}

void ETP__DT::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)
{
  va_list pvar;
  va_start(pvar, p_coding);
  switch(p_coding) {
  case TTCN_EncDec::CT_BER: {
    TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
    unsigned L_form=va_arg(pvar, unsigned);
    ASN_BER_TLV_t tlv;
    BER_decode_str2TLV(p_buf, tlv, L_form);
    BER_decode_TLV(p_td, tlv, L_form);
    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
    break;}
  case TTCN_EncDec::CT_RAW: {
    TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
    if(!p_td.raw)
      TTCN_EncDec_ErrorContext::error_internal
        ("No RAW descriptor available for type '%s'.", p_td.name);
    raw_order_t r_order;
    switch(p_td.raw->top_bit_order) {
    case TOP_BIT_LEFT:
      r_order=ORDER_LSB;
      break;
    case TOP_BIT_RIGHT:
    default:
      r_order=ORDER_MSB;
    }
    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);
    if(rawr<0) switch (-rawr) {
    case TTCN_EncDec::ET_INCOMPL_MSG:
    case TTCN_EncDec::ET_LEN_ERR:
      ec.error((TTCN_EncDec::error_type_t)-rawr, "Can not decode type '%s', because incomplete message was received", p_td.name);
      break;
    case 1:
    default:
      ec.error(TTCN_EncDec::ET_INVAL_MSG, "Can not decode type '%s', because invalid message was received", p_td.name);
      break;
    }
    break;}
  case TTCN_EncDec::CT_TEXT: {
    Limit_Token_List limit;
    TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
    if(!p_td.text)
      TTCN_EncDec_ErrorContext::error_internal
        ("No TEXT descriptor available for type '%s'.", p_td.name);
    const unsigned char *b_data=p_buf.get_data();
    if(b_data[p_buf.get_len()-1]!='\0'){
      p_buf.set_pos(p_buf.get_len());
      p_buf.put_zero(8,ORDER_LSB);
      p_buf.rewind();
    }
    if(TEXT_decode(p_td,p_buf,limit)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    break;}
  case TTCN_EncDec::CT_XER: {
    TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
    unsigned XER_coding=va_arg(pvar, unsigned);
    XER_encode_chk_coding(XER_coding, p_td);
    XmlReaderWrap reader(p_buf);
    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {
      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;
    }
    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);
    size_t bytes = reader.ByteConsumed();
    p_buf.set_pos(bytes);
    break;}
  case TTCN_EncDec::CT_JSON: {
    TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
    if(!p_td.json)
      TTCN_EncDec_ErrorContext::error_internal
        ("No JSON descriptor available for type '%s'.", p_td.name);
    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
    if(JSON_decode(p_td, tok, FALSE)<0)
      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"Can not decode type '%s', because invalid or incomplete message was received", p_td.name);
    p_buf.set_pos(tok.get_buf_pos());
    break;}
  case TTCN_EncDec::CT_OER: {
    TTCN_EncDec_ErrorContext ec("While OER-decoding type '%s': ", p_td.name);
    if(!p_td.oer)
      TTCN_EncDec_ErrorContext::error_internal
        ("No OER descriptor available for type '%s'.", p_td.name);
     OER_struct p_oer;
    OER_decode(p_td, p_buf, p_oer);
    break;}
  default:
    TTCN_error("Unknown coding method requested to decode type '%s'", p_td.name);
  }
  va_end(pvar);
}

int ETP__DT::RAW_decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, int, boolean, const RAW_Force_Omit* force_omit)
{ (void)no_err;
  int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);
  limit-=prepaddlength;
  size_t last_decoded_pos = p_buf.get_pos_bit();
  int decoded_length = 0;
  int decoded_field_length = 0;
  raw_order_t local_top_order;
  if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)local_top_order=top_bit_ord;
  else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order=ORDER_MSB;
  else local_top_order=ORDER_LSB;
  RAW_Force_Omit field_0_force_omit(0, force_omit, SEQ__NO_descr_.raw->forceomit);
  decoded_field_length = field_seq__no.RAW_decode(SEQ__NO_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_0_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  RAW_Force_Omit field_1_force_omit(1, force_omit, General__Types::OCT7_descr_.raw->forceomit);
  decoded_field_length = field_data.RAW_decode(General__Types::OCT7_descr_, p_buf, limit, local_top_order, no_err, -1, TRUE, &field_1_force_omit);
  if (decoded_field_length < 0) return decoded_field_length;
  decoded_length+=decoded_field_length;
  limit-=decoded_field_length;
  last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());
  p_buf.set_pos_bit(last_decoded_pos);
  return decoded_length+prepaddlength+p_buf.increase_pos_padd(p_td.raw->padding);
}

int ETP__DT::RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree& myleaf) const {
  if (!is_bound()) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "Encoding an unbound value.");
  int encoded_length = 0;
  myleaf.isleaf = FALSE;
  myleaf.body.node.num_of_nodes = 2;
  myleaf.body.node.nodes = init_nodes_of_enc_tree(2);
  myleaf.body.node.nodes[0] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 0, SEQ__NO_descr_.raw);
  myleaf.body.node.nodes[1] = new RAW_enc_tree(TRUE, &myleaf, &(myleaf.curr_pos), 1, General__Types::OCT7_descr_.raw);
  encoded_length += field_seq__no.RAW_encode(SEQ__NO_descr_, *myleaf.body.node.nodes[0]);
  encoded_length += field_data.RAW_encode(General__Types::OCT7_descr_, *myleaf.body.node.nodes[1]);
  return myleaf.length = encoded_length;
}

struct ETP__DT_template::single_value_struct {
INTEGER_template field_seq__no;
OCTETSTRING_template field_data;
};

void ETP__DT_template::set_specific()
{
if (template_selection != SPECIFIC_VALUE) {
template_sel old_selection = template_selection;
clean_up();
single_value = new single_value_struct;
set_selection(SPECIFIC_VALUE);
if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {
single_value->field_seq__no = ANY_VALUE;
single_value->field_data = ANY_VALUE;
}
}
}

void ETP__DT_template::copy_value(const ETP__DT& other_value)
{
single_value = new single_value_struct;
if (other_value.seq__no().is_bound()) {
  single_value->field_seq__no = other_value.seq__no();
} else {
  single_value->field_seq__no.clean_up();
}
if (other_value.data().is_bound()) {
  single_value->field_data = other_value.data();
} else {
  single_value->field_data.clean_up();
}
set_selection(SPECIFIC_VALUE);
}

void ETP__DT_template::copy_template(const ETP__DT_template& other_value)
{
switch (other_value.template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
if (UNINITIALIZED_TEMPLATE != other_value.seq__no().get_selection()) {
single_value->field_seq__no = other_value.seq__no();
} else {
single_value->field_seq__no.clean_up();
}
if (UNINITIALIZED_TEMPLATE != other_value.data().get_selection()) {
single_value->field_data = other_value.data();
} else {
single_value->field_data.clean_up();
}
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = other_value.value_list.n_values;
value_list.list_value = new ETP__DT_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].copy_template(other_value.value_list.list_value[list_count]);
break;
default:
TTCN_error("Copying an uninitialized/unsupported template of type @IsobusCMMessageTypes.ETP_DT.");
break;
}
set_selection(other_value);
}

ETP__DT_template::ETP__DT_template()
{
}

ETP__DT_template::ETP__DT_template(template_sel other_value)
 : Base_Template(other_value)
{
check_single_selection(other_value);
}

ETP__DT_template::ETP__DT_template(const ETP__DT& other_value)
{
copy_value(other_value);
}

ETP__DT_template::ETP__DT_template(const OPTIONAL<ETP__DT>& other_value)
{
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ETP__DT&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Creating a template of type @IsobusCMMessageTypes.ETP_DT from an unbound optional field.");
}
}

ETP__DT_template::ETP__DT_template(const ETP__DT_template& other_value)
: Base_Template()
{
copy_template(other_value);
}

ETP__DT_template::~ETP__DT_template()
{
clean_up();
}

ETP__DT_template& ETP__DT_template::operator=(template_sel other_value)
{
check_single_selection(other_value);
clean_up();
set_selection(other_value);
return *this;
}

ETP__DT_template& ETP__DT_template::operator=(const ETP__DT& other_value)
{
clean_up();
copy_value(other_value);
return *this;
}

ETP__DT_template& ETP__DT_template::operator=(const OPTIONAL<ETP__DT>& other_value)
{
clean_up();
switch (other_value.get_selection()) {
case OPTIONAL_PRESENT:
copy_value((const ETP__DT&)other_value);
break;
case OPTIONAL_OMIT:
set_selection(OMIT_VALUE);
break;
default:
TTCN_error("Assignment of an unbound optional field to a template of type @IsobusCMMessageTypes.ETP_DT.");
}
return *this;
}

ETP__DT_template& ETP__DT_template::operator=(const ETP__DT_template& other_value)
{
if (&other_value != this) {
clean_up();
copy_template(other_value);
}
return *this;
}

boolean ETP__DT_template::match(const ETP__DT& other_value, boolean legacy) const
{
if (!other_value.is_bound()) return FALSE;
switch (template_selection) {
case ANY_VALUE:
case ANY_OR_OMIT:
return TRUE;
case OMIT_VALUE:
return FALSE;
case SPECIFIC_VALUE:
if(!other_value.seq__no().is_bound()) return FALSE;
if(!single_value->field_seq__no.match(other_value.seq__no(), legacy))return FALSE;
if(!other_value.data().is_bound()) return FALSE;
if(!single_value->field_data.match(other_value.data(), legacy))return FALSE;
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
if (value_list.list_value[list_count].match(other_value, legacy)) return template_selection == VALUE_LIST;
return template_selection == COMPLEMENTED_LIST;
default:
TTCN_error("Matching an uninitialized/unsupported template of type @IsobusCMMessageTypes.ETP_DT.");
}
return FALSE;
}

boolean ETP__DT_template::is_bound() const
{
if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) return FALSE;
if (template_selection != SPECIFIC_VALUE) return TRUE;
return single_value->field_seq__no.is_bound()

 ||single_value->field_data.is_bound()
;
}

boolean ETP__DT_template::is_value() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent) return FALSE;
return single_value->field_seq__no.is_value()
 &&single_value->field_data.is_value();
}

void ETP__DT_template::clean_up()
{
switch (template_selection) {
case SPECIFIC_VALUE:
delete single_value;
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
delete [] value_list.list_value;
default:
break;
}
template_selection = UNINITIALIZED_TEMPLATE;
}

ETP__DT ETP__DT_template::valueof() const
{
if (template_selection != SPECIFIC_VALUE || is_ifpresent)
TTCN_error("Performing a valueof or send operation on a non-specific template of type @IsobusCMMessageTypes.ETP_DT.");
ETP__DT ret_val;
if (single_value->field_seq__no.is_bound()) {
ret_val.seq__no() = single_value->field_seq__no.valueof();
}
if (single_value->field_data.is_bound()) {
ret_val.data() = single_value->field_data.valueof();
}
return ret_val;
}

void ETP__DT_template::set_type(template_sel template_type, unsigned int list_length)
{
if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
TTCN_error("Setting an invalid list for a template of type @IsobusCMMessageTypes.ETP_DT.");
clean_up();
set_selection(template_type);
value_list.n_values = list_length;
value_list.list_value = new ETP__DT_template[list_length];
}

ETP__DT_template& ETP__DT_template::list_item(unsigned int list_index) const
{
if (template_selection != VALUE_LIST && template_selection != COMPLEMENTED_LIST)
TTCN_error("Accessing a list element of a non-list template of type @IsobusCMMessageTypes.ETP_DT.");
if (list_index >= value_list.n_values)
TTCN_error("Index overflow in a value list template of type @IsobusCMMessageTypes.ETP_DT.");
return value_list.list_value[list_index];
}

INTEGER_template& ETP__DT_template::seq__no()
{
set_specific();
return single_value->field_seq__no;
}

const INTEGER_template& ETP__DT_template::seq__no() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field seq_no of a non-specific template of type @IsobusCMMessageTypes.ETP_DT.");
return single_value->field_seq__no;
}

OCTETSTRING_template& ETP__DT_template::data()
{
set_specific();
return single_value->field_data;
}

const OCTETSTRING_template& ETP__DT_template::data() const
{
if (template_selection != SPECIFIC_VALUE)
TTCN_error("Accessing field data of a non-specific template of type @IsobusCMMessageTypes.ETP_DT.");
return single_value->field_data;
}

int ETP__DT_template::size_of() const
{
  if (is_ifpresent) TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ETP_DT which has an ifpresent attribute.");
  switch (template_selection)
  {
  case SPECIFIC_VALUE:
    return 2;
  case VALUE_LIST:
   {
     if (value_list.n_values<1)
       TTCN_error("Internal error: Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ETP_DT containing an empty list.");
      int item_size = value_list.list_value[0].size_of();
      for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)
      {
        if (value_list.list_value[l_idx].size_of()!=item_size)
          TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ETP_DT containing a value list with different sizes.");
      }
      return item_size;
    }
  case OMIT_VALUE:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ETP_DT containing omit value.");
  case ANY_VALUE:
  case ANY_OR_OMIT:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ETP_DT containing */? value.");
  case COMPLEMENTED_LIST:
    TTCN_error("Performing sizeof() operation on a template of type @IsobusCMMessageTypes.ETP_DT containing complemented list.");
  default:
    TTCN_error("Performing sizeof() operation on an uninitialized/unsupported template of type @IsobusCMMessageTypes.ETP_DT.");
  }
  return 0;
}

void ETP__DT_template::log() const
{
switch (template_selection) {
case SPECIFIC_VALUE:
TTCN_Logger::log_event_str("{ seq_no := ");
single_value->field_seq__no.log();
TTCN_Logger::log_event_str(", data := ");
single_value->field_data.log();
TTCN_Logger::log_event_str(" }");
break;
case COMPLEMENTED_LIST:
TTCN_Logger::log_event_str("complement");
case VALUE_LIST:
TTCN_Logger::log_char('(');
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++) {
if (list_count > 0) TTCN_Logger::log_event_str(", ");
value_list.list_value[list_count].log();
}
TTCN_Logger::log_char(')');
break;
default:
log_generic();
}
log_ifpresent();
}

void ETP__DT_template::log_match(const ETP__DT& match_value, boolean legacy) const
{
if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
if(match(match_value, legacy)){
TTCN_Logger::print_logmatch_buffer();
TTCN_Logger::log_event_str(" matched");
} else{
if (template_selection == SPECIFIC_VALUE) {
size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();
if(!single_value->field_seq__no.match(match_value.seq__no(), legacy)){
TTCN_Logger::log_logmatch_info(".seq_no");
single_value->field_seq__no.log_match(match_value.seq__no(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
if(!single_value->field_data.match(match_value.data(), legacy)){
TTCN_Logger::log_logmatch_info(".data");
single_value->field_data.log_match(match_value.data(), legacy);
TTCN_Logger::set_logmatch_buffer_len(previous_size);
}
}else {
TTCN_Logger::print_logmatch_buffer();
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
TTCN_Logger::log_event_str(" unmatched");
}
}
return;
}
if (template_selection == SPECIFIC_VALUE) {
TTCN_Logger::log_event_str("{ seq_no := ");
single_value->field_seq__no.log_match(match_value.seq__no(), legacy);
TTCN_Logger::log_event_str(", data := ");
single_value->field_data.log_match(match_value.data(), legacy);
TTCN_Logger::log_event_str(" }");
} else {
match_value.log();
TTCN_Logger::log_event_str(" with ");
log();
if (match(match_value, legacy)) TTCN_Logger::log_event_str(" matched");
else TTCN_Logger::log_event_str(" unmatched");
}
}

void ETP__DT_template::encode_text(Text_Buf& text_buf) const
{
encode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value->field_seq__no.encode_text(text_buf);
single_value->field_data.encode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
text_buf.push_int(value_list.n_values);
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].encode_text(text_buf);
break;
default:
TTCN_error("Text encoder: Encoding an uninitialized/unsupported template of type @IsobusCMMessageTypes.ETP_DT.");
}
}

void ETP__DT_template::decode_text(Text_Buf& text_buf)
{
clean_up();
decode_text_base(text_buf);
switch (template_selection) {
case SPECIFIC_VALUE:
single_value = new single_value_struct;
single_value->field_seq__no.decode_text(text_buf);
single_value->field_data.decode_text(text_buf);
case OMIT_VALUE:
case ANY_VALUE:
case ANY_OR_OMIT:
break;
case VALUE_LIST:
case COMPLEMENTED_LIST:
value_list.n_values = text_buf.pull_int().get_val();
value_list.list_value = new ETP__DT_template[value_list.n_values];
for (unsigned int list_count = 0; list_count < value_list.n_values; list_count++)
value_list.list_value[list_count].decode_text(text_buf);
break;
default:
TTCN_error("Text decoder: An unknown/unsupported selection was received in a template of type @IsobusCMMessageTypes.ETP_DT.");
}
}

void ETP__DT_template::set_param(Module_Param& param)
{
  param.basic_check(Module_Param::BC_TEMPLATE, "record template");
  switch (param.get_type()) {
  case Module_Param::MP_Omit:
    *this = OMIT_VALUE;
    break;
  case Module_Param::MP_Any:
    *this = ANY_VALUE;
    break;
  case Module_Param::MP_AnyOrNone:
    *this = ANY_OR_OMIT;
    break;
  case Module_Param::MP_List_Template:
  case Module_Param::MP_ComplementList_Template: {
    ETP__DT_template new_temp;
    new_temp.set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
    for (size_t p_i=0; p_i<param.get_size(); p_i++) {
      new_temp.list_item(p_i).set_param(*param.get_elem(p_i));
    }
    *this = new_temp;
    break; }
  case Module_Param::MP_Value_List:
    if (2<param.get_size()) {
      param.error("record template of type @IsobusCMMessageTypes.ETP_DT has 2 fields but list value has %d fields", (int)param.get_size());
    }
    if (param.get_size()>0 && param.get_elem(0)->get_type()!=Module_Param::MP_NotUsed) seq__no().set_param(*param.get_elem(0));
    if (param.get_size()>1 && param.get_elem(1)->get_type()!=Module_Param::MP_NotUsed) data().set_param(*param.get_elem(1));
    break;
  case Module_Param::MP_Assignment_List: {
    Vector<bool> value_used(param.get_size());
    value_used.resize(param.get_size(), FALSE);
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "seq_no")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          seq__no().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      if (!strcmp(curr_param->get_id()->get_name(), "data")) {
        if (curr_param->get_type()!=Module_Param::MP_NotUsed) {
          data().set_param(*curr_param);
        }
        value_used[val_idx]=TRUE;
      }
    }
    for (size_t val_idx=0; val_idx<param.get_size(); val_idx++) if (!value_used[val_idx]) {
      Module_Param* const curr_param = param.get_elem(val_idx);
      curr_param->error("Non existent field name in type @IsobusCMMessageTypes.ETP_DT: %s", curr_param->get_id()->get_name());
      break;
    }
  } break;
  default:
    param.type_error("record template", "@IsobusCMMessageTypes.ETP_DT");
  }
  is_ifpresent = param.get_ifpresent();
}

void ETP__DT_template::check_restriction(template_res t_res, const char* t_name, boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return;
switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
case TR_OMIT:
if (template_selection==OMIT_VALUE) return;
case TR_VALUE:
if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;
single_value->field_seq__no.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ETP_DT");
single_value->field_data.check_restriction(t_res, t_name ? t_name : "@IsobusCMMessageTypes.ETP_DT");
return;
case TR_PRESENT:
if (!match_omit(legacy)) return;
break;
default:
return;
}
TTCN_error("Restriction `%s' on template of type %s violated.", get_res_name(t_res), t_name ? t_name : "@IsobusCMMessageTypes.ETP_DT");
}

boolean ETP__DT_template::is_present(boolean legacy) const
{
if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
return !match_omit(legacy);
}

boolean ETP__DT_template::match_omit(boolean legacy) const
{
if (is_ifpresent) return TRUE;
switch (template_selection) {
case OMIT_VALUE:
case ANY_OR_OMIT:
return TRUE;
case VALUE_LIST:
case COMPLEMENTED_LIST:
if (legacy) {
for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)
if (value_list.list_value[l_idx].match_omit())
return template_selection==VALUE_LIST;
return template_selection==COMPLEMENTED_LIST;
} // else fall through
default:
return FALSE;
}
return FALSE;
}


/* Bodies of static functions */

static void pre_init_module()
{
TTCN_Location current_location("IsobusCMMessageTypes.ttcn", 0, TTCN_Location::LOCATION_UNKNOWN, "IsobusCMMessageTypes");
General__Types::module_object.pre_init_module();
IsobusMessageTypes::module_object.pre_init_module();
}

static void post_init_module()
{
TTCN_Location current_location("IsobusCMMessageTypes.ttcn", 0, TTCN_Location::LOCATION_UNKNOWN, "IsobusCMMessageTypes");
General__Types::module_object.post_init_module();
IsobusMessageTypes::module_object.post_init_module();
}


} /* end of namespace */
