/src/wireshark/epan/dissectors/packet-z21.c
Line | Count | Source |
1 | | /* packet-z21.c |
2 | | * Routines for Z21 LAN protocol dissection |
3 | | * Copyright 2023, Markku Leiniƶ <markku.leinio@gmail.com> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | /* |
13 | | * Z21 LAN protocol specification can be found at: |
14 | | * https://www.z21.eu/en/downloads/manuals |
15 | | */ |
16 | | |
17 | | #include "config.h" |
18 | | #define WS_LOG_DOMAIN "Z21" |
19 | | |
20 | | #include <epan/packet.h> |
21 | | #include <epan/expert.h> |
22 | | #include <epan/prefs.h> |
23 | | #include <epan/tfs.h> |
24 | | #include <wsutil/array.h> |
25 | | #include "packet-udp.h" |
26 | | |
27 | | void proto_register_z21(void); |
28 | | void proto_reg_handoff_z21(void); |
29 | | |
30 | | /* Initialize the protocol and registered fields */ |
31 | | static int proto_z21; |
32 | | static int hf_z21_datalen; |
33 | | static int hf_z21_command; |
34 | | static int hf_z21_x_bus; |
35 | | static int hf_z21_serial_number; |
36 | | static int hf_z21_checksum; |
37 | | static int hf_z21_main_current; |
38 | | static int hf_z21_prog_current; |
39 | | static int hf_z21_filtered_main_current; |
40 | | static int hf_z21_temperature; |
41 | | static int hf_z21_supply_voltage; |
42 | | static int hf_z21_track_voltage; |
43 | | static int hf_z21_broadcast_flags; |
44 | | static int hf_z21_central_state; |
45 | | static int hf_z21_central_state_ex; |
46 | | static int hf_z21_systemstate_reserved; |
47 | | static int hf_z21_capabilities; |
48 | | static int hf_z21_status; |
49 | | static int hf_z21_loco_mode; |
50 | | static int hf_z21_loco_address; |
51 | | static int hf_z21_loco_direction_and_speed; |
52 | | static int hf_z21_loco_direction; |
53 | | static int hf_z21_loco_speed; |
54 | | static int hf_z21_loco_info_mm; |
55 | | static int hf_z21_loco_info_busy; |
56 | | static int hf_z21_loco_info_speed_steps; |
57 | | static int hf_z21_loco_info_direction; |
58 | | static int hf_z21_loco_info_speed; |
59 | | static int hf_z21_loco_info_double_traction; |
60 | | static int hf_z21_loco_info_smartsearch; |
61 | | static int hf_z21_loco_info_f0; |
62 | | static int hf_z21_loco_info_f1; |
63 | | static int hf_z21_loco_info_f2; |
64 | | static int hf_z21_loco_info_f3; |
65 | | static int hf_z21_loco_info_f4; |
66 | | static int hf_z21_loco_info_f5; |
67 | | static int hf_z21_loco_info_f6; |
68 | | static int hf_z21_loco_info_f7; |
69 | | static int hf_z21_loco_info_f8; |
70 | | static int hf_z21_loco_info_f9; |
71 | | static int hf_z21_loco_info_f10; |
72 | | static int hf_z21_loco_info_f11; |
73 | | static int hf_z21_loco_info_f12; |
74 | | static int hf_z21_loco_info_f13; |
75 | | static int hf_z21_loco_info_f14; |
76 | | static int hf_z21_loco_info_f15; |
77 | | static int hf_z21_loco_info_f16; |
78 | | static int hf_z21_loco_info_f17; |
79 | | static int hf_z21_loco_info_f18; |
80 | | static int hf_z21_loco_info_f19; |
81 | | static int hf_z21_loco_info_f20; |
82 | | static int hf_z21_loco_info_f21; |
83 | | static int hf_z21_loco_info_f22; |
84 | | static int hf_z21_loco_info_f23; |
85 | | static int hf_z21_loco_info_f24; |
86 | | static int hf_z21_loco_info_f25; |
87 | | static int hf_z21_loco_info_f26; |
88 | | static int hf_z21_loco_info_f27; |
89 | | static int hf_z21_loco_info_f28; |
90 | | static int hf_z21_loco_info_f29; |
91 | | static int hf_z21_loco_info_f30; |
92 | | static int hf_z21_loco_info_f31; |
93 | | static int hf_z21_loco_info_extensions; |
94 | | static int hf_z21_loco_func_switch_type; |
95 | | static int hf_z21_loco_func_index; |
96 | | static int hf_z21_speed_steps; |
97 | | static int hf_z21_hw_type; |
98 | | static int hf_z21_firmware_version; |
99 | | static int hf_z21_broadcast_flags_driving_switching; |
100 | | static int hf_z21_broadcast_flags_rmbus; |
101 | | static int hf_z21_broadcast_flags_railcom_subscribed; |
102 | | static int hf_z21_broadcast_flags_system_status; |
103 | | static int hf_z21_broadcast_flags_driving_switching_ex; |
104 | | static int hf_z21_broadcast_flags_loconet; |
105 | | static int hf_z21_broadcast_flags_loconet_driving; |
106 | | static int hf_z21_broadcast_flags_loconet_switching; |
107 | | static int hf_z21_broadcast_flags_loconet_detector; |
108 | | static int hf_z21_broadcast_flags_railcom; |
109 | | static int hf_z21_broadcast_flags_can_detector; |
110 | | static int hf_z21_broadcast_flags_can_booster; |
111 | | static int hf_z21_broadcast_flags_fast_clock; |
112 | | static int hf_z21_state_emergency_stop; |
113 | | static int hf_z21_state_track_voltage_off; |
114 | | static int hf_z21_state_short_circuit; |
115 | | static int hf_z21_state_programming_mode; |
116 | | static int hf_z21_state_high_temperature; |
117 | | static int hf_z21_state_power_lost; |
118 | | static int hf_z21_state_short_circuit_external; |
119 | | static int hf_z21_state_short_circuit_internal; |
120 | | static int hf_z21_state_rcn_213; |
121 | | static int hf_z21_capability_dcc; |
122 | | static int hf_z21_capability_mm; |
123 | | static int hf_z21_capability_reserved; |
124 | | static int hf_z21_capability_railcom; |
125 | | static int hf_z21_capability_loco_cmds; |
126 | | static int hf_z21_capability_accessory_cmds; |
127 | | static int hf_z21_capability_detector_cmds; |
128 | | static int hf_z21_capability_needs_unlock_code; |
129 | | static int hf_z21_function_address; |
130 | | static int hf_z21_turnout_state; |
131 | | static int hf_z21_turnout_activate_bit; |
132 | | static int hf_z21_turnout_output_bit; |
133 | | static int hf_z21_turnout_queue_bit; |
134 | | static int hf_z21_accessory_address; |
135 | | static int hf_z21_accessory_state; |
136 | | static int hf_z21_accessory_status; |
137 | | static int hf_z21_cv_address; |
138 | | static int hf_z21_cv_value; |
139 | | static int hf_z21_register; |
140 | | static int hf_z21_register_value; |
141 | | static int hf_z21_pom_operation; |
142 | | static int hf_z21_cv_bit_position; |
143 | | static int hf_z21_cv_bit_value; |
144 | | static int hf_z21_rmbus_group; |
145 | | static int hf_z21_rmbus_feedbacks; |
146 | | static int hf_z21_rmbus_address; |
147 | | static int hf_z21_railcom_receive_counter; |
148 | | static int hf_z21_railcom_error_counter; |
149 | | static int hf_z21_railcom_reserved1; |
150 | | static int hf_z21_railcom_options; |
151 | | static int hf_z21_railcom_speed; |
152 | | static int hf_z21_railcom_qos; |
153 | | static int hf_z21_railcom_reserved2; |
154 | | static int hf_z21_railcom_type; |
155 | | static int hf_z21_loconet_message; |
156 | | static int hf_z21_loconet_result; |
157 | | static int hf_z21_loconet_type; |
158 | | static int hf_z21_loconet_report_address; |
159 | | static int hf_z21_loconet_feedback_address; |
160 | | static int hf_z21_loconet_info; |
161 | | static int hf_z21_can_type; |
162 | | static int hf_z21_can_network_id; |
163 | | static int hf_z21_can_module_address; |
164 | | static int hf_z21_can_port; |
165 | | static int hf_z21_can_value1; |
166 | | static int hf_z21_can_value2; |
167 | | static int hf_z21_can_booster_name; |
168 | | static int hf_z21_can_booster_output_port; |
169 | | static int hf_z21_can_booster_state; |
170 | | static int hf_z21_can_booster_state_bg_active; |
171 | | static int hf_z21_can_booster_state_short_circuit; |
172 | | static int hf_z21_can_booster_state_track_voltage_off; |
173 | | static int hf_z21_can_booster_state_railcom_active; |
174 | | static int hf_z21_can_booster_state_output_disabled; |
175 | | static int hf_z21_can_booster_vcc; |
176 | | static int hf_z21_can_booster_current; |
177 | | static int hf_z21_can_booster_power; |
178 | | static int hf_z21_zlink_message_type; |
179 | | static int hf_z21_zlink_hwid; |
180 | | static int hf_z21_zlink_fw_major; |
181 | | static int hf_z21_zlink_fw_minor; |
182 | | static int hf_z21_zlink_fw_build; |
183 | | static int hf_z21_zlink_mac; |
184 | | static int hf_z21_zlink_name; |
185 | | static int hf_z21_zlink_reserved; |
186 | | static int hf_z21_booster_name; |
187 | | static int hf_z21_booster_port; |
188 | | static int hf_z21_booster_port_state; |
189 | | static int hf_z21_booster_state_data; |
190 | | static int hf_z21_decoder_name; |
191 | | static int hf_z21_decoder_state_data; |
192 | | static int hf_z21_data; |
193 | | |
194 | | static dissector_handle_t z21_handle; |
195 | | |
196 | | /* Not IANA registered */ |
197 | 14 | #define Z21_UDP_PORTS "21105,21106" |
198 | | static range_t *udp_port_range; |
199 | | |
200 | | /* Initialize the subtree pointers */ |
201 | | static int ett_z21; |
202 | | |
203 | | /* Initialize expert fields */ |
204 | | static expert_field ei_z21_invalid_checksum; |
205 | | |
206 | 26 | #define Z21_MIN_LENGTH 4 |
207 | | |
208 | | /* All commands are here defined as big-endian even though the |
209 | | * specifications are all little-endian. That's fine as we are |
210 | | * not comparing the values numerically, just matching them |
211 | | * in the packets. */ |
212 | 0 | #define Z21_LAN_GET_SERIAL_NUMBER 0x1000 |
213 | 0 | #define Z21_LAN_GET_HWINFO 0x1A00 |
214 | | #define Z21_LAN_LOGOFF 0x3000 |
215 | | /* Responses and requests based on the X-BUS protocol are transmitted |
216 | | * with the Z21-LAN-Header 0x40 and the specific command is indicated |
217 | | * with additional bytes inside the data field. */ |
218 | 0 | #define Z21_LAN_X_BC 0x4000 |
219 | 0 | #define Z21_LAN_SET_BROADCASTFLAGS 0x5000 |
220 | 0 | #define Z21_LAN_GET_BROADCASTFLAGS 0x5100 |
221 | 0 | #define Z21_LAN_GET_LOCOMODE 0x6000 |
222 | 0 | #define Z21_LAN_SET_LOCOMODE 0x6100 |
223 | 0 | #define Z21_LAN_RMBUS_DATACHANGED 0x8000 |
224 | 0 | #define Z21_LAN_RMBUS_GETDATA 0x8100 |
225 | 0 | #define Z21_LAN_RMBUS_PROGRAMMODULE 0x8200 |
226 | 0 | #define Z21_LAN_SYSTEMSTATE_DATACHANGED 0x8400 |
227 | | #define Z21_LAN_SYSTEMSTATE_GETDATA 0x8500 |
228 | 0 | #define Z21_LAN_RAILCOM_DATACHANGED 0x8800 |
229 | 0 | #define Z21_LAN_RAILCOM_GETDATA 0x8900 |
230 | 0 | #define Z21_LAN_LOCONET_Z21_RX 0xA000 |
231 | 0 | #define Z21_LAN_LOCONET_Z21_TX 0xA100 |
232 | 0 | #define Z21_LAN_LOCONET_FROM_LAN 0xA200 |
233 | 0 | #define Z21_LAN_LOCONET_DISPATCH_ADDR 0xA300 |
234 | 0 | #define Z21_LAN_LOCONET_DETECTOR 0xA400 |
235 | 0 | #define Z21_LAN_BOOSTER_SET_POWER 0xB200 |
236 | 0 | #define Z21_LAN_BOOSTER_GET_DESCRIPTION 0xB800 |
237 | 0 | #define Z21_LAN_BOOSTER_SET_DESCRIPTION 0xB900 |
238 | 0 | #define Z21_LAN_BOOSTER_SYSTEMSTATE_DATACHANGED 0xBA00 |
239 | 0 | #define Z21_LAN_BOOSTER_SYSTEMSTATE_GETDATA 0xBB00 |
240 | 0 | #define Z21_LAN_CAN_DETECTOR 0xC400 |
241 | 0 | #define Z21_LAN_CAN_DEVICE_GET_DESCRIPTION 0xC800 |
242 | 0 | #define Z21_LAN_CAN_DEVICE_SET_DESCRIPTION 0xC900 |
243 | 0 | #define Z21_LAN_CAN_BOOSTER_SYSTEMSTATE_CHGD 0xCA00 |
244 | 0 | #define Z21_LAN_CAN_BOOSTER_SET_TRACKPOWER 0xCB00 |
245 | | #define Z21_LAN_FAST_CLOCK_CONTROL 0xCC00 |
246 | | #define Z21_LAN_FAST_CLOCK_DATA 0xCD00 |
247 | | #define Z21_LAN_FAST_CLOCK_SETTINGS_GET 0xCE00 |
248 | | #define Z21_LAN_FAST_CLOCK_SETTINGS_SET 0xCF00 |
249 | 0 | #define Z21_LAN_DECODER_GET_DESCRIPTION 0xD800 |
250 | 0 | #define Z21_LAN_DECODER_SET_DESCRIPTION 0xD900 |
251 | 0 | #define Z21_LAN_DECODER_SYSTEMSTATE_DATACHANGED 0xDA00 |
252 | 0 | #define Z21_LAN_DECODER_SYSTEMSTATE_GETDATA 0xDB00 |
253 | 0 | #define Z21_LAN_ZLINK_GET_HWINFO 0xE800 |
254 | | /* X-BUS commands are listed as 32-bit big-endian */ |
255 | | #define Z21_LAN_X_GET_VERSION_REQUEST 0x40002121 |
256 | | #define Z21_LAN_X_GET_VERSION_REPLY 0x40006321 |
257 | | #define Z21_LAN_X_GET_STATUS_REQUEST 0x40002124 |
258 | | #define Z21_LAN_X_SET_TRACK_POWER_OFF 0x40002180 |
259 | | #define Z21_LAN_X_SET_TRACK_POWER_ON 0x40002181 |
260 | 0 | #define Z21_LAN_X_DCC_READ_REGISTER 0x40002211 |
261 | 0 | #define Z21_LAN_X_CV_READ 0x40002311 |
262 | 0 | #define Z21_LAN_X_DCC_WRITE_REGISTER 0x40002312 |
263 | 0 | #define Z21_LAN_X_CV_WRITE 0x40002412 |
264 | 0 | #define Z21_LAN_X_MM_WRITE_BYTE 0x400024FF |
265 | 0 | #define Z21_LAN_X_GET_TURNOUT_INFO 0x400043 |
266 | 0 | #define Z21_LAN_X_TURNOUT_INFO 0x40FF43 /* To be set manually */ |
267 | 0 | #define Z21_LAN_X_GET_EXT_ACCESSORY_INFO 0x400044 |
268 | 0 | #define Z21_LAN_X_EXT_ACCESSORY_INFO 0x40FF44 /* To be set manually */ |
269 | 0 | #define Z21_LAN_X_SET_TURNOUT 0x400053 |
270 | 0 | #define Z21_LAN_X_SET_EXT_ACCESSORY 0x400054 |
271 | | #define Z21_LAN_X_BC_TRACK_POWER_OFF 0x40006100 |
272 | | #define Z21_LAN_X_BC_TRACK_POWER_ON 0x40006101 |
273 | | #define Z21_LAN_X_BC_PROGRAMMING_MODE 0x40006102 |
274 | | #define Z21_LAN_X_BC_TRACK_SHORT_CIRCUIT 0x40006108 |
275 | | #define Z21_LAN_X_CV_NACK_SC 0x40006112 |
276 | | #define Z21_LAN_X_CV_NACK 0x40006113 |
277 | | #define Z21_LAN_X_UNKNOWN_COMMAND 0x40006182 |
278 | 0 | #define Z21_LAN_X_STATUS_CHANGED 0x40006222 |
279 | 0 | #define Z21_LAN_X_CV_RESULT 0x40006414 |
280 | 0 | #define Z21_LAN_X_SET_STOP 0x400080 |
281 | | #define Z21_LAN_X_BC_STOPPED 0x40008100 |
282 | 0 | #define Z21_LAN_X_SET_LOCO_E_STOP 0x400092 |
283 | 0 | #define Z21_LAN_X_PURGE_LOCO 0x4000E344 |
284 | 0 | #define Z21_LAN_X_GET_LOCO_INFO 0x4000E3F0 |
285 | 0 | #define Z21_LAN_X_SET_LOCO_DRIVE_DCC14 0x4000E410 |
286 | 0 | #define Z21_LAN_X_SET_LOCO_DRIVE_DCC28 0x4000E412 |
287 | 0 | #define Z21_LAN_X_SET_LOCO_DRIVE_DCC128 0x4000E413 |
288 | 0 | #define Z21_LAN_X_SET_LOCO_FUNCTION 0x4000E4F8 |
289 | 0 | #define Z21_LAN_X_SET_LOCO_BINARY_STATE 0x4000E55F |
290 | 0 | #define Z21_LAN_X_CV_POM_COMMANDS 0x4000E630 |
291 | 0 | #define Z21_LAN_X_CV_POM_WRITE_BYTE 0x40FFE630 /* To be set manually */ |
292 | 0 | #define Z21_LAN_X_CV_POM_WRITE_BIT 0x40FEE630 /* To be set manually */ |
293 | 0 | #define Z21_LAN_X_CV_POM_READ_BYTE 0x40FDE630 /* To be set manually */ |
294 | 0 | #define Z21_LAN_X_CV_POM_ACCESSORY_COMMANDS 0x4000E631 |
295 | 0 | #define Z21_LAN_X_CV_POM_ACCESSORY_WRITE_BYTE 0x40FFE631 /* To be set manually */ |
296 | 0 | #define Z21_LAN_X_CV_POM_ACCESSORY_WRITE_BIT 0x40FEE631 /* To be set manually */ |
297 | 0 | #define Z21_LAN_X_CV_POM_ACCESSORY_READ_BYTE 0x40FDE631 /* To be set manually */ |
298 | 0 | #define Z21_LAN_X_LOCO_INFO 0x4000EF |
299 | | #define Z21_LAN_X_GET_FIRMWARE_VERSION_REQUEST 0x4000F10A |
300 | 0 | #define Z21_LAN_X_GET_FIRMWARE_VERSION_REPLY 0x4000F30A |
301 | | |
302 | | /* This should be put in numerical order, not alphabetical order, |
303 | | * if it is ever converted to a value_string_ext, to allow binary search. |
304 | | */ |
305 | | static const value_string z21_command_vals[] = { |
306 | | { Z21_LAN_CAN_BOOSTER_SET_TRACKPOWER, "LAN_CAN_BOOSTER_SET_TRACKPOWER" }, |
307 | | { Z21_LAN_CAN_BOOSTER_SYSTEMSTATE_CHGD, "LAN_CAN_BOOSTER_SYSTEMSTATE_CHGD" }, |
308 | | { Z21_LAN_CAN_DETECTOR, "LAN_CAN_DETECTOR" }, |
309 | | { Z21_LAN_CAN_DEVICE_GET_DESCRIPTION, "LAN_CAN_DEVICE_GET_DESCRIPTION" }, |
310 | | { Z21_LAN_CAN_DEVICE_SET_DESCRIPTION, "LAN_CAN_DEVICE_SET_DESCRIPTION" }, |
311 | | { Z21_LAN_BOOSTER_GET_DESCRIPTION, "LAN_BOOSTER_GET_DESCRIPTION" }, |
312 | | { Z21_LAN_BOOSTER_SET_DESCRIPTION, "LAN_BOOSTER_SET_DESCRIPTION" }, |
313 | | { Z21_LAN_BOOSTER_SET_POWER, "LAN_BOOSTER_SET_POWER" }, |
314 | | { Z21_LAN_BOOSTER_SYSTEMSTATE_DATACHANGED, "LAN_BOOSTER_SYSTEMSTATE_DATACHANGED" }, |
315 | | { Z21_LAN_BOOSTER_SYSTEMSTATE_GETDATA, "LAN_BOOSTER_SYSTEMSTATE_GETDATA" }, |
316 | | { Z21_LAN_DECODER_GET_DESCRIPTION, "LAN_DECODER_GET_DESCRIPTION" }, |
317 | | { Z21_LAN_DECODER_SET_DESCRIPTION, "LAN_DECODER_SET_DESCRIPTION" }, |
318 | | { Z21_LAN_DECODER_SYSTEMSTATE_DATACHANGED, "LAN_DECODER_SYSTEMSTATE_DATACHANGED" }, |
319 | | { Z21_LAN_DECODER_SYSTEMSTATE_GETDATA, "LAN_DECODER_SYSTEMSTATE_GETDATA" }, |
320 | | { Z21_LAN_FAST_CLOCK_CONTROL, "LAN_FAST_CLOCK_CONTROL" }, |
321 | | { Z21_LAN_FAST_CLOCK_DATA, "LAN_FAST_CLOCK_DATA" }, |
322 | | { Z21_LAN_FAST_CLOCK_SETTINGS_GET, "LAN_FAST_CLOCK_SETTINGS_GET" }, |
323 | | { Z21_LAN_FAST_CLOCK_SETTINGS_SET, "LAN_FAST_CLOCK_SETTINGS_SET" }, |
324 | | { Z21_LAN_GET_BROADCASTFLAGS, "LAN_GET_BROADCASTFLAGS" }, |
325 | | { Z21_LAN_GET_HWINFO, "LAN_GET_HWINFO" }, |
326 | | { Z21_LAN_GET_LOCOMODE, "LAN_GET_LOCOMODE" }, |
327 | | { Z21_LAN_GET_SERIAL_NUMBER, "LAN_GET_SERIAL_NUMBER" }, |
328 | | { Z21_LAN_LOCONET_DETECTOR, "LAN_LOCONET_DETECTOR" }, |
329 | | { Z21_LAN_LOCONET_DISPATCH_ADDR, "LAN_LOCONET_DISPATCH_ADDR" }, |
330 | | { Z21_LAN_LOCONET_FROM_LAN, "LAN_LOCONET_FROM_LAN" }, |
331 | | { Z21_LAN_LOCONET_Z21_RX, "LAN_LOCONET_Z21_RX" }, |
332 | | { Z21_LAN_LOCONET_Z21_TX, "LAN_LOCONET_Z21_TX" }, |
333 | | { Z21_LAN_LOGOFF, "LAN_LOGOFF" }, |
334 | | { Z21_LAN_RAILCOM_GETDATA, "LAN_RAILCOM_GETDATA" }, |
335 | | { Z21_LAN_RAILCOM_DATACHANGED, "LAN_RAILCOM_DATACHANGED" }, |
336 | | { Z21_LAN_RMBUS_DATACHANGED, "LAN_RMBUS_DATACHANGED" }, |
337 | | { Z21_LAN_RMBUS_GETDATA, "LAN_RMBUS_GETDATA" }, |
338 | | { Z21_LAN_RMBUS_PROGRAMMODULE, "LAN_RMBUS_PROGRAMMODULE" }, |
339 | | { Z21_LAN_SET_BROADCASTFLAGS, "LAN_SET_BROADCASTFLAGS" }, |
340 | | { Z21_LAN_SET_LOCOMODE, "LAN_SET_LOCOMODE" }, |
341 | | { Z21_LAN_SYSTEMSTATE_DATACHANGED, "LAN_SYSTEMSTATE_DATACHANGED" }, |
342 | | { Z21_LAN_SYSTEMSTATE_GETDATA, "LAN_SYSTEMSTATE_GETDATA" }, |
343 | | { Z21_LAN_X_BC, "LAN_X_xxx" }, /* Unspecified X-Bus command */ |
344 | | { Z21_LAN_X_BC_PROGRAMMING_MODE, "LAN_X_BC_PROGRAMMING_MODE" }, |
345 | | { Z21_LAN_X_BC_STOPPED, "LAN_X_BC_STOPPED" }, |
346 | | { Z21_LAN_X_BC_TRACK_POWER_OFF, "LAN_X_BC_TRACK_POWER_OFF" }, |
347 | | { Z21_LAN_X_BC_TRACK_POWER_ON, "LAN_X_BC_TRACK_POWER_ON" }, |
348 | | { Z21_LAN_X_BC_TRACK_SHORT_CIRCUIT, "LAN_X_BC_TRACK_SHORT_CIRCUIT" }, |
349 | | { Z21_LAN_X_CV_NACK, "LAN_X_CV_NACK" }, |
350 | | { Z21_LAN_X_CV_NACK_SC, "LAN_X_CV_NACK_SC" }, |
351 | | { Z21_LAN_X_CV_POM_ACCESSORY_READ_BYTE, "LAN_X_CV_POM_ACCESSORY_READ_BYTE" }, |
352 | | { Z21_LAN_X_CV_POM_ACCESSORY_WRITE_BIT, "LAN_X_CV_POM_ACCESSORY_WRITE_BIT" }, |
353 | | { Z21_LAN_X_CV_POM_ACCESSORY_WRITE_BYTE, "LAN_X_CV_POM_ACCESSORY_WRITE_BYTE" }, |
354 | | { Z21_LAN_X_CV_POM_READ_BYTE, "LAN_X_CV_POM_READ_BYTE" }, |
355 | | { Z21_LAN_X_CV_POM_WRITE_BIT, "LAN_X_CV_POM_WRITE_BIT" }, |
356 | | { Z21_LAN_X_CV_POM_WRITE_BYTE, "LAN_X_CV_POM_WRITE_BYTE" }, |
357 | | { Z21_LAN_X_CV_READ, "LAN_X_CV_READ" }, |
358 | | { Z21_LAN_X_CV_RESULT, "LAN_X_CV_RESULT" }, |
359 | | { Z21_LAN_X_CV_WRITE, "LAN_X_CV_WRITE" }, |
360 | | { Z21_LAN_X_DCC_READ_REGISTER, "LAN_X_DCC_READ_REGISTER" }, |
361 | | { Z21_LAN_X_DCC_WRITE_REGISTER, "LAN_X_DCC_WRITE_REGISTER" }, |
362 | | { Z21_LAN_X_EXT_ACCESSORY_INFO, "LAN_X_EXT_ACCESSORY_INFO" }, |
363 | | { Z21_LAN_X_GET_EXT_ACCESSORY_INFO, "LAN_X_GET_EXT_ACCESSORY_INFO" }, |
364 | | { Z21_LAN_X_GET_FIRMWARE_VERSION_REQUEST, "LAN_X_GET_FIRMWARE_VERSION" }, |
365 | | { Z21_LAN_X_GET_FIRMWARE_VERSION_REPLY, "LAN_X_GET_FIRMWARE_VERSION" }, |
366 | | { Z21_LAN_X_GET_LOCO_INFO, "LAN_X_GET_LOCO_INFO" }, |
367 | | { Z21_LAN_X_GET_TURNOUT_INFO, "LAN_X_GET_TURNOUT_INFO" }, |
368 | | { Z21_LAN_X_GET_VERSION_REQUEST, "LAN_X_GET_VERSION" }, |
369 | | { Z21_LAN_X_GET_VERSION_REPLY, "LAN_X_GET_VERSION" }, |
370 | | { Z21_LAN_X_GET_STATUS_REQUEST, "LAN_X_GET_STATUS" }, |
371 | | { Z21_LAN_X_LOCO_INFO, "LAN_X_LOCO_INFO" }, |
372 | | { Z21_LAN_X_MM_WRITE_BYTE, "LAN_X_MM_WRITE_BYTE" }, |
373 | | { Z21_LAN_X_PURGE_LOCO, "LAN_X_PURGE_LOCO" }, |
374 | | { Z21_LAN_X_SET_EXT_ACCESSORY, "LAN_X_SET_EXT_ACCESSORY" }, |
375 | | { Z21_LAN_X_SET_LOCO_BINARY_STATE, "LAN_X_SET_LOCO_BINARY_STATE" }, |
376 | | { Z21_LAN_X_SET_LOCO_DRIVE_DCC14, "LAN_X_SET_LOCO_DRIVE" }, |
377 | | { Z21_LAN_X_SET_LOCO_DRIVE_DCC28, "LAN_X_SET_LOCO_DRIVE" }, |
378 | | { Z21_LAN_X_SET_LOCO_DRIVE_DCC128, "LAN_X_SET_LOCO_DRIVE" }, |
379 | | { Z21_LAN_X_SET_LOCO_E_STOP, "LAN_X_SET_LOCO_E_STOP" }, |
380 | | { Z21_LAN_X_SET_LOCO_FUNCTION, "LAN_X_SET_LOCO_FUNCTION" }, |
381 | | { Z21_LAN_X_SET_STOP, "LAN_X_SET_STOP" }, |
382 | | { Z21_LAN_X_SET_TRACK_POWER_OFF, "LAN_X_SET_TRACK_POWER_OFF" }, |
383 | | { Z21_LAN_X_SET_TRACK_POWER_ON, "LAN_X_SET_TRACK_POWER_ON" }, |
384 | | { Z21_LAN_X_SET_TURNOUT, "LAN_X_SET_TURNOUT" }, |
385 | | { Z21_LAN_X_STATUS_CHANGED, "LAN_X_STATUS_CHANGED" }, |
386 | | { Z21_LAN_X_TURNOUT_INFO, "LAN_X_TURNOUT_INFO" }, |
387 | | { Z21_LAN_X_UNKNOWN_COMMAND, "LAN_X_UNKNOWN_COMMAND" }, |
388 | | { Z21_LAN_ZLINK_GET_HWINFO, "LAN_ZLINK_GET_HWINFO" }, |
389 | | { 0, NULL }, |
390 | | }; |
391 | | |
392 | | static const value_string z21_loco_mode_vals[] = { |
393 | | { 0, "DCC Format" }, |
394 | | { 1, "MM Format" }, |
395 | | { 0, NULL }, |
396 | | }; |
397 | | |
398 | | static const value_string z21_hw_type_vals[] = { |
399 | | { 0x00000200, "Z21a" }, |
400 | | { 0x00000201, "Z21b" }, |
401 | | { 0x00000202, "SmartRail" }, |
402 | | { 0x00000203, "z21small" }, |
403 | | { 0x00000204, "z21start" }, |
404 | | { 0x00000205, "Z21 Single Booster" }, |
405 | | { 0x00000206, "Z21 Dual Booster" }, |
406 | | { 0x00000211, "Z21 XL Series" }, |
407 | | { 0x00000212, "Z21 XL Booster" }, |
408 | | { 0x00000301, "Z21 Switch Decoder" }, |
409 | | { 0x00000302, "Z21 Signal Decoder" }, |
410 | | { 0, NULL }, |
411 | | }; |
412 | | |
413 | | static const value_string z21_loco_info_speed_steps_vals[] = { |
414 | | { 0, "14 speed steps" }, |
415 | | { 2, "28 speed steps" }, |
416 | | { 4, "128 speed steps" }, |
417 | | { 0, NULL }, |
418 | | }; |
419 | | |
420 | | static const value_string z21_loco_func_vals[] = { |
421 | | { 0, "Off" }, |
422 | | { 1, "On" }, |
423 | | { 2, "Toggle" }, |
424 | | { 3, "Not allowed" }, |
425 | | { 0, NULL }, |
426 | | }; |
427 | | |
428 | | static const value_string z21_turnout_state_vals[] = { |
429 | | { 0, "Not switched yet" }, |
430 | | { 1, "Turnout is in position \"P=0\"" }, |
431 | | { 2, "Turnout is in position \"P=1\"" }, |
432 | | { 3, "Invalid combination" }, |
433 | | { 0, NULL }, |
434 | | }; |
435 | | |
436 | | static const value_string z21_pom_operation_vals[] = { |
437 | | { 0x39, "Read byte" }, /* 111001 */ |
438 | | { 0x3a, "Write bit" }, /* 111010 */ |
439 | | { 0x3b, "Write byte" }, /* 111011 */ |
440 | | { 0, NULL }, |
441 | | }; |
442 | | |
443 | | static const value_string z21_zlink_message_type_vals[] = { |
444 | | { 0x06, "ZLINK_MSG_TYPE_HW_INFO" }, |
445 | | { 0, NULL }, |
446 | | }; |
447 | | |
448 | | static const true_false_string tfs_forward_reverse = { "Forward", "Reverse" }; |
449 | | static const true_false_string tfs_turnout_command = { "Activate", "Deactivate" }; |
450 | | static const true_false_string tfs_turnout_output = { "Output 2", "Output 1" }; |
451 | | |
452 | | |
453 | | static void |
454 | | update_command_field(proto_item *ti, unsigned command) |
455 | 0 | { |
456 | 0 | int width = 8; |
457 | 0 | if (command <= 0xff) |
458 | 0 | width = 2; |
459 | 0 | else if (command <= 0xffff) |
460 | 0 | width = 4; |
461 | 0 | else if (command <= 0xffffff) |
462 | 0 | width = 6; |
463 | 0 | proto_item_append_text(ti, ": %s (0x%0*x)", |
464 | 0 | val_to_str_const(command, z21_command_vals, "unknown"), |
465 | 0 | width, command); |
466 | 0 | } |
467 | | |
468 | | |
469 | | /* Code to actually dissect the packets */ |
470 | | |
471 | | static int |
472 | | dissect_z21_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
473 | 0 | { |
474 | 0 | proto_item *ti, *temp_ti, *command_ti; |
475 | 0 | proto_tree *z21_tree; |
476 | 0 | unsigned offset = 0, datalen, command; |
477 | 0 | unsigned checksum, calculated_checksum, one_byte, version, temp_uint; |
478 | 0 | unsigned address_bytes, addr, speed_steps = 0, cv_addr; |
479 | 0 | uint64_t status, direction_and_speed, temp_uint64; |
480 | 0 | int32_t main_current, temp_int32; |
481 | 0 | char *buffer; |
482 | 0 | float temp_float; |
483 | 0 | static int * const broadcast_flags_bits[] = { |
484 | 0 | &hf_z21_broadcast_flags_loconet_detector, |
485 | 0 | &hf_z21_broadcast_flags_loconet_switching, |
486 | 0 | &hf_z21_broadcast_flags_loconet_driving, |
487 | 0 | &hf_z21_broadcast_flags_loconet, |
488 | 0 | &hf_z21_broadcast_flags_can_detector, |
489 | 0 | &hf_z21_broadcast_flags_railcom, |
490 | 0 | &hf_z21_broadcast_flags_can_booster, |
491 | 0 | &hf_z21_broadcast_flags_driving_switching_ex, |
492 | 0 | &hf_z21_broadcast_flags_system_status, |
493 | 0 | &hf_z21_broadcast_flags_fast_clock, |
494 | 0 | &hf_z21_broadcast_flags_railcom_subscribed, |
495 | 0 | &hf_z21_broadcast_flags_rmbus, |
496 | 0 | &hf_z21_broadcast_flags_driving_switching, |
497 | 0 | NULL |
498 | 0 | }; |
499 | 0 | static int * const state_bits_byte1[] = { |
500 | 0 | &hf_z21_state_programming_mode, |
501 | 0 | &hf_z21_state_short_circuit, |
502 | 0 | &hf_z21_state_track_voltage_off, |
503 | 0 | &hf_z21_state_emergency_stop, |
504 | 0 | NULL |
505 | 0 | }; |
506 | 0 | static int * const state_bits_byte2[] = { |
507 | 0 | &hf_z21_state_rcn_213, |
508 | 0 | &hf_z21_state_short_circuit_internal, |
509 | 0 | &hf_z21_state_short_circuit_external, |
510 | 0 | &hf_z21_state_power_lost, |
511 | 0 | &hf_z21_state_high_temperature, |
512 | 0 | NULL |
513 | 0 | }; |
514 | 0 | static int * const capability_bits[] = { |
515 | 0 | &hf_z21_capability_needs_unlock_code, |
516 | 0 | &hf_z21_capability_detector_cmds, |
517 | 0 | &hf_z21_capability_accessory_cmds, |
518 | 0 | &hf_z21_capability_loco_cmds, |
519 | 0 | &hf_z21_capability_railcom, |
520 | 0 | &hf_z21_capability_reserved, |
521 | 0 | &hf_z21_capability_mm, |
522 | 0 | &hf_z21_capability_dcc, |
523 | 0 | NULL |
524 | 0 | }; |
525 | 0 | static int * const speed_bits[] = { |
526 | 0 | &hf_z21_loco_direction, |
527 | 0 | &hf_z21_loco_speed, |
528 | 0 | NULL |
529 | 0 | }; |
530 | 0 | static int * const loco_info_bits1[] = { |
531 | 0 | &hf_z21_loco_info_mm, |
532 | 0 | &hf_z21_loco_info_busy, |
533 | 0 | &hf_z21_loco_info_speed_steps, |
534 | 0 | NULL |
535 | 0 | }; |
536 | 0 | static int * const loco_info_bits2[] = { |
537 | 0 | &hf_z21_loco_info_direction, |
538 | 0 | &hf_z21_loco_info_speed, |
539 | 0 | NULL |
540 | 0 | }; |
541 | 0 | static int * const loco_info_bits3[] = { |
542 | 0 | &hf_z21_loco_info_double_traction, |
543 | 0 | &hf_z21_loco_info_smartsearch, |
544 | 0 | &hf_z21_loco_info_f0, |
545 | 0 | &hf_z21_loco_info_f4, |
546 | 0 | &hf_z21_loco_info_f3, |
547 | 0 | &hf_z21_loco_info_f2, |
548 | 0 | &hf_z21_loco_info_f1, |
549 | 0 | NULL |
550 | 0 | }; |
551 | 0 | static int * const loco_info_bits4[] = { |
552 | 0 | &hf_z21_loco_info_f12, |
553 | 0 | &hf_z21_loco_info_f11, |
554 | 0 | &hf_z21_loco_info_f10, |
555 | 0 | &hf_z21_loco_info_f9, |
556 | 0 | &hf_z21_loco_info_f8, |
557 | 0 | &hf_z21_loco_info_f7, |
558 | 0 | &hf_z21_loco_info_f6, |
559 | 0 | &hf_z21_loco_info_f5, |
560 | 0 | NULL |
561 | 0 | }; |
562 | 0 | static int * const loco_info_bits5[] = { |
563 | 0 | &hf_z21_loco_info_f20, |
564 | 0 | &hf_z21_loco_info_f19, |
565 | 0 | &hf_z21_loco_info_f18, |
566 | 0 | &hf_z21_loco_info_f17, |
567 | 0 | &hf_z21_loco_info_f16, |
568 | 0 | &hf_z21_loco_info_f15, |
569 | 0 | &hf_z21_loco_info_f14, |
570 | 0 | &hf_z21_loco_info_f13, |
571 | 0 | NULL |
572 | 0 | }; |
573 | 0 | static int * const loco_info_bits6[] = { |
574 | 0 | &hf_z21_loco_info_f28, |
575 | 0 | &hf_z21_loco_info_f27, |
576 | 0 | &hf_z21_loco_info_f26, |
577 | 0 | &hf_z21_loco_info_f25, |
578 | 0 | &hf_z21_loco_info_f24, |
579 | 0 | &hf_z21_loco_info_f23, |
580 | 0 | &hf_z21_loco_info_f22, |
581 | 0 | &hf_z21_loco_info_f21, |
582 | 0 | NULL |
583 | 0 | }; |
584 | 0 | static int * const loco_info_bits7[] = { |
585 | 0 | &hf_z21_loco_info_f31, |
586 | 0 | &hf_z21_loco_info_f30, |
587 | 0 | &hf_z21_loco_info_f29, |
588 | 0 | NULL |
589 | 0 | }; |
590 | 0 | static int * const loco_func_bits[] = { |
591 | 0 | &hf_z21_loco_func_switch_type, |
592 | 0 | &hf_z21_loco_func_index, |
593 | 0 | NULL |
594 | 0 | }; |
595 | 0 | static int * const turnout_state_bits[] = { |
596 | 0 | &hf_z21_turnout_state, |
597 | 0 | NULL |
598 | 0 | }; |
599 | 0 | static int * const turnout_set_bits[] = { |
600 | 0 | &hf_z21_turnout_queue_bit, |
601 | 0 | &hf_z21_turnout_activate_bit, |
602 | 0 | &hf_z21_turnout_output_bit, |
603 | 0 | NULL |
604 | 0 | }; |
605 | 0 | static int * const cv_bits[] = { |
606 | 0 | &hf_z21_cv_bit_value, |
607 | 0 | &hf_z21_cv_bit_position, |
608 | 0 | NULL |
609 | 0 | }; |
610 | 0 | static int * const booster_state_bits[] = { |
611 | 0 | &hf_z21_can_booster_state_railcom_active, |
612 | 0 | &hf_z21_can_booster_state_output_disabled, |
613 | 0 | &hf_z21_can_booster_state_track_voltage_off, |
614 | 0 | &hf_z21_can_booster_state_short_circuit, |
615 | 0 | &hf_z21_can_booster_state_bg_active, |
616 | 0 | NULL |
617 | 0 | }; |
618 | | |
619 | | /* Check that the packet is long enough for it to belong to us. */ |
620 | 0 | if (tvb_reported_length(tvb) < Z21_MIN_LENGTH) |
621 | 0 | return 0; |
622 | | |
623 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "Z21"); |
624 | |
|
625 | 0 | ti = proto_tree_add_item(tree, proto_z21, tvb, 0, -1, ENC_NA); |
626 | 0 | z21_tree = proto_item_add_subtree(ti, ett_z21); |
627 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_datalen, |
628 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN, &datalen); |
629 | 0 | offset += 2; |
630 | 0 | command = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
631 | 0 | if (command == Z21_LAN_X_BC) { |
632 | 0 | proto_tree_add_boolean(z21_tree, hf_z21_x_bus, tvb, offset, 2, true); |
633 | | /* Note that we do not increment the offset yet */ |
634 | | |
635 | | /* Strategy: |
636 | | * 1. Read two bytes of the data (as big-endian) |
637 | | * 2. Prepend it with 0x4000 (the header bytes for X-BUS) |
638 | | * 3. If the three MSBs are one of the "one-byte commands", |
639 | | * set x_bus_command accordingly and run with that |
640 | | * 4. Otherwise run with "two-byte commands"... |
641 | | * 5. ... except that there are some commands that need more data to |
642 | | * determine the exact command (as their two "command bytes" are the |
643 | | * same), so check for those and set x_bus_command manually for them. |
644 | | */ |
645 | 0 | temp_uint = 0x40000000 + tvb_get_uint16(tvb, offset+2, ENC_BIG_ENDIAN); |
646 | 0 | unsigned x_bus_command = temp_uint >> 8; |
647 | | /* Check for all the "one-byte" commands */ |
648 | 0 | if (x_bus_command == Z21_LAN_X_SET_STOP || |
649 | 0 | x_bus_command == Z21_LAN_X_SET_LOCO_E_STOP || |
650 | 0 | x_bus_command == Z21_LAN_X_GET_EXT_ACCESSORY_INFO || |
651 | 0 | x_bus_command == Z21_LAN_X_SET_EXT_ACCESSORY || |
652 | 0 | x_bus_command == Z21_LAN_X_GET_TURNOUT_INFO || |
653 | 0 | x_bus_command == Z21_LAN_X_SET_TURNOUT || |
654 | 0 | x_bus_command == Z21_LAN_X_LOCO_INFO) { |
655 | | /* Initialize the checksum without the 0x4000 prefix */ |
656 | 0 | calculated_checksum = x_bus_command & 0xff; |
657 | | /* Check for these that are actually another command */ |
658 | 0 | if (x_bus_command == Z21_LAN_X_GET_TURNOUT_INFO && datalen == 9) { |
659 | 0 | x_bus_command = Z21_LAN_X_TURNOUT_INFO; |
660 | 0 | } else if (x_bus_command == Z21_LAN_X_GET_EXT_ACCESSORY_INFO && datalen == 10) { |
661 | 0 | x_bus_command = Z21_LAN_X_EXT_ACCESSORY_INFO; |
662 | 0 | } |
663 | 0 | command_ti = proto_tree_add_uint(z21_tree, hf_z21_command, tvb, offset, 3, x_bus_command); |
664 | 0 | offset += 3; |
665 | 0 | } |
666 | 0 | else { |
667 | | /* First assume "two-byte command", then check for exceptions */ |
668 | 0 | x_bus_command = temp_uint; |
669 | 0 | if (x_bus_command == Z21_LAN_X_CV_POM_COMMANDS || |
670 | 0 | x_bus_command == Z21_LAN_X_CV_POM_ACCESSORY_COMMANDS) { |
671 | | /* Read DB3 from data, get the two interesting bits */ |
672 | 0 | temp_uint = tvb_get_uint8(tvb, offset + 6) >> 2 & 0x3; |
673 | 0 | switch (x_bus_command) { |
674 | 0 | case Z21_LAN_X_CV_POM_COMMANDS: |
675 | 0 | if (temp_uint == 0x1) |
676 | 0 | x_bus_command = Z21_LAN_X_CV_POM_READ_BYTE; |
677 | 0 | else if (temp_uint == 0x2) |
678 | 0 | x_bus_command = Z21_LAN_X_CV_POM_WRITE_BIT; |
679 | 0 | else if (temp_uint == 0x3) |
680 | 0 | x_bus_command = Z21_LAN_X_CV_POM_WRITE_BYTE; |
681 | 0 | break; |
682 | 0 | case Z21_LAN_X_CV_POM_ACCESSORY_COMMANDS: |
683 | 0 | if (temp_uint == 0x1) |
684 | 0 | x_bus_command = Z21_LAN_X_CV_POM_ACCESSORY_READ_BYTE; |
685 | 0 | else if (temp_uint == 0x2) |
686 | 0 | x_bus_command = Z21_LAN_X_CV_POM_ACCESSORY_WRITE_BIT; |
687 | 0 | else if (temp_uint == 0x3) |
688 | 0 | x_bus_command = Z21_LAN_X_CV_POM_ACCESSORY_WRITE_BYTE; |
689 | 0 | break; |
690 | 0 | } |
691 | 0 | } |
692 | 0 | command_ti = proto_tree_add_uint(z21_tree, hf_z21_command, |
693 | 0 | tvb, offset, 4, x_bus_command); |
694 | 0 | offset += 4; |
695 | | /* Initialize the checksum with the two LSBs */ |
696 | 0 | calculated_checksum = ((x_bus_command & 0xff00) >> 8) ^ (x_bus_command & 0x00ff); |
697 | 0 | } |
698 | 0 | update_command_field(command_ti, x_bus_command); |
699 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Command=%s", |
700 | 0 | val_to_str_const(x_bus_command, z21_command_vals, "unknown")); |
701 | 0 | proto_item_append_text(z21_tree, ", Command: %s", |
702 | 0 | val_to_str_const(x_bus_command, z21_command_vals, "unknown")); |
703 | 0 | switch (x_bus_command) { |
704 | 0 | case Z21_LAN_X_STATUS_CHANGED: |
705 | 0 | proto_tree_add_bitmask_ret_uint64(z21_tree, tvb, offset, hf_z21_status, |
706 | 0 | ett_z21, state_bits_byte1, ENC_NA, &status); |
707 | 0 | offset += 1; |
708 | 0 | calculated_checksum ^= (unsigned)status; |
709 | 0 | break; |
710 | 0 | case Z21_LAN_X_SET_LOCO_DRIVE_DCC14: |
711 | 0 | case Z21_LAN_X_SET_LOCO_DRIVE_DCC28: |
712 | 0 | case Z21_LAN_X_SET_LOCO_DRIVE_DCC128: |
713 | 0 | address_bytes = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
714 | 0 | addr = address_bytes & 0x3FFF; |
715 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_address, tvb, offset, 2, addr); |
716 | 0 | switch (x_bus_command) { |
717 | 0 | case Z21_LAN_X_SET_LOCO_DRIVE_DCC14: speed_steps = 14; break; |
718 | 0 | case Z21_LAN_X_SET_LOCO_DRIVE_DCC28: speed_steps = 28; break; |
719 | 0 | case Z21_LAN_X_SET_LOCO_DRIVE_DCC128: speed_steps = 128; break; |
720 | 0 | } |
721 | 0 | proto_tree_add_uint(z21_tree, hf_z21_speed_steps, tvb, offset-1, 1, speed_steps); |
722 | 0 | offset += 2; |
723 | 0 | calculated_checksum ^= address_bytes >> 8; |
724 | 0 | calculated_checksum ^= address_bytes & 0xFF; |
725 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d (%d SS)", |
726 | 0 | addr, speed_steps); |
727 | 0 | temp_ti = proto_tree_add_bitmask_ret_uint64(z21_tree, tvb, offset, hf_z21_loco_direction_and_speed, |
728 | 0 | ett_z21, speed_bits, ENC_NA, &direction_and_speed); |
729 | 0 | offset += 1; |
730 | 0 | calculated_checksum ^= (unsigned)direction_and_speed; |
731 | 0 | if (direction_and_speed & 0x80) { |
732 | 0 | proto_item_set_text(temp_ti, |
733 | 0 | "Locomotive direction and speed: Forward, 0x%02" PRIx64, |
734 | 0 | direction_and_speed & 0x7F); |
735 | 0 | col_append_str(pinfo->cinfo, COL_INFO, ", Forward"); |
736 | 0 | } |
737 | 0 | else { |
738 | 0 | proto_item_set_text(temp_ti, |
739 | 0 | "Locomotive direction and speed: Reverse, 0x%02" PRIx64, |
740 | 0 | direction_and_speed & 0x7F); |
741 | 0 | col_append_str(pinfo->cinfo, COL_INFO, ", Reverse"); |
742 | 0 | } |
743 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Speed=0x%02" PRIx64, |
744 | 0 | direction_and_speed & 0x7F); |
745 | 0 | break; |
746 | 0 | case Z21_LAN_X_GET_LOCO_INFO: |
747 | 0 | address_bytes = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
748 | 0 | addr = address_bytes & 0x3FFF; |
749 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_address, tvb, offset, 2, addr); |
750 | 0 | offset += 2; |
751 | 0 | calculated_checksum ^= address_bytes >> 8; |
752 | 0 | calculated_checksum ^= address_bytes & 0xFF; |
753 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d", addr); |
754 | 0 | break; |
755 | 0 | case Z21_LAN_X_LOCO_INFO: |
756 | 0 | address_bytes = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
757 | 0 | addr = address_bytes & 0x3FFF; |
758 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_address, tvb, offset, 2, addr); |
759 | 0 | offset += 2; |
760 | 0 | calculated_checksum ^= address_bytes >> 8; |
761 | 0 | calculated_checksum ^= address_bytes & 0xFF; |
762 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d", addr); |
763 | 0 | proto_item_append_text(z21_tree, ", Loco: %d", addr); |
764 | |
|
765 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
766 | 0 | loco_info_bits1, ENC_NA, &temp_uint64); |
767 | 0 | offset += 1; |
768 | 0 | calculated_checksum ^= temp_uint64; |
769 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", |
770 | 0 | val_to_str_const((uint32_t)temp_uint64 & 0x07, |
771 | 0 | z21_loco_info_speed_steps_vals, "unknown")); |
772 | |
|
773 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
774 | 0 | loco_info_bits2, ENC_NA, &temp_uint64); |
775 | 0 | offset += 1; |
776 | 0 | calculated_checksum ^= temp_uint64; |
777 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", |
778 | 0 | tfs_get_string((bool)(temp_uint64 >> 7), &tfs_forward_reverse)); |
779 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Speed=0x%02" PRIx64, |
780 | 0 | temp_uint64 & 0x7f); |
781 | |
|
782 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
783 | 0 | loco_info_bits3, ENC_NA, &temp_uint64); |
784 | 0 | offset += 1; |
785 | 0 | calculated_checksum ^= temp_uint64; |
786 | 0 | if (temp_uint64 & 0x40) { |
787 | 0 | col_append_str(pinfo->cinfo, COL_INFO, ", in double traction"); |
788 | 0 | } |
789 | |
|
790 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
791 | 0 | loco_info_bits4, ENC_NA, &temp_uint64); |
792 | 0 | offset += 1; |
793 | 0 | calculated_checksum ^= temp_uint64; |
794 | |
|
795 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
796 | 0 | loco_info_bits5, ENC_NA, &temp_uint64); |
797 | 0 | offset += 1; |
798 | 0 | calculated_checksum ^= temp_uint64; |
799 | | |
800 | | /* The following bytes are not always there it seems */ |
801 | 0 | if (offset < datalen-1) { |
802 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
803 | 0 | loco_info_bits6, ENC_NA, &temp_uint64); |
804 | 0 | offset += 1; |
805 | 0 | calculated_checksum ^= temp_uint64; |
806 | 0 | } |
807 | 0 | if (offset < datalen-1) { |
808 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
809 | 0 | loco_info_bits7, ENC_NA, &temp_uint64); |
810 | 0 | offset += 1; |
811 | 0 | calculated_checksum ^= temp_uint64; |
812 | 0 | } |
813 | | /* If still something, dissect as bytes */ |
814 | 0 | if (offset < datalen-1) { |
815 | 0 | proto_tree_add_item(z21_tree, hf_z21_loco_info_extensions, |
816 | 0 | tvb, offset, datalen-1-offset, ENC_NA); |
817 | | /* Note: Do not increment offset because the checksum |
818 | | * will be calculated below! */ |
819 | 0 | } |
820 | 0 | break; |
821 | 0 | case Z21_LAN_X_PURGE_LOCO: |
822 | 0 | address_bytes = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
823 | 0 | addr = address_bytes & 0x3FFF; |
824 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_address, tvb, offset, 2, addr); |
825 | 0 | offset += 2; |
826 | 0 | calculated_checksum ^= address_bytes >> 8; |
827 | 0 | calculated_checksum ^= address_bytes & 0xFF; |
828 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d", addr); |
829 | 0 | proto_item_append_text(z21_tree, ", Loco: %d", addr); |
830 | 0 | break; |
831 | 0 | case Z21_LAN_X_SET_LOCO_E_STOP: |
832 | 0 | address_bytes = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
833 | 0 | addr = address_bytes & 0x3FFF; |
834 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_address, tvb, offset, 2, addr); |
835 | 0 | offset += 2; |
836 | 0 | calculated_checksum ^= address_bytes >> 8; |
837 | 0 | calculated_checksum ^= address_bytes & 0xFF; |
838 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d", addr); |
839 | 0 | proto_item_append_text(z21_tree, ", Loco: %d", addr); |
840 | 0 | break; |
841 | 0 | case Z21_LAN_X_SET_LOCO_BINARY_STATE: |
842 | 0 | col_append_str(pinfo->cinfo, COL_INFO, ", TO BE COMPLETED"); |
843 | 0 | break; |
844 | 0 | case Z21_LAN_X_SET_LOCO_FUNCTION: |
845 | 0 | address_bytes = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
846 | 0 | addr = address_bytes & 0x3FFF; |
847 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_address, tvb, offset, 2, addr); |
848 | 0 | offset += 2; |
849 | 0 | calculated_checksum ^= address_bytes >> 8; |
850 | 0 | calculated_checksum ^= address_bytes & 0xFF; |
851 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d", addr); |
852 | 0 | proto_item_append_text(z21_tree, ", Loco: %d", addr); |
853 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
854 | 0 | loco_func_bits, ENC_NA, &temp_uint64); |
855 | 0 | offset += 1; |
856 | 0 | calculated_checksum ^= temp_uint64; |
857 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Function=%" PRIu64 ", State=%s", |
858 | 0 | temp_uint64 & 0x3f, |
859 | 0 | val_to_str_const((uint32_t)temp_uint64 >> 6, z21_loco_func_vals, "unknown")); |
860 | 0 | proto_item_append_text(z21_tree, ", Function: %" PRIu64 ", State: %s", |
861 | 0 | temp_uint64 & 0x3f, |
862 | 0 | val_to_str_const((uint32_t)temp_uint64 >> 6, z21_loco_func_vals, "unknown")); |
863 | 0 | break; |
864 | 0 | case Z21_LAN_X_GET_TURNOUT_INFO: |
865 | 0 | addr = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
866 | 0 | proto_tree_add_uint(z21_tree, hf_z21_function_address, |
867 | 0 | tvb, offset, 2, addr); |
868 | 0 | offset += 2; |
869 | 0 | calculated_checksum ^= addr >> 8; |
870 | 0 | calculated_checksum ^= addr & 0xFF; |
871 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Function=%d", addr); |
872 | 0 | proto_item_append_text(z21_tree, ", Function: %d", addr); |
873 | 0 | break; |
874 | 0 | case Z21_LAN_X_TURNOUT_INFO: |
875 | 0 | addr = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
876 | 0 | proto_tree_add_uint(z21_tree, hf_z21_function_address, |
877 | 0 | tvb, offset, 2, addr); |
878 | 0 | offset += 2; |
879 | 0 | calculated_checksum ^= addr >> 8; |
880 | 0 | calculated_checksum ^= addr & 0xFF; |
881 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
882 | 0 | turnout_state_bits, ENC_NA, &temp_uint64); |
883 | 0 | offset += 1; |
884 | 0 | calculated_checksum ^= temp_uint64; |
885 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Address=%d, State=%s", |
886 | 0 | addr, |
887 | 0 | val_to_str_const((uint32_t)temp_uint64 & 0x03, z21_turnout_state_vals, "unknown")); |
888 | 0 | proto_item_append_text(z21_tree, ", Address: %d, State: %s", |
889 | 0 | addr, |
890 | 0 | val_to_str_const((uint32_t)temp_uint64 & 0x03, z21_turnout_state_vals, "unknown")); |
891 | 0 | break; |
892 | 0 | case Z21_LAN_X_SET_TURNOUT: |
893 | 0 | addr = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
894 | 0 | proto_tree_add_uint(z21_tree, hf_z21_function_address, |
895 | 0 | tvb, offset, 2, addr); |
896 | 0 | offset += 2; |
897 | 0 | calculated_checksum ^= addr >> 8; |
898 | 0 | calculated_checksum ^= addr & 0xFF; |
899 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Address=%d", addr); |
900 | 0 | proto_item_append_text(z21_tree, ", Address: %d", addr); |
901 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
902 | 0 | turnout_set_bits, ENC_NA, &temp_uint64); |
903 | 0 | offset += 1; |
904 | 0 | calculated_checksum ^= temp_uint64; |
905 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Address=%d, %s, Output=%s", |
906 | 0 | addr, |
907 | 0 | tfs_get_string((bool)(temp_uint64 & 0x08), &tfs_turnout_command), |
908 | 0 | tfs_get_string((bool)(temp_uint64 & 0x01), &tfs_turnout_output)); |
909 | 0 | proto_item_append_text(z21_tree, ", Address: %d, %s, Output: %s", |
910 | 0 | addr, |
911 | 0 | tfs_get_string((bool)(temp_uint64 & 0x08), &tfs_turnout_command), |
912 | 0 | tfs_get_string((bool)(temp_uint64 & 0x01), &tfs_turnout_output)); |
913 | 0 | break; |
914 | 0 | case Z21_LAN_X_GET_EXT_ACCESSORY_INFO: |
915 | 0 | addr = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
916 | 0 | proto_tree_add_uint(z21_tree, hf_z21_accessory_address, |
917 | 0 | tvb, offset, 2, addr); |
918 | 0 | offset += 2; |
919 | 0 | calculated_checksum ^= addr >> 8; |
920 | 0 | calculated_checksum ^= addr & 0xFF; |
921 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Address=%d", addr); |
922 | 0 | proto_item_append_text(z21_tree, ", Address: %d", addr); |
923 | 0 | break; |
924 | 0 | case Z21_LAN_X_EXT_ACCESSORY_INFO: |
925 | 0 | addr = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
926 | 0 | proto_tree_add_uint(z21_tree, hf_z21_accessory_address, |
927 | 0 | tvb, offset, 2, addr); |
928 | 0 | offset += 2; |
929 | 0 | calculated_checksum ^= addr >> 8; |
930 | 0 | calculated_checksum ^= addr & 0xFF; |
931 | 0 | temp_uint = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
932 | 0 | proto_tree_add_uint(z21_tree, hf_z21_accessory_state, |
933 | 0 | tvb, offset, 1, temp_uint >> 8); |
934 | 0 | offset += 1; |
935 | 0 | calculated_checksum ^= temp_uint >> 8; |
936 | 0 | proto_tree_add_uint(z21_tree, hf_z21_accessory_status, |
937 | 0 | tvb, offset, 1, temp_uint & 0xff); |
938 | 0 | offset += 1; |
939 | 0 | calculated_checksum ^= temp_uint & 0xff; |
940 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Address=%d, State=%d, Status=0x%02x", |
941 | 0 | addr, temp_uint >> 8, temp_uint & 0xff); |
942 | 0 | proto_item_append_text(z21_tree, ", Address: %d, State: %d, Status: 0x%02x", |
943 | 0 | addr, temp_uint >> 8, temp_uint & 0xff); |
944 | 0 | break; |
945 | 0 | case Z21_LAN_X_SET_EXT_ACCESSORY: |
946 | 0 | addr = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
947 | 0 | proto_tree_add_uint(z21_tree, hf_z21_accessory_address, |
948 | 0 | tvb, offset, 2, addr); |
949 | 0 | offset += 2; |
950 | 0 | calculated_checksum ^= addr >> 8; |
951 | 0 | calculated_checksum ^= addr & 0xFF; |
952 | 0 | temp_uint = tvb_get_uint8(tvb, offset); |
953 | 0 | proto_tree_add_uint(z21_tree, hf_z21_accessory_state, |
954 | 0 | tvb, offset, 1, temp_uint); |
955 | 0 | offset += 1; |
956 | 0 | calculated_checksum ^= temp_uint; |
957 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Address=%d, State=%d", |
958 | 0 | addr, temp_uint); |
959 | 0 | proto_item_append_text(z21_tree, ", Address: %d, State: %d", |
960 | 0 | addr, temp_uint); |
961 | 0 | break; |
962 | 0 | case Z21_LAN_X_CV_READ: |
963 | 0 | cv_addr = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
964 | | /* CV addresses are 1-based, update checksum first */ |
965 | 0 | calculated_checksum ^= cv_addr >> 8; |
966 | 0 | calculated_checksum ^= cv_addr & 0xFF; |
967 | 0 | cv_addr += 1; |
968 | 0 | proto_tree_add_uint(z21_tree, hf_z21_cv_address, |
969 | 0 | tvb, offset, 2, cv_addr); |
970 | 0 | offset += 2; |
971 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", CV%d", cv_addr); |
972 | 0 | proto_item_append_text(z21_tree, ", CV%d", cv_addr); |
973 | 0 | break; |
974 | 0 | case Z21_LAN_X_CV_WRITE: |
975 | 0 | cv_addr = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
976 | | /* CV addresses are 1-based, update checksum first */ |
977 | 0 | calculated_checksum ^= cv_addr >> 8; |
978 | 0 | calculated_checksum ^= cv_addr & 0xFF; |
979 | 0 | cv_addr += 1; |
980 | 0 | proto_tree_add_uint(z21_tree, hf_z21_cv_address, |
981 | 0 | tvb, offset, 2, cv_addr); |
982 | 0 | offset += 2; |
983 | 0 | temp_uint = tvb_get_uint8(tvb, offset); |
984 | 0 | proto_tree_add_uint(z21_tree, hf_z21_cv_value, |
985 | 0 | tvb, offset, 1, temp_uint); |
986 | 0 | offset += 1; |
987 | 0 | calculated_checksum ^= temp_uint; |
988 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", CV%d, Value=%d", |
989 | 0 | cv_addr, temp_uint); |
990 | 0 | proto_item_append_text(z21_tree, ", CV%d, Value: %d", |
991 | 0 | cv_addr, temp_uint); |
992 | 0 | break; |
993 | 0 | case Z21_LAN_X_CV_RESULT: |
994 | 0 | cv_addr = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
995 | | /* CV addresses are 1-based, update checksum first */ |
996 | 0 | calculated_checksum ^= cv_addr >> 8; |
997 | 0 | calculated_checksum ^= cv_addr & 0xFF; |
998 | 0 | cv_addr += 1; |
999 | 0 | proto_tree_add_uint(z21_tree, hf_z21_cv_address, |
1000 | 0 | tvb, offset, 2, cv_addr); |
1001 | 0 | offset += 2; |
1002 | 0 | temp_uint = tvb_get_uint8(tvb, offset); |
1003 | 0 | proto_tree_add_uint(z21_tree, hf_z21_cv_value, |
1004 | 0 | tvb, offset, 1, temp_uint); |
1005 | 0 | offset += 1; |
1006 | 0 | calculated_checksum ^= temp_uint; |
1007 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", CV%d, Value=%d", |
1008 | 0 | cv_addr, temp_uint); |
1009 | 0 | proto_item_append_text(z21_tree, ", CV%d, Value: %d", |
1010 | 0 | cv_addr, temp_uint); |
1011 | 0 | break; |
1012 | 0 | case Z21_LAN_X_CV_POM_WRITE_BYTE: |
1013 | 0 | address_bytes = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
1014 | 0 | addr = address_bytes & 0x3FFF; |
1015 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_address, tvb, offset, 2, addr); |
1016 | 0 | offset += 2; |
1017 | 0 | calculated_checksum ^= address_bytes >> 8; |
1018 | 0 | calculated_checksum ^= address_bytes & 0xFF; |
1019 | 0 | temp_uint = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
1020 | 0 | calculated_checksum ^= temp_uint >> 8; |
1021 | 0 | calculated_checksum ^= temp_uint & 0xff; |
1022 | 0 | proto_tree_add_uint(z21_tree, hf_z21_pom_operation, |
1023 | 0 | tvb, offset, 1, temp_uint >> 2); |
1024 | 0 | cv_addr = (temp_uint & 0x03ff) + 1; |
1025 | 0 | proto_tree_add_uint(z21_tree, hf_z21_cv_address, |
1026 | 0 | tvb, offset, 2, cv_addr); |
1027 | 0 | offset += 2; |
1028 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_cv_value, |
1029 | 0 | tvb, offset, 1, ENC_NA, &temp_uint); |
1030 | 0 | offset += 1; |
1031 | 0 | calculated_checksum ^= temp_uint; |
1032 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d, CV%d, Value=%d", |
1033 | 0 | addr, cv_addr, temp_uint); |
1034 | 0 | proto_item_append_text(z21_tree, ", Loco: %d, CV%d, Value: %d", |
1035 | 0 | addr, cv_addr, temp_uint); |
1036 | 0 | break; |
1037 | 0 | case Z21_LAN_X_CV_POM_WRITE_BIT: |
1038 | 0 | address_bytes = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
1039 | 0 | addr = address_bytes & 0x3FFF; |
1040 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_address, tvb, offset, 2, addr); |
1041 | 0 | offset += 2; |
1042 | 0 | calculated_checksum ^= address_bytes >> 8; |
1043 | 0 | calculated_checksum ^= address_bytes & 0xFF; |
1044 | 0 | temp_uint = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
1045 | 0 | calculated_checksum ^= temp_uint >> 8; |
1046 | 0 | calculated_checksum ^= temp_uint & 0xff; |
1047 | 0 | proto_tree_add_uint(z21_tree, hf_z21_pom_operation, |
1048 | 0 | tvb, offset, 1, temp_uint >> 2); |
1049 | 0 | cv_addr = (temp_uint & 0x03ff) + 1; |
1050 | 0 | proto_tree_add_uint(z21_tree, hf_z21_cv_address, |
1051 | 0 | tvb, offset, 2, cv_addr); |
1052 | 0 | offset += 2; |
1053 | 0 | proto_tree_add_bitmask_list_ret_uint64(z21_tree, tvb, offset, 1, |
1054 | 0 | cv_bits, ENC_NA, &temp_uint64); |
1055 | 0 | offset += 1; |
1056 | 0 | calculated_checksum ^= (unsigned)temp_uint64; |
1057 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d, CV%d, Bit position=%" PRIu64 ", Value=%" PRIu64, |
1058 | 0 | addr, cv_addr, temp_uint64 & 0x07, temp_uint64 >> 3 & 0x01); |
1059 | 0 | proto_item_append_text(z21_tree, ", Loco: %d, CV%d, Bit position: %" PRIu64 ", Value: %" PRIu64, |
1060 | 0 | addr, cv_addr, temp_uint64 & 0x07, temp_uint64 >> 3 & 0x01); |
1061 | 0 | break; |
1062 | 0 | case Z21_LAN_X_CV_POM_READ_BYTE: |
1063 | 0 | address_bytes = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
1064 | 0 | addr = address_bytes & 0x3FFF; |
1065 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_address, tvb, offset, 2, addr); |
1066 | 0 | offset += 2; |
1067 | 0 | calculated_checksum ^= address_bytes >> 8; |
1068 | 0 | calculated_checksum ^= address_bytes & 0xFF; |
1069 | 0 | temp_uint = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
1070 | 0 | calculated_checksum ^= temp_uint >> 8; |
1071 | 0 | calculated_checksum ^= temp_uint & 0xff; |
1072 | 0 | proto_tree_add_uint(z21_tree, hf_z21_pom_operation, |
1073 | 0 | tvb, offset, 1, temp_uint >> 2); |
1074 | 0 | cv_addr = (temp_uint & 0x03ff) + 1; |
1075 | 0 | proto_tree_add_uint(z21_tree, hf_z21_cv_address, |
1076 | 0 | tvb, offset, 2, cv_addr); |
1077 | 0 | offset += 2; |
1078 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d, CV%d", |
1079 | 0 | addr, cv_addr); |
1080 | 0 | proto_item_append_text(z21_tree, ", Loco: %d, CV%d", |
1081 | 0 | addr, cv_addr); |
1082 | 0 | break; |
1083 | 0 | case Z21_LAN_X_CV_POM_ACCESSORY_WRITE_BYTE: |
1084 | 0 | case Z21_LAN_X_CV_POM_ACCESSORY_WRITE_BIT: |
1085 | 0 | case Z21_LAN_X_CV_POM_ACCESSORY_READ_BYTE: |
1086 | 0 | col_append_str(pinfo->cinfo, COL_INFO, ", *** TO BE COMPLETED ***"); |
1087 | 0 | break; |
1088 | 0 | case Z21_LAN_X_DCC_READ_REGISTER: |
1089 | 0 | temp_uint = tvb_get_uint8(tvb, offset); |
1090 | 0 | proto_tree_add_uint(z21_tree, hf_z21_register, |
1091 | 0 | tvb, offset, 1, temp_uint); |
1092 | 0 | offset += 1; |
1093 | 0 | calculated_checksum ^= temp_uint; |
1094 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Register%d", |
1095 | 0 | temp_uint); |
1096 | 0 | proto_item_append_text(z21_tree, ", Register%d", |
1097 | 0 | temp_uint); |
1098 | 0 | break; |
1099 | 0 | case Z21_LAN_X_DCC_WRITE_REGISTER: |
1100 | 0 | temp_uint = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
1101 | 0 | proto_tree_add_uint(z21_tree, hf_z21_register, |
1102 | 0 | tvb, offset, 1, temp_uint >> 8); |
1103 | 0 | offset += 1; |
1104 | 0 | calculated_checksum ^= temp_uint >> 8; |
1105 | 0 | proto_tree_add_uint(z21_tree, hf_z21_register_value, |
1106 | 0 | tvb, offset, 1, temp_uint & 0xff); |
1107 | 0 | offset += 1; |
1108 | 0 | calculated_checksum ^= temp_uint & 0xff; |
1109 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Register%d, Value=%d", |
1110 | 0 | temp_uint >> 8, temp_uint & 0xff); |
1111 | 0 | proto_item_append_text(z21_tree, ", Register%d, Value: %d", |
1112 | 0 | temp_uint >> 8, temp_uint & 0xff); |
1113 | 0 | break; |
1114 | 0 | case Z21_LAN_X_MM_WRITE_BYTE: |
1115 | | /* Skip one zero byte */ |
1116 | 0 | offset += 1; |
1117 | 0 | temp_uint = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
1118 | 0 | proto_tree_add_uint(z21_tree, hf_z21_register, |
1119 | 0 | tvb, offset, 1, temp_uint >> 8); |
1120 | 0 | offset += 1; |
1121 | 0 | calculated_checksum ^= temp_uint >> 8; |
1122 | 0 | proto_tree_add_uint(z21_tree, hf_z21_register_value, |
1123 | 0 | tvb, offset, 1, temp_uint & 0xff); |
1124 | 0 | offset += 1; |
1125 | 0 | calculated_checksum ^= temp_uint & 0xff; |
1126 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Register%d, Value=%d", |
1127 | 0 | temp_uint >> 8, temp_uint & 0xff); |
1128 | 0 | proto_item_append_text(z21_tree, ", Register%d, Value: %d", |
1129 | 0 | temp_uint >> 8, temp_uint & 0xff); |
1130 | 0 | break; |
1131 | 0 | case Z21_LAN_X_GET_FIRMWARE_VERSION_REPLY: |
1132 | 0 | version = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
1133 | 0 | buffer = wmem_strdup_printf(pinfo->pool, "%x.%02x", |
1134 | 0 | version >> 8, version & 0xff); |
1135 | 0 | proto_tree_add_string(z21_tree, hf_z21_firmware_version, |
1136 | 0 | tvb, offset, 2, buffer); |
1137 | 0 | offset += 2; |
1138 | 0 | calculated_checksum ^= version >> 8; |
1139 | 0 | calculated_checksum ^= version & 0xFF; |
1140 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Version=%s", |
1141 | 0 | buffer); |
1142 | 0 | } |
1143 | | |
1144 | | /* Calculate checksum for the rest of the bytes (if any) for now */ |
1145 | 0 | while (offset < datalen-1) { |
1146 | 0 | one_byte = tvb_get_uint8(tvb, offset); |
1147 | 0 | offset += 1; |
1148 | 0 | calculated_checksum ^= one_byte; |
1149 | 0 | } |
1150 | | /* No more data in the X-BUS command, read the checksum */ |
1151 | 0 | temp_ti = proto_tree_add_item_ret_uint(z21_tree, hf_z21_checksum, |
1152 | 0 | tvb, offset, 1, ENC_NA, &checksum); |
1153 | 0 | if (checksum != calculated_checksum) { |
1154 | 0 | expert_add_info_format(pinfo, temp_ti, &ei_z21_invalid_checksum, |
1155 | 0 | "Invalid checksum, calculated: 0x%02x", calculated_checksum); |
1156 | 0 | } |
1157 | 0 | } |
1158 | 0 | else { |
1159 | | /* Not X-BUS */ |
1160 | 0 | command_ti = proto_tree_add_uint(z21_tree, hf_z21_command, |
1161 | 0 | tvb, offset, 2, command); |
1162 | 0 | offset += 2; |
1163 | 0 | update_command_field(command_ti, command); |
1164 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Command=%s", |
1165 | 0 | val_to_str_const(command, z21_command_vals, "unknown")); |
1166 | 0 | proto_item_append_text(z21_tree, ", Command: %s", |
1167 | 0 | val_to_str_const(command, z21_command_vals, "unknown")); |
1168 | 0 | switch (command) { |
1169 | 0 | case Z21_LAN_GET_SERIAL_NUMBER: |
1170 | 0 | if (datalen == 8) { |
1171 | 0 | unsigned serial; |
1172 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_serial_number, |
1173 | 0 | tvb, offset, 4, ENC_LITTLE_ENDIAN, &serial); |
1174 | 0 | offset += 4; |
1175 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Serial number: %d", |
1176 | 0 | serial); |
1177 | 0 | } |
1178 | 0 | break; |
1179 | 0 | case Z21_LAN_SYSTEMSTATE_DATACHANGED: |
1180 | 0 | main_current = tvb_get_int16(tvb, offset, ENC_LITTLE_ENDIAN); |
1181 | 0 | proto_tree_add_int_format_value(z21_tree, hf_z21_main_current, |
1182 | 0 | tvb, offset, 2, main_current, "%d mA", main_current); |
1183 | 0 | offset += 2; |
1184 | |
|
1185 | 0 | temp_int32 = tvb_get_int16(tvb, offset, ENC_LITTLE_ENDIAN); |
1186 | 0 | proto_tree_add_int_format_value(z21_tree, hf_z21_prog_current, |
1187 | 0 | tvb, offset, 2, temp_int32, "%d mA", temp_int32); |
1188 | 0 | offset += 2; |
1189 | |
|
1190 | 0 | temp_int32 = tvb_get_int16(tvb, offset, ENC_LITTLE_ENDIAN); |
1191 | 0 | proto_tree_add_int_format_value(z21_tree, hf_z21_filtered_main_current, |
1192 | 0 | tvb, offset, 2, temp_int32, "%d mA", temp_int32); |
1193 | 0 | offset += 2; |
1194 | |
|
1195 | 0 | temp_int32 = tvb_get_int16(tvb, offset, ENC_LITTLE_ENDIAN); |
1196 | 0 | proto_tree_add_int_format_value(z21_tree, hf_z21_temperature, |
1197 | 0 | tvb, offset, 2, temp_int32, "%d°C", temp_int32); |
1198 | 0 | offset += 2; |
1199 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, |
1200 | 0 | ", Temperature=%d°C", temp_int32); |
1201 | |
|
1202 | 0 | temp_uint = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN); |
1203 | 0 | temp_float = (float)temp_uint / 1000; |
1204 | 0 | proto_tree_add_float_format_value(z21_tree, hf_z21_supply_voltage, |
1205 | 0 | tvb, offset, 2, temp_float, "%.3f V", temp_float); |
1206 | 0 | offset += 2; |
1207 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, |
1208 | 0 | ", Track=%.3f V/%d mA", temp_float, main_current); |
1209 | |
|
1210 | 0 | temp_uint = tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN); |
1211 | 0 | temp_float = (float)temp_uint / 1000; |
1212 | 0 | proto_tree_add_float_format_value(z21_tree, hf_z21_track_voltage, |
1213 | 0 | tvb, offset, 2, temp_float, "%.3f V", temp_float); |
1214 | 0 | offset += 2; |
1215 | |
|
1216 | 0 | proto_tree_add_bitmask(z21_tree, tvb, offset, hf_z21_central_state, |
1217 | 0 | ett_z21, state_bits_byte1, ENC_NA); |
1218 | 0 | offset += 1; |
1219 | 0 | proto_tree_add_bitmask(z21_tree, tvb, offset, hf_z21_central_state_ex, |
1220 | 0 | ett_z21, state_bits_byte2, ENC_NA); |
1221 | 0 | offset += 1; |
1222 | 0 | proto_tree_add_item(z21_tree, hf_z21_systemstate_reserved, |
1223 | 0 | tvb, offset, 1, ENC_NA); |
1224 | 0 | offset += 1; |
1225 | 0 | temp_uint = tvb_get_uint8(tvb, offset); |
1226 | 0 | if (temp_uint == 0) { |
1227 | | /* Don't interpret the flags */ |
1228 | 0 | proto_tree_add_uint_format_value(z21_tree, hf_z21_capabilities, |
1229 | 0 | tvb, offset, 1, 0, "0x00 (Capability flags not supported)"); |
1230 | 0 | } |
1231 | 0 | else { |
1232 | 0 | proto_tree_add_bitmask(z21_tree, tvb, offset, hf_z21_capabilities, |
1233 | 0 | ett_z21, capability_bits, ENC_NA); |
1234 | 0 | } |
1235 | 0 | offset += 1; |
1236 | 0 | break; |
1237 | 0 | case Z21_LAN_RMBUS_GETDATA: |
1238 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_rmbus_group, |
1239 | 0 | tvb, offset, 1, ENC_NA, &temp_uint); |
1240 | 0 | offset += 1; |
1241 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Group=%d", temp_uint); |
1242 | 0 | proto_item_append_text(z21_tree, ", Group: %d", temp_uint); |
1243 | 0 | break; |
1244 | 0 | case Z21_LAN_RMBUS_DATACHANGED: |
1245 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_rmbus_group, |
1246 | 0 | tvb, offset, 1, ENC_NA, &temp_uint); |
1247 | 0 | offset += 1; |
1248 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Group=%d", temp_uint); |
1249 | 0 | proto_item_append_text(z21_tree, ", Group: %d", temp_uint); |
1250 | 0 | proto_tree_add_item(z21_tree, hf_z21_rmbus_feedbacks, tvb, offset, 10, ENC_NA); |
1251 | 0 | offset += 10; |
1252 | 0 | break; |
1253 | 0 | case Z21_LAN_RMBUS_PROGRAMMODULE: |
1254 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_rmbus_address, |
1255 | 0 | tvb, offset, 1, ENC_NA, &temp_uint); |
1256 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Address=%d", temp_uint); |
1257 | 0 | proto_item_append_text(z21_tree, ", Address: %d", temp_uint); |
1258 | 0 | offset += 1; |
1259 | 0 | break; |
1260 | 0 | case Z21_LAN_RAILCOM_DATACHANGED: |
1261 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_loco_address, |
1262 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN, &temp_uint); |
1263 | 0 | offset += 2; |
1264 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d", temp_uint); |
1265 | 0 | proto_item_append_text(z21_tree, ", Loco: %d", temp_uint); |
1266 | 0 | proto_tree_add_item(z21_tree, hf_z21_railcom_receive_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
1267 | 0 | offset += 4; |
1268 | 0 | proto_tree_add_item(z21_tree, hf_z21_railcom_error_counter, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1269 | 0 | offset += 2; |
1270 | 0 | proto_tree_add_item(z21_tree, hf_z21_railcom_reserved1, tvb, offset, 1, ENC_NA); |
1271 | 0 | offset += 1; |
1272 | 0 | proto_tree_add_item(z21_tree, hf_z21_railcom_options, tvb, offset, 1, ENC_NA); |
1273 | 0 | offset += 1; |
1274 | 0 | proto_tree_add_item(z21_tree, hf_z21_railcom_speed, tvb, offset, 1, ENC_NA); |
1275 | 0 | offset += 1; |
1276 | 0 | proto_tree_add_item(z21_tree, hf_z21_railcom_qos, tvb, offset, 1, ENC_NA); |
1277 | 0 | offset += 1; |
1278 | 0 | proto_tree_add_item(z21_tree, hf_z21_railcom_reserved2, tvb, offset, 1, ENC_NA); |
1279 | 0 | offset += 1; |
1280 | 0 | break; |
1281 | 0 | case Z21_LAN_RAILCOM_GETDATA: |
1282 | 0 | proto_tree_add_item(z21_tree, hf_z21_railcom_type, tvb, offset, 1, ENC_NA); |
1283 | 0 | offset += 1; |
1284 | 0 | proto_tree_add_item(z21_tree, hf_z21_loco_address, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1285 | 0 | offset += 2; |
1286 | 0 | break; |
1287 | 0 | case Z21_LAN_LOCONET_FROM_LAN: |
1288 | 0 | case Z21_LAN_LOCONET_Z21_RX: |
1289 | 0 | case Z21_LAN_LOCONET_Z21_TX: |
1290 | 0 | proto_tree_add_item(z21_tree, hf_z21_loconet_message, |
1291 | 0 | tvb, offset, datalen-4, ENC_NA); |
1292 | 0 | offset += datalen-4; |
1293 | 0 | break; |
1294 | 0 | case Z21_LAN_LOCONET_DISPATCH_ADDR: |
1295 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_loco_address, |
1296 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN, &temp_uint); |
1297 | 0 | offset += 2; |
1298 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d", temp_uint); |
1299 | 0 | proto_item_append_text(z21_tree, ", Loco: %d", temp_uint); |
1300 | 0 | if (datalen > 6) { |
1301 | | /* Response from Z21 */ |
1302 | 0 | proto_tree_add_item(z21_tree, hf_z21_loconet_result, tvb, offset, 1, ENC_NA); |
1303 | 0 | offset += 1; |
1304 | 0 | } |
1305 | 0 | break; |
1306 | 0 | case Z21_LAN_LOCONET_DETECTOR: |
1307 | 0 | proto_tree_add_item(z21_tree, hf_z21_loconet_type, tvb, offset, 1, ENC_NA); |
1308 | 0 | offset += 1; |
1309 | 0 | if (datalen == 7) { |
1310 | | /* This is request */ |
1311 | 0 | proto_tree_add_item(z21_tree, hf_z21_loconet_report_address, |
1312 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1313 | 0 | offset += 2; |
1314 | 0 | } |
1315 | 0 | else { |
1316 | | /* This is reply */ |
1317 | 0 | proto_tree_add_item(z21_tree, hf_z21_loconet_feedback_address, |
1318 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1319 | 0 | offset += 2; |
1320 | 0 | proto_tree_add_item(z21_tree, hf_z21_loconet_info, |
1321 | 0 | tvb, offset, datalen-7, ENC_NA); |
1322 | 0 | offset += datalen-7; |
1323 | 0 | } |
1324 | 0 | break; |
1325 | 0 | case Z21_LAN_CAN_DETECTOR: |
1326 | 0 | if (datalen == 7) { |
1327 | | /* This is request */ |
1328 | 0 | proto_tree_add_item(z21_tree, hf_z21_can_type, tvb, offset, 1, ENC_NA); |
1329 | 0 | offset += 1; |
1330 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_can_network_id, |
1331 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN, &temp_uint); |
1332 | 0 | offset += 2; |
1333 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", NetworkID=%d", temp_uint); |
1334 | 0 | proto_item_append_text(z21_tree, ", NetworkID: %d", temp_uint); |
1335 | 0 | } |
1336 | 0 | else { |
1337 | | /* This is reply */ |
1338 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_can_network_id, |
1339 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN, &temp_uint); |
1340 | 0 | offset += 2; |
1341 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", NetworkID=%d", temp_uint); |
1342 | 0 | proto_item_append_text(z21_tree, ", NetworkID: %d", temp_uint); |
1343 | 0 | proto_tree_add_item(z21_tree, hf_z21_can_module_address, |
1344 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1345 | 0 | offset += 2; |
1346 | 0 | proto_tree_add_item(z21_tree, hf_z21_can_port, tvb, offset, 1, ENC_NA); |
1347 | 0 | offset += 1; |
1348 | 0 | proto_tree_add_item(z21_tree, hf_z21_can_type, tvb, offset, 1, ENC_NA); |
1349 | 0 | offset += 1; |
1350 | 0 | proto_tree_add_item(z21_tree, hf_z21_can_value1, |
1351 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1352 | 0 | offset += 2; |
1353 | 0 | proto_tree_add_item(z21_tree, hf_z21_can_value2, |
1354 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1355 | 0 | offset += 2; |
1356 | 0 | } |
1357 | 0 | break; |
1358 | 0 | case Z21_LAN_CAN_DEVICE_GET_DESCRIPTION: |
1359 | 0 | case Z21_LAN_CAN_DEVICE_SET_DESCRIPTION: |
1360 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_can_network_id, |
1361 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN, &temp_uint); |
1362 | 0 | offset += 2; |
1363 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", NetworkID=%d", temp_uint); |
1364 | 0 | proto_item_append_text(z21_tree, ", NetworkID: %d", temp_uint); |
1365 | 0 | if (datalen > 6) { |
1366 | 0 | proto_tree_add_item(z21_tree, hf_z21_can_booster_name, |
1367 | 0 | tvb, offset, 16, ENC_ISO_8859_1); |
1368 | 0 | offset += 16; |
1369 | 0 | } |
1370 | 0 | break; |
1371 | 0 | case Z21_LAN_CAN_BOOSTER_SYSTEMSTATE_CHGD: |
1372 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_can_network_id, |
1373 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN, &temp_uint); |
1374 | 0 | offset += 2; |
1375 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", NetworkID=%d", temp_uint); |
1376 | 0 | proto_item_append_text(z21_tree, ", NetworkID: %d", temp_uint); |
1377 | 0 | proto_tree_add_item(z21_tree, hf_z21_can_booster_output_port, |
1378 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1379 | 0 | offset += 2; |
1380 | 0 | proto_tree_add_bitmask(z21_tree, tvb, offset, |
1381 | 0 | hf_z21_can_booster_state, ett_z21, booster_state_bits, ENC_LITTLE_ENDIAN); |
1382 | 0 | offset += 2; |
1383 | 0 | temp_uint = tvb_get_int16(tvb, offset, ENC_LITTLE_ENDIAN); |
1384 | 0 | proto_tree_add_uint_format_value(z21_tree, hf_z21_can_booster_vcc, |
1385 | 0 | tvb, offset, 2, temp_uint, "%d mV", temp_uint); |
1386 | 0 | offset += 2; |
1387 | 0 | temp_uint = tvb_get_int16(tvb, offset, ENC_LITTLE_ENDIAN); |
1388 | 0 | proto_tree_add_uint_format_value(z21_tree, hf_z21_can_booster_current, |
1389 | 0 | tvb, offset, 2, temp_uint, "%d mA", temp_uint); |
1390 | 0 | offset += 2; |
1391 | 0 | break; |
1392 | 0 | case Z21_LAN_CAN_BOOSTER_SET_TRACKPOWER: |
1393 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_can_network_id, |
1394 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN, &temp_uint); |
1395 | 0 | offset += 2; |
1396 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", NetworkID=%d", temp_uint); |
1397 | 0 | proto_item_append_text(z21_tree, ", NetworkID: %d", temp_uint); |
1398 | 0 | proto_tree_add_item(z21_tree, hf_z21_can_booster_power, tvb, offset, 1, ENC_NA); |
1399 | 0 | offset += 1; |
1400 | 0 | break; |
1401 | 0 | case Z21_LAN_ZLINK_GET_HWINFO: |
1402 | 0 | proto_tree_add_item(z21_tree, hf_z21_zlink_message_type, tvb, offset, 1, ENC_NA); |
1403 | 0 | offset += 1; |
1404 | 0 | if (datalen > 5) { |
1405 | 0 | proto_tree_add_item(z21_tree, hf_z21_zlink_hwid, |
1406 | 0 | tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1407 | 0 | offset += 2; |
1408 | 0 | proto_tree_add_item(z21_tree, hf_z21_zlink_fw_major, tvb, offset, 1, ENC_NA); |
1409 | 0 | offset += 1; |
1410 | 0 | proto_tree_add_item(z21_tree, hf_z21_zlink_fw_minor, tvb, offset, 1, ENC_NA); |
1411 | 0 | offset += 1; |
1412 | 0 | proto_tree_add_item(z21_tree, hf_z21_zlink_fw_build, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1413 | 0 | offset += 2; |
1414 | 0 | proto_tree_add_item(z21_tree, hf_z21_zlink_mac, tvb, offset, 18, ENC_ASCII); |
1415 | 0 | offset += 18; |
1416 | 0 | proto_tree_add_item(z21_tree, hf_z21_zlink_name, tvb, offset, 33, ENC_ISO_8859_1); |
1417 | 0 | offset += 18; |
1418 | 0 | proto_tree_add_item(z21_tree, hf_z21_zlink_reserved, tvb, offset, 1, ENC_NA); |
1419 | 0 | offset += 1; |
1420 | 0 | } |
1421 | 0 | break; |
1422 | 0 | case Z21_LAN_BOOSTER_GET_DESCRIPTION: |
1423 | 0 | case Z21_LAN_BOOSTER_SET_DESCRIPTION: |
1424 | 0 | if (datalen > 4) { |
1425 | | /* SET_DESCRIPTION or reply to GET_DESCRIPTION */ |
1426 | 0 | uint8_t *buf = tvb_get_stringz_enc(pinfo->pool, tvb, offset, NULL, ENC_ISO_8859_1); |
1427 | 0 | if (buf[0] == 0xff) { |
1428 | | /* Interpreted as an empty name */ |
1429 | 0 | proto_tree_add_string(z21_tree, hf_z21_booster_name, tvb, offset, 32, ""); |
1430 | 0 | } |
1431 | 0 | else { |
1432 | 0 | proto_tree_add_string(z21_tree, hf_z21_booster_name, tvb, offset, 32, (char*)buf); |
1433 | 0 | } |
1434 | 0 | offset += 32; |
1435 | 0 | } |
1436 | 0 | break; |
1437 | 0 | case Z21_LAN_BOOSTER_SYSTEMSTATE_GETDATA: |
1438 | 0 | case Z21_LAN_DECODER_SYSTEMSTATE_GETDATA: |
1439 | 0 | break; |
1440 | 0 | case Z21_LAN_DECODER_GET_DESCRIPTION: |
1441 | 0 | case Z21_LAN_DECODER_SET_DESCRIPTION: |
1442 | 0 | if (datalen > 4) { |
1443 | | /* SET_DESCRIPTION or reply to GET_DESCRIPTION */ |
1444 | 0 | uint8_t *buf = tvb_get_stringz_enc(pinfo->pool, tvb, offset, NULL, ENC_ISO_8859_1); |
1445 | 0 | if (buf[0] == 0xff) { |
1446 | | /* Interpreted as an empty name */ |
1447 | 0 | proto_tree_add_string(z21_tree, hf_z21_decoder_name, tvb, offset, 32, ""); |
1448 | 0 | } |
1449 | 0 | else { |
1450 | 0 | proto_tree_add_string(z21_tree, hf_z21_decoder_name, tvb, offset, 32, (char*)buf); |
1451 | 0 | } |
1452 | 0 | offset += 32; |
1453 | 0 | } |
1454 | 0 | break; |
1455 | 0 | case Z21_LAN_BOOSTER_SET_POWER: |
1456 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_booster_port, |
1457 | 0 | tvb, offset, 1, ENC_NA, &temp_uint); |
1458 | 0 | offset += 1; |
1459 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Port=%d", temp_uint); |
1460 | 0 | proto_item_append_text(z21_tree, ", Port: %d", temp_uint); |
1461 | 0 | proto_tree_add_item_ret_uint(z21_tree, hf_z21_booster_port_state, |
1462 | 0 | tvb, offset, 1, ENC_NA, &temp_uint); |
1463 | 0 | offset += 1; |
1464 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", State=%d", temp_uint); |
1465 | 0 | proto_item_append_text(z21_tree, ", State: %d", temp_uint); |
1466 | 0 | break; |
1467 | 0 | case Z21_LAN_BOOSTER_SYSTEMSTATE_DATACHANGED: |
1468 | | /* To be expanded later... */ |
1469 | 0 | proto_tree_add_item(z21_tree, hf_z21_booster_state_data, |
1470 | 0 | tvb, offset, 24, ENC_NA); |
1471 | 0 | offset += 24; |
1472 | 0 | break; |
1473 | 0 | case Z21_LAN_DECODER_SYSTEMSTATE_DATACHANGED: |
1474 | | /* To be expanded later... */ |
1475 | | /* Data is variable length */ |
1476 | 0 | proto_tree_add_item(z21_tree, hf_z21_decoder_state_data, |
1477 | 0 | tvb, offset, datalen-4, ENC_NA); |
1478 | 0 | offset += datalen-4; |
1479 | 0 | break; |
1480 | 0 | case Z21_LAN_GET_LOCOMODE: |
1481 | 0 | case Z21_LAN_SET_LOCOMODE: |
1482 | 0 | address_bytes = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN); |
1483 | 0 | addr = address_bytes & 0x3FFF; |
1484 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_address, tvb, offset, 2, addr); |
1485 | 0 | offset += 2; |
1486 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Loco=%d", addr); |
1487 | 0 | if (datalen > 6) { |
1488 | 0 | unsigned mode = tvb_get_uint8(tvb, offset); |
1489 | 0 | proto_tree_add_uint(z21_tree, hf_z21_loco_mode, tvb, offset, 1, mode); |
1490 | 0 | offset += 1; |
1491 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Mode: %d", mode); |
1492 | 0 | } |
1493 | 0 | break; |
1494 | 0 | case Z21_LAN_GET_BROADCASTFLAGS: |
1495 | 0 | case Z21_LAN_SET_BROADCASTFLAGS: |
1496 | 0 | if (datalen == 8) { |
1497 | 0 | proto_tree_add_bitmask_with_flags(z21_tree, tvb, offset, hf_z21_broadcast_flags, |
1498 | 0 | ett_z21, broadcast_flags_bits, ENC_LITTLE_ENDIAN, BMT_NO_APPEND); |
1499 | 0 | offset += 4; |
1500 | 0 | } |
1501 | 0 | break; |
1502 | 0 | case Z21_LAN_GET_HWINFO: |
1503 | 0 | if (datalen == 12) { |
1504 | 0 | unsigned hwtype = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN); |
1505 | 0 | proto_tree_add_uint(z21_tree, hf_z21_hw_type, tvb, offset, 1, hwtype); |
1506 | 0 | offset += 4; |
1507 | 0 | version = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN); |
1508 | 0 | buffer = wmem_strdup_printf(pinfo->pool, "%x.%02x", |
1509 | 0 | version >> 8, version & 0xff); |
1510 | 0 | proto_tree_add_string(z21_tree, hf_z21_firmware_version, |
1511 | 0 | tvb, offset, 2, buffer); |
1512 | 0 | offset += 4; |
1513 | 0 | } |
1514 | 0 | break; |
1515 | 0 | } |
1516 | 0 | if (offset < datalen) { |
1517 | | /* Just dump all the rest, if any */ |
1518 | 0 | proto_tree_add_item(z21_tree, hf_z21_data, tvb, offset, datalen-offset, ENC_NA); |
1519 | 0 | offset += datalen-offset; |
1520 | 0 | } |
1521 | 0 | } |
1522 | 0 | return offset; |
1523 | 0 | } |
1524 | | |
1525 | | static unsigned |
1526 | | get_z21_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) |
1527 | 6 | { |
1528 | 6 | return tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN); |
1529 | 6 | } |
1530 | | |
1531 | | static bool |
1532 | | check_z21_header(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) |
1533 | 7 | { |
1534 | 7 | int remaining_length = tvb_reported_length_remaining(tvb, offset); |
1535 | 7 | if (remaining_length < Z21_MIN_LENGTH) { |
1536 | 1 | return false; |
1537 | 1 | } |
1538 | 6 | int pdu_len = get_z21_pdu_len(pinfo, tvb, offset, data); |
1539 | 6 | if (pdu_len < Z21_MIN_LENGTH || pdu_len > remaining_length) { |
1540 | 6 | return false; |
1541 | 6 | } |
1542 | 0 | uint16_t command = tvb_get_uint16(tvb, offset + 2, ENC_BIG_ENDIAN); |
1543 | 0 | if (!try_val_to_str(command, z21_command_vals)) { |
1544 | 0 | return false; |
1545 | 0 | } |
1546 | 0 | return true; |
1547 | 0 | } |
1548 | | |
1549 | | static int |
1550 | | dissect_z21(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
1551 | 7 | { |
1552 | 7 | return udp_dissect_pdus(tvb, pinfo, tree, Z21_MIN_LENGTH, |
1553 | 7 | check_z21_header, get_z21_pdu_len, dissect_z21_pdu, data); |
1554 | 7 | } |
1555 | | |
1556 | | /* Register the protocol with Wireshark. |
1557 | | * |
1558 | | * This format is required because a script is used to build the C function that |
1559 | | * calls all the protocol registration. |
1560 | | */ |
1561 | | void |
1562 | | proto_register_z21(void) |
1563 | 14 | { |
1564 | 14 | expert_module_t *expert_z21; |
1565 | | |
1566 | 14 | static hf_register_info hf[] = { |
1567 | 14 | { &hf_z21_datalen, |
1568 | 14 | { "Data length", "z21.datalen", |
1569 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1570 | 14 | NULL, HFILL } |
1571 | 14 | }, |
1572 | 14 | { &hf_z21_command, |
1573 | 14 | { "Command", "z21.command", |
1574 | 14 | FT_UINT32, BASE_HEX|BASE_NO_DISPLAY_VALUE, VALS(z21_command_vals), 0x0, |
1575 | 14 | NULL, HFILL } |
1576 | 14 | }, |
1577 | 14 | { &hf_z21_x_bus, |
1578 | 14 | { "X-BUS", "z21.xbus", |
1579 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0x0, |
1580 | 14 | NULL, HFILL } |
1581 | 14 | }, |
1582 | 14 | { &hf_z21_serial_number, |
1583 | 14 | { "Serial number", "z21.serialnumber", |
1584 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1585 | 14 | NULL, HFILL } |
1586 | 14 | }, |
1587 | 14 | { &hf_z21_checksum, |
1588 | 14 | { "Checksum", "z21.checksum", |
1589 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
1590 | 14 | NULL, HFILL } |
1591 | 14 | }, |
1592 | 14 | { &hf_z21_main_current, |
1593 | 14 | { "Main track current", "z21.maincurrent", |
1594 | 14 | FT_INT16, BASE_DEC, NULL, 0x0, |
1595 | 14 | NULL, HFILL } |
1596 | 14 | }, |
1597 | 14 | { &hf_z21_prog_current, |
1598 | 14 | { "Programming track current", "z21.progcurrent", |
1599 | 14 | FT_INT16, BASE_DEC, NULL, 0x0, |
1600 | 14 | NULL, HFILL } |
1601 | 14 | }, |
1602 | 14 | { &hf_z21_filtered_main_current, |
1603 | 14 | { "Filtered main track current", "z21.filteredmaincurrent", |
1604 | 14 | FT_INT16, BASE_DEC, NULL, 0x0, |
1605 | 14 | NULL, HFILL } |
1606 | 14 | }, |
1607 | 14 | { &hf_z21_temperature, |
1608 | 14 | { "Command station temperature", "z21.temperature", |
1609 | 14 | FT_INT16, BASE_DEC, NULL, 0x0, |
1610 | 14 | NULL, HFILL } |
1611 | 14 | }, |
1612 | 14 | { &hf_z21_supply_voltage, |
1613 | 14 | { "Supply voltage", "z21.supplyvoltage", |
1614 | 14 | FT_FLOAT, BASE_DEC, NULL, 0x0, |
1615 | 14 | NULL, HFILL } |
1616 | 14 | }, |
1617 | 14 | { &hf_z21_track_voltage, |
1618 | 14 | { "Track voltage", "z21.trackvoltage", |
1619 | 14 | FT_FLOAT, BASE_DEC, NULL, 0x0, |
1620 | 14 | NULL, HFILL } |
1621 | 14 | }, |
1622 | 14 | { &hf_z21_broadcast_flags, |
1623 | 14 | { "Broadcast flags", "z21.broadcastflags", |
1624 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1625 | 14 | NULL, HFILL } |
1626 | 14 | }, |
1627 | 14 | { &hf_z21_central_state, |
1628 | 14 | { "Central state, first byte", "z21.centralstate1", |
1629 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
1630 | 14 | NULL, HFILL } |
1631 | 14 | }, |
1632 | 14 | { &hf_z21_central_state_ex, |
1633 | 14 | { "Central state, second byte", "z21.centralstate2", |
1634 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
1635 | 14 | NULL, HFILL } |
1636 | 14 | }, |
1637 | 14 | { &hf_z21_systemstate_reserved, |
1638 | 14 | { "Reserved", "z21.systemstatereserved", |
1639 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
1640 | 14 | NULL, HFILL } |
1641 | 14 | }, |
1642 | 14 | { &hf_z21_capabilities, |
1643 | 14 | { "Capabilities", "z21.capabilities", |
1644 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
1645 | 14 | NULL, HFILL } |
1646 | 14 | }, |
1647 | 14 | { &hf_z21_status, |
1648 | 14 | { "Status", "z21.status", |
1649 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
1650 | 14 | NULL, HFILL } |
1651 | 14 | }, |
1652 | 14 | { &hf_z21_broadcast_flags_driving_switching, |
1653 | 14 | { "Broadcasts messages concerning driving and switching", "z21.broadcastflags.driving_switching", |
1654 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x00000001, |
1655 | 14 | NULL, HFILL } |
1656 | 14 | }, |
1657 | 14 | { &hf_z21_broadcast_flags_rmbus, |
1658 | 14 | { "Changes of the feedback devices on the R-Bus", "z21.broadcastflags.rmbus", |
1659 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x00000002, |
1660 | 14 | NULL, HFILL } |
1661 | 14 | }, |
1662 | 14 | { &hf_z21_broadcast_flags_railcom_subscribed, |
1663 | 14 | { "Changes of RailCom data of subscribed locomotives", "z21.broadcastflags.railcom_subscribed", |
1664 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x00000004, |
1665 | 14 | NULL, HFILL } |
1666 | 14 | }, |
1667 | 14 | { &hf_z21_broadcast_flags_system_status, |
1668 | 14 | { "Changes of the Z21 system status", "z21.broadcastflags.system_status", |
1669 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x00000100, |
1670 | 14 | NULL, HFILL } |
1671 | 14 | }, |
1672 | 14 | { &hf_z21_broadcast_flags_driving_switching_ex, |
1673 | 14 | { "Extends flag 0x00000001, LAN_X_LOCO_INFO is sent for all modified locomotives", "z21.broadcastflags.driving_switching_ex", |
1674 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x00010000, |
1675 | 14 | NULL, HFILL } |
1676 | 14 | }, |
1677 | 14 | { &hf_z21_broadcast_flags_loconet, |
1678 | 14 | { "Forward messages from LocoNet without locos and switches", "z21.broadcastflags.loconet", |
1679 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x01000000, |
1680 | 14 | NULL, HFILL } |
1681 | 14 | }, |
1682 | 14 | { &hf_z21_broadcast_flags_loconet_driving, |
1683 | 14 | { "Forward locomotive-specific LocoNet", "z21.broadcastflags.loconet_driving", |
1684 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x02000000, |
1685 | 14 | NULL, HFILL } |
1686 | 14 | }, |
1687 | 14 | { &hf_z21_broadcast_flags_loconet_switching, |
1688 | 14 | { "Forward switch-specific LocoNet", "z21.broadcastflags.loconet_switching", |
1689 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x04000000, |
1690 | 14 | NULL, HFILL } |
1691 | 14 | }, |
1692 | 14 | { &hf_z21_broadcast_flags_loconet_detector, |
1693 | 14 | { "Changes of LocoNet track occupancy detectors", "z21.broadcastflags.emergencystop", |
1694 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x08000000, |
1695 | 14 | NULL, HFILL } |
1696 | 14 | }, |
1697 | 14 | { &hf_z21_broadcast_flags_railcom, |
1698 | 14 | { "Changes of RailCom data", "z21.broadcastflags.railcom", |
1699 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x00040000, |
1700 | 14 | NULL, HFILL } |
1701 | 14 | }, |
1702 | 14 | { &hf_z21_broadcast_flags_can_detector, |
1703 | 14 | { "Changes of CAN-Bus track occupancy detectors", "z21.broadcastflags.can_detector", |
1704 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x00080000, |
1705 | 14 | NULL, HFILL } |
1706 | 14 | }, |
1707 | 14 | { &hf_z21_broadcast_flags_can_booster, |
1708 | 14 | { "Forward CAN-Bus booster status messages", "z21.broadcastflags.can_booster", |
1709 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x00020000, |
1710 | 14 | NULL, HFILL } |
1711 | 14 | }, |
1712 | 14 | { &hf_z21_broadcast_flags_fast_clock, |
1713 | 14 | { "Fast clock time messages", "z21.broadcastflags.fast_clock", |
1714 | 14 | FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x00000010, |
1715 | 14 | NULL, HFILL } |
1716 | 14 | }, |
1717 | 14 | { &hf_z21_state_emergency_stop, |
1718 | 14 | { "Emergency stop", "z21.state.emergencystop", |
1719 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, |
1720 | 14 | NULL, HFILL } |
1721 | 14 | }, |
1722 | 14 | { &hf_z21_state_track_voltage_off, |
1723 | 14 | { "Track voltage off", "z21.state.trackvoltageoff", |
1724 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, |
1725 | 14 | NULL, HFILL } |
1726 | 14 | }, |
1727 | 14 | { &hf_z21_state_short_circuit, |
1728 | 14 | { "Short circuit", "z21.state.shortcircuit", |
1729 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04, |
1730 | 14 | NULL, HFILL } |
1731 | 14 | }, |
1732 | 14 | { &hf_z21_state_programming_mode, |
1733 | 14 | { "Programming mode", "z21.state.programmingmode", |
1734 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20, |
1735 | 14 | NULL, HFILL } |
1736 | 14 | }, |
1737 | 14 | { &hf_z21_state_high_temperature, |
1738 | 14 | { "High temperature", "z21.state.hightemperature", |
1739 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, |
1740 | 14 | NULL, HFILL } |
1741 | 14 | }, |
1742 | 14 | { &hf_z21_state_power_lost, |
1743 | 14 | { "Power lost", "z21.state.powerlost", |
1744 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, |
1745 | 14 | NULL, HFILL } |
1746 | 14 | }, |
1747 | 14 | { &hf_z21_state_short_circuit_external, |
1748 | 14 | { "External short circuit", "z21.state.externalshortcircuit", |
1749 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04, |
1750 | 14 | NULL, HFILL } |
1751 | 14 | }, |
1752 | 14 | { &hf_z21_state_short_circuit_internal, |
1753 | 14 | { "Internal short circuit", "z21.state.internalshortcircuit", |
1754 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08, |
1755 | 14 | NULL, HFILL } |
1756 | 14 | }, |
1757 | 14 | { &hf_z21_state_rcn_213, |
1758 | 14 | { "RCN-213 turnout addressing", "z21.state.rcn213addressing", |
1759 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20, |
1760 | 14 | NULL, HFILL } |
1761 | 14 | }, |
1762 | 14 | { &hf_z21_capability_dcc, |
1763 | 14 | { "DCC capability", "z21.capability.dcc", |
1764 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, |
1765 | 14 | NULL, HFILL } |
1766 | 14 | }, |
1767 | 14 | { &hf_z21_capability_mm, |
1768 | 14 | { "MM capability", "z21.capability.mm", |
1769 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, |
1770 | 14 | NULL, HFILL } |
1771 | 14 | }, |
1772 | 14 | { &hf_z21_capability_reserved, |
1773 | 14 | { "Reserved capability", "z21.capability.reserved", |
1774 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04, |
1775 | 14 | NULL, HFILL } |
1776 | 14 | }, |
1777 | 14 | { &hf_z21_capability_railcom, |
1778 | 14 | { "RailCom capability", "z21.capability.railcom", |
1779 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08, |
1780 | 14 | NULL, HFILL } |
1781 | 14 | }, |
1782 | 14 | { &hf_z21_capability_loco_cmds, |
1783 | 14 | { "Accepts LAN commands for locomotive decoders", "z21.capability.lococmds", |
1784 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10, |
1785 | 14 | NULL, HFILL } |
1786 | 14 | }, |
1787 | 14 | { &hf_z21_capability_accessory_cmds, |
1788 | 14 | { "Accepts LAN commands for accessory decoders", "z21.capability.accessorycmds", |
1789 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20, |
1790 | 14 | NULL, HFILL } |
1791 | 14 | }, |
1792 | 14 | { &hf_z21_capability_detector_cmds, |
1793 | 14 | { "Accepts LAN commands for detectors", "z21.capability.detectorcmds", |
1794 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40, |
1795 | 14 | NULL, HFILL } |
1796 | 14 | }, |
1797 | 14 | { &hf_z21_capability_needs_unlock_code, |
1798 | 14 | { "Needs unlock code", "z21.capability.needsunlockcode", |
1799 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80, |
1800 | 14 | NULL, HFILL } |
1801 | 14 | }, |
1802 | 14 | { &hf_z21_loco_mode, |
1803 | 14 | { "Locomotive mode", "z21.locomode", |
1804 | 14 | FT_UINT8, BASE_DEC, VALS(z21_loco_mode_vals), 0x0, |
1805 | 14 | NULL, HFILL } |
1806 | 14 | }, |
1807 | 14 | { &hf_z21_loco_address, |
1808 | 14 | { "Locomotive address", "z21.locoaddress", |
1809 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1810 | 14 | NULL, HFILL } |
1811 | 14 | }, |
1812 | 14 | { &hf_z21_loco_direction_and_speed, |
1813 | 14 | { "Locomotive direction and speed", "z21.locodirectionandspeed", |
1814 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
1815 | 14 | NULL, HFILL } |
1816 | 14 | }, |
1817 | 14 | { &hf_z21_loco_direction, |
1818 | 14 | { "Locomotive direction", "z21.locodirection", |
1819 | 14 | FT_BOOLEAN, 8, TFS(&tfs_forward_reverse), 0x80, |
1820 | 14 | NULL, HFILL } |
1821 | 14 | }, |
1822 | 14 | { &hf_z21_loco_speed, |
1823 | 14 | { "Locomotive speed", "z21.locospeed", |
1824 | 14 | FT_UINT8, BASE_HEX, NULL, 0x7F, |
1825 | 14 | NULL, HFILL } |
1826 | 14 | }, |
1827 | 14 | { &hf_z21_loco_info_mm, |
1828 | 14 | { "Locomotive is MM (MƤrklin-Motorola)", "z21.locomm", |
1829 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10, |
1830 | 14 | NULL, HFILL } |
1831 | 14 | }, |
1832 | 14 | { &hf_z21_loco_info_busy, |
1833 | 14 | { "Locomotive is busy", "z21.locoinfobusy", |
1834 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08, |
1835 | 14 | "Locomotive is controlled by another X-BUS handset controller", HFILL } |
1836 | 14 | }, |
1837 | 14 | { &hf_z21_loco_info_speed_steps, |
1838 | 14 | { "Locomotive speed steps", "z21.locoinfospeedsteps", |
1839 | 14 | FT_UINT8, BASE_DEC, VALS(z21_loco_info_speed_steps_vals), 0x07, |
1840 | 14 | NULL, HFILL } |
1841 | 14 | }, |
1842 | 14 | { &hf_z21_loco_info_direction, |
1843 | 14 | { "Locomotive direction", "z21.locoinfodirection", |
1844 | 14 | FT_BOOLEAN, 8, TFS(&tfs_forward_reverse), 0x80, |
1845 | 14 | NULL, HFILL } |
1846 | 14 | }, |
1847 | 14 | { &hf_z21_loco_info_speed, |
1848 | 14 | { "Locomotive speed", "z21.locoinfospeed", |
1849 | 14 | FT_UINT8, BASE_HEX, NULL, 0x7f, |
1850 | 14 | NULL, HFILL } |
1851 | 14 | }, |
1852 | 14 | { &hf_z21_loco_info_double_traction, |
1853 | 14 | { "Double traction", "z21.locoinfodoubletraction", |
1854 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40, |
1855 | 14 | NULL, HFILL } |
1856 | 14 | }, |
1857 | 14 | { &hf_z21_loco_info_smartsearch, |
1858 | 14 | { "Smartsearch", "z21.locoinfosmartsearch", |
1859 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20, |
1860 | 14 | NULL, HFILL } |
1861 | 14 | }, |
1862 | 14 | { &hf_z21_loco_info_f0, |
1863 | 14 | { "Function F0 (lights)", "z21.locoinfof0", |
1864 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10, |
1865 | 14 | NULL, HFILL } |
1866 | 14 | }, |
1867 | 14 | { &hf_z21_loco_info_f4, |
1868 | 14 | { "Function F4", "z21.locoinfof4", |
1869 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08, |
1870 | 14 | NULL, HFILL } |
1871 | 14 | }, |
1872 | 14 | { &hf_z21_loco_info_f3, |
1873 | 14 | { "Function F3", "z21.locoinfof3", |
1874 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04, |
1875 | 14 | NULL, HFILL } |
1876 | 14 | }, |
1877 | 14 | { &hf_z21_loco_info_f2, |
1878 | 14 | { "Function F2", "z21.locoinfof2", |
1879 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, |
1880 | 14 | NULL, HFILL } |
1881 | 14 | }, |
1882 | 14 | { &hf_z21_loco_info_f1, |
1883 | 14 | { "Function F1", "z21.locoinfof1", |
1884 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, |
1885 | 14 | NULL, HFILL } |
1886 | 14 | }, |
1887 | 14 | { &hf_z21_loco_info_f12, |
1888 | 14 | { "Function F12", "z21.locoinfof12", |
1889 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80, |
1890 | 14 | NULL, HFILL } |
1891 | 14 | }, |
1892 | 14 | { &hf_z21_loco_info_f11, |
1893 | 14 | { "Function F11", "z21.locoinfof11", |
1894 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40, |
1895 | 14 | NULL, HFILL } |
1896 | 14 | }, |
1897 | 14 | { &hf_z21_loco_info_f10, |
1898 | 14 | { "Function F10", "z21.locoinfof10", |
1899 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20, |
1900 | 14 | NULL, HFILL } |
1901 | 14 | }, |
1902 | 14 | { &hf_z21_loco_info_f9, |
1903 | 14 | { "Function F9", "z21.locoinfof9", |
1904 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10, |
1905 | 14 | NULL, HFILL } |
1906 | 14 | }, |
1907 | 14 | { &hf_z21_loco_info_f8, |
1908 | 14 | { "Function F8", "z21.locoinfof8", |
1909 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08, |
1910 | 14 | NULL, HFILL } |
1911 | 14 | }, |
1912 | 14 | { &hf_z21_loco_info_f7, |
1913 | 14 | { "Function F7", "z21.locoinfof7", |
1914 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04, |
1915 | 14 | NULL, HFILL } |
1916 | 14 | }, |
1917 | 14 | { &hf_z21_loco_info_f6, |
1918 | 14 | { "Function F6", "z21.locoinfof6", |
1919 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, |
1920 | 14 | NULL, HFILL } |
1921 | 14 | }, |
1922 | 14 | { &hf_z21_loco_info_f5, |
1923 | 14 | { "Function F5", "z21.locoinfof5", |
1924 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, |
1925 | 14 | NULL, HFILL } |
1926 | 14 | }, |
1927 | 14 | { &hf_z21_loco_info_f20, |
1928 | 14 | { "Function F20", "z21.locoinfof20", |
1929 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80, |
1930 | 14 | NULL, HFILL } |
1931 | 14 | }, |
1932 | 14 | { &hf_z21_loco_info_f19, |
1933 | 14 | { "Function F19", "z21.locoinfof19", |
1934 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40, |
1935 | 14 | NULL, HFILL } |
1936 | 14 | }, |
1937 | 14 | { &hf_z21_loco_info_f18, |
1938 | 14 | { "Function F18", "z21.locoinfof18", |
1939 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20, |
1940 | 14 | NULL, HFILL } |
1941 | 14 | }, |
1942 | 14 | { &hf_z21_loco_info_f17, |
1943 | 14 | { "Function F17", "z21.locoinfof17", |
1944 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10, |
1945 | 14 | NULL, HFILL } |
1946 | 14 | }, |
1947 | 14 | { &hf_z21_loco_info_f16, |
1948 | 14 | { "Function F16", "z21.locoinfof16", |
1949 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08, |
1950 | 14 | NULL, HFILL } |
1951 | 14 | }, |
1952 | 14 | { &hf_z21_loco_info_f15, |
1953 | 14 | { "Function F15", "z21.locoinfof15", |
1954 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04, |
1955 | 14 | NULL, HFILL } |
1956 | 14 | }, |
1957 | 14 | { &hf_z21_loco_info_f14, |
1958 | 14 | { "Function F14", "z21.locoinfof14", |
1959 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, |
1960 | 14 | NULL, HFILL } |
1961 | 14 | }, |
1962 | 14 | { &hf_z21_loco_info_f13, |
1963 | 14 | { "Function F13", "z21.locoinfof13", |
1964 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, |
1965 | 14 | NULL, HFILL } |
1966 | 14 | }, |
1967 | 14 | { &hf_z21_loco_info_f28, |
1968 | 14 | { "Function F28", "z21.locoinfof28", |
1969 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80, |
1970 | 14 | NULL, HFILL } |
1971 | 14 | }, |
1972 | 14 | { &hf_z21_loco_info_f27, |
1973 | 14 | { "Function F27", "z21.locoinfof27", |
1974 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40, |
1975 | 14 | NULL, HFILL } |
1976 | 14 | }, |
1977 | 14 | { &hf_z21_loco_info_f26, |
1978 | 14 | { "Function F26", "z21.locoinfof26", |
1979 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20, |
1980 | 14 | NULL, HFILL } |
1981 | 14 | }, |
1982 | 14 | { &hf_z21_loco_info_f25, |
1983 | 14 | { "Function F25", "z21.locoinfof25", |
1984 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10, |
1985 | 14 | NULL, HFILL } |
1986 | 14 | }, |
1987 | 14 | { &hf_z21_loco_info_f24, |
1988 | 14 | { "Function F24", "z21.locoinfof24", |
1989 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08, |
1990 | 14 | NULL, HFILL } |
1991 | 14 | }, |
1992 | 14 | { &hf_z21_loco_info_f23, |
1993 | 14 | { "Function F23", "z21.locoinfof23", |
1994 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04, |
1995 | 14 | NULL, HFILL } |
1996 | 14 | }, |
1997 | 14 | { &hf_z21_loco_info_f22, |
1998 | 14 | { "Function F22", "z21.locoinfof22", |
1999 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, |
2000 | 14 | NULL, HFILL } |
2001 | 14 | }, |
2002 | 14 | { &hf_z21_loco_info_f21, |
2003 | 14 | { "Function F21", "z21.locoinfof21", |
2004 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, |
2005 | 14 | NULL, HFILL } |
2006 | 14 | }, |
2007 | 14 | { &hf_z21_loco_info_f31, |
2008 | 14 | { "Function F31", "z21.locoinfof31", |
2009 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04, |
2010 | 14 | NULL, HFILL } |
2011 | 14 | }, |
2012 | 14 | { &hf_z21_loco_info_f30, |
2013 | 14 | { "Function F30", "z21.locoinfof30", |
2014 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, |
2015 | 14 | NULL, HFILL } |
2016 | 14 | }, |
2017 | 14 | { &hf_z21_loco_info_f29, |
2018 | 14 | { "Function F29", "z21.locoinfof29", |
2019 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, |
2020 | 14 | NULL, HFILL } |
2021 | 14 | }, |
2022 | 14 | { &hf_z21_loco_info_extensions, |
2023 | 14 | { "Extensions", "z21.locoinfoextensions", |
2024 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
2025 | 14 | NULL, HFILL } |
2026 | 14 | }, |
2027 | 14 | { &hf_z21_speed_steps, |
2028 | 14 | { "Speed steps", "z21.speedsteps", |
2029 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2030 | 14 | NULL, HFILL } |
2031 | 14 | }, |
2032 | 14 | { &hf_z21_hw_type, |
2033 | 14 | { "Hardware type", "z21.hwtype", |
2034 | 14 | FT_UINT32, BASE_HEX, VALS(z21_hw_type_vals), 0x0, |
2035 | 14 | NULL, HFILL } |
2036 | 14 | }, |
2037 | 14 | { &hf_z21_firmware_version, |
2038 | 14 | { "Firmware version", "z21.firmwareversion", |
2039 | 14 | FT_STRING, BASE_NONE, NULL, 0x0, |
2040 | 14 | NULL, HFILL } |
2041 | 14 | }, |
2042 | 14 | { &hf_z21_loco_func_switch_type, |
2043 | 14 | { "Locomotive function switch type", "z21.locofunctionswitchtype", |
2044 | 14 | FT_UINT8, BASE_DEC, VALS(z21_loco_func_vals), 0xc0, |
2045 | 14 | NULL, HFILL } |
2046 | 14 | }, |
2047 | 14 | { &hf_z21_loco_func_index, |
2048 | 14 | { "Locomotive function index", "z21.locofunctionindex", |
2049 | 14 | FT_UINT8, BASE_DEC, NULL, 0x3f, |
2050 | 14 | NULL, HFILL } |
2051 | 14 | }, |
2052 | 14 | { &hf_z21_function_address, |
2053 | 14 | { "Function address", "z21.functionaddress", |
2054 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2055 | 14 | NULL, HFILL } |
2056 | 14 | }, |
2057 | 14 | { &hf_z21_turnout_state, |
2058 | 14 | { "Turnout state", "z21.turnoutstate", |
2059 | 14 | FT_UINT8, BASE_DEC, VALS(z21_turnout_state_vals), 0x03, |
2060 | 14 | NULL, HFILL } |
2061 | 14 | }, |
2062 | 14 | { &hf_z21_turnout_queue_bit, |
2063 | 14 | { "Queue the turnout command", "z21.turnoutqueue", |
2064 | 14 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20, |
2065 | 14 | NULL, HFILL } |
2066 | 14 | }, |
2067 | 14 | { &hf_z21_turnout_activate_bit, |
2068 | 14 | { "Turnout command", "z21.turnoutcommand", |
2069 | 14 | FT_BOOLEAN, 8, TFS(&tfs_turnout_command), 0x08, |
2070 | 14 | NULL, HFILL } |
2071 | 14 | }, |
2072 | 14 | { &hf_z21_turnout_output_bit, |
2073 | 14 | { "Select turnout output", "z21.turnoutoutput", |
2074 | 14 | FT_BOOLEAN, 8, TFS(&tfs_turnout_output), 0x01, |
2075 | 14 | NULL, HFILL } |
2076 | 14 | }, |
2077 | 14 | { &hf_z21_accessory_address, |
2078 | 14 | { "Accessory address", "z21.accessoryaddress", |
2079 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2080 | 14 | NULL, HFILL } |
2081 | 14 | }, |
2082 | 14 | { &hf_z21_accessory_state, |
2083 | 14 | { "Accessory state", "z21.accessorystate", |
2084 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2085 | 14 | NULL, HFILL } |
2086 | 14 | }, |
2087 | 14 | { &hf_z21_accessory_status, |
2088 | 14 | { "Accessory status", "z21.accessorystatus", |
2089 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2090 | 14 | NULL, HFILL } |
2091 | 14 | }, |
2092 | 14 | { &hf_z21_cv_address, |
2093 | 14 | { "CV address", "z21.cvaddress", |
2094 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2095 | 14 | NULL, HFILL } |
2096 | 14 | }, |
2097 | 14 | { &hf_z21_cv_value, |
2098 | 14 | { "CV value", "z21.cvvalue", |
2099 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2100 | 14 | NULL, HFILL } |
2101 | 14 | }, |
2102 | 14 | { &hf_z21_register, |
2103 | 14 | { "Register", "z21.register", |
2104 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2105 | 14 | NULL, HFILL } |
2106 | 14 | }, |
2107 | 14 | { &hf_z21_register_value, |
2108 | 14 | { "Register value", "z21.registervalue", |
2109 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2110 | 14 | NULL, HFILL } |
2111 | 14 | }, |
2112 | 14 | { &hf_z21_pom_operation, |
2113 | 14 | { "POM operation", "z21.pomoperation", |
2114 | 14 | FT_UINT16, BASE_HEX, VALS(z21_pom_operation_vals), 0x0, |
2115 | 14 | NULL, HFILL } |
2116 | 14 | }, |
2117 | 14 | { &hf_z21_cv_bit_position, |
2118 | 14 | { "CV bit position", "z21.cvbitposition", |
2119 | 14 | FT_UINT8, BASE_DEC, NULL, 0x07, |
2120 | 14 | NULL, HFILL } |
2121 | 14 | }, |
2122 | 14 | { &hf_z21_cv_bit_value, |
2123 | 14 | { "CV bit value", "z21.cvbitvalue", |
2124 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x08, |
2125 | 14 | NULL, HFILL } |
2126 | 14 | }, |
2127 | 14 | { &hf_z21_rmbus_group, |
2128 | 14 | { "R-BUS group index", "z21.rbusgroup", |
2129 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2130 | 14 | NULL, HFILL } |
2131 | 14 | }, |
2132 | 14 | { &hf_z21_rmbus_feedbacks, |
2133 | 14 | { "R-BUS feedbacks", "z21.rbusfeedbacks", |
2134 | 14 | FT_BYTES, BASE_NONE|SEP_SPACE, NULL, 0x0, |
2135 | 14 | NULL, HFILL } |
2136 | 14 | }, |
2137 | 14 | { &hf_z21_rmbus_address, |
2138 | 14 | { "R-BUS feedback module address", "z21.rbusaddress", |
2139 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2140 | 14 | NULL, HFILL } |
2141 | 14 | }, |
2142 | 14 | { &hf_z21_railcom_receive_counter, |
2143 | 14 | { "RailCom receive counter", "z21.railcomreceives", |
2144 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
2145 | 14 | NULL, HFILL } |
2146 | 14 | }, |
2147 | 14 | { &hf_z21_railcom_error_counter, |
2148 | 14 | { "RailCom error counter", "z21.railcomerrors", |
2149 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2150 | 14 | NULL, HFILL } |
2151 | 14 | }, |
2152 | 14 | { &hf_z21_railcom_reserved1, |
2153 | 14 | { "RailCom reserved 1", "z21.railcomreserved1", |
2154 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2155 | 14 | NULL, HFILL } |
2156 | 14 | }, |
2157 | 14 | { &hf_z21_railcom_reserved2, |
2158 | 14 | { "RailCom reserved 2", "z21.railcomreserved2", |
2159 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2160 | 14 | NULL, HFILL } |
2161 | 14 | }, |
2162 | 14 | { &hf_z21_railcom_options, |
2163 | 14 | { "RailCom options", "z21.railcomoptions", |
2164 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2165 | 14 | NULL, HFILL } |
2166 | 14 | }, |
2167 | 14 | { &hf_z21_railcom_speed, |
2168 | 14 | { "RailCom speed", "z21.railcomspeed", |
2169 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2170 | 14 | NULL, HFILL } |
2171 | 14 | }, |
2172 | 14 | { &hf_z21_railcom_qos, |
2173 | 14 | { "RailCom QoS", "z21.railcomqos", |
2174 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2175 | 14 | NULL, HFILL } |
2176 | 14 | }, |
2177 | 14 | { &hf_z21_railcom_type, |
2178 | 14 | { "RailCom type", "z21.railcomtype", |
2179 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2180 | 14 | NULL, HFILL } |
2181 | 14 | }, |
2182 | 14 | { &hf_z21_loconet_message, |
2183 | 14 | { "LocoNet message", "z21.loconetmessage", |
2184 | 14 | FT_BYTES, BASE_NONE|SEP_SPACE, NULL, 0x0, |
2185 | 14 | NULL, HFILL } |
2186 | 14 | }, |
2187 | 14 | { &hf_z21_loconet_result, |
2188 | 14 | { "LocoNet result", "z21.loconetresult", |
2189 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2190 | 14 | NULL, HFILL } |
2191 | 14 | }, |
2192 | 14 | { &hf_z21_loconet_type, |
2193 | 14 | { "LocoNet type", "z21.loconettype", |
2194 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2195 | 14 | NULL, HFILL } |
2196 | 14 | }, |
2197 | 14 | { &hf_z21_loconet_report_address, |
2198 | 14 | { "LocoNet report address", "z21.loconetreportaddress", |
2199 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2200 | 14 | NULL, HFILL } |
2201 | 14 | }, |
2202 | 14 | { &hf_z21_loconet_feedback_address, |
2203 | 14 | { "LocoNet feedback address", "z21.loconetfeedbackaddress", |
2204 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2205 | 14 | NULL, HFILL } |
2206 | 14 | }, |
2207 | 14 | { &hf_z21_loconet_info, |
2208 | 14 | { "LocoNet info", "z21.loconetinfo", |
2209 | 14 | FT_BYTES, BASE_NONE|SEP_SPACE, NULL, 0x0, |
2210 | 14 | NULL, HFILL } |
2211 | 14 | }, |
2212 | 14 | { &hf_z21_can_type, |
2213 | 14 | { "CAN type", "z21.cantype", |
2214 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2215 | 14 | NULL, HFILL } |
2216 | 14 | }, |
2217 | 14 | { &hf_z21_can_network_id, |
2218 | 14 | { "CAN network ID", "z21.cannetworkid", |
2219 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, |
2220 | 14 | NULL, HFILL } |
2221 | 14 | }, |
2222 | 14 | { &hf_z21_can_module_address, |
2223 | 14 | { "CAN module address", "z21.canmoduleaddress", |
2224 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, |
2225 | 14 | NULL, HFILL } |
2226 | 14 | }, |
2227 | 14 | { &hf_z21_can_port, |
2228 | 14 | { "CAN input port (pin)", "z21.canport", |
2229 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2230 | 14 | NULL, HFILL } |
2231 | 14 | }, |
2232 | 14 | { &hf_z21_can_value1, |
2233 | 14 | { "CAN value 1", "z21.canvalue1", |
2234 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, |
2235 | 14 | NULL, HFILL } |
2236 | 14 | }, |
2237 | 14 | { &hf_z21_can_value2, |
2238 | 14 | { "CAN value 2", "z21.canvalue2", |
2239 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, |
2240 | 14 | NULL, HFILL } |
2241 | 14 | }, |
2242 | 14 | { &hf_z21_can_booster_name, |
2243 | 14 | { "CAN booster name", "z21.canboostername", |
2244 | 14 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
2245 | 14 | NULL, HFILL } |
2246 | 14 | }, |
2247 | 14 | { &hf_z21_can_booster_output_port, |
2248 | 14 | { "CAN booster output port", "z21.canboosteroutputport", |
2249 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2250 | 14 | NULL, HFILL } |
2251 | 14 | }, |
2252 | 14 | { &hf_z21_can_booster_state, |
2253 | 14 | { "CAN booster state", "z21.canboosterstate", |
2254 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, |
2255 | 14 | NULL, HFILL } |
2256 | 14 | }, |
2257 | 14 | { &hf_z21_can_booster_state_bg_active, |
2258 | 14 | { "CAN booster brake generator active", "z21.canboosterbrakegenerator", |
2259 | 14 | FT_BOOLEAN, 16, NULL, 0x0001, |
2260 | 14 | NULL, HFILL } |
2261 | 14 | }, |
2262 | 14 | { &hf_z21_can_booster_state_short_circuit, |
2263 | 14 | { "CAN booster short circuit", "z21.canboostershortcircuit", |
2264 | 14 | FT_BOOLEAN, 16, NULL, 0x0020, |
2265 | 14 | NULL, HFILL } |
2266 | 14 | }, |
2267 | 14 | { &hf_z21_can_booster_state_track_voltage_off, |
2268 | 14 | { "CAN booster track voltage off", "z21.canboostertrackvoltageoff", |
2269 | 14 | FT_BOOLEAN, 16, NULL, 0x0080, |
2270 | 14 | NULL, HFILL } |
2271 | 14 | }, |
2272 | 14 | { &hf_z21_can_booster_state_railcom_active, |
2273 | 14 | { "CAN booster RailCom cutout active", "z21.canboosterrailcomactive", |
2274 | 14 | FT_BOOLEAN, 16, NULL, 0x0800, |
2275 | 14 | NULL, HFILL } |
2276 | 14 | }, |
2277 | 14 | { &hf_z21_can_booster_state_output_disabled, |
2278 | 14 | { "CAN booster output disabled", "z21.canboosteroutputdisabled", |
2279 | 14 | FT_BOOLEAN, 16, NULL, 0x0100, |
2280 | 14 | NULL, HFILL } |
2281 | 14 | }, |
2282 | 14 | { &hf_z21_can_booster_vcc, |
2283 | 14 | { "CAN booster VCC voltage", "z21.canboostervoltage", |
2284 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2285 | 14 | NULL, HFILL } |
2286 | 14 | }, |
2287 | 14 | { &hf_z21_can_booster_current, |
2288 | 14 | { "CAN booster current", "z21.canboostercurrent", |
2289 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2290 | 14 | NULL, HFILL } |
2291 | 14 | }, |
2292 | 14 | { &hf_z21_can_booster_power, |
2293 | 14 | { "CAN booster power", "z21.canboosterpower", |
2294 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2295 | 14 | NULL, HFILL } |
2296 | 14 | }, |
2297 | 14 | { &hf_z21_zlink_message_type, |
2298 | 14 | { "zLink message type", "z21.zlinkmessagetype", |
2299 | 14 | FT_UINT8, BASE_HEX, VALS(z21_zlink_message_type_vals), 0x0, |
2300 | 14 | NULL, HFILL } |
2301 | 14 | }, |
2302 | 14 | { &hf_z21_zlink_hwid, |
2303 | 14 | { "zLink hardware ID", "z21.zlinkhwid", |
2304 | 14 | FT_UINT16, BASE_DEC_HEX, NULL, 0x0, |
2305 | 14 | NULL, HFILL } |
2306 | 14 | }, |
2307 | 14 | { &hf_z21_zlink_fw_major, |
2308 | 14 | { "zLink firmware major version", "z21.zlinkmajorversion", |
2309 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2310 | 14 | NULL, HFILL } |
2311 | 14 | }, |
2312 | 14 | { &hf_z21_zlink_fw_minor, |
2313 | 14 | { "zLink firmware minor version", "z21.zlinkminorversion", |
2314 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2315 | 14 | NULL, HFILL } |
2316 | 14 | }, |
2317 | 14 | { &hf_z21_zlink_fw_build, |
2318 | 14 | { "zLink firmware build version", "z21.zlinkbuildversion", |
2319 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2320 | 14 | NULL, HFILL } |
2321 | 14 | }, |
2322 | 14 | { &hf_z21_zlink_mac, |
2323 | 14 | { "zLink MAC address", "z21.zlinkmac", |
2324 | 14 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
2325 | 14 | NULL, HFILL } |
2326 | 14 | }, |
2327 | 14 | { &hf_z21_zlink_name, |
2328 | 14 | { "zLink name", "z21.zlinkname", |
2329 | 14 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
2330 | 14 | NULL, HFILL } |
2331 | 14 | }, |
2332 | 14 | { &hf_z21_zlink_reserved, |
2333 | 14 | { "zLink reserved", "z21.zlinkreserved", |
2334 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2335 | 14 | NULL, HFILL } |
2336 | 14 | }, |
2337 | 14 | { &hf_z21_booster_name, |
2338 | 14 | { "Booster name", "z21.boostername", |
2339 | 14 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
2340 | 14 | NULL, HFILL } |
2341 | 14 | }, |
2342 | 14 | { &hf_z21_booster_port, |
2343 | 14 | { "Booster port", "z21.boosterport", |
2344 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2345 | 14 | NULL, HFILL } |
2346 | 14 | }, |
2347 | 14 | { &hf_z21_booster_port_state, |
2348 | 14 | { "Booster port state", "z21.boosterportstate", |
2349 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2350 | 14 | NULL, HFILL } |
2351 | 14 | }, |
2352 | 14 | { &hf_z21_booster_state_data, |
2353 | 14 | { "Booster state data", "z21.boosterstatedata", |
2354 | 14 | FT_BYTES, BASE_NONE|SEP_SPACE, NULL, 0x0, |
2355 | 14 | NULL, HFILL } |
2356 | 14 | }, |
2357 | 14 | { &hf_z21_decoder_name, |
2358 | 14 | { "Decoder name", "z21.decodername", |
2359 | 14 | FT_STRINGZ, BASE_NONE, NULL, 0x0, |
2360 | 14 | NULL, HFILL } |
2361 | 14 | }, |
2362 | 14 | { &hf_z21_decoder_state_data, |
2363 | 14 | { "Decoder state data", "z21.decoderstatedata", |
2364 | 14 | FT_BYTES, BASE_NONE|SEP_SPACE, NULL, 0x0, |
2365 | 14 | NULL, HFILL } |
2366 | 14 | }, |
2367 | 14 | { &hf_z21_data, |
2368 | 14 | { "Undecoded data", "z21.data", |
2369 | 14 | FT_BYTES, BASE_NONE|SEP_SPACE, NULL, 0x0, |
2370 | 14 | NULL, HFILL } |
2371 | 14 | }, |
2372 | 14 | }; |
2373 | | |
2374 | | /* Setup protocol subtree array */ |
2375 | 14 | static int *ett[] = { |
2376 | 14 | &ett_z21, |
2377 | 14 | }; |
2378 | | |
2379 | | /* Setup protocol expert items */ |
2380 | 14 | static ei_register_info ei[] = { |
2381 | 14 | { &ei_z21_invalid_checksum, |
2382 | 14 | { "z21.invalidchecksum", PI_CHECKSUM, PI_WARN, |
2383 | 14 | "Invalid XOR checksum", EXPFILL } |
2384 | 14 | }, |
2385 | 14 | }; |
2386 | | |
2387 | | /* Register the protocol name and description */ |
2388 | 14 | proto_z21 = proto_register_protocol("Z21 LAN Protocol", "Z21", "z21"); |
2389 | | |
2390 | | /* Required function calls to register the header fields and subtrees */ |
2391 | 14 | proto_register_field_array(proto_z21, hf, array_length(hf)); |
2392 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
2393 | | |
2394 | | /* Required function calls to register expert items */ |
2395 | 14 | expert_z21 = expert_register_protocol(proto_z21); |
2396 | 14 | expert_register_field_array(expert_z21, ei, array_length(ei)); |
2397 | | |
2398 | 14 | z21_handle = register_dissector("z21", dissect_z21, proto_z21); |
2399 | | |
2400 | | /* Register a preferences module (see section 2.6 of README.dissector |
2401 | | * for more details). Registration of a prefs callback is not required |
2402 | | * if there are no preferences that affect protocol registration (an example |
2403 | | * of a preference that would affect registration is a port preference). |
2404 | | * If the prefs callback is not needed, use NULL instead of |
2405 | | * proto_reg_handoff_z21 in the following. |
2406 | | */ |
2407 | 14 | prefs_register_protocol(proto_z21, proto_reg_handoff_z21); |
2408 | 14 | } |
2409 | | |
2410 | | void |
2411 | | proto_reg_handoff_z21(void) |
2412 | 14 | { |
2413 | 14 | static bool initialized = false; |
2414 | | |
2415 | 14 | if (!initialized) { |
2416 | 14 | dissector_add_uint_range_with_preference("udp.port", Z21_UDP_PORTS, z21_handle); |
2417 | | initialized = true; |
2418 | 14 | } |
2419 | 14 | udp_port_range = prefs_get_range_value("Z21", "udp.port"); |
2420 | 14 | } |