aboutsummaryrefslogtreecommitdiffstats
path: root/library/IPA_Emulation.ttcnpp
diff options
context:
space:
mode:
Diffstat (limited to 'library/IPA_Emulation.ttcnpp')
-rw-r--r--library/IPA_Emulation.ttcnpp98
1 files changed, 96 insertions, 2 deletions
diff --git a/library/IPA_Emulation.ttcnpp b/library/IPA_Emulation.ttcnpp
index 60c6061e..07fefe55 100644
--- a/library/IPA_Emulation.ttcnpp
+++ b/library/IPA_Emulation.ttcnpp
@@ -44,6 +44,7 @@ import from MGCP_Types all;
#ifdef IPA_EMULATION_GSUP
import from GSUP_Types all;
+import from GSUP_Templates all;
#endif
#ifdef IPA_EMULATION_RSPRO
@@ -55,6 +56,10 @@ import from RSPRO_Types all;
import from Osmocom_CTRL_Types all;
#endif
+#ifdef IPA_EMULATION_OSMO_PCU
+import from PCUIF_Types all;
+#endif
+
modulepar {
/* Use Osmocom extended IPA mux header */
boolean mp_ipa_mgcp_uses_osmo_ext := true;
@@ -190,12 +195,21 @@ type port IPA_RSPRO_PT message {
} with { extension "internal" }
#endif
+#ifdef IPA_EMULATION_OSMO_PCU
+/* Client port for Osmocom PCU extension inside IPA */
+type port IPA_OSMO_PCU_PT message {
+ inout PCUIF_Message, ASP_IPA_Event;
+} with { extension "internal" }
+#endif
type component IPA_Emulation_CT {
/* down-facing port to IPA codec port */
port IPA_CODEC_PT IPA_PORT;
+ /* Down facing port to configure the component */
+ port IPA_CFG_PT CFG_PORT;
+
#ifdef IPA_EMULATION_SCCP
/* up-facing port to SCCP */
port MTP3asp_SP_PT MTP3_SP_PORT;
@@ -224,6 +238,10 @@ type component IPA_Emulation_CT {
/* up-facing port for RSPRO */
port IPA_RSPRO_PT IPA_RSPRO_PORT;
#endif
+#ifdef IPA_EMULATION_OSMO_PCU
+ /* up-facing port for RSPRO */
+ port IPA_OSMO_PCU_PT IPA_OSMO_PCU_PORT;
+#endif
/* up-facing port for other streams */
port IPA_SP_PT IPA_SP_PORT;
@@ -240,6 +258,9 @@ type component IPA_Emulation_CT {
var IpaMode g_mode;
var boolean g_ccm_enabled;
var IpaInitBehavior g_init_behavior;
+ /* Shall we stop the component once the client disconnects, or keep
+ * running to let next user in ? */
+ var boolean g_server_stop_on_ipa_ev_down := true;
var IPA_CCM_Parameters g_ccm_pars := c_IPA_default_ccm_pars;
}
@@ -269,6 +290,17 @@ const IPA_CCM_Parameters c_IPA_default_ccm_pars := {
osmo_rand := ""
};
+signature IPA_CFG_disconnect(inout IPL4asp_Types.Result res);
+type port IPA_CFG_PT procedure {
+ inout IPA_CFG_disconnect;
+} with { extension "internal" };
+
+function f_ipa_cfg_disconnect(IPA_CFG_PT pt, inout IPL4asp_Types.Result res) {
+ pt.call(IPA_CFG_disconnect:{res}) {
+ [] pt.getreply(IPA_CFG_disconnect:{?}) -> param (res) {};
+ }
+}
+
/* Function to use to connect as client to a remote IPA Server */
function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port,
charstring local_host, IPL4asp_Types.PortNumber local_port,
@@ -301,6 +333,25 @@ function f_bind(charstring local_host, IPL4asp_Types.PortNumber local_port,
g_is_bsc_mgw := false;
}
+private function f_close() runs on IPA_Emulation_CT return IPL4asp_Types.Result {
+ var IPL4asp_Types.Result res;
+ select (g_mode) {
+ case (IPA_MODE_CLIENT) {
+ res := IPA_CodecPort_CtrlFunct.f_IPL4_close(IPA_PORT, g_self_conn_id, {tcp := {}});
+ g_self_conn_id := -1;
+ }
+ case (IPA_MODE_SERVER) {
+ res := IPA_CodecPort_CtrlFunct.f_IPL4_close(IPA_PORT, g_last_conn_id, {tcp := {}});
+ g_last_conn_id := -1;
+ }
+ case else {
+ setverdict(fail, "Unknown mode");
+ mtc.stop;
+ }
+ }
+ return res;
+}
+
#ifdef IPA_EMULATION_SCCP
template ASP_MTP3_TRANSFERind ts_MTP3_XFER_ind(integer opc, octetstring data) := {
sio := { '10'B, '00'B, '0011'B },
@@ -347,6 +398,11 @@ private function f_send_IPA_EVT(template (value) ASP_IPA_Event evt) runs on IPA_
IPA_RSPRO_PORT.send(evt);
}
#endif
+#ifdef IPA_EMULATION_OSMO_PCU
+ if (IPA_OSMO_PCU_PORT.checkstate("Connected")) {
+ IPA_OSMO_PCU_PORT.send(evt);
+ }
+#endif
/* FIXME: to other ports */
}
@@ -360,6 +416,11 @@ private function f_ccm_make_id_resp(PDU_IPA_CCM get) runs on IPA_Emulation_CT re
}
}
+ /* If no Tags were present in the received IPA message, .u = omit */
+ if (not ispresent(get.u)) {
+ return resp;
+ }
+
for (i := 0; i < sizeof(get.u.get); i := i + 1) {
var IpaCcmIdTag tag := get.u.get[i].tag;
var charstring foo;
@@ -549,11 +610,13 @@ function main_client(charstring remote_host, IPL4asp_Types.PortNumber remote_por
/* main function to use for a server-side IPA implementation */
function main_server(charstring local_host, IPL4asp_Types.PortNumber local_port,
boolean ccm_enabled := true,
- IpaInitBehavior init_behavior := IPA_INIT_SEND_IPA_ID_GET)
+ IpaInitBehavior init_behavior := IPA_INIT_SEND_IPA_ID_GET,
+ boolean server_stop_on_ipa_ev_down := true)
runs on IPA_Emulation_CT {
g_mode := IPA_MODE_SERVER;
g_ccm_enabled := ccm_enabled;
g_init_behavior := init_behavior;
+ g_server_stop_on_ipa_ev_down := server_stop_on_ipa_ev_down;
f_bind(local_host, local_port);
ScanEvents();
}
@@ -580,6 +643,13 @@ private function f_rspro_to_user(octetstring msg) runs on IPA_Emulation_CT {
}
#endif
+#ifdef IPA_EMULATION_OSMO_PCU
+private function f_osmo_pcu_to_user(octetstring msg) runs on IPA_Emulation_CT {
+ var PCUIF_Message pcuif_msg := dec_PCUIF_Message(msg);
+ IPA_OSMO_PCU_PORT.send(pcuif_msg);
+}
+#endif
+
#ifdef IPA_EMULATION_MGCP
private function f_mgcp_to_user(octetstring msg) runs on IPA_Emulation_CT {
var charstring msg_ch := oct2char(msg);
@@ -630,6 +700,7 @@ private function ScanEvents() runs on IPA_Emulation_CT {
var Socket_API_Definitions.PortEvent port_evt;
var octetstring payload;
var ASP_IPA_Unitdata ipa_ud;
+ var IPL4asp_Types.Result res;
#ifdef IPA_EMULATION_CTRL
var CtrlMessage ctrl_msg;
#endif
@@ -652,6 +723,9 @@ private function ScanEvents() runs on IPA_Emulation_CT {
#ifdef IPA_EMULATION_RSPRO
var RsproPDU rspro;
#endif
+#ifdef IPA_EMULATION_OSMO_PCU
+ var PCUIF_Message pcu;
+#endif
/* Set function for dissecting the binary */
var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen);
@@ -728,6 +802,11 @@ private function ScanEvents() runs on IPA_Emulation_CT {
f_rspro_to_user(ipa_rx.msg);
}
#endif
+#ifdef IPA_EMULATION_OSMO_PCU
+ case (IPAC_PROTO_EXT_OSMO_PCU) {
+ f_osmo_pcu_to_user(ipa_rx.msg);
+ }
+#endif
case else {
IPA_SP_PORT.send(f_to_asp(ipa_rx));
}
@@ -761,7 +840,9 @@ private function ScanEvents() runs on IPA_Emulation_CT {
log("IPA: Closed");
g_self_conn_id := -1;
f_send_IPA_EVT(ts_ASP_IPA_EV(ASP_IPA_EVENT_DOWN, asp_evt.connClosed.connId));
- self.stop;
+ if (g_mode != IPA_MODE_SERVER or g_server_stop_on_ipa_ev_down) {
+ self.stop;
+ }
}
[] IPA_PORT.receive(Socket_API_Definitions.PortEvent:{result:={errorCode:=ERROR_SOCKET, connId:=?, os_error_code:=?, os_error_text:=?}}) -> value port_evt {
@@ -819,6 +900,14 @@ private function ScanEvents() runs on IPA_Emulation_CT {
}
#endif
+#ifdef IPA_EMULATION_OSMO_PCU
+ [] IPA_OSMO_PCU_PORT.receive(PCUIF_Message:?) -> value pcu {
+ payload := enc_PCUIF_Message(pcu);
+ ipa_ud := valueof(t_ASP_IPA_UD(IPAC_PROTO_OSMO, payload, IPAC_PROTO_EXT_OSMO_PCU));
+ IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud));
+ }
+#endif
+
#ifdef IPA_EMULATION_RSL
/* Received RSL -> down into IPA */
[] IPA_RSL_PORT.receive(ASP_RSL_Unitdata:?) -> value rsl {
@@ -839,6 +928,11 @@ private function ScanEvents() runs on IPA_Emulation_CT {
IPA_PORT.send(f_from_asp(f_ipa_conn_id(), ipa_ud));
}
+ /* Received call to configure/operate the component */
+ [] CFG_PORT.getcall(IPA_CFG_disconnect:{?}) {
+ res := f_close();
+ CFG_PORT.reply(IPA_CFG_disconnect:{res});
+ }
}
}