pgw: Support having several DIAMETER_ConnHdlr per PGW_Session_CT
A new intermediate component DIAMETER_ConnHdlr_CT is added which extends
the required DIAMETER_ConnHdlr by the DIAMETER_Emulation, and forwards
it to the PGW_Session_CT. This way, the PGW_Session_CT, which usually
runs the test code, will have access to GTP2, Gx and Gy messages for the
session.
Initial Gy support for PGW_Tests is added in follow-up patch.
Change-Id: I28f1ac0a013e479058f28a6feff6901b33f6c247
diff --git a/pgw/PGW_Tests.ttcn b/pgw/PGW_Tests.ttcn
index 775b904..16bea57 100644
--- a/pgw/PGW_Tests.ttcn
+++ b/pgw/PGW_Tests.ttcn
@@ -37,9 +37,9 @@
port GTP2EM_PT TEID0;
/* emulated PCRF */
- var DIAMETER_Emulation_CT vc_DIAMETER;
- port DIAMETER_PT DIAMETER_UNIT;
- port DIAMETEREM_PROC_PT DIAMETER_PROC;
+ var DIAMETER_Emulation_CT vc_Gx;
+ port DIAMETER_PT Gx_UNIT;
+ port DIAMETEREM_PROC_PT Gx_PROC;
/* global test case guard timer (actual timeout value is set in f_init()) */
timer T_guard;
}
@@ -52,10 +52,36 @@
}
}
+type component DIAMETER_ConnHdlr_CT extends DIAMETER_ConnHdlr {
+ port DIAMETER_Conn_PT DIAMETER_CLIENT;
+}
+
+function f_diam_connhldr_ct_main(hexstring imsi) runs on DIAMETER_ConnHdlr_CT {
+ var PDU_DIAMETER msg;
+
+ if (DIAMETER_PROC.checkstate("Connected")) {
+ f_diameter_expect(imsi);
+ }
+
+ while (true) {
+ alt {
+ [] DIAMETER_CLIENT.receive(PDU_DIAMETER:?) -> value msg {
+ DIAMETER.send(msg);
+ }
+ [] DIAMETER.receive(PDU_DIAMETER:?) -> value msg {
+ DIAMETER_CLIENT.send(msg);
+ }
+ }
+ }
+}
+
+
/* per-session component; we typically have 1..N per testcase */
-type component PGW_Session_CT extends GTP2_ConnHdlr, DIAMETER_ConnHdlr {
+type component PGW_Session_CT extends GTP2_ConnHdlr {
var SessionPars g_pars;
+ port DIAMETER_Conn_PT Gx;
+
/* TEI (Data) local side */
var OCT4 g_teid;
/* TEI (Control) local side */
@@ -139,13 +165,13 @@
auth_app_id := omit,
vendor_app_id := c_DIAMETER_3GPP_Gx_AID
};
- vc_DIAMETER := DIAMETER_Emulation_CT.create(id);
- map(vc_DIAMETER:DIAMETER, system:DIAMETER_CODEC_PT);
- connect(vc_DIAMETER:DIAMETER_UNIT, self:DIAMETER_UNIT);
- connect(vc_DIAMETER:DIAMETER_PROC, self:DIAMETER_PROC);
- vc_DIAMETER.start(DIAMETER_Emulation.main(ops, pars, id));
+ vc_Gx := DIAMETER_Emulation_CT.create(id);
+ map(vc_Gx:DIAMETER, system:DIAMETER_CODEC_PT);
+ connect(vc_Gx:DIAMETER_UNIT, self:Gx_UNIT);
+ connect(vc_Gx:DIAMETER_PROC, self:Gx_PROC);
+ vc_Gx.start(DIAMETER_Emulation.main(ops, pars, id));
- f_diameter_wait_capability(DIAMETER_UNIT);
+ f_diameter_wait_capability(Gx_UNIT);
/* Give some time for our emulation to get out of SUSPECT list of SUT (3 watchdong ping-pongs):
* RFC6733 sec 5.1
* RFC3539 sec 3.4.1 [5]
@@ -177,31 +203,38 @@
}
}
-function f_start_handler(void_fn fn, template (omit) SessionPars pars := omit)
+function f_start_handler(void_fn fn, template (omit) SessionPars pars_tmpl := omit)
runs on PGW_Test_CT return PGW_Session_CT {
var charstring id := testcasename();
+ var DIAMETER_ConnHdlr_CT vc_conn_gx;
var PGW_Session_CT vc_conn;
+ var SessionPars pars;
+
+ if (isvalue(pars_tmpl)) {
+ pars := valueof(pars_tmpl);
+ } else {
+ /*TODO: set default values */
+ }
+
vc_conn := PGW_Session_CT.create(id);
connect(vc_conn:GTP2, vc_GTP2:CLIENT);
connect(vc_conn:GTP2_PROC, vc_GTP2:CLIENT_PROC);
- if (isbound(vc_DIAMETER)) {
- connect(vc_conn:DIAMETER, vc_DIAMETER:DIAMETER_CLIENT);
- connect(vc_conn:DIAMETER_PROC, vc_DIAMETER:DIAMETER_PROC);
+ if (isbound(vc_Gx)) {
+ vc_conn_gx := DIAMETER_ConnHdlr_CT.create(id);
+ connect(vc_conn_gx:DIAMETER, vc_Gx:DIAMETER_CLIENT);
+ connect(vc_conn_gx:DIAMETER_PROC, vc_Gx:DIAMETER_PROC);
+ connect(vc_conn:Gx, vc_conn_gx:DIAMETER_CLIENT);
+ vc_conn_gx.start(f_diam_connhldr_ct_main(pars.imsi));
}
vc_conn.start(f_handler_init(fn, pars));
return vc_conn;
}
-private function f_handler_init(void_fn fn, template (omit) SessionPars pars := omit)
+private function f_handler_init(void_fn fn, SessionPars pars)
runs on PGW_Session_CT {
- if (isvalue(pars)) {
- g_pars := valueof(pars);
- }
- if (DIAMETER_PROC.checkstate("Connected")) {
- f_diameter_expect(g_pars.imsi);
- }
+ g_pars := valueof(pars);
fn.apply();
}
@@ -225,9 +258,9 @@
return f_concat_pad(12, '49123'H, suffix);
}
-private altstep as_DIA_CCR(DCC_NONE_CC_Request_Type req_type) runs on PGW_Session_CT {
+private altstep as_DIA_Gx_CCR(DCC_NONE_CC_Request_Type req_type) runs on PGW_Session_CT {
var PDU_DIAMETER rx_dia;
- [] DIAMETER.receive(tr_DIA_Gx_CCR(req_type := req_type)) -> value rx_dia {
+ [] Gx.receive(tr_DIA_Gx_CCR(req_type := req_type)) -> value rx_dia {
var template (omit) AVP avp;
var octetstring sess_id;
var AVP_Unsigned32 req_num;
@@ -238,10 +271,10 @@
avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_DCC_NONE_CC_Request_Number);
req_num := valueof(avp.avp_data.avp_DCC_NONE_CC_Request_Number);
- DIAMETER.send(ts_DIA_Gx_CCA(rx_dia.hop_by_hop_id, rx_dia.end_to_end_id, sess_id,
+ Gx.send(ts_DIA_Gx_CCA(rx_dia.hop_by_hop_id, rx_dia.end_to_end_id, sess_id,
req_type, req_num));
}
- [] DIAMETER.receive(PDU_DIAMETER:?) -> value rx_dia {
+ [] Gx.receive(PDU_DIAMETER:?) -> value rx_dia {
setverdict(fail, "Received unexpected DIAMETER ", rx_dia);
self.stop;
}
@@ -330,8 +363,8 @@
g2c.gtpcv2_pdu.createSessionRequest.servingNetwork := ts_GTP2C_ServingNetwork('001'H, '01F'H);
GTP2.send(g2c);
- if (DIAMETER_PROC.checkstate("Connected")) {
- as_DIA_CCR(INITIAL_REQUEST);
+ if (Gx.checkstate("Connected")) {
+ as_DIA_Gx_CCR(INITIAL_REQUEST);
}
alt {
[] GTP2.receive(tr_GTP2C_CreateSessionResp(d_teid:=g_teic, cause:='10'O)) -> value rx {
@@ -389,8 +422,8 @@
teid_list := {}, bearer_id := 1);
GTP2.send(g2c);
- if (DIAMETER_PROC.checkstate("Connected") and expect_diameter) {
- as_DIA_CCR(TERMINATION_REQUEST);
+ if (Gx.checkstate("Connected") and expect_diameter) {
+ as_DIA_Gx_CCR(TERMINATION_REQUEST);
}
alt {
[] GTP2.receive(tr_GTP2C_DeleteSessionResp(d_teid := exp_teid, cause := exp_cause)) {