2017-03-14 02:24:15 +00:00
|
|
|
#
|
|
|
|
# Copyright (c) 2017, CellWire Group
|
|
|
|
# All rights reserved.
|
|
|
|
#
|
|
|
|
# Redistribution and use in source and binary forms, with or without
|
|
|
|
# modification, are permitted provided that the following conditions are met:
|
|
|
|
#
|
|
|
|
# 1. Redistributions of source code must retain the above copyright notice, this
|
|
|
|
# list of conditions and the following disclaimer.
|
|
|
|
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
# this list of conditions and the following disclaimer in the documentation
|
|
|
|
# and/or other materials provided with the distribution.
|
|
|
|
#
|
|
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
|
|
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
|
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
#
|
|
|
|
from docx import Document
|
|
|
|
import re, os, sys, string
|
2017-03-14 08:09:27 +00:00
|
|
|
import datetime
|
2017-03-14 02:24:15 +00:00
|
|
|
import getopt
|
2017-03-14 08:09:27 +00:00
|
|
|
import getpass
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
version = "0.1.0"
|
|
|
|
|
2017-03-15 04:39:57 +00:00
|
|
|
msg_list = {}
|
|
|
|
type_list = {}
|
|
|
|
group_list = {}
|
|
|
|
|
2017-03-14 02:24:15 +00:00
|
|
|
verbosity = 0
|
|
|
|
filename = ""
|
|
|
|
outdir = './'
|
|
|
|
cachedir = './cache/'
|
|
|
|
|
|
|
|
FAIL = '\033[91m'
|
|
|
|
INFO = '\033[93m'
|
|
|
|
ENDC = '\033[0m'
|
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
def d_print(string):
|
2017-03-14 02:24:15 +00:00
|
|
|
if verbosity > 0:
|
2017-03-15 02:54:08 +00:00
|
|
|
sys.stdout.write(string)
|
2017-03-14 02:24:15 +00:00
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
def d_info(string):
|
2017-03-15 02:54:08 +00:00
|
|
|
sys.stdout.write(INFO + string + ENDC + "\n")
|
2017-03-14 02:24:15 +00:00
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
def d_error(string):
|
2017-03-14 02:24:15 +00:00
|
|
|
sys.stderr.write(FAIL + string + ENDC + "\n")
|
|
|
|
sys.exit(0)
|
|
|
|
|
2017-03-15 02:54:08 +00:00
|
|
|
def write_file(f, string):
|
|
|
|
f.write(string)
|
|
|
|
d_print(string)
|
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
def output_header_to_file(f):
|
2017-03-14 08:09:27 +00:00
|
|
|
now = datetime.datetime.now()
|
|
|
|
f.write("""/*
|
|
|
|
* Copyright (c) 2017, CellWire Group
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
|
|
* list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
|
|
* and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
""")
|
|
|
|
f.write("/*******************************************************************************\n")
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write(" * This file had been created by gtp_tlv.py script v%s\n" % (version))
|
2017-03-14 08:09:27 +00:00
|
|
|
f.write(" * Please do not modify this file but regenerate it via script.\n")
|
|
|
|
f.write(" * Created on: %s by %s\n * from %s\n" % (str(now), getpass.getuser(), filename))
|
|
|
|
f.write(" ******************************************************************************/\n\n")
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
def usage():
|
2017-03-17 11:20:37 +00:00
|
|
|
print "Python generating TLV build/parser for GTPv2-C v%s" % (version)
|
2017-03-24 16:07:59 +00:00
|
|
|
print "Usage: python gtp_tlv.py [options]"
|
2017-03-14 02:24:15 +00:00
|
|
|
print "Available options:"
|
|
|
|
print "-d Enable script debug"
|
|
|
|
print "-f [file] Input file to parse"
|
|
|
|
print "-o [dir] Output files to given directory"
|
2017-03-17 11:20:37 +00:00
|
|
|
print "-c [dir] Cache files to given directory"
|
2017-03-14 02:24:15 +00:00
|
|
|
print "-h Print this help and return"
|
|
|
|
|
2017-03-14 08:09:27 +00:00
|
|
|
def v_upper(v):
|
2017-03-15 07:07:52 +00:00
|
|
|
return re.sub('3GPP', '', re.sub('\'', '_', re.sub('/', '_', re.sub('-', '_', re.sub(' ', '_', v)))).upper())
|
2017-03-14 13:44:48 +00:00
|
|
|
|
2017-03-14 08:09:27 +00:00
|
|
|
def v_lower(v):
|
2017-03-15 07:07:52 +00:00
|
|
|
return re.sub('3gpp', '', re.sub('\'', '_', re.sub('/', '_', re.sub('-', '_', re.sub(' ', '_', v)))).lower())
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
def get_cells(cells):
|
|
|
|
instance = cells[4].text.encode('ascii', 'ignore')
|
|
|
|
if instance.isdigit() is not True:
|
|
|
|
return None
|
|
|
|
ie_type = re.sub('\s*\n*\s*\(NOTE.*\)*', '', cells[3].text.encode('ascii', 'ignore'))
|
|
|
|
if ie_type.find('LDN') != -1:
|
|
|
|
ie_type = 'LDN'
|
|
|
|
elif ie_type.find('APCO') != -1:
|
|
|
|
ie_type = 'APCO'
|
2017-03-14 14:56:12 +00:00
|
|
|
elif ie_type.find('Charging Id') != -1:
|
|
|
|
ie_type = 'Charging ID'
|
2017-03-31 00:06:07 +00:00
|
|
|
elif ie_type.find('H(e)NB Information Reporting') != -1:
|
|
|
|
ie_type = 'eNB Information Reporting'
|
|
|
|
elif ie_type.find('IPv4 Configuration Parameters (IP4CP)') != -1:
|
|
|
|
ie_type = 'IP4CP'
|
2017-03-14 13:44:48 +00:00
|
|
|
if ie_type not in type_list.keys():
|
|
|
|
assert False, "Unknown IE type : [" \
|
|
|
|
+ cells[3].text + "]" + "(" + ie_type + ")"
|
|
|
|
presence = cells[1].text.encode('ascii', 'ignore')
|
2017-03-15 01:53:33 +00:00
|
|
|
ie_value = re.sub('\s*\n*\s*\([^\)]*\)*', '', cells[0].text).encode('ascii', 'ignore')
|
2017-03-14 13:44:48 +00:00
|
|
|
comment = cells[2].text.encode('ascii', 'ignore')
|
|
|
|
comment = re.sub('\n|\"|\'|\\\\', '', comment);
|
2017-03-15 04:39:57 +00:00
|
|
|
|
2017-03-15 06:49:56 +00:00
|
|
|
if int(instance) > int(type_list[ie_type]["max_instance"]):
|
2017-03-15 04:39:57 +00:00
|
|
|
type_list[ie_type]["max_instance"] = instance
|
|
|
|
write_file(f, "type_list[\"" + ie_type + "\"][\"max_instance\"] = \"" + instance + "\"\n")
|
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
return { "ie_type" : ie_type, "ie_value" : ie_value, "presence" : presence, "instance" : instance, "comment" : comment }
|
|
|
|
|
|
|
|
def write_cells_to_file(name, cells):
|
|
|
|
write_file(f, name + ".append({ \"ie_type\" : \"" + cells["ie_type"] + \
|
|
|
|
"\", \"ie_value\" : \"" + cells["ie_value"] + \
|
|
|
|
"\", \"presence\" : \"" + cells["presence"] + \
|
|
|
|
"\", \"instance\" : \"" + cells["instance"] + \
|
2017-03-15 02:54:08 +00:00
|
|
|
"\", \"comment\" : \"" + cells["comment"] + "\"})\n")
|
2017-03-14 13:44:48 +00:00
|
|
|
|
2017-03-14 02:24:15 +00:00
|
|
|
try:
|
|
|
|
opts, args = getopt.getopt(sys.argv[1:], "df:ho:c:", ["debug", "file", "help", "output", "cache"])
|
|
|
|
except getopt.GetoptError as err:
|
|
|
|
# print help information and exit:
|
|
|
|
usage()
|
|
|
|
sys.exit(2)
|
|
|
|
|
|
|
|
for o, a in opts:
|
|
|
|
if o in ("-d", "--debug"):
|
|
|
|
verbosity = 1
|
|
|
|
if o in ("-f", "--file"):
|
|
|
|
filename = a
|
|
|
|
if o in ("-o", "--output"):
|
|
|
|
outdir = a
|
|
|
|
if outdir.rfind('/') != len(outdir):
|
|
|
|
outdir += '/'
|
|
|
|
if o in ("-c", "--cache"):
|
|
|
|
cache = a
|
|
|
|
if cachedir.rfind('/') != len(cachedir):
|
|
|
|
cachedir += '/'
|
|
|
|
if o in ("-h", "--help"):
|
|
|
|
usage()
|
|
|
|
sys.exit(2)
|
|
|
|
|
|
|
|
if os.path.isfile(filename) and os.access(filename, os.R_OK):
|
|
|
|
file = open(filename, 'r')
|
|
|
|
else:
|
2017-03-14 13:44:48 +00:00
|
|
|
d_error("Cannot find file : " + filename)
|
2017-03-14 02:24:15 +00:00
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
d_info("[Message List]")
|
2017-03-24 16:07:59 +00:00
|
|
|
cachefile = cachedir + 'tlv_msg_list.py'
|
2017-03-14 02:24:15 +00:00
|
|
|
if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
|
|
|
|
execfile(cachefile)
|
|
|
|
print "Read from " + cachefile
|
|
|
|
else:
|
2017-03-14 04:50:13 +00:00
|
|
|
document = Document(filename)
|
2017-03-14 02:24:15 +00:00
|
|
|
f = open(cachefile, 'w')
|
|
|
|
|
|
|
|
msg_table = ""
|
2017-03-14 14:56:12 +00:00
|
|
|
for i, table in enumerate(document.tables):
|
2017-03-14 02:24:15 +00:00
|
|
|
cell = table.rows[0].cells[0]
|
|
|
|
if cell.text.find('Message Type value') != -1:
|
|
|
|
msg_table = table
|
2017-03-15 02:54:08 +00:00
|
|
|
d_print("Table Index = %d\n" % i)
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
for row in msg_table.rows[2:-4]:
|
2017-03-14 08:23:58 +00:00
|
|
|
key = row.cells[1].text.encode('ascii', 'ignore')
|
|
|
|
type = row.cells[0].text.encode('ascii', 'ignore')
|
2017-03-14 02:24:15 +00:00
|
|
|
if type.isdigit() is False:
|
|
|
|
continue
|
|
|
|
if int(type) in range(128, 160):
|
|
|
|
continue
|
|
|
|
if int(type) in range(231, 240):
|
|
|
|
continue
|
|
|
|
if key.find('Reserved') != -1:
|
|
|
|
continue
|
|
|
|
key = re.sub('\s*\n*\s*\([^\)]*\)*', '', key)
|
|
|
|
msg_list[key] = { "type": type }
|
2017-03-15 02:54:08 +00:00
|
|
|
write_file(f, "msg_list[\"" + key + "\"] = { \"type\" : \"" + type + "\" }\n")
|
2017-03-14 02:24:15 +00:00
|
|
|
f.close()
|
|
|
|
|
2017-03-14 13:44:48 +00:00
|
|
|
d_info("[IE Type List]")
|
2017-03-24 16:07:59 +00:00
|
|
|
cachefile = cachedir + 'tlv_type_list.py'
|
2017-03-14 02:24:15 +00:00
|
|
|
if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
|
|
|
|
execfile(cachefile)
|
|
|
|
print "Read from " + cachefile
|
|
|
|
else:
|
2017-03-14 04:50:13 +00:00
|
|
|
document = Document(filename)
|
2017-03-14 02:24:15 +00:00
|
|
|
f = open(cachefile, 'w')
|
|
|
|
|
|
|
|
ie_table = ""
|
2017-03-14 14:56:12 +00:00
|
|
|
for i, table in enumerate(document.tables):
|
2017-03-14 02:24:15 +00:00
|
|
|
cell = table.rows[0].cells[0]
|
|
|
|
if cell.text.find('IE Type value') != -1:
|
|
|
|
ie_table = table
|
2017-03-15 02:54:08 +00:00
|
|
|
d_print("Table Index = %d\n" % i)
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
for row in ie_table.rows[1:-5]:
|
2017-03-14 08:09:27 +00:00
|
|
|
key = row.cells[1].text.encode('ascii', 'ignore')
|
2017-03-14 02:24:15 +00:00
|
|
|
if key.find('Reserved') != -1:
|
|
|
|
continue
|
|
|
|
if key.find('MM Context') != -1:
|
|
|
|
continue
|
|
|
|
elif key.find('Recovery') != -1:
|
|
|
|
key = 'Recovery'
|
|
|
|
elif key.find('Trusted WLAN Mode Indication') != -1:
|
|
|
|
key = 'TWMI'
|
|
|
|
elif key.find('LDN') != -1:
|
|
|
|
key = 'LDN'
|
|
|
|
elif key.find('APCO') != -1:
|
|
|
|
key = 'APCO'
|
2017-03-14 04:50:13 +00:00
|
|
|
elif key.find('Remote UE IP information') != -1:
|
|
|
|
key = 'Remote UE IP Information'
|
2017-03-14 02:24:15 +00:00
|
|
|
else:
|
2017-03-14 08:09:27 +00:00
|
|
|
key = re.sub('.*\(', '', row.cells[1].text.encode('ascii', 'ignore'))
|
2017-03-14 02:24:15 +00:00
|
|
|
key = re.sub('\)', '', key)
|
2017-03-14 08:09:27 +00:00
|
|
|
key = re.sub('\s*$', '', key)
|
|
|
|
type = row.cells[0].text.encode('ascii', 'ignore')
|
2017-03-15 04:39:57 +00:00
|
|
|
type_list[key] = { "type": type , "max_instance" : "0" }
|
|
|
|
write_file(f, "type_list[\"" + key + "\"] = { \"type\" : \"" + type)
|
|
|
|
write_file(f, "\", \"max_instance\" : \"0\" }\n")
|
2017-03-14 02:24:15 +00:00
|
|
|
f.close()
|
2017-03-15 04:39:57 +00:00
|
|
|
type_list['MM Context'] = { "type": "107", "max_instance" : "0" }
|
2017-03-14 02:24:15 +00:00
|
|
|
|
2017-03-14 14:56:12 +00:00
|
|
|
d_info("[Group IE List]")
|
2017-03-24 16:07:59 +00:00
|
|
|
cachefile = cachedir + 'tlv_group_list.py'
|
2017-03-14 14:56:12 +00:00
|
|
|
if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
|
|
|
|
execfile(cachefile)
|
|
|
|
print "Read from " + cachefile
|
|
|
|
else:
|
|
|
|
document = Document(filename)
|
|
|
|
f = open(cachefile, 'w')
|
|
|
|
|
|
|
|
for i, table in enumerate(document.tables):
|
|
|
|
if table.rows[0].cells[0].text.find('Octet') != -1 and \
|
|
|
|
table.rows[0].cells[2].text.find('IE Type') != -1:
|
2017-03-15 02:54:08 +00:00
|
|
|
d_print("Table Index = %d\n" % i)
|
2017-03-14 14:56:12 +00:00
|
|
|
|
|
|
|
row = table.rows[0];
|
|
|
|
|
|
|
|
if len(re.findall('\d+', row.cells[2].text)) == 0:
|
|
|
|
continue;
|
|
|
|
ie_type = re.findall('\d+', row.cells[2].text)[0].encode('ascii', 'ignore')
|
|
|
|
ie_name = re.sub('\s*IE Type.*', '', row.cells[2].text.encode('ascii', 'ignore'))
|
|
|
|
|
|
|
|
if ie_name not in group_list.keys():
|
2017-03-15 07:26:29 +00:00
|
|
|
ies = []
|
|
|
|
write_file(f, "ies = []\n")
|
2017-03-14 14:56:12 +00:00
|
|
|
for row in table.rows[4:]:
|
|
|
|
cells = get_cells(row.cells)
|
|
|
|
if cells is None:
|
|
|
|
continue
|
|
|
|
|
2017-03-15 07:26:29 +00:00
|
|
|
ies_is_added = True
|
|
|
|
for ie in ies:
|
2017-03-15 01:53:33 +00:00
|
|
|
if (cells["ie_type"], cells["instance"]) == (ie["ie_type"], ie["instance"]):
|
2017-03-15 07:26:29 +00:00
|
|
|
ies_is_added = False
|
|
|
|
if ies_is_added is True:
|
|
|
|
ies.append(cells)
|
|
|
|
write_cells_to_file("ies", cells)
|
2017-03-15 01:53:33 +00:00
|
|
|
|
2017-03-15 07:26:29 +00:00
|
|
|
group_list[ie_name] = { "type" : ie_type, "ies" : ies }
|
|
|
|
write_file(f, "group_list[\"" + ie_name + "\"] = { \"type\" : \"" + ie_type + "\", \"ies\" : ies }\n")
|
2017-03-14 14:56:12 +00:00
|
|
|
else:
|
2017-03-15 01:53:33 +00:00
|
|
|
group_list_is_added = False
|
2017-03-15 07:26:29 +00:00
|
|
|
added_ies = group_list[ie_name]["ies"]
|
|
|
|
write_file(f, "added_ies = group_list[\"" + ie_name + "\"][\"ies\"]\n")
|
2017-03-14 14:56:12 +00:00
|
|
|
for row in table.rows[4:]:
|
|
|
|
cells = get_cells(row.cells)
|
|
|
|
if cells is None:
|
|
|
|
continue
|
2017-03-15 01:53:33 +00:00
|
|
|
|
2017-03-15 07:26:29 +00:00
|
|
|
ies_is_added = True
|
|
|
|
for ie in group_list[ie_name]["ies"]:
|
2017-03-14 14:56:12 +00:00
|
|
|
if (cells["ie_type"], cells["instance"]) == (ie["ie_type"], ie["instance"]):
|
2017-03-15 07:26:29 +00:00
|
|
|
ies_is_added = False
|
|
|
|
for ie in ies:
|
2017-03-14 14:56:12 +00:00
|
|
|
if (cells["ie_type"], cells["instance"]) == (ie["ie_type"], ie["instance"]):
|
2017-03-15 07:26:29 +00:00
|
|
|
ies_is_added = False
|
|
|
|
if ies_is_added is True:
|
|
|
|
added_ies.append(cells)
|
|
|
|
write_cells_to_file("added_ies", cells)
|
2017-03-15 01:53:33 +00:00
|
|
|
group_list_is_added = True
|
|
|
|
if group_list_is_added is True:
|
2017-03-15 07:26:29 +00:00
|
|
|
group_list[ie_name] = { "type" : ie_type, "ies" : added_ies }
|
|
|
|
write_file(f, "group_list[\"" + ie_name + "\"] = { \"type\" : \"" + ie_type + "\", \"ies\" : added_ies }\n")
|
2017-03-14 14:56:12 +00:00
|
|
|
f.close()
|
|
|
|
|
2017-03-14 04:50:13 +00:00
|
|
|
msg_list["Echo Request"]["table"] = 6
|
|
|
|
msg_list["Echo Response"]["table"] = 7
|
|
|
|
msg_list["Create Session Request"]["table"] = 8
|
2017-03-31 00:06:07 +00:00
|
|
|
msg_list["Create Session Response"]["table"] = 13
|
2017-04-13 16:26:50 +00:00
|
|
|
msg_list["Modify Bearer Request"]["table"] = 29
|
|
|
|
msg_list["Modify Bearer Response"]["table"] = 33
|
2017-03-14 02:24:15 +00:00
|
|
|
|
|
|
|
for key in msg_list.keys():
|
|
|
|
if "table" in msg_list[key].keys():
|
2017-03-14 13:44:48 +00:00
|
|
|
d_info("[" + key + "]")
|
2017-03-24 16:07:59 +00:00
|
|
|
cachefile = cachedir + "tlv_msg_" + msg_list[key]["type"] + ".py"
|
2017-03-14 02:24:15 +00:00
|
|
|
if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
|
|
|
|
execfile(cachefile)
|
|
|
|
print "Read from " + cachefile
|
|
|
|
else:
|
2017-03-14 04:50:13 +00:00
|
|
|
document = Document(filename)
|
2017-03-14 02:24:15 +00:00
|
|
|
f = open(cachefile, 'w')
|
|
|
|
|
2017-03-15 07:07:52 +00:00
|
|
|
ies = []
|
|
|
|
write_file(f, "ies = []\n")
|
2017-03-14 04:50:13 +00:00
|
|
|
table = document.tables[msg_list[key]["table"]]
|
2017-03-14 02:24:15 +00:00
|
|
|
for row in table.rows[1:]:
|
2017-03-14 13:44:48 +00:00
|
|
|
cells = get_cells(row.cells)
|
|
|
|
if cells is None:
|
2017-03-14 02:24:15 +00:00
|
|
|
continue
|
2017-03-14 14:56:12 +00:00
|
|
|
|
2017-03-15 01:53:33 +00:00
|
|
|
ies_is_added = True
|
2017-03-14 14:56:12 +00:00
|
|
|
for ie in ies:
|
|
|
|
if (cells["ie_type"], cells["instance"]) == (ie["ie_type"], ie["instance"]):
|
2017-03-15 01:53:33 +00:00
|
|
|
ies_is_added = False
|
|
|
|
if ies_is_added is True:
|
2017-03-14 14:56:12 +00:00
|
|
|
ies.append(cells)
|
|
|
|
write_cells_to_file("ies", cells)
|
2017-03-14 04:50:13 +00:00
|
|
|
msg_list[key]["ies"] = ies
|
2017-03-15 02:54:08 +00:00
|
|
|
write_file(f, "msg_list[key][\"ies\"] = ies\n")
|
2017-03-14 02:24:15 +00:00
|
|
|
f.close()
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2017-03-15 13:28:04 +00:00
|
|
|
type_list["Recovery"]["size"] = 1 # Type : 3
|
|
|
|
type_list["EBI"]["size"] = 1 # Type : 73
|
|
|
|
type_list["RAT Type"]["size"] = 1 # Type : 82
|
|
|
|
type_list["PDN Type"]["size"] = 1 # Type : 99
|
|
|
|
type_list["Port Number"]["size"] = 2 # Type : 126
|
|
|
|
type_list["APN Restriction"]["size"] = 1 # Type : 127
|
|
|
|
type_list["Selection Mode"]["size"] = 1 # Type : 128
|
|
|
|
|
2017-03-24 16:07:59 +00:00
|
|
|
f = open(outdir + 'gtp_tlv.h', 'w')
|
2017-03-14 13:44:48 +00:00
|
|
|
output_header_to_file(f)
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("""#ifndef __GTP_TLV_H__
|
|
|
|
#define __GTP_TLV_H__
|
2017-03-14 08:09:27 +00:00
|
|
|
|
|
|
|
#include "core_tlv_msg.h"
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
tmp = [(k, v["type"]) for k, v in msg_list.items()]
|
|
|
|
sorted_msg_list = sorted(tmp, key=lambda tup: int(tup[1]))
|
|
|
|
for (k, v) in sorted_msg_list:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("#define GTP_" + v_upper(k) + "_TYPE " + v + "\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
|
|
|
|
tmp = [(k, v["type"]) for k, v in type_list.items()]
|
|
|
|
sorted_type_list = sorted(tmp, key=lambda tup: int(tup[1]))
|
|
|
|
for (k, v) in sorted_type_list:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("#define TLV_" + v_upper(k) + "_TYPE " + v + "\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("/* Infomration Element TLV Descriptor */\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
for (k, v) in sorted_type_list:
|
2017-03-17 15:11:57 +00:00
|
|
|
if k in group_list.keys():
|
|
|
|
continue
|
|
|
|
for instance in range(0, int(type_list[k]["max_instance"])+1):
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("extern tlv_desc_t tlv_desc_" + v_lower(k))
|
2017-03-17 15:11:57 +00:00
|
|
|
f.write("_" + str(instance) + ";\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2017-03-15 01:53:33 +00:00
|
|
|
tmp = [(k, v["type"]) for k, v in group_list.items()]
|
|
|
|
sorted_group_list = sorted(tmp, key=lambda tup: int(tup[1]))
|
2017-03-15 05:10:34 +00:00
|
|
|
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("/* Group Infomration Element TLV Descriptor */\n")
|
2017-03-15 01:53:33 +00:00
|
|
|
for (k, v) in sorted_group_list:
|
2017-03-15 05:10:34 +00:00
|
|
|
for instance in range(0, int(type_list[k]["max_instance"])+1):
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("extern tlv_desc_t tlv_desc_" + v_lower(k))
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("_" + str(instance) + ";\n")
|
|
|
|
f.write("\n")
|
2017-03-14 12:02:15 +00:00
|
|
|
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("/* Message Descriptor */\n")
|
2017-03-15 07:07:52 +00:00
|
|
|
for (k, v) in sorted_msg_list:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("extern tlv_desc_t tlv_desc_" + v_lower(k) + ";\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-15 07:07:52 +00:00
|
|
|
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("/* Structure for Infomration Element */\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
for (k, v) in sorted_type_list:
|
2017-03-17 15:11:57 +00:00
|
|
|
if k in group_list.keys():
|
|
|
|
continue
|
|
|
|
if "size" in type_list[k]:
|
|
|
|
if type_list[k]["size"] == 1:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("typedef tlv_uint8_t tlv_" + v_lower(k) + "_t;\n")
|
2017-03-17 15:11:57 +00:00
|
|
|
elif type_list[k]["size"] == 2:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("typedef tlv_uint16_t tlv_" + v_lower(k) + "_t;\n")
|
2017-03-17 15:11:57 +00:00
|
|
|
elif type_list[k]["size"] == 3:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("typedef tlv_uint24_t tlv_" + v_lower(k) + "_t;\n")
|
2017-03-17 15:11:57 +00:00
|
|
|
elif type_list[k]["size"] == 4:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("typedef tlv_uint32_t tlv_" + v_lower(k) + "_t;\n")
|
2017-03-15 13:28:04 +00:00
|
|
|
else:
|
2017-03-17 15:11:57 +00:00
|
|
|
assert False, "Unknown size = %d for key = %s" % (type_list[k]["size"], k)
|
|
|
|
else:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("typedef tlv_octet_t tlv_" + v_lower(k) + "_t;\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("/* Structure for Group Infomration Element */\n")
|
2017-03-15 01:53:33 +00:00
|
|
|
for (k, v) in sorted_group_list:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("typedef struct _tlv_" + v_lower(k) + "_t {\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(" tlv_presence_t presence;\n")
|
2017-03-15 07:26:29 +00:00
|
|
|
for ies in group_list[k]["ies"]:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write(" tlv_" + v_lower(ies["ie_type"]) + "_t " + \
|
2017-03-15 07:26:29 +00:00
|
|
|
v_lower(ies["ie_value"]))
|
|
|
|
if ies["ie_type"] == "F-TEID":
|
|
|
|
if ies["ie_value"] == "S2b-U ePDG F-TEID":
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("_" + ies["instance"] + ";")
|
2017-03-15 07:26:29 +00:00
|
|
|
elif ies["ie_value"] == "S2a-U TWAN F-TEID":
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("_" + ies["instance"] + ";")
|
2017-03-15 03:05:10 +00:00
|
|
|
else:
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(";")
|
|
|
|
f.write(" /* Instance : " + ies["instance"] + " */\n")
|
2017-03-15 01:53:33 +00:00
|
|
|
else:
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(";\n")
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("} tlv_" + v_lower(k) + "_t;\n")
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-15 01:53:33 +00:00
|
|
|
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("/* Structure for Message */\n")
|
2017-03-15 07:07:52 +00:00
|
|
|
for (k, v) in sorted_msg_list:
|
|
|
|
if "ies" in msg_list[k]:
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write("typedef struct _gtp_" + v_lower(k) + "_t {\n")
|
2017-03-15 07:07:52 +00:00
|
|
|
for ies in msg_list[k]["ies"]:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write(" tlv_" + v_lower(ies["ie_type"]) + "_t " + \
|
2017-03-15 07:07:52 +00:00
|
|
|
v_lower(ies["ie_value"]) + ";\n")
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write("} gtp_" + v_lower(k) + "_t;\n")
|
|
|
|
f.write("\n")
|
|
|
|
|
|
|
|
f.write("typedef struct _gtp_message_t {\n")
|
|
|
|
f.write(" union {\n")
|
|
|
|
for (k, v) in sorted_msg_list:
|
|
|
|
if "ies" in msg_list[k]:
|
|
|
|
f.write(" gtp_" + v_lower(k) + "_t " + v_lower(k) + ";\n");
|
|
|
|
f.write(" };\n");
|
|
|
|
f.write("} gtp_message_t;\n\n")
|
2017-03-15 07:07:52 +00:00
|
|
|
|
2017-04-03 13:48:37 +00:00
|
|
|
f.write("""CORE_DECLARE(status_t) gtp_parse_msg(
|
2017-04-03 13:09:48 +00:00
|
|
|
gtp_message_t *gtp_message, c_uint8_t type, pkbuf_t *pkbuf);
|
2017-04-02 13:30:58 +00:00
|
|
|
CORE_DECLARE(status_t) gtp_build_msg(
|
2017-04-03 13:09:48 +00:00
|
|
|
pkbuf_t **pkbuf, c_uint8_t type, gtp_message_t *gtp_message);
|
2017-03-29 10:31:39 +00:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
2017-03-14 08:09:27 +00:00
|
|
|
}
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
2017-03-24 16:07:59 +00:00
|
|
|
#endif /* __GTP_TLV_H__ */
|
2017-03-14 08:09:27 +00:00
|
|
|
""")
|
|
|
|
f.close()
|
|
|
|
|
2017-03-24 16:07:59 +00:00
|
|
|
f = open(outdir + 'gtp_tlv.c', 'w')
|
2017-03-14 13:44:48 +00:00
|
|
|
output_header_to_file(f)
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write("""#include "core_debug.h"
|
|
|
|
#include "gtp_tlv.h"
|
2017-03-14 08:09:27 +00:00
|
|
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
for (k, v) in sorted_type_list:
|
2017-03-17 15:11:57 +00:00
|
|
|
if k in group_list.keys():
|
|
|
|
continue
|
|
|
|
for instance in range(0, int(type_list[k]["max_instance"])+1):
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("tlv_desc_t tlv_desc_%s_%d =\n" % (v_lower(k), instance))
|
2017-03-17 15:11:57 +00:00
|
|
|
f.write("{\n")
|
|
|
|
if "size" in type_list[k]:
|
|
|
|
if type_list[k]["size"] == 1:
|
|
|
|
f.write(" TLV_UINT8,\n")
|
|
|
|
elif type_list[k]["size"] == 2:
|
|
|
|
f.write(" TLV_UINT16,\n")
|
|
|
|
elif type_list[k]["size"] == 3:
|
|
|
|
f.write(" TLV_UINT24,\n")
|
|
|
|
elif type_list[k]["size"] == 4:
|
|
|
|
f.write(" TLV_UINT32,\n")
|
2017-03-15 13:28:04 +00:00
|
|
|
else:
|
2017-03-17 15:11:57 +00:00
|
|
|
assert False, "Unknown size = %d for key = %s" % (type_list[k]["size"], k)
|
|
|
|
else:
|
|
|
|
f.write(" TLV_VAR_STR,\n")
|
|
|
|
f.write(" \"%s\",\n" % k)
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write(" TLV_%s_TYPE,\n" % v_upper(k))
|
2017-03-17 15:11:57 +00:00
|
|
|
if "size" in type_list[k]:
|
|
|
|
f.write(" %d,\n" % type_list[k]["size"])
|
|
|
|
else:
|
|
|
|
f.write(" 0,\n")
|
|
|
|
f.write(" %d,\n" % instance)
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write(" sizeof(tlv_%s_t),\n" % v_lower(k))
|
2017-03-17 15:11:57 +00:00
|
|
|
f.write(" { NULL }\n")
|
|
|
|
f.write("};\n\n")
|
2017-03-15 05:10:34 +00:00
|
|
|
|
|
|
|
for (k, v) in sorted_group_list:
|
|
|
|
for instance in range(0, int(type_list[k]["max_instance"])+1):
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write("tlv_desc_t tlv_desc_%s_%d =\n" % (v_lower(k), instance))
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("{\n")
|
|
|
|
f.write(" TLV_COMPOUND,\n")
|
|
|
|
f.write(" \"%s\",\n" % k)
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write(" TLV_%s_TYPE,\n" % v_upper(k))
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(" 0,\n")
|
|
|
|
f.write(" %d,\n" % instance)
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write(" sizeof(tlv_%s_t),\n" % v_lower(k))
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(" {\n")
|
2017-03-15 07:26:29 +00:00
|
|
|
for ies in group_list[k]["ies"]:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write(" &tlv_desc_%s_%s,\n" % (v_lower(ies["ie_type"]), v_lower(ies["instance"])))
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write(" NULL,\n")
|
|
|
|
f.write(" }\n")
|
|
|
|
f.write("};\n\n")
|
2017-03-15 01:53:33 +00:00
|
|
|
|
2017-03-15 07:20:13 +00:00
|
|
|
for (k, v) in sorted_msg_list:
|
|
|
|
if "ies" in msg_list[k]:
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write("tlv_desc_t tlv_desc_%s =\n" % v_lower(k))
|
|
|
|
f.write("{\n")
|
|
|
|
f.write(" TLV_MESSAGE,\n")
|
|
|
|
f.write(" \"%s\",\n" % k)
|
|
|
|
f.write(" 0, 0, 0, 0, {\n")
|
2017-03-15 07:20:13 +00:00
|
|
|
for ies in msg_list[k]["ies"]:
|
2017-03-24 16:07:59 +00:00
|
|
|
f.write(" &tlv_desc_%s_%s,\n" % (v_lower(ies["ie_type"]), v_lower(ies["instance"])))
|
2017-03-29 10:31:39 +00:00
|
|
|
f.write(" NULL,\n")
|
|
|
|
f.write("}};\n\n")
|
|
|
|
f.write("\n")
|
|
|
|
|
2017-04-03 13:09:48 +00:00
|
|
|
f.write("""status_t gtp_parse_msg(gtp_message_t *gtp_message, c_uint8_t type, pkbuf_t *pkbuf)
|
2017-03-29 10:31:39 +00:00
|
|
|
{
|
|
|
|
status_t rv = CORE_ERROR;
|
|
|
|
|
2017-04-03 13:09:48 +00:00
|
|
|
memset(gtp_message, 0, sizeof(gtp_message_t));
|
|
|
|
switch(type)
|
2017-03-29 10:31:39 +00:00
|
|
|
{
|
|
|
|
""")
|
|
|
|
for (k, v) in sorted_msg_list:
|
|
|
|
if "ies" in msg_list[k]:
|
|
|
|
f.write(" case GTP_%s_TYPE:\n" % v_upper(k))
|
|
|
|
f.write(" rv = tlv_parse_msg(>p_message->%s,\n" % v_lower(k))
|
|
|
|
f.write(" &tlv_desc_%s, pkbuf, TLV_MODE_T1_L2_I1);\n" % v_lower(k))
|
|
|
|
f.write(" break;\n")
|
|
|
|
f.write(""" default:
|
2017-04-03 13:09:48 +00:00
|
|
|
d_warn("Not implmeneted(type:%d)", type);
|
2017-04-02 13:30:58 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
""")
|
|
|
|
|
2017-04-03 13:09:48 +00:00
|
|
|
f.write("""status_t gtp_build_msg(pkbuf_t **pkbuf, c_uint8_t type, gtp_message_t *gtp_message)
|
2017-04-02 13:30:58 +00:00
|
|
|
{
|
|
|
|
status_t rv = CORE_ERROR;
|
|
|
|
|
2017-04-03 13:09:48 +00:00
|
|
|
switch(type)
|
2017-04-02 13:30:58 +00:00
|
|
|
{
|
|
|
|
""")
|
|
|
|
for (k, v) in sorted_msg_list:
|
|
|
|
if "ies" in msg_list[k]:
|
|
|
|
f.write(" case GTP_%s_TYPE:\n" % v_upper(k))
|
|
|
|
f.write(" rv = tlv_build_msg(pkbuf, &tlv_desc_%s,\n" % v_lower(k))
|
|
|
|
f.write(" >p_message->%s, TLV_MODE_T1_L2_I1);\n" % v_lower(k))
|
|
|
|
f.write(" break;\n")
|
|
|
|
f.write(""" default:
|
2017-04-03 13:09:48 +00:00
|
|
|
d_warn("Not implmeneted(type:%d)", type);
|
2017-03-29 10:31:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
""")
|
2017-03-15 07:20:13 +00:00
|
|
|
|
2017-03-17 11:20:37 +00:00
|
|
|
f.write("\n")
|
2017-03-14 08:09:27 +00:00
|
|
|
|
|
|
|
f.close()
|