hnodeb: Add gtp SAPI

Change-Id: Ie4de00641089abbd03273ce5a2d9325659ac7d42
diff --git a/hnodeb/HNB_Tests.ttcn b/hnodeb/HNB_Tests.ttcn
index 05cd2bf..ca42e5c 100644
--- a/hnodeb/HNB_Tests.ttcn
+++ b/hnodeb/HNB_Tests.ttcn
@@ -52,6 +52,10 @@
 import from HNBLLIF_Types all;
 import from HNBLLIF_Templates all;
 
+import from GTPU_Types all;
+import from GTP_Templates all;
+import from GTP_Emulation all;
+
 modulepar {
 	/* IP address at which the HNodeB can be reached */
 	charstring mp_hnodeb_ip := "127.0.0.1";
@@ -359,12 +363,70 @@
 	f_shutdown_helper();
 }
 
+private function f_tc_ps_mo_gtp_ping_pong(charstring id) runs on HNBGW_ConnHdlr {
+	const integer context_id := 30;
+	const bitstring context_id_bstr := '000000000000000000011110'B; /* encoded context_id */
+	const Establishment_Cause est_cause := normal_call;
+	var uint32_t remote_tei := 8888;
+	var uint32_t local_tei;
+	var octetstring gtp_payload := f_rnd_octstring(40);
+	var HNBLLIF_send_data sd;
+
+	f_gtp_register_teid(int2oct(remote_tei, 4));
+
+	f_handle_hnbap_hnb_register_req();
+
+	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONFIGURE_IND(g_pars.mcc, g_pars.mnc, g_pars.cell_identity,
+						  g_pars.lac, g_pars.rac, g_pars.sac, g_pars.rnc_id)));
+
+	/* Now an UE attempts CM Service Request: */
+	LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_ESTABLISH_REQ(context_id, 1, enum2int(est_cause), hex2oct(ranap_cm_service_req))));
+	/* The related RUA Connect + RANAP message is received on Iuh: */
+	RUA.receive(tr_RUA_Connect(ps_domain, context_id_bstr, est_cause, hex2oct(ranap_cm_service_req)));
+
+	/* Now HNBGW answers with RUA-DirectTransfer(RANAP-RabASsReq) */
+	RUA.send(ts_RUA_DirectTransfer(ps_domain, context_id_bstr, hex2oct(ranap_rab_ass_req)));
+
+	/* Now on LLSK first the Conn establishment is confirmed and then we receive data */
+	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_ESTABLISH_CNF(context_id, 1, 0)));
+	LLSK.receive(f_llsk_rx(tr_HNBLLIF_IUH_CONN_DATA_IND(context_id, 1, hex2oct(ranap_rab_ass_req))));
+
+	/* Now LLSK provides the remote TransportLayerAddress from RabAssReq and asks SUT to provide a local address: */
+	LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_ESTABLISH_REQ(context_id, remote_tei, HNBLL_IF_ADDR_TYPE_IPV4,
+							      f_HNBLLIF_Addr(HNBLL_IF_ADDR_TYPE_IPV4, g_pars.hnbgw_addr))));
+	LLSK.receive(f_llsk_rx(tr_HNBLLIF_GTP_CONN_ESTABLISH_CNF(context_id, ?, 0,
+								 HNBLL_IF_ADDR_TYPE_IPV4, ?))) -> value sd;
+	local_tei := sd.data.u.gtp.u.conn_establish.u.cnf.local_tei;
+
+	/* Forward GTP data in both directions */
+	LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_DATA_REQ(context_id, remote_tei, gtp_payload)));
+	GTP.receive(tr_GTPU_GPDU(ts_GtpPeerU(g_pars.hnodeb_addr), int2oct(remote_tei, 4), gtp_payload));
+	f_gtpu_send(local_tei, gtp_payload);
+	LLSK.receive(f_llsk_rx(tr_HNBLLIF_GTP_CONN_DATA_IND(context_id, local_tei, gtp_payload)));
+
+	/* Done, release GTP conn */
+	LLSK.send(f_llsk_tx(ts_HNBLLIF_GTP_CONN_RELEASE_REQ(context_id, remote_tei)));
+
+	/* UE sends Iu Release Complete to release the conn */
+	LLSK.send(f_llsk_tx(ts_HNBLLIF_IUH_CONN_RELEASE_REQ(context_id, 1, 0, 0, hex2oct(iu_release_compl))));
+	RUA.receive(tr_RUA_Disconnect(ps_domain, context_id_bstr, ts_RUA_Cause(normal), hex2oct(iu_release_compl)));
+}
+testcase TC_ps_mo_gtp_ping_pong() runs on test_CT {
+	var HNBGW_ConnHdlr vc_conn;
+
+	f_init();
+	vc_conn := f_start_handler(refers(f_tc_ps_mo_gtp_ping_pong));
+	vc_conn.done;
+	f_shutdown_helper();
+}
+
 control {
 	execute( TC_hnb_register_request_accept() );
 	execute( TC_hnb_register_request_reject() );
 	execute( TC_mo_conn() );
 	execute( TC_paging() );
 	execute( TC_cs_mo_call() );
+	execute( TC_ps_mo_gtp_ping_pong() );
 }
 
 }