3 # Wireshark - Network traffic analyzer
4 # By Gerald Combs <gerald@wireshark.org>
5 # Copyright 1998 Gerald Combs
7 # SPDX-License-Identifier: GPL-2.0-or-later
8 '''Update the "packet-isobus-parameters.h" file.
9 Make-isobus creates a file containing isobus parameters
10 from the databases at isobus.net.
17 import urllib
.request
, urllib
.error
, urllib
.parse
20 def exit_msg(msg
=None, status
=1):
22 sys
.stderr
.write(msg
+ '\n\n')
23 sys
.stderr
.write(__doc__
+ '\n')
26 def open_url_zipped(url
):
27 '''Open a URL of a zipped file.
31 url_path
= '/'.join(url
)
33 req_headers
= { 'User-Agent': 'Wireshark make-isobus' }
35 req
= urllib
.request
.Request(url_path
, headers
=req_headers
)
36 response
= urllib
.request
.urlopen(req
)
37 body
= response
.read()
39 exit_msg('Error opening ' + url_path
)
41 return zipfile
.ZipFile(io
.BytesIO(body
))
44 isobus_output_path
= os
.path
.join('epan', 'dissectors', 'packet-isobus-parameters.h')
46 isobus_zip_url
= [ "https://www.isobus.net/isobus/attachments/", "isoExport_csv.zip"]
49 'indust' : 'Industry Groups.csv',
50 'glblfcts' : 'Global NAME Functions.csv',
51 'igfcts' :'IG Specific NAME Function.csv',
52 'manuf' : 'Manufacturer IDs.csv',
53 'pgn_spns' : 'SPNs and PGNs.csv'
56 zipf
= open_url_zipped(isobus_zip_url
)
59 min_total
= 4 # typically 8
60 f
= zipf
.read(isobus_files
['indust'])
61 lines
= f
.decode('UTF-8', 'replace').splitlines()
63 if len(lines
) < min_total
:
64 exit_msg("{}: Not enough entries ({})".format(isobus_files
['indust'], len(lines
)))
66 indust_csv
= csv
.reader(lines
)
69 # Global Name Functions csv
70 min_total
= 50 # XXX as of 2023-10-18
71 f
= zipf
.read(isobus_files
['glblfcts'])
72 lines
= f
.decode('UTF-8', 'replace').splitlines()
74 if len(lines
) < min_total
:
75 exit_msg("{}: Not enough entries ({})".format(isobus_files
['glblfcts'], len(lines
)))
77 glbl_name_functions_csv
= csv
.reader(lines
)
78 next(glbl_name_functions_csv
)
80 # Specific Name Functions csv
81 min_total
= 200 # 295 as of 2023-10-18
82 f
= zipf
.read(isobus_files
['igfcts'])
83 lines
= f
.decode('UTF-8', 'replace').splitlines()
85 if len(lines
) < min_total
:
86 exit_msg("{}: Not enough entries ({})".format(isobus_files
['igfcts'], len(lines
)))
88 vehicle_system_names
= {}
89 specific_functions
= {}
91 specific_functions_csv
= csv
.reader(lines
)
92 next(specific_functions_csv
)
93 for row
in specific_functions_csv
:
94 ig_id
, vs_id
, vs_name
, f_id
, f_name
= row
[:5]
95 new_id
= int(ig_id
) * 256 + int(vs_id
)
97 if new_id
!= 539: # 539: Weeders ...
98 print(f
"shortening {new_id}: {vs_name} -> {vs_name[:36]}")
99 vs_name
= vs_name
[:36]
100 vehicle_system_names
[new_id
] = vs_name
102 #vehicle_system_names.setdefault(ig_id, {}).setdefault(vs_id, vs_name)
103 new_id2
= 256 * new_id
+ int(f_id
)
104 specific_functions
[new_id2
] = f_name
107 min_total
= 1000 # 1396 as of 2023-10-18
108 f
= zipf
.read(isobus_files
['manuf'])
109 lines
= f
.decode('UTF-8', 'replace').splitlines()
111 if len(lines
) < min_total
:
112 exit_msg("{}: Not enough entries ({})".format(isobus_files
['manuf'], len(lines
)))
114 manuf_csv
= csv
.reader(lines
)
118 min_total
= 20000 # 23756 as of 2023-10-18
119 f
= zipf
.read(isobus_files
['pgn_spns'])
120 lines
= f
.decode('UTF-8', 'replace').splitlines()
122 if len(lines
) < min_total
:
123 exit_msg("{}: Not enough entries ({})".format(isobus_files
['pgn_spns'], len(lines
)))
127 pgn_spn_csv
= csv
.reader(lines
)
129 for row
in pgn_spn_csv
:
131 pgn_id
, pgn_name
, = row
[:2]
132 if not pgn_name
.startswith("Proprietary B"):
133 pgn_names
[int(pgn_id
)] = pgn_name
.replace("\"","'")
137 # prepare output file
139 output_fd
= io
.open(isobus_output_path
, 'w', encoding
='UTF-8')
141 exit_msg("Couldn't open ({}) ".format(isobus_output_path
))
143 output_fd
.write('''/*
144 * This file was generated by running ./tools/make-isobus.py.
146 * SPDX-License-Identifier: GPL-2.0-or-later
148 * The ISOBUS public listings available from:
149 * <https://www.isobus.net/isobus/attachments/isoExport_csv.zip>
153 #ifndef __PACKET_ISOBUS_PARAMETERS_H__
154 #define __PACKET_ISOBUS_PARAMETERS_H__
159 output_fd
.write("static const value_string _isobus_industry_groups[] = {\n")
161 for row
in sorted(indust_csv
, key
=lambda x
: int(x
[0])):
162 output_fd
.write(f
" {{ {row[0]}, \"{row[1]}\" }},\n")
164 output_fd
.write(" { 0, NULL }\n")
165 output_fd
.write("};\n")
166 output_fd
.write("static value_string_ext isobus_industry_groups_ext = VALUE_STRING_EXT_INIT(_isobus_industry_groups);\n\n")
168 # Write Vehicle System Names
169 output_fd
.write("/* key: 256 * Industry-Group-ID + Vehicle-Group-ID */\n")
170 output_fd
.write("static const value_string _isobus_vehicle_systems[] = {\n")
172 for key
in sorted(vehicle_system_names
):
173 output_fd
.write(f
" {{ {hex(key)}, \"{vehicle_system_names[key]}\" }},\n")
175 output_fd
.write(" { 0, NULL }\n")
176 output_fd
.write("};\n")
177 output_fd
.write("static value_string_ext isobus_vehicle_systems_ext = VALUE_STRING_EXT_INIT(_isobus_vehicle_systems);\n\n")
179 # Write Global Name Functions
180 output_fd
.write("static const value_string _isobus_global_name_functions[] = {\n")
182 for row
in sorted(glbl_name_functions_csv
, key
=lambda x
: int(x
[0])):
183 output_fd
.write(f
" {{ {row[0]}, \"{row[1]}\" }},\n")
185 output_fd
.write(" { 0, NULL }\n")
186 output_fd
.write("};\n")
187 output_fd
.write("static value_string_ext isobus_global_name_functions_ext = VALUE_STRING_EXT_INIT(_isobus_global_name_functions);\n\n")
189 # IG Specific Global Name Functions
190 output_fd
.write("/* key: 65536 * Industry-Group-ID + 256 * Vehicle-System-ID + Function-ID */\n")
191 output_fd
.write("static const value_string _isobus_ig_specific_name_functions[] = {\n")
193 for key
in sorted(specific_functions
):
194 output_fd
.write(f
" {{ {hex(key)}, \"{specific_functions[key]}\" }},\n")
196 output_fd
.write(" { 0, NULL }\n")
197 output_fd
.write("};\n")
198 output_fd
.write("static value_string_ext isobus_ig_specific_name_functions_ext = VALUE_STRING_EXT_INIT(_isobus_ig_specific_name_functions);\n\n")
200 # Write Manufacturers
201 output_fd
.write("static const value_string _isobus_manufacturers[] = {\n")
203 for row
in sorted(manuf_csv
, key
=lambda x
: int(x
[0])):
204 output_fd
.write(f
" {{ {row[0]}, \"{row[1]}\" }},\n")
206 output_fd
.write(" { 0, NULL }\n")
207 output_fd
.write("};\n")
208 output_fd
.write("static value_string_ext isobus_manufacturers_ext = VALUE_STRING_EXT_INIT(_isobus_manufacturers);\n\n")
211 output_fd
.write("static const value_string _isobus_pgn_names[] = {\n")
213 for key
in sorted(pgn_names
):
214 output_fd
.write(f
" {{ {key}, \"{pgn_names[key]}\" }},\n")
216 output_fd
.write(" { 0, NULL }\n")
217 output_fd
.write("};\n")
218 output_fd
.write("static value_string_ext isobus_pgn_names_ext = VALUE_STRING_EXT_INIT(_isobus_pgn_names);\n\n")
220 output_fd
.write("#endif /* __PACKET_ISOBUS_PARAMETERS_H__ */")
221 if __name__
== '__main__':