First actual SGSN test case
Change-Id: Id66ddf8dbe1c5cfa96a087235588ba67763b7f05
diff --git a/sgsn/SGSN_Tests.ttcn b/sgsn/SGSN_Tests.ttcn
index d535432..c47403e 100644
--- a/sgsn/SGSN_Tests.ttcn
+++ b/sgsn/SGSN_Tests.ttcn
@@ -6,33 +6,181 @@
import from NS_Emulation all;
import from BSSGP_Types all;
import from BSSGP_Emulation all;
+import from Osmocom_Gb_Types all;
+
+import from MobileL3_CommonIE_Types all;
+import from MobileL3_GMM_SM_Types all;
+import from MobileL3_Types all;
+import from L3_Templates all;
+import from L3_Common all;
+
+import from GSUP_Emulation all;
+import from GSUP_Types all;
+import from IPA_Emulation all;
+
+modulepar {
+ /* IP/port on which we run our internal GSUP/HLR emulation */
+ charstring mp_hlr_ip := "127.0.0.1";
+ integer mp_hlr_port := 4222;
+};
+
+type record GbInstance {
+ NS_CT vc_NS,
+ BSSGP_CT vc_BSSGP,
+ BssgpConfig cfg
+};
type component test_CT {
- var NS_CT vc_NS;
+ var GbInstance g_gb[3];
- var BSSGP_CT vc_BSSGP;
- port BSSGP_PT BSSGP;
+ var GSUP_Emulation_CT vc_GSUP;
+ var IPA_Emulation_CT vc_GSUP_IPA;
+ /* only to get events from IPA underneath GSUP */
+ port IPA_CTRL_PT GSUP_IPA_EVENT;
var boolean g_initialized := false;
};
+type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr {
+ var BSSGP_ConnHdlrPars g_pars;
+}
+
+type record SGSN_ConnHdlrNetworkPars {
+ boolean expect_ptmsi,
+ boolean expect_auth,
+ boolean expect_ciph
+};
+
+type record BSSGP_ConnHdlrPars {
+ /* IMEI of the simulated ME */
+ hexstring imei,
+ /* IMEI of the simulated MS */
+ hexstring imsi,
+ /* MSISDN of the simulated MS (probably unused) */
+ hexstring msisdn,
+ /* P-TMSI allocated to the simulated MS */
+ OCT4 p_tmsi optional,
+ /* TLLI of the simulated MS */
+ OCT4 tlli,
+ RoutingAreaIdentificationV ra optional,
+ BssgpCellId bssgp_cell_id,
+ AuthVector vec optional,
+ SGSN_ConnHdlrNetworkPars net
+};
+
+
+private function f_init_gb(inout GbInstance gb) runs on test_CT {
+ gb.vc_NS := NS_CT.create;
+ gb.vc_BSSGP := BSSGP_CT.create;
+ /* connect lower end of BSSGP emulation with NS upper port */
+ connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
+ /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
+ map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
+
+ gb.vc_NS.start(NSStart());
+ gb.vc_BSSGP.start(BssgpStart(gb.cfg));
+}
+
+private function f_init_gsup(charstring id) runs on test_CT {
+ id := id & "-GSUP";
+ var GsupOps ops := {
+ create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
+ };
+
+ vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
+ vc_GSUP := GSUP_Emulation_CT.create(id);
+
+ map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
+ connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
+ /* we use this hack to get events like ASP_IPA_EVENT_UP */
+ connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
+
+ vc_GSUP.start(GSUP_Emulation.main(ops, id));
+ vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
+
+ /* wait for incoming connection to GSUP port before proceeding */
+ timer T := 10.0;
+ T.start;
+ alt {
+ [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
+ [] T.timeout {
+ setverdict(fail, "No connection to GSUP Port");
+ self.stop;
+ }
+ }
+}
+
function f_init() runs on test_CT {
if (g_initialized == true) {
return;
}
g_initialized := true;
+ g_gb[0].cfg := {
+ nsei := 96,
+ bvci := 196,
+ cell_id := {
+ ra_id := {
+ lai := {
+ mcc_mnc := '26242F'H, lac := 13135},
+ rac := 0
+ },
+ cell_id := 20960
+ },
+ sgsn_role := false
+ };
- vc_NS := NS_CT.create;
- vc_BSSGP := BSSGP_CT.create;
- /* connect our BSSGP port to upper end of BSSGP emulation */
- connect(self:BSSGP, vc_BSSGP:BSSGP_SP);
- /* connect lower end of BSSGP emulation with NS upper port */
- connect(vc_BSSGP:BSCP, vc_NS:NS_SP);
- /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
- map(vc_NS:NSCP, system:NS_CODEC_PORT);
+ f_init_gb(g_gb[0]);
+ f_init_gsup("SGSN_Test");
+}
- vc_NS.start(NSStart());
- vc_BSSGP.start(BssgpStart(false));
+type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
+
+/* helper function to create, connect and start a BSSGP_ConnHdlr component */
+function f_start_handler(void_fn fn, charstring id, GbInstance gb, integer imsi_suffix)
+runs on test_CT return BSSGP_ConnHdlr {
+ var BSSGP_ConnHdlr vc_conn;
+ var SGSN_ConnHdlrNetworkPars net_pars := {
+ expect_ptmsi := true,
+ expect_auth := true,
+ expect_ciph := false
+ };
+ var BSSGP_ConnHdlrPars pars := {
+ imei := f_gen_imei(imsi_suffix),
+ imsi := f_gen_imsi(imsi_suffix),
+ msisdn := f_gen_msisdn(imsi_suffix),
+ p_tmsi := omit,
+ tlli := 'FFFFFFFF'O,
+ ra := omit,
+ bssgp_cell_id := gb.cfg.cell_id,
+ vec := omit,
+ net := net_pars
+ };
+
+ vc_conn := BSSGP_ConnHdlr.create(id);
+ connect(vc_conn:BSSGP, gb.vc_BSSGP:BSSGP_SP);
+ connect(vc_conn:BSSGP_PROC, gb.vc_BSSGP:BSSGP_PROC);
+
+ connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
+ connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
+
+ vc_conn.start(f_handler_init(fn, id, pars));
+ return vc_conn;
+}
+
+/* first function called in every ConnHdlr */
+private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
+runs on BSSGP_ConnHdlr {
+ /* do some common stuff like setting up g_pars */
+ g_pars := pars;
+
+ /* register with BSSGP core */
+ f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id);
+ /* tell GSUP dispatcher to send this IMSI to us */
+ f_create_gsup_expect(hex2str(g_pars.imsi));
+
+ /* call the user-supplied test case function */
+ fn.apply(id);
+ f_bssgp_client_unregister(g_pars.imsi);
}
/* TODO:
@@ -59,8 +207,86 @@
f_sleep(20.0);
}
+altstep as_mm_identity() runs on BSSGP_ConnHdlr {
+ var MobileIdentityLV mi;
+ [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('001'B))) {
+ mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
+ BSSGP.send(ts_GMM_ID_RESP(mi));
+ repeat;
+ }
+ [] BSSGP.receive(tr_BD_L3_MT(tr_GMM_ID_REQ('010'B))) {
+ mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
+ BSSGP.send(ts_GMM_ID_RESP(mi));
+ repeat;
+ }
+}
-//control { }
+function f_gmm_auth () runs on BSSGP_ConnHdlr {
+ var BssgpDecoded bd;
+ var PDU_L3_MS_SGSN l3_mo;
+ var PDU_L3_SGSN_MS l3_mt;
+ var default di := activate(as_mm_identity());
+ if (g_pars.net.expect_auth) {
+ g_pars.vec := f_gen_auth_vec_2g();
+ var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
+ g_pars.vec.sres,
+ g_pars.vec.kc));
+ GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
+ GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
+ BSSGP.receive(tr_BD_L3_MT(tr_GMM_AUTH_REQ(g_pars.vec.rand))) -> value bd;
+ l3_mt := bd.l3_mt;
+ var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
+ l3_mo := valueof(ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres));
+ if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
+ l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
+ l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
+ valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
+ }
+ BSSGP.send(l3_mo);
+ }
+ deactivate(di);
+}
+
+private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
+ var MobileIdentityLV mi;
+ var RoutingAreaIdentificationV old_ra := { '2'H, '6'H, '2'H, 'F'H, '4'H, '2'H, '2342'O, '00'O };
+
+ if (ispresent(g_pars.p_tmsi)) {
+ mi := valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
+ } else {
+ mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
+ }
+
+ BSSGP.send(ts_GMM_ATTACH_REQ(mi, old_ra, false, false, omit, omit));
+ f_gmm_auth();
+ /* Expect MSC to perform LU with HLR */
+ GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
+ GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
+ GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
+ GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
+
+ BSSGP.receive(tr_BD_L3_MT(tr_GMM_ATTACH_ACCEPT(?, ?, ?)));
+ BSSGP.send(ts_GMM_ATTACH_COMPL);
+/*
+ alt {
+ [] as_mm_identity();
+ }
+*/
+ f_sleep(5.0);
+}
+
+testcase TC_attach() runs on test_CT {
+ var BSSGP_ConnHdlr vc_conn;
+ f_init();
+ f_sleep(1.0);
+ vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb[0], 1);
+ vc_conn.done;
+}
+
+
+control {
+ execute( TC_wait_ns_up() );
+}
diff --git a/sgsn/gen_links.sh b/sgsn/gen_links.sh
index 4b76196..bc2727d 100755
--- a/sgsn/gen_links.sh
+++ b/sgsn/gen_links.sh
@@ -55,13 +55,22 @@
FILES="BSSGP_EncDec.cc BSSGP_Types.ttcn"
gen_links $DIR $FILES
+DIR=$BASEDIR/titan.ProtocolModules.LLC_v7.1.0/src
+FILES="LLC_EncDec.cc LLC_Types.ttcn"
+gen_links $DIR $FILES
+
+DIR=$BASEDIR/titan.ProtocolModules.MobileL3_v13.4.0/src
+FILES="MobileL3_CC_Types.ttcn MobileL3_CommonIE_Types.ttcn MobileL3_GMM_SM_Types.ttcn MobileL3_MM_Types.ttcn MobileL3_RRM_Types.ttcn MobileL3_SMS_Types.ttcn MobileL3_SS_Types.ttcn MobileL3_Types.ttcn"
+gen_links $DIR $FILES
+
DIR=../library
FILES="General_Types.ttcn GSM_Types.ttcn GSM_RR_Types.ttcn Osmocom_Types.ttcn RLCMAC_Types.ttcn RLCMAC_CSN1_Types.ttcn RLCMAC_EncDec.cc "
FILES+="NS_Emulation.ttcn NS_CodecPort.ttcn NS_CodecPort_CtrlFunct.ttcn NS_CodecPort_CtrlFunctDef.cc "
FILES+="BSSGP_Emulation.ttcn Osmocom_Gb_Types.ttcn "
FILES+="Osmocom_CTRL_Types.ttcn Osmocom_CTRL_Functions.ttcn Osmocom_CTRL_Adapter.ttcn "
FILES+="Osmocom_VTY_Functions.ttcn "
+FILES+="LLC_Templates.ttcn L3_Templates.ttcn L3_Common.ttcn "
# IPA_Emulation + dependencies
FILES+="IPA_Types.ttcn IPA_Emulation.ttcn IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn
-IPA_CodecPort_CtrlFunctDef.cc Native_Functions.ttcn Native_FunctionDefs.cc GSUP_Types.ttcn MGCP_Types.ttcn RSL_Types.ttcn "
+IPA_CodecPort_CtrlFunctDef.cc Native_Functions.ttcn Native_FunctionDefs.cc GSUP_Types.ttcn GSUP_Emulation.ttcn MGCP_Types.ttcn RSL_Types.ttcn "
gen_links $DIR $FILES
diff --git a/sgsn/regen_makefile.sh b/sgsn/regen_makefile.sh
index 6824d94..c055065 100755
--- a/sgsn/regen_makefile.sh
+++ b/sgsn/regen_makefile.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-FILES="*.ttcn BSSGP_EncDec.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc NS_CodecPort_CtrlFunctDef.cc RLCMAC_EncDec.cc Native_FunctionDefs.cc SDP_EncDec.cc SDP_parse_.tab.c lex.SDP_parse_.c TELNETasp_PT.cc IPA_CodecPort_CtrlFunctDef.cc"
+FILES="*.ttcn BSSGP_EncDec.cc LLC_EncDec.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc NS_CodecPort_CtrlFunctDef.cc RLCMAC_EncDec.cc Native_FunctionDefs.cc SDP_EncDec.cc SDP_parse_.tab.c lex.SDP_parse_.c TELNETasp_PT.cc IPA_CodecPort_CtrlFunctDef.cc"
../regen-makefile.sh SGSN_Tests.ttcn $FILES