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