// 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 "SocketCAN_PortType.hh"

namespace SocketCAN__PortType {

/* Prototypes of static functions */

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

/* Literal string constants */

static const unsigned char module_checksum[] = { 0x38, 0x6e, 0x12, 0x9b, 0x78, 0x43, 0xf9, 0x47, 0xd1, 0x55, 0x30, 0x58, 0xa4, 0x99, 0x8f, 0x8f };

/* Global variable definitions */

TTCN_Module module_object("SocketCAN_PortType", __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 */

void SocketCAN__PT::remove_msg_queue_head()
{
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
switch (my_head->item_selection) {
case MESSAGE_0:
delete (my_head)->message_0;
break;
case MESSAGE_1:
delete (my_head)->message_1;
break;
case MESSAGE_2:
delete (my_head)->message_2;
break;
case MESSAGE_3:
delete (my_head)->message_3;
break;
case MESSAGE_4:
delete (my_head)->message_4;
break;
case MESSAGE_5:
delete (my_head)->message_5;
break;
case MESSAGE_6:
delete (my_head)->message_6;
break;
case MESSAGE_7:
delete (my_head)->message_7;
break;
case MESSAGE_8:
delete (my_head)->message_8;
break;
case MESSAGE_9:
delete (my_head)->message_9;
break;
case MESSAGE_10:
delete (my_head)->message_10;
break;
default:
TTCN_error("Internal error: Invalid message selector in the queue of port %s.", port_name);
}
msg_queue_item_base *next_item = msg_queue_head->next_item;
delete (msg_queue_item*)msg_queue_head;
msg_queue_head = next_item;
if (next_item == NULL) msg_queue_tail = NULL;
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::extract__msg, port_name, 0, ++msg_head_count, CHARSTRING(0,NULL), CHARSTRING(0,NULL));}

void SocketCAN__PT::clear_queue()
{
while (msg_queue_head != NULL) remove_msg_queue_head();
}

SocketCAN__PT::SocketCAN__PT(const char *par_port_name)
 : SocketCAN__PT_PROVIDER(par_port_name)
{
msg_queue_head = NULL;
msg_queue_tail = NULL;
mapped_ports = NULL;
n_mapped_ports = 0;
}

SocketCAN__PT::~SocketCAN__PT()
{
clear_queue();
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__socket& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
if (!is_started) TTCN_error("Sending a message on port %s, which is not started.", port_name);
if (!destination_component.is_bound()) TTCN_error("Unbound component reference in the to clause of send operation.");
const TTCN_Logger::Severity log_sev = destination_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_send(port_name, destination_component,
(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_socket : "),
send_par.log(), TTCN_Logger::end_event_log2str()));
}
if (destination_component == SYSTEM_COMPREF) {
(void)get_default_destination();
outgoing_send(send_par);
}
else {
Text_Buf text_buf;
prepare_message(text_buf, "@SocketCAN_Types.SocketCAN_socket");
send_par.encode_text(text_buf);
send_data(text_buf, destination_component);
}
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__socket& send_par, FLOAT* timestamp_redirect)
{
send(send_par, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__socket_template& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__socket& send_par_value = SocketCAN__Types::SocketCAN__socket(send_par.valueof());
send(send_par_value, destination_component, timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__socket_template& send_par, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__socket& send_par_value = SocketCAN__Types::SocketCAN__socket(send_par.valueof());
send(send_par_value, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__ioctl& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
if (!is_started) TTCN_error("Sending a message on port %s, which is not started.", port_name);
if (!destination_component.is_bound()) TTCN_error("Unbound component reference in the to clause of send operation.");
const TTCN_Logger::Severity log_sev = destination_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_send(port_name, destination_component,
(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_ioctl : "),
send_par.log(), TTCN_Logger::end_event_log2str()));
}
if (destination_component == SYSTEM_COMPREF) {
(void)get_default_destination();
outgoing_send(send_par);
}
else {
Text_Buf text_buf;
prepare_message(text_buf, "@SocketCAN_Types.SocketCAN_ioctl");
send_par.encode_text(text_buf);
send_data(text_buf, destination_component);
}
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__ioctl& send_par, FLOAT* timestamp_redirect)
{
send(send_par, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__ioctl_template& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__ioctl& send_par_value = SocketCAN__Types::SocketCAN__ioctl(send_par.valueof());
send(send_par_value, destination_component, timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__ioctl_template& send_par, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__ioctl& send_par_value = SocketCAN__Types::SocketCAN__ioctl(send_par.valueof());
send(send_par_value, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__connect& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
if (!is_started) TTCN_error("Sending a message on port %s, which is not started.", port_name);
if (!destination_component.is_bound()) TTCN_error("Unbound component reference in the to clause of send operation.");
const TTCN_Logger::Severity log_sev = destination_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_send(port_name, destination_component,
(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_connect : "),
send_par.log(), TTCN_Logger::end_event_log2str()));
}
if (destination_component == SYSTEM_COMPREF) {
(void)get_default_destination();
outgoing_send(send_par);
}
else {
Text_Buf text_buf;
prepare_message(text_buf, "@SocketCAN_Types.SocketCAN_connect");
send_par.encode_text(text_buf);
send_data(text_buf, destination_component);
}
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__connect& send_par, FLOAT* timestamp_redirect)
{
send(send_par, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__connect_template& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__connect& send_par_value = SocketCAN__Types::SocketCAN__connect(send_par.valueof());
send(send_par_value, destination_component, timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__connect_template& send_par, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__connect& send_par_value = SocketCAN__Types::SocketCAN__connect(send_par.valueof());
send(send_par_value, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__bind& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
if (!is_started) TTCN_error("Sending a message on port %s, which is not started.", port_name);
if (!destination_component.is_bound()) TTCN_error("Unbound component reference in the to clause of send operation.");
const TTCN_Logger::Severity log_sev = destination_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_send(port_name, destination_component,
(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_bind : "),
send_par.log(), TTCN_Logger::end_event_log2str()));
}
if (destination_component == SYSTEM_COMPREF) {
(void)get_default_destination();
outgoing_send(send_par);
}
else {
Text_Buf text_buf;
prepare_message(text_buf, "@SocketCAN_Types.SocketCAN_bind");
send_par.encode_text(text_buf);
send_data(text_buf, destination_component);
}
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__bind& send_par, FLOAT* timestamp_redirect)
{
send(send_par, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__bind_template& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__bind& send_par_value = SocketCAN__Types::SocketCAN__bind(send_par.valueof());
send(send_par_value, destination_component, timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__bind_template& send_par, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__bind& send_par_value = SocketCAN__Types::SocketCAN__bind(send_par.valueof());
send(send_par_value, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__send__data& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
if (!is_started) TTCN_error("Sending a message on port %s, which is not started.", port_name);
if (!destination_component.is_bound()) TTCN_error("Unbound component reference in the to clause of send operation.");
const TTCN_Logger::Severity log_sev = destination_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_send(port_name, destination_component,
(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_send_data : "),
send_par.log(), TTCN_Logger::end_event_log2str()));
}
if (destination_component == SYSTEM_COMPREF) {
(void)get_default_destination();
outgoing_send(send_par);
}
else {
Text_Buf text_buf;
prepare_message(text_buf, "@SocketCAN_Types.SocketCAN_send_data");
send_par.encode_text(text_buf);
send_data(text_buf, destination_component);
}
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__send__data& send_par, FLOAT* timestamp_redirect)
{
send(send_par, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__send__data_template& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__send__data& send_par_value = SocketCAN__Types::SocketCAN__send__data(send_par.valueof());
send(send_par_value, destination_component, timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__send__data_template& send_par, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__send__data& send_par_value = SocketCAN__Types::SocketCAN__send__data(send_par.valueof());
send(send_par_value, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__write__data& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
if (!is_started) TTCN_error("Sending a message on port %s, which is not started.", port_name);
if (!destination_component.is_bound()) TTCN_error("Unbound component reference in the to clause of send operation.");
const TTCN_Logger::Severity log_sev = destination_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_send(port_name, destination_component,
(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_write_data : "),
send_par.log(), TTCN_Logger::end_event_log2str()));
}
if (destination_component == SYSTEM_COMPREF) {
(void)get_default_destination();
outgoing_send(send_par);
}
else {
Text_Buf text_buf;
prepare_message(text_buf, "@SocketCAN_Types.SocketCAN_write_data");
send_par.encode_text(text_buf);
send_data(text_buf, destination_component);
}
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__write__data& send_par, FLOAT* timestamp_redirect)
{
send(send_par, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__write__data_template& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__write__data& send_par_value = SocketCAN__Types::SocketCAN__write__data(send_par.valueof());
send(send_par_value, destination_component, timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__write__data_template& send_par, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__write__data& send_par_value = SocketCAN__Types::SocketCAN__write__data(send_par.valueof());
send(send_par_value, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__write__isotp& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
if (!is_started) TTCN_error("Sending a message on port %s, which is not started.", port_name);
if (!destination_component.is_bound()) TTCN_error("Unbound component reference in the to clause of send operation.");
const TTCN_Logger::Severity log_sev = destination_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_send(port_name, destination_component,
(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_write_isotp : "),
send_par.log(), TTCN_Logger::end_event_log2str()));
}
if (destination_component == SYSTEM_COMPREF) {
(void)get_default_destination();
outgoing_send(send_par);
}
else {
Text_Buf text_buf;
prepare_message(text_buf, "@SocketCAN_Types.SocketCAN_write_isotp");
send_par.encode_text(text_buf);
send_data(text_buf, destination_component);
}
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__write__isotp& send_par, FLOAT* timestamp_redirect)
{
send(send_par, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__write__isotp_template& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__write__isotp& send_par_value = SocketCAN__Types::SocketCAN__write__isotp(send_par.valueof());
send(send_par_value, destination_component, timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__write__isotp_template& send_par, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__write__isotp& send_par_value = SocketCAN__Types::SocketCAN__write__isotp(send_par.valueof());
send(send_par_value, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__setsockopt& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
if (!is_started) TTCN_error("Sending a message on port %s, which is not started.", port_name);
if (!destination_component.is_bound()) TTCN_error("Unbound component reference in the to clause of send operation.");
const TTCN_Logger::Severity log_sev = destination_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_send(port_name, destination_component,
(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_setsockopt : "),
send_par.log(), TTCN_Logger::end_event_log2str()));
}
if (destination_component == SYSTEM_COMPREF) {
(void)get_default_destination();
outgoing_send(send_par);
}
else {
Text_Buf text_buf;
prepare_message(text_buf, "@SocketCAN_Types.SocketCAN_setsockopt");
send_par.encode_text(text_buf);
send_data(text_buf, destination_component);
}
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__setsockopt& send_par, FLOAT* timestamp_redirect)
{
send(send_par, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__setsockopt_template& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__setsockopt& send_par_value = SocketCAN__Types::SocketCAN__setsockopt(send_par.valueof());
send(send_par_value, destination_component, timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__setsockopt_template& send_par, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__setsockopt& send_par_value = SocketCAN__Types::SocketCAN__setsockopt(send_par.valueof());
send(send_par_value, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__close& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
if (!is_started) TTCN_error("Sending a message on port %s, which is not started.", port_name);
if (!destination_component.is_bound()) TTCN_error("Unbound component reference in the to clause of send operation.");
const TTCN_Logger::Severity log_sev = destination_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_send(port_name, destination_component,
(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_close : "),
send_par.log(), TTCN_Logger::end_event_log2str()));
}
if (destination_component == SYSTEM_COMPREF) {
(void)get_default_destination();
outgoing_send(send_par);
}
else {
Text_Buf text_buf;
prepare_message(text_buf, "@SocketCAN_Types.SocketCAN_close");
send_par.encode_text(text_buf);
send_data(text_buf, destination_component);
}
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__close& send_par, FLOAT* timestamp_redirect)
{
send(send_par, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__close_template& send_par, const COMPONENT& destination_component, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__close& send_par_value = SocketCAN__Types::SocketCAN__close(send_par.valueof());
send(send_par_value, destination_component, timestamp_redirect);
}

void SocketCAN__PT::send(const SocketCAN__Types::SocketCAN__close_template& send_par, FLOAT* timestamp_redirect)
{
const SocketCAN__Types::SocketCAN__close& send_par_value = SocketCAN__Types::SocketCAN__close(send_par.valueof());
send(send_par_value, COMPONENT(get_default_destination()), timestamp_redirect);
}

void SocketCAN__PT::add_port(PORT* p)
{
++n_mapped_ports;
mapped_ports = static_cast<PORT**>(Realloc(mapped_ports, n_mapped_ports * sizeof(PORT*)));
mapped_ports[n_mapped_ports - 1] = p;
}

void SocketCAN__PT::remove_port(PORT* p)
{
size_t new_size = n_mapped_ports;
for (size_t i = 0; i < n_mapped_ports; ++i) {
if (mapped_ports[i] == p) {
mapped_ports[i] = NULL;
--new_size;
}
}
if (new_size != n_mapped_ports) {
PORT** new_list = static_cast<PORT**>(Malloc(new_size * sizeof(PORT*)));
for (size_t i = 0, j = 0; i < n_mapped_ports; ++i) {
if (mapped_ports[i] != NULL) {
new_list[j] = mapped_ports[i];
++j;
}
}
Free(mapped_ports);
mapped_ports = new_list;
n_mapped_ports = new_size;
}
}

void SocketCAN__PT::reset_port_variables()
{
Free(mapped_ports);
mapped_ports = NULL;
n_mapped_ports = 0;
}

void SocketCAN__PT::outgoing_public_send(const SocketCAN__Types::SocketCAN__socket& send_par) {
outgoing_send(send_par);
}

void SocketCAN__PT::outgoing_public_send(const SocketCAN__Types::SocketCAN__ioctl& send_par) {
outgoing_send(send_par);
}

void SocketCAN__PT::outgoing_public_send(const SocketCAN__Types::SocketCAN__connect& send_par) {
outgoing_send(send_par);
}

void SocketCAN__PT::outgoing_public_send(const SocketCAN__Types::SocketCAN__bind& send_par) {
outgoing_send(send_par);
}

void SocketCAN__PT::outgoing_public_send(const SocketCAN__Types::SocketCAN__send__data& send_par) {
outgoing_send(send_par);
}

void SocketCAN__PT::outgoing_public_send(const SocketCAN__Types::SocketCAN__write__data& send_par) {
outgoing_send(send_par);
}

void SocketCAN__PT::outgoing_public_send(const SocketCAN__Types::SocketCAN__write__isotp& send_par) {
outgoing_send(send_par);
}

void SocketCAN__PT::outgoing_public_send(const SocketCAN__Types::SocketCAN__setsockopt& send_par) {
outgoing_send(send_par);
}

void SocketCAN__PT::outgoing_public_send(const SocketCAN__Types::SocketCAN__close& send_par) {
outgoing_send(send_par);
}

alt_status SocketCAN__PT::receive(const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else {
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS, "Matching on port %s succeeded.", port_name);
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
switch (my_head->item_selection) {
case MESSAGE_0:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_socket_result: "),
my_head->message_0->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_1:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_ioctl_result: "),
my_head->message_1->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_2:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_connect_result: "),
my_head->message_2->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_3:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_bind_result: "),
my_head->message_3->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_4:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_send_data_result: "),
my_head->message_4->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_5:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_data_result: "),
my_head->message_5->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_6:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_isotp_result: "),
my_head->message_6->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_7:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame: "),
my_head->message_7->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_8:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_BCM_message: "),
my_head->message_8->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_9:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_isotp_pdu: "),
my_head->message_9->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_10:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_setsockopt_result: "),
my_head->message_10->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
default:
TTCN_error("Internal error: unknown message");
}
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else {
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS, "Matching on port %s succeeded.", port_name);
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
switch (my_head->item_selection) {
case MESSAGE_0:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_socket_result: "),
my_head->message_0->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_1:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_ioctl_result: "),
my_head->message_1->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_2:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_connect_result: "),
my_head->message_2->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_3:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_bind_result: "),
my_head->message_3->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_4:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_send_data_result: "),
my_head->message_4->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_5:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_data_result: "),
my_head->message_5->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_6:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_isotp_result: "),
my_head->message_6->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_7:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame: "),
my_head->message_7->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_8:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_BCM_message: "),
my_head->message_8->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_9:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_isotp_pdu: "),
my_head->message_9->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_10:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_setsockopt_result: "),
my_head->message_10->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
default:
TTCN_error("Internal error: unknown message");
}
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS, "Matching on port %s succeeded.", port_name);
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
switch (my_head->item_selection) {
case MESSAGE_0:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_socket_result: "),
my_head->message_0->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_1:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_ioctl_result: "),
my_head->message_1->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_2:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_connect_result: "),
my_head->message_2->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_3:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_bind_result: "),
my_head->message_3->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_4:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_send_data_result: "),
my_head->message_4->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_5:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_data_result: "),
my_head->message_5->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_6:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_isotp_result: "),
my_head->message_6->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_7:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame: "),
my_head->message_7->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_8:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_BCM_message: "),
my_head->message_8->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_9:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_isotp_pdu: "),
my_head->message_9->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
case MESSAGE_10:
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_setsockopt_result: "),
my_head->message_10->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);
break;
default:
TTCN_error("Internal error: unknown message");
}
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__socket__result_template& value_template, SocketCAN__Types::SocketCAN__socket__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_0) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_socket_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_0)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_0),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_0;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_0),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_socket_result : "),
my_head->message_0->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__socket__result_template& value_template, SocketCAN__Types::SocketCAN__socket__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_0) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_socket_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_0)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_0),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_0;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_0),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_socket_result : "),
my_head->message_0->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__socket__result_template& value_template, SocketCAN__Types::SocketCAN__socket__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_0) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_socket_result.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_0)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_0),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_0;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_0),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_socket_result : "),
my_head->message_0->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__ioctl__result_template& value_template, SocketCAN__Types::SocketCAN__ioctl__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_1) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_ioctl_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_1)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_1),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_1;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_1),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_ioctl_result : "),
my_head->message_1->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__ioctl__result_template& value_template, SocketCAN__Types::SocketCAN__ioctl__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_1) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_ioctl_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_1)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_1),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_1;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_1),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_ioctl_result : "),
my_head->message_1->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__ioctl__result_template& value_template, SocketCAN__Types::SocketCAN__ioctl__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_1) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_ioctl_result.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_1)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_1),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_1;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_1),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_ioctl_result : "),
my_head->message_1->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__connect__result_template& value_template, SocketCAN__Types::SocketCAN__connect__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_2) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_connect_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_2)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_2),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_2;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_2),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_connect_result : "),
my_head->message_2->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__connect__result_template& value_template, SocketCAN__Types::SocketCAN__connect__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_2) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_connect_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_2)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_2),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_2;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_2),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_connect_result : "),
my_head->message_2->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__connect__result_template& value_template, SocketCAN__Types::SocketCAN__connect__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_2) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_connect_result.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_2)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_2),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_2;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_2),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_connect_result : "),
my_head->message_2->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__bind__result_template& value_template, SocketCAN__Types::SocketCAN__bind__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_3) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_bind_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_3)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_3),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_3;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_3),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_bind_result : "),
my_head->message_3->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__bind__result_template& value_template, SocketCAN__Types::SocketCAN__bind__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_3) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_bind_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_3)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_3),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_3;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_3),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_bind_result : "),
my_head->message_3->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__bind__result_template& value_template, SocketCAN__Types::SocketCAN__bind__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_3) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_bind_result.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_3)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_3),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_3;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_3),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_bind_result : "),
my_head->message_3->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__send__data__result_template& value_template, SocketCAN__Types::SocketCAN__send__data__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_4) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_send_data_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_4)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_4),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_4;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_4),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_send_data_result : "),
my_head->message_4->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__send__data__result_template& value_template, SocketCAN__Types::SocketCAN__send__data__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_4) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_send_data_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_4)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_4),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_4;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_4),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_send_data_result : "),
my_head->message_4->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__send__data__result_template& value_template, SocketCAN__Types::SocketCAN__send__data__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_4) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_send_data_result.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_4)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_4),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_4;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_4),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_send_data_result : "),
my_head->message_4->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__write__data__result_template& value_template, SocketCAN__Types::SocketCAN__write__data__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_5) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_write_data_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_5)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_5),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_5;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_5),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_data_result : "),
my_head->message_5->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__write__data__result_template& value_template, SocketCAN__Types::SocketCAN__write__data__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_5) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_write_data_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_5)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_5),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_5;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_5),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_data_result : "),
my_head->message_5->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__write__data__result_template& value_template, SocketCAN__Types::SocketCAN__write__data__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_5) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_write_data_result.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_5)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_5),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_5;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_5),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_data_result : "),
my_head->message_5->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__write__isotp__result_template& value_template, SocketCAN__Types::SocketCAN__write__isotp__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_6) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_write_isotp_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_6)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_6),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_6;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_6),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_isotp_result : "),
my_head->message_6->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__write__isotp__result_template& value_template, SocketCAN__Types::SocketCAN__write__isotp__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_6) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_write_isotp_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_6)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_6),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_6;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_6),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_isotp_result : "),
my_head->message_6->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__write__isotp__result_template& value_template, SocketCAN__Types::SocketCAN__write__isotp__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_6) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_write_isotp_result.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_6)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_6),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_6;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_6),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_write_isotp_result : "),
my_head->message_6->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame_template& value_template, SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_7) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_7)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_7),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_7;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_7),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame : "),
my_head->message_7->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame_template& value_template, SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_7) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_7)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_7),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_7;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_7),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame : "),
my_head->message_7->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame_template& value_template, SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_7) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_7)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_7),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_7;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_7),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame : "),
my_head->message_7->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__receive__BCM__message_template& value_template, SocketCAN__Types::SocketCAN__receive__BCM__message *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_8) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_receive_BCM_message.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_8)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_8),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_8;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_8),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_BCM_message : "),
my_head->message_8->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__receive__BCM__message_template& value_template, SocketCAN__Types::SocketCAN__receive__BCM__message *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_8) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_receive_BCM_message.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_8)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_8),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_8;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_8),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_BCM_message : "),
my_head->message_8->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__receive__BCM__message_template& value_template, SocketCAN__Types::SocketCAN__receive__BCM__message *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_8) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_receive_BCM_message.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_8)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_8),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_8;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_8),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_BCM_message : "),
my_head->message_8->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__receive__isotp__pdu_template& value_template, SocketCAN__Types::SocketCAN__receive__isotp__pdu *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_9) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_receive_isotp_pdu.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_9)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_9),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_9;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_9),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_isotp_pdu : "),
my_head->message_9->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__receive__isotp__pdu_template& value_template, SocketCAN__Types::SocketCAN__receive__isotp__pdu *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_9) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_receive_isotp_pdu.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_9)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_9),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_9;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_9),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_isotp_pdu : "),
my_head->message_9->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__receive__isotp__pdu_template& value_template, SocketCAN__Types::SocketCAN__receive__isotp__pdu *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_9) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_receive_isotp_pdu.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_9)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_9),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_9;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_9),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_receive_isotp_pdu : "),
my_head->message_9->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::receive(const SocketCAN__Types::SocketCAN__setsockopt__result_template& value_template, SocketCAN__Types::SocketCAN__setsockopt__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_10) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_setsockopt_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_10)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_10),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_10;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_10),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_setsockopt_result : "),
my_head->message_10->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

