248 lines
6.5 KiB
Plaintext
248 lines
6.5 KiB
Plaintext
module REMSIM_Tests {
|
|
|
|
/* Implementation of RSPRO Client in TTCN-3.
|
|
* (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;
|
|
|
|
|
|
modulepar {
|
|
charstring mp_bankd_ip := "127.0.0.1";
|
|
integer mp_bankd_port := 9999;
|
|
|
|
charstring mp_server_ip := "127.0.0.1";
|
|
integer mp_server_port := 9998;
|
|
|
|
integer mp_rsres_port := 9997;
|
|
}
|
|
|
|
const integer NUM_CLIENT := 3;
|
|
|
|
type record RSPRO_Client {
|
|
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
|
|
};
|
|
|
|
type component rspro_client_CT {
|
|
var RSPRO_Client rspro[NUM_CLIENT];
|
|
port IPA_RSPRO_PT RSPRO[NUM_CLIENT];
|
|
};
|
|
|
|
private altstep as_ignore_id_ack(integer i := 0) runs on rspro_client_CT {
|
|
[] RSPRO[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) { repeat; }
|
|
}
|
|
|
|
function f_rspro_init(inout RSPRO_Client clnt, charstring dst_host, integer dst_port,
|
|
ComponentIdentity rspro_id, integer i)
|
|
runs on rspro_client_CT
|
|
{
|
|
timer T := 4.0;
|
|
|
|
clnt.id := "RSPRO" & int2str(i);
|
|
clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id);
|
|
clnt.ccm_pars := c_IPA_default_ccm_pars;
|
|
clnt.ccm_pars.name := "Osmocom TTCN-3 RSPRO client simulator";
|
|
clnt.rspro_id := rspro_id;
|
|
|
|
/* leave it up to the caller to set those */
|
|
clnt.rspro_client_slot := omit;
|
|
clnt.rspro_bank_id := omit;
|
|
clnt.rspro_bank_nslots := omit;
|
|
|
|
map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
|
|
connect(clnt.vc_IPA:IPA_RSPRO_PORT, self:RSPRO[i]);
|
|
|
|
clnt.vc_IPA.start(IPA_Emulation.main_client(dst_host, dst_port, "", 10000+i, clnt.ccm_pars));
|
|
|
|
T.start;
|
|
alt {
|
|
[] RSPRO[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
|
|
[] T.timeout {
|
|
setverdict(fail, "Timeout waiting for ASP_IPA_EVENT_UP");
|
|
mtc.stop;
|
|
}
|
|
}
|
|
T.start;
|
|
alt {
|
|
[] RSPRO[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) { }
|
|
[] T.timeout {
|
|
setverdict(fail, "Timeout waiting for ASP_IPA_EVENT_ID_ACK");
|
|
mtc.stop;
|
|
}
|
|
}
|
|
|
|
|
|
activate(as_ignore_id_ack(i));
|
|
}
|
|
|
|
function f_rspro_fini(inout RSPRO_Client clnt, integer i)
|
|
runs on rspro_client_CT {
|
|
clnt.vc_IPA.stop;
|
|
disconnect(clnt.vc_IPA:IPA_RSPRO_PORT, self:RSPRO[i]);
|
|
unmap(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
|
|
}
|
|
|
|
|
|
function f_rspro_exp(template RsproPDU exp, integer i := 0)
|
|
runs on rspro_client_CT return RsproPDU
|
|
{
|
|
var RsproPDU pdu;
|
|
|
|
timer T := 10.0;
|
|
T.start;
|
|
alt {
|
|
[] RSPRO[i].receive(exp) -> value pdu {
|
|
setverdict(pass);
|
|
}
|
|
[] RSPRO[i].receive(RsproPDU:?) -> value pdu {
|
|
setverdict(fail, "Received unexpected RPSRO", pdu);
|
|
mtc.stop;
|
|
}
|
|
[] RSPRO[i].receive {
|
|
setverdict(fail, "Received unexpected != RPSRO");
|
|
mtc.stop;
|
|
}
|
|
[] T.timeout {
|
|
setverdict(fail, "Timeout waiting for ", exp);
|
|
mtc.stop;
|
|
}
|
|
}
|
|
return pdu;
|
|
}
|
|
|
|
function f_rspro_exp_disconnect(integer i := 0)
|
|
runs on rspro_client_CT {
|
|
timer T := 10.0;
|
|
T.start;
|
|
alt {
|
|
[] RSPRO[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
|
|
setverdict(pass);
|
|
}
|
|
[] T.timeout {
|
|
setverdict(fail, "Timeout expecting disconnect");
|
|
mtc.stop;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function f_rspro_connect_client(integer i, template ResultCode exp_res := ok) runs on rspro_client_CT
|
|
{
|
|
select (rspro[i].rspro_id.type_) {
|
|
case (remsimClient) {
|
|
RSPRO[i].send(ts_RSPRO_ConnectClientReq(rspro[i].rspro_id, rspro[i].rspro_client_slot));
|
|
f_rspro_exp(tr_RSPRO_ConnectClientRes(?, exp_res), i);
|
|
}
|
|
case (remsimBankd) {
|
|
var template IpAddress ip := ts_IPv4(mp_bankd_ip);
|
|
RSPRO[i].send(ts_RSPRO_ConnectBankReq(rspro[i].rspro_id, rspro[i].rspro_bank_id,
|
|
rspro[i].rspro_bank_nslots,
|
|
ts_IpPort(ip, mp_bankd_port)));
|
|
f_rspro_exp(tr_RSPRO_ConnectBankRes(?, exp_res), i);
|
|
}
|
|
case else {
|
|
setverdict(fail, "Unsupported type ", rspro[i].rspro_id.type_);
|
|
mtc.stop;
|
|
}
|
|
}
|
|
}
|
|
|
|
function f_rspro_connect_clients() runs on rspro_client_CT
|
|
{
|
|
var integer i;
|
|
|
|
for (i := 0; i < NUM_CLIENT; i := i+1) {
|
|
select (rspro[i].rspro_id.type_) {
|
|
case (remsimClient) {
|
|
RSPRO[i].send(ts_RSPRO_ConnectClientReq(rspro[i].rspro_id,
|
|
rspro[i].rspro_client_slot));
|
|
}
|
|
case (remsimBankd) {
|
|
var template IpAddress ip := ts_IPv4(mp_bankd_ip);
|
|
RSPRO[i].send(ts_RSPRO_ConnectBankReq(rspro[i].rspro_id, rspro[i].rspro_bank_id,
|
|
rspro[i].rspro_bank_nslots,
|
|
ts_IpPort(ip, mp_bankd_port)));
|
|
}
|
|
}
|
|
}
|
|
for (i := 0; i < NUM_CLIENT; i := i+1) {
|
|
select (rspro[i].rspro_id.type_) {
|
|
case (remsimClient) {
|
|
f_rspro_exp(tr_RSPRO_ConnectClientRes(?, ResultCode:ok), i);
|
|
}
|
|
case (remsimBankd) {
|
|
f_rspro_exp(tr_RSPRO_ConnectBankRes(?, ResultCode:ok), i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* transceive a TPDU from modem to card (and back) */
|
|
function f_rspro_xceive_mdm2card(integer idx, BankSlot bs, template (value) octetstring data,
|
|
template (value) TpduFlags flags) runs on rspro_client_CT return octetstring {
|
|
var RsproPDU rx;
|
|
RSPRO[idx].send(ts_RSPRO_TpduModemToCard(rspro[idx].rspro_client_slot, bs, flags, data));
|
|
rx := f_rspro_exp(tr_RSPRO_TpduCardToModem(bs, rspro[idx].rspro_client_slot, ?, ?));
|
|
return rx.msg.tpduCardToModem.data;
|
|
}
|
|
|
|
/* handle an incoming CreateMapping + ACK it */
|
|
altstep as_rspro_create_mapping(integer i, template ClientSlot cslot := ?, template BankSlot bslot := ?,
|
|
template ResultCode res := ok)
|
|
runs on rspro_client_CT {
|
|
var RsproPDU rx;
|
|
[] RSPRO[i].receive(tr_RSPRO_CreateMappingReq(cslot, bslot)) -> value rx {
|
|
RSPRO[i].send(ts_RSPRO_CreateMappingRes(res));
|
|
}
|
|
}
|
|
|
|
/* handle an incoming RemoveMapping + ACK it */
|
|
altstep as_rspro_remove_mapping(integer i, template ClientSlot cslot := ?, template BankSlot bslot := ?,
|
|
template ResultCode res := ok)
|
|
runs on rspro_client_CT {
|
|
var RsproPDU rx;
|
|
[] RSPRO[i].receive(tr_RSPRO_RemoveMappingReq(cslot, bslot)) -> value rx {
|
|
RSPRO[i].send(ts_RSPRO_RemoveMappingRes(res));
|
|
}
|
|
}
|
|
|
|
altstep as_rspro_cfg_client_id(integer i, template ClientSlot cslot := ?,
|
|
template (value) ResultCode res := ok)
|
|
runs on rspro_client_CT {
|
|
var RsproPDU rx;
|
|
[] RSPRO[i].receive(tr_RSPRO_ConfigClientIdReq(cslot)) -> value rx {
|
|
RSPRO[i].send(ts_RSPRO_ConfigClientIdRes(res));
|
|
}
|
|
}
|
|
|
|
altstep as_rspro_cfg_client_bank(integer i, template BankSlot bslot := ?,
|
|
template IpPort ip_port := ?,
|
|
template (value) ResultCode res := ok)
|
|
runs on rspro_client_CT {
|
|
var RsproPDU rx;
|
|
[] RSPRO[i].receive(tr_RSPRO_ConfigClientBankReq(bslot, ip_port)) -> value rx {
|
|
RSPRO[i].send(ts_RSPRO_ConfigClientBankRes(res));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|