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.orglaforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/17867 ) Change subject: Add GTPv2_Emulation component ...................................................................... Add GTPv2_Emulation component Change-Id: If73aa453e44ebf28032c60d207feb03e8061dc0c --- M deps/Makefile A library/GTPv2_Emulation.ttcn M library/GTPv2_Templates.ttcn M library/General_Types.ttcn M library/Osmocom_Types.ttcn 5 files changed, 1,197 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/67/17867/1 diff --git a/deps/Makefile b/deps/Makefile index 65958ae..977beba 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -59,7 +59,7 @@ titan.ProtocolModules.NAS_EPS_15.2.0.1 \ titan.ProtocolModules.NS_v7.3.0 \ titan.ProtocolModules.SGsAP_13.2.0 \ - titan.ProtocolModules.SNDCP_v7.0.0 \ + titan.ProtocolModules.SNDCP_v7.0.0 OSMOGITHUB_REPOS= titan.TestPorts.SCTPasp \ titan.TestPorts.MTP3asp \ @@ -69,7 +69,8 @@ OSMOGIT_REPOS= titan.ProtocolModules.MAP \ titan.ProtocolModules.BSSMAP \ - titan.TestPorts.USB + titan.TestPorts.USB \ + osmo-uecups ALL_REPOS=$(ECLIPSEGITHUB_REPOS) $(ECLIPSEGIT2_REPOS) $(OSMOGITHUB_REPOS) $(OSMOGIT_REPOS) @@ -125,6 +126,7 @@ titan.TestPorts.UDPasp_commit= c20d77a34f288dd70dd4aaa30e520778876e9336 titan.TestPorts.UNIX_DOMAIN_SOCKETasp_commit= R.2.A-8-g7ec4fe0 titan.TestPorts.USB_commit= master +osmo-uecups_commit= master all: $(foreach dir,$(ALL_REPOS),$(dir)/update) clean: $(foreach dir,$(ALL_REPOS),$(dir)/clean) diff --git a/library/GTPv2_Emulation.ttcn b/library/GTPv2_Emulation.ttcn new file mode 100644 index 0000000..4930d52 --- /dev/null +++ b/library/GTPv2_Emulation.ttcn @@ -0,0 +1,531 @@ +/* GTPv2 Emulation in TTCN-3 + * + * (C) 2018-2020 Harald Welte <laforge at gnumonks.org> + * All rights reserved. + * + * Released under the terms of GNU General Public License, Version 2 or + * (at your option) any later version. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +module GTPv2_Emulation { + +import from IPL4asp_Types all; +import from General_Types all; +import from Osmocom_Types all; +import from GTPv2_Types all; +import from GTPv2_CodecPort all; +import from GTPv2_CodecPort_CtrlFunct all; + +import from UECUPS_Types all; +import from UECUPS_CodecPort all; +import from UECUPS_CodecPort_CtrlFunct all; + +/*********************************************************************** + * Main Emulation Component + ***********************************************************************/ + +modulepar { + charstring mp_uecups_host := "127.0.0.1"; + integer mp_uecups_port := UECUPS_SCTP_PORT; +}; + +const integer GTP2C_PORT := 2123; +const integer GTP1U_PORT := 2152; + +type record Gtp2EmulationCfg { + HostName gtpc_bind_ip, + IPL4asp_Types.PortNumber gtpc_bind_port, + HostName gtpc_remote_ip, + IPL4asp_Types.PortNumber gtpc_remote_port, + //HostName gtpu_bind_ip, + //PortNumber gtpu_bind_port, + boolean sgw_role, + boolean use_gtpu_daemon +}; + +type component GTPv2_Emulation_CT { + /* Communication with underlying GTP CodecPort */ + port GTPv2C_PT GTP2C; + + /* Control port to GTP-U Daemon */ + port UECUPS_CODEC_PT UECUPS; + + /* Communication with Clients */ + port GTP2EM_PT TEID0; + port GTP2EM_PT CLIENT; + port GTP2EM_PROC_PT CLIENT_PROC; + + /* Configuration by the user */ + var Gtp2EmulationCfg g_gtp2_cfg; + + /* State */ + var GtpPeer g_peer; + var integer g_gtp2c_id; + var OCT1 g_restart_ctr; + var uint16_t g_c_seq_nr; + var TidTableRec TidTable[256]; + var ImsiTableRec ImsiTable[256]; + var PidTableRec PidTable[256]; + var integer g_uecups_conn_id; +}; + +type record TidTableRec { + OCT4 teid, + GTP2_ConnHdlr vc_conn +}; + +type record ImsiTableRec { + hexstring imsi, + GTP2_ConnHdlr vc_conn +}; + +type record PidTableRec { + /* process ID of the running process */ + integer pid, + /* component that started it */ + GTP2_ConnHdlr vc_conn +}; + +private function f_comp_by_teid(OCT4 teid) runs on GTPv2_Emulation_CT return GTP2_ConnHdlr { + var integer i; + for (i := 0; i < sizeof(TidTable); i := i+1) { + if (isbound(TidTable[i].teid) and TidTable[i].teid == teid) { + return TidTable[i].vc_conn; + } + } + setverdict(fail, "No Component for TEID ", teid); + mtc.stop; +} + +private function f_comp_by_imsi(hexstring imsi) runs on GTPv2_Emulation_CT return GTP2_ConnHdlr { + var integer i; + for (i := 0; i < sizeof(ImsiTable); i := i+1) { + if (isbound(ImsiTable[i].imsi) and ImsiTable[i].imsi == imsi) { + return ImsiTable[i].vc_conn; + } + } + setverdict(fail, "No Component for IMSI ", imsi); + mtc.stop; +} + +private function f_comp_by_pid(integer pid) runs on GTPv2_Emulation_CT return GTP2_ConnHdlr { + var integer i; + for (i := 0; i < sizeof(PidTable); i := i+1) { + if (isbound(PidTable[i].pid) and PidTable[i].pid == pid) { + /* fixme: remove */ + return PidTable[i].vc_conn; + } + } + setverdict(fail, "No Component for PID ", pid); + mtc.stop; +} + +private function f_tid_tbl_add(OCT4 teid, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT { + var integer i; + for (i := 0; i < sizeof(TidTable); i := i+1) { + if (not isbound(TidTable[i].teid)) { + TidTable[i].teid := teid; + TidTable[i].vc_conn := vc_conn; + return; + } + } + testcase.stop("No Space in TidTable for ", teid); +} + +private function f_imsi_tbl_add(hexstring imsi, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT { + var integer i; + for (i := 0; i < sizeof(ImsiTable); i := i+1) { + if (not isbound(ImsiTable[i].imsi)) { + ImsiTable[i].imsi := imsi; + ImsiTable[i].vc_conn := vc_conn; + return; + } + } + testcase.stop("No Space in IMSI Table for ", imsi); +} + +private function f_pid_tbl_add(integer pid, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT { + var integer i; + for (i := 0; i < sizeof(PidTable); i := i+1) { + if (not isbound(PidTable[i].pid)) { + PidTable[i].pid := pid; + PidTable[i].vc_conn := vc_conn; + return; + } + } + testcase.stop("No Space in PID Table for ", pid); +} + + +/* allocate an unused local teid */ +private function f_alloc_teid() runs on GTPv2_Emulation_CT return OCT4 { + var OCT4 teid; + var integer i, j; + for (i := 0; i < 100; i := i+1) { + teid := f_rnd_octstring(4); + for (j := 0; j < sizeof(TidTable); j := j+1) { + if (isbound(TidTable) and TidTable[i].teid == teid) { + continue; + } + } + /* we iterated over all entries and found no match: great! */ + return teid; + } + testcase.stop("Cannot find unused TEID after ", i, " attempts"); +} + +/* obtain the IMSI from a GTPv2C PDU, if there is any IMSI contained. The way how the TITAN + * GTPv2 decoders are structured (explict IE members rather than a list/set of generic IE structures) + * doesn't make this easy, but requires lots of boilerplate code. Oh well.. */ +function f_gtp2c_extract_imsi(PDU_GTPCv2 gtp) return template (omit) hexstring { + if (ischosen(gtp.gtpcv2_pdu.createSessionRequest)) { + if (ispresent(gtp.gtpcv2_pdu.createSessionRequest.iMSI)) { + return gtp.gtpcv2_pdu.createSessionRequest.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.downlinkDataNotification)) { + if (ispresent(gtp.gtpcv2_pdu.downlinkDataNotification.iMSI)) { + return gtp.gtpcv2_pdu.downlinkDataNotification.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.downlinkDataNotificationAcknowledgement)) { + if (ispresent(gtp.gtpcv2_pdu.downlinkDataNotificationAcknowledgement.iMSI)) { + return gtp.gtpcv2_pdu.downlinkDataNotificationAcknowledgement.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.downlinkDataNotificationFailureIndication)) { + if (ispresent(gtp.gtpcv2_pdu.downlinkDataNotificationFailureIndication.iMSI)) { + return gtp.gtpcv2_pdu.downlinkDataNotificationFailureIndication.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.createIndirectDataForwardingTunnelRequest)) { + if (ispresent(gtp.gtpcv2_pdu.createIndirectDataForwardingTunnelRequest.iMSI)) { + return gtp.gtpcv2_pdu.createIndirectDataForwardingTunnelRequest.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.stopPagingIndication)) { + if (ispresent(gtp.gtpcv2_pdu.stopPagingIndication.iMSI)) { + return gtp.gtpcv2_pdu.stopPagingIndication.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.forwardRelocationRequest)) { + if (ispresent(gtp.gtpcv2_pdu.forwardRelocationRequest.iMSI)) { + return gtp.gtpcv2_pdu.forwardRelocationRequest.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.contextRequest)) { + if (ispresent(gtp.gtpcv2_pdu.contextRequest.iMSI)) { + return gtp.gtpcv2_pdu.contextRequest.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.identificationResponse)) { + if (ispresent(gtp.gtpcv2_pdu.identificationResponse.iMSI)) { + return gtp.gtpcv2_pdu.identificationResponse.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.changeNotificationRequest)) { + if (ispresent(gtp.gtpcv2_pdu.changeNotificationRequest)) { + return gtp.gtpcv2_pdu.changeNotificationRequest.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.changeNotificationResponse)) { + if (ispresent(gtp.gtpcv2_pdu.changeNotificationResponse.iMSI)) { + return gtp.gtpcv2_pdu.changeNotificationResponse.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.relocationCancelRequest)) { + if (ispresent(gtp.gtpcv2_pdu.relocationCancelRequest.iMSI)) { + return gtp.gtpcv2_pdu.relocationCancelRequest.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.uE_RegistrationQueryRequest)) { + if (ispresent(gtp.gtpcv2_pdu.uE_RegistrationQueryRequest.iMSI)) { + return gtp.gtpcv2_pdu.uE_RegistrationQueryRequest.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.uE_RegistrationQueryResponse)) { + if (ispresent(gtp.gtpcv2_pdu.uE_RegistrationQueryResponse.iMSI)) { + return gtp.gtpcv2_pdu.uE_RegistrationQueryResponse.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.suspendNotification)) { + if (ispresent(gtp.gtpcv2_pdu.suspendNotification.iMSI)) { + return gtp.gtpcv2_pdu.suspendNotification.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.resumeNotification)) { + if (ispresent(gtp.gtpcv2_pdu.resumeNotification.iMSI)) { + return gtp.gtpcv2_pdu.resumeNotification.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.cSPagingIndication)) { + if (ispresent(gtp.gtpcv2_pdu.cSPagingIndication.iMSI)) { + return gtp.gtpcv2_pdu.cSPagingIndication.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.pGW_DownlinkTriggeringNotification)) { + if (ispresent(gtp.gtpcv2_pdu.pGW_DownlinkTriggeringNotification.iMSI)) { + return gtp.gtpcv2_pdu.pGW_DownlinkTriggeringNotification.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.pGW_DownlinkTriggeringAcknowledge)) { + if (ispresent(gtp.gtpcv2_pdu.pGW_DownlinkTriggeringAcknowledge.iMSI)) { + return gtp.gtpcv2_pdu.pGW_DownlinkTriggeringAcknowledge.iMSI.iMSI_Value; + } + } else if (ischosen(gtp.gtpcv2_pdu.traceSessionActivation)) { + if (ispresent(gtp.gtpcv2_pdu.traceSessionActivation.iMSI)) { + return gtp.gtpcv2_pdu.traceSessionActivation.iMSI.iMSI_Value; + } + } + return omit; +} + +private template (value) SctpTuple ts_SCTP(template (omit) integer ppid := omit) := { + sinfo_stream := omit, + sinfo_ppid := ppid, + remSocks := omit, + assocId := omit +}; + +function tr_UECUPS_RecvFrom_R(template PDU_UECUPS msg) +runs on GTPv2_Emulation_CT return template UECUPS_RecvFrom { + var template UECUPS_RecvFrom mrf := { + connId := g_uecups_conn_id, + remName := ?, + remPort := ?, + locName := ?, + locPort := ?, + msg := msg + } + return mrf; +} + + +private template PortEvent tr_SctpAssocChange := { + sctpEvent := { + sctpAssocChange := ? + } +} +private template PortEvent tr_SctpPeerAddrChange := { + sctpEvent := { + sctpPeerAddrChange := ? + } +} + +private function f_uecups_xceive(template (value) PDU_UECUPS tx, + template PDU_UECUPS rx_t := ?) +runs on GTPv2_Emulation_CT return PDU_UECUPS { + timer T := 10.0; + var UECUPS_RecvFrom mrf; + + UECUPS.send(t_UECUPS_Send(g_uecups_conn_id, tx)); + alt { + [] UECUPS.receive(tr_UECUPS_RecvFrom_R(rx_t)) -> value mrf { } + [] UECUPS.receive(tr_SctpAssocChange) { repeat; } + [] UECUPS.receive(tr_SctpPeerAddrChange) { repeat; } + [] T.timeout { + setverdict(fail, "Timeout waiting for ", rx_t); + mtc.stop; + } + } + return mrf.msg; +} + +private function f_init(Gtp2EmulationCfg cfg) runs on GTPv2_Emulation_CT { + var Result res; + + map(self:GTP2C, system:GTP2C); + res := GTPv2_CodecPort_CtrlFunct.f_IPL4_listen(GTP2C, cfg.gtpc_bind_ip, + cfg.gtpc_bind_port, {udp:={}}); + g_gtp2c_id := res.connId; + + g_restart_ctr := f_rnd_octstring(1); + g_c_seq_nr := f_rnd_int(65535); + g_gtp2_cfg := cfg; + g_peer := { + connId := g_gtp2c_id, + remName := g_gtp2_cfg.gtpc_remote_ip, + remPort := g_gtp2_cfg.gtpc_remote_port + } + + if (g_gtp2_cfg.use_gtpu_daemon) { + map(self:UECUPS, system:UECUPS); + res := UECUPS_CodecPort_CtrlFunct.f_IPL4_connect(UECUPS, mp_uecups_host, mp_uecups_port, "", -1, -1, { sctp := valueof(ts_SCTP) }); + if (not ispresent(res.connId)) { + setverdict(fail, "Could not connect UECUPS socket, check your configuration"); + testcase.stop; + } + g_uecups_conn_id := res.connId; + + /* clear all tunnel state in the daemon at start */ + f_uecups_xceive({reset_all_state := {}}, {reset_all_state_res:=?}); + } + + /* make sure we always pass incoming UECUPS indications whenever receiving fom the UECUPS port */ + activate(as_uecups_ind()); +} + +private altstep as_uecups_ind() runs on GTPv2_Emulation_CT { +var UECUPS_RecvFrom rx; +var GTP2_ConnHdlr vc_conn; +/* handle incoming program_term_ind; dispatch to whatever component started the process */ +[] UECUPS.receive(tr_UECUPS_RecvFrom_R({program_term_ind:=?})) -> value rx { + vc_conn := f_comp_by_pid(rx.msg.program_term_ind.pid); + CLIENT.send(rx.msg.program_term_ind) to vc_conn; + /* FIXME: remove from table */ + repeat; + } +} + +function main(Gtp2EmulationCfg cfg) runs on GTPv2_Emulation_CT { + var Gtp2cUnitdata g2c_ud; + var PDU_GTPCv2 g2c; + var GTP2_ConnHdlr vc_conn; + var hexstring imsi; + var OCT4 teid; + var PDU_UECUPS rx_uecups; + var UECUPS_CreateTun gtc; + var UECUPS_DestroyTun gtd; + var UECUPS_StartProgram sprog; + + f_init(cfg); + + while (true) { + alt { + /* route inbound GTP2-C based on IMSI or TEID */ + [] GTP2C.receive(Gtp2cUnitdata:?) -> value g2c_ud { + var template hexstring imsi_t := f_gtp2c_extract_imsi(g2c_ud.gtpc); + if (not ispresent(g2c_ud.gtpc.tEID) or g2c_ud.gtpc.tEID == int2oct(0, 4)) { + TEID0.send(g2c_ud.gtpc) to vc_conn; + } else if (ispresent(g2c_ud.gtpc.tEID) and g2c_ud.gtpc.tEID != int2oct(0, 4)) { + vc_conn := f_comp_by_teid(g2c_ud.gtpc.tEID); + CLIENT.send(g2c_ud.gtpc) to vc_conn; + } else if (isvalue(imsi_t)) { + vc_conn := f_comp_by_imsi(valueof(imsi_t)); + CLIENT.send(g2c_ud.gtpc) to vc_conn; + } else { + /* Send to all clients */ + var integer i; + for (i := 0; i < sizeof(TidTable); i := i+1) { + if (isbound(TidTable[i].teid) and TidTable[i].teid == teid) { + CLIENT.send(g2c_ud.gtpc) to TidTable[i].vc_conn; + } + } + } + } + + [] TEID0.receive(PDU_GTPCv2:?) -> value g2c sender vc_conn { + /* patch in the next sequence number */ + /* FIXME: do this only for outbound requests */ + g2c.sequenceNumber := int2oct(g_c_seq_nr, 3); + g_c_seq_nr := g_c_seq_nr + 1; + /* build Gtp2cUnitdata */ + g2c_ud := { peer := g_peer, gtpc := g2c }; + GTP2C.send(g2c_ud); + } + + [] CLIENT.receive(PDU_GTPCv2:?) -> value g2c sender vc_conn { + /* patch in the next sequence number */ + /* FIXME: do this only for outbound requests */ + g2c.sequenceNumber := int2oct(g_c_seq_nr, 3); + g_c_seq_nr := g_c_seq_nr + 1; + /* build Gtp2cUnitdata */ + g2c_ud := { peer := g_peer, gtpc := g2c }; + GTP2C.send(g2c_ud); + } + + [] CLIENT_PROC.getcall(GTP2EM_register_imsi:{?}) -> param(imsi) sender vc_conn { + f_imsi_tbl_add(imsi, vc_conn); + CLIENT_PROC.reply(GTP2EM_register_imsi:{imsi}) to vc_conn; + } + + [] CLIENT_PROC.getcall(GTP2EM_register_teid:{?}) -> param(teid) sender vc_conn { + f_tid_tbl_add(teid, vc_conn); + CLIENT_PROC.reply(GTP2EM_register_teid:{teid}) to vc_conn; + } + [] CLIENT_PROC.getcall(GTP2EM_allocate_teid:{}) -> sender vc_conn { + var OCT4 t := f_alloc_teid(); + f_tid_tbl_add(t, vc_conn); + CLIENT_PROC.reply(GTP2EM_allocate_teid:{} value t) to vc_conn; + } + [] CLIENT_PROC.getcall(GTP2EM_create_tunnel:{?}) -> param(gtc) sender vc_conn { + rx_uecups := f_uecups_xceive({create_tun := gtc}, {create_tun_res:={result:=OK}}); + CLIENT_PROC.reply(GTP2EM_create_tunnel:{gtc}); + } + [] CLIENT_PROC.getcall(GTP2EM_destroy_tunnel:{?}) -> param(gtd) sender vc_conn { + rx_uecups := f_uecups_xceive({destroy_tun := gtd}, {destroy_tun_res:={result:=OK}}); + CLIENT_PROC.reply(GTP2EM_destroy_tunnel:{gtd}); + } + [] CLIENT_PROC.getcall(GTP2EM_start_program:{?}) -> param(sprog) sender vc_conn { + rx_uecups := f_uecups_xceive({start_program := sprog}, {start_program_res:=?}); + /* if successful: store (pid, vc_conn) tuple so we can route program_term_ind */ + if (rx_uecups.start_program_res.result == OK) { + f_pid_tbl_add(rx_uecups.start_program_res.pid, vc_conn); + } + CLIENT_PROC.reply(GTP2EM_start_program:{sprog} value rx_uecups.start_program_res); + } + + } + } +} + + +/*********************************************************************** + * Interaction between Main and Client Components + ***********************************************************************/ +type port GTP2EM_PT message { + inout PDU_GTPCv2, UECUPS_ProgramTermInd; +} with { extension "internal" }; + +signature GTP2EM_register_imsi(hexstring imsi); +signature GTP2EM_register_teid(OCT4 teid); +signature GTP2EM_allocate_teid() return OCT4; +signature GTP2EM_create_tunnel(UECUPS_CreateTun gtc); +signature GTP2EM_destroy_tunnel(UECUPS_DestroyTun gtd); +signature GTP2EM_start_program(UECUPS_StartProgram sprog) return UECUPS_StartProgramRes; + +type port GTP2EM_PROC_PT procedure { + inout GTP2EM_register_imsi, GTP2EM_register_teid, GTP2EM_allocate_teid, + GTP2EM_create_tunnel, GTP2EM_destroy_tunnel, GTP2EM_start_program; +} with { extension "internal" }; + +/*********************************************************************** + * Client Component + ***********************************************************************/ + +type component GTP2_ConnHdlr { + port GTP2EM_PT GTP2; + port GTP2EM_PROC_PT GTP2_PROC; +}; + +function f_gtp2_register_imsi(hexstring imsi) runs on GTP2_ConnHdlr { + GTP2_PROC.call(GTP2EM_register_imsi:{imsi}) { + [] GTP2_PROC.getreply(GTP2EM_register_imsi:{imsi}); + } +} + +function f_gtp2_register_teid(OCT4 teid) runs on GTP2_ConnHdlr { + GTP2_PROC.call(GTP2EM_register_teid:{teid}) { + [] GTP2_PROC.getreply(GTP2EM_register_teid:{teid}); + } +} + +function f_gtp2_allocate_teid() runs on GTP2_ConnHdlr return OCT4 { + var OCT4 t; + GTP2_PROC.call(GTP2EM_allocate_teid:{}) { + [] GTP2_PROC.getreply(GTP2EM_allocate_teid:{}) -> value t { + return t; + } + } +} + +function f_gtp2_create_tunnel(template (value) UECUPS_CreateTun gtc) +runs on GTP2_ConnHdlr { + GTP2_PROC.call(GTP2EM_create_tunnel:{valueof(gtc)}) { + [] GTP2_PROC.getreply(GTP2EM_create_tunnel:{gtc}); + } +} + +function f_gtp2_destroy_tunnel(template (value) UECUPS_DestroyTun gtd) +runs on GTP2_ConnHdlr { + GTP2_PROC.call(GTP2EM_destroy_tunnel:{valueof(gtd)}) { + [] GTP2_PROC.getreply(GTP2EM_destroy_tunnel:{gtd}); + } +} + +function f_gtp2_start_program(template (value) UECUPS_StartProgram sprog) +runs on GTP2_ConnHdlr return UECUPS_StartProgramRes { + var UECUPS_StartProgramRes res; + GTP2_PROC.call(GTP2EM_start_program:{valueof(sprog)}) { + [] GTP2_PROC.getreply(GTP2EM_start_program:{sprog}) -> value res; + } + return res; +} + + + +} diff --git a/library/GTPv2_Templates.ttcn b/library/GTPv2_Templates.ttcn index 23b0053..af3b84b 100644 --- a/library/GTPv2_Templates.ttcn +++ b/library/GTPv2_Templates.ttcn @@ -30,6 +30,7 @@ } template (present) PDU_GTPCv2 tr_PDU_GTP2C(template OCT4 teid := ?, + template (present) OCT3 seq := ?, template (present) GTPCv2_PDUs pdus := ?, template PDU_GTPCv2 piggyback := omit) := { spare := '000'B, @@ -39,7 +40,7 @@ messageType := ?, lengthf := ?, tEID := teid, - sequenceNumber := ?, + sequenceNumber := seq, spare3 := '00'O, gtpcv2_pdu := pdus, piggybackPDU_GTPCv2 := piggyback @@ -62,6 +63,23 @@ iMSI_Value := imsi } +template (present) MSISDN ts_GTP2C_msisdn(template (present) hexstring msisdn) := { + elementIdentifier := '4C'O, + lengthIndicator := 0, /* overwritten */ + instance := '0000'B, + spare := '0000'B, + mSISDN_Value := msisdn +} +private function fs_GTP2C_msisdn(template (omit) hexstring msisdn) return +template (omit) MSISDN { + if (istemplatekind(msisdn, "omit")) { + return omit; + } else { + return ts_GTP2C_msisdn(msisdn); + } +} + + /* 8.4-1 */ /* type enumerated GTP2C_Cause { @@ -109,6 +127,25 @@ instanceOfOffendingIE := *, spare3 := * } +private function fs_GTP2C_Cause(template (omit) OCT1 cause, template (value) BIT1 cs) return +template (omit) Cause { + if (istemplatekind(cause, "omit")) { + return omit; + } else { + return ts_GTP2C_Cause(cause, cs); + } +} +private function fr_GTP2C_Cause(template OCT1 cause) return +template Cause { + if (istemplatekind(cause, "omit")) { + return omit; + } else if (istemplatekind(cause, "*")) { + return *; + } else { + return tr_GTP2C_Cause(cause); + } +} + /* 8.5 */ template (value) AccessPointName ts_GTP2C_APN(template (value) octetstring apn) := { @@ -126,6 +163,41 @@ aPN_Value := apn } +/* 8.7 */ +template (value) AggregateMaximumBitRate +ts_GTP2C_Ambr(integer ambr_ul, integer ambr_dl) := { + elementIdentifier := '48'O, + lengthIndicator := 0, /* overwritten */ + instance := '0000'B, + spare := '0000'B, + aPN_AMBR_for_uplink := int2oct(ambr_ul, 4), + aPN_AMBR_for_downlink := int2oct(ambr_dl, 4) +} + +/* 8.8 */ +template (value) EPS_BearerID +ts_GTP2C_EpsBearerId(template (value) uint4_t bid) := { + elementIdentifier := '49'O, + lengthIndicator := 0, /* overwritten */ + instance := '0000'B, + spare := '0000'B, + ePS_Bearer_ID_Value := bid, + spare2 := '0000'B, + additionalOctets := omit +} +template (present) EPS_BearerID +tr_GTP2C_EpsBearerId(template (present) uint4_t bid) := { + elementIdentifier := '49'O, + lengthIndicator := ?, /* overwritten */ + instance := '0000'B, + spare := '0000'B, + ePS_Bearer_ID_Value := bid, + spare2 := '0000'B, + additionalOctets := * +} + + + /* 8.14 */ template (value) PDN_AddressAllocation ts_GTP2C_PdnAddrAlloc(template (value) BIT3 pdn_type, @@ -156,6 +228,31 @@ tr_GTP2C_PdnAddrAlloc_v4(template (present) OCT4 addr) := ts_GTP2C_PdnAddrAlloc('001'B, {iPv4_Address:=addr}); +/* 8.15 */ +template (value) Bearer_QoS +ts_GTP2C_BearerQos(template (value) OCT1 qci, + uint40_t max_br_ul, uint40_t max_br_dl, + uint40_t g_br_ul, uint40_t g_br_dl, + template (value) BIT4 prio_lvl := '1001'B, + template (value) BIT1 pe_vuln := '0'B, + template (value) BIT1 pe_capa := '0'B) := { + elementIdentifier := '50'O, + lengthIndicator := 0, /* overwritten */ + instance := '0000'B, + spare := '0000'B, + pVI := pe_vuln, + spare2 := '0'B, + pL := prio_lvl, + pCI := pe_capa, + spare3 := '0'B, + labelQCI := qci, + maxBitrateUplink := int2oct(max_br_ul, 5), + maxBitrateDownLink := int2oct(max_br_dl, 5), + guaranteedBitrateUplink := int2oct(g_br_ul, 5), + guaranteedBitrateDownLink := int2oct(g_br_dl, 5), + additionalOctets := omit +} + /* 8.17 */ template (value) RAT_Type ts_GTP2C_RatType(template (value) integer rat) := { elementIdentifier := '53'O, @@ -174,6 +271,66 @@ additionalOctets := * } +/* 8.21 */ +function ts_GTP2C_UserLocInfo(template (omit) CGI cgi := omit, + template (omit) SAI sai := omit, + template (omit) RAI rai := omit, + template (omit) TAI tai := omit, + template (omit) ECGI ecgi := omit, + template (omit) LAI lai := omit) +return template (value) UserLocationInfo { + var template (value) UserLocationInfo uli; + uli.elementIdentifier := '56'O; + uli.lengthIndicator := 0; // overwritten + uli.instance := '0000'B; + uli.spare := '0000'B; + uli.spare2 := '00'B; + uli.additionalOctets := omit; + + if (istemplatekind(cgi, "omit")) { + uli.cGI_Flag := '0'B; + } else { + uli.cGI_Flag := '1'B; + } + uli.cGI := cgi; + + if (istemplatekind(sai, "omit")) { + uli.sAI_Flag := '0'B; + } else { + uli.sAI_Flag := '1'B; + } + uli.sAI := sai; + + if (istemplatekind(rai, "omit")) { + uli.rAI_Flag := '0'B; + } else { + uli.rAI_Flag := '1'B; + } + uli.rAI := rai + + if (istemplatekind(tai, "omit")) { + uli.tAI_Flag := '0'B; + } else { + uli.tAI_Flag := '1'B; + } + uli.tAI := tai + + if (istemplatekind(ecgi, "omit")) { + uli.eCGI_Flag := '0'B; + } else { + uli.eCGI_Flag := '1'B; + } + uli.eCGI := ecgi; + + if (istemplatekind(lai, "omit")) { + uli.lAI_Flag := '0'B; + } else { + uli.lAI_Flag := '1'B; + } + uli.lAI := lai + + return uli; +} /* 8.22 */ private function f_bit4oct(template (omit) octetstring os) return BIT1 @@ -184,16 +341,59 @@ return '1'B; } } +type enumerated FteidInterface { + FTEID_IF_S1U_eNodeB_GTPU (0), + FTEID_IF_S1U_SGW_GTPU (1), + FTEID_IF_S12_RNC_GTPU (2), + FTEID_IF_S12_SGW_GTPU (3), + FTEID_IF_S5S8_SGW_GTPU (4), + FTEID_IF_S5S8_PGW_GTPU (5), + FTEID_IF_S5S8_SGW_GTPC (6), + FTEID_IF_S5S8_PGW_GTPC (7), + FTEID_IF_S5S8_SGW_PMIPv6 (8), + FTEID_IF_S5S8_PGW_PMIPv6 (9), + FTEID_IF_S11_MME_GTPC (10), + FTEID_IF_S11S4_SGW_GTPC (11), + FTEID_IF_S10ND26_MME_GTPC (12), + FTEID_IF_S3_MME_GTPC (13), + FTEID_IF_S3_SGSN_GTPC (14), + FTEID_IF_S4_SGSN_GTPU (15), + FTEID_IF_S4_SGW_GTPU (16), + FTEID_IF_S16_SGSN_GTPC (18), + FTEID_IF_eNB_GTPU_DL_DATA_FW (19), + FTEID_IF_eNB_GTPU_UL_DATA_FW (20), + FTEID_IF_RNC_GTPU_DATA_FW (21), + FTEID_IF_SGSN_GTPU_DATA_FW (22), + FTEID_IF_SGWUPF_GTPU_DL_DATA_FW (23), + FTEID_IF_Sm_MMBS_GW_GTPC (24), + FTEID_IF_Sn_MMBS_GW_GTPC (25), + FTEID_IF_Sm_MME_GTPC (26), + FTEID_IF_Sn_MME_GTPC (27), + FTEID_IF_SGW_GTPU_UL_DATA_FW (28), + FTEID_IF_Sn_SGSN_GTPU (29), + FTEID_IF_S2b_ePDG_GTPC (30), + FTEID_IF_S2bU_ePDG_GTPU (31), + FTEID_IF_S2b_PGW_GTPC (32), + FTEID_IF_S2bU_PGW_GTPU (33), + FTEID_IF_S2a_TWAN_GTPU (34), + FTEID_IF_S2a_TWAN_GTPC (35), + FTEID_IF_S2a_PGW_GTPC (36), + FTEID_IF_S2a_PGW_GTPU (37), + FTEID_IF_S11_MME_GTPU (38), + FTEID_IF_S11_SGW_GTPU (39), + FTEID_IF_N26_AMF_GTPC (40) +}; template (value) FullyQualifiedTEID -ts_GTP2C_FTEID(integer if_type, OCT4 teid, template (omit) OCT4 v4_addr := omit, +ts_GTP2C_FTEID(FteidInterface if_type, OCT4 teid, uint4_t instance := 0, + template (omit) OCT4 v4_addr := omit, template (omit) OCT16 v6_addr := omit) := { elementIdentifier := '57'O, lengthIndicator := 0, /* overwritten */ - instance := '0000'B, + instance := int2bit(instance, 4), spare := '0000'B, - interfaceType := if_type, - v6_Flag := f_bit4oct(v4_addr), - v4_Flag := f_bit4oct(v6_addr), + interfaceType := enum2int(if_type), + v6_Flag := f_bit4oct(v6_addr), + v4_Flag := f_bit4oct(v4_addr), tEID_GRE_Key := teid, iPv4_Address := v4_addr, iPv6_Address := v6_addr, @@ -201,11 +401,12 @@ } template (present) FullyQualifiedTEID tr_GTP2C_FTEID(template (present) integer if_type, template (present) OCT4 teid, + template BIT4 instance := ?, template OCT4 v4_addr := omit, template OCT16 v6_addr := omit) := { elementIdentifier := '57'O, lengthIndicator := ?, - instance := ?, + instance := instance, spare := '0000'B, interfaceType := if_type, v6_Flag := ?, @@ -216,6 +417,134 @@ additionalOctets := omit } +/* 8.28 */ +template (value) BearerContextGrouped +ts_GTP2C_BcGrouped(template (value) BearerContextIEs ies) := { + elementIdentifier := '5D'O, + lengthIndicator := 0, /* overwritten */ + instance := '0000'B, + spare := '0000'B, + bearerContextIEs := ies +} +template (present) BearerContextGrouped +tr_GTP2C_BcGrouped(template (present) BearerContextIEs ies) := { + elementIdentifier := '5D'O, + lengthIndicator := ?, /* overwritten */ + instance := '0000'B, + spare := '0000'B, + bearerContextIEs := ies +} + + + +/* 8.30 */ +template (value) ChargingCharacteristics +ts_GTP2C_ChargingCaracteristics(template (value) OCT2 cc) := { + elementIdentifier := '5F'O, + lengthIndicator := 0, /* overwritten */ + instance := '0000'B, + spare := '0000'B, + chargingCharacteristicsValue := cc, + additionalOctets := omit +} +template (present) ChargingCharacteristics +tr_GTP2C_ChargingCaracteristics(template (present) OCT2 cc) := { + elementIdentifier := '5F'O, + lengthIndicator := ?, /* overwritten */ + instance := '0000'B, + spare := '0000'B, + chargingCharacteristicsValue := cc, + additionalOctets := omit +} + + +/* 8.34 */ +template (value) PDN_Type +ts_GTP2C_PdnType(template (value) BIT3 pdn_type) := { + elementIdentifier := '63'O, + lengthIndicator := 0, + instance := '0000'B, + spare := '0000'B, + pDN_TypeValue := pdn_type, + spare2 := '00000'B, + additionalOctets := omit +} +template (present) PDN_Type +tr_GTP2C_PdnType(template (present) BIT3 pdn_type) := { + elementIdentifier := '63'O, + lengthIndicator := ?, + instance := ?, + spare := ?, + pDN_TypeValue := pdn_type, + spare2 := ?, + additionalOctets := * +} + +/* 8.35 */ +template (value) ProcedureTransactionID +ts_GTP2C_ProcTransId(template (value) integer pti) := { + elementIdentifier := '64'O, + lengthIndicator := 0, + instance := '0000'B, + spare := '0000'B, + pTI_Value := pti, + additionalOctets := omit +} +template (present) ProcedureTransactionID +tr_GTP2C_ProcTransId(template (present) integer pti) := { + elementIdentifier := '64'O, + lengthIndicator := ?, + instance :=?, + spare := ?, + pTI_Value := pti, + additionalOctets := * +} + + +/* 8.57 */ +template (value) APN_Restriction +ts_GTP2C_ApnRestriction(template (value) integer val) := { + elementIdentifier := '7F'O, + lengthIndicator := 0, + instance := '0000'B, + spare := '0000'B, + restrictionTypeValue := val, + additionalOctets := omit +} +template (present) APN_Restriction +tr_GTP2C_ApnRestriction(template (present) integer val) := { + elementIdentifier := '7F'O, + lengthIndicator := ?, + instance := '0000'B, + spare := ?, + restrictionTypeValue := val, + additionalOctets := * +} + + +/* 8.58 */ +template (value) SelectionMode +ts_GTP2C_SelectionMode(template (value) integer mode) := { + elementIdentifier := '80'O, + lengthIndicator := 0, /* overwritten */ + instance := '0000'B, + spare := '0000'B, + selectionModeValue := mode, + spare2 := '000000'B, + additionalOctets := omit +} +template (present) SelectionMode +tr_GTP2C_SelectionMode(template (present) integer mode) := { + elementIdentifier := '80'O, + lengthIndicator := ?, + instance := ?, + spare := ?, + selectionModeValue := mode, + spare2 := ?, + additionalOctets := * +} + + template (value) PDU_GTPCv2 ts_PDU_GTP2C(template (omit) OCT4 teid, template (value) OCT3 seq, @@ -236,8 +565,117 @@ } +template (value) PDU_GTPCv2 +ts_GTP2C_EchoReq(template (value) integer rec_val) := +ts_PDU_GTP2C(omit, '000000'O, '01'O, { + echoRequest := { + recovery := { + elementIdentifier := '03'O, + lengthIndicator := 0, + instance := '0000'B, + spare := '0000'B, + recoveryValue := rec_val + }, + sendingNodeFeatures := omit, + privateExtension := omit + }}); template (present) PDU_GTPCv2 -tr_GTP2C_CreateSessionReq(template (present) hexstring imsi) := tr_PDU_GTP2C('00000000'O, { +tr_GTP2C_EchoReq(template (present) OCT3 seq := ?) := +tr_PDU_GTP2C(omit, seq, { echoRequest := ? }, omit); + +template (value) PDU_GTPCv2 +ts_GTP2C_EchoResp(template (value) integer rec_val) := +ts_PDU_GTP2C(omit, '000000'O, '02'O, { + echoRequest := { + recovery := { + elementIdentifier := '03'O, + lengthIndicator := 0, + instance := '0000'B, + spare := '0000'B, + recoveryValue := rec_val + }, + sendingNodeFeatures := omit, + privateExtension := omit + }}); +template (present) PDU_GTPCv2 +tr_GTP2C_EchoResp(template (present) OCT3 seq := ?) := +tr_PDU_GTP2C(omit, seq, { echoResponse := ? }, omit); + + + +template (present) PDU_GTPCv2 +ts_GTP2C_CreateSessionReq(template (value) hexstring imsi, template (omit) hexstring msisdn, + integer rat_type, template (value) FullyQualifiedTEID sender_fteid, + template (value) octetstring apn, template (value) BIT3 pdn_type, + template (omit) FullyQualifiedTEID_List teid_list, + template (value) OCT2 chg_car, template (value) uint4_t bearer_id, + template (value) Bearer_QoS qos := ts_GTP2C_BearerQos('09'O, 0,0,0,0)) := +ts_PDU_GTP2C('00000000'O, '000000'O, '20'O, { + createSessionRequest := { + iMSI := ts_GTP2C_Imsi(imsi), + mSISDN := fs_GTP2C_msisdn(msisdn), + mEI := omit, + userLocationInfo := omit, + servingNetwork := omit, + rAT_Type := ts_GTP2C_RatType(rat_type), + indication := omit, + fullyQualifiedTEID := { sender_fteid }, + accessPointName := ts_GTP2C_APN(apn), + selectionMode := ts_GTP2C_SelectionMode(0), + pDN_Type := ts_GTP2C_PdnType(pdn_type), + pDN_AddressAllocation := ts_GTP2C_PdnAddrAlloc('001'B, {iPv4_Address:='00000000'O}), + maxAPN_Restriction := ts_GTP2C_ApnRestriction(0), + ambr := ts_GTP2C_Ambr(102400, 102400), + linkedEPS_Bearer_ID := omit, + trustedWLANModeIndication := omit, + protocolConfigOptions := omit, + bearerContextGrouped := { + ts_GTP2C_BcGrouped({ + ePS_Bearer_ID := ts_GTP2C_EpsBearerId(bearer_id), + cause := omit, + ePS_Bearer_TFT := omit, + fullyQualifiedTEID := teid_list, + bearerLevel_QoS := qos, + chargingID := omit, + bearerFlags := omit, + transactionIdentifier := omit, + protocolConfigOptions := omit, + rAN_NASCause := omit, + additionalProtocolConfigOptions := omit, + extendedProtocolConfigOptions := omit + }) + }, + traceInformation := omit, + recovery := omit, + csid := omit, + uE_TimeZone := omit, + user_CSG_Information := omit, + chargingCharacteristics := ts_GTP2C_ChargingCaracteristics(chg_car), + lDN := omit, + signallingPriorityIndication := omit, + iP_Addr := omit, + portNumber := omit, + aPCO := omit, + trustedWLANAccessNetworkIdentifier := omit, + cNOperatorSelectionEntity := omit, + presenceReportingAreaInformation := omit, + overloadControlInformationGrouped := omit, + originationTimeStamp := omit, + maximumWaitTime := omit, + wLANLocationTimestamp := omit, + nBIFOMContainer := omit, + remoteUEContextGrouped := omit, + nodeIdentifier := omit, + extendedProtocolConfigOptions := omit, + servingPLMNRateControl := omit, + counter := omit, + privateExtension := omit + }}); + + +template (present) PDU_GTPCv2 +tr_GTP2C_CreateSessionReq(template (present) hexstring imsi) := +tr_PDU_GTP2C('00000000'O, ?, { createSessionRequest := { iMSI := tr_GTP2C_Imsi(imsi), mSISDN := *, @@ -287,7 +725,7 @@ template (value) PDU_GTPCv2 ts_GTP2C_CreateSessionResp(template (value) FullyQualifiedTEID_List fteids, template (value) PDN_AddressAllocation addr) := -ts_PDU_GTP2C('00000000'O, '000000'O, '20'O, { +ts_PDU_GTP2C('00000000'O, '000000'O, '21'O, { createSessionResponse := { cause := ts_GTP2C_Cause(int2oct(16, 1), '0'B), changeReportingAction := omit, @@ -317,6 +755,219 @@ extendedProtocolConfigOptions := omit, privateExtension := omit }}); +template (present) PDU_GTPCv2 +tr_GTP2C_CreateSessionResp(template (present) OCT4 d_teid := ?, + template (present) OCT3 seq := ?, + template (present) OCT1 cause := ?, + template FullyQualifiedTEID_List fteids := *, + template PDN_AddressAllocation addr := *, + template BearerContextGrouped_List bctxg := *) := +tr_PDU_GTP2C(d_teid, seq, { + createSessionResponse := { + cause := tr_GTP2C_Cause(cause), + changeReportingAction := *, + cSG_InformationReportingAction := *, + heNBInformationReporting := *, + fullyQualifiedTEID := fteids, + pDN_AddressAllocation := addr, + aPN_Restriction := ?, + ambr := *, + linkedEPS_Bearer_ID := *, + protocolConfigOptions := *, + bearerContextGrouped := bctxg, + recovery := *, + chargingGatewayName := *, + chargingGatewayAddress := *, + csid := *, + lDN := *, + pGW_Back_OffTime := *, + aPCO := *, + trustedWLANIPv4Parameters := *, + indicationFlags := *, + presenceReportingAreaAction := *, + loadControlInformationGrouped := *, + overloadControlInformationGrouped := *, + nBIFOMContainer := *, + pDNConnectionChargingID := *, + extendedProtocolConfigOptions := *, + privateExtension := * + }}); + + +template (value) PDU_GTPCv2 +ts_GTP2C_DeleteSessionReq(template (value) OCT4 d_teid, + template (omit) OCT1 cause := omit, + template (value) FullyQualifiedTEID sender_fteid, + template (omit) FullyQualifiedTEID_List teid_list := omit, + template (value) uint4_t bearer_id) := +ts_PDU_GTP2C(d_teid, '000000'O, '24'O, { + deleteSessionRequest := { + cause := fs_GTP2C_Cause(cause, '0'B), + linkedEPS_Bearer_ID := ts_GTP2C_EpsBearerId(bearer_id), + uLI := omit, + indicationFlags := omit, + protocolConfigOptions := omit, + originatingNode := omit, + fullyQualifiedTEID := sender_fteid, + uE_TimeZone := omit, + uLITimestamp := omit, + rANNASReleaseCause := omit, + trustedWLANAccessNetworkIdentifier := omit, + tWANIdentifierTimestamp := omit, + overloadControlInformationGrouped := omit, + uELocalIP_Addr := omit, + portNumber := omit, + extendedProtocolConfigOptions := omit, + privateExtension := omit + }}); +template (present) PDU_GTPCv2 +tr_GTP2C_DeleteSessionReq(template (present) OCT4 d_teid, + template (present) OCT3 seq := ?, + template (omit) OCT1 cause, + template (present) FullyQualifiedTEID sender_fteid, + template FullyQualifiedTEID_List teid_list, + template (present) uint4_t bearer_id) := +tr_PDU_GTP2C(d_teid, seq, { + deleteSessionRequest := { + cause := fr_GTP2C_Cause(cause), + linkedEPS_Bearer_ID := tr_GTP2C_EpsBearerId(bearer_id), + uLI := *, + indicationFlags := *, + protocolConfigOptions := *, + originatingNode := *, + fullyQualifiedTEID := sender_fteid, + uE_TimeZone := *, + uLITimestamp := *, + rANNASReleaseCause := *, + trustedWLANAccessNetworkIdentifier := *, + tWANIdentifierTimestamp := *, + overloadControlInformationGrouped := *, + uELocalIP_Addr := *, + portNumber := *, + extendedProtocolConfigOptions := *, + privateExtension := * + }}); + + +template (value) PDU_GTPCv2 +ts_GTP2C_DeleteSessionResp(template (value) OCT4 d_teid, + template (value) OCT3 seq, + template (value) OCT1 cause) := +ts_PDU_GTP2C(d_teid, '000000'O, '25'O, { + deleteSessionResponse := { + cause := ts_GTP2C_Cause(cause, '0'B), + recovery := omit, + protocolConfigOptions := omit, + indicationFlags := omit, + loadControlInformationGrouped := omit, + overloadControlInformationGrouped := omit, + extendedProtocolConfigOptions := omit, + privateExtension := omit + + }}); +template (present) PDU_GTPCv2 +tr_GTP2C_DeleteSessionResp(template (present) OCT4 d_teid, + template (present) OCT3 seq := ?, + template (present) OCT1 cause := ? + ) := +tr_PDU_GTP2C(d_teid, seq, { + deleteSessionResponse := { + cause := tr_GTP2C_Cause(cause), + recovery := *, + protocolConfigOptions := *, + indicationFlags := *, + loadControlInformationGrouped := *, + overloadControlInformationGrouped := *, + extendedProtocolConfigOptions := *, + privateExtension := * + }}); + +template (value) PDU_GTPCv2 +ts_GTP2C_CreateBearerReq(template (value) OCT4 d_teid, + template (value) integer proc_trans_id, + template (value) uint4_t linked_id, + template (value) uint4_t bearer_id, + template (omit) FullyQualifiedTEID_List teid_list, + template (value) Bearer_QoS qos := ts_GTP2C_BearerQos('09'O, 0,0,0,0)) := +ts_PDU_GTP2C(d_teid, '000000'O, '5F'O, { + createBearerRequest := { + procedureTransactionID := ts_GTP2C_ProcTransId(proc_trans_id), + linkedEPS_BearerID := ts_GTP2C_EpsBearerId(linked_id), + protocolConfigOptions := omit, + bearerContextGrouped := { + ts_GTP2C_BcGrouped({ + ePS_Bearer_ID := ts_GTP2C_EpsBearerId(bearer_id), + cause := omit, + ePS_Bearer_TFT := omit, + fullyQualifiedTEID := teid_list, + bearerLevel_QoS := qos, + chargingID := omit, + bearerFlags := omit, + transactionIdentifier := omit, + protocolConfigOptions := omit, + rAN_NASCause := omit, + additionalProtocolConfigOptions := omit, + extendedProtocolConfigOptions := omit + }) + }, + csid := omit, + changeReportingAction := omit, + cSG_InformationReportingAction := omit, + heNBInformationReporting := omit, + presenceReportingAreaAction := omit, + indicationFlags := omit, + loadControlInformationGrouped := omit, + overloadControlInformationGrouped := omit, + nBIFOMContainer := omit, + privateExtension := omit + }}); + + +template (value) PDU_GTPCv2 +ts_GTP2C_DeleteBearerReq(template (value) OCT4 d_teid, + template (value) integer proc_trans_id, + template (value) uint4_t bearer_id, + template (value) OCT1 cause) := +ts_PDU_GTP2C(d_teid, '000000'O, '63'O, { + deleteBearerRequest := { + epsBearerIdentity := { ts_GTP2C_EpsBearerId(bearer_id) }, + bearerContextGrouped := omit, + procedureTransactionID := ts_GTP2C_ProcTransId(proc_trans_id), + protocolConfigOptions := omit, + csid := omit, + cause := ts_GTP2C_Cause(cause, '0'B), + indicationFlags := omit, + loadControlInformationGrouped := omit, + overloadControlInformationGrouped := omit, + nBIFOMContainer := omit, + extendedProtocolConfigOptions := omit, + privateExtension := omit + }}); + + +template (present) PDU_GTPCv2 +tr_GTP2C_DeleteBearerResp(template (present) OCT4 d_teid, + template (present) OCT3 seq := ?, + template (present) OCT1 cause := ?) := +tr_PDU_GTP2C(d_teid, seq, { + deleteBearerResponse := { + cause := tr_GTP2C_Cause(cause), + linkedBearerIdentity := *, + bearerContextGrouped := *, + recovery := *, + csid := *, + protocolConfigOptions := *, + uE_TimeZone := *, + uLI := *, + uLITimestamp := *, + trustedWLANAccessNetworkIdentifier := *, + tWANIdentifierTimestamp := *, + overloadControlInformationGrouped := *, + iP_Addr := *, + portNumber := *, + nBIFOMContainer := *, + privateExtension := * + }}); diff --git a/library/General_Types.ttcn b/library/General_Types.ttcn index da396b7..40f0770 100644 --- a/library/General_Types.ttcn +++ b/library/General_Types.ttcn @@ -147,6 +147,7 @@ type octetstring OCT3_14n length(3..14) with { variant "" }; type octetstring OCT3_17n length(3..17) with { variant "" }; type octetstring OCT4_8n length(4..8) with { variant "" }; + type octetstring OCT4_16n length(4..16) with { variant "" }; //**************************************************** diff --git a/library/Osmocom_Types.ttcn b/library/Osmocom_Types.ttcn index 2e71123..3b2ca17 100644 --- a/library/Osmocom_Types.ttcn +++ b/library/Osmocom_Types.ttcn @@ -34,6 +34,7 @@ type integer uint13_t (0..8191) with { variant "unsigned 13 bit" }; type integer uint14_t (0..16383) with { variant "unsigned 14 bit" }; type integer uint15_t (0..32767) with { variant "unsigned 15 bit" }; + type integer uint40_t (0..1099511627776) with { variant "unsigned 40 bit" }; const uint16_t c_UINT16_MAX := 65535; -- To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/17867 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: If73aa453e44ebf28032c60d207feb03e8061dc0c Gerrit-Change-Number: 17867 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/20200419/4a640ee5/attachment.htm>