msc_tests: Initial skeleton for osmo-msc testing over SCCP/M3UA
diff --git a/msc_tests/MSC_Tests.ttcn b/msc_tests/MSC_Tests.ttcn
new file mode 100644
index 0000000..adb9453
--- /dev/null
+++ b/msc_tests/MSC_Tests.ttcn
@@ -0,0 +1,321 @@
+module MSC_Tests {
+
+import from General_Types all;
+import from Osmocom_Types all;
+
+import from M3UA_Types all;
+import from M3UA_Emulation all;
+
+import from MTP3asp_Types all;
+import from MTP3asp_PortType all;
+
+import from SCCPasp_Types all;
+import from SCCP_Types all;
+import from SCCP_Emulation all;
+
+import from SCTPasp_Types all;
+import from SCTPasp_PortType all;
+
+import from BSSAP_Types all;
+
+type component MTC_CT {
+ /* M3UA emulation component */
+ var M3UA_CT vc_M3UA;
+ /* SCCP emulation component */
+ var SCCP_CT vc_SCCP;
+ /* test port to SCCP emulation */
+ port SCCPasp_PT SCCP;
+
+ var octetstring g_sio;
+ var MSC_SCCP_MTP3_parameters g_sccp_pars;
+ var SCCP_PAR_Address g_sccp_addr_own, g_sccp_addr_peer;
+
+ var boolean g_initialized := false;
+}
+
+modulepar {
+ charstring mp_sccp_service_type := "mtp3_itu";
+
+ SCTP_Association_Address mp_sctp_addr := { 22905, "127.0.0.1", 2905, "127.0.0.1" };
+ integer mp_own_pc := 196;
+ integer mp_own_ssn := 254;
+
+ integer mp_peer_pc := 185; /* 0.23.1 */
+ integer mp_peer_ssn := 254;
+}
+
+
+/* construct a SCCP_PAR_Address with just PC + SSN and no GT */
+template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn) := {
+ addressIndicator := {
+ pointCodeIndic := '1'B,
+ ssnIndicator := '1'B,
+ globalTitleIndic := '0000'B,
+ routingIndicator := '1'B
+ },
+ signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, '83'O),
+ //signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, g_sio),
+ subsystemNumber := ssn,
+ globalTitle := omit
+}
+
+function init_pars() runs on MTC_CT {
+ g_sio := '83'O;
+ g_sccp_pars := {
+ sio := {
+ ni := substr(oct2bit(g_sio),0,2),
+ prio := substr(oct2bit(g_sio),2,2),
+ si := substr(oct2bit(g_sio),4,4)
+ },
+ opc := mp_own_pc,
+ dpc := mp_peer_pc,
+ sls := 0,
+ sccp_serviceType := mp_sccp_service_type,
+ ssn := mp_own_ssn
+ };
+ g_sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(mp_own_pc, mp_own_ssn));
+ g_sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(mp_peer_pc, mp_peer_ssn));
+}
+
+function init() runs on MTC_CT {
+
+ if (g_initialized == true) {
+ return;
+ }
+ g_initialized := true;
+
+ init_pars();
+
+ /* Create components */
+ vc_M3UA := M3UA_CT.create;
+ vc_SCCP := SCCP_CT.create;
+
+ /* connect system SCTP port to M3UA lower side */
+ map(vc_M3UA:SCTP_PORT, system:sctp);
+
+ /* connect MTP3 service provider to SCCP MTP3 port */
+ connect(vc_M3UA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT);
+
+ /* connect test suite to SCCP service provider port */
+ connect(self:SCCP, vc_SCCP:SCCP_SP_PORT);
+
+ vc_M3UA.start(f_M3UA_Emulation(mp_sctp_addr));
+ vc_SCCP.start(SCCPStart(g_sccp_pars));
+
+}
+
+function terminate() runs on MTC_CT {
+
+ disconnect(self:SCCP, vc_SCCP:SCCP_SP_PORT);
+ disconnect(vc_M3UA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT);
+ unmap(vc_M3UA:SCTP_PORT, system:sctp);
+
+ all component.stop;
+
+ self.stop;
+}
+
+testcase TC_nothing() runs on MTC_CT {
+ init();
+
+ timer T := 30.0;
+ T.start;
+ T.timeout;
+
+}
+
+template PDU_BSSAP ts_BSSAP_BSSMAP := {
+ discriminator := '0'B,
+ spare := '0000000'B,
+ dlci := omit,
+ lengthIndicator := 0, /* overwritten by codec */
+ pdu := ?
+}
+
+template PDU_BSSAP tr_BSSAP_BSSMAP := {
+ discriminator := '0'B,
+ spare := '0000000'B,
+ dlci := omit,
+ lengthIndicator := ?,
+ pdu := {
+ bssmap := ?
+ }
+}
+
+
+type integer BssmapCause;
+
+template (value) BSSMAP_IE_Cause ts_BSSMAP_IE_Cause(BssmapCause val) := {
+ elementIdentifier := '04'O,
+ lengthIndicator := 0,
+ causeValue := int2bit(val, 7),
+ extensionCauseValue := '0'B,
+ spare1 := omit
+}
+
+template (value) PDU_BSSAP ts_BSSMAP_Reset(BssmapCause cause) modifies ts_BSSAP_BSSMAP := {
+ pdu := {
+ bssmap := {
+ reset := {
+ messageType := '30'O,
+ cause := ts_BSSMAP_IE_Cause(cause),
+ a_InterfaceSelectorForReset := omit
+ }
+ }
+ }
+}
+
+template (value) PDU_BSSAP ts_BSSMAP_ResetAck modifies ts_BSSAP_BSSMAP := {
+ pdu := {
+ bssmap := {
+ resetAck := {
+ messageType := '31'O,
+ a_InterfaceSelectorForReset := omit
+ }
+ }
+ }
+}
+
+template PDU_BSSAP tr_BSSMAP_ResetAck modifies tr_BSSAP_BSSMAP := {
+ pdu := {
+ bssmap := {
+ resetAck := {
+ messageType := '31'O,
+ a_InterfaceSelectorForReset := *
+ }
+ }
+ }
+}
+
+template BSSMAP_IE_CellIdentifier ts_BSSMAP_IE_CellID := {
+ elementIdentifier := '05'O,
+ lengthIndicator := 0,
+ cellIdentifierDiscriminator := '0000'B,
+ spare1_4 := '0000'B,
+ cellIdentification := ?
+}
+
+type uint16_t BssmapLAC;
+type uint16_t BssmapCI;
+
+/*
+template BSSMAP_IE_CellIdentifier ts_CellId_CGI(mcc, mnc, lac, ci)
+modifies ts_BSSMAP_IE_CellID := {
+ cellIdentification := {
+ cI_LAC_CGI := {
+ mnc_mcc := FIXME,
+ lac := int2oct(lac, 2),
+ ci := int2oct(ci, 2)
+ }
+ }
+}
+*/
+
+template BSSMAP_IE_CellIdentifier ts_CellID_LAC_CI(BssmapLAC lac, BssmapCI ci)
+modifies ts_BSSMAP_IE_CellID := {
+ cellIdentification := {
+ cI_LAC_CI := {
+ lac := int2oct(lac, 2),
+ ci := int2oct(ci, 2)
+ }
+ }
+}
+
+template BSSMAP_IE_CellIdentifier ts_CellId_CI(BssmapCI ci)
+modifies ts_BSSMAP_IE_CellID := {
+ cellIdentification := {
+ cI_CI := int2oct(ci, 2)
+ }
+}
+
+template BSSMAP_IE_CellIdentifier ts_CellId_none
+modifies ts_BSSMAP_IE_CellID := {
+ cellIdentification := {
+ cI_noCell := ''O
+ }
+}
+
+
+template BSSMAP_IE_Layer3Information ts_BSSMAP_IE_L3Info(octetstring l3info) := {
+ elementIdentifier := '17'O,
+ lengthIndicator := 0,
+ layer3info := l3info
+}
+
+template PDU_BSSAP ts_BSSMAP_ComplL3(BSSMAP_IE_CellIdentifier cell_id, octetstring l3_info)
+modifies ts_BSSAP_BSSMAP := {
+ pdu := {
+ bssmap := {
+ completeLayer3Information := {
+ messageType := '57'O,
+ cellIdentifier := cell_id,
+ layer3Information := ts_BSSMAP_IE_L3Info(l3_info),
+ chosenChannel := omit,
+ lSAIdentifier := omit,
+ aPDU := omit,
+ codecList := omit,
+ redirectAttemptFlag := omit,
+ sendSequenceNumber := omit,
+ iMSI := omit
+ }
+ }
+ }
+}
+
+template PDU_BSSAP ts_BSSMAP_HandoReq(BssmapCause cause, BSSMAP_IE_CellIdentifierList cid_list)
+modifies ts_BSSAP_BSSMAP := {
+ pdu := {
+ bssmap := {
+ handoverRequired := {
+ messageType := '11'O,
+ cause := ts_BSSMAP_IE_Cause(cause),
+ responseRequest := omit,
+ cellIdentifierList := cid_list,
+ circuitPoolList := omit,
+ currentChannelType1 := omit,
+ speechVersion := omit,
+ queueingIndicator := omit,
+ oldToNewBSSInfo := omit,
+ sourceToTargetRNCTransparentInfo := omit,
+ sourceToTargetRNCTransparentInfoCDMA := omit,
+ gERANClassmark := omit,
+ talkerPriority := omit,
+ speechCodec := omit,
+ cSG_Identifier := omit
+ }
+ }
+ }
+}
+
+// enc_PDU_BSSAP
+
+function f_send_BSSAP_UNITDATA(template PDU_BSSAP bssap) runs on MTC_CT {
+ SCCP.send(t_ASP_N_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, '00000001'B, '00000001'B,
+ enc_PDU_BSSAP(valueof(bssap)), omit))
+}
+
+testcase TC_reset() runs on MTC_CT {
+ init();
+
+ timer T := 2.0;
+ T.start;
+ T.timeout;
+
+ f_send_BSSAP_UNITDATA(ts_BSSMAP_Reset(0));
+ T.start;
+ alt {
+ //[] SCCP.receive(tr_BSSMAP_ResetAck) { }
+ [] T.timeout { setverdict(fail); }
+ }
+
+ terminate();
+}
+
+
+control {
+ execute( TC_reset() );
+ execute( TC_nothing() );
+}
+
+
+}