Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 1 | module BSC_Tests { |
| 2 | |
| 3 | import from Osmocom_Types all; |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 4 | import from GSM_Types all; |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 5 | import from IPL4asp_Types all; |
| 6 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 7 | import from BSSAP_Adapter all; |
| 8 | import from BSSAP_CodecPort all; |
| 9 | import from BSSMAP_Templates all; |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 10 | import from IPA_Emulation all; |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 11 | import from IPA_Types all; |
| 12 | import from RSL_Types all; |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 13 | |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 14 | import from Osmocom_CTRL_Functions all; |
Harald Welte | a5d2ab2 | 2017-12-09 14:21:42 +0100 | [diff] [blame^] | 15 | import from Osmocom_CTRL_Types all; |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 16 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 17 | import from RSL_Tests all; |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 18 | |
Harald Welte | 696ddb6 | 2017-12-08 14:01:43 +0100 | [diff] [blame] | 19 | const integer NUM_BTS := 1; |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 20 | const float T3101_MAX := 12.0; |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 21 | |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 22 | type record BTS_State { |
Harald Welte | a5d2ab2 | 2017-12-09 14:21:42 +0100 | [diff] [blame^] | 23 | IPA_Client rsl |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 24 | } |
| 25 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 26 | type component test_CT extends BSSAP_Adapter_CT { |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 27 | var BTS_State bts[NUM_BTS]; |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 28 | port IPA_RSL_PT IPA_RSL[NUM_BTS]; |
Harald Welte | a5d2ab2 | 2017-12-09 14:21:42 +0100 | [diff] [blame^] | 29 | |
| 30 | var IPA_Client ctrl; |
| 31 | port IPA_CTRL_PT IPA_CTRL; |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 32 | |
| 33 | var boolean g_initialized := false; |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 34 | timer T_guard := 30.0; |
| 35 | |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 36 | } |
| 37 | |
| 38 | modulepar { |
Harald Welte | 696ddb6 | 2017-12-08 14:01:43 +0100 | [diff] [blame] | 39 | charstring mp_bsc_ip := "127.0.0.1"; |
| 40 | integer mp_bsc_rsl_port := 3003; |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 41 | integer mp_bsc_ctrl_port := 4249; |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 42 | } |
| 43 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 44 | type record IPA_Client { |
| 45 | IPA_Emulation_CT vc_IPA, |
| 46 | IPA_CCM_Parameters ccm_pars, |
| 47 | charstring id |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 48 | } |
| 49 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 50 | function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i) |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 51 | runs on test_CT { |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 52 | timer T := 10.0; |
| 53 | |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 54 | clnt.id := "IPA" & int2str(i) & "-RSL"; |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 55 | clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA"); |
| 56 | clnt.ccm_pars := c_IPA_default_ccm_pars; |
| 57 | clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator"; |
| 58 | clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0"; |
| 59 | |
| 60 | map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT); |
| 61 | connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]); |
| 62 | |
| 63 | clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", -1, clnt.ccm_pars)); |
| 64 | |
| 65 | /* wait for IPA RSL link to connect and send ID ACK */ |
| 66 | T.start; |
| 67 | alt { |
| 68 | [] IPA_RSL[i].receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_ID_ACK}) { |
| 69 | T.stop; |
| 70 | IPA_RSL[i].send(ts_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,ts_RSL_PAGING_LOAD_IND(23))); |
| 71 | } |
| 72 | [] IPA_RSL[i].receive { repeat } |
| 73 | [] T.timeout { |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 74 | setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK"); |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 75 | self.stop; |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 80 | function f_ipa_ctrl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i) |
| 81 | runs on test_CT { |
| 82 | timer T := 10.0; |
| 83 | |
| 84 | clnt.id := "IPA" & int2str(i) & "-CTRL"; |
| 85 | clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA"); |
| 86 | |
| 87 | map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT); |
Harald Welte | a5d2ab2 | 2017-12-09 14:21:42 +0100 | [diff] [blame^] | 88 | connect(clnt.vc_IPA:IPA_CTRL_PORT, self:IPA_CTRL); |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 89 | |
| 90 | clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", -1)); |
| 91 | |
| 92 | /* wait for IPA CTRL link to connect and send UP */ |
| 93 | T.start; |
| 94 | alt { |
Harald Welte | a5d2ab2 | 2017-12-09 14:21:42 +0100 | [diff] [blame^] | 95 | [] IPA_CTRL.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}) { } |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 96 | [] T.timeout { |
| 97 | setverdict(fail, "Timeout CTRL waiting for ASP_IPA_EVENT_UP"); |
| 98 | self.stop; |
| 99 | } |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | |
Harald Welte | a5d2ab2 | 2017-12-09 14:21:42 +0100 | [diff] [blame^] | 104 | function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT { |
| 105 | timer T := secs_max; |
| 106 | T.start; |
| 107 | while (true) { |
| 108 | if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) { |
| 109 | T.stop; |
| 110 | return; |
| 111 | } |
| 112 | f_sleep(0.1); |
| 113 | if (not T.running) { |
| 114 | setverdict(fail, "Timeout waiting for oml-connection-state ", status); |
| 115 | self.stop; |
| 116 | } |
| 117 | } |
| 118 | } |
| 119 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 120 | function f_sleep(float seconds) { |
| 121 | timer T := seconds; |
| 122 | T.start; |
| 123 | T.timeout; |
| 124 | } |
| 125 | |
| 126 | altstep as_Tguard() runs on test_CT { |
| 127 | [] T_guard.timeout { setverdict(fail, "Timeout of T_guard"); } |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | function f_init() runs on test_CT { |
| 131 | var integer i; |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 132 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 133 | if (g_initialized) { |
| 134 | return; |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 135 | } |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 136 | g_initialized := true; |
| 137 | |
| 138 | /* Call a function of our 'parent component' BSSAP_Adapter_CT to start the |
| 139 | * MSC-side BSSAP emulation */ |
| 140 | f_bssap_init("VirtMSC"); |
Harald Welte | a5d2ab2 | 2017-12-09 14:21:42 +0100 | [diff] [blame^] | 141 | f_ipa_ctrl_start(ctrl, mp_bsc_ip, mp_bsc_ctrl_port, 0); |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 142 | |
Harald Welte | 696ddb6 | 2017-12-08 14:01:43 +0100 | [diff] [blame] | 143 | for (i := 0; i < NUM_BTS; i := i+1) { |
Harald Welte | a5d2ab2 | 2017-12-09 14:21:42 +0100 | [diff] [blame^] | 144 | /* wait until osmo-bts-omldummy has respawned */ |
| 145 | f_wait_oml(i, "degraded", 5.0); |
| 146 | /* start RSL connection */ |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 147 | f_ipa_rsl_start(bts[i].rsl, mp_bsc_ip, mp_bsc_rsl_port, i); |
Harald Welte | a5d2ab2 | 2017-12-09 14:21:42 +0100 | [diff] [blame^] | 148 | /* wait until BSC tells us "connected" */ |
| 149 | f_wait_oml(i, "connected", 5.0); |
Harald Welte | 696ddb6 | 2017-12-08 14:01:43 +0100 | [diff] [blame] | 150 | } |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 151 | f_sleep(0.5); |
Harald Welte | 696ddb6 | 2017-12-08 14:01:43 +0100 | [diff] [blame] | 152 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 153 | T_guard.start; |
| 154 | activate(as_Tguard()); |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 155 | } |
| 156 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 157 | function f_exp_ipa_rx(integer bts_nr, template RSL_Message t_rx, float t_secs := 2.0, IpaStreamId sid := IPAC_PROTO_RSL_TRX0) |
| 158 | runs on test_CT return RSL_Message { |
| 159 | var ASP_RSL_Unitdata rx_rsl_ud; |
| 160 | timer T := t_secs; |
| 161 | |
| 162 | T.start; |
| 163 | alt { |
| 164 | [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(sid, t_rx)) -> value rx_rsl_ud { |
| 165 | T.stop; |
| 166 | } |
| 167 | [] IPA_RSL[bts_nr].receive { repeat; } |
| 168 | [] T.timeout { setverdict(fail, "Timeout expecting ", t_rx); } |
| 169 | } |
| 170 | return rx_rsl_ud.rsl; |
| 171 | } |
| 172 | |
| 173 | function f_ipa_tx(integer bts_nr, template RSL_Message t_tx, IpaStreamId sid := IPAC_PROTO_RSL_TRX0) |
| 174 | runs on test_CT { |
| 175 | IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(sid, t_tx)); |
| 176 | } |
| 177 | |
| 178 | |
| 179 | testcase TC_chan_act_noreply() runs on test_CT { |
| 180 | var BSSAP_N_UNITDATA_ind ud_ind; |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 181 | |
| 182 | f_init(); |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 183 | f_bssap_reset(); |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 184 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 185 | IPA_RSL[0].send(ts_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,ts_RSL_CHAN_RQD('23'O, 23))); |
| 186 | f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV)); |
| 187 | setverdict(pass); |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 188 | } |
| 189 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 190 | /* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */ |
| 191 | testcase TC_chan_act_ack_noest() runs on test_CT { |
| 192 | var RSL_Message rx_rsl; |
| 193 | |
| 194 | f_init(); |
| 195 | f_bssap_reset(); |
| 196 | |
| 197 | /* Send CHAN RQD and wait for allocation; acknowledge it */ |
| 198 | f_ipa_tx(0, ts_RSL_CHAN_RQD('23'O, 23)); |
| 199 | rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV)); |
| 200 | var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr; |
| 201 | f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 23)); |
| 202 | |
| 203 | /* expect BSC to disable the channel again if there's no RLL EST IND */ |
| 204 | rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX); |
| 205 | |
| 206 | setverdict(pass); |
| 207 | } |
| 208 | |
| 209 | /* Test behavior if MSC never answers to CR */ |
| 210 | testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT { |
| 211 | var RSL_Message rx_rsl; |
| 212 | |
| 213 | f_init(); |
| 214 | f_bssap_reset(); |
| 215 | |
| 216 | /* Send CHAN RQD and wait for allocation; acknowledge it */ |
| 217 | f_ipa_tx(0, ts_RSL_CHAN_RQD('23'O, 23)); |
| 218 | rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV)); |
| 219 | var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr; |
| 220 | f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 23)); |
| 221 | |
| 222 | var octetstring l3 := '00010203040506'O |
| 223 | f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3)); |
| 224 | |
| 225 | BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))); |
| 226 | |
| 227 | /* expect BSC to disable the channel again if there's no response from MSC */ |
| 228 | rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX); |
| 229 | |
| 230 | setverdict(pass); |
| 231 | } |
| 232 | |
| 233 | /* Test behavior if MSC answers with CREF to CR */ |
| 234 | testcase TC_chan_act_ack_est_ind_refused() runs on test_CT { |
| 235 | var BSSAP_N_CONNECT_ind rx_c_ind; |
| 236 | var RSL_Message rx_rsl; |
| 237 | |
| 238 | f_init(); |
| 239 | f_bssap_reset(); |
| 240 | |
| 241 | /* Send CHAN RQD and wait for allocation; acknowledge it */ |
| 242 | f_ipa_tx(0, ts_RSL_CHAN_RQD('23'O, 23)); |
| 243 | rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV)); |
| 244 | var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr; |
| 245 | f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 23)); |
| 246 | |
| 247 | var octetstring l3 := '00010203040506'O |
| 248 | f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3)); |
| 249 | |
| 250 | BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind; |
| 251 | BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0)); |
| 252 | |
| 253 | /* expect BSC to disable the channel */ |
| 254 | rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX); |
| 255 | |
| 256 | setverdict(pass); |
| 257 | } |
| 258 | |
Harald Welte | a5d2ab2 | 2017-12-09 14:21:42 +0100 | [diff] [blame^] | 259 | |
| 260 | /* BSC specific CTRL helper functions */ |
| 261 | function f_ctrl_get_bts(IPA_CTRL_PT pt, integer bts_nr, charstring suffix) return CtrlValue { |
| 262 | return f_ctrl_get(pt, "bts." & int2str(bts_nr) & "." & suffix); |
| 263 | } |
| 264 | |
| 265 | template charstring ts_bts(integer bts_nr) := "bts." & int2str(bts_nr) & "."; |
| 266 | template charstring ts_bts_trx(integer bts_nr, integer trx_nr ) := |
| 267 | valueof(ts_bts(bts_nr)) & "trx." & int2str(trx_nr) & "."; |
| 268 | |
| 269 | function f_ctrl_get_exp_bts(IPA_CTRL_PT pt, integer bts_nr, CtrlVariable suffix, template CtrlValue exp) { |
| 270 | f_ctrl_get_exp(pt, valueof(ts_bts(bts_nr)) & suffix, exp); |
| 271 | } |
| 272 | |
| 273 | function f_ctrl_get_exp_trx(IPA_CTRL_PT pt, integer bts_nr, integer trx_nr, CtrlVariable suffix, |
| 274 | template CtrlValue exp) |
| 275 | { |
| 276 | f_ctrl_get_exp(pt, valueof(ts_bts_trx(bts_nr, trx_nr)) & suffix, exp); |
| 277 | } |
| 278 | |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 279 | testcase TC_ctrl() runs on test_CT { |
| 280 | |
| 281 | f_init(); |
| 282 | f_bssap_reset(); |
| 283 | |
| 284 | f_ctrl_get(IPA_CTRL[0], "bts.0.location-area-code"); |
| 285 | } |
| 286 | |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 287 | |
| 288 | |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 289 | control { |
Harald Welte | 96c9441 | 2017-12-09 03:12:45 +0100 | [diff] [blame] | 290 | execute( TC_ctrl() ); |
Harald Welte | ae02669 | 2017-12-09 01:03:01 +0100 | [diff] [blame] | 291 | execute( TC_chan_act_noreply() ); |
| 292 | execute( TC_chan_act_ack_noest() ); |
| 293 | execute( TC_chan_act_ack_est_ind_noreply() ); |
| 294 | execute( TC_chan_act_ack_est_ind_refused() ); |
Harald Welte | 28d943e | 2017-11-25 15:00:50 +0100 | [diff] [blame] | 295 | } |
| 296 | |
| 297 | } |