osmo-ttcn3-hacks/library/MGCP_Emulation.ttcn

204 lines
5.1 KiB
Plaintext

module MGCP_Emulation {
import from MGCP_CodecPort all;
import from MGCP_CodecPort_CtrlFunct all;
import from MGCP_Types all;
import from MGCP_Templates all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
type component MGCP_ConnHdlr {
port MGCP_Conn_PT MGCP;
var MgcpConnectionId mgcp_conn_id;
}
/* port between individual per-connection components and this dispatcher */
type port MGCP_Conn_PT message {
inout MgcpCommand, MgcpResponse;
} with { extension "internal" };
type component MGCP_Emulation_CT {
/* Port facing to the UDP SUT */
port MGCP_CODEC_PT MGCP;
/* All MGCP_ConnHdlr MGCP ports connect here
* MGCP_Emulation_CT.main needs to figure out what messages
* to send where with CLIENT.send() to vc_conn */
port MGCP_Conn_PT CLIENT;
/* currently tracked connections */
// var ConnectionData ConnectionTable[16];
/* pending expected CRCX */
var ExpectData ExpectTable[8];
/* procedure based port to register for incoming connections */
port MGCPEM_PROC_PT PROC;
var charstring g_mgcp_id;
var integer g_mgcp_conn_id := -1;
}
type function MGCPCreateCallback(MgcpCommand cmd, charstring id)
runs on MGCP_Emulation_CT return MGCP_ConnHdlr;
type record MGCPOps {
MGCPCreateCallback create_cb
}
type record MGCP_conn_parameters {
charstring callagent_ip,
uint16_t callagent_udp_port,
charstring mgw_ip,
uint16_t mgw_udp_port
}
function tr_MGCP_RecvFrom_R(template MgcpMessage msg)
runs on MGCP_Emulation_CT return template MGCP_RecvFrom {
var template MGCP_RecvFrom mrf := {
connId := g_mgcp_conn_id,
remName := ?,
remPort := ?,
locName := ?,
locPort := ?,
msg := msg
}
return mrf;
}
function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_Emulation_CT {
var Result res;
g_mgcp_id := id;
//f_conn_table_init();
f_expect_table_init();
map(self:MGCP, system:MGCP_CODEC_PT);
res := MGCP_CodecPort_CtrlFunct.f_IPL4_connect(MGCP, p.mgw_ip,
p.mgw_udp_port,
p.callagent_ip, p.callagent_udp_port, 0, { udp:={} });
g_mgcp_conn_id := res.connId;
while (true) {
var MGCP_ConnHdlr vc_conn;
var ExpectCriteria crit;
var MGCP_RecvFrom mrf;
var MgcpMessage msg;
var MgcpCommand cmd;
var MgcpResponse resp;
alt {
/* MGCP from client */
[] CLIENT.receive(MgcpResponse:?) -> value resp sender vc_conn {
/* Pass message through */
msg.response := resp;
MGCP.send(t_MGCP_Send(g_mgcp_conn_id, msg));
}
[] MGCP.receive(tr_MGCP_RecvFrom_R(?)) -> value mrf {
if (ischosen(mrf.msg.command)) {
cmd := mrf.msg.command;
vc_conn := ops.create_cb.apply(cmd, id);
f_handle_userData(vc_conn, cmd);
} else {
setverdict(fail, "Received unexpected MGCP response: ", mrf.msg.response);
self.stop;
}
}
[] PROC.getcall(MGCPEM_register:{?,?}) -> param(crit, vc_conn) {
f_create_expect(crit, vc_conn);
PROC.reply(MGCPEM_register:{crit, vc_conn});
}
}
}
}
private function f_handle_userData(MGCP_ConnHdlr conn, MgcpCommand cmd)
runs on MGCP_Emulation_CT {
CLIENT.send(cmd) to conn;
}
/* "Expect" Handling */
/* */
type record ExpectCriteria {
MgcpConnectionId connid optional,
MgcpEndpoint endpoint optional,
MgcpTransId transid optional
}
type record ExpectData {
ExpectCriteria crit optional,
MGCP_ConnHdlr vc_conn
}
signature MGCPEM_register(in ExpectCriteria cmd, in MGCP_ConnHdlr hdlr);
type port MGCPEM_PROC_PT procedure {
inout MGCPEM_register;
} with { extension "internal" };
function f_get_mgcp_by_crit(ExpectCriteria crit)
return template MgcpCommand {
template MgcpCommand ret := {
};
return ret;
}
/* Function that can be used as create_cb and will usse the expect table */
function ExpectedCreateCallback(MgcpCommand cmd, charstring id)
runs on MGCP_Emulation_CT return MGCP_ConnHdlr {
var MGCP_ConnHdlr ret := null;
var template MgcpCommand mgcpcmd;
var integer i;
/* Ensure cmd is a CRCX? */
for (i := 0; i < sizeof(ExpectTable); i := i+1) {
if (not ispresent(ExpectTable[i].crit)) {
continue;
}
/* FIXME: Ignore criteria for now */
// mgcpcmd := f_get_mgcp_by_crit(ExpectTable[i].crit);
// if (match(cmd, mgcpcmd)) {
ret := ExpectTable[i].vc_conn;
/* Release this entry */
ExpectTable[i].crit := omit;
ExpectTable[i].vc_conn := null;
log("Found Expect[", i, "] for ", cmd, " handled at ", ret);
return ret;
// }
}
setverdict(fail, "Couldn't find Expect for CRCX", cmd);
return ret;
}
private function f_create_expect(ExpectCriteria crit, MGCP_ConnHdlr hdlr)
runs on MGCP_Emulation_CT {
var integer i;
/* Check an entry like this is not already presnt */
for (i := 0; i < sizeof(ExpectTable); i := i+1) {
if (crit == ExpectTable[i].crit) {
setverdict(fail, "Crit already present", crit);
self.stop;
}
}
for (i := 0; i < sizeof(ExpectTable); i := i+1) {
if (not ispresent(ExpectTable[i].crit)) {
ExpectTable[i].crit := crit;
ExpectTable[i].vc_conn := hdlr;
log("Created Expect[", i, "] for ", crit, " to be handled at ", hdlr);
return;
}
}
setverdict(fail, "No space left in ExpectTable")
}
private function f_expect_table_init()
runs on MGCP_Emulation_CT {
var integer i;
for (i := 0; i < sizeof(ExpectTable); i := i + 1) {
ExpectTable[i].crit := omit;
}
}
}