Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-obd-ii.c
blob358e78efbac680936a96013f95121cdb99abd8a8
1 /* packet-obd-ii.c
2 * Routines for OBD-II PIDs dissection
4 * Based on https://en.wikipedia.org/wiki/OBD-II_PIDs
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/proto.h>
17 #include <epan/unit_strings.h>
18 #include <expert.h>
20 #include <wsutil/utf8_entities.h>
22 #include "packet-socketcan.h"
23 #include "packet-iso15765.h"
25 void proto_register_obdii(void);
26 void proto_reg_handoff_obdii(void);
28 static dissector_handle_t obdii_handle;
30 static int proto_obdii;
32 static int ett_obdii;
34 static int hf_obdii_mode;
35 static int hf_obdii_raw_value;
37 static int hf_obdii_mode01_pid;
38 static int hf_obdii_mode01_supported_pid;
39 static int hf_obdii_mode01_unsupported_pid;
40 static int hf_obdii_mode01_fuel_system1_status;
41 static int hf_obdii_mode01_fuel_system2_status;
42 static int hf_obdii_mode01_engine_load;
43 static int hf_obdii_mode01_engine_coolant_temp;
44 static int hf_obdii_mode01_short_term_fuel_bank1;
45 static int hf_obdii_mode01_long_term_fuel_bank1;
46 static int hf_obdii_mode01_short_term_fuel_bank2;
47 static int hf_obdii_mode01_long_term_fuel_bank2;
48 static int hf_obdii_mode01_fuel_pressure;
49 static int hf_obdii_mode01_engine_rpm;
50 static int hf_obdii_mode01_vehicle_speed;
51 static int hf_obdii_mode01_timing_advance;
52 static int hf_obdii_mode01_intake_air_temp;
53 static int hf_obdii_mode01_maf_air_flow_rate;
54 static int hf_obdii_mode01_throttle_position;
55 static int hf_obdii_mode01_secondary_air_status;
56 static int hf_obdii_mode01_obd_standards;
57 static int hf_obdii_mode01_engine_uptime;
58 static int hf_obdii_mode01_fuel_rail_pressure;
59 static int hf_obdii_mode01_fuel_rail_gauge_pressure;
60 static int hf_obdii_mode01_fuel_rail_absolute_pressure;
61 static int hf_obdii_mode01_commanded_egr;
62 static int hf_obdii_mode01_egr_error;
63 static int hf_obdii_mode01_commanded_evap_purge;
64 static int hf_obdii_mode01_fuel_tank_level_input;
65 static int hf_obdii_mode01_warm_ups;
66 static int hf_obdii_mode01_evap_system_vapor_pressure;
67 static int hf_obdii_mode01_absolute_barometric_pressure;
68 static int hf_obdii_mode01_intake_manifold_absolute_pressure;
69 static int hf_obdii_mode01_oxygen_sensor_id;
70 static int hf_obdii_mode01_oxygen_sensor_fuel_air_ratio;
71 static int hf_obdii_mode01_oxygen_sensor_voltage;
72 static int hf_obdii_mode01_oxygen_sensor_current;
73 static int hf_obdii_mode01_distance_traveled_with_mil;
74 static int hf_obdii_mode01_distance_traveled_since_code_clear;
75 static int hf_obdii_mode01_time_run_with_mil;
76 static int hf_obdii_mode01_time_since_trouble_code_clear;
77 static int hf_obdii_mode01_catalyst_temp_11;
78 static int hf_obdii_mode01_catalyst_temp_21;
79 static int hf_obdii_mode01_catalyst_temp_12;
80 static int hf_obdii_mode01_catalyst_temp_22;
81 static int hf_obdii_mode01_ambient_air_temp;
82 static int hf_obdii_mode01_absolute_throttle_position_B;
83 static int hf_obdii_mode01_absolute_throttle_position_C;
84 static int hf_obdii_mode01_accelerator_pedal_position_D;
85 static int hf_obdii_mode01_accelerator_pedal_position_E;
86 static int hf_obdii_mode01_accelerator_pedal_position_F;
87 static int hf_obdii_mode01_commanded_throttle_actuator;
88 static int hf_obdii_mode01_fuel_type;
89 static int hf_obdii_mode01_control_module_voltage;
90 static int hf_obdii_mode01_absolute_load_value;
91 static int hf_obdii_mode01_fuel_air_commanded_equiv_ratio;
92 static int hf_obdii_mode01_relative_throttle_position;
93 static int hf_obdii_mode01_ethanol_fuel;
94 static int hf_obdii_mode01_absolute_evap_system_vapor_pressure;
95 static int hf_obdii_mode01_relative_accelerator_pedal_position;
96 static int hf_obdii_mode01_hybrid_battery_remaining_life;
97 static int hf_obdii_mode01_engine_oil_temp;
98 static int hf_obdii_mode01_fuel_injection_timing;
99 static int hf_obdii_mode01_engine_fuel_rate;
100 static int hf_obdii_mode01_torque_driver_demand_engine;
101 static int hf_obdii_mode01_torque_actual_engine;
102 static int hf_obdii_mode01_torque_reference_engine;
104 static int hf_obdii_mode09_pid;
105 static int hf_obdii_mode09_supported_pid;
106 static int hf_obdii_mode09_unsupported_pid;
108 static int hf_obdii_vin;
109 static int hf_obdii_ecu_name;
111 static expert_field ei_obdii_padding;
113 /* OBD-II CAN IDs have three aspects.
114 - IDs are either standard 11bit format (SFF) or extended 29bit format (EFF)
115 - An ID can be a query ID or a response ID.
116 - Response IDs fall into two ranges for both SFF and EFF formats
118 SFF response IDs can vary in the lowest nibble as follows:
119 two ranges: 0x7e0-0x7e7 and 0x7e8 - 0x7ef
120 EFF response IDs can vary in the lowest byte or the second lowest byte as follows:
121 0x18daXXf1 or 0x18daf1XX, where XX is in the range 0x00 - 0xff
123 The following defines set up bit patterns and masks to determine both query and responses.
125 #define ODBII_CAN_QUERY_ID_SFF 0x7DF
126 #define ODBII_CAN_RESPONSE_ID_LOWER_MIN_SFF 0x7E0
127 #define ODBII_CAN_RESPONSE_ID_UPPER_MIN_SFF 0x7E8
128 #define ODBII_CAN_RESPONSE_ID_LOWER_MASK_SFF 0x7
129 #define ODBII_CAN_RESPONSE_ID_UPPER_MASK_SFF 0x7
131 #define ODBII_CAN_QUERY_ID_EFF 0x18DB33F1
132 #define ODBII_CAN_RESPONSE_ID_LOWER_MIN_EFF 0x18DA00F1
133 #define ODBII_CAN_RESPONSE_ID_UPPER_MIN_EFF 0x18DAF100
134 #define ODBII_CAN_RESPONSE_ID_LOWER_MASK_EFF 0xFF00
135 #define ODBII_CAN_RESPONSE_ID_UPPER_MASK_EFF 0x00FF
137 #define OBDII_MODE_POS 0x00
138 #define OBDII_PID_POS 0x01
139 #define OBDII_VAL_OFF 0x02
140 #define OBDII_MODE07_DATA_OFF 0x01
142 #define OBDII_MODE01_PIDS_SUPPORT00 0x00
143 #define OBDII_MODE01_MONITOR_STATUS 0x01
144 #define OBDII_MODE01_FREEZE_DTC 0x02
145 #define OBDII_MODE01_FUEL_SYSTEM_STATUS 0x03
146 #define OBDII_MODE01_ENGINE_LOAD 0x04
147 #define OBDII_MODE01_ENGINE_COOLANT_TEMP 0x05
148 #define OBDII_MODE01_SHORT_TERM_FUEL_BANK1 0x06
149 #define OBDII_MODE01_LONG_TERM_FUEL_BANK1 0x07
150 #define OBDII_MODE01_SHORT_TERM_FUEL_BANK2 0x08
151 #define OBDII_MODE01_LONG_TERM_FUEL_BANK2 0x09
152 #define OBDII_MODE01_FUEL_PRESSURE 0x0A
153 #define OBDII_MODE01_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE 0x0B
154 #define OBDII_MODE01_ENGINE_RPM 0x0C
155 #define OBDII_MODE01_VEHICLE_SPEED 0x0D
156 #define OBDII_MODE01_TIMING_ADVANCE 0x0E
157 #define OBDII_MODE01_INTAKE_AIR_TEMP 0x0F
158 #define OBDII_MODE01_MAF_AIR_FLOW_RATE 0x10
159 #define OBDII_MODE01_THROTTLE_POSITION 0x11
160 #define OBDII_MODE01_SECONDARY_AIR_STATUS 0x12
161 #define OBDII_MODE01_OXYGEN_SENSOR_PRESET2 0x13
162 #define OBDII_MODE01_OXYGEN_SENSOR1 0x14
163 #define OBDII_MODE01_OXYGEN_SENSOR2 0x15
164 #define OBDII_MODE01_OXYGEN_SENSOR3 0x16
165 #define OBDII_MODE01_OXYGEN_SENSOR4 0x17
166 #define OBDII_MODE01_OXYGEN_SENSOR5 0x18
167 #define OBDII_MODE01_OXYGEN_SENSOR6 0x19
168 #define OBDII_MODE01_OXYGEN_SENSOR7 0x1A
169 #define OBDII_MODE01_OXYGEN_SENSOR8 0x1B
170 #define OBDII_MODE01_OBD_STANDARDS 0x1C
171 #define OBDII_MODE01_OXYGEN_SENSOR_PRESET4 0x1D
172 #define OBDII_MODE01_AUX_INPUT_STATUS 0x1E
173 #define OBDII_MODE01_ENGINE_UPTIME 0x1F
175 #define OBDII_MODE01_PIDS_SUPPORT20 0x20
176 #define OBDII_MODE01_DISTANCE_TRAVELED_WITH_MIL 0x21
177 #define OBDII_MODE01_FUEL_RAIL_PRESSURE 0x22
178 #define OBDII_MODE01_FUEL_RAIL_GAUGE_PRESSURE 0x23
179 #define OBDII_MODE01_OXYGEN_SENSOR1_ 0x24
180 #define OBDII_MODE01_OXYGEN_SENSOR2_ 0x25
181 #define OBDII_MODE01_OXYGEN_SENSOR3_ 0x26
182 #define OBDII_MODE01_OXYGEN_SENSOR4_ 0x27
183 #define OBDII_MODE01_OXYGEN_SENSOR5_ 0x28
184 #define OBDII_MODE01_OXYGEN_SENSOR6_ 0x29
185 #define OBDII_MODE01_OXYGEN_SENSOR7_ 0x2A
186 #define OBDII_MODE01_OXYGEN_SENSOR8_ 0x2B
187 #define OBDII_MODE01_COMMANDED_EGR 0x2C
188 #define OBDII_MODE01_EGR_ERROR 0x2D
189 #define OBDII_MODE01_COMMANDED_EVAP_PURGE 0x2E
190 #define OBDII_MODE01_FUEL_TANK_LEVEL 0x2F
191 #define OBDII_MODE01_WARM_UPS_SINCE_CLEAR 0x30
192 #define OBDII_MODE01_DISTANCE_TRAVELED_SINCE_CODES_CLEAR 0x31
193 #define OBDII_MODE01_EVAP_SYSTEM_VAPOR_PRESSURE 0x32
194 #define OBDII_MODE01_ABSOLUTE_BAROMETRIC_PRESSURE 0x33
195 #define OBDII_MODE01_OXYGEN_SENSOR1_A 0x34
196 #define OBDII_MODE01_OXYGEN_SENSOR2_A 0x35
197 #define OBDII_MODE01_OXYGEN_SENSOR3_A 0x36
198 #define OBDII_MODE01_OXYGEN_SENSOR4_A 0x37
199 #define OBDII_MODE01_OXYGEN_SENSOR5_A 0x38
200 #define OBDII_MODE01_OXYGEN_SENSOR6_A 0x39
201 #define OBDII_MODE01_OXYGEN_SENSOR7_A 0x3A
202 #define OBDII_MODE01_OXYGEN_SENSOR8_A 0x3B
203 #define OBDII_MODE01_CATALYST_TEMP11 0x3C
204 #define OBDII_MODE01_CATALYST_TEMP21 0x3D
205 #define OBDII_MODE01_CATALYST_TEMP12 0x3E
206 #define OBDII_MODE01_CATALYST_TEMP22 0x3F
208 #define OBDII_MODE01_PIDS_SUPPORT40 0x40
209 #define OBDII_MODE01_CONTROL_MODULE_VOLTAGE 0x42
210 #define OBDII_MODE01_ABSOLUTE_LOAD_VALUE 0x43
211 #define OBDII_MODE01_FUEL_AIR_COMMANDED_EQUIV_RATIO 0x44
212 #define OBDII_MODE01_RELATIVE_THROTTLE_POSITION 0x45
213 #define OBDII_MODE01_AMBIENT_AIR_TEMP 0x46
214 #define OBDII_MODE01_ABSOLUTE_THROTTLE_POSITION_B 0x47
215 #define OBDII_MODE01_ABSOLUTE_THROTTLE_POSITION_C 0x48
216 #define OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_D 0x49
217 #define OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_E 0x4A
218 #define OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_F 0x4B
219 #define OBDII_MODE01_COMMANDED_THROTTLE_ACTUATOR 0x4C
220 #define OBDII_MODE01_TIME_RUN_WITH_MIL 0x4D
221 #define OBDII_MODE01_TIME_SINCE_TROUBLE_CODES_CLEAR 0x4E
222 #define OBDII_MODE01_FUEL_TYPE 0x51
223 #define OBDII_MODE01_ETHANOL_FUEL 0x52
224 #define OBDII_MODE01_ABSOLUTE_EVAP_SYSTEM_VAPOR_PRESSURE 0x53
225 #define OBDII_MODE01_SHORT_TERM_OXYGEN_BANK13 0x55
226 #define OBDII_MODE01_LONG_TERM_OXYGEN_BANK13 0x56
227 #define OBDII_MODE01_SHORT_TERM_OXYGEN_BANK24 0x57
228 #define OBDII_MODE01_LONG_TERM_OXYGEN_BANK24 0x58
229 #define OBDII_MODE01_FUEL_RAIL_ABSOLUTE_PRESSURE 0x59
230 #define OBDII_MODE01_RELATIVE_ACCELERATOR_PEDAL_POSITION 0x5A
231 #define OBDII_MODE01_HYBRID_BATTERY_REMAINING_LIFE 0x5B
232 #define OBDII_MODE01_ENGINE_OIL_TEMP 0x5C
233 #define OBDII_MODE01_FUEL_INJECTION_TIMING 0x5D
234 #define OBDII_MODE01_ENGINE_FUEL_RATE 0x5E
236 #define OBDII_MODE01_PIDS_SUPPORT60 0x60
237 #define OBDII_MODE01_TORQUE_DRIVER_DEMAND_ENGINE 0x61
238 #define OBDII_MODE01_TORQUE_ACTUAL_ENGINE 0x62
239 #define OBDII_MODE01_TORQUE_REFERENCE_ENGINE 0x63
241 #define OBDII_MODE01_PIDS_SUPPORT80 0x80
242 #define OBDII_MODE01_PIDS_SUPPORTA0 0xA0
243 #define OBDII_MODE01_PIDS_SUPPORTC0 0xC0
245 #define OBDII_MODE09_PIDS_SUPPORT00 0x00
246 #define OBDII_MODE09_VIN02 0x02
247 #define OBDII_MODE09_CALIBRATION_ID04 0x04
248 #define OBDII_MODE09_CAL_VER_NUMBERS06 0x06
249 #define OBDII_MODE09_PERFORMANCE_SPARK08 0x08
250 #define OBDII_MODE09_ECU_NAME0A 0x0A
251 #define OBDII_MODE09_PERFORMANCE_COMPRESSION0B 0x0B
253 /* unit_name_string for OBDII_MODE01_TIMING_ADVANCE */
254 static const unit_name_string units_degree_btdc = { UTF8_DEGREE_SIGN "BTDC", NULL };
256 /* value_string[] for OBDII_MODE01_FUEL_SYSTEM_STATUS */
257 static const value_string obdii_fuel_system_status_vals[] =
259 { 1, "Open loop due to insufficient engine temperature" },
260 { 2, "Closed loop, using oxygen sensor feedback to determine fuel mix" },
261 { 4, "Open loop due to engine load OR fuel cut due to deceleration" },
262 { 8, "Open loop due to system failure" },
263 { 16, "Closed loop, using at least one oxygen sensor but there is a fault in the feedback system" },
264 { 0, NULL }
267 /* value_string[] for OBDII_MODE01_SECONDARY_AIR_STATUS */
268 static const value_string obdii_secondary_air_status_vals[] =
270 { 1, "Upstream" },
271 { 2, "Downstream of catalytic converter" },
272 { 4, "From the outside atmosphere or off" },
273 { 8, "Pump commanded on for diagnostics" },
274 { 0, NULL }
277 /* value_string[] for OBDII_MODE01_OBD_STANDARDS */
278 static const value_string obdii_standards_vals[] =
280 { 1, "OBD-II as defined by the CARB" },
281 { 2, "OBD as defined by the EPA" },
282 { 3, "OBD and OBD-II" },
283 { 4, "OBD-I" },
284 { 5, "Not OBD compliant" },
285 { 6, "EOBD" },
286 { 7, "EOBD and OBD-II" },
287 { 8, "EOBD and OBD" },
288 { 9, "EOBD, OBD and OBD II" },
289 { 10, "JOBD" },
290 { 11, "JOBD and OBD II" },
291 { 12, "JOBD and EOBD" },
292 { 13, "JOBD, EOBD, and OBD II" },
293 { 14, "Reserved" },
294 { 15, "Reserved" },
295 { 16, "Reserved" },
296 { 17, "EMD" },
297 { 18, "EMD+" },
298 { 19, "HD OBD-C" },
299 { 20, "HD OBD" },
300 { 21, "WWH OBD" },
301 { 22, "Reserved" },
302 { 23, "HD EOBD-I" },
303 { 24, "HD EOBD-I N" },
304 { 25, "HD EOBD-II" },
305 { 26, "HD EOBD-II N" },
306 { 27, "Reserved" },
307 { 28, "OBDBr-1" },
308 { 29, "OBDBr-2" },
309 { 30, "KOBD" },
310 { 31, "IOBD I" },
311 { 32, "IOBD II" },
312 { 33, "HD EOBD-IV" },
313 /* 34-250 Reserved */
314 /* 251-255 Not available for assignment (SAE J1939 special meaning) */
315 { 0, NULL}
318 /* value_string[] for OBDII_MODE01_FUEL_TYPE */
319 static const value_string obdii_fuel_type_coding_vals[] =
321 { 0, "Not available" },
322 { 1, "Gasoline" },
323 { 2, "Methanol" },
324 { 3, "Ethanol" },
325 { 4, "Diesel" },
326 { 5, "LPG" },
327 { 6, "CNG" },
328 { 7, "Propane" },
329 { 8, "Electric" },
330 { 9, "Bifuel running Gasoline" },
331 { 10, "Bifuel running Methanol" },
332 { 11, "Bifuel running Ethanol" },
333 { 12, "Bifuel running LPG" },
334 { 13, "Bifuel running CNG" },
335 { 14, "Bifuel running Propane" },
336 { 15, "Bifuel running Electricity" },
337 { 16, "Bifuel running electric and combustion engine" },
338 { 17, "Hybrid gasoline" },
339 { 18, "Hybrid Ethanol" },
340 { 19, "Hybrid Diesel" },
341 { 20, "Hybrid Electric" },
342 { 21, "Hybrid running electric and combustion engine" },
343 { 22, "Hybrid Regenerative" },
344 { 23, "Bifuel running diesel" },
345 { 0, NULL }
348 static const value_string obdii_mode01_pid_vals[] =
350 { OBDII_MODE01_PIDS_SUPPORT00, "PIDs supported [01 - 20]" },
351 { OBDII_MODE01_MONITOR_STATUS, "Monitor status" },
352 { OBDII_MODE01_FREEZE_DTC, "Freeze DTC" },
353 { OBDII_MODE01_FUEL_SYSTEM_STATUS, "Fuel system status" },
354 { OBDII_MODE01_ENGINE_LOAD, "Calculated engine load" },
355 { OBDII_MODE01_ENGINE_COOLANT_TEMP, "Engine coolant temperature" },
356 { OBDII_MODE01_SHORT_TERM_FUEL_BANK1, "Short term fuel trim (Bank 1)" },
357 { OBDII_MODE01_LONG_TERM_FUEL_BANK1, "Long term fuel trim (Bank 1)" },
358 { OBDII_MODE01_SHORT_TERM_FUEL_BANK2, "Short term fuel trim (Bank 2)" },
359 { OBDII_MODE01_LONG_TERM_FUEL_BANK2, "Long term fuel trim (Bank 2)" },
360 { OBDII_MODE01_FUEL_PRESSURE, "Fuel pressure" },
361 { OBDII_MODE01_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE, "Intake manifold absolute pressure" },
362 { OBDII_MODE01_ENGINE_RPM, "Engine RPM" },
363 { OBDII_MODE01_VEHICLE_SPEED, "Vehicle speed" },
364 { OBDII_MODE01_TIMING_ADVANCE, "Timing advance" },
365 { OBDII_MODE01_INTAKE_AIR_TEMP, "Intake air temperature" },
366 { OBDII_MODE01_MAF_AIR_FLOW_RATE, "MAF air flow rate" },
367 { OBDII_MODE01_THROTTLE_POSITION, "Throttle position" },
368 { OBDII_MODE01_SECONDARY_AIR_STATUS, "Commanded secondary air status" },
369 { OBDII_MODE01_OXYGEN_SENSOR_PRESET2, "Oxygen sensors present (2 banks)" },
370 { OBDII_MODE01_OXYGEN_SENSOR1, "Oxygen Sensor 1" },
371 { OBDII_MODE01_OXYGEN_SENSOR2, "Oxygen Sensor 2" },
372 { OBDII_MODE01_OXYGEN_SENSOR3, "Oxygen Sensor 3" },
373 { OBDII_MODE01_OXYGEN_SENSOR4, "Oxygen Sensor 4" },
374 { OBDII_MODE01_OXYGEN_SENSOR5, "Oxygen Sensor 5" },
375 { OBDII_MODE01_OXYGEN_SENSOR6, "Oxygen Sensor 6" },
376 { OBDII_MODE01_OXYGEN_SENSOR7, "Oxygen Sensor 7" },
377 { OBDII_MODE01_OXYGEN_SENSOR8, "Oxygen Sensor 8" },
378 { OBDII_MODE01_OBD_STANDARDS, "OBD standards" },
379 { OBDII_MODE01_OXYGEN_SENSOR_PRESET4, "Oxygen sensors present (4 banks)" },
380 { OBDII_MODE01_AUX_INPUT_STATUS, "Auxiliary input status" },
381 { OBDII_MODE01_ENGINE_UPTIME, "Run time since engine start" },
383 { OBDII_MODE01_PIDS_SUPPORT20, "PIDs supported [21 - 40]" },
384 { OBDII_MODE01_DISTANCE_TRAVELED_WITH_MIL, "Distance traveled with MIL on" },
385 { OBDII_MODE01_FUEL_RAIL_PRESSURE, "Fuel Rail Pressure" },
386 { OBDII_MODE01_FUEL_RAIL_GAUGE_PRESSURE, "Fuel Rail Gauge Pressure" },
387 { OBDII_MODE01_OXYGEN_SENSOR1_, "Oxygen Sensor 1" },
388 { OBDII_MODE01_OXYGEN_SENSOR2_, "Oxygen Sensor 2" },
389 { OBDII_MODE01_OXYGEN_SENSOR3_, "Oxygen Sensor 3" },
390 { OBDII_MODE01_OXYGEN_SENSOR4_, "Oxygen Sensor 4" },
391 { OBDII_MODE01_OXYGEN_SENSOR5_, "Oxygen Sensor 5" },
392 { OBDII_MODE01_OXYGEN_SENSOR6_, "Oxygen Sensor 6" },
393 { OBDII_MODE01_OXYGEN_SENSOR7_, "Oxygen Sensor 7" },
394 { OBDII_MODE01_OXYGEN_SENSOR8_, "Oxygen Sensor 8" },
395 { OBDII_MODE01_COMMANDED_EGR, "Commanded EGR" },
396 { OBDII_MODE01_EGR_ERROR, "EGR Error" },
397 { OBDII_MODE01_COMMANDED_EVAP_PURGE, "Commanded evaporative purge" },
398 { OBDII_MODE01_FUEL_TANK_LEVEL, "Fuel Tank Level Input" },
399 { OBDII_MODE01_WARM_UPS_SINCE_CLEAR, "Warm-ups since codes cleared" },
400 { OBDII_MODE01_DISTANCE_TRAVELED_SINCE_CODES_CLEAR, "Distance traveled since codes cleared" },
401 { OBDII_MODE01_EVAP_SYSTEM_VAPOR_PRESSURE, "Evap. System Vapor Pressure" },
402 { OBDII_MODE01_ABSOLUTE_BAROMETRIC_PRESSURE, "Absolute Barometric Pressure" },
403 { OBDII_MODE01_OXYGEN_SENSOR1_A, "Oxygen Sensor 1" },
404 { OBDII_MODE01_OXYGEN_SENSOR2_A, "Oxygen Sensor 2" },
405 { OBDII_MODE01_OXYGEN_SENSOR3_A, "Oxygen Sensor 3" },
406 { OBDII_MODE01_OXYGEN_SENSOR4_A, "Oxygen Sensor 4" },
407 { OBDII_MODE01_OXYGEN_SENSOR5_A, "Oxygen Sensor 5" },
408 { OBDII_MODE01_OXYGEN_SENSOR6_A, "Oxygen Sensor 6" },
409 { OBDII_MODE01_OXYGEN_SENSOR7_A, "Oxygen Sensor 7" },
410 { OBDII_MODE01_OXYGEN_SENSOR8_A, "Oxygen Sensor 8" },
411 { OBDII_MODE01_CATALYST_TEMP11, "Catalyst Temperature (Bank 1, Sensor 1)" },
412 { OBDII_MODE01_CATALYST_TEMP21, "Catalyst Temperature (Bank 2, Sensor 1)" },
413 { OBDII_MODE01_CATALYST_TEMP12, "Catalyst Temperature (Bank 1, Sensor 2)" },
414 { OBDII_MODE01_CATALYST_TEMP22, "Catalyst Temperature (Bank 2, Sensor 2)" },
416 { OBDII_MODE01_PIDS_SUPPORT40, "PIDs supported [41 - 60]" },
417 { 0x41, "Monitor status this cycle" },
418 { OBDII_MODE01_CONTROL_MODULE_VOLTAGE, "Control module voltage" },
419 { OBDII_MODE01_ABSOLUTE_LOAD_VALUE, "Absolute load value" },
420 { OBDII_MODE01_FUEL_AIR_COMMANDED_EQUIV_RATIO, "Fuel-Air commanded equivalence ratio" },
421 { OBDII_MODE01_RELATIVE_THROTTLE_POSITION, "Relative throttle position" },
422 { OBDII_MODE01_AMBIENT_AIR_TEMP, "Ambient air temperature" },
423 { OBDII_MODE01_ABSOLUTE_THROTTLE_POSITION_B, "Absolute throttle position B" },
424 { OBDII_MODE01_ABSOLUTE_THROTTLE_POSITION_C, "Absolute throttle position C" },
425 { OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_D, "Accelerator pedal position D" },
426 { OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_E, "Accelerator pedal position E" },
427 { OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_F, "Accelerator pedal position F" },
428 { OBDII_MODE01_COMMANDED_THROTTLE_ACTUATOR, "Commanded throttle actuator" },
429 { OBDII_MODE01_TIME_RUN_WITH_MIL, "Time run with MIL on" },
430 { OBDII_MODE01_TIME_SINCE_TROUBLE_CODES_CLEAR, "Time since trouble codes cleared" },
431 { 0x4F, "Maximum value for Fuel-Air equivalence ratio, oxygen sensor voltage, oxygen sensor current, intake manifold absolute pressure" },
432 { 0x50, "Maximum value for air flow rate from mass air flow sensor" },
433 { OBDII_MODE01_FUEL_TYPE, "Fuel Type" },
434 { OBDII_MODE01_ETHANOL_FUEL, "Ethanol fuel %" },
435 { OBDII_MODE01_ABSOLUTE_EVAP_SYSTEM_VAPOR_PRESSURE, "Absolute Evap system Vapor Pressure" },
436 { 0x54, "Evap system vapor pressure" },
437 { OBDII_MODE01_SHORT_TERM_OXYGEN_BANK13, "Short term secondary oxygen sensor trim (Bank 1, 3)" },
438 { OBDII_MODE01_LONG_TERM_OXYGEN_BANK13, "Long term secondary oxygen sensor trim (Bank 1, 3)" },
439 { OBDII_MODE01_SHORT_TERM_OXYGEN_BANK24, "Short term secondary oxygen sensor trim (Bank 2, 4)" },
440 { OBDII_MODE01_LONG_TERM_OXYGEN_BANK24, "Long term secondary oxygen sensor trim (Bank 2, 4)" },
441 { OBDII_MODE01_FUEL_RAIL_ABSOLUTE_PRESSURE, "Fuel rail absolute pressure" },
442 { OBDII_MODE01_RELATIVE_ACCELERATOR_PEDAL_POSITION, "Relative accelerator pedal position" },
443 { OBDII_MODE01_HYBRID_BATTERY_REMAINING_LIFE, "Hybrid battery pack remaining life" },
444 { OBDII_MODE01_ENGINE_OIL_TEMP, "Engine oil temperature" },
445 { OBDII_MODE01_FUEL_INJECTION_TIMING, "Fuel injection timing" },
446 { OBDII_MODE01_ENGINE_FUEL_RATE, "Engine fuel rate" },
447 { 0x5F, "Emission requirements to which vehicle is designed" },
449 { OBDII_MODE01_PIDS_SUPPORT60, "PIDs supported [61 - 80]" },
450 { OBDII_MODE01_TORQUE_DRIVER_DEMAND_ENGINE, "Driver's demand engine - percent torque" },
451 { OBDII_MODE01_TORQUE_ACTUAL_ENGINE, "Actual engine - percent torque" },
452 { OBDII_MODE01_TORQUE_REFERENCE_ENGINE, "Engine reference torque" },
453 { 0x64, "Engine percent torque data" },
454 { 0x65, "Auxiliary input / output supported" },
455 { 0x66, "Mass air flow sensor" },
456 { 0x67, "Engine coolant temperature" },
457 { 0x68, "Intake air temperature sensor" },
458 { 0x69, "Commanded EGR and EGR Error" },
459 { 0x6A, "Commanded Diesel intake air flow control and relative intake air flow position" },
460 { 0x6B, "Exhaust gas recirculation temperature" },
461 { 0x6C, "Commanded throttle actuator control and relative throttle position" },
462 { 0x6D, "Fuel pressure control system" },
463 { 0x6E, "Injection pressure control system" },
464 { 0x6F, "Turbocharger compressor inlet pressure" },
465 { 0x70, "Boost pressure control" },
466 { 0x71, "Variable Geometry turbo (VGT) control" },
467 { 0x72, "Wastegate control" },
468 { 0x73, "Exhaust pressure" },
469 { 0x74, "Turbocharger RPM" },
470 { 0x75, "Turbocharger temperature" },
471 { 0x76, "Turbocharger temperature" },
472 { 0x77, "Charge air cooler temperature" },
473 { 0x78, "Exhaust Gas temperature (Bank 1)" },
474 { 0x79, "Exhaust Gas temperature (Bank 2)" },
475 { 0x7A, "Diesel particulate filter" },
476 { 0x7B, "Diesel particulate filter" },
477 { 0x7C, "Diesel Particulate filter temperature" },
478 { 0x7D, "NOx Not-To-Exceed control area status" },
479 { 0x7E, "PM Not-To-Exceed control area status" },
480 { 0x7F, "Engine run time" },
482 { OBDII_MODE01_PIDS_SUPPORT80, "PIDs supported [81 - A0]" },
483 { 0x81, "Engine run time for Auxiliary Emissions Control Device" },
484 { 0x82, "Engine run time for Auxiliary Emissions Control Device" },
485 { 0x83, "NOx sensor" },
486 { 0x84, "Manifold surface temperature" },
487 { 0x85, "NOx reagent system" },
488 { 0x86, "Particulate matter sensor" },
489 { 0x87, "Intake manifold absolute pressure" },
491 { OBDII_MODE01_PIDS_SUPPORTA0, "PIDs supported [A1 - C0]" },
493 { OBDII_MODE01_PIDS_SUPPORTC0, "PIDs supported [C1 - E0]" },
495 { 0x00, NULL }
498 static value_string_ext obdii_mode01_pid_vals_ext = VALUE_STRING_EXT_INIT(obdii_mode01_pid_vals);
500 static const value_string obdii_mode09_pid_vals[] =
502 { OBDII_MODE09_PIDS_SUPPORT00, "PIDs supported [00 - 20]" },
503 { OBDII_MODE09_VIN02, "Vehicle VIN" },
504 { OBDII_MODE09_CALIBRATION_ID04, "Calibration ID" },
505 { OBDII_MODE09_CAL_VER_NUMBERS06, "Calibration Verification Numbers" },
506 { OBDII_MODE09_PERFORMANCE_SPARK08, "In-use performance tracking for spark ignition vehicles" },
507 { OBDII_MODE09_ECU_NAME0A, "ECU Name" },
508 { OBDII_MODE09_PERFORMANCE_COMPRESSION0B, "In-use performance tracking for compression ignition vehicles" },
509 { 0x00, NULL }
512 static value_string_ext obdii_mode09_pid_vals_ext = VALUE_STRING_EXT_INIT(obdii_mode09_pid_vals);
514 static const value_string obdii_mode_vals[] =
516 { 0x01, "Show current data" },
517 { 0x02, "Show freeze frame data" },
518 { 0x03, "Show stored Diagnostic Trouble Codes" },
519 { 0x04, "Clear Diagnostic Trouble Codes and stored values" },
520 { 0x05, "Test results, oxygen sensor monitoring (non CAN only)" },
521 { 0x06, "Test results, other component/system monitoring (Test results, oxygen sensor monitoring for CAN only)" },
522 { 0x07, "Show pending Diagnostic Trouble Codes (detected during current or last driving cycle)" },
523 { 0x08, "Control operation of on-board component/system" },
524 { 0x09, "Request vehicle information" },
525 { 0x0A, "Permanent Diagnostic Trouble Codes (DTCs) (Cleared DTCs)" },
526 { 0x00, NULL }
529 struct obdii_packet_info
531 packet_info *pinfo;
532 uint32_t can_id;
534 uint8_t data_bytes;
535 uint8_t mode;
537 uint8_t value_bytes;
538 int value_offset;
539 uint8_t valueA, valueB, valueC, valueD, valueE;
542 static bool
543 dissect_obdii_common_temperature(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
545 if (oinfo->value_bytes == 1)
547 int16_t val = ((int) oinfo->valueA) - 40;
549 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %d " UTF8_DEGREE_SIGN "C", val);
550 proto_tree_add_int(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
551 return true;
554 return false;
557 static bool
558 dissect_obdii_common_percent(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
560 if (oinfo->value_bytes == 1)
562 double val = (100 * oinfo->valueA) / 255.0;
564 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f %%", val);
565 proto_tree_add_double(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
566 return true;
569 return false;
572 static bool
573 dissect_obdii_common_percent_neg(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
575 if (oinfo->value_bytes == 1)
577 double val = ((100 * oinfo->valueA) / 128.0) - 100.0;
579 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f %%", val);
580 proto_tree_add_double(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
581 return true;
584 return false;
587 static bool
588 dissect_obdii_common_fuel_rail_pressure(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
590 if (oinfo->value_bytes == 2)
592 unsigned val = 10 * (256 * oinfo->valueA + oinfo->valueB);
594 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u kPa", val);
595 proto_tree_add_uint(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
596 return true;
599 return false;
602 static bool
603 dissect_obdii_common_absolute_pressure(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
605 if (oinfo->value_bytes == 1)
607 uint8_t val = oinfo->valueA;
609 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u kPa", val);
610 proto_tree_add_uint(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
611 return true;
614 return false;
617 static bool
618 dissect_obdii_common_distance_travelled(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
620 if (oinfo->value_bytes == 2)
622 uint16_t val = 256 * oinfo->valueA + oinfo->valueB;
624 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u km", val);
625 proto_tree_add_uint(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
626 return true;
629 return false;
632 static bool
633 dissect_obdii_common_time(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
635 if (oinfo->value_bytes == 2)
637 uint16_t val = 256 * oinfo->valueA + oinfo->valueB;
639 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u minutes", val);
640 proto_tree_add_uint(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
641 return true;
644 return false;
647 static bool
648 dissect_obdii_common_torque(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
650 if (oinfo->value_bytes == 1)
652 int val = ((int) oinfo->valueA) - 125;
654 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %d %%", val);
655 proto_tree_add_int(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
656 return true;
659 return false;
662 static void
663 dissect_obdii_mode_01(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree)
665 uint8_t pid = tvb_get_uint8(tvb, OBDII_PID_POS);
666 int value_offset;
667 bool handled = false;
669 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, "- %s", val_to_str_ext(pid, &obdii_mode01_pid_vals_ext, "Unknown (%.2x)"));
670 proto_tree_add_uint(tree, hf_obdii_mode01_pid, tvb, OBDII_PID_POS, 1, pid);
672 proto_tree_add_item(tree, hf_obdii_raw_value, tvb, OBDII_VAL_OFF, MIN(oinfo->value_bytes, 4), ENC_NA);
674 value_offset = OBDII_VAL_OFF;
675 oinfo->value_offset = value_offset;
677 /* https://en.wikipedia.org/wiki/OBD-II_PIDs#Mode_01 */
678 switch (pid)
680 case OBDII_MODE01_PIDS_SUPPORT00:
681 case OBDII_MODE01_PIDS_SUPPORT20:
682 case OBDII_MODE01_PIDS_SUPPORT40:
683 case OBDII_MODE01_PIDS_SUPPORT60:
684 case OBDII_MODE01_PIDS_SUPPORT80:
685 case OBDII_MODE01_PIDS_SUPPORTA0:
686 case OBDII_MODE01_PIDS_SUPPORTC0:
687 if ((handled = (oinfo->value_bytes == 4)))
689 uint32_t val = ((oinfo->valueA << 24) | (oinfo->valueB << 16) | (oinfo->valueC << 8) | (oinfo->valueD << 0));
690 int i;
691 const char *sepa;
692 char bits_str[33];
694 sepa = ": ";
695 for (i = 31; i >= 0; i--)
697 unsigned this_pid = (pid + 32 - i);
698 proto_item *ti;
700 memset(bits_str, '.', 32);
701 bits_str[32] = '\0';
703 if ((val & (1U << i)))
705 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, "%s%.2X", sepa, this_pid);
706 ti = proto_tree_add_uint(tree, hf_obdii_mode01_supported_pid, tvb, value_offset, oinfo->value_bytes, this_pid);
707 sepa = ",";
708 bits_str[31 - i] = '1';
710 else
712 ti = proto_tree_add_uint(tree, hf_obdii_mode01_unsupported_pid, tvb, value_offset, oinfo->value_bytes, this_pid);
713 bits_str[31 - i] = '0';
716 proto_item_prepend_text(ti, "%s = ", bits_str);
719 break;
721 case OBDII_MODE01_FUEL_SYSTEM_STATUS:
722 if ((handled = (oinfo->value_bytes == 2)))
724 uint8_t fuel_system1_val = oinfo->valueA;
725 uint8_t fuel_system2_val = oinfo->valueB;
727 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": System 1: %s", val_to_str(fuel_system1_val, obdii_fuel_system_status_vals, "Unknown (%.2X)"));
728 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", System 2: %s", val_to_str(fuel_system2_val, obdii_fuel_system_status_vals, "Unknown (%.2X)"));
730 proto_tree_add_uint(tree, hf_obdii_mode01_fuel_system1_status, tvb, value_offset + 0, 1, fuel_system1_val);
731 proto_tree_add_uint(tree, hf_obdii_mode01_fuel_system2_status, tvb, value_offset + 1, 1, fuel_system2_val);
733 break;
735 case OBDII_MODE01_ENGINE_LOAD:
736 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_engine_load);
737 break;
739 case OBDII_MODE01_ENGINE_COOLANT_TEMP:
740 handled = dissect_obdii_common_temperature(tvb, oinfo, tree, hf_obdii_mode01_engine_coolant_temp);
741 break;
743 case OBDII_MODE01_SHORT_TERM_FUEL_BANK1:
744 handled = dissect_obdii_common_percent_neg(tvb, oinfo, tree, hf_obdii_mode01_short_term_fuel_bank1);
745 break;
747 case OBDII_MODE01_LONG_TERM_FUEL_BANK1:
748 handled = dissect_obdii_common_percent_neg(tvb, oinfo, tree, hf_obdii_mode01_long_term_fuel_bank1);
749 break;
751 case OBDII_MODE01_SHORT_TERM_FUEL_BANK2:
752 handled = dissect_obdii_common_percent_neg(tvb, oinfo, tree, hf_obdii_mode01_short_term_fuel_bank2);
753 break;
755 case OBDII_MODE01_LONG_TERM_FUEL_BANK2:
756 handled = dissect_obdii_common_percent_neg(tvb, oinfo, tree, hf_obdii_mode01_long_term_fuel_bank2);
757 break;
759 case OBDII_MODE01_FUEL_PRESSURE:
760 if ((handled = (oinfo->value_bytes == 1)))
762 uint16_t val = 3 * oinfo->valueA;
764 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u kPa", val);
765 proto_tree_add_uint(tree, hf_obdii_mode01_fuel_pressure, tvb, value_offset, oinfo->value_bytes, val);
767 break;
769 case OBDII_MODE01_ENGINE_RPM:
770 if ((handled = (oinfo->value_bytes == 2)))
772 double val = (256 * oinfo->valueA + oinfo->valueB) / 4.0;
774 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f rpm", val);
775 proto_tree_add_double(tree, hf_obdii_mode01_engine_rpm, tvb, value_offset, oinfo->value_bytes, val);
777 break;
779 case OBDII_MODE01_VEHICLE_SPEED:
780 if ((handled = (oinfo->value_bytes == 1)))
782 uint8_t val = oinfo->valueA;
784 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u km/h", val);
785 proto_tree_add_uint(tree, hf_obdii_mode01_vehicle_speed, tvb, value_offset, oinfo->value_bytes, val);
787 break;
789 case OBDII_MODE01_TIMING_ADVANCE:
790 if ((handled = (oinfo->value_bytes == 1)))
792 double val = (oinfo->valueA - 128) / 2.0;
794 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f " UTF8_DEGREE_SIGN "BTDC", val);
795 proto_tree_add_double(tree, hf_obdii_mode01_timing_advance, tvb, value_offset, oinfo->value_bytes, val);
797 break;
799 case OBDII_MODE01_INTAKE_AIR_TEMP:
800 handled = dissect_obdii_common_temperature(tvb, oinfo, tree, hf_obdii_mode01_intake_air_temp);
801 break;
803 case OBDII_MODE01_MAF_AIR_FLOW_RATE:
804 if ((handled = (oinfo->value_bytes == 2)))
806 double val = (256 * oinfo->valueA + oinfo->valueB) / 100.0;
808 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f g/s", val);
809 proto_tree_add_double(tree, hf_obdii_mode01_maf_air_flow_rate, tvb, value_offset, oinfo->value_bytes, val);
811 break;
813 case OBDII_MODE01_THROTTLE_POSITION:
814 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_throttle_position);
815 break;
817 case OBDII_MODE01_SECONDARY_AIR_STATUS:
818 if ((handled = (oinfo->value_bytes == 1)))
820 uint8_t air_status = oinfo->valueA;
822 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %s", val_to_str(air_status, obdii_secondary_air_status_vals, "Unknown (%.2X)"));
823 proto_tree_add_uint(tree, hf_obdii_mode01_secondary_air_status, tvb, value_offset, oinfo->value_bytes, air_status);
825 break;
827 case OBDII_MODE01_OXYGEN_SENSOR_PRESET2:
828 if ((handled = (oinfo->value_bytes == 1)))
830 uint8_t bank1_sensor1 = (oinfo->valueA & (1 << 0));
831 uint8_t bank1_sensor2 = (oinfo->valueA & (1 << 1));
832 uint8_t bank1_sensor3 = (oinfo->valueA & (1 << 2));
833 uint8_t bank1_sensor4 = (oinfo->valueA & (1 << 3));
834 uint8_t bank2_sensor1 = (oinfo->valueA & (1 << 4));
835 uint8_t bank2_sensor2 = (oinfo->valueA & (1 << 5));
836 uint8_t bank2_sensor3 = (oinfo->valueA & (1 << 6));
837 uint8_t bank2_sensor4 = (oinfo->valueA & (1 << 7));
839 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": Bank1 sensors: %s%s%s%s%s",
840 bank1_sensor1 ? "1 " : "", bank1_sensor2 ? "2 " : "", bank1_sensor3 ? "3 " : "", bank1_sensor4 ? "4 " : "",
841 ((bank1_sensor1 | bank1_sensor2 | bank1_sensor3 | bank1_sensor4)) ? "" : "None");
843 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Bank2 sensors: %s%s%s%s%s",
844 bank2_sensor1 ? "1 " : "", bank2_sensor2 ? "2 " : "", bank2_sensor3 ? "3 " : "", bank2_sensor4 ? "4 " : "",
845 ((bank2_sensor1 | bank2_sensor2 | bank2_sensor3 | bank2_sensor4)) ? "" : "None");
847 /* TODO: proto tree */
849 break;
851 case OBDII_MODE01_OXYGEN_SENSOR_PRESET4:
852 if ((handled = (oinfo->value_bytes == 1)))
854 uint8_t bank1_sensor1 = (oinfo->valueA & (1 << 0));
855 uint8_t bank1_sensor2 = (oinfo->valueA & (1 << 1));
856 uint8_t bank2_sensor1 = (oinfo->valueA & (1 << 2));
857 uint8_t bank2_sensor2 = (oinfo->valueA & (1 << 3));
858 uint8_t bank3_sensor1 = (oinfo->valueA & (1 << 4));
859 uint8_t bank3_sensor2 = (oinfo->valueA & (1 << 5));
860 uint8_t bank4_sensor1 = (oinfo->valueA & (1 << 6));
861 uint8_t bank4_sensor2 = (oinfo->valueA & (1 << 7));
863 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": Bank1 sensors: %s%s%s",
864 bank1_sensor1 ? "1 " : "", bank1_sensor2 ? "2 " : "",
865 ((bank1_sensor1 | bank1_sensor2)) ? "" : "None");
867 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Bank2 sensors: %s%s%s",
868 bank2_sensor1 ? "1 " : "", bank2_sensor2 ? "2 " : "",
869 ((bank2_sensor1 | bank2_sensor2)) ? "" : "None");
871 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Bank3 sensors: %s%s%s",
872 bank3_sensor1 ? "1 " : "", bank3_sensor2 ? "2 " : "",
873 ((bank3_sensor1 | bank3_sensor2)) ? "" : "None");
875 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Bank4 sensors: %s%s%s",
876 bank4_sensor1 ? "1 " : "", bank4_sensor2 ? "2 " : "",
877 ((bank4_sensor1 | bank4_sensor2)) ? "" : "None");
879 /* TODO: proto tree */
881 break;
883 case OBDII_MODE01_OXYGEN_SENSOR1:
884 case OBDII_MODE01_OXYGEN_SENSOR2:
885 case OBDII_MODE01_OXYGEN_SENSOR3:
886 case OBDII_MODE01_OXYGEN_SENSOR4:
887 case OBDII_MODE01_OXYGEN_SENSOR5:
888 case OBDII_MODE01_OXYGEN_SENSOR6:
889 case OBDII_MODE01_OXYGEN_SENSOR7:
890 case OBDII_MODE01_OXYGEN_SENSOR8:
891 if ((handled = (oinfo->value_bytes == 2)))
893 double volt_val = (oinfo->valueA) / 200.0;
894 double fuel_trim = ((100.0 * oinfo->valueB) / 128.0) - 100.0;
896 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": Voltage: %.3f V", volt_val);
897 if (oinfo->valueB != 0xFF)
898 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Short term fuel trim: %.2f %%", fuel_trim);
900 proto_tree_add_uint(tree, hf_obdii_mode01_oxygen_sensor_id, tvb, value_offset, oinfo->value_bytes, 1 + (pid - OBDII_MODE01_OXYGEN_SENSOR1));
901 proto_tree_add_double(tree, hf_obdii_mode01_oxygen_sensor_voltage, tvb, value_offset, 1, volt_val);
902 /* TODO: proto_tree */
904 break;
906 case OBDII_MODE01_OBD_STANDARDS:
907 if ((handled = (oinfo->value_bytes == 1)))
909 uint8_t val = oinfo->valueA;
911 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %s", val_to_str(val, obdii_standards_vals, "Unknown (%u)"));
912 proto_tree_add_uint(tree, hf_obdii_mode01_obd_standards, tvb, value_offset, oinfo->value_bytes, val);
914 break;
916 case OBDII_MODE01_ENGINE_UPTIME:
917 if ((handled = (oinfo->value_bytes == 2)))
919 uint16_t val = 256 * oinfo->valueA + oinfo->valueB;
921 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u s", val);
922 proto_tree_add_uint(tree, hf_obdii_mode01_engine_uptime, tvb, value_offset, oinfo->value_bytes, val);
924 break;
926 case OBDII_MODE01_FUEL_RAIL_PRESSURE:
927 if ((handled = (oinfo->value_bytes == 2)))
929 double val = 0.079 * (256 * oinfo->valueA + oinfo->valueB);
931 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f kPa", val);
932 proto_tree_add_double(tree, hf_obdii_mode01_fuel_rail_pressure, tvb, value_offset, oinfo->value_bytes, val);
934 break;
936 case OBDII_MODE01_FUEL_RAIL_GAUGE_PRESSURE:
937 handled = dissect_obdii_common_fuel_rail_pressure(tvb, oinfo, tree, hf_obdii_mode01_fuel_rail_gauge_pressure);
938 break;
940 case OBDII_MODE01_FUEL_RAIL_ABSOLUTE_PRESSURE:
941 handled = dissect_obdii_common_fuel_rail_pressure(tvb, oinfo, tree, hf_obdii_mode01_fuel_rail_absolute_pressure);
942 break;
944 case OBDII_MODE01_OXYGEN_SENSOR1_:
945 case OBDII_MODE01_OXYGEN_SENSOR2_:
946 case OBDII_MODE01_OXYGEN_SENSOR3_:
947 case OBDII_MODE01_OXYGEN_SENSOR4_:
948 case OBDII_MODE01_OXYGEN_SENSOR5_:
949 case OBDII_MODE01_OXYGEN_SENSOR6_:
950 case OBDII_MODE01_OXYGEN_SENSOR7_:
951 case OBDII_MODE01_OXYGEN_SENSOR8_:
952 if ((handled = (oinfo->value_bytes == 4)))
954 double fuel_air_ratio = (256 * oinfo->valueA + oinfo->valueB) * (2.0 / 65536.0);
955 double volt_val = (256 * oinfo->valueC + oinfo->valueD) * (8.0 / 65536.0);
957 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": Fuel-Air Equivalence: %.4f ratio", fuel_air_ratio);
958 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Voltage: %.4f V", volt_val);
960 proto_tree_add_uint(tree, hf_obdii_mode01_oxygen_sensor_id, tvb, value_offset, oinfo->value_bytes, 1 + (pid - OBDII_MODE01_OXYGEN_SENSOR1_));
961 proto_tree_add_double(tree, hf_obdii_mode01_oxygen_sensor_fuel_air_ratio, tvb, value_offset, 2, fuel_air_ratio);
962 proto_tree_add_double(tree, hf_obdii_mode01_oxygen_sensor_voltage, tvb, value_offset + 2, 2, volt_val);
964 break;
966 case OBDII_MODE01_COMMANDED_EGR:
967 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_commanded_egr);
968 break;
970 case OBDII_MODE01_EGR_ERROR:
971 handled = dissect_obdii_common_percent_neg(tvb, oinfo, tree, hf_obdii_mode01_egr_error);
972 break;
974 case OBDII_MODE01_COMMANDED_EVAP_PURGE:
975 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_commanded_evap_purge);
976 break;
978 case OBDII_MODE01_FUEL_TANK_LEVEL:
979 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_fuel_tank_level_input);
980 break;
982 case OBDII_MODE01_WARM_UPS_SINCE_CLEAR:
983 if ((handled = (oinfo->value_bytes == 1)))
985 uint8_t val = oinfo->valueA;
987 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u", val);
988 proto_tree_add_uint(tree, hf_obdii_mode01_warm_ups, tvb, value_offset, oinfo->value_bytes, val);
990 break;
992 case OBDII_MODE01_EVAP_SYSTEM_VAPOR_PRESSURE:
993 if ((handled = (oinfo->value_bytes == 2)))
995 double val = ((int16_t) (oinfo->valueA * 256 + oinfo->valueB)) / 4.0;
997 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f kPa", val);
998 proto_tree_add_double(tree, hf_obdii_mode01_evap_system_vapor_pressure, tvb, value_offset, oinfo->value_bytes, val);
1000 break;
1002 case OBDII_MODE01_ABSOLUTE_BAROMETRIC_PRESSURE:
1003 handled = dissect_obdii_common_absolute_pressure(tvb, oinfo, tree, hf_obdii_mode01_absolute_barometric_pressure);
1004 break;
1006 case OBDII_MODE01_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE:
1007 handled = dissect_obdii_common_absolute_pressure(tvb, oinfo, tree, hf_obdii_mode01_intake_manifold_absolute_pressure);
1008 break;
1010 case OBDII_MODE01_OXYGEN_SENSOR1_A:
1011 case OBDII_MODE01_OXYGEN_SENSOR2_A:
1012 case OBDII_MODE01_OXYGEN_SENSOR3_A:
1013 case OBDII_MODE01_OXYGEN_SENSOR4_A:
1014 case OBDII_MODE01_OXYGEN_SENSOR5_A:
1015 case OBDII_MODE01_OXYGEN_SENSOR6_A:
1016 case OBDII_MODE01_OXYGEN_SENSOR7_A:
1017 case OBDII_MODE01_OXYGEN_SENSOR8_A:
1018 if ((handled = (oinfo->value_bytes == 4)))
1020 double fuel_air_ratio = (256 * oinfo->valueA + oinfo->valueB) * (2.0 / 65536.0);
1021 double current_val = (((int) oinfo->valueC) - 128) + (oinfo->valueD / 256.0);
1023 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": Fuel-Air Equivalence: %.4f ratio", fuel_air_ratio);
1024 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Current: %.4f mA", current_val);
1026 proto_tree_add_uint(tree, hf_obdii_mode01_oxygen_sensor_id, tvb, value_offset, oinfo->value_bytes, 1 + (pid - OBDII_MODE01_OXYGEN_SENSOR1_A));
1027 proto_tree_add_double(tree, hf_obdii_mode01_oxygen_sensor_fuel_air_ratio, tvb, value_offset, 2, fuel_air_ratio);
1028 proto_tree_add_double(tree, hf_obdii_mode01_oxygen_sensor_current, tvb, value_offset + 2, 2, current_val);
1030 break;
1032 case OBDII_MODE01_CATALYST_TEMP11:
1033 case OBDII_MODE01_CATALYST_TEMP21:
1034 case OBDII_MODE01_CATALYST_TEMP12:
1035 case OBDII_MODE01_CATALYST_TEMP22:
1036 if ((handled = (oinfo->value_bytes == 2)))
1038 int hf_field =
1039 (pid == OBDII_MODE01_CATALYST_TEMP11) ? hf_obdii_mode01_catalyst_temp_11 :
1040 (pid == OBDII_MODE01_CATALYST_TEMP21) ? hf_obdii_mode01_catalyst_temp_21 :
1041 (pid == OBDII_MODE01_CATALYST_TEMP12) ? hf_obdii_mode01_catalyst_temp_12 :
1042 (pid == OBDII_MODE01_CATALYST_TEMP22) ? hf_obdii_mode01_catalyst_temp_22 :
1045 double val = ((256 * oinfo->valueA + oinfo->valueB) / 10.0) - 40.0;
1047 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f " UTF8_DEGREE_SIGN "C", val);
1048 proto_tree_add_double(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
1050 break;
1052 case OBDII_MODE01_CONTROL_MODULE_VOLTAGE:
1053 if ((handled = (oinfo->value_bytes == 2)))
1055 double val = (256 * oinfo->valueA + oinfo->valueB) / 1000.0;
1057 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f V", val);
1058 proto_tree_add_double(tree, hf_obdii_mode01_control_module_voltage, tvb, value_offset, oinfo->value_bytes, val);
1060 break;
1062 case OBDII_MODE01_ABSOLUTE_LOAD_VALUE:
1063 if ((handled = (oinfo->value_bytes == 2)))
1065 double val = ((256 * oinfo->valueA + oinfo->valueB) * 100) / 255.0;
1067 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f %%", val);
1068 proto_tree_add_double(tree, hf_obdii_mode01_absolute_load_value, tvb, value_offset, oinfo->value_bytes, val);
1070 break;
1072 case OBDII_MODE01_FUEL_AIR_COMMANDED_EQUIV_RATIO:
1073 if ((handled = (oinfo->value_bytes == 2)))
1075 double val = (256 * oinfo->valueA + oinfo->valueB) * (2.0 / 65536.0);
1077 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f", val);
1078 proto_tree_add_double(tree, hf_obdii_mode01_fuel_air_commanded_equiv_ratio, tvb, value_offset, oinfo->value_bytes, val);
1080 break;
1082 case OBDII_MODE01_RELATIVE_THROTTLE_POSITION:
1083 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_relative_throttle_position);
1084 break;
1086 case OBDII_MODE01_AMBIENT_AIR_TEMP:
1087 handled = dissect_obdii_common_temperature(tvb, oinfo, tree, hf_obdii_mode01_ambient_air_temp);
1088 break;
1090 case OBDII_MODE01_ABSOLUTE_THROTTLE_POSITION_B:
1091 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_absolute_throttle_position_B);
1092 break;
1094 case OBDII_MODE01_ABSOLUTE_THROTTLE_POSITION_C:
1095 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_absolute_throttle_position_C);
1096 break;
1098 case OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_D:
1099 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_accelerator_pedal_position_D);
1100 break;
1102 case OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_E:
1103 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_accelerator_pedal_position_E);
1104 break;
1106 case OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_F:
1107 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_accelerator_pedal_position_F);
1108 break;
1110 case OBDII_MODE01_COMMANDED_THROTTLE_ACTUATOR:
1111 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_commanded_throttle_actuator);
1112 break;
1114 case OBDII_MODE01_DISTANCE_TRAVELED_WITH_MIL:
1115 handled = dissect_obdii_common_distance_travelled(tvb, oinfo, tree, hf_obdii_mode01_distance_traveled_with_mil);
1116 break;
1118 case OBDII_MODE01_DISTANCE_TRAVELED_SINCE_CODES_CLEAR:
1119 handled = dissect_obdii_common_distance_travelled(tvb, oinfo, tree, hf_obdii_mode01_distance_traveled_since_code_clear);
1120 break;
1122 case OBDII_MODE01_TIME_RUN_WITH_MIL:
1123 handled = dissect_obdii_common_time(tvb, oinfo, tree, hf_obdii_mode01_time_run_with_mil);
1124 break;
1126 case OBDII_MODE01_TIME_SINCE_TROUBLE_CODES_CLEAR:
1127 handled = dissect_obdii_common_time(tvb, oinfo, tree, hf_obdii_mode01_time_since_trouble_code_clear);
1128 break;
1130 case OBDII_MODE01_FUEL_TYPE:
1131 if ((handled = (oinfo->value_bytes == 1)))
1133 uint8_t val = oinfo->valueA;
1135 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %s", val_to_str(val, obdii_fuel_type_coding_vals, "Unknown (%u)"));
1136 proto_tree_add_uint(tree, hf_obdii_mode01_fuel_type, tvb, value_offset, oinfo->value_bytes, val);
1138 break;
1140 case OBDII_MODE01_ETHANOL_FUEL:
1141 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_ethanol_fuel);
1142 break;
1144 case OBDII_MODE01_ABSOLUTE_EVAP_SYSTEM_VAPOR_PRESSURE:
1145 if ((handled = (oinfo->value_bytes == 2)))
1147 double val = (oinfo->valueA * 256 + oinfo->valueB) / 200.0;
1149 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f kPa", val);
1150 proto_tree_add_double(tree, hf_obdii_mode01_absolute_evap_system_vapor_pressure, tvb, value_offset, oinfo->value_bytes, val);
1152 break;
1154 case OBDII_MODE01_SHORT_TERM_OXYGEN_BANK13:
1155 case OBDII_MODE01_LONG_TERM_OXYGEN_BANK13:
1156 case OBDII_MODE01_SHORT_TERM_OXYGEN_BANK24:
1157 case OBDII_MODE01_LONG_TERM_OXYGEN_BANK24:
1158 if ((handled = (oinfo->value_bytes == 2)))
1160 double bankA_val = ((100.0 * oinfo->valueA) / 128.0) - 100.0;
1161 double bankB_val = ((100.0 * oinfo->valueB) / 128.0) - 100.0;
1163 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": { %.2f %%, %.2f %% }", bankA_val, bankB_val);
1165 /* TODO: proto tree */
1167 break;
1169 case OBDII_MODE01_RELATIVE_ACCELERATOR_PEDAL_POSITION:
1170 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_relative_accelerator_pedal_position);
1171 break;
1173 case OBDII_MODE01_HYBRID_BATTERY_REMAINING_LIFE:
1174 handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_hybrid_battery_remaining_life);
1175 break;
1177 case OBDII_MODE01_ENGINE_OIL_TEMP:
1178 handled = dissect_obdii_common_temperature(tvb, oinfo, tree, hf_obdii_mode01_engine_oil_temp);
1179 break;
1181 case OBDII_MODE01_FUEL_INJECTION_TIMING:
1182 if ((handled = (oinfo->value_bytes == 2)))
1184 double val = ((256 * oinfo->valueA + oinfo->valueB - (210 * 128)) / 128.0);
1186 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f " UTF8_DEGREE_SIGN, val);
1187 proto_tree_add_double(tree, hf_obdii_mode01_fuel_injection_timing, tvb, value_offset, oinfo->value_bytes, val);
1189 break;
1191 case OBDII_MODE01_ENGINE_FUEL_RATE:
1192 if ((handled = (oinfo->value_bytes == 2)))
1194 double val = (256 * oinfo->valueA + oinfo->valueB) / 20.0;
1196 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f L/h", val);
1197 proto_tree_add_double(tree, hf_obdii_mode01_engine_fuel_rate, tvb, value_offset, oinfo->value_bytes, val);
1199 break;
1201 case OBDII_MODE01_TORQUE_DRIVER_DEMAND_ENGINE:
1202 handled = dissect_obdii_common_torque(tvb, oinfo, tree, hf_obdii_mode01_torque_driver_demand_engine);
1203 break;
1205 case OBDII_MODE01_TORQUE_ACTUAL_ENGINE:
1206 handled = dissect_obdii_common_torque(tvb, oinfo, tree, hf_obdii_mode01_torque_actual_engine);
1207 break;
1209 case OBDII_MODE01_TORQUE_REFERENCE_ENGINE:
1210 if ((handled = (oinfo->value_bytes == 2)))
1212 uint16_t val = 256 * oinfo->valueA + oinfo->valueB;
1214 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u Nm", val);
1215 proto_tree_add_uint(tree, hf_obdii_mode01_torque_reference_engine, tvb, value_offset, oinfo->value_bytes, val);
1217 break;
1220 if (!handled)
1222 /* display raw */
1223 col_append_str(oinfo->pinfo->cinfo, COL_INFO, ": <");
1224 if (oinfo->value_bytes >= 1) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueA);
1225 if (oinfo->value_bytes >= 2) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueB);
1226 if (oinfo->value_bytes >= 3) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueC);
1227 if (oinfo->value_bytes >= 4) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueD);
1228 col_append_str(oinfo->pinfo->cinfo, COL_INFO, " >");
1232 static void
1233 dissect_obdii_mode_07(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree)
1235 proto_tree_add_item(tree, hf_obdii_raw_value, tvb, OBDII_MODE07_DATA_OFF, oinfo->value_bytes, ENC_NA);
1237 /* display raw */
1238 col_append_str(oinfo->pinfo->cinfo, COL_INFO, ": <");
1239 if (oinfo->value_bytes >= 1) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueA);
1240 if (oinfo->value_bytes >= 2) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueB);
1241 if (oinfo->value_bytes >= 3) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueC);
1242 if (oinfo->value_bytes >= 4) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueD);
1243 if (oinfo->value_bytes >= 5) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueE);
1244 col_append_str(oinfo->pinfo->cinfo, COL_INFO, " >");
1247 static void
1248 dissect_obdii_mode_09(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree)
1250 uint8_t pid = tvb_get_uint8(tvb, OBDII_PID_POS);
1251 int value_offset;
1253 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, "- %s", val_to_str_ext(pid, &obdii_mode09_pid_vals_ext, "Unknown (%.2x)"));
1254 proto_tree_add_uint(tree, hf_obdii_mode09_pid, tvb, OBDII_PID_POS, 1, pid);
1256 value_offset = OBDII_VAL_OFF;
1257 oinfo->value_offset = value_offset;
1259 switch (pid)
1261 case OBDII_MODE09_PIDS_SUPPORT00:
1262 proto_tree_add_item(tree, hf_obdii_raw_value, tvb, OBDII_VAL_OFF, oinfo->value_bytes, ENC_NA);
1263 break;
1264 case OBDII_MODE09_VIN02:
1265 proto_tree_add_item(tree, hf_obdii_vin, tvb, OBDII_VAL_OFF+1, oinfo->value_bytes-1, ENC_ASCII);
1266 break;
1267 case OBDII_MODE09_CALIBRATION_ID04:
1268 case OBDII_MODE09_CAL_VER_NUMBERS06:
1269 case OBDII_MODE09_PERFORMANCE_SPARK08:
1270 proto_tree_add_item(tree, hf_obdii_raw_value, tvb, OBDII_VAL_OFF, oinfo->value_bytes, ENC_NA);
1271 break;
1272 case OBDII_MODE09_ECU_NAME0A:
1273 proto_tree_add_item(tree, hf_obdii_ecu_name, tvb, OBDII_VAL_OFF+1, oinfo->value_bytes-1, ENC_ASCII);
1274 break;
1275 case OBDII_MODE09_PERFORMANCE_COMPRESSION0B:
1276 default:
1277 proto_tree_add_item(tree, hf_obdii_raw_value, tvb, OBDII_VAL_OFF, oinfo->value_bytes, ENC_NA);
1278 break;
1283 static int
1284 dissect_obdii_query(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree)
1286 uint16_t pid;
1287 int pid_len;
1288 const char *mode_str;
1289 const char *pid_str;
1291 pid_len = oinfo->data_bytes - 1;
1292 if (pid_len == 0)
1294 if (oinfo->mode != 0x04 && oinfo->mode != 0x07)
1295 return 0;
1296 pid = 0; /* Should never be required but set to satisfy petri-dish */
1298 else if (pid_len == 1)
1299 pid = tvb_get_uint8(tvb, OBDII_PID_POS);
1300 else if (pid_len == 2)
1301 pid = tvb_get_ntohs(tvb, OBDII_PID_POS);
1302 else
1303 return 0;
1305 mode_str = val_to_str(oinfo->mode, obdii_mode_vals, "Unknown (%.2x)");
1307 switch (oinfo->mode)
1309 case 0x01:
1310 pid_str = val_to_str_ext(pid, &obdii_mode01_pid_vals_ext, "Unknown (%.2x)");
1311 proto_tree_add_uint(tree, hf_obdii_mode01_pid, tvb, OBDII_PID_POS, pid_len, pid);
1312 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " Request[%.3x] %s - %s", oinfo->can_id, mode_str, pid_str);
1313 break;
1315 case 0x04:
1316 case 0x07:
1317 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " Request[%.3x] %s", oinfo->can_id, mode_str);
1318 break;
1320 case 0x09:
1321 pid_str = val_to_str_ext(pid, &obdii_mode09_pid_vals_ext, "Unknown (%.2x)");
1322 proto_tree_add_uint(tree, hf_obdii_mode09_pid, tvb, OBDII_PID_POS, pid_len, pid);
1323 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " Request[%.3x] %s - %s", oinfo->can_id, mode_str, pid_str);
1324 break;
1326 default:
1327 pid_str = wmem_strdup_printf(wmem_packet_scope(), "Unknown (%.2x)", pid);
1328 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " Request[%.3x] %s - %s", oinfo->can_id, mode_str, pid_str);
1329 break;
1332 return tvb_captured_length(tvb);
1335 static int
1336 dissect_obdii_response(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree)
1338 col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, "Response[%.3x] %s ", oinfo->can_id, val_to_str(oinfo->mode, obdii_mode_vals, "Unknown (%.2x)"));
1340 if (oinfo->mode == 0x04 && oinfo->data_bytes == 0x01) {
1341 return tvb_captured_length(tvb);
1344 oinfo->value_bytes = oinfo->data_bytes - OBDII_VAL_OFF;
1346 if (oinfo->value_bytes >= 1) oinfo->valueA = tvb_get_uint8(tvb, OBDII_VAL_OFF);
1347 if (oinfo->value_bytes >= 2) oinfo->valueB = tvb_get_uint8(tvb, OBDII_VAL_OFF + 1);
1348 if (oinfo->value_bytes >= 3) oinfo->valueC = tvb_get_uint8(tvb, OBDII_VAL_OFF + 2);
1349 if (oinfo->value_bytes >= 4) oinfo->valueD = tvb_get_uint8(tvb, OBDII_VAL_OFF + 3);
1350 if (oinfo->value_bytes >= 5) oinfo->valueE = tvb_get_uint8(tvb, OBDII_VAL_OFF + 4);
1352 switch (oinfo->mode)
1354 case 0x01:
1355 dissect_obdii_mode_01(tvb, oinfo, tree);
1356 break;
1357 case 0x07:
1358 dissect_obdii_mode_07(tvb, oinfo, tree);
1359 break;
1360 case 0x09:
1361 dissect_obdii_mode_09(tvb, oinfo, tree);
1364 return tvb_captured_length(tvb);
1367 static int
1368 dissect_obdii_iso15765(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1370 iso15765_info_t iso15765_info;
1371 uint32_t can_id_only;
1372 struct obdii_packet_info oinfo;
1374 proto_tree *obdii_tree;
1375 proto_item *ti;
1377 uint8_t data_bytes;
1378 uint8_t mode;
1379 bool id_is_query;
1380 bool id_is_response;
1382 DISSECTOR_ASSERT(data);
1384 iso15765_info = *((iso15765_info_t *) data);
1385 if (iso15765_info.bus_type != ISO15765_TYPE_CAN && iso15765_info.bus_type != ISO15765_TYPE_CAN_FD) {
1386 return 0;
1389 can_id_only = iso15765_info.id & CAN_EFF_MASK;
1391 /* If we're using 29bit extended ID's then use extended ID parameters */
1392 if (iso15765_info.id & CAN_EFF_FLAG)
1394 id_is_query = (can_id_only == ODBII_CAN_QUERY_ID_EFF);
1395 id_is_response = ((((can_id_only & ~ODBII_CAN_RESPONSE_ID_LOWER_MASK_EFF) ^ ODBII_CAN_RESPONSE_ID_LOWER_MIN_EFF) == 0) ||
1396 (((can_id_only & ~ODBII_CAN_RESPONSE_ID_UPPER_MASK_EFF) ^ ODBII_CAN_RESPONSE_ID_UPPER_MIN_EFF) == 0)) ? 1 : 0;
1398 else
1400 id_is_query = (can_id_only == ODBII_CAN_QUERY_ID_SFF);
1401 id_is_response = ((((can_id_only & ~ODBII_CAN_RESPONSE_ID_LOWER_MASK_SFF) ^ ODBII_CAN_RESPONSE_ID_LOWER_MIN_SFF) == 0) ||
1402 (((can_id_only & ~ODBII_CAN_RESPONSE_ID_UPPER_MASK_SFF) ^ ODBII_CAN_RESPONSE_ID_UPPER_MIN_SFF) == 0));
1405 /* validate */
1406 if (iso15765_info.id & (CAN_ERR_FLAG | CAN_RTR_FLAG))
1407 return 0;
1409 if (!(id_is_query || id_is_response))
1410 return 0;
1412 data_bytes = tvb_reported_length(tvb);
1413 mode = tvb_get_uint8(tvb, OBDII_MODE_POS);
1415 /* Mode 7 is a datalength of 1, all other queries either 2 or 3 bytes */
1416 if (id_is_query)
1418 if (iso15765_info.len != 8)
1419 expert_add_info(pinfo, NULL, &ei_obdii_padding);
1420 if (data_bytes == 0 || data_bytes > 3)
1421 return 0;
1422 if (mode > 0x0a)
1423 return 0;
1426 if (id_is_response)
1428 if (mode != 0x44 && data_bytes < 2)
1429 return 0;
1430 if (mode < 0x40)
1431 return 0;
1433 mode -= 0x40;
1436 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OBD-II");
1437 col_clear(pinfo->cinfo, COL_INFO);
1439 ti = proto_tree_add_item(tree, proto_obdii, tvb, 0, -1, ENC_NA);
1440 obdii_tree = proto_item_add_subtree(ti, ett_obdii);
1442 proto_tree_add_uint(obdii_tree, hf_obdii_mode, tvb, OBDII_MODE_POS, 1, mode);
1444 memset(&oinfo, 0, sizeof(oinfo));
1445 oinfo.pinfo = pinfo;
1446 oinfo.can_id = can_id_only;
1447 oinfo.data_bytes = data_bytes;
1448 oinfo.mode = mode;
1450 if (id_is_query)
1451 return dissect_obdii_query(tvb, &oinfo, obdii_tree);
1453 if (id_is_response)
1454 return dissect_obdii_response(tvb, &oinfo, obdii_tree);
1456 /* never here */
1457 DISSECTOR_ASSERT_NOT_REACHED();
1459 return tvb_captured_length(tvb);
1462 static int
1463 dissect_obdii_uds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1465 struct obdii_packet_info oinfo;
1467 proto_tree *obdii_tree;
1468 proto_item *ti;
1470 uint8_t data_bytes;
1471 uint8_t mode;
1472 bool response;
1474 data_bytes = tvb_reported_length(tvb);
1475 mode = tvb_get_uint8(tvb, OBDII_MODE_POS);
1476 response = (mode & 0x40) == 0x40;
1477 mode = mode & 0xbf;
1479 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OBD-II");
1480 col_clear(pinfo->cinfo, COL_INFO);
1482 ti = proto_tree_add_item(tree, proto_obdii, tvb, 0, -1, ENC_NA);
1483 obdii_tree = proto_item_add_subtree(ti, ett_obdii);
1485 proto_tree_add_uint(obdii_tree, hf_obdii_mode, tvb, OBDII_MODE_POS, 1, mode);
1487 memset(&oinfo, 0, sizeof(oinfo));
1488 oinfo.pinfo = pinfo;
1489 oinfo.can_id = 0;
1490 oinfo.data_bytes = data_bytes;
1491 oinfo.mode = mode;
1493 if (!response) {
1494 return dissect_obdii_query(tvb, &oinfo, obdii_tree);
1495 } else {
1496 return dissect_obdii_response(tvb, &oinfo, obdii_tree);
1499 /* never here */
1500 DISSECTOR_ASSERT_NOT_REACHED();
1502 return tvb_captured_length(tvb);
1505 static bool
1506 dissect_obdii_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1508 return dissect_obdii_iso15765(tvb, pinfo, tree, data) != 0;
1511 void
1512 proto_register_obdii(void)
1514 static hf_register_info hf[] = {
1515 { &hf_obdii_mode,
1516 { "Mode", "obd-ii.mode", FT_UINT8, BASE_HEX, VALS(obdii_mode_vals), 0x0, NULL, HFILL },
1518 { &hf_obdii_raw_value,
1519 { "Raw value", "obd-ii.raw_value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL },
1521 { &hf_obdii_mode01_pid,
1522 { "PID", "obd-ii.mode01_pid", FT_UINT16, BASE_HEX | BASE_EXT_STRING, VALS_EXT_PTR(&obdii_mode01_pid_vals_ext), 0x0, NULL, HFILL },
1524 { &hf_obdii_mode01_supported_pid,
1525 { "Supported PID", "obd-ii.mode01_supported_pid", FT_UINT8, BASE_HEX | BASE_EXT_STRING, VALS_EXT_PTR(&obdii_mode01_pid_vals_ext), 0x0, NULL, HFILL },
1527 { &hf_obdii_mode01_unsupported_pid,
1528 { "NOT Supported PID", "obd-ii.mode01_unsupported_pid", FT_UINT8, BASE_HEX | BASE_EXT_STRING, VALS_EXT_PTR(&obdii_mode01_pid_vals_ext), 0x0, NULL, HFILL },
1530 { &hf_obdii_mode01_fuel_system1_status,
1531 { "Fuel system 1 status", "obd-ii.mode01_fuel_system1_status", FT_UINT8, BASE_HEX, VALS(obdii_fuel_system_status_vals), 0x0, NULL, HFILL },
1533 { &hf_obdii_mode01_fuel_system2_status,
1534 { "Fuel system 2 status", "obd-ii.mode01_fuel_system2_status", FT_UINT8, BASE_HEX, VALS(obdii_fuel_system_status_vals), 0x0, NULL, HFILL },
1536 { &hf_obdii_mode01_engine_load,
1537 { "Calculated engine load", "obd-ii.mode01_engine_load", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1539 { &hf_obdii_mode01_engine_coolant_temp,
1540 { "Engine coolant temperature", "obd-ii.mode01_engine_coolant_temp", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1542 { &hf_obdii_mode01_short_term_fuel_bank1,
1543 { "Short term fuel trim (Bank 1)", "obd-ii.mode01_short_term_fuel_bank1", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1545 { &hf_obdii_mode01_short_term_fuel_bank2,
1546 { "Short term fuel trim (Bank 2)", "obd-ii.mode01_short_term_fuel_bank2", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1548 { &hf_obdii_mode01_long_term_fuel_bank1,
1549 { "Long term fuel trim (Bank 1)", "obd-ii.mode01_long_term_fuel_bank1", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1551 { &hf_obdii_mode01_long_term_fuel_bank2,
1552 { "Long term fuel trim (Bank 2)", "obd-ii.mode01_long_term_fuel_bank2", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1554 { &hf_obdii_mode01_fuel_pressure,
1555 { "Fuel pressure", "obd-ii.mode01_fuel_pressure", FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL },
1557 { &hf_obdii_mode01_engine_rpm,
1558 { "Engine RPM", "obd-ii.mode01_engine_rpm", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_revolutions_per_minute), 0x0, NULL, HFILL },
1560 { &hf_obdii_mode01_vehicle_speed,
1561 { "Vehicle Speed", "obd-ii.mode01_vehicle_speed", FT_UINT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kmh), 0x0, NULL, HFILL },
1563 { &hf_obdii_mode01_timing_advance,
1564 { "Timing advance", "obd-ii.mode01_timing_advance", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_degree_btdc), 0x0, NULL, HFILL },
1566 { &hf_obdii_mode01_intake_air_temp,
1567 { "Intake air temperature", "obd-ii.mode01_intake_air_temp", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1569 { &hf_obdii_mode01_maf_air_flow_rate,
1570 { "MAF air flow rate", "obd-ii.mode01_maf_air_flow_rate", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_grams_per_second), 0x0, NULL, HFILL },
1572 { &hf_obdii_mode01_throttle_position,
1573 { "Throttle position", "obd-ii.mode01_throttle_position", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1575 { &hf_obdii_mode01_secondary_air_status,
1576 { "Commanded secondary air status", "obd-ii.mode01_secondary_air_status", FT_UINT8, BASE_HEX, VALS(obdii_secondary_air_status_vals), 0x0, NULL, HFILL },
1578 { &hf_obdii_mode01_obd_standards,
1579 { "OBD Standards", "obd-ii.mode01_obd_standards", FT_UINT8, BASE_DEC, VALS(obdii_standards_vals), 0x0, NULL, HFILL }
1581 { &hf_obdii_mode01_engine_uptime,
1582 { "Run time since engine start", "obd-ii.mode01_engine_uptime", FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL }
1584 { &hf_obdii_mode01_fuel_rail_pressure,
1585 { "Fuel Rail Pressure", "obd-ii.mode01_fuel_rail_pressure", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1587 { &hf_obdii_mode01_fuel_rail_gauge_pressure,
1588 { "Fuel Rail Gauge Pressure", "obd-ii.mode01_fuel_rail_gauge_pressure", FT_UINT24, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1590 { &hf_obdii_mode01_fuel_rail_absolute_pressure,
1591 { "Fuel rail absolute pressure", "obd-ii.mode01_fuel_rail_absolute_pressure", FT_UINT24, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1593 { &hf_obdii_mode01_commanded_egr,
1594 { "Commanded EGR", "obd-ii.mode01_commanded_egr", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL }
1596 { &hf_obdii_mode01_egr_error,
1597 { "EGR Error", "obd-ii.mode01_egr_error", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL }
1599 { &hf_obdii_mode01_commanded_evap_purge,
1600 { "Commanded evaporative purge", "obd-ii.mode01_commanded_evap_purge", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL }
1602 { &hf_obdii_mode01_fuel_tank_level_input,
1603 { "Fuel Tank Level Input", "obd-ii.mode01_fuel_tank_level_input", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL }
1605 { &hf_obdii_mode01_warm_ups,
1606 { "Warm-ups since codes cleared", "obd-ii.mode01_warm_ups", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1608 { &hf_obdii_mode01_evap_system_vapor_pressure,
1609 { "Evap. System Vapor Pressure", "obd-ii.mode01_evap_system_vapor_pressure", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1611 { &hf_obdii_mode01_absolute_barometric_pressure,
1612 { "Absolute Barometric Pressure", "obd-ii.mode01_absolute_barometric_pressure", FT_UINT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1614 { &hf_obdii_mode01_intake_manifold_absolute_pressure,
1615 { "Intake manifold absolute pressure", "obd-ii.mode01_intake_manifold_absolute_pressure", FT_UINT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1617 { &hf_obdii_mode01_oxygen_sensor_id,
1618 { "Oxygen Sensor ID", "obd-ii.mode01_oxygen_sensor_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1620 { &hf_obdii_mode01_oxygen_sensor_fuel_air_ratio,
1621 { "Fuel-Air Equivalence Ratio", "obd-ii.mode01_oxygen_sensor_fuel_air_ratio", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1623 { &hf_obdii_mode01_oxygen_sensor_voltage,
1624 { "Voltage", "obd-ii.mode01_oxygen_sensor_voltage", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_volt), 0x0, NULL, HFILL }
1626 { &hf_obdii_mode01_oxygen_sensor_current,
1627 { "Current", "obd-ii.mode01_oxygen_sensor_current", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_milliamps), 0x0, NULL, HFILL }
1629 { &hf_obdii_mode01_distance_traveled_with_mil,
1630 { "Distance traveled with MIL on", "obd-ii.mode01_distance_traveled_with_mil", FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_km), 0x0, NULL, HFILL }
1632 { &hf_obdii_mode01_distance_traveled_since_code_clear,
1633 { "Distance traveled since codes cleared", "obd-ii.mode01_distance_traveled_since_code_clear", FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_km), 0x0, NULL, HFILL }
1635 { &hf_obdii_mode01_time_run_with_mil,
1636 { "Time run with MIL on", "obd-ii.mode01_time_run_with_mil", FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_minute_minutes), 0x0, NULL, HFILL }
1638 { &hf_obdii_mode01_time_since_trouble_code_clear,
1639 { "Time since trouble codes cleared", "obd-ii.mode01_time_since_trouble_code_clear", FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_minute_minutes), 0x0, NULL, HFILL }
1641 { &hf_obdii_mode01_fuel_type,
1642 { "Fuel type", "obd-ii.mode01_fuel_type", FT_UINT8, BASE_DEC, VALS(obdii_fuel_type_coding_vals), 0x0, NULL, HFILL }
1644 { &hf_obdii_mode01_control_module_voltage,
1645 { "Control module voltage", "obd-ii.mode01_control_module_voltage", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_volt), 0x0, NULL, HFILL },
1647 { &hf_obdii_mode01_absolute_load_value,
1648 { "Absolute load value", "obd-ii.mode01_absolute_load_value", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1650 { &hf_obdii_mode01_fuel_air_commanded_equiv_ratio,
1651 { "Fuel-Air commanded equivalence ratio", "obd-ii.mode01_fuel_air_commanded_equiv_ratio", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL },
1653 { &hf_obdii_mode01_relative_throttle_position,
1654 { "Relative throttle position", "obd-ii.mode01_relative_throttle_position", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1656 { &hf_obdii_mode01_catalyst_temp_11,
1657 { "Catalyst Temperature (Bank 1, Sensor 1)", "obd-ii.mode01_catalyst_temp_11", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1659 { &hf_obdii_mode01_catalyst_temp_21,
1660 { "Catalyst Temperature (Bank 2, Sensor 1)", "obd-ii.mode01_catalyst_temp_21", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1662 { &hf_obdii_mode01_catalyst_temp_12,
1663 { "Catalyst Temperature (Bank 1, Sensor 2)", "obd-ii.mode01_catalyst_temp_12", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1665 { &hf_obdii_mode01_catalyst_temp_22,
1666 { "Catalyst Temperature (Bank 2, Sensor 2)", "obd-ii.mode01_catalyst_temp_22", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1668 { &hf_obdii_mode01_ambient_air_temp,
1669 { "Ambient air temperature", "obd-ii.mode01_ambient_air_temp", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1671 { &hf_obdii_mode01_absolute_throttle_position_B,
1672 { "Absolute throttle position B", "obd-ii.mode01_absolute_throttle_position_B", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1674 { &hf_obdii_mode01_absolute_throttle_position_C,
1675 { "Absolute throttle position C", "obd-ii.mode01_absolute_throttle_position_C", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1677 { &hf_obdii_mode01_accelerator_pedal_position_D,
1678 { "Accelerator pedal position D", "obd-ii.mode01_accelerator_pedal_position_D", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1680 { &hf_obdii_mode01_accelerator_pedal_position_E,
1681 { "Accelerator pedal position E", "obd-ii.mode01_accelerator_pedal_position_E", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1683 { &hf_obdii_mode01_accelerator_pedal_position_F,
1684 { "Accelerator pedal position F", "obd-ii.mode01_accelerator_pedal_position_F", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1686 { &hf_obdii_mode01_commanded_throttle_actuator,
1687 { "Commanded throttle actuator", "obd-ii.mode01_commanded_throttle_actuator", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1689 { &hf_obdii_mode01_ethanol_fuel,
1690 { "Ethanol fuel %", "obd-ii.mode01_ethanol_fuel", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1692 { &hf_obdii_mode01_absolute_evap_system_vapor_pressure,
1693 { "Absolute Evap system Vapor Pressure", "obd-ii.mode01_absolute_evap_system_vapor_pressure", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1695 { &hf_obdii_mode01_relative_accelerator_pedal_position,
1696 { "Relative accelerator pedal position", "obd-ii.mode01_relative_accelerator_pedal_position", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1698 { &hf_obdii_mode01_hybrid_battery_remaining_life,
1699 { "Hybrid battery pack remaining life", "obd-ii.mode01_hybrid_battery_remaining_life", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1701 { &hf_obdii_mode01_engine_oil_temp,
1702 { "Engine oil temperature", "obd-ii.mode01_engine_oil_temp", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1704 { &hf_obdii_mode01_fuel_injection_timing,
1705 { "Fuel injection timing", "obd-ii.mode01_fuel_injection_timing", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL },
1707 { &hf_obdii_mode01_engine_fuel_rate,
1708 { "Engine fuel rate", "obd-ii.mode01_engine_fuel_rate", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_liter_per_hour), 0x0, NULL, HFILL },
1710 { &hf_obdii_mode01_torque_driver_demand_engine,
1711 { "Driver's demand engine - percent torque", "obd-ii.mode01_torque_driver_demand_engine", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1713 { &hf_obdii_mode01_torque_actual_engine,
1714 { "Actual engine - percent torque", "obd-ii.mode01_torque_actual_engine", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1716 { &hf_obdii_mode01_torque_reference_engine,
1717 { "Engine reference torque", "obd-ii.mode01_torque_reference_engine", FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_newton_metre), 0x0, NULL, HFILL },
1719 { &hf_obdii_mode09_pid,
1720 { "PID", "obd-ii.mode09_pid", FT_UINT16, BASE_HEX | BASE_EXT_STRING, VALS_EXT_PTR(&obdii_mode09_pid_vals_ext), 0x0, NULL, HFILL },
1722 { &hf_obdii_mode09_supported_pid,
1723 { "Supported PID", "obd-ii.mode09_supported_pid", FT_UINT8, BASE_HEX | BASE_EXT_STRING, VALS_EXT_PTR(&obdii_mode09_pid_vals_ext), 0x0, NULL, HFILL },
1725 { &hf_obdii_mode09_unsupported_pid,
1726 { "NOT Supported PID", "obd-ii.mode09_unsupported_pid", FT_UINT8, BASE_HEX | BASE_EXT_STRING, VALS_EXT_PTR(&obdii_mode09_pid_vals_ext), 0x0, NULL, HFILL },
1728 { &hf_obdii_vin,
1729 { "VIN", "obd-ii.VIN", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL },
1731 { &hf_obdii_ecu_name,
1732 { "ECU Name", "obd-ii.ecu_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL },
1736 static int *ett[] = {
1737 &ett_obdii
1740 struct expert_module *expert_obdii;
1742 static ei_register_info obdii_ei[] =
1744 { &ei_obdii_padding,
1745 { "obdii.padding", PI_PROTOCOL, PI_WARN, "OBD2 Spec requires 8 byte, zero padded frames. Some tools/ecus may ignore frames that don't follow this rule.", EXPFILL }},
1748 proto_obdii = proto_register_protocol("OBD-II PID", "OBD-II", "obd-ii");
1749 proto_register_field_array(proto_obdii, hf, array_length(hf));
1750 proto_register_subtree_array(ett, array_length(ett));
1752 expert_obdii = expert_register_protocol(proto_obdii);
1753 expert_register_field_array(expert_obdii, obdii_ei, array_length(obdii_ei));
1755 obdii_handle = register_dissector("obd-ii", dissect_obdii_iso15765, proto_obdii);
1756 register_dissector("obd-ii-uds", dissect_obdii_uds, proto_obdii);
1759 void
1760 proto_reg_handoff_obdii(void)
1762 dissector_add_for_decode_as("iso15765.subdissector", obdii_handle);
1764 /* heuristics default off since these standardized IDs might be reused outside automotive systems */
1765 heur_dissector_add("can", dissect_obdii_heur, "OBD-II Heuristic", "obd-ii_can_heur", proto_obdii, HEURISTIC_DISABLE);
1769 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1771 * Local variables:
1772 * c-basic-offset: 8
1773 * tab-width: 8
1774 * indent-tabs-mode: t
1775 * End:
1777 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1778 * :indentSize=8:tabSize=8:noTabs=false: