RAN_Emulation: Modularize protocol support
The RAN_Emulation currently unconditionally provides BSSAP and MGCP support.
Let's re-structure the code so that support for those protocols is now
possible to enable/disable at compile time.
This patch is in preparation of introducing RANAP support in RAN_Emulation.
Change-Id: Id53ba3ff05f9946230e0e4a759245de14a0f9fbd
Related: OS#2856
diff --git a/library/RAN_Adapter.ttcnpp b/library/RAN_Adapter.ttcnpp
new file mode 100644
index 0000000..43b4988
--- /dev/null
+++ b/library/RAN_Adapter.ttcnpp
@@ -0,0 +1,165 @@
+module RAN_Adapter {
+
+/* This module implements a 'dumb' RAN adapter. It creates the M3UA and SCCP components and stacks a
+ * BSSAP/RANAP codec port on top. As a result, it provides the ability to transceive SCCP-User-SAP primitives
+ * with deoded BSSAP/RANAP payload. Use this if you want to have full control about what you transmit or
+ * receive, without any automatisms in place. Allows you to refuse connections or other abnormal behavior. */
+
+import from General_Types all;
+import from Osmocom_Types all;
+
+import from M3UA_Emulation all;
+import from MTP3asp_Types all;
+import from MTP3asp_PortType all;
+
+import from IPA_Emulation all;
+
+import from SCCP_Types all;
+import from SCCPasp_Types all;
+import from SCCP_Emulation all;
+import from SCCP_Templates all;
+
+import from SCTPasp_Types all;
+import from SCTPasp_PortType all;
+
+import from BSSMAP_Templates all;
+import from RAN_Emulation all;
+
+type record RAN_Adapter {
+ /* component references */
+ M3UA_CT vc_M3UA, /* only in 3GPP AoIP */
+ IPA_Emulation_CT vc_IPA, /* only in SCCPlite */
+ IPA_EventWaiter_CT vc_WAIT, /* only in SCCPlite */
+ SCCP_CT vc_SCCP,
+
+ MSC_SCCP_MTP3_parameters sccp_pars,
+ SCCP_PAR_Address sccp_addr_own,
+ SCCP_PAR_Address sccp_addr_peer,
+
+ /* handler mode */
+ RAN_Emulation_CT vc_RAN
+}
+
+type enumerated RAN_Transport {
+ BSSAP_TRANSPORT_AoIP, /* 3GPP AoIP: SCCP over M3UA over SCTP */
+ BSSAP_TRANSPORT_SCCPlite_SERVER, /* SCCPlite: SCCP over IPA over TCP */
+ BSSAP_TRANSPORT_SCCPlite_CLIENT /* SCCPlite: SCCP over IPA over TCP */
+};
+
+type record RAN_Configuration {
+ RAN_Transport transport,
+ charstring sccp_service_type,
+ SCTP_Association_Address sctp_addr,
+ integer own_pc,
+ integer own_ssn,
+ integer peer_pc,
+ integer peer_ssn,
+ octetstring sio,
+ integer rctx
+};
+
+private function init_pars(inout RAN_Adapter ba, in RAN_Configuration cfg) {
+ ba.sccp_pars := {
+ sio := {
+ ni := substr(oct2bit(cfg.sio),0,2),
+ prio := substr(oct2bit(cfg.sio),2,2),
+ si := substr(oct2bit(cfg.sio),4,4)
+ },
+ opc := cfg.own_pc,
+ dpc := cfg.peer_pc,
+ sls := 0,
+ sccp_serviceType := cfg.sccp_service_type,
+ ssn := cfg.own_ssn
+ };
+ ba.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(cfg.own_pc, cfg.own_ssn, cfg.sio, cfg.sccp_service_type));
+ ba.sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(cfg.peer_pc, cfg.peer_ssn, cfg.sio, cfg.sccp_service_type));
+}
+
+
+function f_bssap_init(inout RAN_Adapter ba, in RAN_Configuration cfg, charstring id,
+ template RanOps ops) {
+ init_pars(ba, cfg);
+ ops.sccp_addr_local := ba.sccp_addr_own;
+ ops.sccp_addr_peer := ba.sccp_addr_peer;
+
+ /* create components */
+ ba.vc_SCCP := SCCP_CT.create(id & "-SCCP");
+ if (isvalue(ops)) {
+ ba.vc_RAN := RAN_Emulation_CT.create(id & "-RAN");
+ }
+ select (cfg.transport) {
+#ifdef RAN_EMULATION_BSSAP
+ case (BSSAP_TRANSPORT_AoIP) {
+ ba.vc_M3UA := M3UA_CT.create(id & "-M3UA");
+ map(ba.vc_M3UA:SCTP_PORT, system:sctp);
+ /* connect MTP3 service provider (M3UA) to lower side of SCCP */
+ connect(ba.vc_M3UA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);
+ ba.vc_M3UA.start(f_M3UA_Emulation(cfg.sctp_addr, cfg.rctx));
+ }
+ case (BSSAP_TRANSPORT_SCCPlite_SERVER) {
+ ba.vc_IPA := IPA_Emulation_CT.create(id & "-IPA");
+ map(ba.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
+ /* connect MTP3 service provider (IPA) to lower side of SCCP */
+ connect(ba.vc_IPA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);
+ /* connect waiter to general IPA port (for ASP_IPA_Event) */
+ ba.vc_WAIT := IPA_EventWaiter_CT.create(id & "-IPA-WAIT");
+ connect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
+ ba.vc_WAIT.start(IPA_Emulation.waiter_main());
+ ba.vc_IPA.start(IPA_Emulation.main_server(cfg.sctp_addr.local_ip_addr,
+ cfg.sctp_addr.local_sctp_port,
+ true, IPA_INIT_SEND_IPA_ID_ACK));
+ /* wait until we received an IPA CCM ID_ACK */
+ ba.vc_WAIT.done;
+ disconnect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
+ }
+ case (BSSAP_TRANSPORT_SCCPlite_CLIENT) {
+ ba.vc_IPA := IPA_Emulation_CT.create(id & "-IPA");
+ map(ba.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
+ /* connect MTP3 service provider (IPA) to lower side of SCCP */
+ connect(ba.vc_IPA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);
+ /* connect waiter to general IPA port (for ASP_IPA_Event) */
+ ba.vc_WAIT := IPA_EventWaiter_CT.create(id & "-IPA-WAIT");
+ connect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
+ ba.vc_WAIT.start(IPA_Emulation.waiter_main());
+ ba.vc_IPA.start(IPA_Emulation.main_client(cfg.sctp_addr.remote_ip_addr,
+ cfg.sctp_addr.remote_sctp_port,
+ cfg.sctp_addr.local_ip_addr,
+ cfg.sctp_addr.local_sctp_port));
+ /* wait until we received an IPA CCM ID_ACK */
+ ba.vc_WAIT.done;
+ disconnect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
+ }
+#endif
+ case else {
+ setverdict(fail, "Unsuppored RAN_Transport");
+ mtc.stop;
+ }
+ }
+
+ if (isvalue(ops)) {
+ timer T := 5.0;
+ T.start;
+ //T.timeout;
+ log("Connecting BSSMAP Emulation to SCCP_SP_PORT and starting emulation");
+#if RAN_EMULATION_BSSAP
+ /* connect BSSNAP component to upper side of SCCP */
+ connect(ba.vc_RAN:BSSAP, ba.vc_SCCP:SCCP_SP_PORT);
+#endif
+ if (cfg.transport == BSSAP_TRANSPORT_SCCPlite_SERVER or
+ cfg.transport == BSSAP_TRANSPORT_SCCPlite_CLIENT) {
+ /* connect IPA MGCP port with BSSMAP MGCP port */
+ connect(ba.vc_IPA:IPA_MGCP_PORT, ba.vc_RAN:MGCP);
+ }
+ /* start the BSSMAP emulation */
+ ba.vc_RAN.start(RAN_Emulation.main(valueof(ops), ""));
+ }
+
+
+}
+
+function f_bssap_start(inout RAN_Adapter ba) {
+ ba.vc_SCCP.start(SCCPStart(ba.sccp_pars));
+}
+
+
+}