module RSPRO_Server { /* Utility functions implementing an RSRPO server. * (C) 2019 by Harald Welte * All rights reserved. * * Released under the terms of GNU General Public License, Version 2 or * (at your option) any later version. * * SPDX-License-Identifier: GPL-2.0-or-later */ import from IPL4asp_Types all; import from RSPRO all; import from RSPRO_Types all; import from IPA_Types all; import from IPA_Emulation all; type record RSPRO_Server { IPA_Emulation_CT vc_IPA, IPA_CCM_Parameters ccm_pars, charstring id, ComponentIdentity rspro_id//, //ClientSlot rspro_client_slot optional, //BankId rspro_bank_id optional, //SlotNumber rspro_bank_nslots optional }; const integer NUM_SERVER := 2; type component rspro_server_CT { var RSPRO_Server g_rspro_srv[NUM_SERVER]; port IPA_RSPRO_PT RSPRO_SRV[NUM_SERVER]; timer g_rspro_srv_Tguard := 30.0; }; private altstep as_rspro_srv_Tguard() runs on rspro_server_CT { [] g_rspro_srv_Tguard.timeout { setverdict(fail, "RSPRO Server global guard timer timeout"); mtc.stop; } } altstep as_ignore_id_ack(integer i) runs on rspro_server_CT { [] RSPRO_SRV[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) { repeat; } [] RSPRO_SRV[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_RESP)) { repeat; } } function f_rspro_srv_exp_connect(integer i) runs on rspro_server_CT { timer T := 20.0; T.start; alt { [] RSPRO_SRV[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { } [] T.timeout { setverdict(fail, "Timeout waiting for ASP_IPA_EVENT_UP"); mtc.stop; } } } function f_rspro_srv_init(integer i, charstring bind_host, integer bind_port, ComponentIdentity rspro_id, boolean exp_connect := true) runs on rspro_server_CT { g_rspro_srv[i].id := "RSPRO_SRV" & int2str(i); g_rspro_srv[i].vc_IPA := IPA_Emulation_CT.create(g_rspro_srv[i].id); g_rspro_srv[i].ccm_pars := c_IPA_default_ccm_pars; g_rspro_srv[i].ccm_pars.name := "Osmocom TTCN-3 RSPRO server simulator"; g_rspro_srv[i].rspro_id := rspro_id; activate(as_rspro_srv_Tguard()); g_rspro_srv_Tguard.start; map(g_rspro_srv[i].vc_IPA:IPA_PORT, system:IPA_CODEC_PT); connect(g_rspro_srv[i].vc_IPA:IPA_RSPRO_PORT, self:RSPRO_SRV[i]); g_rspro_srv[i].vc_IPA.start(IPA_Emulation.main_server(bind_host, bind_port)); activate(as_ignore_id_ack(i)); if (exp_connect) { f_rspro_srv_exp_connect(i); } } function f_rspro_srv_fini(integer i) runs on rspro_server_CT { g_rspro_srv[i].vc_IPA.stop; disconnect(g_rspro_srv[i].vc_IPA:IPA_RSPRO_PORT, self:RSPRO_SRV[i]); unmap(g_rspro_srv[i].vc_IPA:IPA_PORT, system:IPA_CODEC_PT); } function f_rspro_srv_restart(integer i, charstring bind_host, integer bind_port) runs on rspro_server_CT { g_rspro_srv[i].vc_IPA.stop; g_rspro_srv[i].vc_IPA.start(IPA_Emulation.main_server(bind_host, bind_port)); } function f_rspro_srv_exp(template RsproPDU exp, integer i := 0, float tout := 10.0) runs on rspro_server_CT return RsproPDU { var RsproPDU pdu; timer T := tout; T.start; alt { [] RSPRO_SRV[i].receive(exp) -> value pdu { setverdict(pass); } [] RSPRO_SRV[i].receive(RsproPDU:?) -> value pdu { setverdict(fail, "Received unexpected RPSRO", pdu, " instead of ", exp); mtc.stop; } [] as_ignore_id_ack(i) { repeat; } [] RSPRO_SRV[i].receive { setverdict(fail, "Received unexpected != RPSRO"); mtc.stop; } [] T.timeout { setverdict(fail, "Timeout waiting for ", exp); mtc.stop; } } return pdu; } function f_rspro_srv_create_slotmap(ClientSlot cslot, BankSlot bslot, template ResultCode exp_res := ok, integer i := 0) runs on rspro_server_CT { RSPRO_SRV[i].send(ts_RSPRO_CreateMappingReq(cslot, bslot)); f_rspro_srv_exp(tr_RSPRO_CreateMappingRes(exp_res), i); } function f_rspro_srv_remove_slotmap(ClientSlot cslot, BankSlot bslot, template ResultCode exp_res := ok, integer i := 0) runs on rspro_server_CT { RSPRO_SRV[i].send(ts_RSPRO_RemoveMappingReq(cslot, bslot)); f_rspro_srv_exp(tr_RSPRO_RemoveMappingRes(exp_res), i); } function f_rspro_config_client_bank(template (value) BankSlot bank_slot, template (value) IpPort bank_iport, template ResultCode exp_res := ok, integer i := 0) runs on rspro_server_CT { RSPRO_SRV[i].send(ts_RSPRO_ConfigClientBankReq(bank_slot, bank_iport)); f_rspro_srv_exp(tr_RSPRO_ConfigClientBankRes(exp_res)); } function f_rspro_srv_reset_state(template ResultCode exp_res := ok, integer i := 0) runs on rspro_server_CT { RSPRO_SRV[i].send(ts_RSPRO_ResetStateReq); f_rspro_srv_exp(tr_RSPRO_ResetStateRes(exp_res)); } altstep as_connectBankReq(template ComponentIdentity comp_id := tr_CompId(remsimBankd, ?, "remsim-bankd", ?), template BankId bid := ?, template SlotNumber nslots := ?, ResultCode res := ok, integer i := 0) runs on rspro_server_CT { [] RSPRO_SRV[i].receive(tr_RSPRO_ConnectBankReq(comp_id, bid, nslots)) { RSPRO_SRV[i].send(ts_RSPRO_ConnectBankRes(g_rspro_srv[i].rspro_id, res)); } } altstep as_connectClientReq(template ComponentIdentity comp_id := tr_CompId(remsimClient, ?, "remsim-client", ?), template ClientSlot cslot := *, ResultCode res := ok, integer i := 0) runs on rspro_server_CT { [] RSPRO_SRV[i].receive(tr_RSPRO_ConnectClientReq(comp_id, cslot)) { RSPRO_SRV[i].send(ts_RSPRO_ConnectClientRes(g_rspro_srv[i].rspro_id, res)); } } }