/* GTPv1-U Templates in TTCN-3 * (C) 2018 Harald Welte * contributions by sysmocom - s.f.m.c. GmbH * 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 GTPv1U_Templates { import from General_Types all; import from Osmocom_Types all; import from GTPU_Types all; import from GTPv1U_CodecPort all; template (present) PDU_GTPU tr_GTP1U_PDU(template (present) OCT1 msg_type, template (present) OCT4 teid, template (present) GTPU_IEs ies := ?) := { pn_bit := ?, s_bit := ?, e_bit := ?, spare := ?, /* Protocol Type flag (PT) shall be set to '1' in GTP */ pt := '1'B, /* Version shall be set to decimal 1 ('001'). */ version := '001'B, messageType := msg_type, lengthf := ?, teid := teid, opt_part := *, gtpu_IEs := ies } 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_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; } var GTPU_Header_optional_part ret := { sequenceNumber := int2oct(valueof(seq), 2), npduNumber := '00'O, nextExtHeader := '00'O, gTPU_extensionHeader_List := omit }; return ret; } /* generalized GTP-U send template */ template (value) PDU_GTPU ts_GTP1U_PDU(template (value) OCT1 msg_type, 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 * flag is set to 1. */ pn_bit := '0'B, /* we assume the encoder overwrites this if an optional part is given */ /* If the Sequence Number flag (S) is set to '1' the sequence number field is present and * meaningful otherwise it is set to '0'. For GTP-U messages Echo Request, Echo Response, * Error Indication and Supported Extension Headers Notification, the S flag shall be set to '1'. * * 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(opt_part), /* Extension header presence */ 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, /* Version shall be set to decimal 1 ('001'). */ version := '001'B, messageType := msg_type, lengthf := 0, /* we assume encoder overwrites this */ teid := teid, opt_part := opt_part, gtpu_IEs := ies } template (present) Gtp1uUnitdata tr_GTPU_MsgType(template (present) Gtp1uPeer peer, template (present) OCT1 msg_type, template (present) OCT4 teid) := { peer := peer, gtpu := tr_GTP1U_PDU(msg_type, teid) } /* template matching reception of GTP-U echo-request/response */ template (present) Gtp1uUnitdata tr_GTPU_PING(template (present) Gtp1uPeer peer) := tr_GTPU_MsgType(peer, '01'O, '00000000'O); template (present) Gtp1uUnitdata tr_GTPU_PONG(template (present) Gtp1uPeer peer) := tr_GTPU_MsgType(peer, '02'O, '00000000'O); /* template matching reception of GTP-U GPDU */ template GTPU_IEs t_GPDU(template (present) octetstring data) := { g_PDU_IEs := { data := data } } template (present) Gtp1uUnitdata tr_GTPU_GPDU(template (present) Gtp1uPeer peer, template (present) OCT4 teid, template (present) octetstring data := ?) := { peer := peer, gtpu := tr_GTP1U_PDU('FF'O, teid, t_GPDU(data)) } template (present) GTPU_IEs ts_UEchoReqPDU := { echoRequest_IEs := { private_extension_gtpu := omit } } /* master template for sending a GTP-C echo request */ template (value) Gtp1uUnitdata ts_GTPU_PING(template (value) Gtp1uPeer peer, template (value) uint16_t seq) := { peer := peer, 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) := { echoResponse_IEs := { recovery_gtpu := { type_gtpu := '00'O, /* we assume encoder fixes? */ restartCounter := restart_counter }, private_extension_gtpu := omit } } /* master template for sending a GTP-U echo response */ template (present) Gtp1uUnitdata ts_GTPU_PONG(template (value) Gtp1uPeer peer, template (value) uint16_t seq, template (value) OCT1 rest_ctr) := { peer := peer, 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 := ?) := { type_gtpu := '85'O, lengthf := ?, gSNAddressValue := ip_addr } template (value) GSNAddress_gtpu ts_UGsnAddr(template (value) octetstring ip_addr) := { type_gtpu := '85'O, lengthf := lengthof(valueof(ip_addr)), gSNAddressValue := ip_addr } template (present) TeidDataI_gtpu tr_UteidDataI(template (present) OCT4 teid := ?) := { type_gtpu := '10'O, teidDataI := teid } template (value) TeidDataI_gtpu ts_UteidDataI(template (value) OCT4 teid) := { type_gtpu := '10'O, teidDataI := teid } template (present) GTPU_IEs tr_UErrorIndication(template (present) OCT4 teid := ?, template (present) octetstring gsn_addr := ?) := { errorIndication_IEs := { teidDataI_gtpu := tr_UteidDataI(teid), gSNAddress_gtpu := tr_UGsnAddr(gsn_addr), private_extension_gtpu := * } } template (present) Gtp1uUnitdata tr_GTPU_ErrorIndication(template (present) Gtp1uPeer peer := ?, template (present) OCT4 teid := ?, template (present) octetstring gsn_addr := ?) := { peer := peer, gtpu := tr_GTP1U_PDU('1A'O, '00000000'O, tr_UErrorIndication(teid, gsn_addr)) } template (value) GTPU_IEs ts_UErrorIndication(template (value) OCT4 teid, template (value) octetstring gsn_addr) := { errorIndication_IEs := { teidDataI_gtpu := ts_UteidDataI(teid), gSNAddress_gtpu := ts_UGsnAddr(gsn_addr), private_extension_gtpu := omit } } /* master template for sending a GTP-U Error indication */ template (value) Gtp1uUnitdata ts_GTPU_ErrorIndication(template (value) Gtp1uPeer peer, template (value) uint16_t seq, template (value) OCT4 teid, template (value) octetstring gsn_addr) := { peer := peer, 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) GTPU_Header_optional_part opt_part, template (value) OCT4 teid, template (value) octetstring data) := { peer := peer, gtpu := ts_GTP1U_PDU('FF'O, opt_part, teid, { g_PDU_IEs := { data := data }}) } }