Change in osmo-ttcn3-hacks[master]: pgw: Add support for PCRF emulation (CCR/CCA)

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Sun Apr 26 19:53:21 UTC 2020


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/17950 )


Change subject: pgw: Add support for PCRF emulation (CCR/CCA)
......................................................................

pgw: Add support for PCRF emulation (CCR/CCA)

If mp_pcrf_local_ip is set to a non-empty string, the PGW testsuite
now emulates a PCRF and expects the PGW to perform the related
transactions - so far Credit-Control-Request INITIAL_REQUEST
at session creation, and TERMINATION_REQUST at session deletion.

Change-Id: I5f0c7a66d38e5c8b5f36b45717d49648a14ed7b2
---
M library/DIAMETER_Templates.ttcn
M pgw/PGW_Tests.ttcn
M pgw/gen_links.sh
M pgw/regen_makefile.sh
4 files changed, 176 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/50/17950/1

diff --git a/library/DIAMETER_Templates.ttcn b/library/DIAMETER_Templates.ttcn
index 450e013..2cc2986 100644
--- a/library/DIAMETER_Templates.ttcn
+++ b/library/DIAMETER_Templates.ttcn
@@ -326,6 +326,51 @@
 		}
 	}
 }
+template (present) GenericAVP tr_AVP_AuthAppId(template (present) OCTET4 auth_app_id := ?) := {
+	avp := {
+		avp_header := tr_DIA_Hdr(c_AVP_Code_BASE_NONE_Auth_Application_Id),
+		avp_data := {
+			avp_BASE_NONE_Auth_Application_Id := auth_app_id
+		}
+	}
+}
+
+template (value) GenericAVP ts_AVP_CcReqType(template (value) DCC_NONE_CC_Request_Type r) := {
+	avp := {
+		avp_header := ts_DIA_Hdr(c_AVP_Code_DCC_NONE_CC_Request_Type),
+		avp_data := {
+			avp_DCC_NONE_CC_Request_Type := r
+		}
+	}
+}
+template (present) GenericAVP tr_AVP_CcReqType(template (present) DCC_NONE_CC_Request_Type r := ?) := {
+	avp := {
+		avp_header := tr_DIA_Hdr(c_AVP_Code_DCC_NONE_CC_Request_Type),
+		avp_data := {
+			avp_DCC_NONE_CC_Request_Type := r
+		}
+	}
+}
+
+template (value) GenericAVP ts_AVP_CcReqNum(template (value) AVP_Unsigned32 n) := {
+	avp := {
+		avp_header := ts_DIA_Hdr(c_AVP_Code_DCC_NONE_CC_Request_Number),
+		avp_data := {
+			avp_DCC_NONE_CC_Request_Number := n
+		}
+	}
+}
+template (present) GenericAVP tr_AVP_CcReqNum(template (present) AVP_Unsigned32 n := ?) := {
+	avp := {
+		avp_header := tr_DIA_Hdr(c_AVP_Code_DCC_NONE_CC_Request_Number),
+		avp_data := {
+			avp_DCC_NONE_CC_Request_Number := n
+		}
+	}
+}
+
+
+
 
 template (value) GenericAVP ts_AVP_SuppVendorIdRaw(uint32_t vendor_id) := {
 	avp := {
@@ -879,4 +924,43 @@
 
 
 
+/* RFC 4006 3.1.  Credit-Control-Request (CCR) Command */
+template (present) PDU_DIAMETER
+tr_DIA_CCR(template (present) DCC_NONE_CC_Request_Type req_type := INITIAL_REQUEST)
+:= tr_DIAMETER(flags:='11000000'B, cmd_code:=Credit_Control,
+			    app_id:=int2oct(c_DIAMETER_3GPP_Gx_AID, 4),
+	avps := superset(
+		tr_AVP_SessionId,
+		tr_AVP_OriginHost,
+		tr_AVP_OriginRealm,
+		tr_AVP_DestinationRealm,
+		tr_AVP_AuthAppId(int2oct(c_DIAMETER_3GPP_Gx_AID, 4)),
+		tr_AVP_CcReqType(req_type),
+		tr_AVP_CcReqNum(?)
+	));
+
+
+/* RFC 4006 3.2.  Credit-Control-Answer (CCA) Command */
+template (value) PDU_DIAMETER
+ts_DIA_CCA(template (value) UINT32 hbh_id, template (value) UINT32 ete_id,
+	   template (value) octetstring sess_id,
+	   template (value) DCC_NONE_CC_Request_Type req_type,
+	   template (value) AVP_Unsigned32 req_num)
+
+:= ts_DIAMETER(flags:='01000000'B, cmd_code:=Credit_Control,
+		app_id:=int2oct(c_DIAMETER_3GPP_Gx_AID, 4), hbh_id:=hbh_id, ete_id:=ete_id,
+	avps := {
+		ts_AVP_SessionId(sess_id),
+		ts_AVP_ResultCode(DIAMETER_SUCCESS),
+		ts_AVP_OriginHost("pcrf.localdomain"),
+		ts_AVP_OriginRealm("localdomain"),
+		ts_AVP_AuthAppId(int2oct(c_DIAMETER_3GPP_Gx_AID, 4)),
+		ts_AVP_CcReqType(req_type),
+		ts_AVP_CcReqNum(req_num)//,
+		// qos
+		// default eps bearer qos
+		// supported features
+		// origin
+	});
+
 }
diff --git a/pgw/PGW_Tests.ttcn b/pgw/PGW_Tests.ttcn
index c99302c..875f852 100644
--- a/pgw/PGW_Tests.ttcn
+++ b/pgw/PGW_Tests.ttcn
@@ -12,22 +12,37 @@
 
 import from DNS_Helpers all;
 
+
+import from DIAMETER_Types all;
+import from DIAMETER_Templates all;
+import from DIAMETER_Emulation all;
+
+
 modulepar {
 	charstring mp_pgw_hostname := "127.0.0.3";
 	charstring mp_local_hostname_c := "127.0.0.1";
 	charstring mp_local_hostname_u := "127.0.0.1";
+
 	charstring mp_run_prog_as_user := "laforge";
 	charstring mp_ping_hostname := "10.45.0.1";
+
+	charstring mp_pcrf_local_ip := "127.0.0.5";
+	integer mp_pcrf_local_port := 3868;
 }
 
 /* main component, we typically have one per testcase */
 type component PGW_Test_CT {
 	var GTPv2_Emulation_CT vc_GTP2;
 	port GTP2EM_PT TEID0;
+
+	/* emulated PCRF */
+	var DIAMETER_Emulation_CT vc_DIAMETER;
+	port DIAMETER_PT DIAMETER_UNIT;
+	port DIAMETEREM_PROC_PT DIAMETER_PROC;
 }
 
 /* per-session component; we typically have 1..N per testcase */
-type component PGW_Session_CT extends GTP2_ConnHdlr {
+type component PGW_Session_CT extends GTP2_ConnHdlr, DIAMETER_ConnHdlr {
 	var SessionPars	g_pars;
 
 	/* TEI (Data) local side */
@@ -91,6 +106,35 @@
 
 type function void_fn() runs on PGW_Session_CT;
 
+friend function DiameterForwardUnitdataCallback(PDU_DIAMETER msg)
+runs on DIAMETER_Emulation_CT return template PDU_DIAMETER {
+	DIAMETER_UNIT.send(msg);
+	return omit;
+}
+
+friend function f_init_diameter(charstring id) runs on PGW_Test_CT {
+	var DIAMETEROps ops := {
+		create_cb := refers(DIAMETER_Emulation.ExpectedCreateCallback),
+		unitdata_cb := refers(DiameterForwardUnitdataCallback)
+	};
+	var DIAMETER_conn_parameters pars := {
+		remote_ip := mp_pgw_hostname,
+		remote_sctp_port := -1,
+		local_ip := mp_pcrf_local_ip,
+		local_sctp_port := mp_pcrf_local_port,
+		origin_host := "pcrf.localdomain",
+		origin_realm := "localdomain",
+		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));
+	/* HACK: this is supposed to wait for the PGW to perform the CER/CEA dance */
+	f_sleep(10.0);
+}
+
 private function f_init() runs on PGW_Test_CT {
 	var Gtp2EmulationCfg cfg := {
 		gtpc_bind_ip := mp_local_hostname_c,
@@ -105,6 +149,10 @@
 	map(vc_GTP2:GTP2C, system:GTP2C);
 	connect(vc_GTP2:TEID0, self:TEID0);
 	vc_GTP2.start(GTPv2_Emulation.main(cfg));
+
+	if (mp_pcrf_local_ip != "") {
+		f_init_diameter(testcasename());
+	}
 }
 
 function f_start_handler(void_fn fn, template (omit) SessionPars pars := omit)
@@ -114,6 +162,12 @@
 	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);
+	}
+
 	vc_conn.start(f_handler_init(fn, pars));
 	return vc_conn;
 }
