blob: 61d0f6812e0313d3a1e554af2012fd757a2d3a5c [file] [log] [blame]
Harald Welte245daf92015-08-30 22:38:40 +02001#!/usr/bin/python
2
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)))
263f.write("#endif /* %s_IES_DEFS_H_ */\n\n" % (fileprefix.upper()))
264
265#Generate Decode functions
266f = open(outdir + fileprefix + '_decoder.c', 'w')
267outputHeaderToFile(f, filename)
268f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix))
269for key in iesDefs:
270 if key in ieofielist.values():
271 continue
272 structName = re.sub('ies', '', key)
Harald Weltea0c74242015-12-16 16:45:48 +0100273 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200274 ielistname = re.sub('UE', 'ue', asn1cStruct)
275 ielistnamefirstlower = ielistname[:1].lower() + ielistname[1:]
276 asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
277 keyName = re.sub('-', '_', key)
278 keyupperunderscore = keyName.upper()
279 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
Harald Welte84839c02015-09-10 18:33:14 +0200280 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
Harald Welte245daf92015-08-30 22:38:40 +0200281
282 iesaccess = ""
283 if key not in ieofielist.values():
284 iesaccess = "%s_ies." % (firstlower)
285
286 f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
287 if len(iesDefs[key]["ies"]) != 0:
Harald Welte84839c02015-09-10 18:33:14 +0200288 f.write(" %s_t *%s,\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200289 f.write(" ANY_t *any_p) {\n\n")
290
291 f.write(" %s_t %s;\n %s_t *%s_p = &%s;\n" % (asn1cStruct, asn1cStructfirstlower, asn1cStruct, asn1cStructfirstlower, asn1cStructfirstlower))
292 f.write(" int i, decoded = 0;\n")
293 if len(iesDefs[key]["ies"]) != 0:
294 f.write(" int tempDecoded = 0;\n")
295
296 f.write(" assert(any_p != NULL);\n")
297 if len(iesDefs[key]["ies"]) != 0:
298 f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
299
Harald Welte84839c02015-09-10 18:33:14 +0200300 f.write(" %s_DEBUG(\"Decoding message %s (%%s:%%d)\\n\", __FILE__, __LINE__);\n\n" % (fileprefix.upper(), prefix + re.sub('-', '_', keyName)))
Harald Welte245daf92015-08-30 22:38:40 +0200301 f.write(" ANY_to_type_aper(any_p, &asn_DEF_%s, (void**)&%s_p);\n\n" % (asn1cStruct, asn1cStructfirstlower))
302 f.write(" for (i = 0; i < %s_p->%slist.count; i++) {\n" % (asn1cStructfirstlower, iesaccess))
Harald Welte84839c02015-09-10 18:33:14 +0200303 f.write(" %sIE_t *ie_p;\n" % (prefix))
Harald Welte245daf92015-08-30 22:38:40 +0200304 f.write(" ie_p = %s_p->%slist.array[i];\n" % (asn1cStructfirstlower, iesaccess))
305 f.write(" switch(ie_p->id) {\n")
306 for ie in iesDefs[key]["ies"]:
307 iename = re.sub('id-', '', ie[0])
308 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
309 ienameunderscorefirstlower = lowerFirstCamelWord(ienameunderscore)
Harald Welte84839c02015-09-10 18:33:14 +0200310 ietypesubst = prefix + re.sub('-', '', ie[2])
311 ietypeunderscore = prefix + re.sub('-', '_', ie[2])
312 ieupperunderscore = prefix + re.sub('-', '_', ie[2]).upper()
Harald Welte245daf92015-08-30 22:38:40 +0200313 if ie[3] == "optional":
314 f.write(" /* Optional field */\n")
315 elif ie[3] == "conditional":
316 f.write(" /* Conditional field */\n")
Harald Welte84839c02015-09-10 18:33:14 +0200317 f.write(" case %sProtocolIE_ID_%s:\n" % (prefix, re.sub('-', '_', ie[0])))
Harald Welte245daf92015-08-30 22:38:40 +0200318 f.write(" {\n")
319 f.write(" %s_t %s;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
320 f.write(" %s_t *%s_p = &%s;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst), lowerFirstCamelWord(ietypesubst)))
321 if ie[3] != "mandatory":
322 f.write(" %s->presenceMask |= %s_%s_PRESENT;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
323 f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
324 f.write(" if (tempDecoded < 0) {\n")
325 f.write(" %s_DEBUG(\"Decoding of IE %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore))
326 f.write(" return -1;\n")
327 f.write(" }\n")
328 f.write(" decoded += tempDecoded;\n")
329 f.write(" if (asn1_xer_print)\n")
330 f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
331 if ie[2] in ieofielist.keys():
332 f.write(" if (%s_decode_%s(&%s->%s, %s_p) < 0)\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst)))
333 f.write(" %s_DEBUG(\"Decoding of encapsulated IE %s failed\\n\");\n" % (fileprefix.upper(), lowerFirstCamelWord(ietypesubst)))
334 else:
335 f.write(" memcpy(&%s->%s, %s_p, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst), ietypeunderscore))
336 f.write(" } break;\n")
337 f.write(" default:\n")
338 f.write(" %s_DEBUG(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
339 f.write(" return -1;\n")
340 f.write(" }\n")
341 f.write(" }\n")
342 f.write(" return decoded;\n")
343 f.write("}\n\n")
344
345for key in iesDefs:
346 if key not in ieofielist.values():
347 continue
348
349 keyname = re.sub('IEs', '', re.sub('Item', 'List', key))
350
351 f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', keyname).lower()))
Harald Welte84839c02015-09-10 18:33:14 +0200352 f.write(" %sIEs_t *%sIEs,\n" % (prefix + re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
353 f.write(" %s_t *%s) {\n\n" % (prefix + re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
Harald Welte245daf92015-08-30 22:38:40 +0200354 f.write(" int i, decoded = 0;\n")
355 f.write(" int tempDecoded = 0;\n\n")
356 f.write(" for (i = 0; i < %s->list.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))))
Harald Welte84839c02015-09-10 18:33:14 +0200357 f.write(" %sIE_t *ie_p = %s->list.array[i];\n" % (prefix, lowerFirstCamelWord(re.sub('-', '_', keyname))))
Harald Welte245daf92015-08-30 22:38:40 +0200358 f.write(" switch (ie_p->id) {\n")
359 for ie in iesDefs[key]["ies"]:
360 iename = re.sub('id-', '', ie[0])
361 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
362 f.write(" case ProtocolIE_ID_%s:\n" % (re.sub('-', '_', ie[0])))
363 f.write(" {\n")
Harald Welte84839c02015-09-10 18:33:14 +0200364 f.write(" %s_t *%s_p;\n" % (prefix + re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
Harald Welte245daf92015-08-30 22:38:40 +0200365 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]))))
366 f.write(" if (tempDecoded < 0) {\n")
367 f.write(" %s_DEBUG(\"Decoding of IE %s for message %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore, re.sub('-', '_', keyname)))
368 f.write(" return -1;\n")
369 f.write(" }\n")
370 f.write(" decoded += tempDecoded;\n")
371 f.write(" if (asn1_xer_print)\n")
372 f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
373 f.write(" ASN_SEQUENCE_ADD(&%sIEs->%s, %s_p);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)),
374 re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
375 f.write(" } break;\n")
376 f.write(" default:\n")
377 f.write(" %s_DEBUG(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
378 f.write(" return -1;\n")
379 f.write(" }\n")
380 f.write(" }\n")
381 f.write(" return decoded;\n")
382 f.write("}\n\n")
383
384
385#Generate IES Encode functions
386f = open(outdir + fileprefix + '_encoder.c', 'w')
387outputHeaderToFile(f,filename)
388f.write("#include \"%s_common.h\"\n" % (fileprefix))
389f.write("#include \"%s_ies_defs.h\"\n\n" % (fileprefix))
390for key in iesDefs:
391 if key in ieofielist.values():
392 continue
393
394 structName = re.sub('ies', '', key)
Harald Weltea0c74242015-12-16 16:45:48 +0100395 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte245daf92015-08-30 22:38:40 +0200396 firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
Harald Welte84839c02015-09-10 18:33:14 +0200397 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
398 asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
Harald Welte245daf92015-08-30 22:38:40 +0200399
400 iesaccess = ""
401 if key not in ieofielist.values():
402 iesaccess = "%s_ies." % (firstwordlower)
403
404 keyName = re.sub('-', '_', key)
405 keyupperunderscore = keyName.upper()
406 # No IE to encode...
407 if len(iesDefs[key]["ies"]) == 0:
408 continue
409
410 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
411 f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
Harald Welte84839c02015-09-10 18:33:14 +0200412 f.write(" %s_t *%s) {\n\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
Harald Welte245daf92015-08-30 22:38:40 +0200413
Harald Welte84839c02015-09-10 18:33:14 +0200414 f.write(" %sIE_t *ie;\n\n" % (prefix))
Harald Welte245daf92015-08-30 22:38:40 +0200415
416 for ie in iesDefs[key]["ies"]:
417 iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
Harald Welte84839c02015-09-10 18:33:14 +0200418 ienameunderscore = prefix + re.sub('-', '_', iename)
Harald Welte245daf92015-08-30 22:38:40 +0200419 ienamefirstwordlower = lowerFirstCamelWord(iename)
Harald Welte84839c02015-09-10 18:33:14 +0200420 ieupperunderscore = prefix + re.sub('-', '_', ie[2]).upper()
421 ietypeunderscore = prefix + re.sub('-', '_', ie[2])
Harald Welte245daf92015-08-30 22:38:40 +0200422 if ie[3] != "mandatory":
423 if ie[3] == "optional":
424 f.write(" /* Optional field */\n")
425 elif ie[3] == "conditional":
426 f.write(" /* Conditional field */\n")
427 f.write(" if ((%s->presenceMask & %s_%s_PRESENT)\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
428 f.write(" == %s_%s_PRESENT) {\n" % (keyupperunderscore, ieupperunderscore))
Harald Welte84839c02015-09-10 18:33:14 +0200429 f.write(" if ((ie = %s_new_ie(%sProtocolIE_ID_%s,\n" % (fileprefix, prefix, re.sub('-', '_', ie[0])))
430 f.write(" %sCriticality_%s,\n" % (prefix, ie[1]))
Harald Welte245daf92015-08-30 22:38:40 +0200431 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
432 f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
433 f.write(" return -1;\n")
434 f.write(" }\n")
435 f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n" % (firstwordlower, iesaccess))
436 f.write(" }\n\n")
437 else:
438 if ie[2] in ieofielist.keys():
Harald Welte84839c02015-09-10 18:33:14 +0200439 f.write(" %s_t %s;\n\n" % (prefix + ietypeunderscore, ienamefirstwordlower))
Harald Welte245daf92015-08-30 22:38:40 +0200440 f.write(" memset(&%s, 0, sizeof(%s_t));\n" % (ienamefirstwordlower, ietypeunderscore))
441 f.write("\n")
442 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 +0200443 f.write(" if ((ie = %s_new_ie(%sProtocolIE_ID_%s,\n" % (fileprefix, prefix, re.sub('-', '_', ie[0])))
444 f.write(" %sCriticality_%s,\n" % (prefix, ie[1]))
Harald Welte245daf92015-08-30 22:38:40 +0200445 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
446 if ie[2] in ieofielist.keys():
447 f.write(" &%s)) == NULL) {\n" % (ienamefirstwordlower))
448 else:
449 f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
450 f.write(" return -1;\n")
451 f.write(" }\n")
452 f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n\n" % (firstwordlower, iesaccess))
453
454 f.write(" return 0;\n")
455 f.write("}\n\n")
456
457for (key, value) in iesDefs.items():
458 if key not in ieofielist.values():
459 continue
460
461 ie = value["ies"][0]
462 ietypeunderscore = re.sub('-', '_', ie[2])
463 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
Harald Welte84839c02015-09-10 18:33:14 +0200464 asn1cStruct = prefix + re.sub('Item', 'List', asn1cStruct)
Harald Welte245daf92015-08-30 22:38:40 +0200465 firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
466
467 for (i, j) in ieofielist.items():
468 if j == key:
469 break
470 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', i).lower()))
471 f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
Harald Welte84839c02015-09-10 18:33:14 +0200472 f.write(" %sIEs_t *%sIEs) {\n\n" % (prefix + re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i))))
Harald Welte245daf92015-08-30 22:38:40 +0200473 f.write(" int i;\n")
474
Harald Welte84839c02015-09-10 18:33:14 +0200475 f.write(" %sIE_t *ie;\n\n" % (prefix))
Harald Welte245daf92015-08-30 22:38:40 +0200476
477 f.write(" for (i = 0; i < %sIEs->%s.count; i++) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
478 f.write(" if ((ie = %s_new_ie(ProtocolIE_ID_%s,\n" % (fileprefix, re.sub('-', '_', ie[0])))
479 f.write(" Criticality_%s,\n" % (ie[1]))
480 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
481 f.write(" %sIEs->%s.array[i])) == NULL) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
482 f.write(" return -1;\n")
483 f.write(" }\n")
484 f.write(" ASN_SEQUENCE_ADD(&%s->list, ie);\n" % (firstwordlower))
485 f.write(" }\n")
486 f.write(" return 0;\n")
487 f.write("}\n\n")