diff options
-rw-r--r-- | bsc/BSC_Tests.ttcn | 3 | ||||
-rw-r--r-- | library/MGCP_CodecPort.ttcn | 36 | ||||
-rw-r--r-- | library/MGCP_Emulation.ttcn | 55 | ||||
-rw-r--r-- | msc/MSC_Tests.ttcn | 3 |
4 files changed, 84 insertions, 13 deletions
diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn index 976bc461..4c86e51f 100644 --- a/bsc/BSC_Tests.ttcn +++ b/bsc/BSC_Tests.ttcn @@ -294,7 +294,8 @@ function f_init_mgcp(charstring id) runs on test_CT { callagent_ip := mp_bsc_ip, callagent_udp_port := -1, mgw_ip := mp_test_ip, - mgw_udp_port := 2427 + mgw_udp_port := 2427, + multi_conn_mode := false }; vc_MGCP := MGCP_Emulation_CT.create(id); diff --git a/library/MGCP_CodecPort.ttcn b/library/MGCP_CodecPort.ttcn index d33afe18..8614eef1 100644 --- a/library/MGCP_CodecPort.ttcn +++ b/library/MGCP_CodecPort.ttcn @@ -41,11 +41,33 @@ module MGCP_CodecPort { MgcpMessage msg } + type record MGCP_SendTo { + ConnectionId connId, + HostName remName, + PortNumber remPort, + MgcpMessage msg + }; + template MGCP_Send t_MGCP_Send(template ConnectionId connId, template MgcpMessage msg) := { connId := connId, msg := msg } + template MGCP_SendTo t_MGCP_SendTo(template ConnectionId connId, HostName remName, + PortNumber remPort,template MgcpMessage msg) := { + connId := connId, + remName := remName, + remPort := remPort, + msg := msg + } + + template MGCP_SendTo t_MGCP_SendToMrf(MGCP_RecvFrom mrf,template MgcpMessage msg) := { + connId := mrf.connId, + remName := mrf.remName, + remPort := mrf.remPort, + msg := msg + } + private function IPL4_to_MGCP_RecvFrom(in ASP_RecvFrom pin, out MGCP_RecvFrom pout) { pout.connId := pin.connId; pout.remName := pin.remName; @@ -65,13 +87,23 @@ module MGCP_CodecPort { pout.msg := char2oct(enc_MgcpMessage(pin.msg)); } with { extension "prototype(fast)" }; + private function MGCP_to_IPL4_SendTo(in MGCP_SendTo pin, out ASP_SendTo out_ud) { + out_ud.connId := pin.connId; + out_ud.remName := pin.remName; + out_ud.remPort := pin.remPort; + out_ud.proto := { udp := {} }; + out_ud.msg := char2oct(enc_MgcpMessage(pin.msg)); + } with { extension "prototype(fast)" }; + type port MGCP_CODEC_PT message { - out MGCP_Send; + out MGCP_Send, + MGCP_SendTo; in MGCP_RecvFrom, ASP_ConnId_ReadyToRelease, ASP_Event; } with { extension "user IPL4asp_PT - out(MGCP_Send -> ASP_Send:function(MGCP_to_IPL4_Send)) + out(MGCP_Send -> ASP_Send:function(MGCP_to_IPL4_Send); + MGCP_SendTo -> ASP_SendTo: function(MGCP_to_IPL4_SendTo)) in(ASP_RecvFrom -> MGCP_RecvFrom: function(IPL4_to_MGCP_RecvFrom); ASP_ConnId_ReadyToRelease -> ASP_ConnId_ReadyToRelease: simple; ASP_Event -> ASP_Event: simple)" diff --git a/library/MGCP_Emulation.ttcn b/library/MGCP_Emulation.ttcn index 23cfeb4a..494b1714 100644 --- a/library/MGCP_Emulation.ttcn +++ b/library/MGCP_Emulation.ttcn @@ -37,8 +37,11 @@ import from Osmocom_Types all; import from IPL4asp_Types all; type component MGCP_ConnHdlr { + /* Simple send/recv without caring about peer addr+port. Used with multi_conn_mode=false. */ port MGCP_Conn_PT MGCP; - /* procedure based port to register for incoming connections */ + /* Handle multiple connections concurrently. Used with multi_conn_mode=true. */ + port MGCP_Conn_Multi_PT MGCP_MULTI; + /* procedure based port to register for incoming connections. */ port MGCPEM_PROC_PT MGCP_PROC; } @@ -47,6 +50,11 @@ type port MGCP_Conn_PT message { inout MgcpCommand, MgcpResponse; } with { extension "internal" }; +/* port between individual per-connection components and this dispatcher */ +type port MGCP_Conn_Multi_PT message { + inout MGCP_RecvFrom, MGCP_SendTo; +} with { extension "internal" }; + /* represents a single MGCP Endpoint */ type record EndpointData { MGCP_ConnHdlr comp_ref, @@ -63,6 +71,8 @@ type component MGCP_Emulation_CT { * MGCP_Emulation_CT.main needs to figure out what messages * to send where with CLIENT.send() to vc_conn */ port MGCP_Conn_PT MGCP_CLIENT; + /* This one is used with multi_conn_mode=true and allows differentiating UDP sockets */ + port MGCP_Conn_Multi_PT MGCP_CLIENT_MULTI; /* currently tracked connections */ var EndpointData MgcpEndpointTable[16]; var MgcpTransIds MgcpPendingTrans := {}; @@ -73,6 +83,8 @@ type component MGCP_Emulation_CT { var charstring g_mgcp_id; var integer g_mgcp_conn_id := -1; + + var MGCP_conn_parameters g_pars; } type function MGCPCreateCallback(MgcpCommand cmd, charstring id) @@ -90,7 +102,8 @@ type record MGCP_conn_parameters { HostName callagent_ip, PortNumber callagent_udp_port, HostName mgw_ip, - PortNumber mgw_udp_port + PortNumber mgw_udp_port, + boolean multi_conn_mode } function tr_MGCP_RecvFrom_R(template MgcpMessage msg) @@ -224,14 +237,23 @@ runs on MGCP_Emulation_CT { } } +private function f_forward_to_client(MGCP_RecvFrom mrf, MGCP_ConnHdlr vc_conn) runs on MGCP_Emulation_CT { + if (g_pars.multi_conn_mode) { + MGCP_CLIENT_MULTI.send(mrf) to vc_conn; + } else { + MGCP_CLIENT.send(mrf.msg.command) to vc_conn; + } +} + function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_Emulation_CT { var Result res; + g_pars := p; g_mgcp_id := id; f_ep_table_init(); f_expect_table_init(); map(self:MGCP, system:MGCP_CODEC_PT); - if (p.callagent_udp_port == -1) { + if (p.multi_conn_mode or p.callagent_udp_port == -1) { res := MGCP_CodecPort_CtrlFunct.f_IPL4_listen(MGCP, p.mgw_ip, p.mgw_udp_port, { udp:={} }); } else { res := MGCP_CodecPort_CtrlFunct.f_IPL4_connect(MGCP, p.callagent_ip, p.callagent_udp_port, p.mgw_ip, p.mgw_udp_port, -1, { udp:={} }); @@ -246,6 +268,7 @@ function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_E var MGCP_ConnHdlr vc_conn; var ExpectCriteria crit; var MGCP_RecvFrom mrf; + var MGCP_SendTo mst; var MgcpMessage msg; var MgcpCommand cmd; var MgcpResponse resp; @@ -253,7 +276,7 @@ function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_E alt { /* MGCP from client */ - [] MGCP_CLIENT.receive(MgcpResponse:?) -> value resp sender vc_conn { + [not p.multi_conn_mode] MGCP_CLIENT.receive(MgcpResponse:?) -> value resp sender vc_conn { msg := { response := resp }; @@ -265,9 +288,23 @@ function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_E /* TODO: check which ConnectionID client has allocated + store in table? */ MGCP.send(t_MGCP_Send(g_mgcp_conn_id, msg)); } + + /* MGCP from client in Multi Conn mode */ + [p.multi_conn_mode] MGCP_CLIENT_MULTI.receive(MGCP_SendTo:?) -> value mst sender vc_conn { + /* If this is the resposne to a pending CRCX, extract Endpoint and store in table */ + if (f_trans_id_was_pending(mst.msg.response.line.trans_id)) { + f_ep_table_add(vc_conn, f_mgcp_ep(mst.msg)); + } + /* Pass message through */ + /* TODO: check which ConnectionID client has allocated + store in table? */ + MGCP.send(mst); + } [] MGCP.receive(tr_MGCP_RecvFrom_R(?)) -> value mrf { - if (p.callagent_udp_port == -1) { - /* we aren't yet connected to the remote side port, let's fix this */ + if (not p.multi_conn_mode and p.callagent_udp_port == -1) { + /* we aren't yet connected to the remote side + port, let's fix this. This way upper layers + can use Send/Recv without caring about UDP + src/dst addr + port */ p.callagent_udp_port := mrf.remPort; res := MGCP_CodecPort_CtrlFunct.f_IPL4_connect(MGCP, p.callagent_ip, p.callagent_udp_port, p.mgw_ip, p.mgw_udp_port, g_mgcp_conn_id, { udp:={} }); if (not ispresent(res.connId)) { @@ -279,7 +316,7 @@ function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_E cmd := mrf.msg.command; if (f_ep_known(cmd.line.ep)) { vc_conn := f_comp_by_ep(cmd.line.ep); - MGCP_CLIENT.send(cmd) to vc_conn; + f_forward_to_client(mrf, vc_conn); } else { if (cmd.line.verb == "CRCX") { vc_conn := ops.create_cb.apply(cmd, id); @@ -290,12 +327,12 @@ function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_E /* add this transaction to list of pending transactions */ MgcpPendingTrans := MgcpPendingTrans & {cmd.line.trans_id}; } - MGCP_CLIENT.send(cmd) to vc_conn; + f_forward_to_client(mrf, vc_conn); } else { /* connectionless MGCP, i.e. messages without ConnectionId */ var template MgcpMessage r := ops.unitdata_cb.apply(mrf.msg); if (isvalue(r)) { - MGCP.send(t_MGCP_Send(g_mgcp_conn_id, r)); + MGCP.send(t_MGCP_SendToMrf(mrf, r)); } } } diff --git a/msc/MSC_Tests.ttcn b/msc/MSC_Tests.ttcn index b00e032e..4b00e345 100644 --- a/msc/MSC_Tests.ttcn +++ b/msc/MSC_Tests.ttcn @@ -230,7 +230,8 @@ function f_init_mgcp(charstring id) runs on MTC_CT { callagent_ip := mp_msc_ip, callagent_udp_port := -1, mgw_ip := mp_mgw_ip, - mgw_udp_port := mp_mgw_port + mgw_udp_port := mp_mgw_port, + multi_conn_mode := false } vc_MGCP := MGCP_Emulation_CT.create(id); |