@@ -123,6 +177,9 @@
 	if (isvalue(pars)) {
 		g_pars := valueof(pars);
 	}
+	if (DIAMETER_PROC.checkstate("Connected")) {
+		f_diameter_expect(g_pars.imsi);
+	}
 	fn.apply();
 }
 
@@ -146,6 +203,28 @@
 	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 {
+	var PDU_DIAMETER rx_dia;
+	[] DIAMETER.receive(tr_DIA_CCR(req_type := req_type)) -> value rx_dia {
+		var template (omit) AVP avp;
+		var octetstring sess_id;
+		var AVP_Unsigned32 req_num;
+
+		avp := f_DIAMETER_get_avp(rx_dia, c_AVP_Code_BASE_NONE_Session_Id);
+		sess_id := valueof(avp.avp_data.avp_BASE_NONE_Session_Id);
+
+		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_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 {
+		setverdict(fail, "Received unexpected DIAMETER ", rx_dia);
+		self.stop;
+	}
+}
+
 
 /* find TEID of given interface type (and optionally instance) */
 private function f_find_teid(FullyQualifiedTEID_List list,
@@ -228,6 +307,9 @@
 	g2c.gtpcv2_pdu.createSessionRequest.userLocationInfo := ts_GTP2C_UserLocInfo(tai := tai, ecgi := ecgi);
 
 	GTP2.send(g2c);
+	if (DIAMETER_PROC.checkstate("Connected")) {
+		as_DIA_CCR(INITIAL_REQUEST);
+	}
 	alt {
 	[] GTP2.receive(tr_GTP2C_CreateSessionResp(d_teid:=g_teic, cause:='10'O)) -> value rx {
 		/* extract TEIDs */
@@ -283,6 +365,9 @@
 					  teid_list := {}, bearer_id := 1);
 
 	GTP2.send(g2c);
+	if (DIAMETER_PROC.checkstate("Connected")) {
+		as_DIA_CCR(TERMINATION_REQUEST);
+	}
 	alt {
 	[] GTP2.receive(tr_GTP2C_DeleteSessionResp(d_teid := exp_teid, cause := exp_cause)) {
 		setverdict(pass);
diff --git a/pgw/gen_links.sh b/pgw/gen_links.sh
index 061d78c..a0f1281 100755
--- a/pgw/gen_links.sh
+++ b/pgw/gen_links.sh
@@ -44,12 +44,17 @@
 FILES="UECUPS_CodecPort.ttcn  UECUPS_CodecPort_CtrlFunct.ttcn  UECUPS_CodecPort_CtrlFunctDef.cc UECUPS_Types.ttcn "
 gen_links $DIR $FILES
 
+DIR=$BASEDIR/titan.ProtocolModules.DIAMETER_ProtocolModule_Generator/src
+FILES="DIAMETER_EncDec.cc"
+gen_links $DIR $FILES
+
 DIR=../library
 FILES="Misc_Helpers.ttcn General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn Native_Functions.ttcn Native_FunctionDefs.cc IPCP_Types.ttcn PAP_Types.ttcn "
 FILES+="GTP_CodecPort.ttcn GTP_CodecPort_CtrlFunct.ttcn GTP_CodecPort_CtrlFunctDef.cc GTP_Templates.ttcn "
 FILES+="GTPv2_PrivateExtensions.ttcn GTPv2_Templates.ttcn "
 FILES+="GTPv2_CodecPort.ttcn GTPv2_CodecPort_CtrlFunctDef.cc GTPv2_CodecPort_CtrlFunct.ttcn GTPv2_Emulation.ttcn "
 FILES+="DNS_Helpers.ttcn "
+FILES+="DIAMETER_Types.ttcn DIAMETER_CodecPort.ttcn DIAMETER_CodecPort_CtrlFunct.ttcn DIAMETER_CodecPort_CtrlFunctDef.cc DIAMETER_Emulation.ttcn DIAMETER_Templates.ttcn "
 gen_links $DIR $FILES
 
 ignore_pp_results
diff --git a/pgw/regen_makefile.sh b/pgw/regen_makefile.sh
index f53150c..adb5820 100755
--- a/pgw/regen_makefile.sh
+++ b/pgw/regen_makefile.sh
@@ -2,5 +2,6 @@
 
 FILES="*.ttcn IPL4asp_PT.cc  IPL4asp_discovery.cc  TCCConversion.cc  TCCInterface.cc GTPC_EncDec.cc GTPU_EncDec.cc GTP_CodecPort_CtrlFunctDef.cc GTPv2_CodecPort_CtrlFunctDef.cc ICMPv6_EncDec.cc IP_EncDec.cc Native_FunctionDefs.cc UDP_EncDec.cc ICMP_EncDec.cc "
 FILES+="UECUPS_CodecPort_CtrlFunctDef.cc "
+FILES+="DIAMETER_EncDec.cc DIAMETER_CodecPort_CtrlFunctDef.cc "
 
 ../regen-makefile.sh PGW_Tests.ttcn $FILES

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/17950
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: I5f0c7a66d38e5c8b5f36b45717d49648a14ed7b2
Gerrit-Change-Number: 17950
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200426/2250cb0a/attachment.htm>


More information about the gerrit-log mailing list