Stefan Sperling | c307e68 | 2018-06-14 15:15:46 +0200 | [diff] [blame] | 1 | /* (C) 2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> |
| 2 | * Author: Stefan Sperling <ssperling@sysmocom.de> |
| 3 | * All Rights Reserved |
| 4 | * |
| 5 | * Released under the terms of GNU General Public License, Version 2 or |
| 6 | * (at your option) any later version. |
Harald Welte | 34b5a95 | 2019-05-27 11:54:11 +0200 | [diff] [blame] | 7 | * |
| 8 | * SPDX-License-Identifier: GPL-2.0-or-later |
Stefan Sperling | c307e68 | 2018-06-14 15:15:46 +0200 | [diff] [blame] | 9 | */ |
| 10 | |
| 11 | module SCCP_Tests { |
| 12 | |
| 13 | import from M3UA_Emulation all; |
| 14 | |
| 15 | import from SCCPasp_Types all; |
| 16 | import from SCCP_Types all; |
| 17 | import from SCCP_Emulation all; |
| 18 | import from SCCP_Templates all; |
| 19 | |
| 20 | import from SCTPasp_PortType all; |
| 21 | |
| 22 | import from Osmocom_CTRL_Adapter all; |
| 23 | |
| 24 | import from TELNETasp_PortType all; |
| 25 | import from Osmocom_VTY_Functions all; |
| 26 | |
| 27 | type component system_CT { |
| 28 | port SCTPasp_PT sctp; |
| 29 | }; |
| 30 | |
| 31 | type component MTC_CT extends CTRL_Adapter_CT { |
| 32 | /* VTY to sccp_demo_user (not used yet) */ |
| 33 | port TELNETasp_PT SCCP_DEMO_USER_VTY; |
| 34 | |
| 35 | /* SCCP protocol runs on top of M3UA Emulation. |
| 36 | * "System Under Test" is libosmo-sccp's sccp_demo_user example program. */ |
| 37 | var SCCP_CT vc_SCCP_A; |
| 38 | var M3UA_CT vc_M3UA; |
| 39 | port SCCPasp_PT A_PORT; |
| 40 | } |
| 41 | |
| 42 | type record SCCP_Configuration { |
| 43 | charstring sccp_service_type, |
| 44 | SCTP_Association_Address sctp_addr, |
| 45 | integer own_pc, |
| 46 | integer own_ssn, |
| 47 | integer peer_pc, |
| 48 | integer peer_ssn, |
| 49 | octetstring sio, |
| 50 | integer rctx |
| 51 | }; |
| 52 | |
| 53 | type record of SCCP_Configuration SCCP_Configurations; |
| 54 | modulepar { |
| 55 | SCCP_Configurations sccp_cfg; |
| 56 | } |
| 57 | |
| 58 | function f_init(SCCP_Configuration cfg) runs on MTC_CT { |
| 59 | var MSC_SCCP_MTP3_parameters v_param := { |
| 60 | sio := { |
| 61 | ni := substr(oct2bit(cfg.sio),0,2), |
| 62 | prio := substr(oct2bit(cfg.sio),2,2), |
| 63 | si := substr(oct2bit(cfg.sio),4,4) |
| 64 | }, |
| 65 | opc := cfg.own_pc, |
| 66 | dpc := cfg.peer_pc, |
| 67 | sls := 0, |
| 68 | sccp_serviceType := cfg.sccp_service_type, |
| 69 | ssn := cfg.own_ssn |
| 70 | }; |
| 71 | |
| 72 | map(self:SCCP_DEMO_USER_VTY, system:SCCP_DEMO_USER_VTY); |
| 73 | f_vty_set_prompts(SCCP_DEMO_USER_VTY); |
| 74 | f_vty_transceive(SCCP_DEMO_USER_VTY, "enable"); |
| 75 | |
| 76 | /* Create and connect test components for an SCCP connection with M3UA beneath. */ |
| 77 | vc_SCCP_A := SCCP_CT.create; |
| 78 | vc_M3UA := M3UA_CT.create; |
| 79 | connect(self:A_PORT, vc_SCCP_A:SCCP_SP_PORT); |
| 80 | connect(vc_M3UA:MTP3_SP_PORT, vc_SCCP_A:MTP3_SCCP_PORT); |
| 81 | map(vc_M3UA:SCTP_PORT, system:sctp); |
| 82 | |
| 83 | vc_M3UA.start(f_M3UA_Emulation(cfg.sctp_addr)); |
| 84 | vc_SCCP_A.start(SCCPStart(v_param)); |
| 85 | } |
| 86 | |
| 87 | function f_cleanup() runs on MTC_CT { |
| 88 | all component.stop; |
| 89 | unmap(vc_M3UA:SCTP_PORT, system:sctp); |
| 90 | disconnect(vc_M3UA:MTP3_SP_PORT, vc_SCCP_A:MTP3_SCCP_PORT); |
| 91 | disconnect(self:A_PORT, vc_SCCP_A:SCCP_SP_PORT); |
| 92 | self.stop |
| 93 | } |
| 94 | |
| 95 | /* |
| 96 | * libosmo-sccp does not support Global Title address as a routing indicator. |
| 97 | * But sccp_demo_user should not crash if such a message is received (see OS#2666). |
| 98 | */ |
| 99 | testcase TC_routing_global_title_crash() runs on MTC_CT system system_CT { |
| 100 | timer TL_timer:= 10.0; /* twice the sccp_demo_user connection attempt interval */ |
| 101 | var SCCP_PAR_Address v_CallingAddress; |
| 102 | var SCCP_PAR_Address v_CalledAddress; |
| 103 | var octetstring vl_userdata :='12345678901234567890'O; |
| 104 | var ASP_SCCP_N_UNITDATA_ind vl_N_UNITDATA_ind; |
| 105 | |
| 106 | f_init(sccp_cfg[0]); |
| 107 | |
| 108 | /* Called address with routing indicator set to Global Title Address. This used to trigger the crash. */ |
| 109 | v_CalledAddress := valueof(ts_SccpAddr_GT('012345'H)); |
| 110 | |
| 111 | v_CallingAddress := valueof(ts_SccpAddr_PC_SSN(sccp_cfg[0].own_pc, sccp_cfg[0].own_ssn, |
| 112 | sccp_cfg[0].sio, sccp_cfg[0].sccp_service_type)); |
| 113 | A_PORT.send(t_ASP_N_UNITDATA_req(v_CalledAddress, v_CallingAddress, '00000001'B /* sequence control */, |
| 114 | '00000001'B /* return option */, vl_userdata, omit)); |
| 115 | |
| 116 | /* |
| 117 | * Start a timeout within which our DATA packet will be sent out. |
| 118 | * The M3UA Emulation layer has buffered the packet and is going |
| 119 | * to send it when the sccp_demo_user SCCP client connects. |
| 120 | * |
| 121 | * libosmo-sccp will echo the packet back at us in an SCCP UDTS packet. |
| 122 | * However, the current M3UA Emulation implementation will discard this |
| 123 | * response because it arrives on a separate SCTP association and the |
| 124 | * emulation only supports one association at a time. |
| 125 | * |
| 126 | * As a workaround, we wait for a fixed amount of time and then issue |
| 127 | * another command to the VTY of sccp_demo_user. If sccp_demo_user |
| 128 | * has crashed, this will result in a test failure. |
| 129 | */ |
| 130 | TL_timer.start; |
| 131 | alt { |
| 132 | [] A_PORT.receive(tr_ASP_N_UNITDATA_ind) -> value vl_N_UNITDATA_ind { |
| 133 | log("Received data from SCCP client."); |
| 134 | repeat; |
| 135 | } |
| 136 | |
| 137 | [] TL_timer.timeout { |
| 138 | log("Timeout...."); |
| 139 | } |
| 140 | } |
| 141 | TL_timer.stop; |
| 142 | |
| 143 | /* Check that the VTY is still active (implying that the process hasn't crashed). */ |
| 144 | f_vty_transceive_ret(SCCP_DEMO_USER_VTY, "?"); |
| 145 | setverdict(pass); |
| 146 | |
| 147 | f_cleanup(); |
| 148 | } |
| 149 | |
| 150 | control { |
| 151 | execute( TC_routing_global_title_crash() ); |
| 152 | } |
| 153 | |
| 154 | |
| 155 | } |