diff --git a/bsc/BSC_Tests.cfg b/bsc/BSC_Tests.cfg index 497489fb3..c31c9ebdd 100644 --- a/bsc/BSC_Tests.cfg +++ b/bsc/BSC_Tests.cfg @@ -19,11 +19,15 @@ mtc.FileMask := LOG_ALL | TTCN_DEBUG | TTCN_MATCHING | DEBUG_ENCDEC; #mp_bsc_ip := "127.0.0.1"; #mp_test_ip := "127.0.0.1"; -#mp_sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" }; -#mp_own_pc := 185; -#mp_own_ssn := 254; -#mp_peer_pc := 187; -#mp_peer_ssn := 254; +#BSC_Tests.mp_bssap_cfg := { +# sccp_service_type := "mtp3_itu", +# sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" }, +# own_pc := 185, +# own_ssn := 254, +# peer_pc := 187, +# peer_ssn := 254, +# sio := '83'O +#}; #mp_ipa_mgcp_uses_osmo_ext := true; diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn index 086830a6b..cb2b41e61 100644 --- a/bsc/BSC_Tests.ttcn +++ b/bsc/BSC_Tests.ttcn @@ -56,7 +56,7 @@ type record BTS_State { IPA_Client rsl } -type component test_CT extends BSSAP_Adapter_CT, CTRL_Adapter_CT { +type component test_CT extends CTRL_Adapter_CT { /* Array of per-BTS state */ var BTS_State bts[NUM_BTS]; /* array of per-BTS RSL test ports */ @@ -64,6 +64,10 @@ type component test_CT extends BSSAP_Adapter_CT, CTRL_Adapter_CT { var MGCP_Emulation_CT vc_MGCP; + var BSSAP_Adapter g_bssap; + /* for old legacy-tests only */ + port BSSAP_CODEC_PT BSSAP; + /* are we initialized yet */ var boolean g_initialized := false; @@ -81,6 +85,36 @@ modulepar { integer mp_bsc_ctrl_port := 4249; /* IP address at which the test binds */ charstring mp_test_ip := "127.0.0.1"; + + BSSAP_Configuration mp_bssap_cfg := { + sccp_service_type := "mtp3_itu", + sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" }, + own_pc := 185, + own_ssn := 254, + peer_pc := 187, + peer_ssn := 254, + sio := '83'O + }; +} + +private function f_legacy_bssap_reset() runs on test_CT { + var BSSAP_N_UNITDATA_ind ud_ind; + timer T := 5.0; + BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0))); + T.start; + alt { + [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck)) { + log("Received RESET-ACK in response to RESET, we're ready to go!"); + } + [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind { + log("Respoding to inbound RESET with RESET-ACK"); + BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress, + ts_BSSMAP_ResetAck)); + repeat; + } + [] BSSAP.receive { repeat; } + [] T.timeout { setverdict(fail, "Waiting for RESET-ACK after sending RESET"); } + } } type record IPA_Client { @@ -215,9 +249,11 @@ function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false) runs o /* Call a function of our 'parent component' BSSAP_Adapter_CT to start the * MSC-side BSSAP emulation */ if (handler_mode) { - f_bssap_init("VirtMSC", MSC_BssmapOps); + f_bssap_init(g_bssap, mp_bssap_cfg, "VirtMSC", MSC_BssmapOps); } else { - f_bssap_init("VirtMSC", omit); + f_bssap_init(g_bssap, mp_bssap_cfg, "VirtMSC", omit); + connect(self:BSSAP, g_bssap.vc_SCCP:SCCP_SP_PORT); + f_legacy_bssap_reset(); } f_ipa_ctrl_start(mp_bsc_ip, mp_bsc_ctrl_port); @@ -268,7 +304,6 @@ testcase TC_chan_act_noreply() runs on test_CT { var BSSAP_N_UNITDATA_ind ud_ind; f_init(1); - f_bssap_reset(); IPA_RSL[0].send(ts_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,ts_RSL_CHAN_RQD('23'O, 23))); f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV)); @@ -281,7 +316,6 @@ testcase TC_chan_act_counter() runs on test_CT { var integer chreq_total; f_init(1); - f_bssap_reset(); chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total"); IPA_RSL[0].send(ts_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,ts_RSL_CHAN_RQD('23'O, 23))); @@ -296,7 +330,6 @@ testcase TC_chan_act_ack_noest() runs on test_CT { var RSL_Message rx_rsl; f_init(1); - f_bssap_reset(); /* Send CHAN RQD and wait for allocation; acknowledge it */ var RslChannelNr chan_nr := f_chreq_act_ack(); @@ -315,7 +348,6 @@ testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT { var ASP_RSL_Unitdata rx_rsl_ud; f_init(1); - f_bssap_reset(); /* Send CHAN RQD and wait for allocation; acknowledge it */ var RslChannelNr chan_nr := f_chreq_act_ack(); @@ -345,7 +377,6 @@ testcase TC_chan_act_ack_est_ind_refused() runs on test_CT { var RSL_Message rx_rsl; f_init(1); - f_bssap_reset(); /* Send CHAN RQD and wait for allocation; acknowledge it */ var RslChannelNr chan_nr := f_chreq_act_ack(); @@ -367,7 +398,6 @@ testcase TC_chan_act_nack() runs on test_CT { var integer chact_nack; f_init(1); - f_bssap_reset(); chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack"); @@ -392,7 +422,6 @@ testcase TC_chan_exhaustion() runs on test_CT { var integer chreq_total, chreq_nochan; f_init(1); - f_bssap_reset(); chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total"); chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel"); @@ -440,9 +469,8 @@ testcase TC_chan_exhaustion() runs on test_CT { /* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction) */ testcase TC_outbound_connect() runs on test_CT { f_init(1); - f_bssap_reset(); - BSSAP.send(ts_BSSAP_CONNECT_req(g_sccp_addr_peer, g_sccp_addr_own, 2342, ts_BSSMAP_AssignmentReq)); + BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, 2342, ts_BSSMAP_AssignmentReq)); BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?)); setverdict(pass); } @@ -454,7 +482,6 @@ testcase TC_assignment_cic_only() runs on test_CT { var DchanTuple dt; f_init(1); - f_bssap_reset(); dt := f_est_dchan('23'O, 23, '00000000'O); /* send assignment without AoIP IEs */ @@ -479,7 +506,6 @@ runs on test_CT { var DchanTuple dt; f_init(1); - f_bssap_reset(); dt := f_est_dchan('23'O, 23, '00000000'O); /* send assignment without AoIP IEs */ @@ -560,7 +586,6 @@ testcase TC_chan_rel_rll_rel_ind() runs on test_CT { var DchanTuple dt; f_init(1); - f_bssap_reset(); dt := f_est_dchan('23'O, 23, '00010203040506'O); @@ -585,7 +610,6 @@ testcase TC_chan_rel_conn_fail() runs on test_CT { var DchanTuple dt; f_init(1); - f_bssap_reset(); dt := f_est_dchan('23'O, 23, '00010203040506'O); @@ -657,7 +681,6 @@ testcase TC_chan_rel_hard_clear() runs on test_CT { var DchanTuple dt; f_init(1); - f_bssap_reset(); dt := f_est_dchan('23'O, 23, '00010203040506'O); @@ -680,7 +703,6 @@ testcase TC_chan_rel_hard_rlsd() runs on test_CT { var DchanTuple dt; f_init(1); - f_bssap_reset(); dt := f_est_dchan('23'O, 23, '00010203040506'O); @@ -696,7 +718,6 @@ testcase TC_chan_rel_a_reset() runs on test_CT { var DchanTuple dt; f_init(1); - f_bssap_reset(); dt := f_est_dchan('23'O, 23, '00010203040506'O); @@ -704,9 +725,9 @@ testcase TC_chan_rel_a_reset() runs on test_CT { IPA_RSL[0].clear; /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */ - BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, ts_BSSMAP_Reset(0))); + BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0))); interleave { - [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_sccp_addr_own, g_sccp_addr_peer, tr_BSSMAP_ResetAck)) { } + [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck)) { } [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { } } @@ -719,7 +740,6 @@ testcase TC_rll_est_ind_inact_lchan() runs on test_CT { timer T := 2.0; f_init(1); - f_bssap_reset(); var octetstring l3 := '00010203040506'O; var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6)); @@ -743,7 +763,6 @@ testcase TC_rll_est_ind_inval_sapi1() runs on test_CT { var RslChannelNr chan_nr; f_init(1); - f_bssap_reset(); chan_nr := f_chreq_act_ack() @@ -769,7 +788,6 @@ testcase TC_rll_est_ind_inval_sapi3() runs on test_CT { timer T := 2.0; f_init(1); - f_bssap_reset(); var RslChannelNr chan_nr := f_chreq_act_ack(); @@ -794,7 +812,6 @@ testcase TC_rll_est_ind_inval_sacch() runs on test_CT { timer T := 2.0; f_init(1); - f_bssap_reset(); var RslChannelNr chan_nr := f_chreq_act_ack(); @@ -821,7 +838,6 @@ testcase TC_ctrl_msc_connection_status() runs on test_CT { var charstring ctrl_resp; f_init(1); - f_bssap_reset(); /* See https://osmocom.org/issues/2729 */ f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected"); @@ -832,7 +848,6 @@ testcase TC_ctrl_msc0_connection_status() runs on test_CT { var charstring ctrl_resp; f_init(1); - f_bssap_reset(); f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected"); setverdict(pass); @@ -842,7 +857,6 @@ testcase TC_ctrl() runs on test_CT { var charstring ctrl_resp; f_init(1); - f_bssap_reset(); /* all below values must match the osmo-bsc.cfg config file used */ @@ -872,7 +886,7 @@ testcase TC_ctrl() runs on test_CT { } function f_bssap_tx_ud(template PDU_BSSAP bssap) runs on test_CT { - BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, bssap)); + BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, bssap)); } @@ -914,7 +928,6 @@ private function f_pageing_helper(hexstring imsi, var integer i; f_init(); - f_bssap_reset(); /* Clear the queue, it might still contain stuff like BCCH FILLING */ for (i := 0; i < sizeof(bts_ids); i := i + 1) { @@ -982,7 +995,6 @@ testcase TC_paging_imsi_nochan() runs on test_CT { var integer i; f_init(); - f_bssap_reset(); /* Clear the queue, it might still contain stuff like BCCH FILLING */ for (i := 0; i < NUM_BTS; i := i + 1) { @@ -1188,9 +1200,9 @@ testcase TC_paging_imsi_a_reset() runs on test_CT { f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all); /* Perform a BSSMAP Reset and wait for ACK */ - BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, ts_BSSMAP_Reset(0))); + BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0))); alt { - [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_sccp_addr_own, g_sccp_addr_peer, tr_BSSMAP_ResetAck)) { } + [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck)) { } [] BSSAP.receive { repeat; } } @@ -1223,7 +1235,6 @@ testcase TC_rsl_drop_counter() runs on test_CT { var integer rsl_fail; f_init(1); - f_bssap_reset(); rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail"); @@ -1251,11 +1262,11 @@ function f_start_handler(void_fn fn, charstring id) runs on test_CT return MSC_C var MSC_ConnHdlr vc_conn; vc_conn := MSC_ConnHdlr.create(id); - connect(vc_conn:BSSMAPEM, vc_BSSMAP:PROC); + connect(vc_conn:BSSMAPEM, g_bssap.vc_BSSMAP:PROC); connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC); connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT); connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC); - connect(vc_conn:BSSAP, vc_BSSMAP:CLIENT); + connect(vc_conn:BSSAP, g_bssap.vc_BSSMAP:CLIENT); connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT); vc_conn.start(derefers(fn)(id)); return vc_conn; diff --git a/library/BSSAP_Adapter.ttcn b/library/BSSAP_Adapter.ttcn index 0ebcc3dc7..e27783c31 100644 --- a/library/BSSAP_Adapter.ttcn +++ b/library/BSSAP_Adapter.ttcn @@ -24,144 +24,91 @@ import from BSSAP_CodecPort all; import from BSSMAP_Templates all; import from BSSMAP_Emulation all; -type component BSSAP_Adapter_CT { +type record BSSAP_Adapter { /* component references */ - var M3UA_CT vc_M3UA; - var SCCP_CT vc_SCCP; - /* test port to SCCP emulation */ - port BSSAP_CODEC_PT BSSAP; + M3UA_CT vc_M3UA, + SCCP_CT vc_SCCP, - var octetstring g_sio; - var MSC_SCCP_MTP3_parameters g_sccp_pars; - var SCCP_PAR_Address g_sccp_addr_own, g_sccp_addr_peer; + MSC_SCCP_MTP3_parameters sccp_pars, + SCCP_PAR_Address sccp_addr_own, + SCCP_PAR_Address sccp_addr_peer, /* handler mode */ - var BSSMAP_Emulation_CT vc_BSSMAP; + BSSMAP_Emulation_CT vc_BSSMAP } -modulepar { - charstring mp_sccp_service_type := "mtp3_itu"; - - SCTP_Association_Address mp_sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" }; - integer mp_own_pc := 185; /* 0.23.1 */ - integer mp_own_ssn := 254; - - integer mp_peer_pc := 187; - integer mp_peer_ssn := 254; -} +type record BSSAP_Configuration { + charstring sccp_service_type, + SCTP_Association_Address sctp_addr, + integer own_pc, + integer own_ssn, + integer peer_pc, + integer peer_ssn, + octetstring sio +}; /* construct a SCCP_PAR_Address with just PC + SSN and no GT */ -template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn) := { +template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn, octetstring sio, + charstring sccp_srv_type) := { addressIndicator := { pointCodeIndic := '1'B, ssnIndicator := '1'B, globalTitleIndic := '0000'B, routingIndicator := '1'B }, - signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, '83'O), - //signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, g_sio), + signPointCode := SCCP_SPC_int2bit(pc, sccp_srv_type, sio), subsystemNumber := ssn, globalTitle := omit } -private function init_pars() runs on BSSAP_Adapter_CT { - g_sio := '83'O; - g_sccp_pars := { +private function init_pars(inout BSSAP_Adapter ba, in BSSAP_Configuration cfg) { + ba.sccp_pars := { sio := { - ni := substr(oct2bit(g_sio),0,2), - prio := substr(oct2bit(g_sio),2,2), - si := substr(oct2bit(g_sio),4,4) + ni := substr(oct2bit(cfg.sio),0,2), + prio := substr(oct2bit(cfg.sio),2,2), + si := substr(oct2bit(cfg.sio),4,4) }, - opc := mp_own_pc, - dpc := mp_peer_pc, + opc := cfg.own_pc, + dpc := cfg.peer_pc, sls := 0, - sccp_serviceType := mp_sccp_service_type, - ssn := mp_own_ssn + sccp_serviceType := cfg.sccp_service_type, + ssn := cfg.own_ssn }; - g_sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(mp_own_pc, mp_own_ssn)); - g_sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(mp_peer_pc, mp_peer_ssn)); + ba.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(cfg.own_pc, cfg.own_ssn, cfg.sio, cfg.sccp_service_type)); + ba.sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(cfg.peer_pc, cfg.peer_ssn, cfg.sio, cfg.sccp_service_type)); } -function f_bssap_init(charstring id, template BssmapOps ops) runs on BSSAP_Adapter_CT -{ - init_pars(); +function f_bssap_init(inout BSSAP_Adapter ba, in BSSAP_Configuration cfg, charstring id, + template BssmapOps ops) { + init_pars(ba, cfg); + ops.sccp_addr_local := ba.sccp_addr_own; + ops.sccp_addr_peer := ba.sccp_addr_peer; /* create components */ - vc_M3UA := M3UA_CT.create(id & "-M3UA"); - vc_SCCP := SCCP_CT.create(id & "-SCCP"); + ba.vc_M3UA := M3UA_CT.create(id & "-M3UA"); + ba.vc_SCCP := SCCP_CT.create(id & "-SCCP"); if (isvalue(ops)) { - vc_BSSMAP := BSSMAP_Emulation_CT.create(id & "-BSSMAP"); + ba.vc_BSSMAP := BSSMAP_Emulation_CT.create(id & "-BSSMAP"); } - map(vc_M3UA:SCTP_PORT, system:sctp); + map(ba.vc_M3UA:SCTP_PORT, system:sctp); /* connect MTP3 service provider (M3UA) to lower side of SCCP */ - connect(vc_M3UA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT); - /* connect ourselves to upper side of SCCP */ - connect(self:BSSAP, vc_SCCP:SCCP_SP_PORT); + connect(ba.vc_M3UA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT); - vc_M3UA.start(f_M3UA_Emulation(mp_sctp_addr)); - vc_SCCP.start(SCCPStart(g_sccp_pars)); + ba.vc_M3UA.start(f_M3UA_Emulation(cfg.sctp_addr)); + ba.vc_SCCP.start(SCCPStart(ba.sccp_pars)); if (isvalue(ops)) { timer T := 5.0; T.start; - T.timeout; - /* Perform reset procedure */ - f_bssap_reset(); - /* disconect ourselves */ - disconnect(self:BSSAP, vc_SCCP:SCCP_SP_PORT); + //T.timeout; + log("Connecting BSSMAP Emulation to SCCP_SP_PORT and starting emulation"); /* connect BSSNAP component to upposer side of SCCP */ - connect(vc_BSSMAP:BSSAP, vc_SCCP:SCCP_SP_PORT); + connect(ba.vc_BSSMAP:BSSAP, ba.vc_SCCP:SCCP_SP_PORT); /* start the BSSMAP emulation */ - vc_BSSMAP.start(BSSMAP_Emulation.main(valueof(ops), "")); - } -} - -private altstep as_reset_ack() runs on BSSAP_Adapter_CT { - var BSSAP_N_UNITDATA_ind ud_ind; - [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind { - log("Respoding to inbound RESET with RESET-ACK"); - BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress, - ts_BSSMAP_ResetAck)); - repeat; - } -} - - -function f_bssap_wait_for_reset() runs on BSSAP_Adapter_CT { - var BSSAP_N_UNITDATA_ind ud_ind; - timer T := 20.0; - - T.start; - alt { - [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind { - BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress, - ts_BSSMAP_ResetAck)); - } - [] as_reset_ack(); - [] BSSAP.receive { - repeat; - } - [] T.timeout { - setverdict(fail); - } - } -} - -function f_bssap_reset() runs on BSSAP_Adapter_CT { - timer T := 5.0; - - BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, ts_BSSMAP_Reset(0))); - T.start; - alt { - [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_sccp_addr_own, g_sccp_addr_peer, tr_BSSMAP_ResetAck)) { - log("Received RESET-ACK in response to RESET, we're ready to go!"); - } - [] as_reset_ack(); - [] BSSAP.receive { repeat }; - [] T.timeout { setverdict(fail, "Waiting for RESET-ACK after sending RESET"); } + ba.vc_BSSMAP.start(BSSMAP_Emulation.main(valueof(ops), "")); } } diff --git a/library/BSSMAP_Emulation.ttcn b/library/BSSMAP_Emulation.ttcn index 4aacdf27b..b1c6b8141 100644 --- a/library/BSSMAP_Emulation.ttcn +++ b/library/BSSMAP_Emulation.ttcn @@ -102,7 +102,14 @@ template PDU_DTAP_MO tr_PDU_DTAP_MO(template PDU_ML3_MS_NW dtap, template OCT1 d /* port between individual per-connection components and this dispatcher */ type port BSSAP_Conn_PT message { - inout PDU_BSSAP, PDU_DTAP_MO, PDU_DTAP_MT, BSSAP_Conn_Prim, BSSAP_Conn_Req, MgcpCommand, MgcpResponse; + /* BSSAP or direct DTAP messages from/to clients */ + inout PDU_BSSAP, PDU_DTAP_MO, PDU_DTAP_MT, + /* misc indications / requests between SCCP and client */ + BSSAP_Conn_Prim, + /* Client requests us to create SCCP Connection */ + BSSAP_Conn_Req, + /* MGCP, only used for IPA SCCPlite (MGCP in IPA mux) */ + MgcpCommand, MgcpResponse; } with { extension "internal" }; @@ -417,7 +424,10 @@ type record BssmapOps { BssmapCreateCallback create_cb, BssmapUnitdataCallback unitdata_cb, boolean decode_dtap, - boolean role_ms + boolean role_ms, + /* needed for performing BSSMAP RESET */ + SCCP_PAR_Address sccp_addr_local optional, + SCCP_PAR_Address sccp_addr_peer optional } template BIT4 t_ML3_DISC_CC_MM_SS := ('0011'B, '0101'B, '1011'B); @@ -459,6 +469,52 @@ private function f_bssap_l3_is_rr(PDU_BSSAP bssap) return boolean { return false; } +private altstep as_reset_ack() runs on BSSMAP_Emulation_CT { + var BSSAP_N_UNITDATA_ind ud_ind; + [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind { + log("Respoding to inbound RESET with RESET-ACK"); + BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress, + ts_BSSMAP_ResetAck)); + repeat; + } +} + + +private function f_bssap_wait_for_reset() runs on BSSMAP_Emulation_CT { + var BSSAP_N_UNITDATA_ind ud_ind; + timer T := 20.0; + + T.start; + alt { + [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind { + BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress, + ts_BSSMAP_ResetAck)); + } + [] as_reset_ack(); + [] BSSAP.receive { + repeat; + } + [] T.timeout { + setverdict(fail); + } + } +} + +function f_bssap_reset(SCCP_PAR_Address peer, SCCP_PAR_Address own) runs on BSSMAP_Emulation_CT { + timer T := 5.0; + + BSSAP.send(ts_BSSAP_UNITDATA_req(peer, own, ts_BSSMAP_Reset(0))); + T.start; + alt { + [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(own, peer, tr_BSSMAP_ResetAck)) { + log("Received RESET-ACK in response to RESET, we're ready to go!"); + } + [] as_reset_ack(); + [] BSSAP.receive { repeat }; + [] T.timeout { setverdict(fail, "Waiting for RESET-ACK after sending RESET"); } + } +} + function main(BssmapOps ops, charstring id) runs on BSSMAP_Emulation_CT { g_bssmap_id := id; @@ -466,6 +522,10 @@ function main(BssmapOps ops, charstring id) runs on BSSMAP_Emulation_CT { f_conn_table_init(); f_expect_table_init(); + if (isvalue(ops.sccp_addr_peer) and isvalue(ops.sccp_addr_local)) { + f_bssap_reset(ops.sccp_addr_peer, ops.sccp_addr_local); + } + while (true) { var BSSAP_N_UNITDATA_ind ud_ind; var BSSAP_N_CONNECT_ind conn_ind; diff --git a/library/RTP_Emulation.ttcn b/library/RTP_Emulation.ttcn index f9525106d..8d741fba3 100644 --- a/library/RTP_Emulation.ttcn +++ b/library/RTP_Emulation.ttcn @@ -14,6 +14,43 @@ module RTP_Emulation { * * enable/disable generation/verification of RTCP */ +/* Ideas: + +* each component consists of transmitter and receiver +* transmitters and receivers can be operated as tuple? +* high-level operation +** set-up config at transmitter + receiver +** transmit sequence of payloads +** verify receiption of those payloads +* can operate full-duplex/bi-directional as needed + +* transmitter +** trigger transmission of n number of packets +** transmit them at normal ptime interval +** payload size configurable +** payload contents PRBS or the like + +* receiver +** count number of related packets at receiver +** check received payload type +** check received timestamp increments +** check received seq_nr increments +** (optionally) check for SSRC +** (optionally) check for payload size +** (optionally) check for payload contents + +* later +** how to test transcoding? +** how to test pure play-out endpoints (rx only)? +** how to test "Rx from wrong IP/port" scenarios? +** how to test RTCP? +** maybe keep ports un-connected to show wrong src -lrt + +*/ + + + + import from General_Types all; import from Osmocom_Types all; import from IPL4asp_Types all; diff --git a/msc/BSC_ConnectionHandler.ttcn b/msc/BSC_ConnectionHandler.ttcn index 856b20a09..2d65a34c0 100644 --- a/msc/BSC_ConnectionHandler.ttcn +++ b/msc/BSC_ConnectionHandler.ttcn @@ -147,7 +147,9 @@ const BssmapOps BSC_BssmapOps := { create_cb := refers(BSSMAP_Emulation.ExpectedCreateCallback), unitdata_cb := refers(BscUnitdataCallback), decode_dtap := true, - role_ms := true + role_ms := true, + sccp_addr_local := omit, + sccp_addr_peer := omit } diff --git a/msc/MSC_Tests.cfg b/msc/MSC_Tests.cfg index ab8a2ff0f..a7605aba0 100644 --- a/msc/MSC_Tests.cfg +++ b/msc/MSC_Tests.cfg @@ -4,7 +4,7 @@ SourceInfoFormat := Single; #ConsoleMask := ERROR | WARNING | TESTCASE | TTCN_MATCHING | DEBUG_ENCDEC FileMask := LOG_ALL | TTCN_MATCHING; -BSSAP.FileMask := LOG_NOTHING; +#BSSAP.FileMask := LOG_NOTHING; "MSC_Test-M3UA".FileMask := ERROR | WARNING; "MSC_Test-SCCP".FileMask := ERROR | WARNING; "MSC_Test-GSUP-IPA".FileMask := ERROR | WARNING; @@ -27,9 +27,15 @@ mtc.FileMask := ERROR | WARNING; [MODULE_PARAMETERS] M3UA_Emulation.tsp_logVerbose := true; -BSSAP_Adapter.mp_own_pc := 193; /* 0.23.3 */ -BSSAP_Adapter.mp_peer_pc := 185; /* 0.23.1 */ -BSSAP_Adapter.mp_sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" }; +MSC_Tests.mp_bssap_cfg := { + sccp_service_type := "mtp3_itu", + sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" }, + own_pc := 193, + own_ssn := 254, + peer_pc := 185, + peer_ssn := 254, + sio := '83'O +}; Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoMSC"; [MAIN_CONTROLLER] diff --git a/msc/MSC_Tests.ttcn b/msc/MSC_Tests.ttcn index 9ec65f1b9..17995083b 100644 --- a/msc/MSC_Tests.ttcn +++ b/msc/MSC_Tests.ttcn @@ -47,9 +47,11 @@ import from MobileL3_CommonIE_Types all; import from L3_Templates all; -type component MTC_CT extends BSSAP_Adapter_CT, CTRL_Adapter_CT { +type component MTC_CT extends CTRL_Adapter_CT { var boolean g_initialized := false; + var BSSAP_Adapter g_bssap; + /* no 'adapter_CT' for MNCC or GSUP */ var MNCC_Emulation_CT vc_MNCC; var MGCP_Emulation_CT vc_MGCP; @@ -75,6 +77,15 @@ modulepar { integer mp_mgw_port := 2427; charstring mp_msc_mncc := "/tmp/mncc"; + + BSSAP_Configuration mp_bssap_cfg := { + sccp_service_type := "mtp3_itu", + sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" }, + own_pc := 185, + own_ssn := 254, + peer_pc := 187, + peer_ssn := 254 + }; } @@ -144,7 +155,7 @@ function f_init() runs on MTC_CT { } g_initialized := true; - f_bssap_init("MSC_Test", BSC_BssmapOps); + f_bssap_init(g_bssap, mp_bssap_cfg, "MSC_Test", BSC_BssmapOps); f_ipa_ctrl_start(mp_msc_ip, mp_msc_ctrl_port); f_init_mncc("MSC_Test"); f_init_mgcp("MSC_Test"); @@ -323,12 +334,6 @@ modifies ts_BSSAP_BSSMAP := { } } -// enc_PDU_BSSAP - -function f_send_BSSAP_UNITDATA(template PDU_BSSAP bssap) runs on MTC_CT { - BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, bssap)) -} - type function void_fn(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr; private function f_concat_pad(integer tot_len, hexstring prefix, integer suffix) return hexstring { @@ -361,8 +366,8 @@ function f_start_handler(void_fn fn, charstring id, integer imsi_suffix) runs on expect_ciph := false }; var BSC_ConnHdlrPars pars := { - sccp_addr_own := g_sccp_addr_own, - sccp_addr_peer := g_sccp_addr_peer, + sccp_addr_own := g_bssap.sccp_addr_own, + sccp_addr_peer := g_bssap.sccp_addr_peer, cell_id := valueof(ts_CellId_CGI('262'H, '042'H, 23, 42)), imei := f_gen_imei(imsi_suffix), imsi := f_gen_imsi(imsi_suffix), @@ -377,8 +382,8 @@ function f_start_handler(void_fn fn, charstring id, integer imsi_suffix) runs on vc_conn := BSC_ConnHdlr.create(id); /* BSSMAP part / A interface */ - connect(vc_conn:BSSAP, vc_BSSMAP:CLIENT); - connect(vc_conn:BSSAP_PROC, vc_BSSMAP:PROC); + connect(vc_conn:BSSAP, g_bssap.vc_BSSMAP:CLIENT); + connect(vc_conn:BSSAP_PROC, g_bssap.vc_BSSMAP:PROC); /* MNCC part */ connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT); connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);