2018-01-17 11:37:14 +00:00
|
|
|
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;
|
2018-01-17 14:23:45 +00:00
|
|
|
var MgcpConnectionId mgcp_conn_id;
|
2018-01-17 11:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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;
|
2018-01-17 14:28:04 +00:00
|
|
|
var integer g_mgcp_conn_id := -1;
|
2018-01-17 11:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2018-01-17 14:28:04 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-01-17 14:22:32 +00:00
|
|
|
function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_Emulation_CT {
|
2018-01-17 11:37:14 +00:00
|
|
|
var Result res;
|
|
|
|
g_mgcp_id := id;
|
|
|
|
//f_conn_table_init();
|
2018-01-17 14:22:32 +00:00
|
|
|
f_expect_table_init();
|
2018-01-17 11:37:14 +00:00
|
|
|
|
|
|
|
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:={} });
|
|
|
|
|
2018-01-17 14:28:04 +00:00
|
|
|
g_mgcp_conn_id := res.connId;
|
2018-01-17 11:37:14 +00:00
|
|
|
|
|
|
|
while (true) {
|
2018-01-17 14:28:04 +00:00
|
|
|
var MGCP_ConnHdlr vc_conn;
|
|
|
|
var ExpectCriteria crit;
|
|
|
|
var MGCP_RecvFrom mrf;
|
|
|
|
var MgcpMessage msg;
|
|
|
|
var MgcpCommand cmd;
|
|
|
|
var MgcpResponse resp;
|
|
|
|
|
2018-01-17 11:37:14 +00:00
|
|
|
alt {
|
2018-01-17 14:28:04 +00:00
|
|
|
/* 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;
|
2018-01-17 11:37:14 +00:00
|
|
|
}
|
|
|
|
}
|
2018-01-17 14:22:32 +00:00
|
|
|
[] PROC.getcall(MGCPEM_register:{?,?}) -> param(crit, vc_conn) {
|
|
|
|
f_create_expect(crit, vc_conn);
|
|
|
|
PROC.reply(MGCPEM_register:{crit, vc_conn});
|
|
|
|
}
|
2018-01-17 11:37:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-17 14:28:04 +00:00
|
|
|
private function f_handle_userData(MGCP_ConnHdlr conn, MgcpCommand cmd)
|
|
|
|
runs on MGCP_Emulation_CT {
|
|
|
|
CLIENT.send(cmd) to conn;
|
|
|
|
}
|
|
|
|
|
2018-01-17 11:37:14 +00:00
|
|
|
/* "Expect" Handling */
|
|
|
|
|
|
|
|
/* */
|
2018-01-17 14:22:32 +00:00
|
|
|
type record ExpectCriteria {
|
|
|
|
MgcpConnectionId connid optional,
|
|
|
|
MgcpEndpoint endpoint optional,
|
|
|
|
MgcpTransId transid optional
|
2018-01-17 11:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type record ExpectData {
|
|
|
|
ExpectCriteria crit optional,
|
2018-01-17 14:22:32 +00:00
|
|
|
MGCP_ConnHdlr vc_conn
|
2018-01-17 11:37:14 +00:00
|
|
|
}
|
|
|
|
|
2018-01-17 14:22:32 +00:00
|
|
|
signature MGCPEM_register(in ExpectCriteria cmd, in MGCP_ConnHdlr hdlr);
|
2018-01-17 11:37:14 +00:00
|
|
|
|
|
|
|
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) {
|
2018-01-17 14:22:32 +00:00
|
|
|
if (not ispresent(ExpectTable[i].crit)) {
|
2018-01-17 11:37:14 +00:00
|
|
|
continue;
|
|
|
|
}
|
2018-01-17 14:22:32 +00:00
|
|
|
/* FIXME: Ignore criteria for now */
|
|
|
|
// mgcpcmd := f_get_mgcp_by_crit(ExpectTable[i].crit);
|
|
|
|
// if (match(cmd, mgcpcmd)) {
|
2018-01-17 11:37:14 +00:00
|
|
|
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;
|
2018-01-17 14:22:32 +00:00
|
|
|
// }
|
2018-01-17 11:37:14 +00:00
|
|
|
}
|
|
|
|
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")
|
|
|
|
}
|
|
|
|
|
2018-01-17 14:22:32 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-17 11:37:14 +00:00
|
|
|
}
|