blob: 5586e40b0f98a28a1bd38930187865a604240583 [file] [log] [blame]
Pau Espin Pedrol166a3762017-04-05 11:22:48 +02001#!/usr/bin/env python2
Harald Welte245daf92015-08-30 22:38:40 +02002
3import re, os, sys, string
4import datetime
5import getopt
6import getpass
7
Harald Welte84839c02015-09-10 18:33:14 +02008version = "0.5osmo1"
Harald Welte245daf92015-08-30 22:38:40 +02009
10lines = ""
11iesDefs = {}
12ieofielist = {}
13outdir = './'
14
15filenames = []
16verbosity = 0
17prefix = ""
18
19FAIL = '\033[91m'
20WARN = '\033[93m'
21ENDC = '\033[0m'
22
23fileprefix = ""
24
25def printFail(string):
26 sys.stderr.write(FAIL + string + ENDC + "\n")
27
28def printWarning(string):
29 print WARN + string + ENDC
30
31def printDebug(string):
32 if verbosity > 0:
33 print string
34
35def outputHeaderToFile(f, filename):
36 now = datetime.datetime.now()
Harald Welte245daf92015-08-30 22:38:40 +020037 f.write("/*******************************************************************************\n")
38 f.write(" * This file had been created by asn1tostruct.py script v%s\n" % (version))
39 f.write(" * Please do not modify this file but regenerate it via script.\n")
40 f.write(" * Created on: %s by %s\n * from %s\n" % (str(now), getpass.getuser(), filenames))
41 f.write(" ******************************************************************************/\n")
42
43def lowerFirstCamelWord(word):
44 """ puts the first word in a CamelCase Word in lowercase.
45
46 I.e. CustomerID becomes customerID, XMLInfoTest becomes xmlInfoTest
47 """
48 newstr = ''
49 swapped = word.swapcase()
50 idx = 0
51
52 # if it's all-caps, return an all-lowered version
53 lowered = word.lower()
54
55 if swapped == lowered:
56 return lowered
57
58 for c in swapped:
59 if c in string.lowercase:
60 newstr += c
61 idx += 1
62 else:
63 break
64 if idx < 2:
65 newstr += word[idx:]
66 else:
67 newstr = newstr[:-1]+ word[idx-1:]
68
69 return newstr
70
71def usage():
72 print "Python parser for asn1 v%s" % (version)
73 print "Usage: python asn1tostruct.py [options]"
74 print "Available options:"
75 print "-d Enable script debug"
76 print "-f [file] Input file to parse"
77 print "-o [dir] Output files to given directory"
Harald Welte84839c02015-09-10 18:33:14 +020078 print "-p [pfx] Prefix all types with given prefix"
Harald Welte245daf92015-08-30 22:38:40 +020079 print "-h Print this help and return"
80
81try:
Harald Welte84839c02015-09-10 18:33:14 +020082 opts, args = getopt.getopt(sys.argv[1:], "df:ho:p:", ["debug", "file", "help", "outdir", "prefix"])
Harald Welte245daf92015-08-30 22:38:40 +020083except getopt.GetoptError as err:
84 # print help information and exit:
85 usage()
86 sys.exit(2)
87
88for o, a in opts:
89 if o in ("-f", "--file"):
90 filenames.append(a)
91 if o in ("-d", "--debug"):
92 verbosity = 1
93 if o in ("-o", "--outdir"):
94 outdir = a
95 if outdir.rfind('/') != len(outdir):
96 outdir += '/'
Harald Welte84839c02015-09-10 18:33:14 +020097 if o in ("-p", "--prefix"):
98 prefix = a
Harald Welte245daf92015-08-30 22:38:40 +020099 if o in ("-h", "--help"):
100 usage()
101 sys.exit(2)
102
103for filename in filenames:
104 file = open(filename, 'r')
105 for line in file:
106 # Removing any comment
107 if line.find('--') >= 0:
108 line = line[:line.find('--')]
109 # Removing any carriage return
110 lines += re.sub('\r', '', line)
111
112 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):
113 ieofielist[m[0]] = m[1]
114 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):
115 ieofielist[m[0]] = m[1]
116
117 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):
118 ies = []
119 maxLength = 0
120 # TODO: handle extensions
121 if i[1].find('EXTENSION') >= 0:
122 continue
123 if fileprefix == "":
124 fileprefix = i[1][:i[1].find('-')].lower()
125 for j in re.findall(r'\s*\{\s*([a-zA-Z0-9-\ \t]+)\s*\}\s*[\|,]*', i[2], re.MULTILINE):
126 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):
127 printDebug("Got new ie for message " + i[0] + ": " + str(k))
128 if len(k[2]) > maxLength:
129 maxLength = len(k[2])
130 ies.append(k)
131
132 if len(ies) > 0:
133 iesDefs[i[0]] = { "length": maxLength, "ies": ies}
134 else:
135 printWarning("Didn't find any information element for message: " + i[0])
136
137if len(iesDefs) == 0:
138 printFail("No Information Element parsed, exiting")
139 sys.exit(0)
140
141f = open(outdir + fileprefix + '_ies_defs.h', 'w')
142outputHeaderToFile(f, filename)
143f.write("#include \"%s_common.h\"\n\n" % (fileprefix))
144f.write("#ifndef %s_IES_DEFS_H_\n#define %s_IES_DEFS_H_\n\n" % (fileprefix.upper(), fileprefix.upper()))
145
146for key in iesDefs:
147
148 if key not in ieofielist.values():
149 continue
150
151 for (i, j) in ieofielist.items():
152 if j == key:
153 break
154
Harald Welte84839c02015-09-10 18:33:14 +0200155 f.write("typedef struct %sIEs_s {\n" % (prefix + re.sub('-', '_', i)))
156 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])))))
157 f.write("} %sIEs_t;\n\n" % (prefix + re.sub('-', '_', i)))
Harald Welte245daf92015-08-30 22:38:40 +0200158
159for key in iesDefs:
160 keyupperunderscore = re.sub('-', '_', key.upper())
161 keylowerunderscore = re.sub('-', '_', key.lower())
162 shift = 0
163
164 if len(iesDefs[key]["ies"]) == 0:
165 continue
166
167 # Presence mask
168 for ie in iesDefs[key]["ies"]:
169 ieupperunderscore = re.sub('-', '_', ie[2].upper())
170 if ie[3] == "optional" or ie[3] == "conditional":
Harald Welte84839c02015-09-10 18:33:14 +0200171 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 +0200172 pad=iesDefs[key]["length"] + len(keyupperunderscore) + 9))
173 shift += 1
174 if (shift > 0):
175 f.write("\n")
176
Harald Welte84839c02015-09-10 18:33:14 +0200177 f.write("typedef struct %s_s {\n" % (prefix + re.sub('-', '_', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200178 if (shift > 0):
179 f.write(" {0:<{pad}} {1};\n".format("uint16_t", "presenceMask", pad=iesDefs[key]["length"] + 2))
180 for ie in iesDefs[key]["ies"]:
Harald Welte84839c02015-09-10 18:33:14 +0200181 ieunderscore = prefix + re.sub('-', '_', ie[2])
Harald Welte245daf92015-08-30 22:38:40 +0200182 iename = re.sub('id-', '', ie[0])
183 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
184 if ie[2] in ieofielist:
185 f.write(" %sIEs_t %s;" % (re.sub('-', '_', ie[2]), ienameunderscore))
186 else:
187 f.write(" {0:<{pad}} {1};".format("%s_t" % ieunderscore, ienameunderscore, pad=iesDefs[key]["length"] + 2))
188 if ie[3] == "optional":
189 f.write(" ///< Optional field")
190 elif ie[3] == "conditional":
191 f.write(" ///< Conditional field")
192 f.write("\n")
193
Harald Welte84839c02015-09-10 18:33:14 +0200194 f.write("} %s_t;\n\n" % (prefix + re.sub('-', '_', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200195
196f.write("typedef struct %s_message_s {\n" % (fileprefix))
197f.write(" uint8_t procedureCode;\n")
198f.write(" uint8_t criticality;\n")
199f.write(" uint8_t direction;\n")
200f.write(" union {\n")
201
202messageList = iesDefs.keys()
203messageList.sort()
204for message in messageList:
205 if message in ieofielist.values():
206 continue
207 if len(iesDefs[message]["ies"]) == 0:
208 continue
Harald Welte84839c02015-09-10 18:33:14 +0200209 f.write(" %s_t %s;\n" % (prefix + re.sub('-', '_', message), lowerFirstCamelWord(re.sub('-', '_', message))))
Harald Welte245daf92015-08-30 22:38:40 +0200210f.write(" } msg;\n")
211f.write("} %s_message;\n\n" % (fileprefix))
212
213for key in iesDefs:
214 if key in ieofielist.values():
215 continue
216 structName = re.sub('ies', '', key)
217 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte84839c02015-09-10 18:33:14 +0200218 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
Harald Welte245daf92015-08-30 22:38:40 +0200219 keylowerunderscore = re.sub('-', '_', key.lower())
220 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
221 f.write("/** \\brief Decode function for %s ies.\n" % (key))
222 if len(iesDefs[key]["ies"]) != 0:
223 f.write(" * \\param %s Pointer to ASN1 structure in which data will be stored\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
224 f.write(" * \\param any_p Pointer to the ANY value to decode.\n")
225 f.write(" **/\n")
226 f.write("int %s_decode_%s(\n" % (fileprefix, keylowerunderscore))
227
228 if len(iesDefs[key]["ies"]) != 0:
Harald Welte84839c02015-09-10 18:33:14 +0200229 f.write(" %s_t *%s,\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200230 f.write(" ANY_t *any_p);\n\n")
231
232 if len(iesDefs[key]["ies"]) == 0:
233 continue
234
235 f.write("/** \\brief Encode function for %s ies.\n" % (key))
236 f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
237 f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
238 f.write(" **/\n")
239 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
240 f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower))
Harald Welte84839c02015-09-10 18:33:14 +0200241 f.write(" %s_t *%s);\n\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200242
243for key in iesDefs:
244 if key not in ieofielist.values():
245 continue
246 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
Harald Welte84839c02015-09-10 18:33:14 +0200247 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
Harald Welte245daf92015-08-30 22:38:40 +0200248 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
249 f.write("/** \\brief Encode function for %s ies.\n" % (key))
250 f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
251 f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
252 f.write(" **/\n")
253 f.write("int %s_encode_%s(\n" % (fileprefix, firstlower.lower()))
254 f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower))
255 f.write(" %sIEs_t *%sIEs);\n\n" % (asn1cStruct, firstlower))
256 f.write("/** \\brief Decode function for %s ies.\n" % (key))
257 f.write(" * \\param any_p Pointer to the ANY value to decode.\n")
258 f.write(" * \\param callback Callback function called when any_p is successfully decoded.\n")
259 f.write(" **/\n")
260 f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower()))
261 f.write(" %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower))
262 f.write(" %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct)))
Daniel Willmann19dea8b2016-02-19 16:53:43 +0100263
264for key in iesDefs:
265 keyupperunderscore = re.sub('-', '_', key.upper())
266 keylowerunderscore = re.sub('-', '_', key.lower())
267 structName = re.sub('ies', '', key)
268
269 if len(iesDefs[key]["ies"]) == 0:
270 continue
271
272 f.write("int %s_free_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
273 if len(iesDefs[key]["ies"]) != 0:
274 f.write(" %s_t *%s);\n\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200275f.write("#endif /* %s_IES_DEFS_H_ */\n\n" % (fileprefix.upper()))
276
277#Generate Decode functions
278f = open(outdir + fileprefix + '_decoder.c', 'w')
279outputHeaderToFile(f, filename)
280f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix))
281for key in iesDefs:
282 if key in ieofielist.values():
283 continue
284 structName = re.sub('ies', '', key)
Harald Weltea0c74242015-12-16 16:45:48 +0100285 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200286 ielistname = re.sub('UE', 'ue', asn1cStruct)
287 ielistnamefirstlower = ielistname[:1].lower() + ielistname[1:]
288 asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
289 keyName = re.sub('-', '_', key)
290 keyupperunderscore = keyName.upper()
291 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
Harald Welte84839c02015-09-10 18:33:14 +0200292 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
Harald Welte245daf92015-08-30 22:38:40 +0200293
294 iesaccess = ""
295 if key not in ieofielist.values():
296 iesaccess = "%s_ies." % (firstlower)
297
298 f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
299 if len(iesDefs[key]["ies"]) != 0:
Harald Welte84839c02015-09-10 18:33:14 +0200300 f.write(" %s_t *%s,\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200301 f.write(" ANY_t *any_p) {\n\n")
302
Neels Hofmeyrc13ebf72016-01-05 12:55:13 +0100303 f.write(" %s_t *%s_p = NULL;\n" % (asn1cStruct, asn1cStructfirstlower))
Harald Welte245daf92015-08-30 22:38:40 +0200304 f.write(" int i, decoded = 0;\n")
305 if len(iesDefs[key]["ies"]) != 0:
306 f.write(" int tempDecoded = 0;\n")
307
308 f.write(" assert(any_p != NULL);\n")
309 if len(iesDefs[key]["ies"]) != 0:
310 f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
Daniel Willmann86a14052016-01-12 09:46:21 +0100311 f.write(" memset(%s, 0, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), prefix + re.sub('-', '_', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200312
Harald Welte84839c02015-09-10 18:33:14 +0200313 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 +0100314 f.write(" tempDecoded = ANY_to_type_aper(any_p, &asn_DEF_%s, (void**)&%s_p);\n\n" % (asn1cStruct, asn1cStructfirstlower))
315 f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (asn1cStructfirstlower))
316 f.write(" %s_DEBUG(\"Decoding of message %s failed\\n\");\n" % (fileprefix.upper(), prefix + re.sub('-', '_', keyName)))
317 f.write(" return -1;\n")
318 f.write(" }\n\n")
319
Harald Welte245daf92015-08-30 22:38:40 +0200320 f.write(" for (i = 0; i < %s_p->%slist.count; i++) {\n" % (asn1cStructfirstlower, iesaccess))
Harald Welte84839c02015-09-10 18:33:14 +0200321 f.write(" %sIE_t *ie_p;\n" % (prefix))
Harald Welte245daf92015-08-30 22:38:40 +0200322 f.write(" ie_p = %s_p->%slist.array[i];\n" % (asn1cStructfirstlower, iesaccess))
323 f.write(" switch(ie_p->id) {\n")
324 for ie in iesDefs[key]["ies"]:
325 iename = re.sub('id-', '', ie[0])
326 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
327 ienameunderscorefirstlower = lowerFirstCamelWord(ienameunderscore)
Harald Welte84839c02015-09-10 18:33:14 +0200328 ietypesubst = prefix + re.sub('-', '', ie[2])
329 ietypeunderscore = prefix + re.sub('-', '_', ie[2])
330 ieupperunderscore = prefix + re.sub('-', '_', ie[2]).upper()
Harald Welte245daf92015-08-30 22:38:40 +0200331 if ie[3] == "optional":
332 f.write(" /* Optional field */\n")
333 elif ie[3] == "conditional":
334 f.write(" /* Conditional field */\n")
Harald Welte84839c02015-09-10 18:33:14 +0200335 f.write(" case %sProtocolIE_ID_%s:\n" % (prefix, re.sub('-', '_', ie[0])))
Harald Welte245daf92015-08-30 22:38:40 +0200336 f.write(" {\n")
Neels Hofmeyrc13ebf72016-01-05 12:55:13 +0100337 f.write(" %s_t *%s_p = NULL;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
Harald Welte245daf92015-08-30 22:38:40 +0200338 if ie[3] != "mandatory":
339 f.write(" %s->presenceMask |= %s_%s_PRESENT;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
340 f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
341 f.write(" if (tempDecoded < 0) {\n")
342 f.write(" %s_DEBUG(\"Decoding of IE %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore))
343 f.write(" return -1;\n")
344 f.write(" }\n")
345 f.write(" decoded += tempDecoded;\n")
346 f.write(" if (asn1_xer_print)\n")
347 f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
348 if ie[2] in ieofielist.keys():
Daniel Willmannd174e762015-12-22 16:22:53 +0100349 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 +0200350 f.write(" %s_DEBUG(\"Decoding of encapsulated IE %s failed\\n\");\n" % (fileprefix.upper(), lowerFirstCamelWord(ietypesubst)))
Daniel Willmannd174e762015-12-22 16:22:53 +0100351 f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
Harald Welte245daf92015-08-30 22:38:40 +0200352 else:
353 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 +0100354 f.write(" FREEMEM(%s_p);\n" % (lowerFirstCamelWord(ietypesubst)))
Harald Welte245daf92015-08-30 22:38:40 +0200355 f.write(" } break;\n")
356 f.write(" default:\n")
357 f.write(" %s_DEBUG(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
358 f.write(" return -1;\n")
359 f.write(" }\n")
360 f.write(" }\n")
Daniel Willmannd174e762015-12-22 16:22:53 +0100361 f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (asn1cStruct, asn1cStructfirstlower))
Harald Welte245daf92015-08-30 22:38:40 +0200362 f.write(" return decoded;\n")
363 f.write("}\n\n")
364
365for key in iesDefs:
Daniel Willmannd10002c2016-01-07 12:27:41 +0100366 keyupperunderscore = re.sub('-', '_', key.upper())
367 keylowerunderscore = re.sub('-', '_', key.lower())
368 structName = re.sub('ies', '', key)
369
370 if len(iesDefs[key]["ies"]) == 0:
371 continue
372
373 f.write("int %s_free_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
374 if len(iesDefs[key]["ies"]) != 0:
375 f.write(" %s_t *%s) {\n\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
376
377 for ie in iesDefs[key]["ies"]:
378 ietypeunderscore = prefix + re.sub('-', '_', ie[2])
379 ieupperunderscore = prefix + re.sub('-', '_', ie[2]).upper()
380 if ie[3] != "mandatory":
381 if ie[3] == "optional":
382 f.write(" /* Optional field */\n")
383 elif ie[3] == "conditional":
384 f.write(" /* Conditional field */\n")
385 f.write(" if ((%s->presenceMask & %s_%s_PRESENT)\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
386 f.write(" == %s_%s_PRESENT) \n " % (keyupperunderscore, ieupperunderscore))
387
388 ieunderscore = prefix + re.sub('-', '_', ie[2])
389 iename = re.sub('id-', '', ie[0])
390 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
391 f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s->%s);\n" % (ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore))
392 f.write("}\n\n")
393
394for key in iesDefs:
Harald Welte245daf92015-08-30 22:38:40 +0200395 if key not in ieofielist.values():
396 continue
397
398 keyname = re.sub('IEs', '', re.sub('Item', 'List', key))
399
400 f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', keyname).lower()))
Harald Welte84839c02015-09-10 18:33:14 +0200401 f.write(" %sIEs_t *%sIEs,\n" % (prefix + re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
402 f.write(" %s_t *%s) {\n\n" % (prefix + re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
Harald Welte245daf92015-08-30 22:38:40 +0200403 f.write(" int i, decoded = 0;\n")
404 f.write(" int tempDecoded = 0;\n\n")
405 f.write(" for (i = 0; i < %s->list.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))))
Harald Welte84839c02015-09-10 18:33:14 +0200406 f.write(" %sIE_t *ie_p = %s->list.array[i];\n" % (prefix, lowerFirstCamelWord(re.sub('-', '_', keyname))))
Harald Welte245daf92015-08-30 22:38:40 +0200407 f.write(" switch (ie_p->id) {\n")
408 for ie in iesDefs[key]["ies"]:
409 iename = re.sub('id-', '', ie[0])
410 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
411 f.write(" case ProtocolIE_ID_%s:\n" % (re.sub('-', '_', ie[0])))
412 f.write(" {\n")
Harald Welte84839c02015-09-10 18:33:14 +0200413 f.write(" %s_t *%s_p;\n" % (prefix + re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
Harald Welte245daf92015-08-30 22:38:40 +0200414 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 +0100415 f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
Harald Welte245daf92015-08-30 22:38:40 +0200416 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 +0100417 f.write(" if (%s_p)\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
418 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 +0200419 f.write(" return -1;\n")
420 f.write(" }\n")
421 f.write(" decoded += tempDecoded;\n")
422 f.write(" if (asn1_xer_print)\n")
423 f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
424 f.write(" ASN_SEQUENCE_ADD(&%sIEs->%s, %s_p);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)),
425 re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
426 f.write(" } break;\n")
427 f.write(" default:\n")
428 f.write(" %s_DEBUG(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
429 f.write(" return -1;\n")
430 f.write(" }\n")
431 f.write(" }\n")
432 f.write(" return decoded;\n")
433 f.write("}\n\n")
434
435
436#Generate IES Encode functions
437f = open(outdir + fileprefix + '_encoder.c', 'w')
438outputHeaderToFile(f,filename)
439f.write("#include \"%s_common.h\"\n" % (fileprefix))
440f.write("#include \"%s_ies_defs.h\"\n\n" % (fileprefix))
441for key in iesDefs:
442 if key in ieofielist.values():
443 continue
444
445 structName = re.sub('ies', '', key)
Harald Weltea0c74242015-12-16 16:45:48 +0100446 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200447 firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
Harald Welte84839c02015-09-10 18:33:14 +0200448 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
449 asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
Harald Welte245daf92015-08-30 22:38:40 +0200450
451 iesaccess = ""
452 if key not in ieofielist.values():
453 iesaccess = "%s_ies." % (firstwordlower)
454
455 keyName = re.sub('-', '_', key)
456 keyupperunderscore = keyName.upper()
457 # No IE to encode...
458 if len(iesDefs[key]["ies"]) == 0:
459 continue
460
461 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
462 f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
Harald Welte84839c02015-09-10 18:33:14 +0200463 f.write(" %s_t *%s) {\n\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200464
Harald Welte84839c02015-09-10 18:33:14 +0200465 f.write(" %sIE_t *ie;\n\n" % (prefix))
Harald Welte245daf92015-08-30 22:38:40 +0200466
467 for ie in iesDefs[key]["ies"]:
468 iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
Harald Welte84839c02015-09-10 18:33:14 +0200469 ienameunderscore = prefix + re.sub('-', '_', iename)
Harald Welte245daf92015-08-30 22:38:40 +0200470 ienamefirstwordlower = lowerFirstCamelWord(iename)
Harald Welte84839c02015-09-10 18:33:14 +0200471 ieupperunderscore = prefix + re.sub('-', '_', ie[2]).upper()
472 ietypeunderscore = prefix + re.sub('-', '_', ie[2])
Harald Welte245daf92015-08-30 22:38:40 +0200473 if ie[3] != "mandatory":
474 if ie[3] == "optional":
475 f.write(" /* Optional field */\n")
476 elif ie[3] == "conditional":
477 f.write(" /* Conditional field */\n")
478 f.write(" if ((%s->presenceMask & %s_%s_PRESENT)\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
479 f.write(" == %s_%s_PRESENT) {\n" % (keyupperunderscore, ieupperunderscore))
Harald Welte84839c02015-09-10 18:33:14 +0200480 f.write(" if ((ie = %s_new_ie(%sProtocolIE_ID_%s,\n" % (fileprefix, prefix, re.sub('-', '_', ie[0])))
481 f.write(" %sCriticality_%s,\n" % (prefix, ie[1]))
Harald Welte245daf92015-08-30 22:38:40 +0200482 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
483 f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
484 f.write(" return -1;\n")
485 f.write(" }\n")
486 f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n" % (firstwordlower, iesaccess))
487 f.write(" }\n\n")
488 else:
489 if ie[2] in ieofielist.keys():
Harald Welte84839c02015-09-10 18:33:14 +0200490 f.write(" %s_t %s;\n\n" % (prefix + ietypeunderscore, ienamefirstwordlower))
Harald Welte245daf92015-08-30 22:38:40 +0200491 f.write(" memset(&%s, 0, sizeof(%s_t));\n" % (ienamefirstwordlower, ietypeunderscore))
492 f.write("\n")
493 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 +0200494 f.write(" if ((ie = %s_new_ie(%sProtocolIE_ID_%s,\n" % (fileprefix, prefix, re.sub('-', '_', ie[0])))
495 f.write(" %sCriticality_%s,\n" % (prefix, ie[1]))
Harald Welte245daf92015-08-30 22:38:40 +0200496 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
497 if ie[2] in ieofielist.keys():
498 f.write(" &%s)) == NULL) {\n" % (ienamefirstwordlower))
499 else:
500 f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
501 f.write(" return -1;\n")
502 f.write(" }\n")
503 f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n\n" % (firstwordlower, iesaccess))
Daniel Willmannd174e762015-12-22 16:22:53 +0100504 if ie[2] in ieofielist.keys():
505 f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s);\n\n" % (ietypeunderscore, ienamefirstwordlower))
Harald Welte245daf92015-08-30 22:38:40 +0200506
507 f.write(" return 0;\n")
508 f.write("}\n\n")
509
510for (key, value) in iesDefs.items():
511 if key not in ieofielist.values():
512 continue
513
514 ie = value["ies"][0]
515 ietypeunderscore = re.sub('-', '_', ie[2])
516 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte84839c02015-09-10 18:33:14 +0200517 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
Harald Welte245daf92015-08-30 22:38:40 +0200518 firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
519
520 for (i, j) in ieofielist.items():
521 if j == key:
522 break
523 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', i).lower()))
524 f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
Harald Welte84839c02015-09-10 18:33:14 +0200525 f.write(" %sIEs_t *%sIEs) {\n\n" % (prefix + re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i))))
Harald Welte245daf92015-08-30 22:38:40 +0200526 f.write(" int i;\n")
527
Harald Welte84839c02015-09-10 18:33:14 +0200528 f.write(" %sIE_t *ie;\n\n" % (prefix))
Harald Welte245daf92015-08-30 22:38:40 +0200529
530 f.write(" for (i = 0; i < %sIEs->%s.count; i++) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
531 f.write(" if ((ie = %s_new_ie(ProtocolIE_ID_%s,\n" % (fileprefix, re.sub('-', '_', ie[0])))
532 f.write(" Criticality_%s,\n" % (ie[1]))
533 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
534 f.write(" %sIEs->%s.array[i])) == NULL) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
535 f.write(" return -1;\n")
536 f.write(" }\n")
537 f.write(" ASN_SEQUENCE_ADD(&%s->list, ie);\n" % (firstwordlower))
538 f.write(" }\n")
539 f.write(" return 0;\n")
540 f.write("}\n\n")