MME2 changes - Propped commits from openmme/paging branch. Added scripts
for code gen
Change-Id: Ie55032217232214ac8544ca76ea34335205329e4
diff --git a/scripts/GtpV2StackCodeGen/README.txt b/scripts/GtpV2StackCodeGen/README.txt
new file mode 100644
index 0000000..7958516
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/README.txt
@@ -0,0 +1,28 @@
+Requirements:
+1.Python3.6.
+2.Install the template-toolkit package.
+ a. pip3 install Template-Toolkit-Python or
+ b. git clone https://github.com/lmr/Template-Toolkit-Python, and set the path of the package in the datatypeCodeGen.py,groupedIECodeGen.py,iECodeGen.py,msgCodeGen.py,xlUtils.py script [as argument in sys.path.append]
+
+Inputs:
+ 1 Excel file with 4 spreadsheets:
+ Message Modeling ,IE Modeling,Grouped IE Modeling and DataType Modeling: Defines the message structure,IEs,Grouped IEs and Datatype of IEs for the GTP classes to be generated .
+Output:
+ 1. IE Classes .cpp and header files.
+ 2. Message Classes .cpp and header files.
+ 3. gtpV2stack .cpp and header files
+ 4. MakeFile
+
+
+Remove all existing generated Files:
+-Use below commands:
+ rm ../../src/gtpV2Codec/ieClasses/*.cpp ../../src/gtpV2Codec/ieClasses/*.h;
+ rm ../../src/gtpV2Codec/msgClasses/*.cpp ../../src/gtpV2Codec/msgClasses/*.h;
+ rm ../../src/gtpV2Codec/Makefile;
+Execution:
+-Run the below command:
+ python3 startCodeGen.py
+
+
+
+
diff --git a/scripts/GtpV2StackCodeGen/dataModel/prototypeV8.xlsx b/scripts/GtpV2StackCodeGen/dataModel/prototypeV8.xlsx
new file mode 100644
index 0000000..6b3d954
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/dataModel/prototypeV8.xlsx
Binary files differ
diff --git a/scripts/GtpV2StackCodeGen/datatypeCodeGen.py b/scripts/GtpV2StackCodeGen/datatypeCodeGen.py
new file mode 100644
index 0000000..81e48a9
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/datatypeCodeGen.py
@@ -0,0 +1,335 @@
+# Copyright 2019-present Infosys Limited
+# SPDX-License-Identifier: Apache-2.0
+
+
+import re
+from template import Template
+import os
+from xlUtils import xlUtils,wb
+dataTypeData={}
+dataTypeData['arrayTypeList']=[]
+dataTypeData['DataTypeListAuto']=[]
+class GenerateDataTypeClass():
+ def __init__( self ):
+ self.templateDataTypes()
+
+
+ def templateDataTypes(self):
+ typeDataTemplate = GenerateDataTypeClass.dataTypeParser()
+
+ templateData = dict()
+ sequenceList = []
+ dataTypeListAuto = []
+ arrayTypeInfoList = []
+ dataTypeListManual = []
+ templateData['className'] = 'DataTypeCodecUtils'
+ templateData['fileName'] = templateData['className'][0].lower()+templateData['className'][1:]
+ templateData['classNameUC'] = templateData['className'].upper()
+
+ #building the dictionary obtained to a dict 'templateData'
+ #which is the input to template process
+ for typeNames in typeDataTemplate['DataTypeList']:
+ myData = {}
+ sequenceList = []
+
+
+ myData['typeName'] = typeNames
+ for typeDetails in typeDataTemplate['typeDetails']:
+ if typeNames in typeDetails:
+ myTypeData = typeDetails[typeNames]
+
+ for varDetails in myTypeData['varDetails']:
+
+ for key,value in varDetails.items():
+ for en in myTypeData['encodeSeq']:
+
+ mEncode = re.search('encode:(\w+):',en)
+ mSkip = re.search('skip:(\d+):(\w+)',en)
+ item = dict()
+
+ if mSkip:
+ bitByte = mSkip.group(2)
+ skipValue = mSkip.group(1)
+ item['skipType'] = 'y'
+ item['bitByte'] = bitByte
+ item['skipValue'] = skipValue
+ elif mEncode:
+ varName = mEncode.group(1)
+ if key == varName:
+ item['fieldName'] = varName
+ if value['bitLength'] != 0:
+ item['bitField'] = 'y'
+ item['fieldSize'] = value['bitLength']
+ item['leafType'] = 'y'
+ else:
+ item['fieldSize'] = value['byteLength']
+ if value['decodeCondition'] != '':
+ item['decodeConditional'] = 'y'
+ item['decodeCondition'] = value['decodeCondition']
+ if value['encodeCondition'] != '':
+ item['encodeConditional'] = 'y'
+ item['encodeCondition'] = value['encodeCondition']
+ if value['presence'] == 'optional':
+ item['presence'] = 'optional'
+ item['fieldType'] = value['varType']
+ mUint = re.search('^Uint(\d+)$',value['varType'])
+ if mUint or value['varType'] == 'bool':
+
+ item['leafType'] = 'y'
+
+ else:
+ if value['lengthStr'] == 'EOI' or value['lengthStr'] == '':
+ item['length'] = 'lengthLeft'
+ else:
+ item['length'] = value['lengthStr']
+ mArrayUint = re.search('^(\w+)Array(\d+)$',value['varType'])
+ if mArrayUint :
+
+ item['arrayType'] = 'y'
+
+ item['count'] =0
+
+ if value['validation'] != '':
+
+ item['validationPresent'] = 'y'
+ item['validationRule'] = value['validation']
+
+ if item not in sequenceList and item!={}:
+ sequenceList.append(item)
+
+
+
+ for arrayLists in typeDataTemplate['ArrayTypeList']:
+ arrayTypeInfo = {}
+
+ if typeNames in arrayLists:
+
+ arrayType = arrayLists[typeNames]
+ arrayTypeInfo['typeName'] = arrayType['arrayTypeName']
+ arrayTypeInfo['subType'] = arrayType['arraySubType']
+ mArraySubType = re.search('^Uint\d+$',arrayTypeInfo['subType'])
+ if mArraySubType:
+ arrayTypeInfo['leafType'] = 'y'
+
+ arrayTypeInfoList.append(arrayTypeInfo)
+
+ for dataCodecManual in typeDataTemplate['DataTypeCodecList']:
+ if typeNames == dataCodecManual:
+ dataTypeListManual.append(myData)
+
+
+
+ if sequenceList != []:
+ myData['sequence'] = sequenceList
+ dataTypeListAuto.append(myData)
+
+
+
+ templateData['arrayTypeList'] = arrayTypeInfoList
+ templateData['DataTypeListManual'] = dataTypeListManual
+ templateData['DataTypeListAuto'] = dataTypeListAuto
+
+ GenerateDataTypeClass.generateDataType(templateData)
+ outputDir = '../../src/gtpV2Codec/ieClasses'
+ ttFileNameCpp = 'tts/datatypetemplate.cpp.tt'
+ ttFileNameH = 'tts/datatypetemplate.h.tt'
+ xlUtils.templateProcess(templateData,ttFileNameCpp,ttFileNameH,outputDir,outputDir)
+
+ #Parse the data from excel sheet 'DataType Modeling'
+ #and build to a dict 'typeData'
+ def dataTypeParser():
+
+ sheet = wb['DataType Modeling']
+ state = ''
+ typeData = {}
+ encodeSeq = []
+ varDetailList = []
+ dataTypeList = []
+ dataTypeCodecList = []
+ arrayTypeList = []
+ typeDataList = []
+ currentType = ''
+ currentDataType = ''
+ varType = ''
+ decodeCondition = ''
+ encodeCondition = ''
+ validation = ''
+ bitLength = 0
+ byteLength = 0
+ lengthStr = ''
+ presence = ''
+ dataType = {}
+
+ for i in range(1,sheet.max_row+1):
+ cell_value_B = xlUtils.getCellValue(sheet,i,'B')
+
+ # Search pattern for data definition start,end
+ mDataDefineStartCodec = re.search('DataType Definition Start:(\w+):Codec\[Manual\]\s*$',str(cell_value_B))
+ mArrayDefine = re.search('ArrayTypes Definition:([\w\d]*)Array(\d+)',str(cell_value_B))
+ mDataDefineStart = re.search('DataType Definition Start:(\w+)',str(cell_value_B))
+ mDataDefineEnd = re.search('DataType Definition End:(\w+)',str(cell_value_B))
+ if mDataDefineStartCodec:
+ currentType = mDataDefineStartCodec.group(1)
+ currentDataType = currentType
+ dataTypeCodecList.append(currentDataType)
+ typeData['DataTypeCodecList'] = dataTypeCodecList
+ dataTypeList.append(currentDataType)
+ typeData['DataTypeList'] = dataTypeList
+ continue
+
+ if mArrayDefine:
+
+ arraySubType = mArrayDefine.group(1)
+ arrayCount = mArrayDefine.group(2)
+ arrayTypeName = arraySubType + 'Array' + arrayCount
+ typeData['ArrayTypeList'] = {}
+ typeData['ArrayTypeList'][arrayTypeName] = {}
+ typeData['ArrayTypeList'][arrayTypeName]['arrayTypeName'] = arrayTypeName
+ typeData['ArrayTypeList'][arrayTypeName]['arraySubType'] = arraySubType
+ typeData['ArrayTypeList'][arrayTypeName]['arrayCount'] = arrayCount
+ arrayTypeList.append(typeData['ArrayTypeList'])
+ typeData['ArrayTypeList'] = arrayTypeList
+ dataTypeList.append(arrayTypeName)
+ typeData['DataTypeList'] = dataTypeList
+ continue
+
+ if mDataDefineStart:
+ currentType = mDataDefineStart.group(1)
+ currentDataType = currentType
+
+ state = 'StartDetected'
+ dataTypeList.append(currentDataType)
+ typeData['DataTypeList'] = dataTypeList
+ typeData['typeDetails'] = {}
+ typeData['typeDetails'][currentDataType] = {}
+ dataType = typeData['typeDetails'][currentDataType]
+ typeData['typeDetails'][currentDataType]['typeName'] = currentType
+ typeDataList.append(typeData['typeDetails'])
+ typeData['typeDetails'] = typeDataList
+
+ elif mDataDefineEnd:
+ state = 'EndDetected'
+
+ elif state == 'StartDetected':
+ encodeSeq = []
+ varDetailList = []
+ state = 'TypeDefinitionStart'
+ elif state == 'TypeDefinitionStart':
+ (byteLength,lengthStr) = xlUtils.getByteLength(sheet,i)
+
+ #for fields less than 1 bytelength
+
+ if byteLength == 0:
+ varList = []
+
+ for j in map(chr, range( ord('D'), ord('L'))):
+ field = xlUtils.getCellValue(sheet,i,j)
+ bitLength = 0
+ byteLength = 0
+ if field != None:
+
+ bitLength = xlUtils.getBitLength(sheet,i,j)
+ (varName,varType,encodeCondition,decodeCondition,validation,count) = xlUtils.extractField(field)
+
+ if varType == '':
+ varType = 'Uint8'
+ if bitLength == 8:
+ byteLength = 1
+ bitLength = 0
+ if varName != 'Spare':
+ varList.append(varName)
+
+ dataType['varDetails'] = {}
+ dataType['varDetails'][varName] = {}
+ dataType['varDetails'][varName]['varType'] = varType
+ dataType['varDetails'][varName]['decodeCondition'] = decodeCondition
+ dataType['varDetails'][varName]['encodeCondition'] = encodeCondition
+ dataType['varDetails'][varName]['validation'] = validation
+ dataType['varDetails'][varName]['bitLength'] = bitLength
+ dataType['varDetails'][varName]['byteLength'] = byteLength
+ dataType['varDetails'][varName]['lengthStr'] = lengthStr
+ dataType['varDetails'][varName]['presence'] = presence
+
+ encStrBit = 'encode:' + varName + ':' + str(bitLength) + ':Bits'
+ encodeSeq.append(encStrBit)
+ dataType['encodeSeq'] = encodeSeq
+ varDetailList.append(dataType['varDetails'])
+ dataType['varDetails'] = varDetailList
+
+
+
+
+ else:
+ skipStrBit = 'skip:'+ str(bitLength) + ':Bits'
+ encodeSeq.append(skipStrBit)
+ dataType['encodeSeq'] = encodeSeq
+
+ #for fields of length 1 byte
+ else:
+ varList = []
+
+ field = sheet.cell(row=i, column=4).value
+ (varName,varType,encodeCondition,decodeCondition,validation,count) = xlUtils.extractField(field)
+
+ if varType == '':
+ varType = xlUtils.lengthToType(byteLength)
+
+ if varName != 'Spare':
+ varList.append(varName)
+
+
+ dataType['varDetails'] = {}
+ dataType['varDetails'][varName] = {}
+ dataType['varDetails'][varName]['varType'] = varType
+ dataType['varDetails'][varName]['decodeCondition'] = decodeCondition
+ dataType['varDetails'][varName]['encodeCondition'] = encodeCondition
+ dataType['varDetails'][varName]['validation'] = validation
+ dataType['varDetails'][varName]['bitLength'] = bitLength
+ dataType['varDetails'][varName]['byteLength'] = byteLength
+ dataType['varDetails'][varName]['lengthStr'] = lengthStr
+ bitLength = 0
+ byteLength = 0
+
+ if str(cell_value_B) == 'Yes':
+ presence = 'optional'
+ dataType['varDetails'][varName]['presence'] = presence
+ varDetailList.append(dataType['varDetails'])
+ dataType['varDetails'] = varDetailList
+
+ encStrByte = 'encode:' + varName + ':' + str(byteLength) + ':Bytes'
+ encodeSeq.append(encStrByte)
+ dataType['encodeSeq'] = encodeSeq
+
+ else:
+ skipStrByte = 'skip:'+ str(byteLength) + ':Bytes'
+ encodeSeq.append(skipStrByte)
+ dataType['encodeSeq'] = encodeSeq
+
+ return typeData
+
+ def generateDataType(templateData):
+ dataTypeInfo={}
+ dataTypeData['arrayTypeList']=[]
+ for dataType in templateData['arrayTypeList']:
+ dataTypeInfo={}
+ dataTypeInfo['typeName']=dataType['typeName']
+ dataTypeInfo['subType']=dataType['subType']
+ mtypeName = re.search('^(\w+)Array(\d+)$',dataTypeInfo['typeName'])
+ if mtypeName:
+
+ dataTypeInfo['arraySize']=mtypeName.group(2)
+ dataTypeData['arrayTypeList'].append(dataTypeInfo)
+ dataTypeData['DataTypeListAuto']=templateData['DataTypeListAuto']
+
+
+ template = Template()
+ ttFileNamefactoryH = 'tts/v2DataTypetemplate.h.tt'
+ outputDir = '../../src/gtpV2Codec/ieClasses'
+
+ if not os.path.exists(outputDir):
+ os.makedirs(outputDir)
+ outputFileName = 'gtpV2DataTypes.h'
+ template.__init__({'OUTPUT' : outputFileName, 'OUTPUT_PATH' : outputDir})
+ template.process(ttFileNamefactoryH, {'tempdata' : dataTypeData})
+
+GenerateDataTypeClass()
diff --git a/scripts/GtpV2StackCodeGen/groupedIECodeGen.py b/scripts/GtpV2StackCodeGen/groupedIECodeGen.py
new file mode 100644
index 0000000..072ccc0
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/groupedIECodeGen.py
@@ -0,0 +1,271 @@
+# Copyright 2019-present Infosys Limited
+# SPDX-License-Identifier: Apache-2.0
+
+
+import re
+import os
+
+from template import Template
+from xlUtils import xlUtils,wb
+templateData = {}
+templateData['instList']=[]
+grpIeDataTypeData={}
+grpIeDataTypeData['grpList']=[]
+grpIeDataTypeData['grpTypeList']=[]
+class GenerateGrpIeClass():
+ def __init__( self ):
+
+ self.groupIEParser()
+
+ def groupIEParser(self):
+
+
+ sheet = wb['Grouped IE Modeling']
+ state = ''
+
+ data = {}
+ grpIeData = {}
+ currentGrpie = ''
+ currentMsg = ''
+ currentVar = ''
+ currentInstance = ''
+ currentInstanceValue = 0
+ grpIeList = []
+ ieDetailsList = []
+ ieList = []
+
+ for i in range(1,sheet.max_row+1):
+
+ cell_value_B = xlUtils.getCellValue(sheet,i,'B')
+
+ mGroupedIeDefStart = re.search('Grouped IE Definition Start:(\w+):(\d+):(\w+):(\w+):Instance\[(\d+)]',str(cell_value_B))
+ mGroupedIeDefEnd = re.search('Grouped IE Definition End:(\w+):(\w+)',str(cell_value_B))
+
+ if mGroupedIeDefStart:
+
+ state = 'StartDetected'
+ currentGrpie = mGroupedIeDefStart.group(1)
+ currentMsg = mGroupedIeDefStart.group(4)
+ currentVar = mGroupedIeDefStart.group(3)
+ currentInstanceValue = mGroupedIeDefStart.group(5)
+ currentInstance = currentVar + 'In' + currentMsg
+
+ if currentGrpie not in grpIeList:
+ grpIeList.append(currentGrpie)
+ data['grpIeList'] = grpIeList
+ data['grpIeDetails'] = {}
+ data['grpIeDetails'][currentGrpie] = {}
+ data['grpIeDetails'][currentGrpie]['ieTypeValue'] = mGroupedIeDefStart.group(2)
+ data['grpIeDetails'][currentGrpie]['instList'] = []
+ data['grpIeDetails'][currentGrpie]['instList'].append(currentInstance)
+ data['grpIeDetails'][currentGrpie][currentInstance] = {}
+ data['grpIeDetails'][currentGrpie][currentInstance]['instance'] = currentInstanceValue
+ grpIeData = data['grpIeDetails'][currentGrpie][currentInstance]
+ grpIeData['msgName'] = currentMsg
+
+ elif mGroupedIeDefEnd:
+ state = 'EndDetected'
+ grpIeData = {}
+ ieList = []
+ grpIeList=[]
+ ieDetailsList = []
+
+ GenerateGrpIeClass.generateGroupedIeClasses(data)
+ GenerateGrpIeClass.prepareGrpIeMakeFile()
+
+
+ elif state == 'StartDetected':
+ state = 'IeListStart'
+
+ elif state == 'IeListStart':
+
+ if xlUtils.getCellValue(sheet,i,'D') != None:
+ ieData = {}
+ ieDescription = xlUtils.getCellValue(sheet,i,'D')
+ ieData['ieDescription'] = xlUtils.getCellValue(sheet,i,'D')
+ ieData['presence'] = xlUtils.getCellValue(sheet,i,'E')
+ ieData['grouped'] = xlUtils.getCellValue(sheet,i,'B')
+ ieData['cardinality'] = xlUtils.getCellValue(sheet,i,'C')
+ ieData['instance'] = xlUtils.getCellValue(sheet,i,'H')
+
+ if ieData['cardinality'] == None:
+ ieData['cardinality'] = 1
+ ieTypeDescription = xlUtils.getCellValue(sheet,i,'G')
+ ieData['ieTypeDescription'] = ieTypeDescription
+
+ ieVarName = xlUtils.getVarNameFromString(ieDescription,0)
+
+ ieTypeName = xlUtils.getVarNameFromString(ieTypeDescription,1)
+
+ if ieData['grouped'] == 'Yes':
+ ieData['ieGroupTypeName'] = ieVarName.capitalize() + 'In' + currentMsg
+
+ ieData['ieVarName'] = ieVarName
+ ieData['ieTypeName'] = ieTypeName
+
+
+ ieList.append(ieVarName)
+ grpIeData['ieList'] = ieList
+ grpIeData['ieDetails'] = {}
+ grpIeData['ieDetails'][ieVarName] = ieData
+ ieDetailsList.append(grpIeData['ieDetails'])
+ grpIeData['ieDetails'] = ieDetailsList
+
+
+ def generateGroupedIeClasses(data):
+ parsedData = data
+
+ for grpIe in parsedData['grpIeList']:
+
+ grpIeDetails = parsedData['grpIeDetails'][grpIe]
+
+ GenerateGrpIeClass.generateGroupedIeClass(grpIeDetails,grpIe)
+ GenerateGrpIeClass.generateGroupedIeDataType(grpIeDetails, grpIe)
+ def generateGroupedIeClass(grpIeDetails,grpIe):
+
+ templateData['fileName'] = grpIe[0].lower()+grpIe[1:] + 'Ie'
+ templateData['className'] = grpIe + 'Ie'
+ templateData['classNameUC'] = templateData['fileName'].upper()
+ fileName=templateData['fileName']
+
+ for inst in grpIeDetails['instList']:
+ instanceInfo = {}
+ instDetails = grpIeDetails[inst]
+ GenerateGrpIeClass.generateGroupedIeInstanceClass(instDetails, inst)
+
+ instanceInfo['className'] = inst
+ instanceInfo['fileName'] = inst[0].lower()+inst[1:]
+ instanceInfo['msgType'] = instDetails['msgName'] + 'MsgType'
+ instanceInfo['instance'] = instDetails['instance']
+
+ if instanceInfo not in templateData['instList']:
+ templateData['instList'].append(instanceInfo)
+
+ templateData[fileName]=[inst for inst in templateData['instList'] if grpIe in inst['className']]
+
+ outputDir = '../../src/gtpV2Codec/ieClasses'
+ ttFileNameCpp = 'tts/grpietemplate.cpp.tt'
+ ttFileNameH = 'tts/grpietemplate.h.tt'
+ xlUtils.templateProcess(templateData,ttFileNameCpp,ttFileNameH,outputDir,outputDir)
+
+ objectfile ='ieClasses/' + templateData['fileName'] + '.o'
+ sourcefile = 'ieClasses/' + templateData['fileName'] + '.cpp'
+ xlUtils.addToMakeSo('gtpV2Stack.so',objectfile,sourcefile)
+
+ def generateGroupedIeDataType(grpIeDetails, grpIe):
+ grpIeInfo={}
+
+ grpIeInfo['iePresenceList']=[]
+ grpIeTypeInfo={}
+ grpIeTypeInfo['grpIeTypeName']=grpIe + 'IeType'
+ grpIeTypeInfo['grpIeTypeValue']=grpIeDetails['ieTypeValue']
+ if grpIeTypeInfo not in grpIeDataTypeData['grpTypeList']:
+ grpIeDataTypeData['grpTypeList'].append(grpIeTypeInfo)
+
+ for inst in grpIeDetails['instList']:
+
+ instDetails = grpIeDetails[inst]
+ grpIeInfo={}
+ grpIeInfo['iePresenceList']=[]
+ grpIeInfo['grpIeName']= inst+'Data'
+ grpIeInfo['ieList']=[]
+ for ieDict in instDetails['ieDetails']:
+ for ieDetails in ieDict:
+ if ieDict[ieDetails]['presence']!='M':
+ grpIeInfo['iePresenceList'].append(ieDict[ieDetails]['ieVarName']+'IePresent')
+ ieInfo={}
+ ieInfo['ieTypeName']=ieDict[ieDetails]['ieTypeName']+'IeData'
+ ieInfo['ieVarName']=ieDict[ieDetails]['ieVarName']
+ grpIeInfo['ieList'].append(ieInfo)
+
+ if grpIeInfo not in grpIeDataTypeData['grpList']:
+ grpIeDataTypeData['grpList'].append(grpIeInfo)
+ template = Template()
+ ttFileNamefactoryH = 'tts/grpIeDataTypetemplate.h.tt'
+ outputDir = '../../src/gtpV2Codec/ieClasses/'
+
+ if not os.path.exists(outputDir):
+ os.makedirs(outputDir)
+ outputFileName = 'gtpV2GrpIeDataTypes.h'
+ template.__init__({'OUTPUT' : outputFileName, 'OUTPUT_PATH' : outputDir})
+ template.process(ttFileNamefactoryH, {'tempdata' : grpIeDataTypeData})
+
+ def generateGroupedIeInstanceClass(instDetails, inst):
+ templateInstData = {}
+ ieTypeList = []
+ ieTypeDetailsList = []
+
+ ieInfoList =[]
+
+ templateInstData['fileName'] = inst[0].lower()+inst[1:]
+
+ templateInstData['msgClassName'] = inst
+ templateInstData['classNameUC'] = templateInstData['fileName'].upper()
+
+ for ieEntry in instDetails['ieList']:
+
+ ieInfo = {}
+ ieTypeInfo = {}
+
+ ies = instDetails['ieDetails']
+ for x in ies:
+
+ ie = x.get(ieEntry)
+
+ if ie != None and ieEntry == ie.get('ieVarName'):
+ ieInfo['ieName'] = ie['ieVarName']
+ ieInfo['ieVarName'] = ie['ieVarName']
+ ieInfo['ieType'] = ie['ieTypeName']
+ ieInfo['ieFileName'] = ie['ieTypeName'][0].lower()+ie['ieTypeName'][1:] + 'Ie'
+ ieInfo['ieLocalVar'] = ie['ieTypeName'][0].lower()+ie['ieTypeName'][1:]
+ ieInfo['iePresence'] = ie['presence']
+ ieInfo['ieCardinality'] = ie['cardinality']
+ ieInfo['instance'] = ie['instance']
+ ieInfo['grouped'] = ie['grouped']
+
+ ieType = ieInfo['ieType']
+
+ ieTypeInfo['ieName'] = ie['ieVarName']
+ ieTypeInfo['ieVarName'] = ie['ieVarName']
+ ieTypeInfo['ieType'] = ie['ieTypeName']
+ ieTypeInfo['ieFileName'] = ie['ieTypeName'][0].lower()+ie['ieTypeName'][1:] + 'Ie'
+ ieTypeInfo['ieLocalVar'] = ie['ieTypeName'][0].lower()+ie['ieTypeName'][1:]
+ ieTypeInfo['iePresence'] = ie['presence']
+ ieTypeInfo['ieCardinality'] = ie['cardinality']
+ ieTypeInfo['instance'] = ie['instance']
+ ieTypeInfo['grouped'] = ie['grouped']
+
+ if ieInfo['ieType'] not in ieTypeList:
+ ieTypeList.append(ieInfo['ieType'])
+ templateInstData['ieTypeList'] = ieTypeList
+
+ if ieInfo not in ieInfoList:
+
+ ieInfoList.append(ieInfo)
+ templateInstData['ieList'] = ieInfoList
+
+ templateInstData['ieTypeDetails'] = {}
+ templateInstData['ieTypeDetails'][ieType] = []
+ if ieTypeInfo not in templateInstData['ieTypeDetails'][ieType]:
+ templateInstData['ieTypeDetails'][ieType].append(ieTypeInfo)
+ ieTypeDetailsList.append(templateInstData['ieTypeDetails'])
+ templateInstData['ieTypeDetails'] = ieTypeDetailsList
+
+ GenerateGrpIeClass.templateInstanceprocess(templateInstData)
+ outputDirCpp = 'ieClasses/'
+ objectfile = outputDirCpp +templateInstData['fileName'] + '.o'
+ sourcefile = outputDirCpp + templateInstData['fileName'] + '.cpp'
+ xlUtils.addToMakeSo('gtpV2Stack.so',objectfile,sourcefile)
+
+ def templateInstanceprocess(templateInstData):
+
+ ttFileNameInstCpp = 'tts/grpieinsttemplate.cpp.tt'
+ outputDir = '../../src/gtpV2Codec/ieClasses'
+ ttFileNameInstH = 'tts/grpieinsttemplate.h.tt'
+ xlUtils.templateProcess(templateInstData,ttFileNameInstCpp,ttFileNameInstH,outputDir,outputDir)
+
+ def prepareGrpIeMakeFile():
+ outputDirCpp = 'ieClasses/manual/'
+ xlUtils.addToMakeSo("gtpV2Stack.so", outputDirCpp+'gtpV2GroupedIe.o',outputDirCpp+'gtpV2GroupedIe.cpp')
+
+GenerateGrpIeClass()
diff --git a/scripts/GtpV2StackCodeGen/iECodeGen.py b/scripts/GtpV2StackCodeGen/iECodeGen.py
new file mode 100644
index 0000000..2a90656
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/iECodeGen.py
@@ -0,0 +1,318 @@
+# Copyright 2019-present Infosys Limited
+# SPDX-License-Identifier: Apache-2.0
+
+
+import re
+import os
+from template import Template
+from xlUtils import xlUtils,wb
+
+ieFactoryData = {}
+ieFactoryData['ieList'] = []
+
+ieDataTypeData = {}
+ieDataTypeData['ieTypeList'] = []
+ieDataTypeData['ieList'] = []
+class GenerateIeClass:
+
+ def __init__( self ):
+
+ self.ieParser()
+
+ #Parse the data from excel sheet 'IE Modeling'
+ #and build to a dict 'iedata'
+ def ieParser(self):
+
+ sheet = wb['IE Modeling']
+ state = ''
+
+ encodeSeq = []
+ byteLength = 0
+ currentType = ''
+ validation = ''
+ count = ''
+ decodeCondition = ''
+ encodeCondition = ''
+ typeVal = ''
+ presence = ''
+ bitLength = 0
+ varDetailList = []
+ ieData = dict()
+ ieTypeList = []
+ lengthStr = ''
+ varType = ''
+ varName = ''
+ mType=0
+ varList=[]
+ grpIeList = []
+
+ for i in range(1,sheet.max_row+1):
+ presence = ''
+ bitLength = 0
+ byteLength = 0
+ cell_value_B = xlUtils.getCellValue(sheet,i,'B')
+ cell_value_D = xlUtils.getCellValue(sheet,i,'D')
+ cell_value_H = xlUtils.getCellValue(sheet,i,'H')
+
+ # Search pattern for IE definition start,end
+ mGroupedIe = re.search('Grouped IE Definition:(\w+)',str(cell_value_B))
+ mIeDefStart = re.search('IE Definition Start:(\w+)',str(cell_value_B))
+ mIeDefEnd = re.search('IE Definition End:(\w+)' ,str(cell_value_B))
+
+ if mGroupedIe:
+
+ grpIeName = mGroupedIe.group(1)
+ grpIeList.append(grpIeName)
+ for grpie in grpIeList:
+ self.generateIeFactory(grpie)
+
+ if mIeDefStart:
+ currentType = mIeDefStart.group(1)
+ state = 'StartDetected'
+ ieTypeList.append(currentType)
+
+ elif mIeDefEnd:
+
+ state = 'EndDetected'
+ self.templateIes(ieData,currentType)
+ self.generateIeFactory(currentType)
+ self.generateIeDataType(currentType,typeVal,varList)
+ self.prepareIeMakeFile()
+ varList = []
+
+ elif state == 'StartDetected':
+ varDetailList = []
+ encodeSeq = []
+
+ colDValue = str(cell_value_D)
+ mType = re.search('Type = (\d+)',colDValue)
+ mSpare = re.search('Spare',colDValue)
+ mInstance = re.search('Instance',str(cell_value_H))
+
+ if mType:
+ typeVal = mType.group(1)
+ ieData['ieDetails'] = {}
+ ieData['ieDetails'][currentType] = {}
+ ieData['ieDetails'][currentType]['ieName'] = currentType
+ ieData['ieDetails'][currentType]['ieTypeVal'] = typeVal
+
+ if mSpare and mInstance:
+ state = 'TypeDefinitionStart'
+
+ elif state == 'TypeDefinitionStart':
+
+ (byteLength,lengthStr) = xlUtils.getByteLength(sheet,i)
+
+ #for fields less than 1 bytelength
+ if byteLength == 0:
+
+ for j in map(chr, range( ord('D'), ord('L'))):
+ field = xlUtils.getCellValue(sheet,i,j)
+ fieldDetails=dict()
+ if field != None:
+
+ bitLength = xlUtils.getBitLength(sheet,i,j)
+ (varName,varType,encodeCondition,decodeCondition,validation,count) = xlUtils.extractField(field)
+
+ if varType == '':
+ varType = 'Uint8'
+ if bitLength == 8:
+ byteLength = 1
+ bitLength = 0
+ if varName != 'Spare':
+ fieldDetails['varName']=varName
+ fieldDetails['varType']=varType
+ fieldDetails['presence']=presence
+ varList.append(fieldDetails)
+
+ ieData['varDetails'] = {}
+ ieData['varDetails'][varName] = {}
+ ieData['varDetails'][varName]['varType'] = varType
+ ieData['varDetails'][varName]['decodeCondition'] = decodeCondition
+ ieData['varDetails'][varName]['encodeCondition'] = encodeCondition
+ ieData['varDetails'][varName]['validation'] = validation
+ ieData['varDetails'][varName]['bitLength'] = bitLength
+ ieData['varDetails'][varName]['byteLength'] = byteLength
+ ieData['varDetails'][varName]['lengthStr'] = lengthStr
+ ieData['varDetails'][varName]['presence'] = presence
+ ieData['varDetails'][varName]['count'] = count
+ varDetailList.append(ieData['varDetails'])
+ ieData['varDetails'] = varDetailList
+
+ encStrBit = 'encode:' + varName + ':' + str(bitLength) + ':Bits'
+ encodeSeq.append(encStrBit)
+ ieData['encodeSeq'] = encodeSeq
+
+ else:
+ skipStrBit = 'skip:'+ str(bitLength) + ':Bits'
+ encodeSeq.append(skipStrBit)
+ ieData['encodeSeq'] = encodeSeq
+
+ #for fields of length 1 byte
+ else:
+
+ field = sheet.cell(row=i, column=4).value
+ (varName,varType,encodeCondition,decodeCondition,validation,count) = xlUtils.extractField(field)
+ fieldDetails=dict()
+ if varType == '':
+ varType = xlUtils.lengthToType(byteLength)
+
+ if varName != 'Spare':
+ fieldDetails['varName']=varName
+ fieldDetails['varType']=varType
+ if xlUtils.getCellValue(sheet,i,'B') == 'Yes':
+ presence = 'optional'
+ fieldDetails['presence']=presence
+ varList.append(fieldDetails)
+
+ ieData['varDetails'] = {}
+ ieData['varDetails'][varName] = {}
+ ieData['varDetails'][varName]['varType'] = varType
+ ieData['varDetails'][varName]['decodeCondition'] = decodeCondition
+ ieData['varDetails'][varName]['encodeCondition'] = encodeCondition
+ ieData['varDetails'][varName]['validation'] = validation
+ ieData['varDetails'][varName]['bitLength'] = bitLength
+ ieData['varDetails'][varName]['byteLength'] = byteLength
+ ieData['varDetails'][varName]['lengthStr'] = lengthStr
+ ieData['varDetails'][varName]['count'] = count
+
+ if xlUtils.getCellValue(sheet,i,'B') == 'Yes':
+ presence = 'optional'
+
+ ieData['varDetails'][varName]['presence'] = presence
+ varDetailList.append(ieData['varDetails'])
+ ieData['varDetails'] = varDetailList
+
+ encstrbyte = 'encode:' + varName + ':' + str(byteLength) + ':Bytes'
+ encodeSeq.append(encstrbyte)
+ ieData['encodeSeq'] = encodeSeq
+ else:
+ skipstrbyte = 'skip:'+ str(byteLength) + ':Bytes'
+ encodeSeq.append(skipstrbyte)
+ ieData['encodeSeq'] = encodeSeq
+ return ieData
+
+ def templateIes(self,ieData,currentType):
+
+ templateData = dict()
+ varDetailsList = []
+ sequenceList = []
+ varDetailsList = ieData['varDetails']
+ templateData['className'] = ieData['ieDetails'][currentType]['ieName']+'Ie'
+ templateData['fileName'] = templateData['className'][0].lower() + templateData['className'][1:]
+ templateData['classNameUC'] = templateData['className'].upper()
+ templateData['ieTypeVal'] = ieData['ieDetails'][currentType]['ieTypeVal']
+
+ #building the dictionary obtained to a dict 'templateData'
+ #which is the input to template process
+
+ for en in ieData['encodeSeq']:
+ mEncode = re.search('encode:(\w+):',en)
+ mSkip = re.search('skip:(\d+):(\w+)',en)
+ item = dict()
+ if mSkip:
+ bitByte = mSkip.group(2)
+ skipValue = mSkip.group(1)
+ item['skipType'] = 'y'
+ item['bitByte'] = bitByte
+ item['skipValue'] = skipValue
+ elif mEncode:
+ varName = mEncode.group(1)
+ for variableDetails in varDetailsList:
+ for key,value in variableDetails.items():
+ if key == varName:
+ item['fieldName'] = varName
+ if value['bitLength'] != 0:
+ item['bitField'] = 'y'
+ item['fieldSize'] = value['bitLength']
+ item['leafType'] = 'y'
+ else:
+ item['fieldSize'] = value['byteLength']
+ if value['decodeCondition'] != '':
+ item['decodeConditional'] = 'y'
+ item['decodeCondition'] = value['decodeCondition']
+ if value['encodeCondition'] != '':
+ item['encodeConditional'] = 'y'
+ item['encodeCondition'] = value['encodeCondition']
+ if value.get('presence') == 'optional':
+ item['presence'] = 'optional'
+ item['fieldType'] = value['varType']
+ mUint = re.search('^Uint(\d+)$',value['varType'])
+ if mUint or value['varType'] == 'bool':
+ item['leafType'] = 'y'
+ else:
+ if value['lengthStr'] == 'EOI' or value['lengthStr'] == '':
+ item['length'] = 'lengthLeft'
+ else:
+ item['length'] = value['lengthStr']
+ if value['validation'] != '':
+
+ item['validationPresent'] = 'y'
+ item['validationRule'] = value['validation']
+ mArray = re.search('Array',value['varType'])
+ if mArray:
+ item['arrayType']='y'
+ if value['count'] =='':
+ item['count']=0
+ else:
+ item['count']=value['count']
+
+ if item != {}:
+ sequenceList.append(item)
+ templateData['sequence'] = sequenceList
+
+ outputDir = '../../src/gtpV2Codec/ieClasses'
+ ttFileNameCpp = 'tts/ietemplate.cpp.tt'
+ ttFileNameH = 'tts/ietemplate.h.tt'
+ xlUtils.templateProcess(templateData,ttFileNameCpp,ttFileNameH,outputDir,outputDir)
+
+ objectFile = 'ieClasses/' +templateData['fileName'] + '.o'
+ sourceFile ='ieClasses/' + templateData['fileName'] + '.cpp'
+ xlUtils.addToMakeSo('gtpV2Stack.so',objectFile,sourceFile)
+
+ def ieFactoryTemplate(self,ieFactoryData):
+
+ ieFactoryData['fileName']='gtpV2IeFactory'
+ ttFileNameFactoryCpp = 'tts/iefactorytemplate.cpp.tt'
+ outputDir = '../../src/gtpV2Codec/ieClasses'
+ ttFileNamefactoryH = 'tts/iefactorytemplate.h.tt'
+ xlUtils.templateProcess(ieFactoryData,ttFileNameFactoryCpp,ttFileNamefactoryH,outputDir,outputDir)
+
+ def generateIeFactory(self,currentType):
+ ieinfo = {}
+ ieinfo['className'] = currentType + 'Ie'
+ ieinfo['ieFileName'] = currentType[0].lower()+currentType[1:] + 'Ie'
+ if ieinfo not in ieFactoryData['ieList']:
+ ieFactoryData['ieList'].append(ieinfo)
+ outputDir = 'ieClasses/'
+ self.ieFactoryTemplate(ieFactoryData)
+ xlUtils.addToMakeSo('gtpV2Stack.so',outputDir+'gtpV2IeFactory.o',outputDir+'gtpV2IeFactory.cpp')
+
+ def generateIeDataType(self,currentType,typeVal,varList):
+ ieinfo = {}
+ ieTypeInfo={}
+ ieinfo['ieName'] = currentType + 'IeData'
+ ieinfo['varList'] = varList
+ ieTypeInfo['ieName']=currentType + 'IeType'
+ ieTypeInfo['value']=typeVal
+ if ieinfo not in ieDataTypeData['ieList']:
+ ieDataTypeData['ieList'].append(ieinfo)
+ if ieTypeInfo not in ieDataTypeData['ieTypeList']:
+ ieDataTypeData['ieTypeList'].append(ieTypeInfo)
+ #print(ieDataTypeData)
+ template = Template()
+ ttFileNamefactoryH = 'tts/ieDataTypetemplate.h.tt'
+ outputDir = '../../src/gtpV2Codec/ieClasses'
+
+ if not os.path.exists(outputDir):
+ os.makedirs(outputDir)
+ outputFileName = 'gtpV2IeDataTypes.h'
+ template.__init__({'OUTPUT' : outputFileName, 'OUTPUT_PATH' : outputDir})
+ template.process(ttFileNamefactoryH, {'tempdata' : ieDataTypeData})
+
+ def prepareIeMakeFile(self):
+ outputDir = 'ieClasses/'
+ xlUtils.addToMakeSo('gtpV2Stack.so', outputDir+'dataTypeCodecUtils.o', outputDir+'dataTypeCodecUtils.cpp')
+ xlUtils.addToMakeSo('gtpV2Stack.so', outputDir+'manual/gtpV2Ie.o', outputDir+'manual/gtpV2Ie.cpp')
+
+GenerateIeClass()
diff --git a/scripts/GtpV2StackCodeGen/msgCodeGen.py b/scripts/GtpV2StackCodeGen/msgCodeGen.py
new file mode 100644
index 0000000..cfa7281
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/msgCodeGen.py
@@ -0,0 +1,267 @@
+# Copyright 2019-present Infosys Limited
+# SPDX-License-Identifier: Apache-2.0
+
+
+import re
+
+import os
+from template import Template
+
+
+from xlUtils import xlUtils,wb
+msgFactoryData = {}
+msgFactoryData['msgList'] = []
+msgDataTypeData = {}
+msgDataTypeData['msgTypeList'] = []
+msgDataTypeData['msgList'] = []
+class GenerateMsgClass():
+ def __init__( self ):
+ self.msgParser()
+
+ def msgParser(self):
+
+ sheet = wb['Message Modeling']
+ state = ''
+ ieDetailList = []
+ ieList = []
+
+ currentMessage = ''
+ msgValue = 0
+ msgData = {}
+
+
+ for i in range(1,sheet.max_row+1):
+
+ cell_value_B = xlUtils.getCellValue(sheet,i,'B')
+
+ mMsgDefinitionStart = re.search('Message Definition Start:(\w+):(\d+)',str(cell_value_B))
+ mMsgDefinitionEnd = re.search('Message Definition End:(\w+)',str(cell_value_B))
+ mResponseMsg = re.search('ResponseMessage',str(cell_value_B))
+ mGrouped = re.search('Grouped',str(cell_value_B))
+
+
+ if mMsgDefinitionStart:
+
+
+ state = 'StartDetected'
+ currentMessage = mMsgDefinitionStart.group(1)
+ msgValue = mMsgDefinitionStart.group(2)
+
+
+ if mMsgDefinitionEnd:
+
+ ieList = []
+ ieDetailList = []
+ state = 'EndDetected'
+
+ GenerateMsgClass.templateIes(msgData,currentMessage)
+ GenerateMsgClass.generateMsgFactory(msgData,currentMessage)
+ GenerateMsgClass.generateMsgDataType(msgData,currentMessage)
+ GenerateMsgClass.prepareMsgMakeFile()
+
+ elif state == 'StartDetected':
+
+ msgData['msgDetails'] = {}
+ msgData['msgDetails'][currentMessage] = {}
+ msgData['msgDetails'][currentMessage]['msgValue'] = msgValue
+ msgData['msgDetails'][currentMessage]['msgDataType'] = currentMessage + 'MsgData'
+ msgData['msgDetails'][currentMessage]['msgCategory'] = "RequestMessage"
+ if mResponseMsg:
+
+ msgData['msgDetails'][currentMessage]['msgCategory'] = "ResponseMessage"
+ elif mGrouped:
+ state = 'IeListStart'
+
+
+
+ elif state == 'IeListStart':
+
+ if xlUtils.getCellValue(sheet,i,'D') != None:
+
+ ieDescription = xlUtils.getCellValue(sheet,i,'D')
+ presence = xlUtils.getCellValue(sheet,i,'E')
+ grouped = xlUtils.getCellValue(sheet,i,'B')
+ cardinality = xlUtils.getCellValue(sheet,i,'C')
+ instance = xlUtils.getCellValue(sheet,i,'H')
+ msgData['ieDetails'] = {}
+ msgData['ieDetails'][ieDescription] = {}
+ msgData['ieDetails'][ieDescription]['ieDescription'] = ieDescription
+ msgData['ieDetails'][ieDescription]['presence'] = presence
+ msgData['ieDetails'][ieDescription]['grouped'] = grouped
+ msgData['ieDetails'][ieDescription]['cardinality'] = cardinality
+ msgData['ieDetails'][ieDescription]['instance'] = instance
+
+ if msgData['ieDetails'][ieDescription]['cardinality'] is None:
+ msgData['ieDetails'][ieDescription]['cardinality'] = 1
+ ieTypeDescription = xlUtils.getCellValue(sheet,i,'G')
+ msgData['ieDetails'][ieDescription]['ieTypeDescription'] = ieTypeDescription
+
+ ieVarName = xlUtils.getVarNameFromString(ieDescription,0)
+ ieTypeName = xlUtils.getVarNameFromString(ieTypeDescription,1)
+ ieVarName = ieVarName.replace('/','')
+
+ msgData['ieDetails'][ieDescription]['ieGroupTypeName'] = ''
+ if msgData['ieDetails'][ieDescription]['grouped'] == 'Yes':
+ msgData['ieDetails'][ieDescription]['ieGroupTypeName'] = ieVarName + 'In' + currentMessage
+ msgData['ieDetails'][ieDescription]['ieVarName'] = ieVarName
+ msgData['ieDetails'][ieDescription]['ieTypeName'] = ieTypeName
+
+ if ieVarName!="privateExtension":
+ ieDetailList.append(msgData['ieDetails'])
+
+ ieList.append(ieVarName)
+ msgData['ieList'] = ieList
+ msgData['ieDetails'] = ieDetailList
+
+ return msgData
+
+
+ def templateIes(msgData,currentMessage):
+ templateData = dict()
+ ieListTemplate = []
+ ieTypeTemplate = []
+ ieTypeDetailList = []
+ ieTypeList = []
+ templateData['fileName'] = currentMessage[0].lower()+currentMessage[1:] + 'Msg'
+ templateData['msgClassName'] = currentMessage[0].upper()+currentMessage[1:] + 'Msg'
+ templateData['classNameUC'] = templateData['fileName'].upper()
+ templateData['msgCategory'] = msgData['msgDetails'][currentMessage]['msgCategory']
+
+ for ieDetail in msgData['ieDetails']:
+ for key,value in ieDetail.items():
+ for ie in msgData['ieList']:
+ ieInfo = {}
+ ieTypeInfo = {}
+ if value['ieVarName'] == ie:
+
+ ieInfo['ieName'] = value['ieVarName']
+ ieInfo['ieVarName'] = value['ieVarName']
+ ieInfo['ieType'] = value['ieTypeName']
+ ieInfo['ieFileName'] = value['ieTypeName'][0].lower()+value['ieTypeName'][1:] + 'Ie'
+ ieInfo['ieLocalVar'] = value['ieTypeName'][0].lower()+value['ieTypeName'][1:]
+ ieInfo['iePresence'] = value['presence']
+ ieInfo['ieCardinality'] = value['cardinality']
+ ieInfo['instance'] = value['instance']
+ ieInfo['grouped'] = value['grouped']
+ ieInfo['grpIeInstClassName'] = value['ieGroupTypeName']
+ if ieInfo['grouped']=='Yes':
+ ieInfo['grpIeInstClassName'] = value['ieGroupTypeName'][0].upper()+value['ieGroupTypeName'][1:]
+ ieInfo['grpIeInstFileName'] = value['ieGroupTypeName']
+
+ ieType = ieInfo['ieType']
+ ieTypeInfo['ieName'] = value['ieVarName']
+ ieTypeInfo['ieVarName'] = value['ieVarName']
+ ieTypeInfo['ieType'] = value['ieTypeName']
+ ieTypeInfo['ieFileName'] = value['ieTypeName'][0].lower()+value['ieTypeName'][1:] + 'Ie'
+ ieTypeInfo['ieLocalVar'] = value['ieTypeName'].capitalize()
+ ieTypeInfo['iePresence'] = value['presence']
+ ieTypeInfo['ieCardinality'] = value['cardinality']
+ ieTypeInfo['instance'] = value['instance']
+ ieTypeInfo['grouped'] = value['grouped']
+ ieTypeInfo['grpIeInstClassName'] = value['ieGroupTypeName']
+ if ieTypeInfo['grouped']=='Yes':
+ ieTypeInfo['grpIeInstClassName'] = value['ieGroupTypeName'][0].upper()+value['ieGroupTypeName'][1:]
+ ieTypeInfo['grpIeInstFileName'] = value['ieGroupTypeName'].capitalize()
+
+
+ ieListTemplate.append(ieInfo)
+ templateData['ieList'] = ieListTemplate
+
+ if ieInfo['ieType'] not in ieTypeList:
+ ieTypeList.append(ieInfo['ieType'])
+ templateData['ieTypeList'] = ieTypeList
+
+ ieTypeTemplate = []
+ ieTypeTemplate.append(ieTypeInfo)
+ templateData['ieTypeDetails'] = {}
+ templateData['ieTypeDetails'][ieType] = ieTypeTemplate
+
+ ieTypeDetailList.append(templateData['ieTypeDetails'])
+ templateData['ieTypeDetails'] = ieTypeDetailList
+
+ outputDir = '../../src/gtpV2Codec/msgClasses'
+ ttFileNameCpp = 'tts/msgtemplate.cpp.tt'
+ ttFileNameH = 'tts/msgtemplate.h.tt'
+ xlUtils.templateProcess(templateData,ttFileNameCpp,ttFileNameH,outputDir,outputDir)
+
+ objectFile = 'msgClasses/' +templateData['fileName'] + '.o'
+ sourceFile = 'msgClasses/' + templateData['fileName'] + '.cpp'
+ xlUtils.addToMakeSo('gtpV2Stack.so',objectFile,sourceFile)
+
+ def generateMsgFactory(msgData,currentMessage):
+ msgInfo = {}
+
+ msgInfo['className'] = currentMessage + 'Msg'
+ msgInfo['msgFileName'] = currentMessage[0].lower()+currentMessage[1:] + 'Msg'
+ msgInfo['dataMember'] = currentMessage[0].lower()+currentMessage[1:] + 'StackData'
+ if msgInfo not in msgFactoryData['msgList']:
+ msgFactoryData['msgList'].append(msgInfo)
+ outputDirCpp = 'msgClasses/'
+ GenerateMsgClass.msgfactoryStacktemplate(msgFactoryData)
+ xlUtils.addToMakeSo('gtpV2Stack.so',outputDirCpp+'gtpV2MsgFactory.o',outputDirCpp+'gtpV2MsgFactory.cpp')
+ xlUtils.addToMakeSo('gtpV2Stack.so','gtpV2Stack.o','gtpV2Stack.cpp')
+
+ def msgfactoryStacktemplate(msgFactoryData):
+
+ ttFileNamefactoryCpp = 'tts/msgfactorytemplate.cpp.tt'
+ outputDir = '../../src/gtpV2Codec/msgClasses'
+ msgFactoryData['fileName'] = 'gtpV2MsgFactory'
+ ttFileNamefactoryH = 'tts/msgfactorytemplate.h.tt'
+ xlUtils.templateProcess(msgFactoryData,ttFileNamefactoryCpp,ttFileNamefactoryH,outputDir,outputDir)
+
+ ttFileNameStackCpp = 'tts/stacktemplate.cpp.tt'
+ outputDir = '../../src/gtpV2Codec/'
+ msgFactoryData['fileName'] = 'gtpV2Stack'
+ ttFileNameStackH = 'tts/stacktemplate.h.tt'
+
+ xlUtils.templateProcess(msgFactoryData,ttFileNameStackCpp,ttFileNameStackH,outputDir,outputDir)
+
+
+
+ def prepareMsgMakeFile():
+ outputDir = 'msgClasses/manual/'
+ xlUtils.addToMakeSo('gtpV2Stack.so', outputDir+'gtpV2Message.o', outputDir+'gtpV2Message.cpp')
+ def generateMsgDataType(msgData,currentMessage):
+ msginfo = {}
+ msgTypeInfo={}
+ msginfo['msgDataName'] = currentMessage + 'MsgData'
+ msginfo['ieDetails']=[]
+ msgTypeInfo['msgDataType']=currentMessage + 'MsgType'
+ msgTypeInfo['msgValue']=msgData['msgDetails'][currentMessage]['msgValue']
+
+ if msgTypeInfo not in msgDataTypeData['msgTypeList']:
+ msgDataTypeData['msgTypeList'].append(msgTypeInfo)
+
+ for ieDetail in msgData['ieDetails']:
+ for key,value in ieDetail.items():
+ for ie in msgData['ieList']:
+ ieInfo = {}
+
+ if value['ieVarName'] == ie:
+ ieInfo['ieName'] = value['ieVarName']
+ ieInfo['ieVarName'] = value['ieVarName']
+ ieInfo['ieType'] = value['ieTypeName']
+ ieInfo['iePresence'] = value['presence']
+ ieInfo['ieCardinality'] = value['cardinality']
+ ieInfo['grouped'] = value['grouped']
+ ieInfo['grpIeInstClassName'] = value['ieGroupTypeName']
+ if ieInfo['grouped']=='Yes':
+ ieInfo['grpIeInstClassName'] = value['ieGroupTypeName'][0].upper()+value['ieGroupTypeName'][1:]
+ ieInfo['grpIeInstFileName'] = value['ieGroupTypeName']
+ if ieInfo not in msginfo['ieDetails']:
+ msginfo['ieDetails'].append(ieInfo)
+ if msginfo not in msgDataTypeData['msgList']:
+ msgDataTypeData['msgList'].append(msginfo)
+
+ template = Template()
+ ttFileNamefactoryH = 'tts/msgDataTypetemplate.h.tt'
+ outputDir = '../../src/gtpV2Codec/msgClasses'
+
+ if not os.path.exists(outputDir):
+ os.makedirs(outputDir)
+ outputFileName = 'gtpV2MsgDataTypes.h'
+ template.__init__({'OUTPUT' : outputFileName, 'OUTPUT_PATH' : outputDir})
+ template.process(ttFileNamefactoryH, {'tempdata' : msgDataTypeData})
+
+
+GenerateMsgClass()
\ No newline at end of file
diff --git a/scripts/GtpV2StackCodeGen/startCodeGen.py b/scripts/GtpV2StackCodeGen/startCodeGen.py
new file mode 100644
index 0000000..a3a2a27
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/startCodeGen.py
@@ -0,0 +1,16 @@
+
+# Copyright 2019-present Infosys Limited
+# SPDX-License-Identifier: Apache-2.0
+
+from iECodeGen import GenerateIeClass
+from datatypeCodeGen import GenerateDataTypeClass
+from xlUtils import xlUtils
+from msgCodeGen import GenerateMsgClass
+from groupedIECodeGen import GenerateGrpIeClass
+
+GenerateIeClass()
+GenerateDataTypeClass()
+GenerateMsgClass()
+GenerateGrpIeClass()
+
+xlUtils.generateMakeFile()
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
diff --git a/scripts/GtpV2StackCodeGen/xlUtils.py b/scripts/GtpV2StackCodeGen/xlUtils.py
new file mode 100644
index 0000000..1af0983
--- /dev/null
+++ b/scripts/GtpV2StackCodeGen/xlUtils.py
@@ -0,0 +1,219 @@
+# Copyright 2019-present Infosys Limited
+# SPDX-License-Identifier: Apache-2.0
+
+import re
+from template import Template
+import os
+from openpyxl import load_workbook
+
+libData = {}
+progData = {}
+template = Template()
+wb = load_workbook('dataModel/prototypeV8.xlsx')
+class xlUtils:
+ def __init__(self):
+ pass
+
+
+ def extractField(field):
+ varName = ''
+ varType = ''
+ encodeCondition = ''
+ decodeCondition = ''
+ validation = ''
+ count = ''
+ mVarName = re.search('^(\w+)',str(field))
+ mVarType = re.search(':Type\[(\w+)\]',str(field))
+ mEnCond = re.search(':Condition\[([^\:]*)\]',str(field))
+ mDeCond = re.search(':DecodeCondition\[([^\:]*)]',str(field))
+ mValid = re.search(':Validation\[([^\:]+)\]',str(field))
+ mCount = re.search(':Count\[([^\:]*)]',str(field))
+ if mVarName:
+ varName = mVarName.group(1)
+
+ if mVarType:
+ varType = mVarType.group(1)
+
+ if mEnCond:
+ encodeCondition = mEnCond.group(1)
+
+ if mDeCond:
+ decodeCondition = mDeCond.group(1)
+ else:
+ if mEnCond:
+ decodeCondition = mEnCond.group(1)
+
+
+ if mValid:
+ validation = mValid.group(1)
+ dataVarName = 'data.' + varName
+ validation = re.sub(r'\$.',dataVarName,validation)
+
+ if mCount:
+ count = mCount.group(1)
+
+ return (varName,varType,encodeCondition,decodeCondition,validation,count)
+
+ def lengthToType(byteLength):
+ lTdict = {1:'Uint8',2:'Uint16',3:'Uint32',4:'Uint32',5:'Uint64',6:'Uint64',7:'Uint64',8:'Uint64',65535:'Uint8',9:'Uint8',12:'Uint8'}
+ return lTdict[byteLength]
+
+ def getByteLength(sheet,i):
+ length = 0
+ lengthStr = ''
+ cell_value_C = xlUtils.getCellValue(sheet,i,'C')
+ octets = str(cell_value_C)
+
+ mTo = re.search('to',str(octets))
+ mVar = re.search('^variable\[(.*)]',str(octets))
+ mToD = re.search('^(\d+) to (\d+)',str(octets))
+ mToWD = re.search('^(\w) to (\w)\+(\d+)',str(octets))
+ mToWWD = re.search('^(\w)\+(\d+) to (\w)\+(\d+)',str(octets))
+
+ if not mTo:
+ if mVar:
+ lenStr = mVar.group(1)
+ length = 65535
+ lengthStr = lenStr
+
+ elif xlUtils.getBitLength(sheet,i,'D') == 8:
+ length = 1
+
+ else:
+ if mToD:
+ toD = mToD.group(1)
+ toD2 = mToD.group(2)
+ length = int(toD2) - int(toD) + 1
+
+ elif mToWD:
+ ToWD = mToWD.group(3)
+ length = int(ToWD) + 1
+
+ elif mToWWD:
+ ToWWD2 = mToWWD.group(2)
+ ToWWD4 = mToWWD.group(4)
+ length = int(ToWWD4) - int(ToWWD2) + 1
+ return (length,lengthStr)
+
+ def getBitLength(sheet,i,j):
+ length = 0
+ fieldName = xlUtils.getCellValue(sheet,i,j)
+ mcolDtoK = re.search('[D-K]',j)
+ if fieldName != None and mcolDtoK:
+ for k in map(chr, range( ord(j), ord('L'))):
+ fName = xlUtils.getCellValue(sheet,i,k)
+
+ if length == 0:
+ length = length + 1
+
+ elif fName == None:
+ length = length + 1
+
+ else:
+ break
+ return length
+
+
+ def getCellValue(sheet,row,column):
+ colNum = 0
+ chartoint = {'A' : 1,'B' : 2, 'C' : 3, 'D' : 4, 'E' : 5, 'F' : 6, 'G' : 7,
+ 'H' : 8, 'I' : 9, 'J' : 10, 'K' : 11, 'L' : 12, 'M' : 13, 'N' : 14,
+ 'O' : 15, 'P' : 16, 'Q' : 17, 'R' : 18, 'S' : 19, 'T' : 20, 'U' : 21,
+ 'V' : 22, 'W' : 23, 'X' : 24, 'Y' : 25, 'Z' : 26}
+
+ colNum = chartoint[column]
+ cellvalue = sheet.cell(row=row, column=colNum).value
+ return cellvalue
+
+ def getVarNameFromString(localString,typeName):
+
+ localString = localString.lower()
+ varName = ''
+ localString = re.sub(r'\(.*\)'," ",localString)
+ localString=localString.replace('/'," ")
+ localString = re.sub('-'," ",localString)
+ tokens = [x.capitalize() for x in localString.split(" ")]
+ varName = varName.join(tokens)
+ varName = varName[0].upper() + varName[1:]
+ if typeName == 1:
+ return varName
+ else:
+ return varName[0].lower() + varName[1:]
+
+ def templateProcess(templateData,ttFileNameCpp,ttFileNameH,outputDirCpp,outputDirH):
+
+
+ template = Template()
+
+ if not os.path.exists(outputDirCpp):
+ os.makedirs(outputDirCpp)
+ outputFileNameCpp = templateData['fileName'] + '.cpp'
+
+ template.__init__({'OUTPUT' : outputFileNameCpp, 'OUTPUT_PATH' : outputDirCpp})
+ template.process(ttFileNameCpp, {'tempdata' : templateData})
+
+
+ if not os.path.exists(outputDirH):
+ os.makedirs(outputDirH)
+ outputFileNameH = templateData['fileName'] + '.h'
+ template.__init__({'OUTPUT' : outputFileNameH, 'OUTPUT_PATH' : outputDirH})
+ template.process(ttFileNameH, {'tempdata' : templateData})
+
+ def addToMakeSo(libName,objFile,srcFile):
+
+ fileData = {}
+ fileData['objFile'] = objFile
+ fileData['sourceFile'] = srcFile
+ if libName not in libData:
+ lib = libName
+ lib = re.sub(r'.so','',lib)
+ libData[libName] = {}
+ libData[libName]['libName'] = lib
+ libData[libName]['fileList'] = []
+ if fileData not in libData[libName]['fileList']:
+ libData[libName]['fileList'].append(fileData)
+
+ def addToMakeExe(progName,objFile,srcFile):
+ fileData = {}
+ fileData['objFile'] = objFile
+ fileData['sourceFile'] = srcFile
+
+ if progName not in progData:
+ prog = progName
+ prog = re.sub(r'.exe','',prog)
+ progData[progName] = {}
+ progData[progName]['progName'] = prog
+
+ progData[progName]['fileList'] = []
+ progData[progName]['fileList'].append(fileData)
+
+ def addSoToMakeExe(progName,soName):
+ if progName not in progData:
+ prog = progName
+ prog = re.sub(r'.exe','',prog)
+ progData[progName] = {}
+ progData[progName]['progName'] = prog
+
+ progData[progName]['soList'] = []
+ progData[progName]['soList'].append(soName)
+
+ def generateMakeFile():
+ makeFileData = {}
+
+ for libr in libData.keys():
+ makeFileData['libList'] = []
+ makeFileData['libList'].append(libData[libr])
+ for prog in progData.keys():
+ makeFileData['progList']=[]
+ makeFileData['progList'].append(progData[prog])
+
+
+ ttFileName = 'tts/makefiletemplate.tt'
+
+ fileName = 'Makefile'
+ outputDir='../../src/gtpV2Codec'
+
+ template.__init__({'OUTPUT' : fileName, 'OUTPUT_PATH' : outputDir})
+ template.process(ttFileName, {'makefiledata': makeFileData})
+
+xlUtils()