blob: 126cfbc532680fe2299543c213ab4869a8d8e24a [file] [log] [blame]
Harald Weltecef7ef62017-01-22 19:04:08 +01001#!/usr/bin/env python
2#
3# Code to parse the ASCII Database files of QXDM
4# (C) 2017 by Harald Welte <laforge@gnumonks.org>
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20import csv
21
22def export_value_str(name, vals, flavor='osmocom'):
23 if flavor == 'osmocom':
24 print("const struct value_string %s[] = {" % name);
25 elif flavor == 'wireshark':
26 print("const value_string %s[] = {" % name);
27 for v in sorted(vals.iterkeys(), key=int):
28 print("\t{ %d, \"%s\" }," % (int(v), vals[v]));
29 print("\t{ 0, NULL }")
30 print("};");
31
32class QxdmDb(object):
33 file_fields = {
34 'Enum': ['id', 'name', 'entries_id', 'unknown'],
35 'EnumEntry': ['enum_id', 'value', 'name', 'unknown'],
36 'EventID': ['value', 'name', 'category_id', 'description_id'],
37 'EventCategory': ['value', 'name', 'unknown', 'unknown2'],
38 'Struct': ['id', 'index', 'unknown', 'field_id', 'unknown2', 'unknown3', 'unknown4'],
39 'Field': ['id', 'name', 'bits', 'unknown1', 'unknown2',
40 'unknown3', 'unknown4', 'unknown5'],
41 'Description': ['id', 'text'],
42 'LogItem': ['id', 'name', 'category_id', 'unknown'],
43 'LogCategory': ['id', 'name', 'unknown', 'parent_id'],
44 'MessageLevel': ['id', 'level', 'name', 'category_id'],
45 'MessageCategory': ['id', 'name', 'unknown', 'parent_id'],
46 }
47 _csvdicts= {}
48
49 descs = {}
50 enums = {}
51 events = {}
52 event_cats = {}
53 logitems = {}
54 log_cats = {}
55 msgs = {}
56 msg_cats = {}
57
58 @staticmethod
59 def read_into_dict(fname, fieldnames=None):
60 csvfile = open(fname, 'rb')
61 r = csv.DictReader(csvfile, fieldnames=fieldnames, delimiter='^')
62 return r
63
64 def gen_descs(self):
65 for d in self._csvdicts['Description']:
66 self.descs[int(d['id'], base=0)] = d['text']
67
68 def gen_enums(self):
69 for e in self._csvdicts['Enum']:
70 self.enums[int(e['id'], base=0)] = {'name': e['name'], 'entries': {}}
71 for ee in self._csvdicts['EnumEntry']:
72 self.enums[int(ee['enum_id'], base=0)]['entries'][int(ee['value'],base=0)] = ee['name']
73
74 def gen_events(self):
75 for c in self._csvdicts['EventCategory']:
76 self.event_cats[int(c['value'],base=0)] = {'name': c['name'], 'events': []}
77
78 for e in self._csvdicts['EventID']:
79 val_int = int(e['value'], base=0)
80 self.events[val_int] = {'name': e['name']}
81 if e['description_id'] != '-1':
82 self.events[val_int]['description'] = self.descs[int(e['description_id'], base=0)]
83 cats = e['category_id'].split(',')
84 for c in cats:
85 cat_int = int(c, base=0)
86 if cat_int in self.event_cats:
87 self.event_cats[cat_int]['events'].append(self.events[val_int])
88
89 def gen_logitems(self):
90 for c in self._csvdicts['LogCategory']:
91 self.log_cats[int(c['id'],base=0)] = {'name': c['name'], 'items': []}
92
93 for l in self._csvdicts['LogItem']:
94 val_int = int(l['id'], base=0)
95 self.logitems[val_int] = {'name': l['name']}
96
97 cats = l['category_id'].split(',')
98 for c in cats:
99 cat_int = int(c, base=0)
100 if cat_int in self.log_cats:
101 self.log_cats[cat_int]['items'].append(self.logitems[val_int])
102
103 def gen_msglevels(self):
104 def strip_suffix(s):
105 slash = s.rfind('/')
106 if slash == -1:
107 return s
108 else:
109 return s[:slash]
110 for c in self._csvdicts['MessageCategory']:
111 self.msg_cats[int(c['id'],base=0)] = {'name': c['name'], 'msgs': []}
112
113 for l in self._csvdicts['MessageLevel']:
114 val_int = int(l['id'], base=0)
115 level_int = int(l['level'], base=0)
116 if not val_int in self.msgs:
117 self.msgs[val_int] = {'levels':{}, 'name': strip_suffix(l['name'])}
118 self.msgs[val_int]['levels'][level_int] = {'name': l['name']}
119
120 cats = l['category_id'].split(',')
121 for c in cats:
122 cat_int = int(c, base=0)
123 if cat_int in self.msg_cats:
124 self.msg_cats[cat_int]['msgs'].append(self.msgs[val_int]['levels'][level_int])
125
126
127 def __init__(self, dir_to_db):
128 for f in self.file_fields:
129 fname = '%s/%s.txt' % (dir_to_db, f)
130 self._csvdicts[f] = self.read_into_dict(fname, self.file_fields[f])
131 self.gen_descs()
132 self.gen_enums()
133 self.gen_events()
134 self.gen_logitems()
135 self.gen_msglevels()
136
137 def export_valstr_events(self):
138 def f(v):
139 return v['name']
140 vals = dict(zip(self.events, map(f, self.events.values())))
141 export_value_str('diag_event_vals', vals)
142
143 def export_valstr_event_descs(self):
144 vals = {}
145 for e in self.events:
146 if 'description' in self.events[e]:
147 vals[e] = self.events[e]['description']
148 export_value_str('diag_event_descs', vals)
149
150 def export_valstr_logitems(self):
151 def f(v):
152 return v['name']
153 vals = dict(zip(self.logitems, map(f, self.logitems.values())))
154 export_value_str('diag_log_item_vals', vals)
155
156 def export_valstr_msgs(self):
157 def f(v):
158 return v['name']
159 vals = dict(zip(self.msgs, map(f, self.msgs.values())))
160 export_value_str('diag_msg_vals', vals)