alt_status SocketCAN__PT::check_receive(const SocketCAN__Types::SocketCAN__setsockopt__result_template& value_template, SocketCAN__Types::SocketCAN__setsockopt__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Check-receive operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s failed: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
return ALT_NO;
} else if (my_head->item_selection != MESSAGE_10) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s failed: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_setsockopt_result.", port_name);
return ALT_NO;
} else if (!value_template.match(*my_head->message_10)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_10),
 TTCN_Logger::end_event_log2str()));
}
return ALT_NO;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_10;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_10),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::check__receive__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_setsockopt_result : "),
my_head->message_10->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
return ALT_YES;
}
}

alt_status SocketCAN__PT::trigger(const SocketCAN__Types::SocketCAN__setsockopt__result_template& value_template, SocketCAN__Types::SocketCAN__setsockopt__result *value_redirect, const COMPONENT_template& sender_template, COMPONENT *sender_ptr, FLOAT* timestamp_redirect, Index_Redirect*)
{
if (value_template.get_selection() == ANY_OR_OMIT) TTCN_error("Trigger operation using '*' as matching template");
msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;
if (msg_queue_head == NULL) {
if (is_started) return ALT_MAYBE;
else {
TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, "Matching on port %s failed: Port is not started and the queue is empty.", port_name);
return ALT_NO;
}
} else if (!sender_template.match(my_head->sender_component)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::begin_event(log_sev);
TTCN_Logger::log_event("Matching on port %s will drop a message: Sender of the first message in the queue does not match the from clause: ", port_name);
sender_template.log_match(my_head->sender_component);
TTCN_Logger::end_event();
}
remove_msg_queue_head();
return ALT_REPEAT;
} else if (my_head->item_selection != MESSAGE_10) {
TTCN_Logger::log(my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC, "Matching on port %s will drop a message: Type of the first message in the queue is not @SocketCAN_Types.SocketCAN_setsockopt_result.", port_name);
remove_msg_queue_head();
return ALT_REPEAT;
} else if (!value_template.match(*my_head->message_10)) {
const TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF ? TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_10),
 TTCN_Logger::end_event_log2str()));
}
remove_msg_queue_head();
return ALT_REPEAT;
} else {
if (value_redirect != NULL) {
*value_redirect = *my_head->message_10;
}
if (sender_ptr != NULL) *sender_ptr = my_head->sender_component;
TTCN_Logger::Severity log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,
port_name, my_head->sender_component,
(TTCN_Logger::begin_event(log_sev, TRUE), value_template.log_match(*my_head->message_10),
 TTCN_Logger::end_event_log2str()));
}
log_sev = my_head->sender_component==SYSTEM_COMPREF?TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;
if (TTCN_Logger::log_this_event(log_sev)) {
TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::trigger__op,
my_head->sender_component, CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(": @SocketCAN_Types.SocketCAN_setsockopt_result : "),
my_head->message_10->log(), TTCN_Logger::end_event_log2str()),
msg_head_count+1);
}
remove_msg_queue_head();
return ALT_YES;
}
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__socket__result& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_socket_result", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_socket_result : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_0;
new_item->message_0 = new SocketCAN__Types::SocketCAN__socket__result(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__ioctl__result& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_ioctl_result", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_ioctl_result : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_1;
new_item->message_1 = new SocketCAN__Types::SocketCAN__ioctl__result(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__connect__result& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_connect_result", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_connect_result : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_2;
new_item->message_2 = new SocketCAN__Types::SocketCAN__connect__result(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__bind__result& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_bind_result", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_bind_result : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_3;
new_item->message_3 = new SocketCAN__Types::SocketCAN__bind__result(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__send__data__result& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_send_data_result", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_send_data_result : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_4;
new_item->message_4 = new SocketCAN__Types::SocketCAN__send__data__result(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__write__data__result& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_write_data_result", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_write_data_result : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_5;
new_item->message_5 = new SocketCAN__Types::SocketCAN__write__data__result(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__write__isotp__result& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_write_isotp_result", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_write_isotp_result : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_6;
new_item->message_6 = new SocketCAN__Types::SocketCAN__write__isotp__result(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_7;
new_item->message_7 = new SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__receive__BCM__message& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_receive_BCM_message", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_receive_BCM_message : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_8;
new_item->message_8 = new SocketCAN__Types::SocketCAN__receive__BCM__message(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__receive__isotp__pdu& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_receive_isotp_pdu", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_receive_isotp_pdu : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_9;
new_item->message_9 = new SocketCAN__Types::SocketCAN__receive__isotp__pdu(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__setsockopt__result& incoming_par, component sender_component)
{
for (size_t i = 0; i < n_mapped_ports; i++) {
if (mapped_ports[i] != NULL && mapped_ports[i]->incoming_message_handler(&incoming_par, "@SocketCAN_Types.SocketCAN_setsockopt_result", sender_component, FLOAT())) {
return;
}
}
if (!is_started) TTCN_error("Port %s is not started but a message has arrived on it.", port_name);
msg_tail_count++;
if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) {
TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg, port_name, sender_component, msg_tail_count,
CHARSTRING(0, NULL),
(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE), TTCN_Logger::log_event_str(" @SocketCAN_Types.SocketCAN_setsockopt_result : "), incoming_par.log(), TTCN_Logger::end_event_log2str()));
}
msg_queue_item *new_item = new msg_queue_item;
new_item->item_selection = MESSAGE_10;
new_item->message_10 = new SocketCAN__Types::SocketCAN__setsockopt__result(incoming_par);
new_item->sender_component = sender_component;
append_to_msg_queue(new_item);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__socket__result& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__ioctl__result& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__connect__result& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__bind__result& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__send__data__result& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__write__data__result& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__write__isotp__result& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__receive__BCM__message& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__receive__isotp__pdu& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

void SocketCAN__PT::incoming_message(const SocketCAN__Types::SocketCAN__setsockopt__result& incoming_par)
{
incoming_message(incoming_par, SYSTEM_COMPREF);
}

boolean SocketCAN__PT::process_message(const char *message_type, Text_Buf& incoming_buf, component sender_component, OCTETSTRING&)
{
if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_socket_result")) {
SocketCAN__Types::SocketCAN__socket__result incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_ioctl_result")) {
SocketCAN__Types::SocketCAN__ioctl__result incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_connect_result")) {
SocketCAN__Types::SocketCAN__connect__result incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_bind_result")) {
SocketCAN__Types::SocketCAN__bind__result incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_send_data_result")) {
SocketCAN__Types::SocketCAN__send__data__result incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_write_data_result")) {
SocketCAN__Types::SocketCAN__write__data__result incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_write_isotp_result")) {
SocketCAN__Types::SocketCAN__write__isotp__result incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_receive_CAN_or_CAN_FD_frame")) {
SocketCAN__Types::SocketCAN__receive__CAN__or__CAN__FD__frame incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_receive_BCM_message")) {
SocketCAN__Types::SocketCAN__receive__BCM__message incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_receive_isotp_pdu")) {
SocketCAN__Types::SocketCAN__receive__isotp__pdu incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else if (!strcmp(message_type, "@SocketCAN_Types.SocketCAN_setsockopt_result")) {
SocketCAN__Types::SocketCAN__setsockopt__result incoming_par;
incoming_par.decode_text(incoming_buf);
incoming_message(incoming_par, sender_component);
return TRUE;
} else return FALSE;
}


/* Bodies of static functions */

static void pre_init_module()
{
TTCN_Location current_location("../src/SocketCAN_PortType.ttcn", 0, TTCN_Location::LOCATION_UNKNOWN, "SocketCAN_PortType");
SocketCAN__Types::module_object.pre_init_module();
}

static void post_init_module()
{
TTCN_Location current_location("../src/SocketCAN_PortType.ttcn", 0, TTCN_Location::LOCATION_UNKNOWN, "SocketCAN_PortType");
SocketCAN__Types::module_object.post_init_module();
}


} /* end of namespace */
