blob: adf5455c05947ebc0990b76bec89b9408618edbf [file] [log] [blame]
anjana_sreekumar@infosys.com991c2062020-01-08 11:42:57 +05301#
2# Copyright (c) 2015, EURECOM (www.eurecom.fr)
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are met:
7#
8# 1. Redistributions of source code must retain the above copyright notice, this
9# list of conditions and the following disclaimer.
10# 2. Redistributions in binary form must reproduce the above copyright notice,
11# this list of conditions and the following disclaimer in the documentation
12# and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24#
25# The views and conclusions contained in the software and documentation are those
26# of the authors and should not be interpreted as representing official policies,
27# either expressed or implied, of the FreeBSD Project.
28
29import re, os, sys, string
30import datetime
31import getopt
32import getpass
33
34version = "1.0.2"
35
36lines = ""
37iesDefs = {}
38ieofielist = {}
39outdir = './'
40
41filenames = []
42verbosity = 0
43prefix = ""
44
45FAIL = '\033[91m'
46WARN = '\033[93m'
47ENDC = '\033[0m'
48
49fileprefix = ""
50fileprefix_first_upper = ""
51
52def printFail(string):
53 sys.stderr.write(FAIL + string + ENDC + "\n")
54
55def printWarning(string):
56 print WARN + string + ENDC
57
58def printDebug(string):
59 if verbosity > 0:
60 print string
61
62def outputHeaderToFile(f, filename):
63 now = datetime.datetime.now()
64 f.write("""/*
65 * Copyright (c) 2015, EURECOM (www.eurecom.fr)
66 * All rights reserved.
67 *
68 * Redistribution and use in source and binary forms, with or without
69 * modification, are permitted provided that the following conditions are met:
70 *
71 * 1. Redistributions of source code must retain the above copyright notice, this
72 * list of conditions and the following disclaimer.
73 * 2. Redistributions in binary form must reproduce the above copyright notice,
74 * this list of conditions and the following disclaimer in the documentation
75 * and/or other materials provided with the distribution.
76 *
77 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
78 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
79 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
81 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
82 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
83 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
84 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
85 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
86 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87 *
88 * The views and conclusions contained in the software and documentation are those
89 * of the authors and should not be interpreted as representing official policies,
90 * either expressed or implied, of the FreeBSD Project.
91 */
92
93""")
94 f.write("/*******************************************************************************\n")
95 f.write(" * This file had been created by asn1tostruct.py script v%s\n" % (version))
96 f.write(" * Please do not modify this file but regenerate it via script.\n")
97 f.write(" * Created on: %s by %s\n * from %s\n" % (str(now), getpass.getuser(), filenames))
98 f.write(" ******************************************************************************/\n")
99
100def lowerFirstCamelWord(word):
101 """ puts the first word in a CamelCase Word in lowercase.
102
103 I.e. CustomerID becomes customerID, XMLInfoTest becomes xmlInfoTest
104 """
105 newstr = ''
106 swapped = word.swapcase()
107 idx = 0
108
109 # if it's all-caps, return an all-lowered version
110 lowered = word.lower()
111
112 if swapped == lowered:
113 return lowered
114
115 for c in swapped:
116 if c in string.lowercase:
117 newstr += c
118 idx += 1
119 else:
120 break
121 if idx < 2:
122 newstr += word[idx:]
123 else:
124 newstr = newstr[:-1]+ word[idx-1:]
125
126 return newstr
127
128def usage():
129 print "Python parser for asn1 v%s" % (version)
130 print "Usage: python asn1tostruct.py [options]"
131 print "Available options:"
132 print "-d Enable script debug"
133 print "-f [file] Input file to parse"
134 print "-o [dir] Output files to given directory"
135 print "-h Print this help and return"
136
137try:
138 opts, args = getopt.getopt(sys.argv[1:], "df:ho:", ["debug", "file", "help", "outdir"])
139except getopt.GetoptError as err:
140 # print help information and exit:
141 usage()
142 sys.exit(2)
143
144for o, a in opts:
145 if o in ("-f", "--file"):
146 filenames.append(a)
147 if o in ("-d", "--debug"):
148 verbosity = 1
149 if o in ("-o", "--outdir"):
150 outdir = a
151 if outdir.rfind('/') != len(outdir):
152 outdir += '/'
153 if o in ("-h", "--help"):
154 usage()
155 sys.exit(2)
156
157for filename in filenames:
158 file = open(filename, 'r')
159 for line in file:
160 # Removing any comment
161 if line.find('--') >= 0:
162 line = line[:line.find('--')]
163 # Removing any carriage return
164 lines += re.sub('\r', '', line)
165
166 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):
167 ieofielist[m[0]] = m[1]
168 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):
169 ieofielist[m[0]] = m[1]
170
171 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):
172 ies = []
173 maxLength = 0
174 # TODO: handle extensions
175 if i[1].find('EXTENSION') >= 0:
176 continue
177 if fileprefix == "":
178 fileprefix = i[1][:i[1].find('-')].lower()
179 for j in re.findall(r'\s*\{\s*([a-zA-Z0-9-\ \t]+)\s*\}\s*[\|,]*', i[2], re.MULTILINE):
180 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):
181 printDebug("Got new ie for message " + i[0] + ": " + str(k))
182 if len(k[2]) > maxLength:
183 maxLength = len(k[2])
184 ies.append(k)
185
186 if len(ies) > 0:
187 iesDefs[i[0]] = { "length": maxLength, "ies": ies }
188 else:
189 printWarning("Didn't find any information element for message: " + i[0])
190
191if len(iesDefs) == 0:
192 printFail("No Information Element parsed, exiting")
193 sys.exit(0)
194
195fileprefix_first_upper = fileprefix[0].upper() + fileprefix[1:]
196
197f = open(outdir + fileprefix + '_ies_defs.h', 'w')
198outputHeaderToFile(f, filename)
199f.write("#include \"%s_common.h\"\n\n" % (fileprefix))
200f.write("#ifndef %s_IES_DEFS_H_\n#define %s_IES_DEFS_H_\n\n" % (fileprefix.upper(), fileprefix.upper()))
201f.write("/* Define the version of script used to generate this file */\n")
202f.write("#define %s_SCRIPT_VERSION (%s)\n\n" % (fileprefix.upper(), re.sub('\.', '', version)))
203
204for key in iesDefs:
205
206 if key not in ieofielist.values():
207 continue
208
209 for (i, j) in ieofielist.items():
210 if j == key:
211 break
212
213 f.write("typedef struct %sIEs_s {\n" % (re.sub('-', '_', i)))
214 f.write(" A_SEQUENCE_OF(struct %s_s) %s;\n" % (re.sub('IEs', '', re.sub('-', '_', ieofielist[i])), lowerFirstCamelWord(re.sub('IEs', '', re.sub('-', '_', ieofielist[i])))))
215 f.write("} %sIEs_t;\n\n" % (re.sub('-', '_', i)))
216
217for key in iesDefs:
218 keyupperunderscore = re.sub('-', '_', key.upper())
219 keylowerunderscore = re.sub('-', '_', key.lower())
220 shift = 0
221
222 if len(iesDefs[key]["ies"]) == 0:
223 continue
224
225 # Presence mask
226 for ie in iesDefs[key]["ies"]:
227 ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
228
229 if ie[3] == "optional" or ie[3] == "conditional":
230 f.write("#define {0:<{pad}} {1}\n".format("%s_%s_PRESENT" % (keyupperunderscore, ieupperunderscore), "(1 << %d)" % shift,
231 pad=iesDefs[key]["length"] + len(keyupperunderscore) + 9))
232 shift += 1
233 if (shift > 0):
234 f.write("\n")
235
236 f.write("typedef struct %s_s {\n" % (re.sub('-', '_', key)))
237 if (shift > 0):
238 f.write(" {0:<{pad}} {1};\n".format("uint16_t", "presenceMask", pad=iesDefs[key]["length"] + 2))
239 for ie in iesDefs[key]["ies"]:
240 ieunderscore = re.sub('-', '_', ie[2])
241 iename = re.sub('id-', '', ie[0])
242 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
243 if ie[2] in ieofielist:
244 f.write(" %sIEs_t %s;" % (re.sub('-', '_', ie[2]), ienameunderscore))
245 else:
246 f.write(" {0:<{pad}} {1};".format("%s_t" % ieunderscore, ienameunderscore, pad=iesDefs[key]["length"] + 2))
247 if ie[3] == "optional":
248 f.write(" ///< Optional field")
249 elif ie[3] == "conditional":
250 f.write(" ///< Conditional field")
251 f.write("\n")
252
253 f.write("} %s_t;\n\n" % (re.sub('-', '_', key)))
254
255f.write("typedef struct %s_message_s {\n" % (fileprefix))
256f.write(" %s_ProcedureCode_t procedureCode;\n" % (fileprefix_first_upper))
257f.write(" %s_Criticality_t criticality;\n" % (fileprefix_first_upper))
258f.write(" uint8_t direction;\n")
259f.write(" union {\n")
260
261messageList = iesDefs.keys()
262messageList.sort()
263for message in messageList:
264 if message in ieofielist.values():
265 continue
266 if len(iesDefs[message]["ies"]) == 0:
267 continue
268 f.write(" %s_t %s;\n" % (re.sub('-', '_', message), lowerFirstCamelWord(re.sub('-', '_', message))))
269f.write(" } msg;\n")
270f.write("} %s_message;\n\n" % (fileprefix))
271
272for key in iesDefs:
273 if key in ieofielist.values():
274 continue
275 structName = re.sub('ies', '', key)
276 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
277 asn1cStruct = re.sub('Item', 'List', asn1cStruct)
278 keylowerunderscore = re.sub('-', '_', key.lower())
279 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
280 f.write("/** \\brief Decode function for %s ies.\n" % (key))
281 if len(iesDefs[key]["ies"]) != 0:
282 f.write(" * \\param %s Pointer to ASN1 structure in which data will be stored\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
283 f.write(" * \\param any_p Pointer to the ANY value to decode.\n")
284 f.write(" **/\n")
285 f.write("int %s_decode_%s(\n" % (fileprefix, keylowerunderscore))
286
287 if len(iesDefs[key]["ies"]) != 0:
288 f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
289 f.write(" ANY_t *any_p);\n\n")
290
291 if len(iesDefs[key]["ies"]) == 0:
292 continue
293
294 f.write("/** \\brief Encode function for %s ies.\n" % (key))
295 f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
296 f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
297 f.write(" **/\n")
298 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
299 f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower))
300 f.write(" %s_t *%s);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
301
302for key in iesDefs:
303 if key not in ieofielist.values():
304 continue
305 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
306 asn1cStruct = re.sub('Item', 'List', asn1cStruct)
307 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
308 f.write("/** \\brief Encode function for %s ies.\n" % (key))
309 f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
310 f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
311 f.write(" **/\n")
312 f.write("int %s_encode_%s(\n" % (fileprefix, firstlower.lower()))
313 f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower))
314 f.write(" %sIEs_t *%sIEs);\n\n" % (asn1cStruct, firstlower))
315 f.write("/** \\brief Decode function for %s ies.\n" % (key))
316 f.write(" * \\param any_p Pointer to the ANY value to decode.\n")
317 f.write(" * \\param callback Callback function called when any_p is successfully decoded.\n")
318 f.write(" **/\n")
319 f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower()))
320 f.write(" %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower))
321 f.write(" %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct)))
322
323for key in iesDefs:
324 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
325 asn1cStruct = re.sub('Item', 'List', asn1cStruct)
326 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
327
328 if key in ieofielist.values():
329 f.write("/** \\brief Display %s encapsulated IE using XER encoding.\n" % (asn1cStruct))
330 f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
331 f.write(" * \\param file File descriptor to write output.\n")
332 f.write(" **/\n")
333 f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('item', 'list', firstlower.lower())))
334 f.write(" asn_app_consume_bytes_f *cb,\n")
335 f.write(" void *app_key,\n")
336 f.write(" %sIEs_t *%sIEs);\n\n" % (re.sub('item', 'list', asn1cStruct), firstlower))
337 else:
338 f.write("/** \\brief Display %s message using XER encoding.\n" % (asn1cStruct))
339 f.write(" * \\param message_p Pointer to root message.\n")
340 f.write(" * \\param file File descriptor to write output.\n")
341 f.write(" **/\n")
342 f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, firstlower.lower()))
343 f.write(" asn_app_consume_bytes_f *cb,\n")
344 f.write(" void *app_key,\n")
345 f.write(" %s_message *message_p);\n\n" % (fileprefix))
346
347f.write("int %s_xer__print2sp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower()))
348f.write("int %s_xer__print2fp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower()))
349f.write("extern size_t %s_string_total_size;\n\n" % (fileprefix.lower()))
350
351for key in iesDefs:
352 if len(iesDefs[key]["ies"]) == 0:
353 continue
354 keyupperunderscore = re.sub('-', '_', key.upper())
355 keylowerunderscore = re.sub('-', '_', key.lower())
356 structName = re.sub('ies', '', key, flags=re.IGNORECASE)
357 f.write("int free_%s(\n" % (re.sub('-', '_', structName.lower())))
358 f.write(" %s_t *%s);\n\n" % (prefix + re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
359f.write("#endif /* %s_IES_DEFS_H_ */\n\n" % (fileprefix.upper()))
360
361#Generate Decode functions
362f = open(outdir + fileprefix + '_decoder.c', 'w')
363outputHeaderToFile(f, filename)
364f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n#include \"log.h\"\n\n" % (fileprefix, fileprefix))
365for key in iesDefs:
366 if key in ieofielist.values():
367 continue
368 structName = re.sub('ies', '', key)
369 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
370 if asn1cStruct.rfind('_') == len(asn1cStruct) - 1:
371 asn1cStruct = asn1cStruct[:-1]
372 asn1cStruct = re.sub('Item', 'List', asn1cStruct)
373 ielistname = re.sub('UE', 'ue', asn1cStruct)
374 ielistnamefirstlower = ielistname[:1].lower() + ielistname[1:]
375 asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
376 keyName = re.sub('-', '_', key)
377 keyupperunderscore = keyName.upper()
378 firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
379
380 iesaccess = ""
381 if key not in ieofielist.values():
382 iesaccess = "%s_ies." % (firstlower)
383
384 f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
385 if len(iesDefs[key]["ies"]) != 0:
386 f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
387 f.write(" ANY_t *any_p) {\n\n")
388
389 f.write(" %s_t %s;\n %s_t *%s_p = &%s;\n" % (asn1cStruct, asn1cStructfirstlower, asn1cStruct, asn1cStructfirstlower, asn1cStructfirstlower))
390 f.write(" int i, decoded = 0;\n")
391 if len(iesDefs[key]["ies"]) != 0:
392 f.write(" int tempDecoded = 0;\n")
393
394 f.write(" assert(any_p != NULL);\n")
395 if len(iesDefs[key]["ies"]) != 0:
396 f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
397 f.write(" memset(%s, 0, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), prefix + re.sub('-', '_', key)))
398
399 f.write(" OAILOG_DEBUG (LOG_%s, \"Decoding message %s (%%s:%%d)\\n\", __FILE__, __LINE__);\n\n" % (fileprefix.upper(), re.sub('-', '_', keyName)))
400 f.write(" ANY_to_type_aper(any_p, &asn_DEF_%s, (void**)&%s_p);\n\n" % (asn1cStruct, asn1cStructfirstlower))
401 f.write(" for (i = 0; i < %s_p->%slist.count; i++) {\n" % (asn1cStructfirstlower, iesaccess))
402 f.write(" %s_IE_t *ie_p;\n" % (fileprefix[0].upper() + fileprefix[1:]))
403 f.write(" ie_p = %s_p->%slist.array[i];\n" % (asn1cStructfirstlower, iesaccess))
404 f.write(" switch(ie_p->id) {\n")
405 for ie in iesDefs[key]["ies"]:
406 iename = re.sub('id-', '', ie[0])
407 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
408 ienameunderscorefirstlower = lowerFirstCamelWord(ienameunderscore)
409 ietypesubst = re.sub('-', '', ie[2])
410 ietypeunderscore = re.sub('-', '_', ie[2])
411 ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
412
413 if ie[3] == "optional":
414 f.write(" /* Optional field */\n")
415 elif ie[3] == "conditional":
416 f.write(" /* Conditional field */\n")
417 f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0])))
418 f.write(" {\n")
419 f.write(" %s_t *%s_p = NULL;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
420 if ie[3] != "mandatory":
421 f.write(" %s->presenceMask |= %s_%s_PRESENT;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
422 f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
423 f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(ietypesubst)))
424 f.write(" OAILOG_ERROR (LOG_%s, \"Decoding of IE %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore))
425 f.write(" if (%s_p)\n" % (lowerFirstCamelWord(ietypesubst)))
426 f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
427 f.write(" return -1;\n")
428 f.write(" }\n")
429 f.write(" decoded += tempDecoded;\n")
430 f.write(" if (asn1_xer_print)\n")
431 f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
432 if ie[2] in ieofielist.keys():
433 f.write(" if (%s_decode_%s(&%s->%s, %s_p) < 0) {\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst)))
434 f.write(" OAILOG_ERROR (LOG_%s, \"Decoding of encapsulated IE %s failed (1) \\n\");\n" % (fileprefix.upper(), lowerFirstCamelWord(ietypesubst)))
435# f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
436 f.write(" }\n")
437 f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
438 else:
439 f.write(" memcpy(&%s->%s, %s_p, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst), ietypeunderscore))
440 f.write(" FREEMEM(%s_p);\n" % (lowerFirstCamelWord(ietypesubst)))
441 f.write(" %s_p = NULL;\n" % (lowerFirstCamelWord(ietypesubst)))
442 f.write(" } break;\n")
443 f.write(" default:\n")
444 f.write(" OAILOG_ERROR (LOG_%s, \"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
445 f.write(" return -1;\n")
446 f.write(" }\n")
447 f.write(" }\n")
448 f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (asn1cStruct, asn1cStructfirstlower))
449 f.write(" return decoded;\n")
450 f.write("}\n\n")
451
452
453# Generate free functions for encapsulated IEs
454for key in iesDefs:
455 if key not in ieofielist.values():
456 continue
457 if len(iesDefs[key]["ies"]) == 0:
458 continue
459 # TODO: Check if the encapsulated IE also contains further encap.
460 ie = iesDefs[key]["ies"][0]
461 ietypeunderscore = prefix + re.sub('-', '_', ie[2])
462 keyname = re.sub('IEs', '', re.sub('Item', 'List', key))
463 iesStructName = lowerFirstCamelWord(re.sub('Item', 'List', re.sub('-', '_', key)))
464 f.write("int free_%s(\n" % (re.sub('-', '_', keyname).lower()))
465 f.write(" %sIEs_t *%s) {\n\n" % (re.sub('-', '_', keyname), iesStructName))
466 f.write(" assert(%s != NULL);\n\n" % (iesStructName))
467 f.write(" for (int i = 0; i < %s->%s.count; i++) {\n" %
468 (iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
469 f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, %s->%s.array[i]);\n" %
470 (ietypeunderscore, iesStructName, re.sub('IEs', '',lowerFirstCamelWord(re.sub('-', '_', key)))))
471 f.write(" FREEMEM(%s->%s.array[i]);\n" %
472 (iesStructName, re.sub('IEs', '',lowerFirstCamelWord(re.sub('-', '_', key)))))
473 f.write(" }\n")
474 f.write(" /* Remove the array containing the elements. */\n")
475 f.write(" FREEMEM(%s->%s.array);\n" %
476 (iesStructName, re.sub('IEs', '',lowerFirstCamelWord(re.sub('-', '_', key)))))
477 f.write(" return 0;\n")
478 f.write("}\n\n")
479
480
481
482for key in iesDefs:
483 if len(iesDefs[key]["ies"]) == 0:
484 continue
485 keyupperunderscore = re.sub('-', '_', key.upper())
486 keylowerunderscore = re.sub('-', '_', key.lower())
487 structName = re.sub('ies', '', key, flags=re.IGNORECASE)
488
489
490 f.write("int free_%s(\n" % (re.sub('-', '_', structName.lower())))
491 f.write(" %s_t *%s) {\n\n" % (prefix + re.sub('-', '_', key),
492 lowerFirstCamelWord(re.sub('-', '_', key))))
493
494 for ie in iesDefs[key]["ies"]:
495 ietypeunderscore = prefix + re.sub('-', '_', ie[2])
496 ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
497 if ie[3] != "mandatory":
498 if ie[3] == "optional":
499 f.write(" /* Optional field */\n")
500 elif ie[3] == "conditional":
501 f.write(" /* Conditional field */\n")
502 f.write(" if ((%s->presenceMask & %s_%s_PRESENT)\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
503 f.write(" == %s_%s_PRESENT) \n " % (keyupperunderscore, ieupperunderscore))
504
505 iename = re.sub('id-', '', ie[0])
506 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
507 # Check if this is an encapsulated IE, if so call the free function.
508 if ie[2] in ieofielist.keys():
509 keyname = re.sub('IEs', '', re.sub('Item', 'List', ie[2]))
510 f.write(" free_%s(&%s->%s);\n" % (re.sub('-', '_', keyname).lower(),
511 lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore))
512 else:
513 f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s->%s);\n" % (ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore))
514 f.write(" return 0;\n")
515 f.write("}\n\n")
516
517for key in iesDefs:
518 if key not in ieofielist.values():
519 continue
520
521 keyname = re.sub('IEs', '', re.sub('Item', 'List', key))
522
523 f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', keyname).lower()))
524 f.write(" %sIEs_t *%sIEs,\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
525 f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
526 f.write(" int i, decoded = 0;\n")
527 f.write(" int tempDecoded = 0;\n\n")
528
529 f.write(" assert(%s != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))))
530 f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))))
531
532 f.write(" for (i = 0; i < %s->list.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))))
533 f.write(" %s_IE_t *ie_p = %s->list.array[i];\n" % (fileprefix[0].upper() + fileprefix[1:], lowerFirstCamelWord(re.sub('-', '_', keyname))))
534 f.write(" switch (ie_p->id) {\n")
535 for ie in iesDefs[key]["ies"]:
536 iename = re.sub('id-', '', ie[0])
537 ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
538 f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0])))
539 f.write(" {\n")
540 f.write(" %s_t *%s_p = NULL;\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
541 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]))))
542 f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
543 f.write(" OAILOG_ERROR (LOG_%s, \"Decoding of IE %s for message %s failed (2) \\n\");\n" % (fileprefix.upper(), ienameunderscore, re.sub('-', '_', keyname)))
544 f.write(" if (%s_p)\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
545 f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
546 f.write(" return -1;\n")
547 f.write(" }\n")
548 f.write(" decoded += tempDecoded;\n")
549 f.write(" if (asn1_xer_print)\n")
550 f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
551 f.write(" ASN_SEQUENCE_ADD(&%sIEs->%s, %s_p);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)),
552 re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
553 f.write(" } break;\n")
554 f.write(" default:\n")
555 f.write(" OAILOG_ERROR (LOG_%s, \"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
556 f.write(" return -1;\n")
557 f.write(" }\n")
558 f.write(" }\n")
559 f.write(" return decoded;\n")
560 f.write("}\n\n")
561
562
563#Generate IES Encode functions
564f = open(outdir + fileprefix + '_encoder.c', 'w')
565outputHeaderToFile(f,filename)
566f.write("#include \"%s_common.h\"\n" % (fileprefix))
567f.write("#include \"%s_ies_defs.h\"\n\n" % (fileprefix))
568for key in iesDefs:
569 if key in ieofielist.values():
570 continue
571
572 structName = re.sub('ies', '', key)
573 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
574 asn1cStruct = re.sub('Item', 'List', asn1cStruct)
575 if asn1cStruct.rfind('_') == len(asn1cStruct) - 1:
576 asn1cStruct = asn1cStruct[:-1]
577 asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
578 firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
579
580 iesaccess = ""
581 if key not in ieofielist.values():
582 iesaccess = "%s_ies." % (firstwordlower)
583
584 keyName = re.sub('-', '_', key)
585 keyupperunderscore = keyName.upper()
586 # No IE to encode...
587 if len(iesDefs[key]["ies"]) == 0:
588 continue
589
590 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
591 f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
592 f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
593
594 f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper))
595
596 f.write(" assert(%s != NULL);\n" % (firstwordlower));
597 f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))));
598
599 for ie in iesDefs[key]["ies"]:
600 iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
601 ienameunderscore = re.sub('-', '_', iename)
602 ienamefirstwordlower = lowerFirstCamelWord(iename)
603 ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
604 ietypeunderscore = re.sub('-', '_', ie[2])
605
606 if ie[3] != "mandatory":
607 if ie[3] == "optional":
608 f.write(" /* Optional field */\n")
609 elif ie[3] == "conditional":
610 f.write(" /* Conditional field */\n")
611 f.write(" if (%s->presenceMask & %s_%s_PRESENT) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
612 #f.write(" == %s_%s_PRESENT) {\n" % (keyupperunderscore, ieupperunderscore))
613 f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
614 f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
615 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
616 f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
617 f.write(" return -1;\n")
618 f.write(" }\n")
619 f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n" % (firstwordlower, iesaccess))
620 f.write(" }\n\n")
621 else:
622 if ie[2] in ieofielist.keys():
623 f.write(" %s_t %s;\n\n" % (ietypeunderscore, ienamefirstwordlower))
624 f.write(" memset(&%s, 0, sizeof(%s_t));\n" % (ienamefirstwordlower, ietypeunderscore))
625 f.write("\n")
626 f.write(" if (%s_encode_%s(&%s, &%s->%s) < 0) return -1;\n" % (fileprefix, ietypeunderscore.lower(), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
627 f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
628 f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
629 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
630 if ie[2] in ieofielist.keys():
631 f.write(" &%s)) == NULL) {\n" % (ienamefirstwordlower))
632 else:
633 f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
634 f.write(" return -1;\n")
635 f.write(" }\n")
636 f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n\n" % (firstwordlower, iesaccess))
637 if ie[2] in ieofielist.keys():
638 f.write(" /* Free any dynamic allocation that is no more used */\n")
639 f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s);\n\n" % (ietypeunderscore, ienamefirstwordlower))
640
641 f.write(" return 0;\n")
642 f.write("}\n\n")
643
644for (key, value) in iesDefs.items():
645 if key not in ieofielist.values():
646 continue
647
648 ie = value["ies"][0]
649 ietypeunderscore = re.sub('-', '_', ie[2])
650 asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
651 asn1cStruct = re.sub('Item', 'List', asn1cStruct)
652 firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
653
654 for (i, j) in ieofielist.items():
655 if j == key:
656 break
657 f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', i).lower()))
658 f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
659 f.write(" %sIEs_t *%sIEs) {\n\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i))))
660 f.write(" int i;\n")
661
662 f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper))
663
664 f.write(" assert(%s != NULL);\n" % (firstwordlower));
665 f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', i))));
666
667 f.write(" for (i = 0; i < %sIEs->%s.count; i++) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
668 f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
669 f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
670 f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
671 f.write(" %sIEs->%s.array[i])) == NULL) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
672 f.write(" return -1;\n")
673 f.write(" }\n")
674 f.write(" ASN_SEQUENCE_ADD(&%s->list, ie);\n" % (firstwordlower))
675 f.write(" }\n")
676 f.write(" return 0;\n")
677 f.write("}\n\n")
678
679#Generate xer print functions
680f = open(outdir + fileprefix + '_xer_print.c', 'w')
681outputHeaderToFile(f, filename)
682f.write("#include <stdlib.h>\n")
683f.write("#include <stdio.h>\n\n")
684f.write("#include <asn_application.h>\n#include <asn_internal.h>\n\n")
685f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix))
686
687f.write("size_t %s_string_total_size = 0;\n\n" % (fileprefix.lower()))
688f.write("""int
689%s_xer__print2fp(const void *buffer, size_t size, void *app_key) {
690 FILE *stream = (FILE *)app_key;
691
692 if(fwrite(buffer, 1, size, stream) != size)
693 return -1;
694
695 return 0;
696}
697
698""" % (fileprefix.lower()))
699
700f.write("""int %s_xer__print2sp(const void *buffer, size_t size, void *app_key) {
701 char *string = (char *)app_key;
702
703 /* Copy buffer to the formatted string */
704 memcpy(&string[%s_string_total_size], buffer, size);
705
706 %s_string_total_size += size;
707
708 return 0;
709}
710
711""" % (fileprefix.lower(), fileprefix.lower(), fileprefix.lower()))
712
713f.write("""static asn_enc_rval_t
714xer_encode_local(asn_TYPE_descriptor_t *td, void *sptr,
715 asn_app_consume_bytes_f *cb, void *app_key, int indent) {
716 asn_enc_rval_t er, tmper;
717 const char *mname;
718 size_t mlen;
719 int xcan = 2;
720
721 if(!td || !sptr) goto cb_failed;
722
723 mname = td->xml_tag;
724 mlen = strlen(mname);
725
726 _i_ASN_TEXT_INDENT(0, indent);
727 _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
728
729 tmper = td->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key);
730 if(tmper.encoded == -1) return tmper;
731
732 _ASN_CALLBACK3("</", 2, mname, mlen, ">\\n", xcan);
733
734 er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
735
736 _ASN_ENCODED_OK(er);
737cb_failed:
738 _ASN_ENCODE_FAILED;
739}
740""")
741
742for (key, value) in iesDefs.items():
743 keyName = re.sub('-', '_', key)
744 keyupperunderscore = keyName.upper()
745 iesStructName = lowerFirstCamelWord(re.sub('-', '_', key))
746
747 ie = value["ies"][0]
748 ietypeunderscore = re.sub('-', '_', ie[2])
749
750 if key in ieofielist.values():
751 f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('item', 'list', re.sub('-', '_', key).lower()))))
752 else:
753 f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', key).lower())))
754 #f.write(" FILE *file,\n")
755 f.write(" asn_app_consume_bytes_f *cb,\n")
756 f.write(" void *app_key,\n")
757 if key in ieofielist.values():
758 iesStructName = lowerFirstCamelWord(re.sub('Item', 'List', re.sub('-', '_', key)))
759 f.write(" %sIEs_t *%s) {\n\n" % (re.sub('IEs', '', re.sub('Item', 'List', re.sub('-', '_', key))), iesStructName))
760 f.write(" int i;\n")
761 f.write(" asn_enc_rval_t er;\n")
762 else:
763 f.write(" %s_message *message_p)\n{\n" % (fileprefix))
764 f.write(" %s_t *%s;\n" % (re.sub('-', '_', key), iesStructName))
765 f.write(" asn_enc_rval_t er;\n")
766 #f.write(" void *app_key = (void *)file;\n")
767 #f.write(" asn_app_consume_bytes_f *cb = %s_xer__print2fp;\n\n" % (fileprefix.lower()))
768
769 f.write(" %s = &message_p->msg.%s;\n\n" % (iesStructName, iesStructName))
770
771 if key in ieofielist.values():
772 # Increase indentation level
773 f.write(" for (i = 0; i < %s->%s.count; i++) {\n" % (iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
774 #f.write(" xer_fprint(file, &asn_DEF_%s, %s->%s.array[i]);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
775 f.write(" er = xer_encode(&asn_DEF_%s, %s->%s.array[i], XER_F_BASIC, cb, app_key);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
776 f.write(" }\n")
777 else:
778 f.write(" cb(\"<%s-PDU>\\n\", %d, app_key);\n" % (key, len("<%s-PDU>\n" % (key))))
779 f.write(" xer_encode_local(&asn_DEF_%s_Criticality, &message_p->criticality, cb, app_key, 1);\n" % fileprefix_first_upper)
780 f.write(" xer_encode_local(&asn_DEF_%s_ProcedureCode, &message_p->procedureCode, cb, app_key, 1);\n" % fileprefix_first_upper)
781
782 f.write(" cb(\" <%s>\\n\", %d, app_key);\n" % (key, len(" <%s>\n" % (key))))
783
784 for ie in iesDefs[key]["ies"]:
785 iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
786 ienameunderscore = re.sub('-', '_', iename)
787 ienamefirstwordlower = lowerFirstCamelWord(iename)
788 ietypeunderscore = re.sub('-', '_', ie[2])
789 ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
790
791 if ie[3] != "mandatory":
792 if ie[3] == "optional":
793 f.write(" /* Optional field */\n")
794 elif ie[3] == "conditional":
795 f.write(" /* Conditional field */\n")
796 f.write(" if (%s->presenceMask & %s_%s_PRESENT)\n " % (iesStructName, keyupperunderscore, ieupperunderscore))
797
798 # Is it an encapsulated IE ?
799 if ie[2] in ieofielist.keys():
800 f.write(" %s_xer_print_%s(cb, app_key, &%s->%s);\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', ie[2]).lower()), iesStructName, ienamefirstwordlower))
801 else:
802 f.write(" xer_encode_local(&asn_DEF_%s, &%s->%s, cb, app_key, 2);\n" % (ietypeunderscore, iesStructName, ienamefirstwordlower))
803 f.write(" cb(\" </%s>\\n\", %d, app_key);\n" % (key, len(" </%s>\n" % (key))))
804 f.write(" cb(\"</%s-PDU>\\n\", %d, app_key);\n" % (key, len("</%s-PDU>\n" % (key))))
805
806 f.write(" _ASN_ENCODED_OK(er);\n")
807 #if key not in ieofielist.values():
808 #f.write("cb_failed:\n")
809 #f.write(" return er;\n")
810 f.write("}\n\n")