MME2 changes - Propped commits from openmme/paging branch. Added scripts
for code gen
Change-Id: Ie55032217232214ac8544ca76ea34335205329e4
diff --git a/scripts/GtpV2StackCodeGen/tts/datatypetemplate.cpp.tt b/scripts/GtpV2StackCodeGen/tts/datatypetemplate.cpp.tt
new file mode 100644
index 0000000..14d1288
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/datatypetemplate.cpp.tt
@@ -0,0 +1,395 @@
+/*
+ * Copyright 2019-present Infosys Limited
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/datatypetemplate.cpp.tt>
+ ******************************************************************************/
+#include "[% tempdata.fileName %].h"
+
+// TODO
+
+[% tempdata.className %]::[% tempdata.className %]()
+{
+ // TODO
+}
+
+[% tempdata.className %]::~[%tempdata.className %]() {
+ // TODO Auto-generated destructor stub
+}
+
+[% FOREACH type IN tempdata.DataTypeListAuto %]
+bool [%tempdata.className %]::encode[% type.typeName %](MsgBuffer &buffer, [% type.typeName %] const &data)
+{
+[% IF type.validationPresent == "y" -%]
+ if (!([% type.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% type.typeName %]\n");
+ return false; //TODO need to add validations
+ }
+[% END -%]
+[% FOREACH Item IN type.sequence -%]
+[% IF Item.skipType == "y" -%]
+ buffer.skip[% Item.bitByte %]([% Item.skipValue %]);
+
+[% ELSE -%]
+[% IF Item.presence == "optional" -%]
+ if (data.[% Item.fieldName %]Present)
+ {
+
+[% IF Item.encodeConditional == "y" -%]
+ if ([% Item.encodeCondition %])
+ {
+
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false; //TODO need to add validations
+ }
+[% END -%]
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ buffer.writeBits(data.[% Item.fieldName %], [% Item.fieldSize %]);
+[% ELSE -%]
+ buffer.write[% Item.fieldType %](data.[% Item.fieldName %]);
+[% END -%]
+[% ELSE -%]
+ if (!(DataTypeCodecUtils::encode[% Item.fieldType %](buffer, data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Failed to encode [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+
+ }
+ }
+[% ELSE -%]
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ buffer.writeBits(data.[% Item.fieldName %], [% Item.fieldSize %]);
+[% ELSE -%]
+ buffer.write[% Item.fieldType %](data.[% Item.fieldName %]);
+[% END -%]
+[% ELSE -%]
+ if (!(DataTypeCodecUtils::encode[% Item.fieldType %](buffer, data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Failed to encode [% Item.fieldName %]\n");
+ return false;
+ }
+
+[% END -%]
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.encodeConditional == "y" -%]
+ if ([% Item.encodeCondition %])
+ {
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false; //TODO need to add validations
+ }
+[% END -%]
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ buffer.writeBits(data.[% Item.fieldName %], [% Item.fieldSize %]);
+[% ELSE -%]
+ buffer.write[% Item.fieldType %](data.[% Item.fieldName %]);
+[% END -%]
+[% ELSE -%]
+ if (!(DataTypeCodecUtils::encode[% Item.fieldType %](buffer, data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Failed to encode [% Item.fieldName %]\n");
+ return false;
+ }
+
+[% END -%]
+ }
+
+[% ELSE -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false; //TODO need to add validations
+ }
+[% END -%]
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ buffer.writeBits(data.[% Item.fieldName %], [% Item.fieldSize %]);
+[% ELSE -%]
+ buffer.write[% Item.fieldType %](data.[% Item.fieldName %]);
+[% END -%]
+[% ELSE -%]
+ if (!(DataTypeCodecUtils::encode[% Item.fieldType %](buffer, data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Failed to encode [% Item.fieldName %]\n");
+ return false;
+ }
+
+[% END -%]
+[% END -%]
+[% END -%]
+[% END -%]
+[% END -%]
+ return true;
+}
+
+bool [%tempdata.className %]::decode[% type.typeName %](MsgBuffer &buffer,[% type.typeName %] &data,
+ Uint16 length)
+{
+
+ Uint16 typeBoundary = buffer.getCurrentIndex() + length;
+[% FOREACH Item IN type.sequence -%]
+[% IF Item.skipType == "y" -%]
+ buffer.skip[% Item.bitByte %]([% Item.skipValue %]);
+ if (buffer.getCurrentIndex() > typeBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond type boundary: [% Item.fieldName %]\n");
+ return false;
+ }
+[% ELSE -%]
+[% IF Item.decodeConditional == "y" %]
+ if ([% Item.decodeCondition %])
+ {
+
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ data.[% Item.fieldName %] = buffer.readBits([% Item.fieldSize %]);
+ if (buffer.getCurrentIndex() > typeBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond type boundary: [% Item.fieldName %]\n");
+ return false;
+ }
+[% ELSE %]
+ buffer.read[% Item.fieldType %](data.[% Item.fieldName %]);
+ if (buffer.getCurrentIndex() > typeBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond type boundary: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.length == "lengthLeft" -%]
+ Uint16 lengthLeft = typeBoundary - buffer.getCurrentIndex();
+[% END -%]
+[% IF Item.arrayType == "y" -%]
+ if (!(DataTypeCodecUtils::decode[% Item.fieldType %](buffer, data.[% Item.fieldName %], [% Item.length %], [% Item.count %])))
+[% ELSE -%]
+ if (!(DataTypeCodecUtils::decode[% Item.fieldType %](buffer, data.[% Item.fieldName %], [% Item.length %])))
+[% END -%]
+ {
+ errorStream.add((char *)"Failed to decode: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false; //TODO need to add validations
+ }
+[% END -%]
+[% IF Item.presence == "optional" -%]
+ data.[% Item.fieldName %]Present = true;
+[% END -%]
+
+ }
+[% ELSE -%]
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ data.[% Item.fieldName %] = buffer.readBits([% Item.fieldSize %]);
+ if (buffer.getCurrentIndex() > typeBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond type boundary: [% Item.fieldName %]\n");
+ return false;
+ }
+[% ELSE %]
+ buffer.read[% Item.fieldType %](data.[% Item.fieldName %]);
+ if (buffer.getCurrentIndex() > typeBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond type boundary: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.length == "lengthLeft" -%]
+ Uint16 lengthLeft = typeBoundary - buffer.getCurrentIndex();
+[% END -%]
+[% IF Item.arrayType == "y" -%]
+ if (!(DataTypeCodecUtils::decode[% Item.fieldType %](buffer, data.[% Item.fieldName %], [% Item.length %], [% Item.count %])))
+[% ELSE -%]
+ if (!(DataTypeCodecUtils::decode[% Item.fieldType %](buffer, data.[% Item.fieldName %], [% Item.length %])))
+[% END -%]
+ {
+ errorStream.add((char *)"Failed to decode: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false; //TODO need to add validations
+ }
+[% END -%]
+[% IF Item.presence == "optional" -%]
+ data.[% Item.fieldName %]Present = true;
+[% END -%]
+[% END -%]
+[% END -%]
+[% END -%]
+
+[% IF validationPresent == "y" -%]
+ if (!([% validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure at IE: [%tempdata.className %]\n");
+ return false;
+ }
+[% END -%]
+ return true;
+}
+
+void [%tempdata.className %]::display[% type.typeName %]_v([% type.typeName %] const &data, Debug &stream)
+{
+ stream.incrIndent();
+ stream.add((char *)"[% type.typeName %]:");
+ stream.incrIndent();
+ stream.endOfLine();
+[% FOREACH Item IN type.sequence -%]
+[% IF Item.skipType != "y" -%]
+[% IF Item.presence == "optional" -%]
+ if (data.[% Item.fieldName %]Present)
+ {
+[% IF Item.encodeConditional == "y" %]
+ if ([% Item.encodeCondition %])
+ {
+[% IF Item.leafType == "y" -%]
+ stream.add((char *)"[% Item.fieldName %] = ");
+ stream.add(data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% ELSE -%]
+ DataTypeCodecUtils::display[% Item.fieldType %]_v(data.[% Item.fieldName %], stream);
+[% END -%]
+ }
+ }
+[%ELSE-%]
+[% IF Item.leafType == "y" -%]
+ stream.add((char *)"[% Item.fieldName %] = ");
+ stream.add(data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% ELSE -%]
+ DataTypeCodecUtils::display[% Item.fieldType %]_v(data.[% Item.fieldName %], stream);
+[% END -%]
+ }
+
+[% END -%]
+[% ELSE -%]
+[% IF Item.encodeConditional == "y" %]
+ if ([% Item.encodeCondition %])
+ {
+[% IF Item.leafType == "y" -%]
+ stream.add((char *)"[% Item.fieldName %] = ");
+ stream.add(data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% END -%]
+ }
+[%ELSE-%]
+[% IF Item.leafType == "y" -%]
+ stream.add((char *)"[% Item.fieldName %] = ");
+ stream.add(data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% END -%]
+[% END -%]
+[% END -%]
+[% END -%]
+[% END -%]
+ stream.decrIndent();
+ stream.decrIndent();
+}
+[% END %]
+
+[% FOREACH arrayType IN tempdata.arrayTypeList %]
+bool [%tempdata.className %]::encode[% arrayType.typeName %](MsgBuffer &buffer,
+ [% arrayType.typeName %] const &data)
+{
+ Uint16 i;
+ for (i = 0; i < data.count; i++)
+ {
+[% IF arrayType.leafType == "y" -%]
+ buffer.write[% arrayType.subType %](data.values[i]);
+[% ELSE -%]
+ if (!(DataTypeCodecUtils::encode[% arrayType.subType %](buffer, data.values[i])))
+ {
+ errorStream.add((char *)"Failed to encode [% arrayType.typeName %]\n");
+ return false;
+ }
+[% END -%]
+ }
+ return true;
+}
+
+bool [%tempdata.className %]::decode[% arrayType.typeName %](MsgBuffer &buffer,
+ [% arrayType.typeName %] &data, Uint16 length, Uint16 count)
+{
+ Uint16 i = 0;
+ data.count = 0;
+ bool readTillEnd = (count == 0);
+ Uint16 startIndex = buffer.getCurrentIndex();
+ Uint16 typeBoundary = startIndex+length;
+
+ while ((i < count)||(readTillEnd && (buffer.getCurrentIndex() < typeBoundary)))
+ {
+[% IF arrayType.leafType == "y" -%]
+ buffer.read[% arrayType.subType %](data.values[i]);
+[% ELSE -%]
+ Uint16 lengthLeft = typeBoundary - buffer.getCurrentIndex();
+ [% IF arrayType.arrayType == "y" -%]
+ if (!(DataTypeCodecUtils::decode[% arrayType.subType %](buffer, data.values[i], lengthLeft, data.count)))
+ [% ELSE -%]
+ if (!(DataTypeCodecUtils::decode[% arrayType.subType %](buffer, data.values[i], lengthLeft)))
+ [% END -%]
+
+ {
+ errorStream.add((char *)"Failed to encode [% arrayType.typeName %]\n");
+ return false;
+ }
+[% END -%]
+ if (buffer.getCurrentIndex() > typeBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond type boundary:[% arrayType.typeName %]\n");
+ return false;
+ }
+ data.count++;
+ i++;
+ }
+ return true;
+}
+
+void [%tempdata.className %]::display[% arrayType.typeName %]_v([% arrayType.typeName %] const &data, Debug &stream)
+{
+ stream.incrIndent();
+ stream.add((char *)"[% arrayType.typeName %]: Count: ");
+ stream.add(data.count);
+ stream.incrIndent();
+ stream.endOfLine();
+[% IF arrayType.leafType == "y" -%]
+ Uint16 i;
+ for (i = 0; i < data.count; i++)
+ {
+ stream.add(data.values[i]);
+ stream.endOfLine();
+ }
+[% END -%]
+ stream.decrIndent();
+ stream.decrIndent();
+}
+[% END %]
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/datatypetemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/datatypetemplate.h.tt
new file mode 100644
index 0000000..a1fbf4b
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/datatypetemplate.h.tt
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/datatypetemplate.h.tt>
+ ******************************************************************************/
+
+#ifndef [% tempdata.classNameUC %]_H_
+#define [% tempdata.classNameUC %]_H_
+
+#include <sstream>
+#include <msgBuffer.h>
+#include "gtpV2IeDataTypes.h"
+#include "gtpV2DataTypes.h"
+#include "manual/gtpV2DataTypes_Manual.h"
+
+//TODO Includes
+
+class DataTypeCodecUtils {
+public:
+ [% tempdata.className %]();
+ virtual ~[% tempdata.className %]();
+
+[% FOREACH type IN tempdata.DataTypeListAuto %]
+ static bool encode[% type.typeName %](MsgBuffer &buffer, [% type.typeName %] const &data);
+ static bool decode[% type.typeName %](MsgBuffer &buffer, [% type.typeName %] &data,
+ Uint16 length);
+ static void display[% type.typeName %]_v([% type.typeName %] const &data, Debug &stream);
+[% END %]
+
+ // The following methods are generated to encode, decode and display array types
+[% FOREACH arrayType IN tempdata.arrayTypeList %]
+ static bool encode[% arrayType.typeName %](MsgBuffer &buffer, [% arrayType.typeName %] const &data);
+ static bool decode[% arrayType.typeName %](MsgBuffer &buffer, [% arrayType.typeName %] &data,
+ Uint16 length, Uint16 count);
+ static void display[% arrayType.typeName %]_v([% arrayType.typeName %] const &data, Debug &stream);
+
+[% END -%]
+
+ // The following methods are to be written manually
+ // See DataTypeCodecUtils_Manual.cc for implementation
+[% FOREACH type IN tempdata.DataTypeListManual %]
+ static bool encode[% type.typeName %](MsgBuffer &buffer, [% type.typeName %] const &data);
+ static bool decode[% type.typeName %](MsgBuffer &buffer, [% type.typeName %] &data,
+ Uint16 length);
+ static void display[% type.typeName %]_v([% type.typeName %] const &data, Debug &stream);
+[% END %]
+
+};
+
+#endif /*[% tempdata.classNameUC %]_H_*/
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/grpIeDataTypetemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/grpIeDataTypetemplate.h.tt
new file mode 100644
index 0000000..55943ca
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/grpIeDataTypetemplate.h.tt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/grpIeDataTypetemplate.h.tt>
+ ******************************************************************************/
+#ifndef GTPV2GRPIEDATATYPES_H_
+#define GTPV2GRPIEDATATYPES_H_
+
+#include "../../gtpV2Codec/ieClasses/gtpV2IeDataTypes.h"
+
+[% FOREACH grpIe IN tempdata.grpList -%]
+typedef struct
+{
+[% FOREACH iePresence IN grpIe.iePresenceList -%]
+ bool [% iePresence %];
+[% END -%]
+
+[% FOREACH ie IN grpIe.ieList -%]
+ [% ie.ieTypeName %] [% ie.ieVarName %];
+[% END -%]
+
+}[% grpIe.grpIeName %];
+
+[% END -%]
+
+//Ie Type Constants
+[% FOREACH ie IN tempdata.grpTypeList -%]
+static const Uint8 [% ie.grpIeTypeName %] = [% ie.grpIeTypeValue %];
+[% END -%]
+
+
+#endif
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/grpieinsttemplate.cpp.tt b/scripts/GtpV2StackCodeGen/tts/grpieinsttemplate.cpp.tt
new file mode 100644
index 0000000..60935b4
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/grpieinsttemplate.cpp.tt
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2019-present Infosys Limited
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/grpieinsttemplate.cpp.tt>
+ ******************************************************************************/
+
+#include "[% tempdata.fileName %].h"
+#include "manual/gtpV2Ie.h"
+#include "gtpV2IeFactory.h"
+[% FOREACH ieData IN tempdata.ieList -%]
+#include "[% ieData.ieFileName %].h"
+[% END -%]
+
+[% tempdata.msgClassName %]::
+[% tempdata.msgClassName %]()
+{
+[% PROCESS MandIeList %]
+}
+
+[% tempdata.msgClassName %]::
+~[% tempdata.msgClassName %]()
+{
+
+}
+bool [% tempdata.msgClassName %]::
+encode[% tempdata.msgClassName %](MsgBuffer &buffer,
+ [% tempdata.msgClassName %]Data
+ const &data)
+{
+ bool rc = false;
+ GtpV2IeHeader header;
+ Uint16 startIndex = 0;
+ Uint16 endIndex = 0;
+ Uint16 length = 0;
+[% FOREACH ieData IN tempdata.ieList -%]
+
+[% IF ieData.iePresence != 'M' -%]
+ if (data.[% ieData.ieVarName %]IePresent)
+ {
+ [% INCLUDE tts/msgEncode.tt FILTER indent%]
+ if (!(rc))
+ {
+ errorStream.add((char *)"Failed to encode IE: [% ieData.ieVarName %]\n");
+ return false;
+ }
+ }
+[% ELSE %]
+ [% INCLUDE tts/msgEncode.tt -%]
+ if (!(rc))
+ {
+ errorStream.add((char *)"Failed to encode IE: [% ieData.ieVarName %]\n");
+ return false;
+ }
+[% END -%]
+[% END -%]
+ return rc;
+}
+
+bool [% tempdata.msgClassName %]::
+decode[% tempdata.msgClassName %](MsgBuffer &buffer,
+ [% tempdata.msgClassName %]Data
+ &data, Uint16 length)
+{
+
+ bool rc = false;
+ GtpV2IeHeader ieHeader;
+ set<Uint16> mandatoryIeLocalList = mandatoryIeSet;
+ while (buffer.lengthLeft() > IE_HEADER_SIZE)
+ {
+ GtpV2Ie::decodeGtpV2IeHeader(buffer, ieHeader);
+ if (ieHeader.length > buffer.lengthLeft())
+ {
+ // We do not have enough bytes left in the message for this IE
+ errorStream.add((char *)"IE Length exceeds beyond message boundary\n");
+ errorStream.add((char *)" Offending IE Type: ");
+ errorStream.add(ieHeader.ieType);
+ errorStream.add((char *)"\n Ie Length in Header: ");
+ errorStream.add(ieHeader.length);
+ errorStream.add((char *)"\n Bytes left in message: ");
+ errorStream.add(buffer.lengthLeft());
+ errorStream.endOfLine();
+ return false;
+ }
+
+ switch (ieHeader.ieType){
+[% FOREACH ieTypeEntry IN tempdata.ieTypeList -%]
+ case [% ieTypeEntry %]IeType:
+ {
+ [% ieTypeEntry %]Ie ieObject =
+ dynamic_cast<
+ [% ieTypeEntry %]Ie&>(GtpV2IeFactory::getInstance().
+ getIeObject([% ieTypeEntry %]IeType));
+[% SET first = 1 -%]
+[% FOREACH ieTypeData IN tempdata.ieList -%]
+[% IF ieTypeData.ieType == ieTypeEntry -%]
+
+[% IF first == 1 -%]
+[% SET first = 0 %]
+ if(ieHeader.instance == [% ieTypeData.instance %])
+[% ELSE -%]
+ else if(ieHeader.instance == [% ieTypeData.instance %])
+[% END -%]
+ {
+
+ [% INCLUDE tts/msgDecode.tt %]
+[% IF ieTypeData.ieCardinality == 1 %][% IF ieTypeData.iePresence != "M" -%]
+ data.[% ieTypeData.ieVarName %]IePresent = true;
+[% END %][% END -%]
+ if (!(rc))
+ {
+ errorStream.add((char *)"Failed to decode IE: [% ieTypeData.ieVarName %]\n");
+ return false;
+ }
+[% IF ieTypeData.iePresence == 'M' -%]
+ Uint16 mandIe = [% ieTypeEntry %]IeType;
+ mandIe = (mandIe << 8) | [% ieTypeData.instance %];
+ mandatoryIeLocalList.erase(mandIe);
+[% END -%]
+ }
+[% END -%]
+[% END -%]
+ else
+ {
+ // Unknown IE instance print error TODO
+ errorStream.add((char *)"Unknown IE Type: ");
+ errorStream.add(ieHeader.ieType);
+ errorStream.endOfLine();
+ buffer.skipBytes(ieHeader.length);
+ }
+ break;
+ }
+[% END -%]
+ default:
+ {
+ // Unknown IE print error
+ errorStream.add((char *)"Unknown IE Type: ");
+ errorStream.add(ieHeader.ieType);
+ errorStream.endOfLine();
+ buffer.skipBytes(ieHeader.length);
+ }
+ }
+ }
+ if (!mandatoryIeLocalList.empty())
+ {
+ // some mandatory IEs are missing
+ errorStream.add((char *)"Missing Mandatory IEs:");
+ errorStream.endOfLine();
+ while (!mandatoryIeLocalList.empty())
+ {
+ Uint16 missingMandIe = *mandatoryIeLocalList.begin ();
+ mandatoryIeLocalList.erase (mandatoryIeLocalList.begin ());
+ Uint16 missingInstance = missingMandIe & 0x00FF;
+ Uint16 missingIeType = (missingMandIe >> 8);
+ errorStream.add ((char *)"Missing Ie type: ");
+ errorStream.add (missingIeType);
+ errorStream.add ((char *)" Instance: ");
+ errorStream.add (missingInstance);
+ errorStream.endOfLine();
+ }
+ rc = false;
+
+ }
+ return rc;
+}
+
+void [% tempdata.msgClassName %]::
+display[% tempdata.msgClassName %]Data_v
+([% tempdata.msgClassName %]Data const &data, Debug &stream)
+{
+ stream.incrIndent();
+ stream.add((char *)"[% tempdata.msgClassName %]:");
+ stream.endOfLine();
+ stream.incrIndent();
+[% FOREACH ieData IN tempdata.ieList -%]
+
+[% IF ieData.iePresence != 'M' -%][% IF ieData.ieCardinality == 1 -%]
+ if (data.[% ieData.ieVarName %]IePresent)
+ {
+
+[% IF ieData.ieCardinality == 1 -%]
+ stream.add((char *)"[% ieData.ieVarName %]:");
+ stream.endOfLine();
+ [% ieData.ieType %]Ie [% ieData.ieLocalVar %]=
+ dynamic_cast<
+ [% ieData.ieType %]Ie&>(GtpV2IeFactory::getInstance().getIeObject([% ieData.ieType %]IeType));
+ [% PROCESS ieDisplay_grp %]
+[% ELSE -%]
+ for (Uint8 i = 0; i < data.[% ieData.ieVarName %]Count; i++)
+ {
+ stream.add((char *)"IE - [% ieData.ieVarName %]:");
+ stream.endOfLine();
+ [% ieData.ieType %]Ie [% ieData.ieLocalVar %]=
+ dynamic_cast<[% ieData.ieType %]Ie&>(GtpV2IeFactory::getInstance().getIeObject([% ieData.ieType %]IeType));
+ [% PROCESS ieDisplay_grp %]
+ }
+[% END -%]
+ }
+[% ELSE -%]
+[% IF ieData.ieCardinality == 1 -%]
+ stream.add((char *)"[% ieData.ieVarName %]:");
+ stream.endOfLine();
+ [% ieData.ieType %]Ie [% ieData.ieLocalVar %]=
+ dynamic_cast<
+ [% ieData.ieType %]Ie&>(GtpV2IeFactory::getInstance().getIeObject([% ieData.ieType %]IeType));
+[% PROCESS ieDisplay_grp -%]
+[% ELSE -%]
+ for (Uint8 i = 0; i < data.[% ieData.ieVarName %]Count; i++)
+ {
+ stream.add((char *)"IE - [% ieData.ieVarName %]:");
+ stream.endOfLine();
+ [% ieData.ieType %]Ie [% ieData.ieLocalVar %]=
+ dynamic_cast<[% ieData.ieType %]Ie&>(GtpV2IeFactory::getInstance().getIeObject([% ieData.ieType %]IeType));
+ [% PROCESS ieDisplay_grp -%]
+ }
+[% END -%]
+[% END %][% END -%]
+[% END -%]
+
+ stream.decrIndent();
+ stream.decrIndent();
+}
+
+
+[% BLOCK ieDisplay_grp -%]
+[% IF ieData.grouped == "Yes" -%]
+ [% ieData.grpIeInstClassName %] groupedIeInstance =
+ dynamic_cast<
+ [% ieData.grpIeInstClassName %]&>([% ieData.ieLocalVar %].getGroupedIe(msgType, [% ieData.instance %]));
+ groupedIeInstance.display[% ieData.grpIeInstClassName %]Data_v(data.[% ieData.ieVarName %][% PROCESS cardinalIndex %], stream);
+[% ELSE -%]
+ [% ieData.ieLocalVar %].display[% ieData.ieType %]Ie_v(data.[% ieData.ieVarName %][% PROCESS cardinalIndex %], stream);
+[% END -%]
+[% END -%]
+
+[% BLOCK cardinalIndex -%]
+[% IF ieData.ieCardinality != 1 %][i][% END -%]
+[% END -%]
+
+
+[% BLOCK MandIeList -%]
+[% SET first = 1 -%]
+[% FOREACH ieData IN tempdata.ieList -%]
+[% IF ieData.iePresence == 'M' -%]
+[% IF first == 1 -%]
+ Uint16 mandIe;
+[% SET first = 0 -%]
+[% END -%]
+ mandIe = [% ieData.ieType %]IeType;
+ mandIe = (mandIe << 8) | [% ieData.instance %]; // [% ieData.ieVarName %]
+ mandatoryIeSet.insert(mandIe);
+[% END -%]
+[% END -%]
+[% END -%]
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/grpieinsttemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/grpieinsttemplate.h.tt
new file mode 100644
index 0000000..a1549e8
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/grpieinsttemplate.h.tt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/grpieinsttemplate.h.tt>
+ ******************************************************************************/
+#ifndef [% tempdata.classNameUC %]_H_
+#define [% tempdata.classNameUC %]_H_
+
+#include <set>
+#include <sstream>
+#include "manual/gtpV2GroupedIe.h"
+#include <msgBuffer.h>
+#include "gtpV2GrpIeDataTypes.h"
+#include "../msgClasses/gtpV2MsgDataTypes.h"
+
+class [% tempdata.msgClassName %]:public GtpV2GroupedIe
+{
+public:
+ [% tempdata.msgClassName %]();
+ virtual ~[% tempdata.msgClassName %]();
+ bool encode[% tempdata.msgClassName %](MsgBuffer &buffer,
+ [% tempdata.msgClassName %]Data
+ const &data);
+
+ bool decode[% tempdata.msgClassName %] (MsgBuffer &buffer,
+ [% tempdata.msgClassName %]Data
+ & data, Uint16 length);
+
+ void display[% tempdata.msgClassName %]Data_v
+ ([% tempdata.msgClassName %]Data const &data,
+ Debug &stream);
+
+private:
+ set <Uint16> mandatoryIeSet;
+};
+
+#endif
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/grpietemplate.cpp.tt b/scripts/GtpV2StackCodeGen/tts/grpietemplate.cpp.tt
new file mode 100644
index 0000000..9a68e5a
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/grpietemplate.cpp.tt
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019-present Infosys Limited
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/grpietemplate.cpp.tt>
+ ******************************************************************************/
+#include "[% tempdata.fileName %].h"
+#include "gtpV2GrpIeDataTypes.h"
+#include "manual/gtpV2GroupedIe.h"
+[%fileList =tempdata.fileName -%]
+
+[% FOREACH inst IN tempdata.$fileList -%]
+#include "[% inst.fileName %].h"
+[% END -%]
+
+[% tempdata.className %]::[% tempdata.className %]()
+{
+ ieType = [% tempdata.className %]Type;
+
+[% FOREACH inst IN tempdata.$fileList -%]
+ [% inst.className %]* [% inst.fileName %]_p = new ([% inst.className %]);
+ insertGroupedIeObject([% inst.msgType %], [% inst.instance %], [% inst.fileName %]_p);
+[% END -%]
+}
+
+[% tempdata.className %]::~[% tempdata.className %]() {
+// TODO Auto-generated destructor stub
+}
+
+GtpV2GroupedIe& [% tempdata.className %]::getGroupedIe(Uint8 msgType, Uint8 instance)
+{
+ std::map<Uint16, GtpV2GroupedIe*>::iterator it;
+ Uint16 key = msgType;
+ key = (key << 8) + instance;
+ it = groupedIeObjectContainer.find(key);
+ return *(it->second);
+}
+
+void [% tempdata.className %]::insertGroupedIeObject(Uint8 msgType, Uint8 instance, GtpV2GroupedIe* grpIe_p)
+{
+
+ Uint16 key = msgType;
+ key = (key << 8) + instance;
+
+ groupedIeObjectContainer.insert(std::pair<Uint16, GtpV2GroupedIe*>(key, grpIe_p));
+
+}
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/grpietemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/grpietemplate.h.tt
new file mode 100644
index 0000000..f8105c5
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/grpietemplate.h.tt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/grpietemplate.h.tt>
+ ******************************************************************************/
+#ifndef [% tempdata.classNameUC %]_H_
+#define [% tempdata.classNameUC %]_H_
+
+#include <map>
+#include "manual/gtpV2Ie.h"
+#include "manual/gtpV2GroupedIe.h"
+#include "gtpV2DataTypes.h"
+
+class [% tempdata.className %]:public GtpV2Ie
+{
+public:
+ [% tempdata.className %] ();
+ virtual ~ [% tempdata.className %] ();
+
+ GtpV2GroupedIe & getGroupedIe (Uint8 msgType, Uint8 instance);
+ void insertGroupedIeObject (Uint8 msgType, Uint8 instance,
+ GtpV2GroupedIe * grpIe_p);
+
+private:
+ map < Uint16, GtpV2GroupedIe * >groupedIeObjectContainer; // map[msgType || instance]
+};
+
+#endif
diff --git a/scripts/GtpV2StackCodeGen/tts/ieDataTypetemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/ieDataTypetemplate.h.tt
new file mode 100644
index 0000000..99b2c7b
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/ieDataTypetemplate.h.tt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/ieDataTypetemplate.h.tt>
+ ******************************************************************************/
+#ifndef GTPV2IEDATATYPES_H_
+#define GTPV2IEDATATYPES_H_
+
+#include "gtpV2DataTypes.h"
+#include "manual/gtpV2DataTypes_Manual.h"
+
+[% FOREACH ie IN tempdata.ieList -%]
+typedef struct
+{
+[% FOREACH ieField IN ie.varList -%]
+[% IF ieField.presence == "optional" -%]
+ bool [% ieField.varName %]Present;
+[% END -%]
+ [% ieField.varType %] [% ieField.varName %];
+[% END -%]
+
+}[% ie.ieName %];
+
+[% END -%]
+
+//Ie Type Constants
+[% FOREACH ie IN tempdata.ieTypeList -%]
+static const Uint8 [% ie.ieName %] = [% ie.value %];
+[% END -%]
+
+
+#endif
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/iefactorytemplate.cpp.tt b/scripts/GtpV2StackCodeGen/tts/iefactorytemplate.cpp.tt
new file mode 100644
index 0000000..5ecde81
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/iefactorytemplate.cpp.tt
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019-present Infosys Limited
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/iefactorytemplate.cpp.tt>
+ ******************************************************************************/
+
+#include <map>
+#include "gtpV2IeFactory.h"
+#include "manual/gtpV2Ie.h"
+#include "gtpV2GrpIeDataTypes.h"
+[% FOREACH ie IN tempdata.ieList -%]
+#include "[% ie.ieFileName %].h"
+[% END -%]
+
+GtpV2IeFactory::GtpV2IeFactory()
+{
+ //Create Message Objects
+[% FOREACH ie IN tempdata.ieList -%]
+ [% ie.className %]* [% ie.ieFileName %]_p = new ([% ie.className %]);
+ ieObjectContainer.insert(std::pair<Uint8, GtpV2Ie*>([% ie.className %]Type, [% ie.ieFileName %]_p));
+
+[% END -%]
+
+}
+
+GtpV2IeFactory::~GtpV2IeFactory() {
+ // TODO clean up the allocated memory for message objects
+}
+
+GtpV2IeFactory& GtpV2IeFactory::getInstance()
+{
+ static GtpV2IeFactory gtpV2IeFactory;
+ return gtpV2IeFactory;
+}
+
+GtpV2Ie& GtpV2IeFactory::getIeObject(Uint8 ieType)
+{
+ std::map<Uint8, GtpV2Ie*>::iterator it;
+ it = ieObjectContainer.find(ieType);
+ return *(it->second);
+}
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/iefactorytemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/iefactorytemplate.h.tt
new file mode 100644
index 0000000..b04eb47
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/iefactorytemplate.h.tt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/iefactorytemplate.h.tt>
+ ******************************************************************************/
+#ifndef GTPV2IEFACTORY_H_
+#define GTPV2IEFACTORY_H_
+
+#include <map>
+#include "manual/gtpV2Ie.h"
+
+class GtpV2IeFactory {
+public:
+ GtpV2IeFactory();
+ virtual ~GtpV2IeFactory();
+
+ static GtpV2IeFactory& getInstance();
+
+ GtpV2Ie& getIeObject(Uint8 ieType);
+
+private:
+
+ map<Uint8, GtpV2Ie*> ieObjectContainer;
+
+};
+
+
+#endif /* GTPV2MSGFACTORY_H_ */
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/ietemplate.cpp.tt b/scripts/GtpV2StackCodeGen/tts/ietemplate.cpp.tt
new file mode 100644
index 0000000..2e1a131
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/ietemplate.cpp.tt
@@ -0,0 +1,445 @@
+/*
+ * Copyright 2019-present Infosys Limited
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/ietemplate.cpp.tt>
+ ******************************************************************************/
+
+#include "[% tempdata.fileName %].h"
+#include "dataTypeCodecUtils.h"
+
+[% tempdata.className %]::[% tempdata.className %]()
+{
+ ieType = [% tempdata.ieTypeVal %];
+ // TODO
+
+}
+
+[% tempdata.className %]::~[% tempdata.className %]() {
+ // TODO Auto-generated destructor stub
+}
+
+bool [% tempdata.className %]::encode[% tempdata.className %](MsgBuffer &buffer, [% tempdata.className %]Data const &data)
+{
+[% IF validationPresent == "y" -%]
+ if (!([% validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure at IE : [% tempdata.className %]\n");
+ return false;
+ }[% END -%]
+[% FOREACH Item IN tempdata.sequence -%]
+[% IF Item -%]
+[% IF Item.skipType == "y" -%]
+ buffer.skip[% Item.bitByte %]([% Item.skipValue %]);
+
+[% ELSE -%]
+[% IF Item.presence == "optional" -%]
+ if (data.[% Item.fieldName %]Present)
+ {
+[% IF Item.encodeConditional == "y" -%]
+ if ([% Item.encodeCondition %])
+ {
+[% IF Item.leafType == "y" -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+[% IF Item.bitField == "y" -%]
+ if(!(buffer.writeBits(data.[% Item.fieldName %], [% Item.fieldSize %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% ELSE -%]
+ if (!(buffer.write[% Item.fieldType %](data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+ if (!(DataTypeCodecUtils::encode[% Item.fieldType %](buffer, data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% END -%]
+ }
+ }
+[% ELSE -%]
+[% IF Item.leafType == "y" -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+[% IF Item.bitField == "y" -%]
+ if(!(buffer.writeBits(data.[% Item.fieldName %], [% Item.fieldSize %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% ELSE -%]
+ if (!(buffer.write[% Item.fieldType %](data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+ if (!(DataTypeCodecUtils::encode[% Item.fieldType %](buffer, data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% END -%]
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.encodeConditional == "y" -%]
+ if ([% Item.encodeCondition %])
+ {
+[% IF Item.leafType == "y" -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+[% IF Item.bitField == "y" -%]
+ if(!(buffer.writeBits(data.[% Item.fieldName %], [% Item.fieldSize %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% ELSE -%]
+ if (!(buffer.write[% Item.fieldType %](data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+ if (!(DataTypeCodecUtils::encode[% Item.fieldType %](buffer, data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% END -%]
+ }
+[% ELSE -%]
+[% IF Item.leafType == "y" -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+[% IF Item.bitField == "y" -%]
+ if(!(buffer.writeBits(data.[% Item.fieldName %], [% Item.fieldSize %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% ELSE -%]
+ if (!(buffer.write[% Item.fieldType %](data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+ if (!(DataTypeCodecUtils::encode[% Item.fieldType %](buffer, data.[% Item.fieldName %])))
+ {
+ errorStream.add((char *)"Encoding of [% Item.fieldName %] failed\n");
+ return false;
+ }
+[% END -%]
+[% END -%]
+[% END -%]
+[% END -%]
+[% END -%]
+[% END %]
+ return true;
+}
+
+bool [% tempdata.className %]::decode[% tempdata.className %](MsgBuffer &buffer, [% tempdata.className %]Data &data, Uint16 length)
+{
+[%- flag = 0 -%]
+
+ // TODO optimize the length checks
+
+ Uint16 ieBoundary = buffer.getCurrentIndex() + length;
+[% FOREACH Item IN tempdata.sequence -%]
+[% IF Item.length == "lengthLeft" -%][%- IF flag == 0 %]
+ Uint16 lengthLeft = length;
+ [%- flag = 1 %]
+[% END -%][% END -%]
+[% IF Item.skipType == "y" -%]
+ buffer.skip[% Item.bitByte %]([% Item.skipValue %]);
+ if (buffer.getCurrentIndex() > ieBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond IE boundary: [% Item.fieldName %]\n");
+ return false;
+ }
+
+[% ELSE -%]
+[% IF Item.decodeConditional == "y" %]
+ if ([% Item.decodeCondition %])
+ {
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ data.[% Item.fieldName %] = buffer.readBits([% Item.fieldSize %]);
+ // confirm that we are not reading beyond the IE boundary
+ if (buffer.getCurrentIndex() > ieBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond IE boundary: [% Item.fieldName %]\n");
+ return false;
+ }
+[% ELSE %]
+ buffer.read[% Item.fieldType %](data.[% Item.fieldName %]);
+ if (buffer.getCurrentIndex() > ieBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond IE boundary: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure : [% Item.fieldName %]\n");
+ return false; //TODO need to add validations
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.length == "lengthLeft" -%]
+ lengthLeft = ieBoundary - buffer.getCurrentIndex();
+[% END -%]
+[% IF Item.arrayType == "y" -%]
+ if (!(DataTypeCodecUtils::decode[% Item.fieldType %](buffer, data.[% Item.fieldName %], [% Item.length %], [% Item.count %])))
+[% ELSE -%]
+ if (!(DataTypeCodecUtils::decode[% Item.fieldType %](buffer, data.[% Item.fieldName %], [% Item.length %])))
+[% END -%]
+ {
+ errorStream.add((char *)"Failed to decode: [% Item.fieldName %]\n");
+ return false;
+ }
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure : [% Item.fieldName %]\n");
+ return false; //TODO need to add validations
+ }
+[% END -%]
+[% END -%]
+[% IF Item.presence == "optional" -%]
+ data.[% Item.fieldName %]Present = true;
+[% END -%]
+ }
+[% ELSE -%]
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ data.[% Item.fieldName %] = buffer.readBits([% Item.fieldSize %]);
+ // confirm that we are not reading beyond the IE boundary
+ if (buffer.getCurrentIndex() > ieBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond IE boundary: [% Item.fieldName %]\n");
+ return false;
+ }
+[% ELSE %]
+ buffer.read[% Item.fieldType %](data.[% Item.fieldName %]);
+ if (buffer.getCurrentIndex() > ieBoundary)
+ {
+ errorStream.add((char *)"Attempt to read beyond IE boundary: [% Item.fieldName %]\n");
+ return false;
+ }
+[% END -%]
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure : [% Item.fieldName %]\n");
+ return false; //TODO need to add validations
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.length == "lengthLeft" -%]
+ lengthLeft = ieBoundary - buffer.getCurrentIndex();
+[% END -%]
+[% IF Item.arrayType == "y" -%]
+ if (!(DataTypeCodecUtils::decode[% Item.fieldType %](buffer, data.[% Item.fieldName %], [% Item.length %], [% Item.count %])))
+[% ELSE -%]
+ if (!(DataTypeCodecUtils::decode[% Item.fieldType %](buffer, data.[% Item.fieldName %], [% Item.length %])))
+[% END -%]
+ {
+ errorStream.add((char *)"Failed to decode: [% Item.fieldName %]\n");
+ return false;
+ }
+[% IF Item.validationPresent == "y" -%]
+ if (!([% Item.validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure : [% Item.fieldName %]\n");
+ return false; //TODO need to add validations
+ }
+[% END -%]
+[% END -%]
+[% IF Item.presence == "optional" -%]
+ data.[% Item.fieldName %]Present = true;
+[% END -%]
+[% END -%]
+[% END -%]
+[% END -%]
+[% IF validationPresent == "y" -%]
+ if (!([% validationRule %]))
+ {
+ errorStream.add((char *)"Data validation failure at IE: [% tempdata.className %]\n");
+ return false;
+ }
+[% END -%]
+
+ // The IE is decoded now. The buffer index should be pointing to the
+ // IE Boundary. If not, we have some more data left for the IE which we don't know
+ // how to decode
+ if (ieBoundary == buffer.getCurrentIndex())
+ {
+ return true;
+ }
+ else
+ {
+ errorStream.add((char *)"Unable to decode IE [% tempdata.className %]\n");
+ return false;
+ }
+}
+void [% tempdata.className %]::display[% tempdata.className %]_v([% tempdata.className %]Data const &data, Debug &stream)
+{
+ stream.incrIndent();
+ stream.add((char *)"[% tempdata.className %]Data:");
+ stream.incrIndent();
+ stream.endOfLine();
+[% FOREACH Item IN tempdata.sequence -%]
+[% IF Item.skipType != "y" -%]
+
+[% IF Item.presence == "optional" -%]
+ if (data.[% Item.fieldName %]Present)
+ {
+[% IF Item.encodeConditional == "y" -%]
+ if ([% Item.encodeCondition %])
+ {
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ stream.add((char *) "[% Item.fieldName %]: ");
+ stream.add((Uint8)data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% ELSE -%]
+ stream.add((char *)"[% Item.fieldName %]: ");
+ stream.add(data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% END -%]
+[% ELSE -%]
+ stream.add((char *)"[% Item.fieldName %]:");
+ stream.endOfLine();
+ DataTypeCodecUtils::display[% Item.fieldType %]_v(data.[% Item.fieldName %], stream);
+[% END -%]
+ }
+ }
+[% ELSE -%]
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ stream.add((char *) "[% Item.fieldName %]: ");
+ stream.add((Uint8)data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% ELSE -%]
+ stream.add((char *)"[% Item.fieldName %]: ");
+ stream.add(data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% END -%]
+[% ELSE -%]
+ stream.add((char *)"[% Item.fieldName %]:");
+ stream.endOfLine();
+ DataTypeCodecUtils::display[% Item.fieldType %]_v(data.[% Item.fieldName %], stream);
+[% END -%]
+ }
+[% END -%]
+[% ELSE -%]
+[% IF Item.encodeConditional == "y" -%]
+ if ([% Item.encodeCondition %])
+ {
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ stream.add( (char *)"[% Item.fieldName %]: ");
+ stream.add((Uint8)data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% ELSE -%]
+ stream.add((char *)"[% Item.fieldName %]: ");
+ stream.add(data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% END -%]
+[% ELSE -%]
+ stream.add((char *)"[% Item.fieldName %]:");
+ stream.endOfLine();
+ DataTypeCodecUtils::display[% Item.fieldType %]_v(data.[% Item.fieldName %], stream);
+[% END -%]
+ }
+[% ELSE -%]
+[% IF Item.leafType == "y" -%]
+[% IF Item.bitField == "y" -%]
+ stream.add( (char *)"[% Item.fieldName %]: ");
+ stream.add((Uint8)data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% ELSE -%]
+ stream.add((char *)"[% Item.fieldName %]: ");
+ stream.add(data.[% Item.fieldName %]);
+ stream.endOfLine();
+[% END -%]
+[% ELSE -%]
+ stream.add((char *)"[% Item.fieldName %]:");
+ stream.endOfLine();
+ DataTypeCodecUtils::display[% Item.fieldType %]_v(data.[% Item.fieldName %], stream);
+[% END -%]
+[% END -%]
+[% END -%]
+[% END -%]
+[% END -%]
+ stream.decrIndent();
+ stream.decrIndent();
+}
diff --git a/scripts/GtpV2StackCodeGen/tts/ietemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/ietemplate.h.tt
new file mode 100644
index 0000000..0dafcd2
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/ietemplate.h.tt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/ietemplate.h.tt>
+ ******************************************************************************/
+#ifndef [% tempdata.classNameUC %]_H_
+#define [% tempdata.classNameUC %]_H_
+
+#include "manual/gtpV2Ie.h"
+
+
+
+class [% tempdata.className %]: public GtpV2Ie {
+public:
+ [% tempdata.className %]();
+ virtual ~[% tempdata.className %]();
+
+ bool encode[% tempdata.className %](MsgBuffer &buffer,
+ [% tempdata.className %]Data const &data);
+ bool decode[% tempdata.className %](MsgBuffer &buffer,
+ [% tempdata.className %]Data &data, Uint16 length);
+ void display[% tempdata.className %]_v([% tempdata.className %]Data const &data,
+ Debug &stream);
+};
+
+#endif /* [% tempdata.classNameUC %]_H_ */
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/makefiletemplate.tt b/scripts/GtpV2StackCodeGen/tts/makefiletemplate.tt
new file mode 100644
index 0000000..63e4c88
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/makefiletemplate.tt
@@ -0,0 +1,51 @@
+#
+# Copyright 2019-present, Infosys Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+include ../../Makefile.common
+
+gtpV2CodecOBJDIR := $(OBJDIR)/gtpV2Codec/
+
+gtpV2CodecLIB := $(LIBDIR)/libgtpV2Codec.so
+
+[% FOREACH lib IN makefiledata.libList -%]
+gtpV2CodecOBJS := $(addprefix $(gtpV2CodecOBJDIR), \
+[% FOREACH file IN lib.fileList -%]
+ [% file.objFile -%] \
+[% END -%]
+ ieClasses/manual/dataTypeCodecUtils_manual.o \
+ gtpV2StackWrappers.o )
+[% END -%]
+all : $(gtpV2CodecLIB)
+
+.PHONY : all
+
+$(gtpV2CodecLIB) : $(gtpV2CodecOBJS)
+ mkdir -p $(LIBDIR)
+ $(CC) $(CFLAGS) -shared -o $(gtpV2CodecLIB) $(gtpV2CodecOBJS)
+
+$(gtpV2CodecOBJS) : $(OBJDIR)/gtpV2Codec/%.o : %.cpp
+ echo "$@ from $< "
+ mkdir -p $(gtpV2CodecOBJDIR)/ieClasses/manual
+ mkdir -p $(gtpV2CodecOBJDIR)/msgClasses/manual
+ $(CC) $(CFLAGS) $(INC_DIRS) -fPIC -c $< -o $@
+
+install:
+ mkdir -p $(TOPDIR)/target/lib
+ cp -rf $(gtpV2CodecLIB) $(TOPDIR)/target/lib
+
+clean :
+ rm -rf $(gtpV2CodecLIB)
+ rm -rf $(gtpV2CodecOBJDIR)
+
+.PHONY : clean
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/msgDataTypetemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/msgDataTypetemplate.h.tt
new file mode 100644
index 0000000..0bccf65
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/msgDataTypetemplate.h.tt
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/msgDataTypetemplate.h.tt>
+ ******************************************************************************/
+#ifndef GTPV2MSGDATATYPES_H_
+#define GTPV2MSGDATATYPES_H_
+
+#include "../../gtpV2Codec/ieClasses/gtpV2GrpIeDataTypes.h"
+#include "../../gtpV2Codec/ieClasses/gtpV2IeDataTypes.h"
+
+typedef struct
+{
+ Uint8 msgType;
+ Uint16 msgLength;
+ bool teidPresent;
+ Uint32 teid;
+ Uint32 sequenceNumber;
+}GtpV2MessageHeader;
+
+[% FOREACH msg IN tempdata.msgList -%]
+typedef struct
+{
+[% FOREACH ieData IN msg.ieDetails -%]
+[% IF ieData.iePresence != 'M' -%][% IF ieData.ieCardinality == 1 -%]
+ bool [% ieData.ieVarName %]IePresent;
+[% END -%][% END -%]
+[% END -%]
+
+
+[% FOREACH ieData IN msg.ieDetails -%]
+[% IF ieData.ieCardinality != 1 -%]
+
+ Uint16 [% ieData.ieVarName %]Count;
+[% END -%]
+[% IF ieData.grouped == 'Yes'-%]
+[% IF ieData.ieCardinality != 1 -%]
+ [% ieData.grpIeInstClassName%]Data [% ieData.ieVarName%][[%ieData.ieCardinality%]];
+[% ELSE -%]
+ [% ieData.grpIeInstClassName%]Data [% ieData.ieVarName%];
+[% END -%]
+[% ELSE -%]
+ [% ieData.ieType%]IeData [% ieData.ieVarName%];
+[% END -%]
+[% END -%]
+}[% msg.msgDataName %];
+
+[% END -%]
+
+//Ie Type Constants
+[% FOREACH msg IN tempdata.msgTypeList -%]
+static const Uint8 [% msg.msgDataType %] = [% msg.msgValue %];
+[% END -%]
+
+
+#endif
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/msgDecode.tt b/scripts/GtpV2StackCodeGen/tts/msgDecode.tt
new file mode 100644
index 0000000..bd96798
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/msgDecode.tt
@@ -0,0 +1,27 @@
+[% IF ieTypeData.ieCardinality == 1 -%][% IF ieTypeData.grouped == "Yes" -%]
+ [% ieTypeData.grpIeInstClassName %] groupedIeInstance =
+ dynamic_cast<
+ [% ieTypeData.grpIeInstClassName %]&>(ieObject.getGroupedIe(msgType, [% ieTypeData.instance %]));
+ rc = groupedIeInstance.decode[% ieTypeData.grpIeInstClassName %](buffer, data.[% ieTypeData.ieVarName %], ieHeader.length);
+[% ELSE -%]
+ rc = ieObject.decode[% ieTypeData.ieType %]Ie(buffer, data.[% ieTypeData.ieVarName %], ieHeader.length);
+[% END -%]
+[% ELSE -%]
+ // First check if we have enough space left to decode and store this instance
+ if (data.[% ieTypeData.ieVarName %]Count == [% ieTypeData.ieCardinality %])
+ {
+ errorStream.add((char *)"More than [% ieTypeData.ieCardinality %] instances of [% ieTypeData.ieVarName %] received\n");
+ return false;
+ }
+[% IF ieTypeData.grouped == "Yes" -%]
+ [% ieTypeData.grpIeInstClassName %] groupedIeInstance =
+ dynamic_cast<
+ [% ieTypeData.grpIeInstClassName %]&>(ieObject.getGroupedIe(msgType, [% ieTypeData.instance %]));
+ rc = groupedIeInstance.decode[% ieTypeData.grpIeInstClassName %](buffer,
+ data.[% ieTypeData.ieVarName %][data.[% ieTypeData.ieVarName %]Count], ieHeader.length);
+ data.[% ieTypeData.ieVarName %]Count++; // TODO Count validation
+[% ELSE -%]
+ rc = ieObject.decode[% ieTypeData.ieType %]Ie(buffer, data.[% ieTypeData.ieVarName %][[% ieTypeData.ieVarName %]Count], ieHeader.length);
+ data.[% ieTypeData.ieVarName %]Count++; // TODO Count validation
+[% END -%]
+[% END -%]
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/msgEncode.tt b/scripts/GtpV2StackCodeGen/tts/msgEncode.tt
new file mode 100644
index 0000000..b1dcd54
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/msgEncode.tt
@@ -0,0 +1,63 @@
+[% IF ieData.ieCardinality == 1 -%]
+
+ // Encode the Ie Header
+ header.ieType = [% ieData.ieType %]IeType;
+ header.instance = [% ieData.instance %];
+ header.length = 0; // We will encode the IE first and then update the length
+ GtpV2Ie::encodeGtpV2IeHeader(buffer, header);
+ startIndex = buffer.getCurrentIndex();
+ [% ieData.ieType %]Ie [% ieData.ieLocalVar %]=
+ dynamic_cast<
+ [% ieData.ieType %]Ie&>(GtpV2IeFactory::getInstance().getIeObject([% ieData.ieType %]IeType));
+[% IF ieData.grouped == 'Yes'-%]
+ [% ieData.grpIeInstClassName %] groupedIeInstance =
+ dynamic_cast<
+ [% ieData.grpIeInstClassName %]&>([% ieData.ieLocalVar %].getGroupedIe(msgType, [% ieData.instance %]));
+ rc = groupedIeInstance.encode[% ieData.grpIeInstClassName %](buffer, data.[% ieData.ieVarName %]);
+[% ELSE -%]
+ rc = [% ieData.ieLocalVar %].encode[% ieData.ieType %]Ie(buffer, data.[% ieData.ieVarName %]);
+[% END -%]
+ endIndex = buffer.getCurrentIndex();
+ length = endIndex - startIndex;
+
+ // encode the length value now
+ buffer.goToIndex(startIndex - 3);
+ buffer.writeUint16(length, false);
+ buffer.goToIndex(endIndex);
+[% ELSE -%]
+ // First validate if the applicatoin provided more than the expected cardinality
+ if (data.[% ieData.ieVarName %]Count > [% ieData.ieCardinality %])
+ {
+ errorStream.add((char *)"Number of entries of [% ieData.ieVarName %] exceeded\n");
+ errorStream.add((char *)"Expected count: [% ieData.ieCardinality %] Received count: ");
+ errorStream.add((char *)"data.[% ieData.ieVarName %]Count");
+ errorStream.endOfLine();
+ return false;
+ }
+ for (Uint8 i = 0; i < data.[% ieData.ieVarName %]Count; i++)
+ {
+ // Encode the Ie Header
+ header.ieType = [% ieData.ieType %]IeType;
+ header.instance = [% ieData.instance %];
+ header.length = 0; // We will encode the IE first and then update the length
+ GtpV2Ie::encodeGtpV2IeHeader(buffer, header);
+ startIndex = buffer.getCurrentIndex();
+ [% ieData.ieType %]Ie [% ieData.ieLocalVar %]=
+ dynamic_cast<
+ [% ieData.ieType %]Ie&>(GtpV2IeFactory::getInstance().
+ getIeObject([% ieData.ieType %]IeType));
+[% IF ieData.grouped == 'Yes'-%]
+ [% ieData.grpIeInstClassName %] groupedIeInstance = dynamic_cast<[% ieData.grpIeInstClassName %]&>([% ieData.ieLocalVar %].getGroupedIe(msgType, [% ieData.instance %]));
+ rc = groupedIeInstance.encode[% ieData.grpIeInstClassName %](buffer, data.[% ieData.ieVarName %][i]);
+[% ELSE -%]
+ rc = [% ieData.ieLocalVar %].encode[% ieData.ieType %]Ie(buffer, data.[% ieData.ieVarName %][i]);
+[% END -%]
+ endIndex = buffer.getCurrentIndex();
+ length = endIndex - startIndex;
+
+ // encode the length value now
+ buffer.goToIndex(startIndex - 3);
+ buffer.writeUint16(length, false);
+ buffer.goToIndex(endIndex);
+ }
+[% END -%]
diff --git a/scripts/GtpV2StackCodeGen/tts/msgfactorytemplate.cpp.tt b/scripts/GtpV2StackCodeGen/tts/msgfactorytemplate.cpp.tt
new file mode 100644
index 0000000..d21197e
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/msgfactorytemplate.cpp.tt
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019-present Infosys Limited
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/msgfactorytemplate.cpp.tt>
+ ******************************************************************************/
+
+#include "gtpV2MsgFactory.h"
+[% FOREACH msg IN tempdata.msgList -%]
+#include "[% msg.msgFileName %].h"
+[% END -%]
+
+static GtpV2MsgFactory gtpV2MsgFactory;
+
+GtpV2MsgFactory::GtpV2MsgFactory()
+{
+ //Create Message Objects
+
+[% FOREACH msg IN tempdata.msgList -%]
+ [% msg.className %]* [% msg.msgFileName %]_p = new ([% msg.className %]);
+ msgObjectContainer.insert(std::pair<Uint8, GtpV2Message*>([% msg.className %]Type, [% msg.msgFileName %]_p));
+
+[% END -%]
+
+}
+
+GtpV2MsgFactory::~GtpV2MsgFactory() {
+ // TODO clean up the allocated memory for message objects
+}
+
+GtpV2MsgFactory& GtpV2MsgFactory::getInstance()
+{
+ static GtpV2MsgFactory gtpV2MsgFactory;
+ return gtpV2MsgFactory;
+}
+
+GtpV2Message& GtpV2MsgFactory::getMsgObject(Uint8 msgType)
+{
+ std::map<Uint8, GtpV2Message*>::iterator it;
+ it = msgObjectContainer.find(msgType);
+ return *(it->second);
+}
diff --git a/scripts/GtpV2StackCodeGen/tts/msgfactorytemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/msgfactorytemplate.h.tt
new file mode 100644
index 0000000..e2546b2
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/msgfactorytemplate.h.tt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/msgfactorytemplate.h.tt>
+ ******************************************************************************/
+#ifndef GTPV2MSGFACTORY_H_
+#define GTPV2MSGFACTORY_H_
+
+#include <map>
+#include "manual/gtpV2Message.h"
+
+class GtpV2MsgFactory {
+public:
+ GtpV2MsgFactory();
+ virtual ~GtpV2MsgFactory();
+
+ static GtpV2MsgFactory& getInstance();
+ GtpV2Message& getMsgObject(Uint8 msgType);
+
+private:
+
+ map<Uint8, GtpV2Message*> msgObjectContainer;
+
+};
+
+
+#endif /* GTPV2MSGFACTORY_H_ */
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/msgtemplate.cpp.tt b/scripts/GtpV2StackCodeGen/tts/msgtemplate.cpp.tt
new file mode 100644
index 0000000..ceef7ae
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/msgtemplate.cpp.tt
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2019-present Infosys Limited
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/msgtemplate.cpp.tt>
+ ******************************************************************************/
+
+#include "[% tempdata.fileName %].h"
+#include "../ieClasses/manual/gtpV2Ie.h"
+#include "../ieClasses/gtpV2IeFactory.h"
+[% FOREACH ieData IN tempdata.ieList -%]
+#include "../ieClasses/[% ieData.ieFileName %].h"
+[% IF ieData.grouped == 'Yes'-%]
+#include "../ieClasses/[% ieData.grpIeInstFileName %].h"
+[% END -%]
+[% END -%]
+
+[% tempdata.msgClassName %]::[% tempdata.msgClassName %]()
+{
+ msgType = [% tempdata.msgClassName %]Type;
+[% PROCESS MandIeList %]
+}
+
+[% tempdata.msgClassName %]::~[% tempdata.msgClassName %]()
+{
+
+}
+
+bool [% tempdata.msgClassName %]::encode[% tempdata.msgClassName %](MsgBuffer &buffer,
+ [% tempdata.msgClassName %]Data
+ const &data)
+{
+ bool rc = false;
+ GtpV2IeHeader header;
+ Uint16 startIndex = 0;
+ Uint16 endIndex = 0;
+ Uint16 length = 0;
+[% FOREACH ieData IN tempdata.ieList -%]
+
+[% IF ieData.iePresence != 'M' -%][% IF ieData.ieCardinality == 1 -%]
+ if (data.[% ieData.ieVarName %]IePresent)
+ {
+ [% INCLUDE tts/msgEncode.tt FILTER indent%]
+ if (!(rc))
+ {
+ errorStream.add((char *)"Failed to encode IE: [% ieData.ieVarName %]\n");
+ return false;
+ }
+ }
+[% ELSE -%]
+ [% INCLUDE tts/msgEncode.tt %]
+ if (!(rc))
+ {
+ errorStream.add((char *)"Failed to encode IE: [% ieData.ieVarName %]\n");
+ return false;
+ }
+[% END -%]
+[% ELSE -%]
+ [% INCLUDE tts/msgEncode.tt %]
+ if (!(rc))
+ {
+ errorStream.add((char *)"Failed to encode IE: [% ieData.ieVarName %]\n");
+ return false;
+ }
+[% END -%]
+[% END -%]
+ return rc;
+
+}
+
+bool [% tempdata.msgClassName %]::decode[% tempdata.msgClassName %](MsgBuffer &buffer,
+ [% tempdata.msgClassName %]Data
+ &data, Uint16 length)
+{
+
+ bool rc = false;
+ GtpV2IeHeader ieHeader;
+
+ set<Uint16> mandatoryIeLocalList = mandatoryIeSet;
+ while (buffer.lengthLeft() > IE_HEADER_SIZE)
+ {
+ GtpV2Ie::decodeGtpV2IeHeader(buffer, ieHeader);
+ if (ieHeader.length > buffer.lengthLeft())
+ {
+ // We do not have enough bytes left in the message for this IE
+ errorStream.add((char *)"IE Length exceeds beyond message boundary\n");
+ errorStream.add((char *)" Offending IE Type: ");
+ errorStream.add(ieHeader.ieType);
+ errorStream.add((char *)"\n Ie Length in Header: ");
+ errorStream.add(ieHeader.length);
+ errorStream.add((char *)"\n Bytes left in message: ");
+ errorStream.add(buffer.lengthLeft());
+ errorStream.endOfLine();
+ return false;
+ }
+
+ switch (ieHeader.ieType){
+[% FOREACH ieTypeEntry IN tempdata.ieTypeList -%]
+
+ case [% ieTypeEntry %]IeType:
+ {
+ [% ieTypeEntry %]Ie ieObject =
+ dynamic_cast<
+ [% ieTypeEntry %]Ie&>(GtpV2IeFactory::getInstance().getIeObject([% ieTypeEntry %]IeType));
+[% SET first = 1 -%]
+[% FOREACH ieTypeData IN tempdata.ieList -%]
+[% IF ieTypeData.ieType == ieTypeEntry -%]
+[% IF first == 1 -%]
+[% SET first = 0 %]
+ if(ieHeader.instance == [% ieTypeData.instance %])
+[% ELSE -%]
+ else if(ieHeader.instance == [% ieTypeData.instance %])
+[% END -%]
+ {
+[% INCLUDE tts/msgDecode.tt %]
+[% IF ieTypeData.ieCardinality == 1 -%][% IF ieTypeData.iePresence != "M" -%]
+ data.[% ieTypeData.ieVarName %]IePresent = true;
+[% END -%][% END -%]
+ if (!(rc))
+ {
+ errorStream.add((char *)"Failed to decode IE: [% ieTypeData.ieVarName %]\n");
+ return false;
+ }
+ }
+[% END %][% END %]
+ else
+ {
+ // Unknown IE instance print error
+ errorStream.add((char *)"Unknown IE Type: ");
+ errorStream.add(ieHeader.ieType);
+ errorStream.endOfLine();
+ buffer.skipBytes(ieHeader.length);
+ }
+ break;
+ }
+[% END %]
+ default:
+ {
+ // Unknown IE print error
+ errorStream.add((char *)"Unknown IE Type: ");
+ errorStream.add(ieHeader.ieType);
+ errorStream.endOfLine();
+ buffer.skipBytes(ieHeader.length);
+ }
+ }
+ }
+ return rc; // TODO validations
+}
+
+void [% tempdata.msgClassName %]::
+display[% tempdata.msgClassName %]Data_v([% tempdata.msgClassName %]Data const &data, Debug &stream)
+{
+ stream.incrIndent();
+ stream.add((char *)"[% tempdata.msgClassName %]:");
+ stream.endOfLine();
+ stream.incrIndent();
+
+ [%- flag = 0 -%]
+
+
+[% FOREACH ieData IN tempdata.ieList -%]
+[% IF ieData.ieCardinality != 1 -%]
+[%- IF flag == 0 %]
+ Uint8 displayCount;
+
+[%- flag = 1 %]
+[% END -%][% END -%]
+[% IF ieData.iePresence != 'M' -%][% IF ieData.ieCardinality == 1 -%]
+ if (data.[% ieData.ieVarName %]IePresent)
+ {
+
+
+ stream.add((char *)"IE - [% ieData.ieVarName %]:");
+ stream.endOfLine();
+ [% ieData.ieType %]Ie [% ieData.ieLocalVar %]=
+ dynamic_cast<
+ [% ieData.ieType %]Ie&>(GtpV2IeFactory::getInstance().getIeObject([% ieData.ieType %]IeType));
+ [% PROCESS ieDisplay_grp %]
+ }
+[% ELSE -%]
+ displayCount = data.[% ieData.ieVarName %]Count;
+ if (displayCount > [% ieData.ieCardinality %])
+ {
+ stream.add((char *)"Invalid data more than [% ieData.ieCardinality %] instances");
+ stream.endOfLine();
+ stream.add((char *)"Displaying only [% ieData.ieCardinality %]");
+ stream.endOfLine();
+ displayCount = [% ieData.ieCardinality %];
+ }
+ for (Uint8 i = 0; i < displayCount; i++)
+ {
+ stream.add((char *)"IE - [% ieData.ieVarName %]:");
+ stream.endOfLine();
+ [% ieData.ieType %]Ie [% ieData.ieLocalVar %]=
+ dynamic_cast<
+ [% ieData.ieType %]Ie&>(GtpV2IeFactory::getInstance().getIeObject([% ieData.ieType %]IeType));
+ [% PROCESS ieDisplay_grp -%]
+ }
+
+
+
+
+[% END -%]
+[% ELSE -%]
+[% IF ieData.ieCardinality == 1 -%]
+ stream.add((char *)"IE - [% ieData.ieVarName %]:");
+ stream.endOfLine();
+ [% ieData.ieType %]Ie [% ieData.ieLocalVar %]=
+ dynamic_cast<
+ [% ieData.ieType %]Ie&>(GtpV2IeFactory::getInstance().getIeObject([% ieData.ieType %]IeType));
+ [% PROCESS ieDisplay_grp %]
+[% ELSE -%]
+ displayCount = data.[% ieData.ieVarName %]Count;
+ if (displayCount > [% ieData.ieCardinality %])
+ {
+ stream.add((char *)"Invalid data more than [% ieData.ieCardinality %] instances");
+ stream.endOfLine();
+ stream.add((char *)"Displaying only [% ieData.ieCardinality %]");
+ stream.endOfLine();
+ displayCount = [% ieData.ieCardinality %];
+ }
+ for (Uint8 i = 0; i < displayCount; i++)
+ {
+ stream.add((char *)"IE - [% ieData.ieVarName %]:");
+ stream.endOfLine();
+ [% ieData.ieType %]Ie [% ieData.ieLocalVar %]=
+ dynamic_cast<
+ [% ieData.ieType %]Ie&>(GtpV2IeFactory::getInstance().getIeObject([% ieData.ieType %]IeType));
+[% PROCESS ieDisplay_grp %]
+ }
+[% END -%]
+[% END -%]
+[% END -%]
+
+ stream.decrIndent();
+ stream.decrIndent();
+}
+
+[% BLOCK ieDisplay_grp -%]
+[% IF ieData.grouped == "Yes" -%]
+ [% ieData.grpIeInstClassName %] groupedIeInstance =
+ dynamic_cast<
+ [% ieData.grpIeInstClassName %]&>([% ieData.ieLocalVar %].getGroupedIe(msgType, [% ieData.instance %]));
+ groupedIeInstance.display[% ieData.grpIeInstClassName %]Data_v(data.[% ieData.ieVarName %][% PROCESS cardinalIndex %], stream);
+[% ELSE -%]
+ [% ieData.ieLocalVar %].display[% ieData.ieType %]Ie_v(data.[% ieData.ieVarName %][% PROCESS cardinalIndex %], stream);
+[% END -%]
+[% END -%]
+
+[% BLOCK cardinalIndex -%]
+[% IF ieData.ieCardinality != 1 %][i][% END -%]
+[% END -%]
+[% BLOCK MandIeList -%]
+[% SET first = 1 -%]
+[% FOREACH ieData IN tempdata.ieList -%]
+[% IF ieData.iePresence == 'M' -%]
+[% IF first == 1 -%]
+ Uint16 mandIe;
+[% SET first = 0 -%]
+[% END -%]
+ mandIe = [% ieData.ieType %]IeType;
+ mandIe = (mandIe << 8) | [% ieData.instance %]; // [% ieData.ieVarName %]
+ mandatoryIeSet.insert(mandIe);
+[%- END -%]
+[% END -%]
+[% END -%]
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/msgtemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/msgtemplate.h.tt
new file mode 100644
index 0000000..949d03f
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/msgtemplate.h.tt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/msgtemplate.h.tt>
+ ******************************************************************************/
+#ifndef [% tempdata.classNameUC %]_H_
+#define [% tempdata.classNameUC %]_H_
+
+#include <set>
+#include "manual/gtpV2Message.h"
+#include <msgBuffer.h>
+#include <debug.h>
+#include "gtpV2MsgDataTypes.h"
+
+
+class [% tempdata.msgClassName %]:public GtpV2Message
+{
+public:
+ [% tempdata.msgClassName %]();
+ virtual ~[% tempdata.msgClassName %]();
+ bool encode[% tempdata.msgClassName %](MsgBuffer &buffer, [% tempdata.msgClassName %]Data const &data);
+
+ bool decode[% tempdata.msgClassName %] (MsgBuffer &buffer, [% tempdata.msgClassName %]Data& data, Uint16 length);
+
+ void display[% tempdata.msgClassName %]Data_v([% tempdata.msgClassName %]Data const &data, Debug &stream);
+
+private:
+ set <Uint16> mandatoryIeSet;
+};
+
+#endif
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/tts/stacktemplate.cpp.tt b/scripts/GtpV2StackCodeGen/tts/stacktemplate.cpp.tt
new file mode 100644
index 0000000..a9d511c
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/stacktemplate.cpp.tt
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2019-present Infosys Limited
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/stacktemplate.cpp.tt>
+ ******************************************************************************/
+#include <cstring>
+#include <stdint.h>
+#include "gtpV2Stack.h"
+#include "msgClasses/gtpV2MsgFactory.h"
+#include "msgClasses/manual/gtpV2Message.h"
+[% FOREACH msg IN tempdata.msgList -%]
+#include "msgClasses/[% msg.msgFileName %].h"
+[% END -%]
+
+cmn::utils::Debug errorStream;
+
+GtpV2Stack::GtpV2Stack ()
+{
+ // TODO Auto-generated constructor stub
+
+}
+
+GtpV2Stack::~GtpV2Stack ()
+{
+ // TODO Auto-generated destructor stub
+}
+
+bool
+GtpV2Stack::encodeMessage (GtpV2MessageHeader & msgHeader,
+ MsgBuffer & buffer, void *data_p)
+{
+
+ //Clear the global errorStream
+ errorStream.clearStream ();
+ bool rc = false;
+ GtpV2Message & msg =
+ GtpV2MsgFactory::getInstance ().getMsgObject (msgHeader.msgType);
+
+ uint16_t gtpHeaderStartIdx = buffer.getCurrentIndex();
+ // Encode the header
+ GtpV2Message::encodeHeader (buffer, msgHeader);
+
+ Uint16 startIndex = buffer.getCurrentIndex();
+
+ switch (msgHeader.msgType)
+ {
+[% FOREACH msg IN tempdata.msgList -%]
+ case [% msg.className %]Type:
+ {
+ if (data_p != NULL)
+ {
+ rc =
+ dynamic_cast<
+ [% msg.className %] & >(msg).
+ encode[% msg.className %](buffer,
+ *(([% msg.className %]Data *)
+ data_p));
+ }
+ else
+ {
+ // Application has filled the data structure provided by the stack
+ rc =
+ dynamic_cast<
+ [% msg.className %] & >(msg).
+ encode[% msg.className %] (buffer,
+ [% msg.dataMember %]);
+ }
+ break;
+ }
+[% END -%]
+ }
+
+ Uint16 endIndex = buffer.getCurrentIndex ();
+
+ Uint16 messageLength = (endIndex - startIndex)+8;
+
+ buffer.goToIndex (gtpHeaderStartIdx + 2); // 2 is where length is encoded in a gtp message TODO remove hardcoding
+ buffer.writeUint16 (messageLength, false);
+ buffer.goToIndex (endIndex);
+ return rc;
+}
+
+bool
+GtpV2Stack::decodeGtpMessageHeader(GtpV2MessageHeader& msgHeader, MsgBuffer& buffer)
+{
+ return GtpV2Message::decodeHeader (buffer, msgHeader);
+}
+
+
+bool
+GtpV2Stack::decodeMessage (GtpV2MessageHeader& msgHeader,
+ MsgBuffer& buffer,void* data_p)
+{
+ errorStream.clearStream();
+ // First decode the message header
+ bool rc = false;
+
+
+
+ Uint16 msgDataLength = msgHeader.msgLength;
+
+ if (msgHeader.teidPresent)
+ {
+ msgDataLength = msgDataLength - 8; //teid and sequence number
+ }
+ else
+ {
+ msgDataLength = msgDataLength - 4; //only sequence number
+ }
+
+ // Validate the length before proceeding
+ if (msgDataLength != buffer.lengthLeft() )
+ {
+ // Encoded message length does not match the number of bytes left in the message
+ errorStream.add ((char *)"Message length does not match bytes in buffer\n");
+ errorStream.add ((char *)"Computed Message length: ");
+ errorStream.add (msgDataLength);
+ errorStream.add ((char *)" Bytes Left in buffer: ");
+ errorStream.add (buffer.lengthLeft());
+ errorStream.endOfLine ();
+ return false;
+ }
+
+ GtpV2Message& msg =
+ GtpV2MsgFactory::getInstance ().getMsgObject (msgHeader.msgType);
+
+ switch (msgHeader.msgType){
+[% FOREACH msg IN tempdata.msgList -%]
+ case [% msg.className %]Type:
+ {
+ if (data_p != NULL)
+ {
+ rc =
+ dynamic_cast<
+ [% msg.className %] & >(msg).
+ decode[% msg.className %](buffer,
+ *([% msg.className %]Data*)
+ data_p, msgDataLength);
+ }
+ else
+ {
+ // Application wants to use the data structure provided by the stack
+ // let us first clear any data present in the internal data structure
+ memset (&[% msg.dataMember %], 0,
+ sizeof ([% msg.className %]Data));
+ rc =
+ dynamic_cast<
+ [% msg.className %] & >(msg).
+ decode[% msg.className %](buffer,
+ [% msg.dataMember %],
+ msgDataLength);
+ }
+ break;
+ }
+[% END -%]
+ }
+ return rc;
+}
+
+void
+GtpV2Stack::display_v(Uint8 msgType, Debug& stream, void* data_p)
+{
+ // Display the messageType
+ stream.add ((char *)"MessageType: ");
+ stream.add (msgType);
+ stream.endOfLine ();
+
+ GtpV2Message& msg = GtpV2MsgFactory::getInstance ().getMsgObject (msgType);
+
+ switch (msgType){
+[% FOREACH msg IN tempdata.msgList -%]
+ case [% msg.className %]Type:
+ {
+ stream.add ((char *)"Message: [% msg.className %]");
+ stream.endOfLine ();
+ if (data_p != NULL)
+ {
+ dynamic_cast<
+ [% msg.className %] & >(msg).
+ display[% msg.className %]Data_v (*
+ (([% msg.className %]Data*) data_p), stream);
+ }
+ else
+ {
+ // Application wants to use the data structure provided by the stack
+ dynamic_cast<
+ [% msg.className %] & >(msg).
+ display[% msg.className %]Data_v
+ ([% msg.dataMember %], stream);
+ }
+ break;
+ }
+[% END -%]
+ }
+}
diff --git a/scripts/GtpV2StackCodeGen/tts/stacktemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/stacktemplate.h.tt
new file mode 100644
index 0000000..044c57a
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/stacktemplate.h.tt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/stacktemplate.h.tt>
+ ******************************************************************************/
+#ifndef GTPV2STACK_H_
+#define GTPV2STACK_H_
+
+#include <sstream>
+#include <basicTypes.h>
+#include <msgBuffer.h>
+#include "msgClasses/gtpV2MsgDataTypes.h"
+
+class GtpV2Stack {
+public:
+ GtpV2Stack();
+ virtual ~GtpV2Stack();
+
+ // Public datastructures that hold decoded data or data to be encoded
+[% FOREACH msg IN tempdata.msgList -%]
+ [% msg.className %]Data [% msg.dataMember %];
+[% END -%]
+
+ bool encodeMessage(GtpV2MessageHeader& msgHeader, MsgBuffer& buffer,
+ void* data_p = NULL);
+ bool decodeGtpMessageHeader(GtpV2MessageHeader& msgHeader, MsgBuffer& buffer);
+ bool decodeMessage(GtpV2MessageHeader& msgHeader, MsgBuffer& buffer,
+ void* data_p = NULL);
+ void display_v(Uint8 msgType, Debug& stream, void* data_p = NULL);
+};
+
+#endif /* GTPV2STACK_H_ */
diff --git a/scripts/GtpV2StackCodeGen/tts/v2DataTypetemplate.h.tt b/scripts/GtpV2StackCodeGen/tts/v2DataTypetemplate.h.tt
new file mode 100644
index 0000000..b3d982d
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/tts/v2DataTypetemplate.h.tt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2019-present, Infosys Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /******************************************************************************
+ *
+ * This is an auto generated file.
+ * Please do not edit this file.
+ * All edits to be made through template source file
+ * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/v2DataTypetemplate.h.tt>
+ ******************************************************************************/
+#ifndef GTPV2DATATYPES_H_
+#define GTPV2DATATYPES_H_
+#include <basicTypes.h>
+
+[%- arrayDataTypesList = [] -%]
+[%- FOREACH data IN tempdata.DataTypeListAuto -%]
+ [%- FOREACH seq IN data.sequence -%]
+ [%- IF seq.skipType !='y' -%]
+ [%- FOREACH arrayItem IN tempdata.arrayTypeList -%]
+ [%- IF seq.fieldType == arrayItem.typeName -%]
+ [% arrayDataTypesList.push(arrayItem.typeName) -%]
+ [% END -%]
+ [% END -%]
+ [% END -%]
+ [% END -%]
+[% END -%]
+[%- arrayDataTypesList = arrayDataTypesList.unique -%]
+[%- FOREACH data IN tempdata.arrayTypeList -%]
+ [%- flag = 0 -%]
+ [%- FOREACH item IN arrayDataTypesList -%]
+ [%- IF item == data.typeName %]
+ [%- flag = 1 %]
+ [%- END -%]
+ [%- END -%]
+ [%- IF flag == 1 %]
+typedef struct
+{
+ Uint16 count;
+ [% data.subType %] values[[% data.arraySize %]];
+
+}[% data.typeName %];
+ [% END -%]
+[% END -%]
+
+[% FOREACH data IN tempdata.DataTypeListAuto -%]
+typedef struct
+{
+[% FOREACH seq IN data.sequence -%][% IF seq.skipType !='y' -%]
+ [% seq.fieldType %] [% seq.fieldName %];
+[% END -%][% END -%]
+}[% data.typeName %];
+
+[% END -%]
+
+[% FOREACH data IN tempdata.arrayTypeList -%]
+ [% flag = 0 -%]
+ [% FOREACH item IN arrayDataTypesList -%]
+ [% IF item == data.typeName %]
+ [% flag = 1 %]
+ [% END -%]
+ [% END -%]
+ [% IF flag == 0 %]
+typedef struct
+{
+ Uint16 count;
+ [% data.subType %] values[[% data.arraySize %]];
+
+}[% data.typeName %];
+ [% END -%]
+[% END -%]
+
+#endif
\ No newline at end of file