blob: 220517d0d9d732b96ddd9282674b0c5dec240b5e [file] [log] [blame]
Oliver Smith16441ff2019-12-11 09:03:33 +01001#!/usr/bin/env python3
Harald Welte245daf92015-08-30 22:38:40 +02002
3import re, os, sys, string
4import datetime
5import getopt
6import getpass
Bernhard M. Wiedemann7a97fca2018-05-30 13:20:29 +02007import time
Harald Welte245daf92015-08-30 22:38:40 +02008
Harald Welte84839c02015-09-10 18:33:14 +02009version = "0.5osmo1"
Harald Welte245daf92015-08-30 22:38:40 +020010
11lines = ""
12iesDefs = {}
13ieofielist = {}
14outdir = './'
15
16filenames = []
17verbosity = 0
18prefix = ""
19
20FAIL = '\033[91m'
21WARN = '\033[93m'
22ENDC = '\033[0m'
23
24fileprefix = ""
25
26def printFail(string):
27 sys.stderr.write(FAIL + string + ENDC + "\n")
28
29def printWarning(string):
Oliver Smith16441ff2019-12-11 09:03:33 +010030 print(WARN + string + ENDC)
Harald Welte245daf92015-08-30 22:38:40 +020031
32def printDebug(string):
33 if verbosity > 0:
Oliver Smith16441ff2019-12-11 09:03:33 +010034 print(string)
Harald Welte245daf92015-08-30 22:38:40 +020035
36def outputHeaderToFile(f, filename):
Bernhard M. Wiedemann7a97fca2018-05-30 13:20:29 +020037 now = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time())))
Harald Welte245daf92015-08-30 22:38:40 +020038 f.write("/*******************************************************************************\n")
39 f.write(" * This file had been created by asn1tostruct.py script v%s\n" % (version))
40 f.write(" * Please do not modify this file but regenerate it via script.\n")
Bernhard M. Wiedemann7a97fca2018-05-30 13:20:29 +020041 f.write(" * Created on: %s\n * from %s\n" % (str(now), filenames))
Harald Welte245daf92015-08-30 22:38:40 +020042 f.write(" ******************************************************************************/\n")
43
44def lowerFirstCamelWord(word):
45 """ puts the first word in a CamelCase Word in lowercase.
46
47 I.e. CustomerID becomes customerID, XMLInfoTest becomes xmlInfoTest
48 """
49 newstr = ''
50 swapped = word.swapcase()
51 idx = 0
52
53 # if it's all-caps, return an all-lowered version
54 lowered = word.lower()
55
56 if swapped == lowered:
57 return lowered
58
59 for c in swapped:
Oliver Smith16441ff2019-12-11 09:03:33 +010060 if c.islower():
Harald Welte245daf92015-08-30 22:38:40 +020061 newstr += c
62 idx += 1
63 else:
64 break
65 if idx < 2:
66 newstr += word[idx:]
67 else:
68 newstr = newstr[:-1]+ word[idx-1:]
69
70 return newstr
71
72def usage():
Oliver Smith16441ff2019-12-11 09:03:33 +010073 print("Python parser for asn1 v%s" % (version))
74 print("Usage: python asn1tostruct.py [options]")
75 print("Available options:")
76 print("-d Enable script debug")
77 print("-f [file] Input file to parse")
78 print("-o [dir] Output files to given directory")
79 print("-p [pfx] Prefix all types with given prefix")
80 print("-h Print this help and return")
Harald Welte245daf92015-08-30 22:38:40 +020081
82try:
Harald Welte84839c02015-09-10 18:33:14 +020083 opts, args = getopt.getopt(sys.argv[1:], "df:ho:p:", ["debug", "file", "help", "outdir", "prefix"])
Harald Welte245daf92015-08-30 22:38:40 +020084except getopt.GetoptError as err:
85 # print help information and exit:
86 usage()
87 sys.exit(2)
88
89for o, a in opts:
90 if o in ("-f", "--file"):
91 filenames.append(a)
92 if o in ("-d", "--debug"):
93 verbosity = 1
94 if o in ("-o", "--outdir"):
95 outdir = a
96 if outdir.rfind('/') != len(outdir):
97 outdir += '/'
Harald Welte84839c02015-09-10 18:33:14 +020098 if o in ("-p", "--prefix"):
99 prefix = a
Harald Welte245daf92015-08-30 22:38:40 +0200100 if o in ("-h", "--help"):
101 usage()
102 sys.exit(2)
103
104for filename in filenames:
Oliver Smith16441ff2019-12-11 09:03:33 +0100105 file = open(filename, 'r', encoding='utf-8')
Harald Welte245daf92015-08-30 22:38:40 +0200106 for line in file:
107 # Removing any comment
108 if line.find('--') >= 0:
109 line = line[:line.find('--')]
110 # Removing any carriage return
111 lines += re.sub('\r', '', line)
112
113 for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+SEQUENCE\s+\(\s*SIZE\s*\(\s*\d+\s*\.\.\s*[0-9a-zA-Z-]+\s*\)\s*\)\s*OF\s+[a-zA-Z-]+\s*\{\s*\{\s*([0-9a-zA-Z-]+)\s*\}\s*\}', lines, re.MULTILINE):
114 ieofielist[m[0]] = m[1]
115 for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+E-RAB-IE-ContainerList\s*\{\s*\{\s*([a-zA-Z0-9-]+)\s*\}\s*\}', lines, re.MULTILINE):
116 ieofielist[m[0]] = m[1]
117
118 for i in re.findall(r'([a-zA-Z0-9-]+)\s+([A-Z0-9-]+)\s*::=\s*\{\s+([\,\|\{\}\t\n\.{3}\ \-a-zA-Z0-9]+)\s+}\n', lines, re.MULTILINE):
119 ies = []
120 maxLength = 0
121 # TODO: handle extensions
122 if i[1].find('EXTENSION') >= 0:
123 continue
124 if fileprefix == "":
125 fileprefix = i[1][:i[1].find('-')].lower()
126 for j in re.findall(r'\s*\{\s*([a-zA-Z0-9-\ \t]+)\s*\}\s*[\|,]*', i[2], re.MULTILINE):
127 for k in re.findall(r'ID\s*([a-zA-Z0-9\-]+)\s*CRITICALITY\s*([a-zA-Z0-9\-]+)\s+[A-Z]+\s+([a-zA-Z0-9\-]+)\s*PRESENCE\s*([a-zA-Z0-9\-]+)', j, re.MULTILINE):
128 printDebug("Got new ie for message " + i[0] + ": " + str(k))
129 if len(k[2]) > maxLength:
130 maxLength = len(k[2])
131 ies.append(k)
132
133 if len(ies) > 0:
134 iesDefs[i[0]] = { "length": maxLength, "ies": ies}
135 else:
136 printWarning("Didn't find any information element for message: " + i[0])
137
138if len(iesDefs) == 0:
139 printFail("No Information Element parsed, exiting")
140 sys.exit(0)
141
Oliver Smith16441ff2019-12-11 09:03:33 +0100142f = open(outdir + fileprefix + '_ies_defs.h', 'w', encoding='utf-8')
Harald Welte245daf92015-08-30 22:38:40 +0200143outputHeaderToFile(f, filename)
144f.write("#include \"%s_common.h\"\n\n" % (fileprefix))
145f.write("#ifndef %s_IES_DEFS_H_\n#define %s_IES_DEFS_H_\n\n" % (fileprefix.upper(), fileprefix.upper()))
146
147for key in iesDefs:
148
Oliver Smith16441ff2019-12-11 09:03:33 +0100149 if key not in list(ieofielist.values()):
Harald Welte245daf92015-08-30 22:38:40 +0200150 continue
151
Oliver Smith16441ff2019-12-11 09:03:33 +0100152 for (i, j) in list(ieofielist.items()):
Harald Welte245daf92015-08-30 22:38:40 +0200153 if j == key:
154 break
155
Harald Welte84839c02015-09-10 18:33:14 +0200156 f.write("typedef struct %sIEs_s {\n" % (prefix + re.sub('-', '_', i)))
157 f.write(" A_SEQUENCE_OF(struct %s_s) %s;\n" % (prefix + re.sub('IEs', '', re.sub('-', '_', ieofielist[i])), lowerFirstCamelWord(re.sub('IEs', '', re.sub('-', '_', ieofielist[i])))))
158 f.write("} %sIEs_t;\n\n" % (prefix + re.sub('-', '_', i)))
Harald Welte245daf92015-08-30 22:38:40 +0200159
160for key in iesDefs:
161 keyupperunderscore = re.sub('-', '_', key.upper())
162 keylowerunderscore = re.sub('-', '_', key.lower())
163 shift = 0
164
165 if len(iesDefs[key]["ies"]) == 0:
166 continue
167
168 # Presence mask
169 for ie in iesDefs[key]["ies"]:
170 ieupperunderscore = re.sub('-', '_', ie[2].upper())
171 if ie[3] == "optional" or ie[3] == "conditional":
Harald Welte84839c02015-09-10 18:33:14 +0200172 f.write("#define {0:<{pad}} {1}\n".format("%s_%s%s_PRESENT" % (keyupperunderscore, prefix, ieupperunderscore), "(1 << %d)" % shift,
Harald Welte245daf92015-08-30 22:38:40 +0200173 pad=iesDefs[key]["length"] + len(keyupperunderscore) + 9))
174 shift += 1
175 if (shift > 0):
176 f.write("\n")
177
Harald Welte84839c02015-09-10 18:33:14 +0200178 f.write("typedef struct %s_s {\n" % (prefix + re.sub('-', '_', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200179 if (shift > 0):
180 f.write(" {0:<{pad}} {1};\n".format("uint16_t", "presenceMask", pad=iesDefs[key]["length"] + 2))
181 for ie in iesDefs[key]["ies"]:
Harald Welte84839c02015-09-10 18:33:14 +0200182 ieunderscore = prefix + re.sub('-', '_', ie[2])
Harald Welte245daf92015-08-30 22:38:40 +0200183 iename = re.sub('id-', '', ie[0])
184 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
185 if ie[2] in ieofielist:
186 f.write(" %sIEs_t %s;" % (re.sub('-', '_', ie[2]), ienameunderscore))
187 else:
188 f.write(" {0:<{pad}} {1};".format("%s_t" % ieunderscore, ienameunderscore, pad=iesDefs[key]["length"] + 2))
189 if ie[3] == "optional":
190 f.write(" ///< Optional field")
191 elif ie[3] == "conditional":
192 f.write(" ///< Conditional field")
193 f.write("\n")
194
Harald Welte84839c02015-09-10 18:33:14 +0200195 f.write("} %s_t;\n\n" % (prefix + re.sub('-', '_', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200196
197f.write("typedef struct %s_message_s {\n" % (fileprefix))
198f.write(" uint8_t procedureCode;\n")
199f.write(" uint8_t criticality;\n")
200f.write(" uint8_t direction;\n")
201f.write(" union {\n")
202
Oliver Smith16441ff2019-12-11 09:03:33 +0100203messageList = list(iesDefs.keys())
Harald Welte245daf92015-08-30 22:38:40 +0200204messageList.sort()
205for message in messageList:
Oliver Smith16441ff2019-12-11 09:03:33 +0100206 if message in list(ieofielist.values()):
Harald Welte245daf92015-08-30 22:38:40 +0200207 continue
208 if len(iesDefs[message]["ies"]) == 0:
209 continue
Harald Welte84839c02015-09-10 18:33:14 +0200210 f.write(" %s_t %s;\n" % (prefix + re.sub('-', '_', message), lowerFirstCamelWord(re.sub('-', '_', message))))
Harald Welte245daf92015-08-30 22:38:40 +0200211f.write(" } msg;\n")
212f.write("} %s_message;\n\n" % (fileprefix))
213
214for key in iesDefs:
Oliver Smith16441ff2019-12-11 09:03:33 +0100215 if key in list(ieofielist.values()):
Harald Welte245daf92015-08-30 22:38:40 +0200216 continue
217 structName = re.sub('ies', '', key)
218 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte84839c02015-09-10 18:33:14 +0200219 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
Harald Welte245daf92015-08-30 22:38:40 +0200220 keylowerunderscore = re.sub('-', '_', key.lower())
221 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
222 f.write("/** \\brief Decode function for %s ies.\n" % (key))
223 if len(iesDefs[key]["ies"]) != 0:
224 f.write(" * \\param %s Pointer to ASN1 structure in which data will be stored\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
225 f.write(" * \\param any_p Pointer to the ANY value to decode.\n")
226 f.write(" **/\n")
227 f.write("int %s_decode_%s(\n" % (fileprefix, keylowerunderscore))
228
229 if len(iesDefs[key]["ies"]) != 0:
Harald Welte84839c02015-09-10 18:33:14 +0200230 f.write(" %s_t *%s,\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200231 f.write(" ANY_t *any_p);\n\n")
232
233 if len(iesDefs[key]["ies"]) == 0:
234 continue
235
236 f.write("/** \\brief Encode function for %s ies.\n" % (key))
237 f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
238 f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
239 f.write(" **/\n")
240 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
241 f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower))
Harald Welte84839c02015-09-10 18:33:14 +0200242 f.write(" %s_t *%s);\n\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200243
244for key in iesDefs:
Oliver Smith16441ff2019-12-11 09:03:33 +0100245 if key not in list(ieofielist.values()):
Harald Welte245daf92015-08-30 22:38:40 +0200246 continue
247 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
Harald Welte84839c02015-09-10 18:33:14 +0200248 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
Harald Welte245daf92015-08-30 22:38:40 +0200249 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
250 f.write("/** \\brief Encode function for %s ies.\n" % (key))
251 f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
252 f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
253 f.write(" **/\n")
254 f.write("int %s_encode_%s(\n" % (fileprefix, firstlower.lower()))
255 f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower))
256 f.write(" %sIEs_t *%sIEs);\n\n" % (asn1cStruct, firstlower))
257 f.write("/** \\brief Decode function for %s ies.\n" % (key))
258 f.write(" * \\param any_p Pointer to the ANY value to decode.\n")
259 f.write(" * \\param callback Callback function called when any_p is successfully decoded.\n")
260 f.write(" **/\n")
261 f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower()))
262 f.write(" %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower))
263 f.write(" %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct)))
Daniel Willmann19dea8b2016-02-19 16:53:43 +0100264
265for key in iesDefs:
266 keyupperunderscore = re.sub('-', '_', key.upper())
267 keylowerunderscore = re.sub('-', '_', key.lower())
268 structName = re.sub('ies', '', key)
269
270 if len(iesDefs[key]["ies"]) == 0:
271 continue
272
273 f.write("int %s_free_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
274 if len(iesDefs[key]["ies"]) != 0:
275 f.write(" %s_t *%s);\n\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200276f.write("#endif /* %s_IES_DEFS_H_ */\n\n" % (fileprefix.upper()))
277
278#Generate Decode functions
Oliver Smith16441ff2019-12-11 09:03:33 +0100279f = open(outdir + fileprefix + '_decoder.c', 'w', encoding='utf-8')
Harald Welte245daf92015-08-30 22:38:40 +0200280outputHeaderToFile(f, filename)
281f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix))
282for key in iesDefs:
Oliver Smith16441ff2019-12-11 09:03:33 +0100283 if key in list(ieofielist.values()):
Harald Welte245daf92015-08-30 22:38:40 +0200284 continue
285 structName = re.sub('ies', '', key)
Harald Weltea0c74242015-12-16 16:45:48 +0100286 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200287 ielistname = re.sub('UE', 'ue', asn1cStruct)
288 ielistnamefirstlower = ielistname[:1].lower() + ielistname[1:]
289 asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
290 keyName = re.sub('-', '_', key)
291 keyupperunderscore = keyName.upper()
292 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
Harald Welte84839c02015-09-10 18:33:14 +0200293 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
Harald Welte245daf92015-08-30 22:38:40 +0200294
295 iesaccess = ""
Oliver Smith16441ff2019-12-11 09:03:33 +0100296 if key not in list(ieofielist.values()):
Harald Welte245daf92015-08-30 22:38:40 +0200297 iesaccess = "%s_ies." % (firstlower)
298
299 f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
300 if len(iesDefs[key]["ies"]) != 0:
Harald Welte84839c02015-09-10 18:33:14 +0200301 f.write(" %s_t *%s,\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200302 f.write(" ANY_t *any_p) {\n\n")
303
Neels Hofmeyrc13ebf72016-01-05 12:55:13 +0100304 f.write(" %s_t *%s_p = NULL;\n" % (asn1cStruct, asn1cStructfirstlower))
Harald Welte245daf92015-08-30 22:38:40 +0200305 f.write(" int i, decoded = 0;\n")
306 if len(iesDefs[key]["ies"]) != 0:
307 f.write(" int tempDecoded = 0;\n")
308
309 f.write(" assert(any_p != NULL);\n")
310 if len(iesDefs[key]["ies"]) != 0:
311 f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
Daniel Willmann86a14052016-01-12 09:46:21 +0100312 f.write(" memset(%s, 0, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), prefix + re.sub('-', '_', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200313
Harald Welte84839c02015-09-10 18:33:14 +0200314 f.write(" %s_DEBUG(\"Decoding message %s (%%s:%%d)\\n\", __FILE__, __LINE__);\n\n" % (fileprefix.upper(), prefix + re.sub('-', '_', keyName)))
Neels Hofmeyr6eeef112017-12-20 23:14:45 +0100315 f.write(" tempDecoded = ANY_to_type_aper(any_p, &asn_DEF_%s, (void**)&%s_p);\n\n" % (asn1cStruct, asn1cStructfirstlower))
316 f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (asn1cStructfirstlower))
317 f.write(" %s_DEBUG(\"Decoding of message %s failed\\n\");\n" % (fileprefix.upper(), prefix + re.sub('-', '_', keyName)))
318 f.write(" return -1;\n")
319 f.write(" }\n\n")
320
Harald Welte245daf92015-08-30 22:38:40 +0200321 f.write(" for (i = 0; i < %s_p->%slist.count; i++) {\n" % (asn1cStructfirstlower, iesaccess))
Harald Welte84839c02015-09-10 18:33:14 +0200322 f.write(" %sIE_t *ie_p;\n" % (prefix))
Harald Welte245daf92015-08-30 22:38:40 +0200323 f.write(" ie_p = %s_p->%slist.array[i];\n" % (asn1cStructfirstlower, iesaccess))
324 f.write(" switch(ie_p->id) {\n")
325 for ie in iesDefs[key]["ies"]:
326 iename = re.sub('id-', '', ie[0])
327 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
328 ienameunderscorefirstlower = lowerFirstCamelWord(ienameunderscore)
Harald Welte84839c02015-09-10 18:33:14 +0200329 ietypesubst = prefix + re.sub('-', '', ie[2])
330 ietypeunderscore = prefix + re.sub('-', '_', ie[2])
331 ieupperunderscore = prefix + re.sub('-', '_', ie[2]).upper()
Harald Welte245daf92015-08-30 22:38:40 +0200332 if ie[3] == "optional":
333 f.write(" /* Optional field */\n")
334 elif ie[3] == "conditional":
335 f.write(" /* Conditional field */\n")
Harald Welte84839c02015-09-10 18:33:14 +0200336 f.write(" case %sProtocolIE_ID_%s:\n" % (prefix, re.sub('-', '_', ie[0])))
Harald Welte245daf92015-08-30 22:38:40 +0200337 f.write(" {\n")
Neels Hofmeyrc13ebf72016-01-05 12:55:13 +0100338 f.write(" %s_t *%s_p = NULL;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
Harald Welte245daf92015-08-30 22:38:40 +0200339 if ie[3] != "mandatory":
340 f.write(" %s->presenceMask |= %s_%s_PRESENT;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
341 f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
342 f.write(" if (tempDecoded < 0) {\n")
343 f.write(" %s_DEBUG(\"Decoding of IE %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore))
344 f.write(" return -1;\n")
345 f.write(" }\n")
346 f.write(" decoded += tempDecoded;\n")
347 f.write(" if (asn1_xer_print)\n")
348 f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
Oliver Smith16441ff2019-12-11 09:03:33 +0100349 if ie[2] in list(ieofielist.keys()):
Daniel Willmannd174e762015-12-22 16:22:53 +0100350 f.write(" if (%s_decode_%s(&%s->%s, %s_p) < 0) {\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst)))
Harald Welte245daf92015-08-30 22:38:40 +0200351 f.write(" %s_DEBUG(\"Decoding of encapsulated IE %s failed\\n\");\n" % (fileprefix.upper(), lowerFirstCamelWord(ietypesubst)))
Daniel Willmannd174e762015-12-22 16:22:53 +0100352 f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
Harald Welte245daf92015-08-30 22:38:40 +0200353 else:
354 f.write(" memcpy(&%s->%s, %s_p, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst), ietypeunderscore))
Daniel Willmannd10002c2016-01-07 12:27:41 +0100355 f.write(" FREEMEM(%s_p);\n" % (lowerFirstCamelWord(ietypesubst)))
Harald Welte245daf92015-08-30 22:38:40 +0200356 f.write(" } break;\n")
357 f.write(" default:\n")
358 f.write(" %s_DEBUG(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
359 f.write(" return -1;\n")
360 f.write(" }\n")
361 f.write(" }\n")
Daniel Willmannd174e762015-12-22 16:22:53 +0100362 f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (asn1cStruct, asn1cStructfirstlower))
Harald Welte245daf92015-08-30 22:38:40 +0200363 f.write(" return decoded;\n")
364 f.write("}\n\n")
365
366for key in iesDefs:
Daniel Willmannd10002c2016-01-07 12:27:41 +0100367 keyupperunderscore = re.sub('-', '_', key.upper())
368 keylowerunderscore = re.sub('-', '_', key.lower())
369 structName = re.sub('ies', '', key)
370
371 if len(iesDefs[key]["ies"]) == 0:
372 continue
373
374 f.write("int %s_free_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
375 if len(iesDefs[key]["ies"]) != 0:
376 f.write(" %s_t *%s) {\n\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
377
378 for ie in iesDefs[key]["ies"]:
379 ietypeunderscore = prefix + re.sub('-', '_', ie[2])
380 ieupperunderscore = prefix + re.sub('-', '_', ie[2]).upper()
381 if ie[3] != "mandatory":
382 if ie[3] == "optional":
383 f.write(" /* Optional field */\n")
384 elif ie[3] == "conditional":
385 f.write(" /* Conditional field */\n")
386 f.write(" if ((%s->presenceMask & %s_%s_PRESENT)\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
387 f.write(" == %s_%s_PRESENT) \n " % (keyupperunderscore, ieupperunderscore))
388
389 ieunderscore = prefix + re.sub('-', '_', ie[2])
390 iename = re.sub('id-', '', ie[0])
391 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
392 f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s->%s);\n" % (ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore))
Neels Hofmeyrf33d1642017-12-21 05:23:44 +0100393
394 f.write(" return 0;\n")
Daniel Willmannd10002c2016-01-07 12:27:41 +0100395 f.write("}\n\n")
396
397for key in iesDefs:
Oliver Smith16441ff2019-12-11 09:03:33 +0100398 if key not in list(ieofielist.values()):
Harald Welte245daf92015-08-30 22:38:40 +0200399 continue
400
401 keyname = re.sub('IEs', '', re.sub('Item', 'List', key))
402
403 f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', keyname).lower()))
Harald Welte84839c02015-09-10 18:33:14 +0200404 f.write(" %sIEs_t *%sIEs,\n" % (prefix + re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
405 f.write(" %s_t *%s) {\n\n" % (prefix + re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
Harald Welte245daf92015-08-30 22:38:40 +0200406 f.write(" int i, decoded = 0;\n")
407 f.write(" int tempDecoded = 0;\n\n")
408 f.write(" for (i = 0; i < %s->list.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))))
Harald Welte84839c02015-09-10 18:33:14 +0200409 f.write(" %sIE_t *ie_p = %s->list.array[i];\n" % (prefix, lowerFirstCamelWord(re.sub('-', '_', keyname))))
Harald Welte245daf92015-08-30 22:38:40 +0200410 f.write(" switch (ie_p->id) {\n")
411 for ie in iesDefs[key]["ies"]:
412 iename = re.sub('id-', '', ie[0])
413 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
414 f.write(" case ProtocolIE_ID_%s:\n" % (re.sub('-', '_', ie[0])))
415 f.write(" {\n")
Harald Welte84839c02015-09-10 18:33:14 +0200416 f.write(" %s_t *%s_p;\n" % (prefix + re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
Harald Welte245daf92015-08-30 22:38:40 +0200417 f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
Daniel Willmannd174e762015-12-22 16:22:53 +0100418 f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
Harald Welte245daf92015-08-30 22:38:40 +0200419 f.write(" %s_DEBUG(\"Decoding of IE %s for message %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore, re.sub('-', '_', keyname)))
Daniel Willmannd174e762015-12-22 16:22:53 +0100420 f.write(" if (%s_p)\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
421 f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
Harald Welte245daf92015-08-30 22:38:40 +0200422 f.write(" return -1;\n")
423 f.write(" }\n")
424 f.write(" decoded += tempDecoded;\n")
425 f.write(" if (asn1_xer_print)\n")
426 f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
427 f.write(" ASN_SEQUENCE_ADD(&%sIEs->%s, %s_p);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)),
428 re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
429 f.write(" } break;\n")
430 f.write(" default:\n")
431 f.write(" %s_DEBUG(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
432 f.write(" return -1;\n")
433 f.write(" }\n")
434 f.write(" }\n")
435 f.write(" return decoded;\n")
436 f.write("}\n\n")
437
438
439#Generate IES Encode functions
Oliver Smith16441ff2019-12-11 09:03:33 +0100440f = open(outdir + fileprefix + '_encoder.c', 'w', encoding='utf-8')
Harald Welte245daf92015-08-30 22:38:40 +0200441outputHeaderToFile(f,filename)
442f.write("#include \"%s_common.h\"\n" % (fileprefix))
443f.write("#include \"%s_ies_defs.h\"\n\n" % (fileprefix))
444for key in iesDefs:
Oliver Smith16441ff2019-12-11 09:03:33 +0100445 if key in list(ieofielist.values()):
Harald Welte245daf92015-08-30 22:38:40 +0200446 continue
447
448 structName = re.sub('ies', '', key)
Harald Weltea0c74242015-12-16 16:45:48 +0100449 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200450 firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
Harald Welte84839c02015-09-10 18:33:14 +0200451 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
452 asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
Harald Welte245daf92015-08-30 22:38:40 +0200453
454 iesaccess = ""
Oliver Smith16441ff2019-12-11 09:03:33 +0100455 if key not in list(ieofielist.values()):
Harald Welte245daf92015-08-30 22:38:40 +0200456 iesaccess = "%s_ies." % (firstwordlower)
457
458 keyName = re.sub('-', '_', key)
459 keyupperunderscore = keyName.upper()
460 # No IE to encode...
461 if len(iesDefs[key]["ies"]) == 0:
462 continue
463
464 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
465 f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
Harald Welte84839c02015-09-10 18:33:14 +0200466 f.write(" %s_t *%s) {\n\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200467
Harald Welte84839c02015-09-10 18:33:14 +0200468 f.write(" %sIE_t *ie;\n\n" % (prefix))
Harald Welte245daf92015-08-30 22:38:40 +0200469
470 for ie in iesDefs[key]["ies"]:
471 iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
Harald Welte84839c02015-09-10 18:33:14 +0200472 ienameunderscore = prefix + re.sub('-', '_', iename)
Harald Welte245daf92015-08-30 22:38:40 +0200473 ienamefirstwordlower = lowerFirstCamelWord(iename)
Harald Welte84839c02015-09-10 18:33:14 +0200474 ieupperunderscore = prefix + re.sub('-', '_', ie[2]).upper()
475 ietypeunderscore = prefix + re.sub('-', '_', ie[2])
Harald Welte245daf92015-08-30 22:38:40 +0200476 if ie[3] != "mandatory":
477 if ie[3] == "optional":
478 f.write(" /* Optional field */\n")
479 elif ie[3] == "conditional":
480 f.write(" /* Conditional field */\n")
481 f.write(" if ((%s->presenceMask & %s_%s_PRESENT)\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
482 f.write(" == %s_%s_PRESENT) {\n" % (keyupperunderscore, ieupperunderscore))
Harald Welte84839c02015-09-10 18:33:14 +0200483 f.write(" if ((ie = %s_new_ie(%sProtocolIE_ID_%s,\n" % (fileprefix, prefix, re.sub('-', '_', ie[0])))
484 f.write(" %sCriticality_%s,\n" % (prefix, ie[1]))
Harald Welte245daf92015-08-30 22:38:40 +0200485 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
486 f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
487 f.write(" return -1;\n")
488 f.write(" }\n")
489 f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n" % (firstwordlower, iesaccess))
490 f.write(" }\n\n")
491 else:
Oliver Smith16441ff2019-12-11 09:03:33 +0100492 if ie[2] in list(ieofielist.keys()):
Harald Welte84839c02015-09-10 18:33:14 +0200493 f.write(" %s_t %s;\n\n" % (prefix + ietypeunderscore, ienamefirstwordlower))
Harald Welte245daf92015-08-30 22:38:40 +0200494 f.write(" memset(&%s, 0, sizeof(%s_t));\n" % (ienamefirstwordlower, ietypeunderscore))
495 f.write("\n")
496 f.write(" if (%s_encode_%s(&%s, &%s->%s) < 0) return -1;\n" % (fileprefix, ietypeunderscore.lower(), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
Harald Welte84839c02015-09-10 18:33:14 +0200497 f.write(" if ((ie = %s_new_ie(%sProtocolIE_ID_%s,\n" % (fileprefix, prefix, re.sub('-', '_', ie[0])))
498 f.write(" %sCriticality_%s,\n" % (prefix, ie[1]))
Harald Welte245daf92015-08-30 22:38:40 +0200499 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
Oliver Smith16441ff2019-12-11 09:03:33 +0100500 if ie[2] in list(ieofielist.keys()):
Harald Welte245daf92015-08-30 22:38:40 +0200501 f.write(" &%s)) == NULL) {\n" % (ienamefirstwordlower))
502 else:
503 f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
504 f.write(" return -1;\n")
505 f.write(" }\n")
506 f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n\n" % (firstwordlower, iesaccess))
Oliver Smith16441ff2019-12-11 09:03:33 +0100507 if ie[2] in list(ieofielist.keys()):
Daniel Willmannd174e762015-12-22 16:22:53 +0100508 f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s);\n\n" % (ietypeunderscore, ienamefirstwordlower))
Harald Welte245daf92015-08-30 22:38:40 +0200509
510 f.write(" return 0;\n")
511 f.write("}\n\n")
512
Oliver Smith16441ff2019-12-11 09:03:33 +0100513for (key, value) in list(iesDefs.items()):
514 if key not in list(ieofielist.values()):
Harald Welte245daf92015-08-30 22:38:40 +0200515 continue
516
517 ie = value["ies"][0]
518 ietypeunderscore = re.sub('-', '_', ie[2])
519 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte84839c02015-09-10 18:33:14 +0200520 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
Harald Welte245daf92015-08-30 22:38:40 +0200521 firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
522
Oliver Smith16441ff2019-12-11 09:03:33 +0100523 for (i, j) in list(ieofielist.items()):
Harald Welte245daf92015-08-30 22:38:40 +0200524 if j == key:
525 break
526 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', i).lower()))
527 f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
Harald Welte84839c02015-09-10 18:33:14 +0200528 f.write(" %sIEs_t *%sIEs) {\n\n" % (prefix + re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i))))
Harald Welte245daf92015-08-30 22:38:40 +0200529 f.write(" int i;\n")
530
Harald Welte84839c02015-09-10 18:33:14 +0200531 f.write(" %sIE_t *ie;\n\n" % (prefix))
Harald Welte245daf92015-08-30 22:38:40 +0200532
533 f.write(" for (i = 0; i < %sIEs->%s.count; i++) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
534 f.write(" if ((ie = %s_new_ie(ProtocolIE_ID_%s,\n" % (fileprefix, re.sub('-', '_', ie[0])))
535 f.write(" Criticality_%s,\n" % (ie[1]))
536 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
537 f.write(" %sIEs->%s.array[i])) == NULL) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
538 f.write(" return -1;\n")
539 f.write(" }\n")
540 f.write(" ASN_SEQUENCE_ADD(&%s->list, ie);\n" % (firstwordlower))
541 f.write(" }\n")
542 f.write(" return 0;\n")
543 f.write("}\n\n")