| module RSPRO_Server { |
| |
| /* Utility functions implementing an RSRPO server. |
| * (C) 2019 by Harald Welte <laforge@gnumonks.org> |
| * 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)); |
| } |
| } |
| |
| |
| |
| } |