osmith has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/38381?usp=email )
Change subject: library/GTPv1U_Templates: support sending ext hdrs ......................................................................
library/GTPv1U_Templates: support sending ext hdrs
Replace the seq (sequenceNumber) parameter in ts_GTP1U_PDU with opt_part (GTPU_Header_optional_part). opt_part contains seq:
type record GTPU_Header_optional_part { OCT2 sequenceNumber, OCT1 npduNumber, OCT1 nextExtHeader, GTPU_ExtensionHeader_List gTPU_extensionHeader_List optional }
With this change it is possible to set the extension headers too when sending GTPU packets. This is in preparation for a GGSN test case with extension headers.
Related: OS#6223 Change-Id: I5b1668d45f4454f92c234054678e17145bd4fe49 --- M epdg/EPDG_Tests.ttcn M ggsn_tests/GGSN_Tests.ttcn M hnodeb/HNBGW_ConnectionHandler.ttcn M library/GTPv1U_Templates.ttcn M sgsn/BSSGP_ConnHdlr.ttcn 5 files changed, 31 insertions(+), 19 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/81/38381/1
diff --git a/epdg/EPDG_Tests.ttcn b/epdg/EPDG_Tests.ttcn index f963994..d9300a6 100644 --- a/epdg/EPDG_Tests.ttcn +++ b/epdg/EPDG_Tests.ttcn @@ -862,7 +862,7 @@ } private function f_GTP1U_send(octetstring payload) runs on EPDG_ConnHdlr { var Gtp1uPeer peer := valueof(ts_GtpPeerU(f_inet_addr(g_pars.bearer.gtpu_addr_remote))); - GTP2.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, g_pars.bearer.teid_remote, payload)); + GTP2.send(ts_GTP1U_GPDU(peer, omit /*opt_part*/, g_pars.bearer.teid_remote, payload)); } private function f_GTP1U_echo_ping_pong(uint16_t seq_nr := 0) runs on EPDG_ConnHdlr { var Gtp1uPeer peer := valueof(ts_GtpPeerU(f_inet_addr(g_pars.bearer.gtpu_addr_remote))); diff --git a/ggsn_tests/GGSN_Tests.ttcn b/ggsn_tests/GGSN_Tests.ttcn index 7f4a7bb..e88ab80 100644 --- a/ggsn_tests/GGSN_Tests.ttcn +++ b/ggsn_tests/GGSN_Tests.ttcn @@ -399,12 +399,14 @@
/* send GTP-U for a given context and increment sequence number */ function f_send_gtpu(inout PdpContext ctx, in octetstring data) runs on GT_CT { + var template (omit) GTPU_Header_optional_part opt_part; + if (use_gtpu_txseq) { - GTPU.send(ts_GTP1U_GPDU(g_peer_u, g_d_seq_nr, ctx.teid_remote, data)); + opt_part := f_GTPU_opt_part_from_seq(g_d_seq_nr); g_d_seq_nr := (g_d_seq_nr + 1) mod 65536; - } else { - GTPU.send(ts_GTP1U_GPDU(g_peer_u, omit, ctx.teid_remote, data)); } + + GTPU.send(ts_GTP1U_GPDU(g_peer_u, opt_part, ctx.teid_remote, data)); }
function f_handle_create_req(inout PdpContext ctx, in Gtp1cUnitdata ud, in template OCT1 exp_cause := '80'O) runs on GT_CT { diff --git a/hnodeb/HNBGW_ConnectionHandler.ttcn b/hnodeb/HNBGW_ConnectionHandler.ttcn index a72b5f2..5afeede 100644 --- a/hnodeb/HNBGW_ConnectionHandler.ttcn +++ b/hnodeb/HNBGW_ConnectionHandler.ttcn @@ -200,7 +200,7 @@
function f_gtpu_send(uint32_t tei, octetstring payload) runs on HNBGW_ConnHdlr { var Gtp1uPeer peer := valueof(ts_GtpPeerU(g_pars.hnodeb_addr)); - GTP[0].send(ts_GTP1U_GPDU(peer, 0 /*seq*/, int2oct(tei, 4), payload)); + GTP[0].send(ts_GTP1U_GPDU(peer, omit /*opt_part*/, int2oct(tei, 4), payload)); }
/* HNBLLIF socket may at any time receive a new INFO.ind */ diff --git a/library/GTPv1U_Templates.ttcn b/library/GTPv1U_Templates.ttcn index c242115..6efb96b 100644 --- a/library/GTPv1U_Templates.ttcn +++ b/library/GTPv1U_Templates.ttcn @@ -34,14 +34,24 @@ gtpu_IEs := ies }
- function f_GTPU_s_bit(template (omit) uint16_t seq) return BIT1 { - if (istemplatekind(seq, "omit")) { + function f_GTPU_s_bit(template (omit) GTPU_Header_optional_part opt_part) return BIT1 { + if (istemplatekind(opt_part, "omit")) { return '0'B; } return '1'B; }
- function f_GTPU_opt_part(template (omit) uint16_t seq) return template (omit) GTPU_Header_optional_part { + function f_GTPU_e_bit(template (omit) GTPU_Header_optional_part opt_part) return BIT1 { + if (istemplatekind(opt_part, "omit")) { + return '0'B; + } + if (istemplatekind(opt_part.gTPU_extensionHeader_List, "omit")) { + return '0'B; + } + return '1'B; + } + + function f_GTPU_opt_part_from_seq(template (omit) uint16_t seq) return template (omit) GTPU_Header_optional_part { if (istemplatekind(seq, "omit")) { return omit; } @@ -56,7 +66,7 @@
/* generalized GTP-U send template */ template (value) PDU_GTPU ts_GTP1U_PDU(template (value) OCT1 msg_type, - template (omit) uint16_t seq, + template (omit) GTPU_Header_optional_part opt_part, template (value) OCT4 teid, template (value) GTPU_IEs ies) := { /* N-PDU Number flag (PN): the GTP-U header contains a meaningful N-PDU Number field if the PN @@ -69,9 +79,9 @@ * Note that the caller must ensure that these conditions hold. * The caller can either pass a sequence number (we set s_bit to '1'B) when appropriate, * or may omit the sequence number (we set s_bit to '0'B). */ - s_bit := f_GTPU_s_bit(seq), + s_bit := f_GTPU_s_bit(opt_part), /* Extension header presence */ - e_bit := '0'B, + e_bit := f_GTPU_e_bit(opt_part), spare := '0'B, /* Protocol Type flag (PT) shall be set to '1' in GTP */ pt := '1'B, @@ -80,7 +90,7 @@ messageType := msg_type, lengthf := 0, /* we assume encoder overwrites this */ teid := teid, - opt_part := f_GTPU_opt_part(seq), + opt_part := opt_part, gtpu_IEs := ies }
@@ -119,7 +129,7 @@ template (value) Gtp1uUnitdata ts_GTPU_PING(template (value) Gtp1uPeer peer, template (value) uint16_t seq) := { peer := peer, - gtpu := ts_GTP1U_PDU('01'O, seq, '00000000'O, ts_UEchoReqPDU) + gtpu := ts_GTP1U_PDU('01'O, f_GTPU_opt_part_from_seq(seq), '00000000'O, ts_UEchoReqPDU) }
template GTPU_IEs ts_UEchoRespPDU(template (value) OCT1 restart_counter) := { @@ -137,7 +147,7 @@ template (value) uint16_t seq, template (value) OCT1 rest_ctr) := { peer := peer, - gtpu := ts_GTP1U_PDU('02'O, seq, '00000000'O, ts_UEchoRespPDU(rest_ctr)) + gtpu := ts_GTP1U_PDU('02'O, f_GTPU_opt_part_from_seq(seq), '00000000'O, ts_UEchoRespPDU(rest_ctr)) }
template (present) GSNAddress_gtpu tr_UGsnAddr(template (present) octetstring ip_addr := ?) := { @@ -189,15 +199,15 @@ template (value) OCT4 teid, template (value) octetstring gsn_addr) := { peer := peer, - gtpu := ts_GTP1U_PDU('1A'O, seq, '00000000'O, ts_UErrorIndication(teid, gsn_addr)) + gtpu := ts_GTP1U_PDU('1A'O, f_GTPU_opt_part_from_seq(seq), '00000000'O, ts_UErrorIndication(teid, gsn_addr)) }
/* master template for sending a GTP-U user plane data */ template (value) Gtp1uUnitdata ts_GTP1U_GPDU(template (value) Gtp1uPeer peer, - template (omit) uint16_t seq, + template (omit) GTPU_Header_optional_part opt_part, template (value) OCT4 teid, template (value) octetstring data) := { peer := peer, - gtpu := ts_GTP1U_PDU('FF'O, seq, teid, { g_PDU_IEs := { data := data }}) + gtpu := ts_GTP1U_PDU('FF'O, opt_part, teid, { g_PDU_IEs := { data := data }}) } } diff --git a/sgsn/BSSGP_ConnHdlr.ttcn b/sgsn/BSSGP_ConnHdlr.ttcn index 055902a..c39b614 100644 --- a/sgsn/BSSGP_ConnHdlr.ttcn +++ b/sgsn/BSSGP_ConnHdlr.ttcn @@ -1060,7 +1060,7 @@ peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u)); rem_teid := apars.sgsn_tei_u; } - GTP[GTP_GGSN_IDX].send(ts_GTP1U_GPDU(peer, 0 /*seq*/, rem_teid, payload)); + GTP[GTP_GGSN_IDX].send(ts_GTP1U_GPDU(peer, omit /*opt_part*/, rem_teid, payload)); }
altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr { @@ -1143,7 +1143,7 @@ } else if (is_iu(ran_index)) { /* Send PDU via GTPv1U from simulated MS/RNC directly to the simulated GGSN: */ rx_peer := valueof(ts_GtpPeerU(apars.rnc_ip_u)); - GTP[ran2gtp_idx(ran_index)].send(ts_GTP1U_GPDU(valueof(ts_GtpPeerU(apars.ggsn_ip_u)), 0 /*seq*/, apars.ggsn_tei_u, payload)); + GTP[ran2gtp_idx(ran_index)].send(ts_GTP1U_GPDU(valueof(ts_GtpPeerU(apars.ggsn_ip_u)), omit /*opt_part*/, apars.ggsn_tei_u, payload)); } /* Expect PDU via GTP from RNC/SGSN on simulated GGSN */ alt {