osmo-ttcn3-hacks/MTP3asp_CNL113337/demo/MTP3asp_PT.cc

2953 lines
91 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// //
// Copyright Test Competence Center (TCC) ETH 2012 //
// //
// The copyright to the computer program(s) herein is the property of TCC. //
// The program(s) may be used and/or copied only with the written permission //
// of TCC or in accordance with the terms and conditions stipulated in the //
// agreement/contract under which the program(s) have been supplied //
// //
///////////////////////////////////////////////////////////////////////////////
//
// File: MTP3asp_PT.cc
// Description: Implementation of port MTP3asp_PT
// This test port is written to connect TTCN-3 to SEA according
// to specification ITU-T SS7 MTP3, ANSI, TCC, IETF, MPT
// Reference: ITU-T Recommendation Q.704, RFC3332
// Rev: R11A01
// Prodnr: CNL 113 337
// Updated: 2012-05-24
// Contact: http://ttcn.ericsson.se
// IMPORTANT MODIFICATION:
// mtp3_ttc uses ALWAYS 16 bits long SPCs, regardless of mtp3_ni sio
#include "MTP3asp_PT.hh"
#include "MTP3asp_Types.hh"
#include "MTP3asp_PortType.hh"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <poll.h>
#include <errno.h>
#include <stdarg.h>
#include <string.h>
// Constans for M3UA, see rfc 3332 and 2/1056-FCPW 101 86/P-1
// Constants for decoding M3UA common headers
#define M3UA_VER_OFFS 0
#define M3UA_CLS_OFFS 2
#define M3UA_TYP_OFFS 3
#define M3UA_LGT_OFFS 4
#define M3UA_MSG_OFFS 8
#define M3UA_MSG_LENGTH_LENGTH 4
// Constants for M3UA protocol
//Msg classes
#define M3UA_MSG_CLS_MGMT 0x00
#define M3UA_MSG_CLS_TRNSFM 0x01
#define M3UA_MSG_CLS_SSNM 0x02
#define M3UA_MSG_CLS_ASPSM 0x03
#define M3UA_MSG_CLS_ASPTM 0x04
#define M3UA_MSG_CLS_RKM 0x09
//Msg types
#define M3UA_MSG_TYP_MGMT_ERR 0x00
#define M3UA_MSG_TYP_MGMT_NTFY 0x01
#define M3UA_MSG_TYP_TRSNFM_DATA 0x01
#define M3UA_MSG_TYP_SSNM_DUNA 0x01
#define M3UA_MSG_TYP_SSNM_DAVA 0x02
#define M3UA_MSG_TYP_SSNM_DAUD 0x03
#define M3UA_MSG_TYP_SSNM_SCON 0x04
#define M3UA_MSG_TYP_SSNM_DUPU 0x05
#define M3UA_MSG_TYP_SSNM_DRST 0x06
#define M3UA_MSG_TYP_ASPSM_ASPUP 0x01
#define M3UA_MSG_TYP_ASPSM_ASPDN 0x02
#define M3UA_MSG_TYP_ASPSM_BEAT 0x03
#define M3UA_MSG_TYP_ASPSM_ASPUPAck 0x04
#define M3UA_MSG_TYP_ASPSM_ASPDNAck 0x05
#define M3UA_MSG_TYP_ASPSM_BEATAck 0x06
#define M3UA_MSG_TYP_ASPTM_ASPAC 0x01
#define M3UA_MSG_TYP_ASPTM_ASPIA 0x02
#define M3UA_MSG_TYP_ASPTM_ASPACAck 0x03
#define M3UA_MSG_TYP_ASPTM_ASPIAAck 0x04
#define M3UA_MSG_TYP_RKM_REGREQ 0x01
#define M3UA_MSG_TYP_RKM_REGRSP 0x02
#define M3UA_MSG_TYP_RKM_DEREGREQ 0x03
#define M3UA_MSG_TYP_RKM_DEREGRESP 0x04
//parameters
//common for all adaptation layer
#define PAR_PREFIX_COMMON 0x00
#define PAR_INFO_STR 0x04
#define PAR_ROUTING_CTX 0x06
#define PAR_DIAG_INFO 0x07
#define PAR_HEART_BEAT 0x09
#define PAR_TRAFFMODE_T 0x0b
#define PAR_ERROR_CODE 0x0c
#define PAR_STATUS 0x0d
#define PAR_ASP_ID 0x11
#define PAR_AFFECTED_PC 0x12
#define PAR_CORREL_ID 0x13
//M3UA specific
#define PAR_PREFIX_M3UA 0x02
#define PAR_NETW_APP 0x00
#define PAR_USR_O_CAUSE 0x04
#define PAR_CNGST_IND 0x05
#define PAR_CNCRD_IND 0x06
#define PAR_ROUTING_KEY 0x07
#define PAR_REG_RSLT 0x08
#define PAR_DEREG_RSLT 0x09
#define PAR_LOC_RK_ID 0x0a
#define PAR_DPC 0x0b
#define PAR_SI 0x0c
#define PAR_OPC_LIST 0x0e
#define PAR_CIRC_RNG 0x0f
#define PAR_PROT_DATA 0x10
#define PAR_REG_STAT 0x12
#define PAR_DEREG_STAT 0x13
// error codes:
#define PAR_ERRC_IVER 0x01
#define PAR_ERRC_UNSMC 0x03
#define PAR_ERRC_UNSMT 0x04
#define PAR_ERRC_UNTMT 0x05
#define PAR_ERRC_UNEM 0x06
#define PAR_ERRC_PERR 0x07
#define PAR_ERRC_ISI 0x09
#define PAR_ERRC_RMB 0x0D
#define PAR_ERRC_ASPIDR 0x0E
#define PAR_ERRC_IASPID 0x0F
#define PAR_ERRC_IPARV 0x11
#define PAR_ERRC_PARFE 0x12
#define PAR_ERRC_UPAR 0x13
#define PAR_ERRC_DSU 0x14
#define PAR_ERRC_INA 0x15
#define PAR_ERRC_MP 0x16
#define PAR_ERRC_IRC 0x19
#define PAR_ERRC_NCFAS 0x1A
// --------------------------
// Basic Test Port functions
// --------------------------
using namespace MTP3asp__Types;
namespace MTP3asp__PortType {
//external functions
//##########################################################
//f__MTP3__SEA__connect (for MTP3asp_PT)
BOOLEAN f__MTP3__SEA__connect(MTP3asp__PT& portRef,
const CHARSTRING& Hostname,const INTEGER& Port,const CHARSTRING& EntityName,const BOOLEAN& Http)
{
return f__MTP3__SEA__connect__extern(portRef,Hostname,Port,EntityName,Http);
}
//------------
//f__MTP3__SEA__disconnect (for MTP3asp_PT)
BOOLEAN f__MTP3__SEA__disconnect(MTP3asp__PT& portRef)
{
return f__MTP3__SEA__disconnect__extern(portRef);
}
//------------
//f__MTP3__SEA__connect__extern
BOOLEAN f__MTP3__SEA__connect__extern(MTP3asp__PT_PROVIDER& portRef,
const CHARSTRING& Hostname,const INTEGER& Port,const CHARSTRING& EntityName,const BOOLEAN& Http)
{
#ifndef TARGET_TEST
if (portRef.dynamicConnection && (!(portRef.connectionUp)))
{
delete [] portRef.hostname;
int len = strlen(Hostname);
portRef.hostname = new char[len + 1];
memcpy(portRef.hostname, Hostname, len + 1);
portRef.httpport = Port;
delete [] portRef.entityname;
len = strlen(EntityName);
portRef.entityname = new char[len + 1];
memcpy(portRef.entityname, EntityName, len + 1);
if(Http)
portRef.MTP3_open_channel(TRUE);
else
portRef.MTP3_open_channel(FALSE);
if(portRef.wait_for_open())
{
portRef.user_connect();
portRef.connectionUp = TRUE;
return TRUE;
}
}
else
#endif
portRef.log("Dynamic connection feature is not active or already connected.");
return FALSE;
}
//------------
//f__MTP3__SEA__disconnect__extern
BOOLEAN f__MTP3__SEA__disconnect__extern(MTP3asp__PT_PROVIDER& portRef)
{
#ifndef TARGET_TEST
if (portRef.connectionUp)
{
portRef.MTP3_close_connection();
portRef.connectionUp = FALSE;
return TRUE;
}
#endif
return FALSE;
}
//------------
// Test Port constructor
MTP3asp__PT_PROVIDER::MTP3asp__PT_PROVIDER(const char *par_port_name)
: PORT(par_port_name)
{
MTP_fd=-1;
httpport=-1;
hostname=NULL;
destinationname = NULL;
dynamicConnection = FALSE;
const char *str="b303d76a-266c-11d4-b8f5-08002090d3da";
int len = strlen(str);
iid_string= new char[len + 1];
memcpy(iid_string, str, len + 1);
entityname=NULL;
Filter=Loop=-1;
Sut_Pc=Tester_Pc=-1;
Ni_is_set = FALSE;
MTPServiceType = MTP3itu;
M3UA_version = 1;
M3UAState = AssocDown; // unnecessary...
mtp3_ni=0;
#ifndef TARGET_TEST
user_map_p = &MTP3asp__PT_PROVIDER::MTP3_user_map;
user_unmap_p = &MTP3asp__PT_PROVIDER::MTP3_user_unmap;
interpreter = &MTP3asp__PT_PROVIDER::MTP3_interpreter;
#endif
forward_pause = FALSE;
forward_resume = FALSE;
forward_status = FALSE;
}
//------------
// Test Port destructor
MTP3asp__PT_PROVIDER::~MTP3asp__PT_PROVIDER()
{
delete [] hostname;
delete [] entityname;
delete [] iid_string;
}
//------------
// set_parameter
void MTP3asp__PT_PROVIDER::set_parameter(const char *parameter_name,
const char *parameter_value)
{
log("set_parameter: %s = %s",parameter_name,parameter_value);
if (!strcmp(parameter_name,"Hostname"))
{
delete [] hostname;
int len = strlen(parameter_value);
hostname = new char[len + 1];
memcpy(hostname, parameter_value, len + 1);
}
else if (!strcmp(parameter_name, "HttpPort"))
{
httpport = atoi(parameter_value);
}
else if (!strcmp(parameter_name,"EntityName"))
{
delete [] entityname;
int len = strlen(parameter_value);
entityname= new char[len + 1];
memcpy(entityname, parameter_value, len + 1);
}
else if (!strcmp(parameter_name,"DestinationName"))
{
delete [] destinationname;
int len = strlen(parameter_value);
destinationname= new char[len + 1];
memcpy(destinationname, parameter_value, len + 1);
}
else if (!strcmp(parameter_name,"Filter"))
{
if (!strcmp(parameter_value,"ON")) Filter = MTP3_ON;
else Filter = MTP3_OFF;
}
else if (!strcmp(parameter_name,"Loop"))
{
if (!strcmp(parameter_value,"ON")) Loop = MTP3_ON;
else Loop = MTP3_OFF;
}
else if (!strcmp(parameter_name,"NI"))
{
Ni_is_set = TRUE;
mtp3_ni = atoi(parameter_value);
debuglog("Network indicator is set to %i",mtp3_ni);
}
else if (!strcmp(parameter_name,"SUT_Pc"))
{
Sut_Pc = atoi(parameter_value);
}
else if (!strcmp(parameter_name,"TESTER_Pc"))
{
Tester_Pc = atoi(parameter_value);
}
else if (!strcmp(parameter_name,"M3UA_version"))
{
M3UA_version = atoi(parameter_value);
debuglog("%d",M3UA_version);
}
#ifndef TARGET_TEST
else if (!strcmp(parameter_name,"DynamicConnection"))
{
if (!strcasecmp(parameter_value,"ON"))
{
dynamicConnection = TRUE;
}
}
#endif
else if (!strcmp(parameter_name,"MTP3ServiceType"))
{
if (!strcmp(parameter_value,"TargetM3UA"))
{
#ifndef TARGET_TEST
error("TargetM3UA not supported, since TARGET_TEST not in Makefile");
#else
log("MTP3ServiceType is set to TargetM3UA");
user_map_p = &MTP3asp__PT_PROVIDER::Target_user_map;
user_unmap_p = &MTP3asp__PT_PROVIDER::Target_user_unmap;
MTPServiceType = TargetM3UA;
#endif
}
else if (!strcmp(parameter_value,"TargetSTC"))
{
#ifndef TARGET_TEST
error("TargetSTC not supported, since TARGET_TEST not in Makefile");
#else
log("MTP3ServiceType is set to TargetSTC");
user_map_p = &MTP3asp__PT_PROVIDER::TargetSTC_user_map;
user_unmap_p = &MTP3asp__PT_PROVIDER::Target_user_unmap; //Same as by Target M3UA
MTPServiceType = TargetSTC;
#endif
}
#ifndef TARGET_TEST
else if (!strcmp(parameter_value,"M3UA"))
{ //M3UA
log("MTP3ServiceType is set to M3UA");
interpreter = &MTP3asp__PT_PROVIDER::M3UA_interpreter;
user_map_p = &MTP3asp__PT_PROVIDER::M3UA_user_map;
user_connect_p = &MTP3asp__PT_PROVIDER::M3UA_user_connect;
user_unmap_p = &MTP3asp__PT_PROVIDER::M3UA_user_unmap;
MTPServiceType = M3UA;
}
else if (!strcmp(parameter_value,"MTP3itu"))
{
log("MTP3ServiceType is set to MTP3itu");
interpreter = &MTP3asp__PT_PROVIDER::MTP3_interpreter;
user_map_p = &MTP3asp__PT_PROVIDER::MTP3_user_map;
user_connect_p = &MTP3asp__PT_PROVIDER::MTP3_user_connect;
user_unmap_p = &MTP3asp__PT_PROVIDER::MTP3_user_unmap;
MTPServiceType = MTP3itu;
}
else if ( !strcmp(parameter_value,"MTP3ansi"))
{
log("MTP3ServiceType is set to MTP3ansi");
interpreter = &MTP3asp__PT_PROVIDER::MTP3_interpreter;
user_map_p = &MTP3asp__PT_PROVIDER::MTP3_user_map;
user_connect_p = &MTP3asp__PT_PROVIDER::MTP3_user_connect;
user_unmap_p = &MTP3asp__PT_PROVIDER::MTP3_user_unmap;
MTPServiceType = MTP3ansi;
}
else if ( !strcmp(parameter_value,"MTP3ttc"))
{
log("MTP3ServiceType is set to MTP3ttc");
interpreter = &MTP3asp__PT_PROVIDER::MTP3_interpreter;
user_map_p = &MTP3asp__PT_PROVIDER::MTP3_user_map;
user_connect_p = &MTP3asp__PT_PROVIDER::MTP3_user_connect;
user_unmap_p = &MTP3asp__PT_PROVIDER::MTP3_user_unmap;
MTPServiceType = MTP3ttc;
}
else if ( !strcmp(parameter_value,"MTP3mpt"))
{
log("MTP3ServiceType is set to MTP3mpt");
interpreter = &MTP3asp__PT_PROVIDER::MTP3_interpreter;
user_map_p = &MTP3asp__PT_PROVIDER::MTP3_user_map;
user_connect_p = &MTP3asp__PT_PROVIDER::MTP3_user_connect;
user_unmap_p = &MTP3asp__PT_PROVIDER::MTP3_user_unmap;
MTPServiceType = MTP3mpt;
}
else if ( !strcmp(parameter_value,"MTP3bttc"))
{
log("MTP3ServiceType is set to MTP3bttc");
interpreter = &MTP3asp__PT_PROVIDER::MTP3_interpreter;
user_map_p = &MTP3asp__PT_PROVIDER::MTP3_user_map;
user_connect_p = &MTP3asp__PT_PROVIDER::MTP3_user_connect;
user_unmap_p = &MTP3asp__PT_PROVIDER::MTP3_user_unmap;
MTPServiceType = MTP3bttc;
}
else if ( !strcmp(parameter_value,"MTP3iup"))
{
log("MTP3ServiceType is set to MTP3iup");
interpreter = &MTP3asp__PT_PROVIDER::MTP3_interpreter;
user_map_p = &MTP3asp__PT_PROVIDER::MTP3_user_map;
user_connect_p = &MTP3asp__PT_PROVIDER::MTP3_user_connect;
user_unmap_p = &MTP3asp__PT_PROVIDER::MTP3_user_unmap;
MTPServiceType = MTP3iup;
}
else if ( !strcmp(parameter_value,"STC"))
{
log("MTP3ServiceType is set to STC");
interpreter = &MTP3asp__PT_PROVIDER::STC_interpreter;
user_map_p = &MTP3asp__PT_PROVIDER::STC_user_map;
user_connect_p = &MTP3asp__PT_PROVIDER::STC_user_connect;
user_unmap_p = &MTP3asp__PT_PROVIDER::STC_user_unmap;
MTPServiceType = STC;
}
#endif
else
{
log("Unsupported MTP3ServiceType: %s, falling back to MTP3itu",
parameter_value);
}
}
else if(strcasecmp(parameter_name, "forward_pause") == 0)
{
if (strcasecmp(parameter_value,"forward") == 0)
forward_pause = TRUE;
else if(strcasecmp(parameter_value,"ignore") == 0)
forward_pause = FALSE;
else
error("set_parameter(): Invalid parameter value: %s for parameter %s. Only forward and ignore can be used!" ,
parameter_value, parameter_name);
}
else if(strcasecmp(parameter_name, "forward_resume") == 0)
{
if (strcasecmp(parameter_value,"forward") == 0)
forward_resume = TRUE;
else if(strcasecmp(parameter_value,"ignore") == 0)
forward_resume = FALSE;
else
error("set_parameter(): Invalid parameter value: %s for parameter %s. Only forward and ignore can be used!" ,
parameter_value, parameter_name);
}
else if(strcasecmp(parameter_name, "forward_status") == 0)
{
if (strcasecmp(parameter_value,"forward") == 0)
forward_status = TRUE;
else if(strcasecmp(parameter_value,"ignore") == 0)
forward_status = FALSE;
else
error("set_parameter(): Invalid parameter value: %s for parameter %s. Only forward and ignore can be used!" ,
parameter_value, parameter_name);
}
else
#ifdef TARGET_TEST
if(!parameter_set(parameter_name ,parameter_value)) //TCP parameters
#endif
log("Unsupported parameter: %s", parameter_name);
}
//------------
// User map
void MTP3asp__PT_PROVIDER::user_map(const char *system_port)
{
if (user_map_p == NULL)
error("Parameter MTP3ServiceType should be set to TargetM3UA in TARGET_TEST mode!");
(this->*user_map_p)(system_port);
}
//------------
// User unmap
void MTP3asp__PT_PROVIDER::user_unmap(const char *system_port)
{
(this->*user_unmap_p)(system_port);
}
//------------
#ifndef TARGET_TEST
// User connect
void MTP3asp__PT_PROVIDER::user_connect()
{
(this->*user_connect_p)();
}
//------------
#endif
//User start
void MTP3asp__PT_PROVIDER::user_start()
{ debuglog("user start ordered");
}
//------------
//User stop
void MTP3asp__PT_PROVIDER::user_stop()
{ debuglog("User stop ordered");
}
//------------
//Event Handler
void MTP3asp__PT_PROVIDER::Handle_Fd_Event(int fd,
boolean is_readable, boolean is_writable, boolean is_error)
{
if (MTPServiceType == TargetM3UA )
{
#ifdef TARGET_TEST
//In case of target Abstract Socket handles the received message
Handle_Socket_Event(fd, is_readable, is_writable, is_error);
#endif
}
#ifndef TARGET_TEST
else
{
int result;
result = MPH_ProcessConnection(myConnection);
if (result <= 0)
{
MPH_CloseConnection(myConnection);
if (result == 0) log("Connection closed by peer.");
else log("Error in incoming message.");
}
}
#endif
}
void MTP3asp__PT_PROVIDER::Handle_Timeout(double time_since_last_call)
{
#ifdef TARGET_TEST
Handle_Timeout_Event(time_since_last_call);
#endif
}
//------------
//Outgoing send
void MTP3asp__PT_PROVIDER::outgoing_send(const ASP__MTP3__TRANSFERreq& send_par)
{
MTP3__Field__sio sio_field = send_par.sio();
#ifndef TARGET_TEST
int si=bit2int(sio_field.si());
#endif
OCTETSTRING sio_oct = bit2oct(sio_field.ni()+sio_field.prio()+sio_field.si());
OCTETSTRING bttc_oct = int2oct(stored_bttc_octet, 1); // additional octet for MTP3bttc
//Message sending by testing on Target
if (MTPServiceType == TargetM3UA)
{
#ifdef TARGET_TEST
OCTETSTRING tcpData = int2oct(1,1); //Message type
tcpData = tcpData + int2oct(send_par.data().lengthof()+15,4); //Length
tcpData = tcpData + sio_oct;
tcpData = tcpData + int2oct(send_par.opc(),4);
tcpData = tcpData + int2oct(send_par.dpc(),4);
tcpData = tcpData + int2oct(send_par.sls(),1);
tcpData = tcpData + send_par.data();
send_outgoing((const unsigned char*)tcpData,tcpData.lengthof());
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("MTP3 Test Port (%s): ", get_name());
TTCN_Logger::log_event_str("Transfer Req message sent: ");
tcpData.log();
TTCN_Logger::end_event();
#endif
return;
}
//Message sending by testing on Target
if (MTPServiceType == TargetSTC)
{
#ifdef TARGET_TEST
OCTETSTRING tcpData = int2oct(1,1); //Message type
tcpData = tcpData + int2oct(send_par.data().lengthof()+15,4); //Length
tcpData = tcpData + int2oct(0,1);
tcpData = tcpData + int2oct(0,4);
tcpData = tcpData + int2oct(0,4);
tcpData = tcpData + int2oct(0,1);
tcpData = tcpData + send_par.data();
send_outgoing((const unsigned char*)tcpData,tcpData.lengthof());
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("MTP3 Test Port (%s): ", get_name());
TTCN_Logger::log_event_str("Transfer Req (STC) message sent: ");
tcpData.log();
TTCN_Logger::end_event();
#endif
return;
}
#ifndef TARGET_TEST
if (dynamicConnection &&(!connectionUp))
{
warn("Connection was not activated via function f_M3UA_SEA_connect.");
return;
}
unsigned int offset;
int MSU_length = send_par.data().lengthof();
int M3UA_par_length;
int length;
int labellen; // sio+routinglabel length
switch ( MTPServiceType)
{
case STC:
length = MSU_length;
memcpy(buffer, send_par.data(), send_par.data().lengthof());
break;
case MTP3iup:
if(si==4)
{
offset = 0;
labellen=6; //ITU-T:sio(1byte) + standard telephony label(5byte)
length = MSU_length+labellen;
buffer[0] = *((const unsigned char*)sio_oct);
SetPointCodesIUP(send_par.sls(), send_par.opc(), send_par.dpc(),
buffer + offset + 1);
memcpy(buffer + offset + labellen, send_par.data(), send_par.data().lengthof());
}
else
{
offset = 0;
labellen=5; //ITU-T:sio(1byte) + routing label(4byte) see /Q.704/15.4.1
length = MSU_length + labellen; //SIF+SIO ;
//append MTP3 MSU
buffer[offset] = *((const unsigned char*)sio_oct);
SetPointCodes(send_par.sls(), send_par.opc(), send_par.dpc(),
buffer + offset + 1);
memcpy(buffer + offset + labellen, send_par.data(), send_par.data().lengthof());
}
break;
case MTP3itu:
offset = 0;
labellen=5; //ITU-T:sio(1byte) + routing label(4byte) see /Q.704/15.4.1
length = MSU_length + labellen; //SIF+SIO ;
//append MTP3 MSU
buffer[offset] = *((const unsigned char*)sio_oct);
SetPointCodes(send_par.sls(), send_par.opc(), send_par.dpc(),
buffer + offset + 1);
memcpy(buffer + offset + labellen, send_par.data(), send_par.data().lengthof());
break;
case MTP3ansi:
offset = 0;
labellen=8; //ANSI: sio(1byte) +routing label(7byte) see T1.111.4
length = MSU_length + labellen; //SIF+SIO ;
//append MTP3 MSU
buffer[offset] = *((const unsigned char*)sio_oct);
SetPointCodes(send_par.sls(), send_par.opc(), send_par.dpc(),
buffer + offset + 1);
memcpy(buffer + offset + labellen, send_par.data(), send_par.data().lengthof());
break;
case MTP3ttc:
offset = 0;
//if (mtp3_ni==0){ labellen=5;}
//else {
labellen=6;
//} //TTC: sio(1byte) +routing label(6byte) see ...
length = MSU_length + labellen; //SIF+SIO ;
//append MTP3 MSU
buffer[offset] = *((const unsigned char*)sio_oct);
SetPointCodes(send_par.sls(), send_par.opc(), send_par.dpc(),
buffer + offset + 1);
memcpy(buffer + offset + labellen, send_par.data(), send_par.data().lengthof());
break;
case MTP3bttc:
offset = 0;
buffer[offset] = *((const unsigned char*)bttc_oct);
offset += 1;
labellen=7; //routing label(7byte)
length = 1 + MSU_length + labellen; //SIF+SIO ;
//append MTP3 MSU
buffer[offset] = *((const unsigned char*)sio_oct);
SetPointCodes(send_par.sls(), send_par.opc(), send_par.dpc(),
buffer + offset + 1);
memcpy(buffer + offset + labellen, send_par.data(), send_par.data().lengthof());
break;
case MTP3mpt:
offset = 0;
if (mtp3_ni==2)
{ labellen=8;} //MPT national: sio(1byte) +routing label(7byte)
else
{ labellen=5;} //MPT international: sio(1byte) +routing label(4byte)
length = MSU_length + labellen; //SIF+SIO ;
//append MTP3 MSU
buffer[offset] = *((const unsigned char*)sio_oct);
SetPointCodes(send_par.sls(), send_par.opc(), send_par.dpc(),
buffer + offset + 1);
memcpy(buffer + offset + labellen,
send_par.data(), send_par.data().lengthof());
break;
case M3UA :
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("MTP3 test port debug: Message to be encoded is: {");
send_par.data().log();
TTCN_Logger::log_event(" ");
if( M3UAState != AssocActive )
{
TTCN_Logger::log_event(" M3UAState is not ready to send data. Its state code: %d",AssocActive);
TTCN_Logger::log_event("}");
TTCN_Logger::end_event();
return;
}
//calculating lengths
M3UA_par_length = MSU_length + 16; // ProtocolData parameter
// header length=16 <== see f
TTCN_Logger::log_event(", Adjusted M3UA_par_length to %d to support 16 octets M3UA param header",M3UA_par_length);
length = 8 + M3UA_par_length; //msg length = header+par
TTCN_Logger::log_event(", M3UA MSU_length is %d ==> there should be %d padding octets", MSU_length, 4-(MSU_length%4));
if (MSU_length%4) { //should be padded to be multiple of 4 octets
length += 4 - (MSU_length%4); //padding shall be counted in msg
//length, but not in par_length
}
TTCN_Logger::log_event(", Set msg length (which includes 8 octets M3UA hdr) to %d ",length);
//filling the first part of the buffer
//common msg hdr ======================================
buffer[0] = M3UA_version;
buffer[1] = 0x00; //spare
buffer[2] = M3UA_MSG_CLS_TRNSFM; // msg class
buffer[3] = M3UA_MSG_TYP_TRSNFM_DATA; // msg type
encode_32b_int(buffer+4, length); //msg length, 4 bytes
//ProtocolData parameter header=========================
//tag
buffer[M3UA_MSG_OFFS] = PAR_PREFIX_M3UA; //par. tag 1st octet
buffer[M3UA_MSG_OFFS+1] = PAR_PROT_DATA; // par tag 2nd octet
//length, NOTE: should not contain the padding bytes!
encode_16b_int(buffer+M3UA_MSG_OFFS+2,M3UA_par_length);
//OPC,DPC
encode_32b_int(buffer+M3UA_MSG_OFFS+4,send_par.opc());
encode_32b_int(buffer+M3UA_MSG_OFFS+8,send_par.dpc());
//SI, NI, MP, SLS
buffer[M3UA_MSG_OFFS+12] = bit2int(sio_field.si()); // SI LSb aligned
buffer[M3UA_MSG_OFFS+13] = bit2int(sio_field.ni()); // NI LSb aligned
buffer[M3UA_MSG_OFFS+14] = bit2int(sio_field.prio()); //MP LSb
//aligned
buffer[M3UA_MSG_OFFS+15] = 0xFF & send_par.sls(); //SLS
// finally the MTP3 MSU itself....
offset = M3UA_MSG_OFFS + 16;
TTCN_Logger::log_event(", buffer offset is now set to %d", offset);
TTCN_Logger::log_event("}");
TTCN_Logger::end_event();
//append MTP3 MSU
memcpy(buffer + offset, send_par.data(), send_par.data().lengthof());
//padding
for (int ii = 0; ii< (MSU_length%4); ++ii) buffer[offset+MSU_length+ii]= 0x00;
break;
default:
error("Invalid MTP3ServiceType setting!");
}
if (TTCN_Logger::log_this_event(TTCN_DEBUG))
{
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("The encoded buffer is: {");
OCTETSTRING(length, buffer).log();
TTCN_Logger::log_event("}");
TTCN_Logger::end_event();
}
send_msg(buffer, length);
#endif
}
//------------
void MTP3asp__PT_PROVIDER::log(const char *msg, ...)
{
TTCN_Logger::begin_event(TTCN_PORTEVENT);
TTCN_Logger::log_event("MTP3 Test Port (%s): ", get_name());
va_list ap;
va_start(ap, msg);
TTCN_Logger::log_event_va_list(msg, ap);
va_end(ap);
TTCN_Logger::end_event();
}
//------------
void MTP3asp__PT_PROVIDER::warn(const char *msg, ...)
{
TTCN_Logger::begin_event(TTCN_WARNING);
TTCN_Logger::log_event("MTP3 Test Port (%s): ", get_name());
va_list ap;
va_start(ap, msg);
TTCN_Logger::log_event_va_list(msg, ap);
va_end(ap);
TTCN_Logger::end_event();
}
//------------
void MTP3asp__PT_PROVIDER::debuglog(const char *msg, ...)
{
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("MTP3 Test Port (%s): ", get_name());
va_list ap;
va_start(ap, msg);
TTCN_Logger::log_event_va_list(msg, ap);
va_end(ap);
TTCN_Logger::end_event();
}
//------------
void MTP3asp__PT_PROVIDER::error(const char *msg, ...)
{
TTCN_Logger::begin_event(TTCN_ERROR);
TTCN_Logger::log_event("MTP3 Test Port (%s): ", get_name());
va_list ap;
va_start(ap, msg);
TTCN_Logger::log_event_va_list(msg, ap);
va_end(ap);
TTCN_Logger::end_event();
TTCN_error("Fatal error in MTP3 Test Port %s.", get_name());
}
//------------
void MTP3asp__PT_PROVIDER::close_log_event()
{
TTCN_Logger::log_event("}");
TTCN_Logger::end_event();
}
//------------
#ifndef TARGET_TEST
// --------------------------------------------
// Functions and definitions for test with SEA
// --------------------------------------------
// Functions of MPH toolkit
// ---------------------------
void connectCallback(CONNECTION* con, int channel, void *clientData)
{
((MTP3asp__PT_PROVIDER *)clientData)->log("Opening channel succeeded "
"(channel number is %u)", channel);
((MTP3asp__PT_PROVIDER *)clientData)->set_channel(channel);
if(((MTP3asp__PT_PROVIDER *)clientData)->dynamicConnection)
((MTP3asp__PT_PROVIDER *)clientData)->conn_state = 1;
}
void messageCallback(CONNECTION* con, int channel, int length,
unsigned char *msg, void *clientData)
{
((MTP3asp__PT_PROVIDER *)clientData)->log("Incoming message from channel: %d",channel);
((MTP3asp__PT_PROVIDER *)clientData)->doInterpret(msg,length,channel,con);
}
void closeCallback(CONNECTION* con, int channel, void *clientData)
{
((MTP3asp__PT_PROVIDER *)clientData)->log("Closed channel: %d", channel);
}
void errorCallback(CONNECTION* con, char *name, char *errorMessage,
void *clientData)
{
if(((MTP3asp__PT_PROVIDER *)clientData)->dynamicConnection)
{
((MTP3asp__PT_PROVIDER *)clientData)->log("Opening channel %s failed: %s", name, errorMessage);
((MTP3asp__PT_PROVIDER *)clientData)->conn_state = 2;
}
else
((MTP3asp__PT_PROVIDER *)clientData)->error("Opening channel %s failed: %s",
name, errorMessage);
}
//------------
//MTP3_open_channel
void MTP3asp__PT_PROVIDER::MTP3_open_channel(boolean http)
{
int result;
int Mphport;
char *perrorString;
if( Loop == MTP3_ON )
{
MTP_fd=-1;
myConnection = NULL;
log("MTP3_open_channel finished for LOOP");
return;
}
if(http)
{
Mphport = MPH_GetMphPort(hostname,httpport,&perrorString);
}
else
{
Mphport = httpport;
}
if (Mphport == -1)
error("GetMphPort failed: %s", *perrorString);
result = MPH_StringToIid(iid_string, &iid);
if (result == -1)
error("Converting %s to MPH_IID failed.", iid_string);
myConnection = MPH_OpenConnection(hostname, Mphport);
if (myConnection == NULL)
error("Opening connection to %s:%d failed.", hostname, Mphport);
MPH_OpenChannel(myConnection,
entityname,
&iid,
connectCallback,
messageCallback,
closeCallback,
errorCallback,
this);
MTP_fd = MPH_GetConnectionFd(myConnection);
if (MTP_fd != -1)
Handler_Add_Fd_Read(MTP_fd);
else
error("Incorrect file descriptor: %d.", MTP_fd);
}
//------------
// MTP3_close_connection
void MTP3asp__PT_PROVIDER::MTP3_close_connection()
{
MPH_CloseConnection(myConnection);
Handler_Remove_Fd_Read(MTP_fd);
close( MTP_fd );
//Uninstall_Handler(); // Unnecessary if only socket MTP_fd is in use
}
//------------
// wait_for_open
boolean MTP3asp__PT_PROVIDER::wait_for_open()
{
conn_state = 0;
while(conn_state==0)
{
pollfd pollFd = { MTP_fd, POLLIN, 0 };
int nEvents = poll(&pollFd, 1, 3000 /* ms */);
if (nEvents == 0) {
log("MPH channel opening time out");
return FALSE;
}
if (nEvents < 0 || (pollFd.revents & (POLLIN | POLLHUP)) == 0) {
log("MPH channel opening error (%d)", (nEvents < 0) ? errno : 0);
return FALSE;
}
Handle_Fd_Event(MTP_fd, TRUE, FALSE, FALSE);
}
if(conn_state == 1) //connectCallback received
{
conn_state = 0;
return TRUE;
}
else //errorCallback received
{
conn_state = 0;
return FALSE;
}
}
//------------
//send msg
void MTP3asp__PT_PROVIDER::send_msg(unsigned char *outbuff, int length)
{
OCTETSTRING buff(length,outbuff);
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("MTP3/M3UA Test Port (%s): {", get_name());
TTCN_Logger::log_event("outgoing buffer= ");
buff.log();
TTCN_Logger::log_event("}");
TTCN_Logger::end_event();
if (Loop == MTP3_ON)
{
log("Message looped back");
doInterpret(outbuff, length, channel, myConnection);
} else
{
MPH_SendMessage(myConnection,channel,length,outbuff);
log("Message sent on channel %d", channel);
}
}
//------------
//Check TestPortVariables
void MTP3asp__PT_PROVIDER::Check_TestPort_Variables()
{
if(!dynamicConnection)
{
if (httpport==-1) error("Parameter HttpPort is not set.");
if (hostname==NULL) error("Parameter Hostname is not set.");
if (entityname==NULL) error("Parameter EntityName is not set.");
}
if (Filter==-1) error("Parameter Filter is not set.");
if (Loop==-1) error("Parameter Loop is not set.");
if (Sut_Pc==-1) error("Parameter SUT_Pc is not set.");
if (Tester_Pc==-1) error("Parameter TESTER_Pc is not set.");
if (!Ni_is_set) error("Parameter NI is not set.");
}
//------------
// -------------------------------------------------
// STC Functions and definitions for test with SEA
// -------------------------------------------------
void MTP3asp__PT_PROVIDER::Check_TestPort_Variables_STC()
{
if(!dynamicConnection)
{
if (httpport==-1) error("Parameter HttpPort is not set.");
if (hostname==NULL) error("Parameter Hostname is not set.");
if (entityname==NULL) error("Parameter EntityName is not set.");
}
}
//------------
//STC user map
void MTP3asp__PT_PROVIDER::STC_user_map(const char *system_port)
{
debuglog("Function STC_user_map started");
Check_TestPort_Variables_STC();
if(dynamicConnection)
{
connectionUp = FALSE;
}
else
{
MTP3_open_channel(TRUE);
STC_user_connect();
}
}
//------------
//STC user connect
void MTP3asp__PT_PROVIDER::STC_user_connect()
{
}
//STC user unmap
void MTP3asp__PT_PROVIDER::STC_user_unmap(const char *system_port)
{
MTP3_close_connection();
dynamicConnection = FALSE;
}
//------------
//STC interpreter
void MTP3asp__PT_PROVIDER::STC_interpreter(unsigned char* inbuffer,int length,int from_channel,CONNECTION* con)
{
if ((length==0) || (inbuffer==NULL))
{
log("0 byte long message received -> packet dropped.");
return;
}
if (length==1)
{
log("1 byte long internal SEA message received -> packet dropped.");
return;
}
if ( !strcmp((const char*)inbuffer,"start") )
{
log("start message received from SEA");
return;
}
else if (!strcmp((const char*)inbuffer,"stop"))
{
log("stop message received from SEA");
return;
}
// writing out the contents of the buffer
OCTETSTRING buff(length,inbuffer);
TTCN_Logger::begin_event(TTCN_PORTEVENT);
TTCN_Logger::log_event("incoming buffer: ");
buff.log();
TTCN_Logger::end_event();
ASP__MTP3__TRANSFERind recv_msg;
MTP3__Field__sio recv_sio;
recv_sio.ni()= int2bit(0,2);
recv_sio.prio()= int2bit(0,2);
recv_sio.si()= int2bit(0,4);
recv_msg.sio() = recv_sio;
recv_msg.sls() = 0;
recv_msg.opc() = 0;
recv_msg.dpc() = 0;
recv_msg.data() = OCTETSTRING(length, &inbuffer[0]);
incoming_message( recv_msg );
}
// -------------------------------------------------
// MTP3 Functions and definitions for test with SEA
// -------------------------------------------------
// SLTM messages for MTP3
// -----------------------
unsigned char ttcn_in_sltm[] = {
'T','T','C','N','-','3',' ','E','x','e','c','u','t','o','r'};
const int sizeof_ttcn_in_sltm=15;
// ITU:
unsigned char sltm_msg_itu[] =
{
0x1, //SIO /'test & maint' see Q.704 /14.2.1 => 0x81 suggested !!!
0x0, 0x0, 0x0, 0x0, //4 bytes for label (dpc, opc,sls)
0x11, //Heading code ITU, see Q.707/5.4
0xF0, //spare+Length of the following string:
'T', 'T', 'C', 'N', '-', '3', ' ', 'E', 'x', 'e', 'c', 'u', 't', 'o', 'r'
};
const int sizeof_sltm_msg_itu=7+15;
// ANSI:
unsigned char sltm_msg_ansi[]=
{
0xB1, //SIO
0x0,0x0,0x0,0x0,0x0,0x0,0x0, // 7 bytes for label
0x11, // Heading Code ANSI T1.111.7-2001
0xF0, // SLC(is 0 OK???)+Length in bytes of the following string:
'T', 'T', 'C', 'N', '-', '3', ' ', 'E', 'x', 'e', 'c', 'u', 't', 'o', 'r'
};
const int sizeof_sltm_ansi=10+15;
// TTC:
unsigned char sltm_msg_ttc_national[]=
{
0x81, //SIO
0x0,0x0,0x0,0x0,0x0,0x0, // 6 bytes for label TO BE CONT!!!
0x11, // Heading Code
0xF0, // SLC(is 0 OK???)+Length in bytes of the following string:
'T', 'T', 'C', 'N', '-', '3', ' ', 'E', 'x', 'e', 'c', 'u', 't', 'o', 'r'
};
const int sizeof_sltm_msg_ttc_national=9+15;
// BTTC:
unsigned char sltm_msg_bttc_national[]=
{
0x0, // extra octet, ignored
0x81, //SIO
0x0,0x0,0x0,0x0,0x0,0x0, // 6 bytes for label TO BE CONT!!!
0x23, // Heading Code
'T', 'T'
};
const int sizeof_sltm_msg_bttc_national=1+8+2;
// MPT:
unsigned char sltm_msg_mpt_national[]=
{
0x81, //SIO
0x0,0x0,0x0,0x0,0x0,0x0,0x0, // 7 bytes for label
0x11, // Heading Code
0xF0, // SLC(is 0 OK???)+Length in bytes of the following string:
'T', 'T', 'C', 'N', '-', '3', ' ', 'E', 'x', 'e', 'c', 'u', 't', 'o', 'r'
};
const int sizeof_sltm_msg_mpt_national=10+15;
//------------
// coder functions for MTP3
// -------------------------
// unsigned int<-> unsigned char array
// Integer encode/decode functions that will encode/decode from/to
// Result: Least Significant Byte first (in lowest address) = LSB = Little Endian
void MTP3asp__PT_PROVIDER::encode_56bLSB_int(unsigned char *to, unsigned long long int from)
{
to[0] = from & 0xFF;
from >>= 8;
to[1] = from & 0xFF;
from >>= 8;
to[2] = from & 0xFF;
from >>= 8;
to[3] = from & 0xFF;
from >>= 8;
to[4] = from & 0xFF;
from >>= 8;
to[5] = from & 0xFF;
from >>= 8;
to[6] = from & 0xFF;
}
//------------
unsigned long long int MTP3asp__PT_PROVIDER::decode_56bLSB_int(const unsigned char *from)
{
typedef unsigned long long int ull;
return ((ull) from[0]) |
((ull) from[1] <<8)|
((ull) from[2] << 16)|
((ull) from[3] << 24)|
((ull) from[4] << 32)|
((ull) from[5] << 40)|
((ull) from[6] << 48);
}
//------------
void MTP3asp__PT_PROVIDER::encode_48bLSB_int(unsigned char *to, unsigned long long int from)
{
to[0] = from & 0xFF;
from >>= 8;
to[1] = from & 0xFF;
from >>= 8;
to[2] = from & 0xFF;
from >>= 8;
to[3] = from & 0xFF;
from >>= 8;
to[4] = from & 0xFF;
from >>= 8;
to[5] = from & 0xFF;
}
//------------
unsigned long long int MTP3asp__PT_PROVIDER::decode_48bLSB_int(const unsigned char *from)
{
typedef unsigned long long int ull;
return ((ull) from[0]) |
((ull) from[1] <<8)|
((ull) from[2] << 16)|
((ull) from[3] << 24)|
((ull) from[4] << 32)|
((ull) from[5] << 40);
}
//------------
void MTP3asp__PT_PROVIDER::encode_40bLSB_int(unsigned char *to, unsigned long long int from)
{
to[0] = from & 0xFF;
from >>= 8;
to[1] = from & 0xFF;
from >>= 8;
to[2] = from & 0xFF;
from >>= 8;
to[3] = from & 0xFF;
from >>= 8;
to[4] = from & 0xFF;
}
//------------
unsigned long long int MTP3asp__PT_PROVIDER::decode_40bLSB_int(const unsigned char *from)
{
typedef unsigned long long int ull;
return ((ull) from[0]) |
((ull) from[1] <<8)|
((ull) from[2] << 16)|
((ull) from[3] << 24)|
((ull) from[4] << 32);
}
//------------
void MTP3asp__PT_PROVIDER::encode_32bLSB_int(unsigned char *to, unsigned int from)
{
to[0] = from & 0xFF;
from >>= 8;
to[1] = from & 0xFF;
from >>= 8;
to[2] = from & 0xFF;
from >>= 8;
to[3] = from & 0xFF;
}
//------------
unsigned int MTP3asp__PT_PROVIDER::decode_32bLSB_int(const unsigned char *from)
{
return from[0] | (from[1] << 8) | (from[2] << 16) | (from[3] << 24);
}
//------------
void MTP3asp__PT_PROVIDER::encode_24bLSB_int(unsigned char *to, int from)
{
to[0] = from & 0xFF;
from >>= 8;
to[1] = from & 0xFF;
from >>= 8;
to[2] = from & 0xFF;
}
//------------
unsigned int MTP3asp__PT_PROVIDER::decode_24bLSB_int(const unsigned char *from)
{
return from[0] | (from[1] << 8) | (from[2] << 16);
}
//------------
void MTP3asp__PT_PROVIDER::encode_16bLSB_int(unsigned char *to, int from)
{
to[0] = from & 0xFF;
from >>= 8;
to[1] = from & 0xFF;
}
//------------
unsigned int MTP3asp__PT_PROVIDER::decode_16bLSB_int(const unsigned char *from)
{
return from[0] | (from[1] << 8);
}
//------------
//MTP3 user map
void MTP3asp__PT_PROVIDER::MTP3_user_map(const char *system_port)
{
debuglog("Function MTP3_user_map started");
Check_TestPort_Variables();
if(dynamicConnection)
{
connectionUp = FALSE;
}
else
{
MTP3_open_channel(TRUE);
MTP3_user_connect();
}
debuglog("Function MTP3_user_map finished");
}
//------------
//MTP3 user connect
void MTP3asp__PT_PROVIDER::MTP3_user_connect()
{
// Sending out an SLTM message:
unsigned char * sltm_msg;
unsigned int offset = 0;
int sizeof_msg;
switch( MTPServiceType)
{
case MTP3itu:
case MTP3iup:
sltm_msg=sltm_msg_itu;
sizeof_msg=sizeof_sltm_msg_itu;
break;
case MTP3ansi:
sltm_msg=sltm_msg_ansi;
sizeof_msg=sizeof_sltm_ansi;
break;
case MTP3ttc:
/* if (mtp3_ni == 0){
sltm_msg=sltm_msg_itu;
sizeof_msg=sizeof_sltm_msg_itu;
}
else {
*/
sltm_msg=sltm_msg_ttc_national;
sizeof_msg=sizeof_sltm_msg_ttc_national;
// }
break;
case MTP3bttc:
sltm_msg=sltm_msg_bttc_national;
sizeof_msg=sizeof_sltm_msg_bttc_national;
offset = 1;
break;
case MTP3mpt:
if (mtp3_ni == 2)
{
sltm_msg = sltm_msg_mpt_national;
sizeof_msg = sizeof_sltm_msg_mpt_national;
} else
{
sltm_msg = sltm_msg_itu;
sizeof_msg = sizeof_sltm_msg_itu;
}
break;
default:
sltm_msg=sltm_msg_itu;
sizeof_msg=sizeof_sltm_msg_itu;
break;
}
stored_bttc_octet = 0;
unsigned char sio = ((unsigned char) mtp3_ni) << 6;
if (Ni_is_set)
{ sltm_msg[0+offset] = sio | 0x1; }
else
{ sltm_msg[0+offset] = 0x1; };//SIO /'test & maint' see Q.704 /14.2.1 => 0x81 suggested !!!
SetPointCodes(0, Tester_Pc, Sut_Pc, sltm_msg + 1 +offset); // common for ITU, ANSI and TTC
log("MTP3/SLTM message sending...");
send_msg(sltm_msg, sizeof_msg);
}
//MTP3 user unmap
void MTP3asp__PT_PROVIDER::MTP3_user_unmap(const char *system_port)
{
MTP3_close_connection();
dynamicConnection = FALSE;
}
//MTP3 interpreter
void MTP3asp__PT_PROVIDER::MTP3_interpreter(unsigned char* inbuffer,int length,int from_channel,CONNECTION* con)
{
if ((length==0) || (inbuffer==NULL))
{
log("0 byte long message received -> packet dropped.");
return;
}
if (length==1)
{
log("1 byte long internal SEA message received -> packet dropped.");
return;
}
if ( !strcmp((const char*)inbuffer,"start") )
{
log("start message received from SEA");
return;
}
else if (!strcmp((const char*)inbuffer,"stop"))
{
log("stop message received from SEA");
return;
}
// writing out the contents of the buffer
OCTETSTRING buff(length,inbuffer);
TTCN_Logger::begin_event(TTCN_PORTEVENT);
TTCN_Logger::log_event("incoming buffer: ");
buff.log();
TTCN_Logger::end_event();
unsigned int offset = 0;
if ( MTPServiceType==MTP3bttc )
{
stored_bttc_octet = inbuffer[0];
offset = 1;
}
int labellen; // sio+routinglabel length
int rec_ni = (inbuffer[offset]) >> 6; //network indicator
if (rec_ni != mtp3_ni)
error("Received NI is different from sent NI.");
unsigned char sio = inbuffer[offset];
unsigned int si = sio&0x0F;
if ( MTPServiceType==MTP3itu )
{ labellen=5; //ITU-T:sio(1byte) + routing label(4byte) see /Q.704/15.4.1
}
else if ( MTPServiceType==MTP3iup )
{
if(si==4)
labellen=6; //ITU-T:sio(1byte) + standard telephony label(5byte)
else
labellen=5; //ITU-T:sio(1byte) + routing label(4byte) see /Q.704/15.4.1
}
else if ( MTPServiceType==MTP3ansi )
{ labellen=8; //ANSI: sio(1byte) +routing label(7byte) see T1.111.4
}
else if (MTPServiceType==MTP3ttc)
{ labellen=6; //new (2004-03-02): 6= sio(1byte)+ routing label(5bytes)
}
else if (MTPServiceType==MTP3mpt)
{
if ( mtp3_ni == 2)
{labellen=8;} //MPT national: sio(1byte) +routing label(7byte)
else
{labellen=5;} //MPT international: sio(1byte) +routing label(4byte)
}
else if (MTPServiceType==MTP3bttc)
{ labellen=7; //7= sio(1byte)+ routing label(6bytes)
}
else
{ log("incorrect MTPServiceType - programming error-> packet dropped");
return;
}
// checking SIO field (first incoming byte) - management or test message
switch (si)
{
case 0: processing_MTP3_management_msg(inbuffer+offset,length-offset);
return;
case 1: //MTP3itu
case 2: processing_MTP3_test_msg(inbuffer+offset,length-offset); //MTP3ansi
return;
default:
break;
}
// filling up TTCN structure
if ((Loop==MTP3_ON) || (!Filter) || (Filter&&Check_PcMatch(Sut_Pc,Tester_Pc,&inbuffer[offset+1])))
{
ASP__MTP3__TRANSFERind recv_msg;
MTP3__Field__sio recv_sio;
BITSTRING sio_bit = oct2bit(OCTETSTRING(1,inbuffer+offset));
recv_sio.ni()= substr(sio_bit,0,2);
recv_sio.prio()= substr(sio_bit,2,2);
recv_sio.si()= substr(sio_bit,4,4);
recv_msg.sio() = recv_sio;
unsigned int sls,opc,dpc;
if ( (MTPServiceType==MTP3iup) && (si==4) )
GetPointCodesIUP(sls,opc,dpc,&inbuffer[1]);
else
GetPointCodes(sls,opc,dpc,&inbuffer[offset+1]);
recv_msg.sls() = sls;
recv_msg.opc() = opc;
recv_msg.dpc() = dpc;
int len;
len= length-labellen-offset; //len= length-labellen;
recv_msg.data() = OCTETSTRING(len, &inbuffer[offset+labellen]);
incoming_message( recv_msg );
}
else
{ log("The rooting label (OPC, DPC) not matched with the filter setting -> packet dropped.");
return;
}
}
void MTP3asp__PT_PROVIDER::processing_MTP3_management_msg(unsigned char* inbuff,int len)
{
int outlen=0;
int labellen; // sio+routinglabel length
int chm_addlen; // (Changeback) additional length = Heading Code + SLC+ (changeback codes)
int mim_addlen; // (MIM) -"-
unsigned int offset = 0;
OCTETSTRING bttc_oct = int2oct(stored_bttc_octet, 1); // additional octet for MTP3bttc
if ( MTPServiceType==MTP3itu || MTPServiceType==MTP3iup)
{ labellen=5; //ITU-T:sio(1byte) + routing label(4byte) see /Q.704/15.4.1
chm_addlen = 2;
mim_addlen = 1;
}
else if ( MTPServiceType==MTP3ansi )
{ labellen=8; //ANSI: sio(1byte) +routing label(7byte) see T.1.111.4
chm_addlen = 3;
mim_addlen = 2;
}
else if (MTPServiceType==MTP3ttc)
{ //if ( mtp3_ni == 0 ) { labellen=5;} //ITU-T:sio(1byte) + routing label(4byte) see /Q.704/15.4.1
//else {
labellen=6;
//} //sio(1byte)+ routing label(6bytes) see 3/15517-FAY 112 011/2 or jt-q704.
}
else if (MTPServiceType==MTP3mpt)
{ if ( mtp3_ni == 2 ) { labellen=8; }
else { labellen=5; }
chm_addlen = 2;
mim_addlen = 1;
}
else if (MTPServiceType==MTP3bttc)
{ labellen=7;//sio(1byte)+routing label(6bytes) see 3/15517-FAY 112 011/2 or jt-q704
offset = 1;
}
else
{ log("incorrect MTPServiceType- programming error-> packet dropped");
return;
}
if (MTPServiceType==MTP3bttc)
{
buffer[0]=*((const unsigned char*)bttc_oct); //additional stored octet in front
buffer[1]=inbuff[0]; //SIO
if (!ChangePointCodes(&buffer[2],&inbuff[1],len))
{ log("incorrect incoming management message -> packet dropped.");
return;
}
}
else
{
buffer[0]=inbuff[0]; //SIO
if (!ChangePointCodes(&buffer[1],&inbuff[1],len))
{ log("incorrect incoming management message -> packet dropped.");
return;
}
}
// Changeover & changeback(CHM) see ITU: Q.704/15.4.1 ANSI: T.1.111.4/15.2-4
if (inbuff[labellen]==0x51) //CBD
{
outlen=labellen+chm_addlen;
if (len<outlen)
{ log("incorrect incoming CHM message -> packet dropped.");
return;
}
else
{ buffer[offset + labellen]= 0x61; // Heading Code <- CBA
memcpy(&buffer[offset + labellen+1],&inbuff[labellen+1],len-labellen-1);
outlen = len;
}
}
else if (inbuff[labellen]==0x16) //MIM H0=6=Mgmt inhibit msg, H1=1=LIN
{
outlen=labellen+mim_addlen;
if (len<outlen)
{ log("incorrect incoming MIM message -> packet dropped.");
return;
}
else
{
buffer[offset + labellen]= 0x56; // LIN -> LID ; LID = link inhibit denied
memcpy(&buffer[offset + labellen+1],&inbuff[labellen+1],(len-labellen-1)); //SLC+spare+...
outlen = len;
}
}
else if (inbuff[labellen]==0x17 && (MTPServiceType==MTP3iup))
{
if(forward_resume) incoming_message(ASP__MTP3__RESUME(NULL_VALUE));
return;
}
/* else if (inbuff[labellen]==0x17 && (MTPServiceType==MTP3iup)) //TRM H0=7, H1=1 : TRA
{
outlen=labellen+1;
if (len<outlen)
{ log("incorrect incoming TRA message -> packet dropped.");
return;
}
else
{
outlen = len;
}
}*/
else
{ log("This management message type is not supported -> packet dropped.");
return;
}
// send message
log("function processing_MTP3_management_msg sends a msg");
send_msg(buffer, outlen+offset);
}
// processing MTP3 test msg
// Signalling link test message handling according to Q.707 (ITU) and T1.111.7-2001 (ANSI)
void MTP3asp__PT_PROVIDER::processing_MTP3_test_msg(unsigned char* inbuff,int len)
{
int outlen=0;
int labellen; // sio+routinglabel length
int addlen; //Heading Code+length indicator
//unsigned int ni; //network indicator
OCTETSTRING bttc_oct = int2oct(stored_bttc_octet, 1); // additional octet for MTP3bttc
unsigned int offset = 0;
if ( MTPServiceType==MTP3itu || MTPServiceType==MTP3iup)
{
labellen=5; //ITU-T:sio(1byte) + routing label(4byte) see /Q.704/15.4.1
addlen = 2; //HC(1 byte)+length ind(1 byte) see Q.707/5.8
}
else if ( MTPServiceType==MTP3ansi )
{
labellen=8; //ANSI: sio(1byte) +routing label(7byte) see T1.111.4
addlen = 2; //HC(1byte) +(length ind+SLC(1byte)) see T1.111.7-2001/5
}
else if (MTPServiceType==MTP3ttc)
{
/* if (mtp3_ni == 0) {
debuglog("processing_MTP3_test_msg/TTC (Japanese) international");
labellen=5; //TTC (Japanese) international
addlen=2;
} else {
*/
labellen=6; // previously 7
// TTC national [ 56bits=sio(1byte)+routing label ]
// r.label= dpc(2bytes)+opc(2bytes)+sls(4bit)+12bits (?)
addlen=2;
//}
}
else if (MTPServiceType==MTP3mpt)
{
if (mtp3_ni == 2)
{ labellen=8; //MPT national
addlen=2;
}
else
{ labellen=5; // MPT international
addlen=2;
}
}
else if (MTPServiceType==MTP3bttc)
{
labellen=7;
addlen=2;
offset = 1;
}
else
{ log("incorrect MTPServiceType - programming error-> packet dropped");
return;
}
if (MTPServiceType==MTP3bttc)
{
buffer[0]=*((const unsigned char*)bttc_oct); //additional stored octet in front
buffer[1]=inbuff[0]; //SIO
if (!ChangePointCodes(&buffer[2],&inbuff[1],len))
{
log("incorrect incoming test message -> packet dropped.");
return;
}
}
else
{
buffer[0]=inbuff[0]; //SIO
if (!ChangePointCodes(&buffer[1],&inbuff[1],len))
{
log("incorrect incoming test message -> packet dropped.");
return;
}
}
// Test message handling: SLTM->SLTA, SRT->SRA, SLTA->TRA, others only logged
debuglog("\n==>Test message handling: msg type:%x\n", inbuff[labellen] ); // temporary
switch( inbuff[labellen] )
{
case 0x11: //SLTM
log("MTP3/SLTM message received");
outlen=labellen+addlen;
if (len<outlen )
{ log("incorrect incoming MTP3/SLTM message -> packet dropped.");
return;
}
else
{ buffer[offset + labellen]= 0x21; // SLTA
memcpy(&buffer[offset + labellen+1],&inbuff[labellen+1],(len-labellen-1));
outlen = len;
}
break;
case 0x21: //SLTA
if(!strncmp((const char *)(inbuff+labellen+addlen),(const char *)ttcn_in_sltm,sizeof_ttcn_in_sltm))
{
log("MTP3/SLTA message received for SLTM sent by Test Port-> TRA message sent");
buffer[offset]--;
buffer[offset + labellen]= 0x17; // TRA
outlen = labellen+1;
return;
// if(forward_resume) incoming_message(ASP__MTP3__RESUME(NULL_VALUE));
}
else
{
log("MTP3/SLTA message received -> packet dropped");
return;
}
break;
case 0x23: // TTC (Japanese) SRT (Signalling Routing Test signal)
log("MTP3ttc/SRT message received");
outlen=labellen+addlen;
if (len<outlen )
{ log("incorrect incoming MTP3ttc/SRT message (length error)-> packet dropped.");
return;
}
else
{ buffer[offset + labellen]= 0x84; // TTC (Japanese) SRA
memcpy(&buffer[offset + labellen+1],&inbuff[labellen+1],(len-labellen-1));
outlen = len;
}
break;
case 0x84: // TTC (Japanese) SRA (Signalling Routing test Ack signal)
log("MTP3ttc/SRA message received -> packet dropped");
return;
default:
log("This management message type is not supported -> packet dropped ");
return;
}
// send message
log("function processing_MTP3_test_msg sends a message");
send_msg( buffer,outlen+offset);
}
// Point Code Manipulation (Get/Set/Change)
// -------------------------------------------------
void MTP3asp__PT_PROVIDER::GetPointCodes(unsigned int &sls,unsigned int &opc,unsigned int &dpc, unsigned char* msg)
{
unsigned int label;
sls=0; opc=0; dpc=0;
unsigned long long int Label;
switch( MTPServiceType)
{
case MTP3itu:
label= decode_32bLSB_int(msg);
sls = (label>>28)&0xF; //sls = (label&0xF0000000)>>28;
opc = (label>>14)&0x3FFF; //opc = (label&0x0FFFC000)>>14;
dpc = label&0x3FFF; //dpc = (label&0x00003FFF);
debuglog("Function GetPointCodes called for service type MTP3itu");
break;
case MTP3iup:
label= decode_32bLSB_int(msg);
sls = (label>>28)&0xF; //sls = (label&0xF0000000)>>28;
opc = (label>>14)&0x3FFF; //opc = (label&0x0FFFC000)>>14;
dpc = label&0x3FFF; //dpc = (label&0x00003FFF);
debuglog("Function GetPointCodes called for service type MTP3iup");
break;
case MTP3ansi:
Label=decode_56bLSB_int(msg);
sls = (Label >> 48) & 0xFF; //sls = (Label&0x00FF000000000000)>>48;
opc = (Label >> 24) & 0xFFFFFF;//opc = (Label&0x0000FFFFFF000000)>>24;
dpc = Label & 0xFFFFFF; //dpc = (Label&0x0000000000FFFFFF);
debuglog("Function GetPointCodes called for service type MTP3ansi");
break;
case MTP3ttc:
/*
if( mtp3_ni == 0)
{
label= decode_32bLSB_int(msg);
sls = (label>>28)&0xF; //sls = (label&0xF0000000)>>28;
opc = (label>>14)&0x3FFF; //opc = (label&0x0FFFC000)>>14;
dpc = label&0x3FFF;
debuglog("Function GetPointCodes called for service type MTP3ttc/international");
} else
{*/
Label=decode_48bLSB_int(msg); //0x010203040506
sls = (Label>>32)&0xF; // sls = (Label&0x000F00000000)>>32; // only 4 bits!!!
opc = (Label>>16)&0xFFFF;//opc = (Label&0x0000FFFF0000)>>16;
dpc = Label&0xFFFF; //dpc = (Label&0x00000000FFFF);
debuglog("Function GetPointCodes called for service type MTP3ttc/national");
//}
break;
case MTP3bttc:
Label=decode_48bLSB_int(msg);
sls = (Label>>32)&0xF; // sls = (Label&0x000F00000000)>>32; // only 4 bits!!!
opc = (Label>>16)&0xFFFF;//opc = (Label&0x0000FFFF0000)>>16;
dpc = Label&0xFFFF; //dpc = (Label&0x00000000FFFF);
debuglog("Function GetPointCodes called for service type MTP3bttc/national");
break;
case MTP3mpt:
if( mtp3_ni == 2)
{
Label=decode_56bLSB_int(msg);
sls = (Label >> 48) & 0xFF; //sls = (Label&0x00FF000000000000)>>48;
opc = (Label >> 24) & 0xFFFFFF;//opc = (Label&0x0000FFFFFF000000)>>24;
dpc = Label & 0xFFFFFF; //dpc = (Label&0x0000000000FFFFFF);
debuglog("Function GetPointCodes called for service type MTP3mpt(nat)");
}
else
{
label= decode_32bLSB_int(msg);
sls = (label>>28)&0xF; //sls = (label&0xF0000000)>>28;
opc = (label>>14)&0x3FFF; //opc = (label&0x0FFFC000)>>14;
dpc = label&0x3FFF; //dpc = (label&0x00003FFF);
debuglog("Function GetPointCodes called for service type MTP3mpt(int)");
}
break;
default:
break;
}
debuglog("sls:%u opc:%u, dpc:%u",sls,opc,dpc);
}
//------------
void MTP3asp__PT_PROVIDER::GetPointCodesIUP(unsigned int &cic,unsigned int &opc,unsigned int &dpc, unsigned char* msg)
{
debuglog("Function GetPointCodesIUP called");
cic=0; opc=0; dpc=0;
unsigned long long int Label;
Label=decode_40bLSB_int(msg); //0x0102030405
cic = (Label>>28)&0xFFF; //cic = (label&0xFFF0000000)>>28;
opc = (Label>>14)&0x3FFF; //opc = (label&0x000FFFC000)>>14;
dpc = Label&0x3FFF; //dpc = (label&0x0000003FFF);
debuglog("cic:%u opc:%u, dpc:%u",cic,opc,dpc);
}
void MTP3asp__PT_PROVIDER::SetPointCodes(unsigned int sls,unsigned int opc,unsigned int dpc, unsigned char* msg)
{
unsigned long long int Sls,Opc,Dpc;
switch( MTPServiceType)
{
case MTP3itu:
encode_32bLSB_int( msg, ((sls<<28)|(opc<<14)|dpc ));
debuglog("Function SetPointCodes called for service type MTP3itu");
break;
case MTP3iup:
encode_32bLSB_int( msg, ((sls<<28)|(opc<<14)|dpc ));
debuglog("Function SetPointCodes called for service type MTP3iup");
break;
case MTP3ansi:
Sls=sls; Opc=opc; Dpc=dpc;
encode_56bLSB_int( msg, ((Sls<<48)|(Opc<<24)|Dpc));
debuglog("Function SetPointCodes called for service type MTP3ansi");
break;
case MTP3ttc:
/* if ( mtp3_ni == 0 ){
encode_32bLSB_int( msg, ((sls<<28)|(opc<<14)|dpc ));
debuglog("Function SetPointCodes called for service type MTP3ttc/international");
} else {
*/
Sls=sls; Opc=opc; Dpc=dpc;
encode_48bLSB_int( msg, ((Sls<<32)|(Opc<<16)|Dpc));
debuglog("Function SetPointCodes called for service type MTP3ttc/national");
//}
break;
case MTP3bttc:
Sls=sls; Opc=opc; Dpc=dpc;
encode_48bLSB_int( msg, ((Sls<<32)|(Opc<<16)|Dpc));
debuglog("Function SetPointCodes called for service type MTP3bttc/national");
break;
case MTP3mpt:
if ( mtp3_ni == 2 )
{ Sls=sls; Opc=opc; Dpc=dpc;
encode_56bLSB_int( msg, ((Sls<<48)|(Opc<<24)|Dpc));
debuglog("Function SetPointCodes called for service type MTP3mpt(nat)");
}
else
{ encode_32bLSB_int( msg, ((sls<<28)|(opc<<14)|dpc ));
debuglog("Function SetPointCodes called for service type MTP3mpt(int)");
}
break;
default:
break;
}
}
//------------
void MTP3asp__PT_PROVIDER::SetPointCodesIUP(unsigned int cic,unsigned int opc,unsigned int dpc, unsigned char* msg)
{
unsigned long long int Cic,Opc,Dpc;
Cic=cic; Opc=opc; Dpc=dpc;
debuglog("Function SetPointCodesIUP called");
encode_40bLSB_int( msg, ((Cic<<28)|(Opc<<14)|Dpc ));
}
//Changes the Point codes: dpc<->opc ie. destination <->orig
// inbuff starts from dpc i.e doesn't contain sio !!!!
int MTP3asp__PT_PROVIDER::ChangePointCodes(unsigned char* outbuff, unsigned char *inbuff, int len)
{
switch( MTPServiceType)
{
case MTP3itu:
case MTP3iup:
if (len<5)
{ warn("MTP3itu:len<5. Too short message!"); return 0; };
break;
case MTP3ansi:
if (len<9 ) return 0;
break;
case MTP3ttc:
//if ( mtp3_ni == 0 && len<5)
//{ warn("MTP3ttc:len<5. Too short message!"); return 0; }
//else
if (len<6)
{ warn("MTP3ttc:len<6. Too short message!"); return 0; }
break;
case MTP3bttc:
if (len<7)
{ warn("MTP3bttc:len<7. Too short message!"); return 0; }
break;
case MTP3mpt:
if ( mtp3_ni == 2 && len<8)
{ warn("MTP3mpt:len<8. Too short message!"); return 0; }
else if (len<5)
{ warn("MTP3mpt:len<5. Too short message!"); return 0; }
break;
default:
warn("Unknown MTPServiceType!!!");
break;
}
unsigned int sls,opc,dpc;
GetPointCodes(sls,opc,dpc,inbuff);
SetPointCodes(sls,dpc,opc,outbuff);
return 1;
}
//------------
int MTP3asp__PT_PROVIDER::Check_PcMatch(unsigned int opc, unsigned int dpc, unsigned char *buff)
{
unsigned int temp_opc,temp_dpc,temp_sls;
GetPointCodes(temp_sls,temp_opc,temp_dpc,buff);
if ( (temp_opc == opc) && (temp_dpc == dpc) ) return 1;
return 0;
}
//------------
// -------------------------------------------------
// M3UA Functions and definitions for test with SEA
// -------------------------------------------------
// Structures for M3UA
static unsigned char aspup_msg[] =
{
//common MsUA msg hdr, see M3UA PS
//Doc no. 1/1056-FCP 103 3571/F Uen, RevA
0x01, //Release Version
0x00, //reserved
M3UA_MSG_CLS_ASPSM, //Msg class: ASPSM
M3UA_MSG_TYP_ASPSM_ASPUP, //Msg type: ASPUP
0x00, //Msg length begins (4 octets)
0x00, //
0x00, //
0x08 // length ends = 8 octets
// ,PAR_PREFIX_COMMON, //optional Info string tag, in included, then msg
// PAR_INFO_STR //msg length should be +20, that is 28=0x1c
// 0x00,0x0f, // length: "TTCN-3 Executor" is 15 chars
// 'T', 'T', 'C', 'N',
// '-', '3', ' ', 'E',
// 'x', 'e', 'c', 'u',
// 't', 'o', 'r', 0x00 //las octet is padding
};
const int sizeof_aspup_msg = 8;
static unsigned char aspupack_msg[] =
{
//common MsUA msg hdr, see M3UA PS
//Doc no. 1/1056-FCP 103 3571/F Uen, RevA
0x01, //Release Version
0x00, //reserved
M3UA_MSG_CLS_ASPSM, //Msg class: ASPSM
M3UA_MSG_TYP_ASPSM_ASPUPAck, //Msg type: ASPUP
0x00, //Msg length begins (4 octets)
0x00, //
0x00, //
0x08 // length ends = 8 octets
};
const int sizeof_aspupack_msg = 8;
static unsigned char aspac_msg[] =
{
//common MsUA msg hdr, see M3UA PS
//Doc no. 1/1056-FCP 103 3571/F Uen, RevA
0x01, //Release Version: 01
0x00, //reserved
M3UA_MSG_CLS_ASPTM, //Msg class
M3UA_MSG_TYP_ASPTM_ASPAC, //Msg type
0x00, //Msg length begins (4 octets)
0x00, //
0x00, //
0x08 // length ends = 8 octets
};
const int sizeof_aspac_msg = 8;
// ASP Active Acknowledge msg:
static unsigned char aspac_ack_msg[] =
{
//common MsUA msg hdr, see M3UA PS
//Doc no. 1/1056-FCP 103 3571/F Uen, RevA
0x01, //Release Version: 01
0x00, //reserved
M3UA_MSG_CLS_ASPTM, //Msg class
M3UA_MSG_TYP_ASPTM_ASPACAck, //Msg type
0x00, //Msg length begins (4 octets)
0x00, //
0x00, //
0x08 // length ends = 8 octets
};
const int sizeof_aspac_ack_msg = 8;
static unsigned char aspia_ack_msg[] =
{
//common MsUA msg hdr, see M3UA PS
//Doc no. 1/1056-FCP 103 3571/F Uen, RevA
0x01, //Release Version: 01
0x00, //reserved
M3UA_MSG_CLS_ASPTM, //Msg class
M3UA_MSG_TYP_ASPTM_ASPIAAck, //Msg type
0x00, //Msg length begins (4 octets)
0x00, //
0x00, //
0x08 // length ends = 8 octets
};
const int sizeof_aspia_ack_msg = 8;
// ASP DOWN Acknowledge msg:
static unsigned char aspdn_ack_msg[] =
{
//common MsUA msg hdr, see M3UA PS
//Doc no. 1/1056-FCP 103 3571/F Uen, RevA
0x01, //Release Version: 01
0x00, //reserved
M3UA_MSG_CLS_ASPSM, //Msg class
M3UA_MSG_TYP_ASPSM_ASPDNAck, //Msg type
0x00, //Msg length begins (4 octets)
0x00, //
0x00, //
0x08 // length ends = 8 octets
};
const int sizeof_aspdn_ack_msg = 8;
//ASP Destination Available msg:
static unsigned char dava_1apc_msg[] =
{
//common MsUA msg hdr, see M3UA PS
//Doc no. 1/1056-FCP 103 3571/F Uen, RevA
//or updated doc 2/1056-FCPW 101 86/P-1
0x01, //Release Version: 01
0x00, //reserved
M3UA_MSG_CLS_SSNM, //Msg class
M3UA_MSG_TYP_SSNM_DAVA, //Msg type
0x00, //Msg length begins (4 octets)
0x00, //
0x00, //
0x10, // length ends, 16 octets
//Affected point code
PAR_PREFIX_COMMON,
PAR_AFFECTED_PC,
0x00, //par length begins (2 octets)
0x08, //length ends, 8 octets
0x00, // point code placeholder begins
0x00, //
0x00, //
0x00 // point code placeholder ends
};
const int sizeof_dava_1apc_msg = 16;
static unsigned char duna_1apc_msg[] =
{
//common MsUA msg hdr, see M3UA PS
//Doc no. 1/1056-FCP 103 3571/F Uen, RevA
0x01, //Release Version: 01
0x00, //reserved
M3UA_MSG_CLS_SSNM, //Msg class
M3UA_MSG_TYP_SSNM_DUNA, //Msg type
0x00, //Msg length begins (4 octets)
0x00, //
0x00, //
0x10, // length ends, 16 octets
//Affected point code
PAR_PREFIX_COMMON,
PAR_AFFECTED_PC,
0x00, //par length begins (2 octets)
0x08, //length ends, 8 octets
0x00, // point code placeholder begins
0x00, //
0x00, //
0x00 // point code placeholder ends
};
const int sizeof_duna_1apc_msg = 16;
static unsigned char error_msg[] =
{
//common MsUA msg hdr, see M3UA PS
//Doc no. 1/1056-FCP 103 3571/F Uen, RevA
0x01, //Release Version: 01
0x00, //reserved
M3UA_MSG_CLS_MGMT, //Msg class
M3UA_MSG_TYP_MGMT_ERR, //Msg type
0x00, //Msg length begins (4 octets)
0x00, //
0x00, //
0x18, // length ends, 16+8 octets
// Error code field:
PAR_PREFIX_COMMON,
PAR_ERROR_CODE,
0x00, //par length begins (2 octets)
0x08, //length ends, 8 octets
0x00, // error code placeholder begins (M3UA_MSG_OFFS+4)
0x00, //
0x00, //
0x00, // error code placeholder ends
// additional field:
0x00, // M3UA_MSG_OFFS+8
0x00, // Routing context or Network Appearanance or APC or DI = error_code_id
0x00, // par length begins (2 octets)
0x08, // length ends, 8 octets
0x00, // value placeholder begins M3UA_MSG_OFFS+12
0x00, //
0x00, //
0x00 // value place holder ends
};
const int sizeof_error_msg = 24;
void MTP3asp__PT_PROVIDER::M3UA_user_unmap(const char *system_port)
{
MTP3_close_connection();
dynamicConnection = FALSE;
}
//------------
void MTP3asp__PT_PROVIDER::M3UA_user_map(const char *system_port)
{
M3UAState = AssocDown;
Check_TestPort_Variables();
if(dynamicConnection)
{
connectionUp = FALSE;
}
else
{
MTP3_open_channel(TRUE);
M3UA_user_connect();
}
}
//------------
void MTP3asp__PT_PROVIDER::M3UA_user_connect()
{
M3UAState = AssocEstabl;
// Sending out an ASPUP message
log("Message ASPUP will be sent");
send_msg(aspup_msg, sizeof_aspup_msg);
// NOTE: the ASPUPAck will be handled by M3UA_interpreter, which
// also will take care of sending ASPAC upon receiving the ASPUPAck
}
//------------
// M3UA_interpreter
void MTP3asp__PT_PROVIDER::M3UA_interpreter(unsigned char* inbuffer,int length,int from_channel,CONNECTION* con)
{
if ((length==0) || (inbuffer==NULL))
{ warn("0 byte long message received -> packet dropped.");
return;
}
if (length==1)
{
log("1 byte long internal SEA message received -> packet dropped.");
return;
}
if ( !strcmp((const char*)inbuffer,"start") )
{ log("start message received from SEA");
return;
}
else if (!strcmp((const char*)inbuffer,"stop"))
{ log("stop message received from SEA");
return;
}
// writing out the contents of the buffer
OCTETSTRING buff(length,inbuffer);
TTCN_Logger::begin_event(TTCN_PORTEVENT);
TTCN_Logger::log_event("incoming buffer: ");
buff.log();
TTCN_Logger::end_event();
// version checking
if ( inbuffer[M3UA_VER_OFFS] != M3UA_version )
{ warn("Incompatible M3UA protocol version in header -> packet dropped");
return;
}
//length checking
unsigned int indicated_length = decode_32b_int(inbuffer + M3UA_LGT_OFFS );
if ( indicated_length != (unsigned)length)
warn("Length in common header (%d) mismatches received buffer length (%d),"
"Assuming that it is because of the omission of final parameter padding"
"in indicated length",indicated_length, length);
// checking MSG class
int unprocessed_chars = 0;
switch (inbuffer[M3UA_CLS_OFFS])
{
case M3UA_MSG_CLS_MGMT:
unprocessed_chars = processing_M3UA_MGMT_msg(inbuffer, length);
break;
case M3UA_MSG_CLS_TRNSFM :
unprocessed_chars = processing_M3UA_Transfer_msg(inbuffer, length);
break;
case M3UA_MSG_CLS_SSNM :
unprocessed_chars = processing_M3UA_SSNM_msg(inbuffer, length);
break;
case M3UA_MSG_CLS_ASPSM :
unprocessed_chars = processing_M3UA_ASPSM_msg(inbuffer, length);
break;
case M3UA_MSG_CLS_ASPTM :
unprocessed_chars = processing_M3UA_ASPTM_msg(inbuffer, length);
break;
case M3UA_MSG_CLS_RKM :
unprocessed_chars = processing_M3UA_RKM_msg(inbuffer, length);
break;
default:
unprocessed_chars = processing_M3UA_unsupported_msg_class(inbuffer, length);
break;
}
debuglog("%d chars remained unprocessed (might be due to padding)", unprocessed_chars);
}
//------------
//processing M3UA MGMT msg
int MTP3asp__PT_PROVIDER::processing_M3UA_MGMT_msg(unsigned char* inbuffer,int length)
{
debuglog("Entering function:processing_MGMT_msg");
int offset = M3UA_MSG_OFFS; //pointer for processing
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("MTP3 Test Port (%s): {", get_name());
TTCN_Logger::log_event("decoded msg class: Mgmt, ");
switch (inbuffer[M3UA_TYP_OFFS])//msg type
{
case M3UA_MSG_TYP_MGMT_ERR:
TTCN_Logger::log_event("type: ERROR-> ignored");
TTCN_Logger::log_event("}");
TTCN_Logger::end_event();
break;
case M3UA_MSG_TYP_MGMT_NTFY:
TTCN_Logger::log_event("type: NOTIFY -> ignored");
TTCN_Logger::log_event("}");
TTCN_Logger::end_event();
break;
default:
send_M3UA_error_msg( PAR_ERRC_UNSMT, inbuffer[M3UA_TYP_OFFS]);
TTCN_Logger::log_event("Unsupported M3UA msg type %x of class MGMT -> packet dropped.", inbuffer[M3UA_TYP_OFFS]);
TTCN_Logger::log_event("}");
TTCN_Logger::end_event();
break;
}
return length - offset;
}
//------------
//processing M3UA SSNM msg
int MTP3asp__PT_PROVIDER::processing_M3UA_SSNM_msg(unsigned char* inbuffer,int length)
{
debuglog("Entering function:processing_SSNM_msg");
TTCN_Logger::begin_event(TTCN_PORTEVENT);
TTCN_Logger::log_event("MTP3 Test Port (%s): {", get_name());
TTCN_Logger::log_event("decoded msg class: SSNM, ");
int offset = M3UA_MSG_OFFS; //pointer for processing
switch (inbuffer[M3UA_TYP_OFFS])
{
case M3UA_MSG_TYP_SSNM_DAUD:
while (offset <= length-8 ) //processing potential params
{
switch (inbuffer[offset++]) //1st octet of tag
{
case PAR_PREFIX_COMMON:
TTCN_Logger::log_event (" DAUD: COMMON parameter ");
switch (inbuffer[offset++]) //2nd octet of COMMON tag
{
case PAR_ROUTING_CTX:
TTCN_Logger::log_event ("Routing Context (unsupported par) -> skipped), ");
skip_par_after_tag(inbuffer, offset);
break;
case PAR_INFO_STR:
TTCN_Logger::log_event ("Info String (unsupported par) -> skipped), ");
skip_par_after_tag(inbuffer, offset);
break;
case PAR_AFFECTED_PC:
TTCN_Logger::log_event ("Affected Point Code -> will send DUNA/DAVA, ");
TTCN_Logger::log_event("will ignore remainder parameters after APC}");
TTCN_Logger::end_event();
Send_DAVA_DUNA_to_APCinDAUD(Tester_Pc, inbuffer, offset);
return length-offset;
default:
TTCN_Logger::log_event ("invalid COMMON param tag:0x%02x%02x-> skipped", PAR_PREFIX_COMMON, inbuffer[offset-1]);
send_M3UA_error_msg( PAR_ERRC_PARFE, inbuffer[offset-1]);
skip_par_after_tag(inbuffer, offset);
break;
}
break;
case PAR_PREFIX_M3UA:
TTCN_Logger::log_event ("DAUD: M3UA parameter: ");
switch (inbuffer[offset++]) //2nd octet of M3UA tag
{
case PAR_NETW_APP:
TTCN_Logger::log_event ("Network Appearance (unsupported par) -> skipped), ");
skip_par_after_tag(inbuffer, offset);
break;
default:
TTCN_Logger::log_event ("invalid M3UA param tag:0x%02x%02x-> skipped",
PAR_PREFIX_M3UA, inbuffer[offset-1]);
send_M3UA_error_msg( PAR_ERRC_PARFE, inbuffer[offset-1]);
skip_par_after_tag(inbuffer, offset);
}
break;
default: //1st octet of tag
TTCN_Logger::log_event ("invalid 1st octet param tag:0x%02x in DATA (packet dropped)",inbuffer[offset-1]);
close_log_event();
return length -offset;
break;
}
}
break;
case M3UA_MSG_TYP_SSNM_DAVA: // Destination Available // Notification to the user part ?????
TTCN_Logger::log_event("type: SSNM_DAVA -> ignored");
close_log_event();
break;
case M3UA_MSG_TYP_SSNM_DUNA: // Destination Unavailable // Notification to the user part ?????
TTCN_Logger::log_event("type: SSNM_DUNA -> ignored");
close_log_event();
break;
case M3UA_MSG_TYP_SSNM_SCON: // Signalling Congestion // Notification to the user part ?????
TTCN_Logger::log_event("type: SSNM_SCON -> ignored");
close_log_event();
break;
case M3UA_MSG_TYP_SSNM_DUPU: //Destinationn User Part Unavailable // Notification to the user part ?????
TTCN_Logger::log_event("type: SSNM_DUPU -> ignored");
close_log_event();
break;
case M3UA_MSG_TYP_SSNM_DRST: //Destination Restricted // Notification to the user part ?????
TTCN_Logger::log_event("type: SSNM_DRST -> ignored");
close_log_event();
break;
default: //msg type
send_M3UA_error_msg( PAR_ERRC_UNSMT, inbuffer[M3UA_TYP_OFFS]);
TTCN_Logger::log_event("Unsupported M3UA msg type -> packet dropped.");
close_log_event();
break;
}
return length - offset;
}
//------------
//processing M3UA ASPSM msg
int MTP3asp__PT_PROVIDER::processing_M3UA_ASPSM_msg(unsigned char* inbuffer,int length)
{
debuglog("Entering function:processing_ASPSM_msg");
TTCN_Logger::begin_event(TTCN_PORTEVENT);
TTCN_Logger::log_event("MTP3 Test Port (%s): {", get_name());
TTCN_Logger::log_event("decoded msg class: ASPSM, ");
int offset = M3UA_MSG_OFFS; //pointer for processing
switch (inbuffer[M3UA_TYP_OFFS])
{
case M3UA_MSG_TYP_ASPSM_ASPUP:
TTCN_Logger::log_event("type: ASPSM_ASPUP -> ASPUPAck will be sent");
close_log_event();
send_msg(aspupack_msg, sizeof_aspupack_msg);
break;
case M3UA_MSG_TYP_ASPSM_ASPDN:
TTCN_Logger::log_event("type: ASPSM_ASPDN -> ASPDNAck will be sent");
close_log_event();
send_msg(aspdn_ack_msg, sizeof_aspdn_ack_msg);
break;
case M3UA_MSG_TYP_ASPSM_BEAT:
TTCN_Logger::log_event("type: ASPSM_BEAT -> ASPSM_BEATAck will be sent");
close_log_event();
//Sending back the packet as acknowledge:
inbuffer[M3UA_TYP_OFFS]= M3UA_MSG_TYP_ASPSM_BEATAck;
send_msg(inbuffer, length);
break;
case M3UA_MSG_TYP_ASPSM_ASPUPAck:
TTCN_Logger::log_event("type: ASPSM_ASPUPAck -> ASPAC will be sent");
M3UAState = AssocInac;
TTCN_Logger::log_event(" M3UAState's been changed to AssocInac");
close_log_event();
send_msg(aspac_msg, sizeof_aspac_msg );
break;
case M3UA_MSG_TYP_ASPSM_ASPDNAck:
M3UAState = AssocDown;
TTCN_Logger::log_event(" M3UAState's been changed to AssocDown");
TTCN_Logger::log_event("type: ASPSM_ASPDNAck -> nothing will be sent");
close_log_event();
break;
case M3UA_MSG_TYP_ASPSM_BEATAck:
TTCN_Logger::log_event("type: ASPSM_BEATAck -> nothing will be sent");
close_log_event();
break;
default:
TTCN_Logger::log_event("Unsupported M3UA msg type %x of class ASPSM-> packet dropped.", (unsigned char)(inbuffer[M3UA_TYP_OFFS]));
close_log_event();
send_M3UA_error_msg( PAR_ERRC_UNSMT, inbuffer[M3UA_TYP_OFFS]);
break;
}
return length - offset;
}
//------------
//processing M3UA ASPTM msg
int MTP3asp__PT_PROVIDER::processing_M3UA_ASPTM_msg(unsigned char* inbuffer,int length)
{
debuglog("Entering function:processing_ASPTM_msg");
TTCN_Logger::begin_event(TTCN_PORTEVENT);
TTCN_Logger::log_event("MTP3 Test Port (%s): {", get_name());
TTCN_Logger::log_event("decoded msg class: ASPTM, ");
int offset = M3UA_MSG_OFFS; //pointer for processing
switch (inbuffer[M3UA_TYP_OFFS])
{
case M3UA_MSG_TYP_ASPTM_ASPAC: //ASP Active
M3UAState = AssocActive;
TTCN_Logger::log_event("type: ASPTM_ASPAC -> ASPACAck will be sent");
close_log_event();
send_msg(aspac_ack_msg, sizeof_aspac_ack_msg);
break;
case M3UA_MSG_TYP_ASPTM_ASPIA: //ASP InActive
TTCN_Logger::log_event("type: ASPTM_ASPIA -> ASPIAAck will be sent");
close_log_event();
send_msg(aspia_ack_msg, sizeof_aspia_ack_msg);
break;
case M3UA_MSG_TYP_ASPTM_ASPACAck:
M3UAState = AssocActive;
TTCN_Logger::log_event("type: ASPTM_ASPACAck -> nothing will be sent");
TTCN_Logger::log_event("M3UAState's been changed to AssocActive.");
close_log_event();
break;
case M3UA_MSG_TYP_ASPTM_ASPIAAck:
TTCN_Logger::log_event("type: ASPTM_ASPIAAck -> nothing will be sent");
close_log_event();
break;
default:
TTCN_Logger::log_event("Unsupported M3UA msg type %x of class ASPSM-> packet dropped.", (unsigned char)(inbuffer[M3UA_TYP_OFFS]));
close_log_event();
send_M3UA_error_msg( PAR_ERRC_UNSMT, inbuffer[M3UA_TYP_OFFS]);
break;
}
return length - offset;
}
//------------
//processing M3UA RKM msg
int MTP3asp__PT_PROVIDER::processing_M3UA_RKM_msg(unsigned char* inbuffer,int length)
{
debuglog("Entering function:processing_RKM_msg");
int offset = M3UA_MSG_OFFS; //pointer for processing
warn("Unsupported M3UA msg class M3UA_RKM -> packet dropped.");
return length - offset;
}
//------------
//processing M3UA unsupported msg class
int MTP3asp__PT_PROVIDER::processing_M3UA_unsupported_msg_class(unsigned char* inbuffer,int length)
{
warn("Unsupported M3UA msg class -> packet dropped.");
send_M3UA_error_msg( PAR_ERRC_UNSMC, inbuffer[M3UA_CLS_OFFS] );
int offset = M3UA_MSG_OFFS; //pointer for processing
return length - offset;
}
//------------
// processing_M3UA_Transfer_msg - called if the msg class is "Transfer" i.e M3UA_MSG_CLS_TRNSFM:
int MTP3asp__PT_PROVIDER::processing_M3UA_Transfer_msg(unsigned char* inbuffer,int length)
{
debuglog("Entering function:processing_M3UA_Transfer_msg");
int offset = M3UA_MSG_OFFS; //pointer for processing
unsigned int recv_opc, recv_dpc,recv_si, recv_ni, recv_mp,recv_sls =0;
int param_length = 0;
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("MTP3 Test Port (%s): {", get_name());
TTCN_Logger::log_event("decoded msg class: DataTrnsf, ");
switch (inbuffer[M3UA_TYP_OFFS]) //msg type
{
case M3UA_MSG_TYP_TRSNFM_DATA:
TTCN_Logger::log_event("msg type DATA, ");
while (offset <= length-8) //processing potential params
{
switch (inbuffer[offset++]) //1st octet of tag. Offset already incremented after the 'case' !
{
case PAR_PREFIX_COMMON:
TTCN_Logger::log_event (" DATA: COMMON parameter, ");
switch (inbuffer[offset++]) //2nd octet of tag
{
case PAR_ROUTING_CTX:
TTCN_Logger::log_event ("Routing Context (unsupported par) -> skipped), ");
// Send back an error msg
skip_par_after_tag(inbuffer, offset);
break;
case PAR_CORREL_ID:
TTCN_Logger::log_event ("Correlation ID (unsupported par) -> skipped), ");
skip_par_after_tag(inbuffer, offset);
break;
default:
TTCN_Logger::log_event ("invalid COMMON param tag:0x%02x%02x -> skipped", PAR_PREFIX_COMMON, inbuffer[offset-1]);
skip_par_after_tag(inbuffer, offset);
break;
}
case PAR_PREFIX_M3UA:
TTCN_Logger::log_event ("DATA: M3UA parameter: ");
switch (inbuffer[offset++]) //2nd octet of M3UA tag
{
case PAR_PROT_DATA:
//---------------------------------------------
TTCN_Logger::log_event ("Protocol Data");
// retrieving length
param_length = decode_16b_int(inbuffer+offset); offset+=2;
TTCN_Logger::log_event(", DATA: Length of Protocol Data parameter is %d",param_length);
// retrieving M3UA protocol data paremeter opc, dpc, si, ni, mp,
// sls
recv_opc = decode_32b_int(inbuffer+offset); offset +=4;
recv_dpc = decode_32b_int(inbuffer+offset); offset +=4;
recv_si = (unsigned int)(inbuffer[offset++]);
recv_ni = (unsigned int)(inbuffer[offset++]);
recv_mp = (unsigned int)(inbuffer[offset++]);
recv_sls = (unsigned int)(inbuffer[offset++]);
TTCN_Logger::log_event(", DATA: decoded Protocol Data parameter:");
// filling up TTCN structure
if ((Loop==MTP3_ON) ||
(!Filter) ||
(Filter &&
(recv_opc == (unsigned)Sut_Pc) && (recv_dpc == (unsigned)Tester_Pc) &&
(recv_ni == (unsigned)mtp3_ni)
))
{
ASP__MTP3__TRANSFERind recv_msg;
MTP3__Field__sio recv_sio;
recv_sio.ni()= int2bit(recv_ni,2);
recv_sio.prio()= int2bit(recv_mp,2);
recv_sio.si()= int2bit(recv_si,4);
recv_msg.sio() = recv_sio;
recv_msg.sls() = recv_sls;
recv_msg.opc()= recv_opc;
recv_msg.dpc() = recv_dpc;;
recv_msg.data() = OCTETSTRING(param_length-16, // 16 octet paramheader + 5 routing label
&inbuffer[offset]);
recv_msg.log();
close_log_event();
incoming_message ( recv_msg );
offset += param_length-16;
return length - offset;
}
else
{
close_log_event();
log("Either the received M3UA(OPC, DPC, SI) fields, or the embedded MTP3 rooting label (OPC, DPC) not matched with the filter setting -> packet dropped.");
return length - offset;
}
break;
default:
TTCN_Logger::log_event ("invalid M3UA param tag:0x%02x%02x-> skipped", PAR_PREFIX_M3UA, inbuffer[offset-1]);
skip_par_after_tag(inbuffer, offset);
}
break;
default:
TTCN_Logger::log_event ("invalid 1st octet param tag:0x%02x in DATA (packet dropped)",inbuffer[offset-1]);
close_log_event();
return length -offset;
break;
}
}// Checking parameter tag (offset <length-8)
break;
default:
TTCN_Logger::log_event("Invalid M3UA msg class TransferMessage msg type %d -> packet dropped",
(unsigned int)(inbuffer[M3UA_TYP_OFFS]));
close_log_event();
send_M3UA_error_msg( PAR_ERRC_UNSMT, inbuffer[M3UA_TYP_OFFS]);
break;
}
return length -offset;
}
// Set M3UA SingleAPC - Stores field Single Affected Point Code
void MTP3asp__PT_PROVIDER::Set_M3UA_SingleAPC(unsigned int pc, unsigned char* apc_par)
{
//setting par type to APC
apc_par[0] = PAR_PREFIX_COMMON;
apc_par[1] = PAR_AFFECTED_PC;
//setting the length to 4+4 = 8
apc_par[2] = 0x00;
apc_par[3] = 0x08;
//setting the mask
apc_par[4] = 0x00;
//setting the pc
encode_24b_int(apc_par+5,pc);
}
// Send DAVA DUNA to APCinDAUD
void MTP3asp__PT_PROVIDER::Send_DAVA_DUNA_to_APCinDAUD(unsigned int dava_sep, unsigned char* inbuffer, int & offset)
{
unsigned int length = decode_16b_int(inbuffer+offset);
offset +=2;
unsigned int current_pc;
//checking the length
if ((length < 8) || (length%4))
{ warn("Invalid length in APC parameter -> not processed");
return;
}
for (unsigned int i = 4 ; i < length; i += 4)
{
if (inbuffer[offset++] == 0x00) // mask===>single pc
{
current_pc = decode_24b_int(inbuffer+offset);
offset +=3;
if (dava_sep == current_pc) //dava
{ Set_M3UA_SingleAPC(dava_sep, dava_1apc_msg+M3UA_MSG_OFFS);
log("DAVA will be sent for pc=%d", dava_sep);
send_msg(dava_1apc_msg, sizeof_dava_1apc_msg);
}
else //duna
{ Set_M3UA_SingleAPC(current_pc, duna_1apc_msg+M3UA_MSG_OFFS);
log("DUNA will be sent for pc=%d", current_pc);
send_msg(duna_1apc_msg, sizeof_duna_1apc_msg);
}
}
else //masked pc
{ warn("Unsupported masking (mask=0x%02x) for PC=%d in APC parameter -> ignored",
inbuffer[offset-1], current_pc);
}
}
return;
}
// send M3UA error msg
// send an eror msg with error_code. Additional parameter matches to the error code:
void MTP3asp__PT_PROVIDER::send_M3UA_error_msg(unsigned int error_code, unsigned int add_par )
{
encode_16b_int( error_msg+M3UA_MSG_OFFS+4, error_code);
encode_16b_int( error_msg+M3UA_MSG_OFFS+8, add_par);
send_msg(error_msg, sizeof_error_msg );
};
// Coder functions for M3UA: int -> unsigned char array
//------------------------------------------------------
// Result:Less significant byte in highest address
// Most Significant Byte first (in lowest address) = MSB = Big Endian = Network Byte Order
void MTP3asp__PT_PROVIDER::encode_32b_int(unsigned char *to, unsigned int from)
{
to[3] = from & 0xFF;
from >>= 8;
to[2] = from & 0xFF;
from >>= 8;
to[1] = from & 0xFF;
from >>= 8;
to[0] = from & 0xFF;
}
//------------
unsigned int MTP3asp__PT_PROVIDER::decode_32b_int(const unsigned char *from)
{
return from[3] | (from[2] << 8) | (from[1] << 16) | (from[0] << 24);
}
//------------
void MTP3asp__PT_PROVIDER::encode_24b_int(unsigned char *to, unsigned int from)
{
to[2] = from & 0xFF;
from >>= 8;
to[1] = from & 0xFF;
from >>= 8;
to[0] = from & 0xFF;
}
//------------
unsigned int MTP3asp__PT_PROVIDER::decode_24b_int(const unsigned char *from)
{
return from[2] | (from[1] << 8) | (from[0] << 16);
}
//------------
void MTP3asp__PT_PROVIDER::encode_16b_int(unsigned char *to, int from)
{
to[1] = from & 0xFF;
from >>= 8;
to[0] = from & 0xFF;
}
//------------
unsigned int MTP3asp__PT_PROVIDER::decode_16b_int(const unsigned char *from)
{
return from[1] | (from[0] << 8);
}
//------------
//skip par after tag
void MTP3asp__PT_PROVIDER::skip_par_after_tag(unsigned char* inbuffer, int &offset)
{
offset += decode_16b_int(inbuffer+offset)-2; //the length contains
//the param hdr. itself
if (offset%4) offset += 4-(offset%4); //skipping padding
}
//------------
#endif
#ifdef TARGET_TEST
// --------------------------
// Functions for Target testing
// --------------------------
// In case of target this function handles the received message
void MTP3asp__PT_PROVIDER::message_incoming(const unsigned char* msg, int messageLength, int)
{
OCTETSTRING rcvData = OCTETSTRING(messageLength, msg);
int msgType = oct2int(substr(rcvData,0,1));
switch (msgType)
{
case 0: //TRANSFERind message received
if(Tcp_is_up) //Registration was already performed
{
ASP__MTP3__TRANSFERind recv_msg;
MTP3__Field__sio recv_sio;
BITSTRING sio_bit = oct2bit(substr(rcvData,5,1));
recv_sio.ni()= substr(sio_bit,0,2);
recv_sio.prio()= substr(sio_bit,2,2);
recv_sio.si()= substr(sio_bit,4,4);
recv_msg.sio() = recv_sio;
recv_msg.opc() = oct2int(substr(rcvData,6,4));
recv_msg.dpc() = oct2int(substr(rcvData,10,4));
recv_msg.sls() = oct2int(substr(rcvData,14,1));
recv_msg.data() = substr(rcvData,15,rcvData.lengthof()-15);
if (Tcp_is_up == 1) //No unregistration ongoing
incoming_message(recv_msg);
else //Unregistration ongoing
log("Received ASP_MTP3_TRANSFERind is ignored since unregistration is started.");
}
else
error("Message was received before successful registration in M3UA server.");
break;
case 4: //Status message received
{
int status = oct2int(substr(rcvData,5,1));
if(Tcp_is_up == 2) // Unregistration ongoing
{
const char * rcvDat = oct2str(rcvData);
log("Message \"%s\" received. Status = %i", rcvDat, status);
if (status == 2)
{
log("Unregistration performed.");
Tcp_is_up = 0;
}
else if (status == 3)
error("Unsuccessful unregistration.");
else if (status == 5) {
if(forward_status) {
incoming_message(ASP__MTP3__STATUS(NULL_VALUE));
}
else {
warn("Invalid STATUS message received from M3UA server with status code=%d.", status);
}
}
}
else if(Tcp_is_up == 1) // Active state
{
if (status == 5) {
if(forward_status) {
incoming_message(ASP__MTP3__STATUS(NULL_VALUE));
}
}
else {
warn("Invalid STATUS message received from M3UA server with status code=%d.", status);
}
}
else // Registration ongoing
{
const char * rcvDat = oct2str(rcvData);
log("Message \"%s\" received. Status = %i", rcvDat, status);
if (status == 0)
{
log("Registration performed.");
Tcp_is_up = 1;
}
else {
error("Unsuccessful registration.");
}
}
}
break;
case 5:
{
if(forward_pause) incoming_message(ASP__MTP3__PAUSE(NULL_VALUE));
}
break;
case 6:
{
if(forward_resume) incoming_message(ASP__MTP3__RESUME(NULL_VALUE));
}
break;
default: //Unexpected message received
warn("Invalid message received from M3UA server.");
}
}
void MTP3asp__PT_PROVIDER::Check_Target_TestPort_Variables()
{
if (Sut_Pc==-1) error("Parameter SUT_Pc is not set.");
if (Tester_Pc==-1) error("Parameter TESTER_Pc is not set.");
if (!Ni_is_set) error("Parameter NI is not set.");
if (M3UA_version==0) error("Parameter M3UA_version cannot be set to 0 in TargetM3UA mode.");
//packet header
header_descr = new PacketHeaderDescr( 1, 4, PacketHeaderDescr::Header_MSB);
}
void MTP3asp__PT_PROVIDER::Check_Target_TestPort_Variables_STC()
{
if( destinationname == NULL) error("Parameter DestinationName is not set in TargetSTC mode.");
header_descr = new PacketHeaderDescr( 1, 4, PacketHeaderDescr::Header_MSB);
}
void MTP3asp__PT_PROVIDER::Target_user_map(const char *system_port)
{
Tcp_is_up = 0;
Check_Target_TestPort_Variables();
map_user();
OCTETSTRING tcpData = int2oct(2,1); //Message type
if( destinationname == NULL)
tcpData = tcpData + int2oct(char2oct(system_port).lengthof()+15,4); //Length
else
tcpData = tcpData + int2oct(char2oct(destinationname).lengthof()+15,4);
tcpData = tcpData + int2oct(mtp3_ni,1);
tcpData = tcpData + int2oct(Sut_Pc,4);
tcpData = tcpData + int2oct(Tester_Pc,4);
tcpData = tcpData + int2oct(M3UA_version,1);
if( destinationname == NULL)
tcpData = tcpData + char2oct(system_port);
else
tcpData = tcpData + char2oct(destinationname);
send_outgoing((const unsigned char*)tcpData,tcpData.lengthof());
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("MTP3 Test Port (%s): ", get_name());
TTCN_Logger::log_event_str("Registration message sent: ");
tcpData.log();
TTCN_Logger::end_event();
int fd = get_socket_fd();
pollfd pollFd = { fd, POLLIN, 0 };
int nEvents = poll(&pollFd, 1, 3000 /* ms */);
if (nEvents == 0)
error("No response received for REGISTER message. Exiting after timeout.");
if (nEvents < 0 || (pollFd.revents & (POLLIN | POLLHUP)) == 0)
error("No response received for REGISTER message. Exiting after error (%d)",
(nEvents < 0) ? errno : 0);
Handle_Fd_Event(fd, TRUE, FALSE, FALSE);
}
void MTP3asp__PT_PROVIDER::TargetSTC_user_map(const char *system_port)
{
Tcp_is_up = 0;
Check_Target_TestPort_Variables_STC();
map_user();
OCTETSTRING tcpData = int2oct(2,1); //Message type
tcpData = tcpData + int2oct(char2oct(destinationname).lengthof()+15,4);
tcpData = tcpData + int2oct(0,1);
tcpData = tcpData + int2oct(0,4);
tcpData = tcpData + int2oct(0,4);
tcpData = tcpData + int2oct(0,1);
tcpData = tcpData + char2oct(destinationname);
send_outgoing((const unsigned char*)tcpData,tcpData.lengthof());
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("MTP3 Test Port (%s): ", get_name());
TTCN_Logger::log_event_str("Registration message sent: ");
tcpData.log();
TTCN_Logger::end_event();
int fd = get_socket_fd();
pollfd pollFd = { fd, POLLIN, 0 };
int nEvents = poll(&pollFd, 1, 3000 /* ms */);
if (nEvents == 0)
error("No response received for REGISTER message. Exiting after timeout.");
if (nEvents < 0 || (pollFd.revents & (POLLIN | POLLHUP)) == 0)
error("No response received for REGISTER message. Exiting after error (%d)",
(nEvents < 0) ? errno : 0);
Handle_Fd_Event(fd, TRUE, FALSE, FALSE);
}
void MTP3asp__PT_PROVIDER::Target_user_unmap(const char *system_port)
{
OCTETSTRING tcpData = int2oct(3,1); //Message type
tcpData = tcpData + int2oct(6,4); //Length
tcpData = tcpData + int2oct(0,1);
send_outgoing((const unsigned char*)tcpData,tcpData.lengthof());
TTCN_Logger::begin_event(TTCN_DEBUG);
TTCN_Logger::log_event("MTP3 Test Port (%s): ", get_name());
TTCN_Logger::log_event_str("Unregistration message sent: ");
tcpData.log();
TTCN_Logger::end_event();
Tcp_is_up = 2; //Unregistration ongoing
while (Tcp_is_up == 2)
{
int fd = get_socket_fd();
pollfd pollFd = { fd, POLLIN, 0 };
int nEvents = poll(&pollFd, 1, 3000 /* ms */);
if (nEvents == 0)
error("No response received for UNREGISTER message. Exiting after timeout.");
if (nEvents < 0 || (pollFd.revents & (POLLIN | POLLHUP)) == 0)
error("No response received for UNREGISTER message. Exiting after error (%d)",
(nEvents < 0) ? errno : 0);
Handle_Fd_Event(fd, TRUE, FALSE, FALSE);
}
unmap_user();
}
#endif
}