| /////////////////////////////////////////////////////////////////////////////// |
| // Copyright (c) 2000-2019 Ericsson Telecom AB |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v2.0 |
| // which accompanies this distribution, and is available at |
| // https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // File: SCTP_Engine_Core.ttcn |
| // Description: Core functions of the SCTP Engine |
| // Rev: <RnXnn> |
| // Prodnr: CNL 113 840 |
| // |
| module SCTP_Engine_Core{ |
| |
| import from SCTP_Engine_Definition all; |
| import from SCTP_Engine_PortTypes all |
| import from SCTP_Engine_Functions all |
| import from SCTP_Types all |
| |
| //***************************************************************************// |
| // |
| // The main function, it should be started |
| // |
| //***************************************************************************// |
| function SCTP_Core_main() runs on SCTP_Engine_CT { |
| // Start the run timer |
| t_run_time.start(2147482.0) // ~24 days. Can be set higher, but in that case |
| // the TITAN will flood the log with stupid warning |
| |
| // Activate the handler altsteps |
| alt{ |
| [] SCTP_core_lower_handler() |
| [] SCTP_Core_timer_handler() |
| [] SCTP_Core_upper_handler() |
| } |
| |
| |
| } |
| |
| |
| |
| //***************************************************************************// |
| // |
| // Upper port event handler functions |
| // |
| //***************************************************************************// |
| |
| altstep SCTP_Core_upper_handler() runs on SCTP_Engine_CT { |
| var SCTP_Listen_data vl_listen_data; |
| var SCTP_Connect_data vl_connect_data; |
| var SCTP_Engine_CT vl_sender; |
| var SCTP_MSG_data vl_send_msg_data ; |
| var SCTP_Shutdown_data vl_shutdown_data ; |
| var SCTP_Reconfiguration_req vl_reconfig; |
| var integer vl_assoc_id; |
| |
| [] p_sctp_req_api.getcall(S_SCTP_Listen:{?}) -> param (vl_listen_data) sender vl_sender{ |
| SCTP_api_handle_listen(vl_listen_data,vl_sender) |
| repeat; |
| } |
| [] p_sctp_req_api.getcall(S_SCTP_Connect:{?}) -> param (vl_connect_data) sender vl_sender{ |
| SCTP_api_handle_connect(vl_connect_data,vl_sender) |
| repeat; |
| } |
| [] p_sctp_req_api.getcall(S_SCTP_Send_req:{?}) -> param (vl_send_msg_data) sender vl_sender{ |
| SCTP_api_handle_send_msg(vl_send_msg_data,vl_sender) |
| repeat; |
| } |
| |
| [] p_sctp_req_api.getcall(S_SCTP_Shutdown:{?}) -> param (vl_shutdown_data) sender vl_sender{ |
| SCTP_api_handle_shutdown(vl_shutdown_data,vl_sender) |
| repeat; |
| } |
| |
| [] p_sctp_req_api.getcall(S_SCTP_Shutdown_conf:{?}) -> param (vl_assoc_id) sender vl_sender{ |
| SCTP_api_handle_shutdown_conf(vl_assoc_id,vl_sender) |
| repeat; |
| } |
| |
| [] p_sctp_req_api.getcall(S_SCTP_reconfig:{?}) -> param (vl_reconfig) sender vl_sender{ |
| SCTP_api_handle_reconfig(vl_reconfig,vl_sender) |
| repeat; |
| } |
| |
| } |
| |
| //***************************************************************************// |
| // |
| // Time event handler functions |
| // |
| //***************************************************************************// |
| altstep SCTP_Core_timer_handler() runs on SCTP_Engine_CT { |
| [] t_next_event.timeout { |
| // Store the event data |
| var integer vl_assoc_id:=v_event_db.events[v_event_db.the_sceduled_event].assoc_id |
| var integer vl_timer_id:=v_event_db.events[v_event_db.the_sceduled_event].timer_id |
| // remove the event from the queue |
| SCTP_event_remove(v_event_db.the_sceduled_event) |
| |
| // Call the timer handler |
| select(vl_timer_id){ |
| case (c_timer_T1) { |
| SCTP_timeout_T1_init(vl_assoc_id) |
| } |
| case (c_timer_T1_cookie) { |
| SCTP_timeout_T1_cookie(vl_assoc_id) |
| } |
| case (c_timer_T3_rtx) { |
| SCTP_timeout_T3_rtx(vl_assoc_id) |
| } |
| case (c_timer_T2_shutdown) { |
| SCTP_timeout_T2_shutdown(vl_assoc_id) |
| } |
| case (c_timer_heartbeat) { |
| SCTP_timeout_heartbeat(vl_assoc_id) |
| } |
| case (c_timer_reconfig) { |
| SCTP_timeout_reconfig(vl_assoc_id) |
| } |
| case (c_timer_close) { |
| SCTP_timeout_close(vl_assoc_id) |
| } |
| } |
| repeat; |
| } |
| } |
| |
| |
| //***************************************************************************// |
| // |
| // Lower port event handler functions |
| // |
| //***************************************************************************// |
| |
| altstep SCTP_core_lower_handler() runs on SCTP_Engine_CT { |
| var SCTP_Engine_packet vl_recv_packet; |
| var SCTP_Packet vl_sctp_pdu; |
| var integer vl_decode_res; |
| |
| [] p_packet_port.receive(SCTP_Engine_packet:?) -> value vl_recv_packet { |
| // Process the incoming sctp packet |
| vl_decode_res:=f_SCTP_dec(vl_recv_packet.sctp_packet,vl_sctp_pdu); |
| //log("received: ",vl_decode_res) |
| if(vl_decode_res==0){ // Decode OK |
| // Find the association |
| var integer vl_assoc_id:=SCTP_find_id_map(vl_recv_packet.transport_id, |
| // incoming packet, the destination port is the local port |
| vl_sctp_pdu.common_header.destination_port, |
| vl_sctp_pdu.common_header.source_port) |
| |
| //log("assoc id ",vl_assoc_id) |
| if(vl_assoc_id != -1 ){ // we found the assoctiation |
| SCTP_message_incoming_handler(vl_assoc_id,vl_sctp_pdu); |
| repeat; |
| } else { |
| // if it is an INIT or COOKIE ECHO chunk, try to find the listening |
| // association |
| if((lengthof(vl_sctp_pdu.chunks)>0) and |
| (ischosen(vl_sctp_pdu.chunks[0].init) |
| or ischosen(vl_sctp_pdu.chunks[0].cookie_echo) ) |
| ){ |
| // Lets find the listening association |
| vl_assoc_id:=SCTP_find_id_map(vl_recv_packet.transport_id, |
| // incoming packet, the destination port is the local port |
| vl_sctp_pdu.common_header.destination_port, |
| // the remote port is 0 for listening assoc |
| 0) |
| if(vl_assoc_id == -1){ |
| // The listening assoc_id is not found |
| // Look for assoc listening on all transport |
| vl_assoc_id:=SCTP_find_id_map(-1, // All transport |
| // incoming packet, the destination port is the local port |
| vl_sctp_pdu.common_header.destination_port, |
| // the remote port is 0 for listening assoc |
| 0) |
| |
| } |
| |
| |
| if(vl_assoc_id != -1 ){ // we found the assoctiation |
| SCTP_message_incoming_init_cookie_handler(vl_assoc_id, |
| vl_recv_packet.transport_id, vl_sctp_pdu); |
| repeat; |
| } |
| } |
| } |
| // Not processed message, Out of the blue packet |
| // Send abort |
| SCTP_message_process_oob_packet(vl_recv_packet.transport_id, vl_sctp_pdu); |
| } else { |
| // What the hell we received? |
| log("Undecodable packet: ", vl_recv_packet); |
| // just drop it |
| } |
| repeat; |
| } |
| |
| [] p_packet_port.receive(SCTP_Addr_change_notification:?) { |
| repeat; |
| } |
| |
| } |
| |
| } |