mme: Add GTPv2 support
this includes a GTPv2_CodecPort (for the usual transcoding)
as wella as an empty GTPv2_PrivateExtensions.ttcn without which
the TITAN GTPv2 ProtocolModule won't compile.
Change-Id: I1c1b8409077103dd4e64e467d21d33d8c9c4ac95
diff --git a/library/GTPv2_CodecPort.ttcn b/library/GTPv2_CodecPort.ttcn
new file mode 100644
index 0000000..1f08f19
--- /dev/null
+++ b/library/GTPv2_CodecPort.ttcn
@@ -0,0 +1,57 @@
+/* dual-faced port sitting on top of IPL4_asp UDP to encode/decode GTPv2C
+ * (C) 2019 Harald Welte <laforge@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_CodecPort {
+ import from IPL4asp_PortType all;
+ import from IPL4asp_Types all;
+ import from GTPv2C_Types all;
+
+ /* identifies a remote peer (sender or receiver) */
+ type record GtpPeer {
+ ConnectionId connId,
+ HostName remName,
+ PortNumber remPort
+ }
+
+ /* Decoded GTP2C (Control Plane), used in send and receive direction */
+ type record Gtp2cUnitdata {
+ GtpPeer peer,
+ PDU_GTPCv2 gtpc
+ }
+
+ /* Translation port on top of IPL4asp; ASP_Event passed through transparently */
+ type port GTPv2C_PT message {
+ out Gtp2cUnitdata;
+ in Gtp2cUnitdata,
+ ASP_ConnId_ReadyToRelease,
+ ASP_Event;
+ } with { extension "user IPL4asp_PT
+ out(Gtp2cUnitdata -> ASP_SendTo: function(f_enc_Gtp2cUD))
+ in(ASP_RecvFrom -> Gtp2cUnitdata: function(f_dec_Gtp2cUD);
+ ASP_ConnId_ReadyToRelease -> ASP_ConnId_ReadyToRelease: simple;
+ ASP_Event -> ASP_Event: simple)" }
+
+ private function f_enc_Gtp2cUD(in Gtp2cUnitdata in_ud, out ASP_SendTo out_ud) {
+ out_ud.connId := in_ud.peer.connId;
+ out_ud.remName := in_ud.peer.remName;
+ out_ud.remPort := in_ud.peer.remPort;
+ out_ud.proto := { udp := {} };
+ out_ud.msg := enc_PDU_GTPCv2(in_ud.gtpc);
+ } with { extension "prototype(fast)" };
+
+ private function f_dec_Gtp2cUD(in ASP_RecvFrom in_ud, out Gtp2cUnitdata out_ud) {
+ out_ud.peer.connId := in_ud.connId;
+ out_ud.peer.remName := in_ud.remName;
+ out_ud.peer.remPort := in_ud.remPort;
+ out_ud.gtpc := dec_PDU_GTPCv2(in_ud.msg);
+ } with { extension "prototype(fast)" };
+
+}
diff --git a/library/GTPv2_PrivateExtensions.ttcn b/library/GTPv2_PrivateExtensions.ttcn
new file mode 100644
index 0000000..63552f2
--- /dev/null
+++ b/library/GTPv2_PrivateExtensions.ttcn
@@ -0,0 +1,21 @@
+module GTPv2_PrivateExtensions {
+
+/* This is a small stub module to make GTPv2_Types.ttcn from
+ * titan.ProtocolModules.GTPv2_v13.7.0 compile */
+
+import from General_Types all;
+
+type record PrivateExtension {
+ OCT1 elementIdentifier,
+ LIN2_BO_LAST lengthIndicator,
+ BIT4 instance,
+ BIT4 spare,
+ octetstring data
+} with {
+ variant (lengthIndicator) "LENGTHTO(data)";
+ variant "PRESENCE (elementIdentifier = 'FE'O; )"
+}
+
+type record of PrivateExtension PrivateExtension_List;
+
+} with{ encode "RAW" }
diff --git a/library/GTPv2_Templates.ttcn b/library/GTPv2_Templates.ttcn
new file mode 100644
index 0000000..23b0053
--- /dev/null
+++ b/library/GTPv2_Templates.ttcn
@@ -0,0 +1,323 @@
+module GTPv2_Templates {
+
+/* (C) 2019 by Harald Welte <laforge@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
+ */
+
+import from General_Types all;
+import from Osmocom_Types all;
+import from GTPv2_Types all;
+
+private function fs_GTP2C_t_bit(template (omit) OCT4 teid) return BIT1 {
+ if (istemplatekind(teid, "omit")) {
+ return '0'B;
+ } else {
+ return '1'B;
+ }
+}
+
+private function fs_GTP2C_p_bit(template (omit) PDU_GTPCv2 piggyback) return BIT1 {
+ if (istemplatekind(piggyback, "omit")) {
+ return '0'B;
+ } else {
+ return '1'B;
+ }
+}
+
+template (present) PDU_GTPCv2 tr_PDU_GTP2C(template OCT4 teid := ?,
+ template (present) GTPCv2_PDUs pdus := ?,
+ template PDU_GTPCv2 piggyback := omit) := {
+ spare := '000'B,
+ t_Bit := ?,
+ p_Bit := ?,
+ version := '010'B,
+ messageType := ?,
+ lengthf := ?,
+ tEID := teid,
+ sequenceNumber := ?,
+ spare3 := '00'O,
+ gtpcv2_pdu := pdus,
+ piggybackPDU_GTPCv2 := piggyback
+}
+
+
+/* 8.3 */
+template (value) IMSI ts_GTP2C_Imsi(template (value) hexstring imsi) := {
+ elementIdentifier := '01'O,
+ lengthIndicator := 0, /* overwritten */
+ instance := '0000'B,
+ spare := '0000'B,
+ iMSI_Value := imsi
+}
+template (present) IMSI tr_GTP2C_Imsi(template (present) hexstring imsi) := {
+ elementIdentifier := '01'O,
+ lengthIndicator := ?,
+ instance := ?,
+ spare := '0000'B,
+ iMSI_Value := imsi
+}
+
+/* 8.4-1 */
+/*
+type enumerated GTP2C_Cause {
+ Local_Detach (2),
+ Complete_Detach (3),
+ RAT_changed_from_3GPP_to_Non_3GPP (4),
+ ISR_deactivation (5),
+ Error_Ind_from_RNC_eNB_SGSN_MME (5),
+ IMSI_Detach_Only (7),
+ Reactivation_Required (8),
+}
+*/
+
+const integer c_GTP2C_Cause_LocalDetach := 1;
+
+/* 8.4 */
+template (value) Cause ts_GTP2C_Cause(template (value) OCT1 cause,
+ template (value) BIT1 cs) := {
+ elementIdentifier := '02'O,
+ lengthIndicator := 0, /* overwritten */
+ instance := '0000'B,
+ spare := '0000'B,
+ causeValue := cause,
+ cS := cs,
+ bCE := '0'B,
+ pCE := '0'B,
+ spare2 := '00000'B,
+ typeOfOffendingIE := omit,
+ lengthIndicator2 := omit,
+ instanceOfOffendingIE := omit,
+ spare3 := omit
+}
+template (present) Cause tr_GTP2C_Cause(template (present) OCT1 cause) := {
+ elementIdentifier := '02'O,
+ lengthIndicator := ?,
+ instance := ?,
+ spare := '0000'B,
+ causeValue := cause,
+ cS := ?,
+ bCE := ?,
+ pCE := ?,
+ spare2 := '00000'B,
+ typeOfOffendingIE := *,
+ lengthIndicator2 := *,
+ instanceOfOffendingIE := *,
+ spare3 := *
+}
+
+/* 8.5 */
+template (value) AccessPointName ts_GTP2C_APN(template (value) octetstring apn) := {
+ elementIdentifier := '48'O,
+ lengthIndicator := 0, /* overwritten */
+ instance := '0000'B,
+ spare := '0000'B,
+ aPN_Value := apn
+}
+template (present) AccessPointName tr_GTP2C_APN(template (present) octetstring apn) := {
+ elementIdentifier := '48'O,
+ lengthIndicator := ?,
+ instance := ?,
+ spare := '0000'B,
+ aPN_Value := apn
+}
+
+/* 8.14 */
+template (value) PDN_AddressAllocation
+ts_GTP2C_PdnAddrAlloc(template (value) BIT3 pdn_type,
+ template (value) PDN_Address_and_Prefix addr_pfx) := {
+ elementIdentifier := '4F'O,
+ lengthIndicator := 0, /* overwritten */
+ instance := '0000'B,
+ spare := '0000'B,
+ pDN_Type := pdn_type,
+ spare2 := '00000'B,
+ pDN_Address_and_Prefix := addr_pfx
+}
+template (present) PDN_AddressAllocation
+tr_GTP2C_PdnAddrAlloc(template (present) BIT3 pdn_type,
+ template (present) PDN_Address_and_Prefix addr_pfx) := {
+ elementIdentifier := '4F'O,
+ lengthIndicator := ?,
+ instance := ?,
+ spare := '0000'B,
+ pDN_Type := pdn_type,
+ spare2 := '00000'B,
+ pDN_Address_and_Prefix := addr_pfx
+}
+template (value) PDN_AddressAllocation
+ts_GTP2C_PdnAddrAlloc_v4(template (value) OCT4 addr) :=
+ ts_GTP2C_PdnAddrAlloc('001'B, {iPv4_Address:=addr});
+template (present) PDN_AddressAllocation
+tr_GTP2C_PdnAddrAlloc_v4(template (present) OCT4 addr) :=
+ ts_GTP2C_PdnAddrAlloc('001'B, {iPv4_Address:=addr});
+
+/* 8.17 */
+template (value) RAT_Type ts_GTP2C_RatType(template (value) integer rat) := {
+ elementIdentifier := '53'O,
+ lengthIndicator := 0, /* overwritten */
+ instance := '0000'B,
+ spare := '0000'B,
+ rAT_TypeValue := rat,
+ additionalOctets := omit
+}
+template (present) RAT_Type tr_GTP2C_RatType(template (present) integer rat) := {
+ elementIdentifier := '53'O,
+ lengthIndicator := ?,
+ instance := ?,
+ spare := '0000'B,
+ rAT_TypeValue := rat,
+ additionalOctets := *
+}
+
+
+/* 8.22 */
+private function f_bit4oct(template (omit) octetstring os) return BIT1
+{
+ if (istemplatekind(os, "omit")) {
+ return '0'B;
+ } else {
+ return '1'B;
+ }
+}
+template (value) FullyQualifiedTEID
+ts_GTP2C_FTEID(integer if_type, OCT4 teid, template (omit) OCT4 v4_addr := omit,
+ template (omit) OCT16 v6_addr := omit) := {
+ elementIdentifier := '57'O,
+ lengthIndicator := 0, /* overwritten */
+ instance := '0000'B,
+ spare := '0000'B,
+ interfaceType := if_type,
+ v6_Flag := f_bit4oct(v4_addr),
+ v4_Flag := f_bit4oct(v6_addr),
+ tEID_GRE_Key := teid,
+ iPv4_Address := v4_addr,
+ iPv6_Address := v6_addr,
+ additionalOctets := omit
+}
+template (present) FullyQualifiedTEID
+tr_GTP2C_FTEID(template (present) integer if_type, template (present) OCT4 teid,
+ template OCT4 v4_addr := omit,
+ template OCT16 v6_addr := omit) := {
+ elementIdentifier := '57'O,
+ lengthIndicator := ?,
+ instance := ?,
+ spare := '0000'B,
+ interfaceType := if_type,
+ v6_Flag := ?,
+ v4_Flag := ?,
+ tEID_GRE_Key := teid,
+ iPv4_Address := v4_addr,
+ iPv6_Address := v6_addr,
+ additionalOctets := omit
+}
+
+
+
+template (value) PDU_GTPCv2 ts_PDU_GTP2C(template (omit) OCT4 teid, template (value) OCT3 seq,
+ template (value) OCT1 msg_type,
+ template (value) GTPCv2_PDUs pdus,
+ template (omit) PDU_GTPCv2 piggyback := omit) := {
+ spare := '000'B,
+ t_Bit := fs_GTP2C_t_bit(teid),
+ p_Bit := fs_GTP2C_p_bit(piggyback),
+ version := '010'B,
+ messageType := msg_type,
+ lengthf := 0, /* overwritten */
+ tEID := teid,
+ sequenceNumber := seq,
+ spare3 := '00'O,
+ gtpcv2_pdu := pdus,
+ piggybackPDU_GTPCv2 := piggyback
+}
+
+
+template (present) PDU_GTPCv2
+tr_GTP2C_CreateSessionReq(template (present) hexstring imsi) := tr_PDU_GTP2C('00000000'O, {
+ createSessionRequest := {
+ iMSI := tr_GTP2C_Imsi(imsi),
+ mSISDN := *,
+ mEI := *,
+ userLocationInfo := ?,
+ servingNetwork := ?,
+ rAT_Type := tr_GTP2C_RatType(6),
+ indication := *,
+ fullyQualifiedTEID := ?,
+ accessPointName := tr_GTP2C_APN('012a'O), // '*'
+ selectionMode := ?,
+ pDN_Type := ?,
+ pDN_AddressAllocation := ?,
+ maxAPN_Restriction := ?,
+ ambr := *,
+ linkedEPS_Bearer_ID := omit,
+ trustedWLANModeIndication := omit,
+ protocolConfigOptions := omit,
+ bearerContextGrouped := ?,
+ traceInformation := *,
+ recovery := omit,
+ csid := omit,
+ uE_TimeZone := ?,
+ user_CSG_Information := omit,
+ chargingCharacteristics := ?,
+ lDN := omit,
+ signallingPriorityIndication := *,
+ iP_Addr := omit,
+ portNumber := omit,
+ aPCO := omit,
+ trustedWLANAccessNetworkIdentifier := omit,
+ cNOperatorSelectionEntity := omit,
+ presenceReportingAreaInformation := omit,
+ overloadControlInformationGrouped := omit,
+ originationTimeStamp := *,
+ maximumWaitTime := *,
+ wLANLocationTimestamp := omit,
+ nBIFOMContainer := omit,
+ remoteUEContextGrouped := *,
+ nodeIdentifier := *,
+ extendedProtocolConfigOptions := omit,
+ servingPLMNRateControl := omit,
+ counter := omit,
+ privateExtension := omit
+ }});
+
+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, {
+ createSessionResponse := {
+ cause := ts_GTP2C_Cause(int2oct(16, 1), '0'B),
+ changeReportingAction := omit,
+ cSG_InformationReportingAction := omit,
+ heNBInformationReporting := omit,
+ fullyQualifiedTEID := fteids,
+ pDN_AddressAllocation := addr,
+ aPN_Restriction := omit,
+ ambr := omit,
+ linkedEPS_Bearer_ID := omit,
+ protocolConfigOptions := omit,
+ bearerContextGrouped := omit,
+ recovery := omit,
+ chargingGatewayName := omit,
+ chargingGatewayAddress := omit,
+ csid := omit,
+ lDN := omit,
+ pGW_Back_OffTime := omit,
+ aPCO := omit,
+ trustedWLANIPv4Parameters := omit,
+ indicationFlags := omit,
+ presenceReportingAreaAction := omit,
+ loadControlInformationGrouped := omit,
+ overloadControlInformationGrouped := omit,
+ nBIFOMContainer := omit,
+ pDNConnectionChargingID := omit,
+ extendedProtocolConfigOptions := omit,
+ privateExtension := omit
+ }});
+
+
+
+}