| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // Copyright Test Competence Center (TCC) ETH 2009 // |
| // // |
| // 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: M3UA_Emulation.ttcn |
| // Reference: M3UA Protocol Emulation |
| // Rev: R1B01 |
| // Prodnr: CNL 113 537 |
| // Updated: 2009-01-06 |
| // Contact: http://ttcn.ericsson.se |
| |
| module M3UA_Emulation |
| { |
| |
| modulepar |
| { |
| boolean tsp_logVerbose := false; |
| float tsp_Timer := 2.0; // General timer used in M3UA emulation. |
| float tsp_ASPUP_Resend_Timer := 2.0; |
| float tsp_ASPAC_Resend_Timer := 2.0; |
| float tsp_Assoc_Restart_Timer := 60.0; |
| float tsp_Heartbeat_Timer := 30.0; |
| integer tsp_SCTP_PayloadProtocolID := 3; // 3 for M3UA. |
| boolean tsp_Enable_M3UA_Heartbeat := false; // Send SCTP packets periodically. |
| boolean tsp_SCTP_Server_Mode := false; |
| boolean tsp_M3UA_Server_Mode := false; |
| } |
| |
| import from General_Types all; |
| import from M3UA_Types all; |
| import from SCTPasp_Types all; |
| import from SCTPasp_PortType all; |
| import from MTP3asp_Types all; |
| |
| type record of ASP_MTP3_TRANSFERreq TRANSFERreq_Buffer; |
| |
| type record SCTP_Association_Address |
| { |
| integer local_sctp_port, |
| charstring local_ip_addr, |
| integer remote_sctp_port, |
| charstring remote_ip_addr |
| } |
| |
| // Definition of M3UA_Entity which contains M3UA entity data. |
| type record M3UA_Entity |
| { |
| M3UA_CommStatus commStatus optional, |
| integer sCTP_Assoc_ID optional, |
| SCTP_Association_Address assoc |
| } |
| |
| // Type for status of SCTP communication for an M3UA entity. |
| type enumerated M3UA_CommStatus |
| { |
| aSP_Down_initial_State (0), |
| aSP_Down_sCTP_Initialize_Done (1), |
| aSP_Down_sCTP_Associate_done (2), |
| aSP_Down_commUP_Received (3), |
| aSP_Down_ASPUP_Sent (4), |
| aSP_Inactive (5), |
| aSP_Inact_ASPAC_Sent (6), |
| aSP_Active (7) // aSPAC_Ack_Received |
| } |
| |
| // We need an internal port to communicate with the MTP3 side. |
| // internal in name |
| type port MTP3asp_SP_PT_Int message |
| { |
| in ASP_MTP3_TRANSFERreq; |
| out ASP_MTP3_TRANSFERind; |
| // out ASP_MTP3_PAUSE; |
| // out ASP_MTP3_RESUME; |
| // out ASP_MTP3_STATUS; |
| } with { |
| extension "internal" |
| } |
| |
| // M3UA emulation component. |
| type component M3UA_CT |
| { |
| var M3UA_Entity v_Entity; |
| var TRANSFERreq_Buffer v_TRANSFERreq_Buffer := {}; |
| |
| var ASP_SCTP v_ASP_SCTP; |
| var ASP_SCTP_SEND_FAILED v_ASP_SCTP_SEND_FAILED; |
| var ASP_SCTP_RESULT v_ASP_SCTP_RESULT; |
| var ASP_SCTP_Connected v_ASP_SCTP_Connected; |
| var ASP_SCTP_ASSOC_CHANGE v_ASP_SCTP_ASSOC_CHANGE; |
| var ASP_SCTP_SHUTDOWN_EVENT v_ASP_SCTP_SHUTDOWN_EVENT; |
| |
| var PDU_M3UA v_PDU_M3UA; |
| |
| // Component timers. |
| timer T_Timer := tsp_Timer; |
| timer T_ASPUP_resend := tsp_ASPUP_Resend_Timer; |
| timer T_ASPAC_resend := tsp_ASPAC_Resend_Timer; |
| timer T_Heartbeat := tsp_Heartbeat_Timer; |
| timer T_Assoc_restart := tsp_Assoc_Restart_Timer; |
| |
| // Port declarations. |
| port MTP3asp_SP_PT_Int MTP3_SP_PORT; // Port towards MTP3/M3UA. |
| port SCTPasp_PT SCTP_PORT; // Port towards target through SCTP. |
| } |
| |
| //******************************** |
| // Start of SCTP related templates |
| //******************************** |
| template ASP_SCTP t_S_SCTP_Send |
| (in template integer pl_associationID, |
| in template integer pl_streamID, |
| in template octetstring pl_userData, |
| in template integer pl_protocolID) := |
| { |
| client_id := pl_associationID, |
| sinfo_stream := pl_streamID, |
| sinfo_ppid := pl_protocolID, |
| data := pl_userData |
| } |
| |
| template ASP_SCTP_SEND_FAILED t_ASP_SCTP_SEND_FAILED |
| (in template integer pl_streamID) := |
| { |
| client_id := pl_streamID |
| } |
| |
| template ASP_SCTP_Listen t_ASP_SCTP_Listen |
| (template charstring pl_local_hostname, |
| template integer pl_local_portnumber) := |
| { |
| local_hostname := pl_local_hostname, |
| local_portnumber := pl_local_portnumber |
| } |
| |
| template ASP_SCTP_Connected tr_ASP_SCTP_Connected |
| (template integer pl_client_id, |
| template charstring pl_local_hostname, |
| template integer pl_local_portnumber, |
| template charstring pl_peer_hostname, |
| template integer pl_peer_portnumber) := |
| { |
| client_id := pl_client_id, |
| local_hostname := pl_local_hostname, |
| local_portnumber := pl_local_portnumber, |
| peer_hostname := pl_peer_hostname, |
| peer_portnumber := pl_peer_portnumber |
| } |
| |
| template ASP_SCTP_ConnectFrom t_ASP_SCTP_ConnectFrom |
| (template charstring pl_local_hostname, |
| template integer pl_local_portnumber, |
| template charstring pl_peer_hostname, |
| template integer pl_peer_portnumber) := |
| { |
| local_hostname := pl_local_hostname, |
| local_portnumber := pl_local_portnumber, |
| peer_hostname := pl_peer_hostname, |
| peer_portnumber := pl_peer_portnumber |
| } |
| |
| template ASP_SCTP_RESULT t_ASP_SCTP_RESULT |
| (template integer pl_client_id, |
| template boolean pl_error_status, |
| template charstring pl_error_message) := |
| { |
| client_id := pl_client_id, |
| error_status := pl_error_status, |
| error_message := pl_error_message |
| } |
| |
| template ASP_SCTP_ASSOC_CHANGE tr_S_SCTP_CommunicationUp |
| (in template integer pl_associationID) := |
| { |
| client_id := pl_associationID, |
| sac_state := SCTP_COMM_UP |
| } |
| |
| template ASP_SCTP_ASSOC_CHANGE tr_S_SCTP_CommunicationLost |
| (in template integer pl_associationID) := |
| { |
| client_id := pl_associationID, |
| sac_state := SCTP_COMM_LOST |
| } |
| |
| template ASP_SCTP_ASSOC_CHANGE tr_S_SCTP_ShutdownComplete |
| (in template integer pl_associationID) := |
| { |
| client_id := pl_associationID, |
| sac_state := SCTP_SHUTDOWN_COMP |
| } |
| |
| template ASP_SCTP_SHUTDOWN_EVENT tr_S_SCTP_ShutdownEvent |
| (in template integer pl_associationID) := |
| { |
| client_id := pl_associationID |
| } |
| |
| template ASP_SCTP_ASSOC_CHANGE tr_S_SCTP_Restart |
| (in template integer pl_associationID) := |
| { |
| client_id := pl_associationID, |
| sac_state := SCTP_RESTART |
| } |
| |
| template ASP_SCTP_ASSOC_CHANGE tr_S_SCTP_CANT_STR_ASSOC |
| (in template integer pl_associationID) := |
| { |
| client_id := pl_associationID, |
| sac_state := SCTP_CANT_STR_ASSOC |
| } |
| |
| template ASP_SCTP tr_S_SCTP_DataArrive |
| (in template integer pl_associationID, |
| in template integer pl_streamID, |
| in template integer pl_protocolID, |
| in template PDU_SCTP pl_data) := |
| { |
| client_id := pl_associationID, |
| sinfo_stream := pl_streamID, |
| sinfo_ppid := pl_protocolID, |
| data := pl_data |
| } |
| |
| template ASP_SCTP_Close t_ASP_SCTP_Close |
| (in template integer pl_associationID) := |
| { |
| client_id := pl_associationID |
| } |
| //****************************** |
| // End of SCTP related templates |
| //****************************** |
| |
| //***************************** |
| // Start of M3UA PDU templates. |
| //***************************** |
| template PDU_M3UA t_PDU_M3UA_ASPUP |
| (in template M3UA_ASP_Identifier pl_aSP_Identifier, |
| in template M3UA_Info_String pl_info_String) := |
| { |
| m3UA_ASPUP := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0301'O, |
| messageLength := 0, |
| messageParameters := { |
| aSP_Identifier := pl_aSP_Identifier, |
| info_String := pl_info_String |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_ASPUP_Ack := |
| { |
| m3UA_ASPUP_Ack := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0304'O, |
| messageLength := 0, |
| messageParameters := { |
| info_String := omit |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_ASPDN := |
| { |
| m3UA_ASPDN := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0302'O, |
| messageLength := 0, |
| messageParameters := { |
| info_String := omit |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_ASPDN_Ack := |
| { |
| m3UA_ASPDN_Ack := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0305'O, |
| messageLength := 0, |
| messageParameters := { |
| info_String := omit |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_ASPAC |
| (in template M3UA_Traffic_Mode_Type pl_traffic_Mode_Type, |
| in template M3UA_Routing_Context pl_routing_Context, |
| in template M3UA_Info_String pl_info_String) := |
| { |
| m3UA_ASPAC := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0401'O, |
| messageLength := 0, |
| messageParameters := { |
| traffic_Mode_Type := pl_traffic_Mode_Type, |
| routing_Context := pl_routing_Context, |
| info_String := pl_info_String |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_ASPAC_Ack |
| (in template M3UA_Traffic_Mode_Type pl_traffic_mode_type, |
| in template M3UA_Routing_Context pl_routing_Context) := |
| { |
| m3UA_ASPAC_Ack := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0403'O, |
| messageLength := 0, |
| messageParameters := { |
| traffic_Mode_Type := pl_traffic_mode_type, |
| routing_Context := pl_routing_Context, |
| info_String := omit |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_ASPIA |
| (in template M3UA_Routing_Context pl_routing_Context, |
| in template M3UA_Info_String pl_info_String) := |
| { |
| m3UA_ASPIA := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0402'O, |
| messageLength := 0, |
| messageParameters := { |
| routing_Context := pl_routing_Context, |
| info_String := pl_info_String |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_ASPIA_Ack |
| (in template M3UA_Routing_Context pl_routing_Context) := |
| { |
| m3UA_ASPIA_Ack := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0404'O, |
| messageLength := 0, |
| messageParameters := { |
| routing_Context := pl_routing_Context, |
| info_String := omit |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_Heartbeat |
| (in template M3UA_Heartbeat_Data pl_heartbeat_Data) := |
| { |
| m3UA_BEAT := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0303'O, |
| messageLength := 0, |
| messageParameters := { |
| heartbeat_Data := pl_heartbeat_Data |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_Beat_Ack |
| (in template M3UA_Heartbeat_Data pl_heartbeat_Data) := |
| { |
| m3UA_BEAT_Ack := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0306'O, |
| messageLength := 0, |
| messageParameters := { |
| heartbeat_Data := pl_heartbeat_Data |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_DATA |
| (in template M3UA_Network_Appearance pl_network_Appearance, |
| in template M3UA_Routing_Context pl_routing_Context, |
| in template M3UA_Protocol_Data pl_protocol_Data, |
| in template M3UA_Correlation_ID pl_correlation_ID) := |
| { |
| m3UA_DATA := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0101'O, |
| messageLength := 0, |
| messageParameters := { |
| network_Appearance := pl_network_Appearance, |
| routing_Context := pl_routing_Context, |
| protocol_Data := pl_protocol_Data, |
| correlation_ID := pl_correlation_ID |
| } |
| } |
| } |
| |
| template PDU_M3UA t_PDU_M3UA_DAVA |
| (in template M3UA_Network_Appearance pl_network_Appearance, |
| in template M3UA_Routing_Context pl_routing_Context, |
| in template M3UA_Affected_Point_Codes pl_affected_Point_Codes, |
| in template M3UA_Info_String pl_info_String) := |
| { |
| m3UA_DAVA := { |
| version := '01'O, |
| reserved := '00'O, |
| messageClassAndType := '0202'O, |
| messageLength := 0, |
| messageParameters := { |
| network_Appearance := pl_network_Appearance, |
| routing_Context := pl_routing_Context, |
| affected_Point_Codes := pl_affected_Point_Codes, |
| info_String := pl_info_String |
| } |
| } |
| } |
| //************************** |
| // End of M3UA PDU templates |
| //************************** |
| |
| //********************************** |
| // Start of M3UA parameter templates |
| //********************************** |
| template M3UA_Protocol_Data t_M3UA_Protocol_Data |
| (template OCT4 pl_oPC, |
| template OCT4 pl_dPC, |
| template OCT1 pl_sI, |
| template OCT1 pl_nI, |
| template OCT1 pl_mP, |
| template OCT1 pl_sLS, |
| template octetstring pl_userProtocolData) := |
| { |
| tag := '0210'O, |
| lengthInd := 0, |
| oPC := pl_oPC, |
| dPC := pl_dPC, |
| sI := pl_sI, |
| nI := pl_nI, |
| mP := pl_mP, |
| sLS := pl_sLS, |
| userProtocolData := pl_userProtocolData |
| } |
| //******************************** |
| // End of M3UA parameter templates |
| //******************************** |
| |
| //*********************************** |
| // Dynamic part of the M3UA emulation |
| //*********************************** |
| |
| function f_M3UA_Emulation(SCTP_Association_Address pl_Boot) runs on M3UA_CT |
| { |
| // Initialize parameters from the test case. |
| v_Entity.assoc := pl_Boot; |
| v_Entity.commStatus := aSP_Down_initial_State; |
| |
| // At this point, we assume that the ports are already connected and mapped |
| // properly by the user. |
| log("*************************************************"); |
| log("M3UA emulation initiated, the test can be started"); |
| log("*************************************************"); |
| |
| f_Initialize_SCTP(); |
| |
| // Start the main function in an infinte loop. |
| f_M3UA_ScanEvents(); |
| } |
| |
| // Initialize the SCTP layer with parameters read from the configuration file. |
| // We have only a single association. |
| function f_Initialize_SCTP() runs on M3UA_CT |
| { |
| v_Entity.commStatus := aSP_Down_sCTP_Initialize_Done; |
| if (tsp_SCTP_Server_Mode) { |
| // Send out a LISTEN message. The communication status doesn't change |
| // here. |
| SCTP_PORT.send |
| (t_ASP_SCTP_Listen(v_Entity.assoc.local_ip_addr, |
| v_Entity.assoc.local_sctp_port)); |
| } |
| else { |
| // Send ConnectFrom sequentially, wait for RESULT messages. |
| f_Associate(); |
| T_Assoc_restart.start; |
| } |
| |
| if (tsp_SCTP_PayloadProtocolID == 3) { |
| if (not tsp_M3UA_Server_Mode) { |
| T_ASPUP_resend.start; |
| T_ASPAC_resend.start; |
| } |
| if (tsp_Enable_M3UA_Heartbeat) { |
| T_Heartbeat.start; |
| } |
| } |
| } |
| |
| // Associate SCTP connection for a M3UA entity. |
| function f_Associate() runs on M3UA_CT |
| { |
| SCTP_PORT.send(t_ASP_SCTP_ConnectFrom |
| (v_Entity.assoc.local_ip_addr, |
| v_Entity.assoc.local_sctp_port, |
| v_Entity.assoc.remote_ip_addr, |
| v_Entity.assoc.remote_sctp_port)); |
| |
| T_Timer.start; |
| alt { |
| [] SCTP_PORT.receive(t_ASP_SCTP_RESULT(*, ?, *)) -> value v_ASP_SCTP_RESULT { |
| if (v_ASP_SCTP_RESULT.error_status) { |
| log("Connect failed: ", v_ASP_SCTP_RESULT.error_message); |
| } |
| else { |
| v_Entity.sCTP_Assoc_ID := v_ASP_SCTP_RESULT.client_id; |
| v_Entity.commStatus := aSP_Down_sCTP_Associate_done; |
| log("SCTP_ConnectResult -> connection established from: ", |
| v_Entity.assoc.local_ip_addr, ":", v_Entity.assoc.local_sctp_port, |
| " to server: ", v_Entity.assoc.remote_ip_addr, ":", |
| v_Entity.assoc.remote_sctp_port, " association #", |
| v_Entity.sCTP_Assoc_ID); |
| if (tsp_logVerbose) { |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to ", |
| v_Entity.commStatus); |
| } |
| } |
| T_Timer.stop; |
| } |
| [] T_Timer.timeout { |
| log("----------------------------------------------"); |
| log("No response received to t_ASP_SCTP_ConnectFrom"); |
| log("----------------------------------------------"); |
| setverdict(fail); |
| // mtc.stop; |
| } |
| } |
| } |
| |
| // Starts M3UA emulation execution. |
| function f_M3UA_ScanEvents() runs on M3UA_CT |
| { |
| var ASP_MTP3_TRANSFERreq vl_ASP_MTP3_TRANSFERreq; |
| |
| alt { |
| [] MTP3_SP_PORT.receive(ASP_MTP3_TRANSFERreq : ?) |
| -> value vl_ASP_MTP3_TRANSFERreq { |
| f_Send_MTP3_TRANSFERreq(vl_ASP_MTP3_TRANSFERreq); |
| repeat; |
| } |
| [] as_SCTP_CommunicationUp() |
| [] as_SCTP_DataArrive() |
| [] as_SCTP_Connected() |
| [] as_Unexpected_SCTP_Events() |
| [] as_handleM3UA_timers() |
| [] as_handleSCTP_timers() |
| } |
| } |
| |
| function f_Send_MTP3_TRANSFERreq(ASP_MTP3_TRANSFERreq pl_ASP_MTP3_TRANSFERreq) |
| runs on M3UA_CT |
| { |
| if (v_Entity.commStatus == aSP_Active) { |
| if (tsp_SCTP_PayloadProtocolID == 3) { // M3UA |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 1, |
| enc_PDU_M3UA |
| (valueof |
| (t_PDU_M3UA_DATA |
| (omit, |
| omit, |
| t_M3UA_Protocol_Data |
| (int2oct(pl_ASP_MTP3_TRANSFERreq.opc, 4), // OPC |
| int2oct(pl_ASP_MTP3_TRANSFERreq.dpc, 4), // DPC |
| bit2oct('0000'B & pl_ASP_MTP3_TRANSFERreq.sio.si), // SIO |
| bit2oct('000000'B & pl_ASP_MTP3_TRANSFERreq.sio.ni), |
| bit2oct('000000'B & pl_ASP_MTP3_TRANSFERreq.sio.prio), |
| int2oct(pl_ASP_MTP3_TRANSFERreq.sls, 1), // SLS |
| pl_ASP_MTP3_TRANSFERreq.data), |
| omit))), |
| tsp_SCTP_PayloadProtocolID)); |
| } |
| else { // Non-M3UA |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 1, |
| pl_ASP_MTP3_TRANSFERreq.data, |
| tsp_SCTP_PayloadProtocolID)); |
| } |
| if (tsp_logVerbose) { |
| log("MTP3_SP_PORT: ASP_MTP3_TRANSFERreq received -> message sent " & |
| "via SCTP"); |
| } |
| } |
| else { |
| // If the SCTP association is not yet running, we have to buffer the data |
| // messages arrived from the MTP3 side. Sending of buffered data messages |
| // should occure when the SCTP association is up and before sending the |
| // data message in reply for a new ASP_MTP3_TRANSFERreq data message. The |
| // buffer should be checked before sending. |
| v_TRANSFERreq_Buffer[sizeof(v_TRANSFERreq_Buffer)] := |
| pl_ASP_MTP3_TRANSFERreq; |
| if (tsp_logVerbose) { |
| log("MTP3_SP_PORT: ASP_MTP3_TRANSFERreq received in an inactive state " & |
| "-> message was buffered"); |
| } |
| } |
| } |
| |
| // Handle communication up messages of users which performed associate earlier. |
| // We have only one association. |
| altstep as_SCTP_CommunicationUp() runs on M3UA_CT |
| { |
| [] SCTP_PORT.receive(tr_S_SCTP_CommunicationUp(?)) |
| -> value v_ASP_SCTP_ASSOC_CHANGE { |
| if (v_Entity.sCTP_Assoc_ID == v_ASP_SCTP_ASSOC_CHANGE.client_id) { |
| if (v_Entity.commStatus == aSP_Down_sCTP_Associate_done) { |
| v_Entity.commStatus := aSP_Down_commUP_Received; |
| if (tsp_SCTP_PayloadProtocolID != 3) { // Non-M3UA |
| v_Entity.commStatus := aSP_Active; |
| var integer v_i; |
| for (v_i := 0; v_i < sizeof(v_TRANSFERreq_Buffer); v_i := v_i + 1) { |
| log("Sending buffered message #", v_i); |
| f_Send_MTP3_TRANSFERreq(v_TRANSFERreq_Buffer[v_i]); |
| } |
| v_TRANSFERreq_Buffer := {}; |
| // MTP3_SP_PORT.send(ASP_MTP3_RESUME : {}); |
| } |
| if (tsp_logVerbose) { |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| if ((not tsp_M3UA_Server_Mode) and |
| (tsp_SCTP_PayloadProtocolID == 3)) { // M3UA |
| f_ASPUP_Sending(); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("SCTP_CommunicationUp received in wrong state (i.e. not after " & |
| "SCTP_Associate is done) in state: ", v_Entity.commStatus); |
| } |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("Association does not exists, received in CommunicationUp"); |
| } |
| } |
| repeat; |
| } |
| } |
| |
| // This altstep handles the data received from SCTP. |
| altstep as_SCTP_DataArrive() runs on M3UA_CT |
| { |
| [] SCTP_PORT.receive(tr_S_SCTP_DataArrive |
| (?, // associationID |
| ?, // streamID |
| ?, // protocolID |
| ? // data |
| )) -> value v_ASP_SCTP { |
| // Checking the identifier for the association is not necessary, because we |
| // have only only one association. |
| if (f_Assoc_Exists(v_ASP_SCTP.client_id)) { |
| if (tsp_logVerbose) { |
| log("Message received on association #", v_Entity.sCTP_Assoc_ID); |
| } |
| if (tsp_SCTP_PayloadProtocolID == 3) { // M3UA |
| v_PDU_M3UA := dec_PDU_M3UA(v_ASP_SCTP.data); |
| f_handle_M3UA_msg(v_PDU_M3UA); |
| } |
| else { // Non-M3UA |
| f_handle_nonM3UA_msg(v_ASP_SCTP.data); |
| } |
| } |
| else{ |
| log("Message received on unknown association #", v_Entity.sCTP_Assoc_ID, |
| " -> closing connection"); |
| SCTP_PORT.send(t_ASP_SCTP_Close(v_Entity.sCTP_Assoc_ID)); |
| log("SCTP connection closed"); |
| } |
| repeat; |
| } |
| } |
| |
| // Handle the SCTP connected messages. It is sent from the SCTP side and it |
| // signals, that we're on the right track to create the association. This is |
| // for server mode. |
| altstep as_SCTP_Connected() runs on M3UA_CT |
| { |
| [tsp_SCTP_Server_Mode] SCTP_PORT.receive(tr_ASP_SCTP_Connected(?, ?, ?, ?, ?)) |
| -> value v_ASP_SCTP_Connected { |
| // Message from the configured endpoint. |
| if ((v_ASP_SCTP_Connected.local_portnumber == |
| v_Entity.assoc.local_sctp_port) and |
| (v_ASP_SCTP_Connected.local_hostname == |
| v_Entity.assoc.local_ip_addr) and |
| (v_ASP_SCTP_Connected.peer_portnumber == |
| v_Entity.assoc.remote_sctp_port) and |
| (v_ASP_SCTP_Connected.peer_hostname == |
| v_Entity.assoc.remote_ip_addr)) { |
| v_Entity.sCTP_Assoc_ID := v_ASP_SCTP_Connected.client_id; |
| v_Entity.commStatus := aSP_Down_sCTP_Associate_done; |
| log("ASP_SCTP_Connected -> accepted connection from client: ", |
| v_ASP_SCTP_Connected.peer_hostname, ":", |
| v_ASP_SCTP_Connected.peer_portnumber, " on server: ", |
| v_ASP_SCTP_Connected.local_hostname, ":", |
| v_ASP_SCTP_Connected.local_portnumber, " with association #", |
| v_Entity.sCTP_Assoc_ID); |
| } |
| else { |
| log("ASP_SCTP_Connected -> connection from unknown client: ", |
| v_ASP_SCTP_Connected.peer_hostname, ":", |
| v_ASP_SCTP_Connected.peer_portnumber); |
| } |
| repeat; |
| } |
| } |
| |
| // Handle error messages of users. |
| altstep as_Unexpected_SCTP_Events() runs on M3UA_CT |
| { |
| // Handle communications lost message. State of user with given index jumps |
| // back to initial state and stays there. That user will not be able to |
| // communicate anymore. |
| [] SCTP_PORT.receive(tr_S_SCTP_CommunicationLost(?)) |
| -> value v_ASP_SCTP_ASSOC_CHANGE { |
| if (f_Assoc_Exists(v_ASP_SCTP_ASSOC_CHANGE.client_id)) { |
| if (v_Entity.commStatus == aSP_Active) { |
| // MTP3_SP_PORT.send(ASP_MTP3_PAUSE : {}); |
| } |
| v_Entity.commStatus := aSP_Down_sCTP_Initialize_Done; |
| v_Entity.sCTP_Assoc_ID := omit; |
| if (tsp_logVerbose) { |
| log("SCTP_CommunicationLost received"); |
| log("Association #", v_Entity.sCTP_Assoc_ID, " cleared, state " & |
| "changed to: ", v_Entity.commStatus); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("Association does not exist, received in CommunicationLost"); |
| } |
| } |
| repeat; |
| } |
| [] SCTP_PORT.receive(tr_S_SCTP_ShutdownComplete(?)) |
| -> value v_ASP_SCTP_ASSOC_CHANGE { |
| if (f_Assoc_Exists(v_ASP_SCTP_ASSOC_CHANGE.client_id)) { |
| if (v_Entity.commStatus == aSP_Active) { |
| // MTP3_SP_PORT.send(ASP_MTP3_PAUSE : {}); |
| } |
| v_Entity.commStatus := aSP_Down_sCTP_Initialize_Done; |
| if (tsp_logVerbose) { |
| log("SCTP_ShutdownComplete received"); |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("Association does not exist, received in ShutdownComplete"); |
| } |
| } |
| repeat; |
| } |
| [] SCTP_PORT.receive(tr_S_SCTP_ShutdownEvent(?)) |
| -> value v_ASP_SCTP_SHUTDOWN_EVENT { |
| if (f_Assoc_Exists(v_ASP_SCTP_SHUTDOWN_EVENT.client_id)) { |
| if (v_Entity.commStatus == aSP_Active) { |
| // MTP3_SP_PORT.send(ASP_MTP3_PAUSE : {}); |
| } |
| v_Entity.commStatus := aSP_Down_sCTP_Initialize_Done; |
| if (tsp_logVerbose) { |
| log("SCTP_ShutdownEvent received"); |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("Association does not exist, received in ShutdownEvent"); |
| } |
| } |
| repeat; |
| } |
| [] SCTP_PORT.receive(tr_ASP_SCTP_Connected(?, ?, ?, ?, ?)) |
| -> value v_ASP_SCTP_Connected { |
| log("Unexpected ASP_SCTP_Connected"); |
| repeat; |
| } |
| [] SCTP_PORT.receive(tr_S_SCTP_Restart(?)) -> value v_ASP_SCTP_ASSOC_CHANGE { |
| if (f_Assoc_Exists(v_ASP_SCTP_ASSOC_CHANGE.client_id)) { |
| log("SCTP_Restart received"); |
| v_Entity.commStatus := aSP_Down_commUP_Received; |
| if (tsp_logVerbose) { |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("Association does not exist, received in SCTP_Restart"); |
| } |
| } |
| repeat; |
| } |
| [] SCTP_PORT.receive(t_ASP_SCTP_SEND_FAILED(?)) |
| -> value v_ASP_SCTP_SEND_FAILED { |
| log("SCTP_Send failed for association #", v_Entity.sCTP_Assoc_ID); |
| if (f_Assoc_Exists(v_ASP_SCTP_SEND_FAILED.client_id)) { |
| // Daemon sends an error status message here. |
| // MTP3_SP_PORT.send(ASP_MTP3_PAUSE : {}); |
| } |
| else { |
| log("Send error received for association that doesn't exist"); |
| } |
| repeat; |
| } |
| [] SCTP_PORT.receive(tr_S_SCTP_CANT_STR_ASSOC(?)) { |
| repeat; |
| } |
| [] SCTP_PORT.receive { |
| repeat; |
| } |
| } |
| |
| // After reception of SCTP_CommunicationUp M3UA ASPUP/ASPAC is resent by the |
| // entity if it didn't receive ASPUP_Ack/ASPAC_Ack. |
| altstep as_handleM3UA_timers() runs on M3UA_CT |
| { |
| [] T_ASPUP_resend.timeout { |
| if ((v_Entity.commStatus == aSP_Down_commUP_Received) or |
| (v_Entity.commStatus == aSP_Down_ASPUP_Sent)) { |
| // Try to send ASPUP again. |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, |
| enc_PDU_M3UA(valueof(t_PDU_M3UA_ASPUP(omit, omit))), |
| tsp_SCTP_PayloadProtocolID)); |
| v_Entity.commStatus := aSP_Down_ASPUP_Sent; |
| if (tsp_logVerbose) { |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| } |
| T_ASPUP_resend.start; |
| repeat; |
| } |
| |
| [] T_ASPAC_resend.timeout { |
| if ((v_Entity.commStatus == aSP_Inactive) or |
| (v_Entity.commStatus == aSP_Inact_ASPAC_Sent)) { |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, |
| enc_PDU_M3UA(valueof(t_PDU_M3UA_ASPAC(omit, omit, omit))), |
| tsp_SCTP_PayloadProtocolID)); |
| v_Entity.commStatus := aSP_Inact_ASPAC_Sent; |
| if (tsp_logVerbose) { |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| } |
| T_ASPAC_resend.start; |
| repeat; |
| } |
| |
| [tsp_Enable_M3UA_Heartbeat] T_Heartbeat.timeout { |
| if (v_Entity.commStatus == aSP_Active) { |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, |
| enc_PDU_M3UA(valueof(t_PDU_M3UA_Heartbeat(omit))), |
| tsp_SCTP_PayloadProtocolID)); |
| if (tsp_logVerbose) { |
| log("Heartbeat sent to association #", v_Entity.sCTP_Assoc_ID); |
| } |
| } |
| T_Heartbeat.start; |
| repeat; |
| } |
| } |
| |
| // Handles SCTP timer events. In server mode we don't associate. |
| altstep as_handleSCTP_timers() runs on M3UA_CT |
| { |
| [not tsp_SCTP_Server_Mode] T_Assoc_restart.timeout { |
| if (v_Entity.commStatus == aSP_Down_sCTP_Initialize_Done) { |
| f_Associate(); |
| } |
| T_Assoc_restart.start; |
| repeat; |
| } |
| } |
| |
| // After reception of SCTP CommunicationUp messages M3UA ASPUP is sent by |
| // every entity and the M3UA ASPUP_Ack is received by every entity. |
| function f_ASPUP_Sending() runs on M3UA_CT |
| { |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, // streamID |
| enc_PDU_M3UA(valueof(t_PDU_M3UA_ASPUP(omit, omit))), |
| tsp_SCTP_PayloadProtocolID)); |
| v_Entity.commStatus := aSP_Down_ASPUP_Sent; |
| if (tsp_logVerbose) { |
| log("M3UA_ASPUP sent"); |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| } |
| |
| |
| // Test if an association with assocID exists or not. We have only one |
| // association at the moment, we just check if the given assocID is the same, |
| // that is associated with our single entity. If we would have more entities |
| // in a table, the index of it should be returned instead of a boolean value. |
| function f_Assoc_Exists(integer pl_assocID) runs on M3UA_CT return boolean |
| { |
| if (v_Entity.sCTP_Assoc_ID == pl_assocID) { |
| return true; |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("Association #", v_Entity.sCTP_Assoc_ID, " not found"); |
| } |
| } |
| return false; |
| } |
| |
| function f_handle_M3UA_msg(PDU_M3UA pl_PDU_M3UA) runs on M3UA_CT |
| { |
| if (ischosen(pl_PDU_M3UA.m3UA_DATA)) { |
| if (v_Entity.commStatus == aSP_Active) { |
| // Send ASP_MTP3_TRANSFERind message. |
| MTP3_SP_PORT.send |
| (valueof |
| (tr_ASP_MTP3_TRANSFERind_sio |
| (substr(oct2bit(pl_PDU_M3UA.m3UA_DATA.messageParameters.protocol_Data.nI), 6, 2), |
| substr(oct2bit(pl_PDU_M3UA.m3UA_DATA.messageParameters.protocol_Data.mP), 6, 2), |
| substr(oct2bit(pl_PDU_M3UA.m3UA_DATA.messageParameters.protocol_Data.sI), 4, 4), |
| oct2int(pl_PDU_M3UA.m3UA_DATA.messageParameters.protocol_Data.oPC), |
| oct2int(pl_PDU_M3UA.m3UA_DATA.messageParameters.protocol_Data.dPC), |
| oct2int(pl_PDU_M3UA.m3UA_DATA.messageParameters.protocol_Data.sLS), |
| pl_PDU_M3UA.m3UA_DATA.messageParameters.protocol_Data.userProtocolData))); |
| if (tsp_logVerbose) { |
| log("MTP3_SP_PORT: Data received -> TRANSFERind sent"); |
| } |
| } |
| else { |
| // Buffering indication messages? |
| if (tsp_logVerbose) { |
| log("MTP3_SP_PORT: Data received, no user connected -> discard"); |
| } |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_BEAT)) { |
| if (v_Entity.commStatus == aSP_Active) { |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, |
| enc_PDU_M3UA |
| (valueof |
| (t_PDU_M3UA_Beat_Ack |
| (pl_PDU_M3UA.m3UA_BEAT.messageParameters.heartbeat_Data))), |
| tsp_SCTP_PayloadProtocolID)); |
| if (tsp_logVerbose) { |
| log("M3UA_BEAT received -> M3UA_BEAT_Ack sent"); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("M3UA_BEAT received in wrong state"); |
| } |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_BEAT_Ack)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_BEAT_Ack -> discard"); |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_ERR)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_ERR -> discard"); |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_NOTIFY)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_NOTIFY -> discard"); |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_DUNA)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_DUNA -> discard"); |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_DAVA)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_DAVA -> discard"); |
| } |
| } |
| // In server mode ASP_M3UA_DAUD messages can be received. In response the |
| // server must send ASP_M3UA_DAVA messages. It's not checked if we're |
| // servers or not. |
| else if (ischosen(pl_PDU_M3UA.m3UA_DAUD)) { |
| if ((v_Entity.commStatus == aSP_Inactive) or |
| (v_Entity.commStatus == aSP_Inact_ASPAC_Sent) or |
| (v_Entity.commStatus == aSP_Active)) { |
| // Send ASP_M3UA_DAVA message. |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, |
| enc_PDU_M3UA |
| (valueof |
| (t_PDU_M3UA_DAVA |
| (pl_PDU_M3UA.m3UA_DAUD.messageParameters.network_Appearance, |
| pl_PDU_M3UA.m3UA_DAUD.messageParameters.routing_Context, |
| pl_PDU_M3UA.m3UA_DAUD.messageParameters.affected_Point_Codes, |
| pl_PDU_M3UA.m3UA_DAUD.messageParameters.info_String))), |
| tsp_SCTP_PayloadProtocolID)); |
| if (tsp_logVerbose) { |
| log("M3UA_DAUD received -> DAVA sent"); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("M3UA_DAUD received in wrong state"); |
| } |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_SCON)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_SCON -> discard"); |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_DUPU)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_DUPU -> discard"); |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_DRST)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_DRST -> discard"); |
| } |
| } |
| // In server mode we can receive M3UA_ASPUP messages. The answer will be a |
| // M3UA_ASPUP_Ack message to the client. |
| else if (ischosen(pl_PDU_M3UA.m3UA_ASPUP)) { |
| if (((v_Entity.commStatus == aSP_Down_commUP_Received) or |
| (v_Entity.commStatus == aSP_Down_ASPUP_Sent)) and |
| tsp_M3UA_Server_Mode) { |
| v_Entity.commStatus := aSP_Inactive; |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, |
| enc_PDU_M3UA(valueof(t_PDU_M3UA_ASPUP_Ack)), |
| tsp_SCTP_PayloadProtocolID)); |
| if (tsp_logVerbose) { |
| log("M3UA_ASPUP received -> M3UA_ASPUP_Ack sent"); |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("M3UA_ASPUP received in wrong state or the emulation is not in " & |
| "M3UA server mode"); |
| } |
| } |
| } |
| // Receives a M3UA_ASPDN message and sends a M3UA_ASPDN_Ack message in |
| // response. |
| else if (ischosen(pl_PDU_M3UA.m3UA_ASPDN)) { |
| if ((v_Entity.commStatus == aSP_Inactive) or |
| (v_Entity.commStatus == aSP_Inact_ASPAC_Sent) or |
| (v_Entity.commStatus == aSP_Active)) { |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, |
| enc_PDU_M3UA(valueof(t_PDU_M3UA_ASPDN_Ack)), |
| tsp_SCTP_PayloadProtocolID)); |
| if (v_Entity.commStatus == aSP_Active) { |
| // MTP3_SP_PORT.send(ASP_MTP3_PAUSE : {}); |
| } |
| v_Entity.commStatus := aSP_Down_commUP_Received; |
| if (tsp_logVerbose) { |
| log("M3UA_ASPDN received -> ASPDN_Ack sent"); |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("ASPDN received in wrong state or the emulation is not in M3UA " & |
| "server mode"); |
| } |
| } |
| } |
| // The M3UA client receives M3UA_ASPUP_Ack messages from the server. In |
| // response of a M3UA_ASPUP message sent by the client. |
| else if (ischosen(pl_PDU_M3UA.m3UA_ASPUP_Ack)) { |
| if (((v_Entity.commStatus == aSP_Down_ASPUP_Sent) or |
| (v_Entity.commStatus == aSP_Inactive)) and |
| not tsp_M3UA_Server_Mode) { |
| v_Entity.commStatus := aSP_Inactive; |
| if (tsp_logVerbose) { |
| log("M3UA_ASPUP_Ack received -> send M3UA_ASPAC"); |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, |
| enc_PDU_M3UA(valueof(t_PDU_M3UA_ASPAC(omit, omit, omit))), |
| tsp_SCTP_PayloadProtocolID)); |
| // The state changes again after sending the M3UA_ASPAC message. |
| v_Entity.commStatus := aSP_Inact_ASPAC_Sent; |
| if (tsp_logVerbose) { |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("M3UA_ASPUP_Ack received in wrong state or the emulation is not " & |
| "in M3UA client mode"); |
| } |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_ASPDN_Ack)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_ASPDN_Ack -> discard"); |
| } |
| } |
| // M3UA_ASPAC messages are received on the server side. The server sends a |
| // M3UA_ASPAC_Ack message back to the client. This step makes the |
| // association active on both sides. |
| else if (ischosen(pl_PDU_M3UA.m3UA_ASPAC)) { |
| if (((v_Entity.commStatus == aSP_Inactive) or |
| (v_Entity.commStatus == aSP_Inact_ASPAC_Sent)) and |
| tsp_M3UA_Server_Mode) { |
| v_Entity.commStatus := aSP_Active; |
| if (tsp_logVerbose) { |
| log("M3UA_ASPAC received -> M3UA_ASPAC_Ack sent"); |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| var integer v_i; |
| for (v_i := 0; v_i < sizeof(v_TRANSFERreq_Buffer); v_i := v_i + 1) { |
| log("Sending buffered message #", v_i); |
| f_Send_MTP3_TRANSFERreq(v_TRANSFERreq_Buffer[v_i]); |
| } |
| v_TRANSFERreq_Buffer := {}; |
| // Send M3UA_ASPAC_Ack. |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, |
| enc_PDU_M3UA |
| (valueof |
| (t_PDU_M3UA_ASPAC_Ack |
| (pl_PDU_M3UA.m3UA_ASPAC.messageParameters.traffic_Mode_Type, |
| pl_PDU_M3UA.m3UA_ASPAC.messageParameters.routing_Context))), |
| tsp_SCTP_PayloadProtocolID)); |
| // MTP3_SP_PORT.send(ASP_MTP3_RESUME : {}); |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("M3UA_ASPAC received in wrong state or the emulation is not in " & |
| "M3UA server mode"); |
| } |
| } |
| } |
| // The client receives M3UA_ASPAC_Ack messages from the server. The |
| // association will be activated. The buffered messages should be send here. |
| else if (ischosen(pl_PDU_M3UA.m3UA_ASPAC_Ack)) { |
| if (((v_Entity.commStatus == aSP_Inact_ASPAC_Sent) or |
| (v_Entity.commStatus == aSP_Active)) and |
| not tsp_M3UA_Server_Mode) { |
| // MTP3_SP_PORT.send(ASP_MTP3_RESUME : {}); |
| v_Entity.commStatus := aSP_Active; |
| if (tsp_logVerbose) { |
| log("ASPAC_Ack received for association #", v_Entity.sCTP_Assoc_ID); |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| var integer v_i; |
| for (v_i := 0; v_i < sizeof(v_TRANSFERreq_Buffer); v_i := v_i + 1) { |
| log("Sending buffered message #", v_i); |
| f_Send_MTP3_TRANSFERreq(v_TRANSFERreq_Buffer[v_i]); |
| } |
| v_TRANSFERreq_Buffer := {}; |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("M3UA_ASPAC_Ack received in wrong state on association #", |
| v_Entity.sCTP_Assoc_ID, " or the emulation is not in M3UA " & |
| "client mode"); |
| } |
| } |
| } |
| // Receives a M3UA_ASPIA message and sends back a M3UA_ASPIA_Ack message in |
| // response. |
| else if (ischosen(pl_PDU_M3UA.m3UA_ASPIA)) { |
| if (v_Entity.commStatus == aSP_Active) { |
| SCTP_PORT.send |
| (t_S_SCTP_Send |
| (v_Entity.sCTP_Assoc_ID, |
| 0, |
| enc_PDU_M3UA |
| (valueof |
| (t_PDU_M3UA_ASPIA_Ack |
| (pl_PDU_M3UA.m3UA_ASPIA.messageParameters.routing_Context))), |
| tsp_SCTP_PayloadProtocolID)); |
| // MTP3_SP_PORT.send(ASP_MTP3_PAUSE : {}); |
| v_Entity.commStatus := aSP_Inactive; |
| if (tsp_logVerbose) { |
| log("M3UA_ASPIA received -> M3UA_ASPIA_Ack sent"); |
| log("Association #", v_Entity.sCTP_Assoc_ID, " state changed to: ", |
| v_Entity.commStatus); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("M3UA_ASPIA received in wrong state or the emulation is not " & |
| "running in M3UA server mode"); |
| } |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_ASPIA_Ack)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_ASPIA_Ack -> discard"); |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_REG_REQ)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_REG_REQ -> discard"); |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_REG_RSP)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_REG_RSP -> discard"); |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_DEREG_REQ)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_DEREG_REQ -> discard"); |
| } |
| } |
| else if (ischosen(pl_PDU_M3UA.m3UA_DEREG_RSP)) { |
| if (tsp_logVerbose) { |
| log("Received M3UA_DEREG_RSP -> discard"); |
| } |
| } |
| } |
| |
| function f_handle_nonM3UA_msg(octetstring pl_PDU) runs on M3UA_CT |
| { |
| if (v_Entity.commStatus == aSP_Active) { |
| // Send TRANSFERind message. |
| MTP3_SP_PORT.send(valueof |
| (tr_ASP_MTP3_TRANSFERind_sio |
| ('00'B, |
| '00'B, |
| '0000'B, |
| 0, |
| 0, |
| 0, |
| pl_PDU))); |
| if (tsp_logVerbose) { |
| log("Non-M3UA DATA received -> TRANSFERind sent"); |
| } |
| } |
| else { |
| if (tsp_logVerbose) { |
| log("DATA received, but no user connected -> discard"); |
| } |
| } |
| } |
| |
| } |