Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-obd-ii.c
Line
Count
Source
1
/* packet-obd-ii.c
2
 * Routines for OBD-II PIDs dissection
3
 *
4
 * Based on https://en.wikipedia.org/wiki/OBD-II_PIDs
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
#include <epan/packet.h>
16
#include <epan/proto.h>
17
#include <epan/unit_strings.h>
18
#include <expert.h>
19
20
#include <wsutil/utf8_entities.h>
21
22
#include "packet-socketcan.h"
23
#include "packet-iso15765.h"
24
25
void proto_register_obdii(void);
26
void proto_reg_handoff_obdii(void);
27
28
static dissector_handle_t obdii_handle;
29
30
static int proto_obdii;
31
32
static int ett_obdii;
33
34
static int hf_obdii_mode;
35
static int hf_obdii_raw_value;
36
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;
103
104
static int hf_obdii_mode09_pid;
105
static int hf_obdii_mode09_supported_pid;
106
static int hf_obdii_mode09_unsupported_pid;
107
108
static int hf_obdii_vin;
109
static int hf_obdii_ecu_name;
110
111
static expert_field ei_obdii_padding;
112
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
117
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
122
123
   The following defines set up bit patterns and masks to determine both query and responses.
124
*/
125
0
#define ODBII_CAN_QUERY_ID_SFF               0x7DF
126
0
#define ODBII_CAN_RESPONSE_ID_LOWER_MIN_SFF  0x7E0
127
0
#define ODBII_CAN_RESPONSE_ID_UPPER_MIN_SFF  0x7E8
128
0
#define ODBII_CAN_RESPONSE_ID_LOWER_MASK_SFF 0x7
129
0
#define ODBII_CAN_RESPONSE_ID_UPPER_MASK_SFF 0x7
130
131
0
#define ODBII_CAN_QUERY_ID_EFF               0x18DB33F1
132
0
#define ODBII_CAN_RESPONSE_ID_LOWER_MIN_EFF  0x18DA00F1
133
0
#define ODBII_CAN_RESPONSE_ID_UPPER_MIN_EFF  0x18DAF100
134
0
#define ODBII_CAN_RESPONSE_ID_LOWER_MASK_EFF 0xFF00
135
0
#define ODBII_CAN_RESPONSE_ID_UPPER_MASK_EFF 0x00FF
136
137
48
#define OBDII_MODE_POS  0x00
138
34
#define OBDII_PID_POS   0x01
139
146
#define OBDII_VAL_OFF   0x02
140
1
#define OBDII_MODE07_DATA_OFF 0x01
141
142
0
#define OBDII_MODE01_PIDS_SUPPORT00         0x00
143
#define OBDII_MODE01_MONITOR_STATUS         0x01
144
#define OBDII_MODE01_FREEZE_DTC             0x02
145
0
#define OBDII_MODE01_FUEL_SYSTEM_STATUS     0x03
146
0
#define OBDII_MODE01_ENGINE_LOAD            0x04
147
0
#define OBDII_MODE01_ENGINE_COOLANT_TEMP    0x05
148
0
#define OBDII_MODE01_SHORT_TERM_FUEL_BANK1  0x06
149
0
#define OBDII_MODE01_LONG_TERM_FUEL_BANK1   0x07
150
0
#define OBDII_MODE01_SHORT_TERM_FUEL_BANK2  0x08
151
0
#define OBDII_MODE01_LONG_TERM_FUEL_BANK2   0x09
152
0
#define OBDII_MODE01_FUEL_PRESSURE          0x0A
153
0
#define OBDII_MODE01_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE 0x0B
154
0
#define OBDII_MODE01_ENGINE_RPM             0x0C
155
1
#define OBDII_MODE01_VEHICLE_SPEED          0x0D
156
0
#define OBDII_MODE01_TIMING_ADVANCE         0x0E
157
0
#define OBDII_MODE01_INTAKE_AIR_TEMP        0x0F
158
0
#define OBDII_MODE01_MAF_AIR_FLOW_RATE      0x10
159
0
#define OBDII_MODE01_THROTTLE_POSITION      0x11
160
1
#define OBDII_MODE01_SECONDARY_AIR_STATUS   0x12
161
0
#define OBDII_MODE01_OXYGEN_SENSOR_PRESET2  0x13
162
0
#define OBDII_MODE01_OXYGEN_SENSOR1         0x14
163
0
#define OBDII_MODE01_OXYGEN_SENSOR2         0x15
164
1
#define OBDII_MODE01_OXYGEN_SENSOR3         0x16
165
1
#define OBDII_MODE01_OXYGEN_SENSOR4         0x17
166
1
#define OBDII_MODE01_OXYGEN_SENSOR5         0x18
167
1
#define OBDII_MODE01_OXYGEN_SENSOR6         0x19
168
1
#define OBDII_MODE01_OXYGEN_SENSOR7         0x1A
169
2
#define OBDII_MODE01_OXYGEN_SENSOR8         0x1B
170
0
#define OBDII_MODE01_OBD_STANDARDS          0x1C
171
0
#define OBDII_MODE01_OXYGEN_SENSOR_PRESET4  0x1D
172
#define OBDII_MODE01_AUX_INPUT_STATUS       0x1E
173
0
#define OBDII_MODE01_ENGINE_UPTIME          0x1F
174
175
0
#define OBDII_MODE01_PIDS_SUPPORT20             0x20
176
0
#define OBDII_MODE01_DISTANCE_TRAVELED_WITH_MIL 0x21
177
0
#define OBDII_MODE01_FUEL_RAIL_PRESSURE         0x22
178
1
#define OBDII_MODE01_FUEL_RAIL_GAUGE_PRESSURE   0x23
179
0
#define OBDII_MODE01_OXYGEN_SENSOR1_            0x24
180
0
#define OBDII_MODE01_OXYGEN_SENSOR2_            0x25
181
0
#define OBDII_MODE01_OXYGEN_SENSOR3_            0x26
182
0
#define OBDII_MODE01_OXYGEN_SENSOR4_            0x27
183
0
#define OBDII_MODE01_OXYGEN_SENSOR5_            0x28
184
0
#define OBDII_MODE01_OXYGEN_SENSOR6_            0x29
185
0
#define OBDII_MODE01_OXYGEN_SENSOR7_            0x2A
186
1
#define OBDII_MODE01_OXYGEN_SENSOR8_            0x2B
187
0
#define OBDII_MODE01_COMMANDED_EGR              0x2C
188
1
#define OBDII_MODE01_EGR_ERROR                  0x2D
189
0
#define OBDII_MODE01_COMMANDED_EVAP_PURGE       0x2E
190
0
#define OBDII_MODE01_FUEL_TANK_LEVEL            0x2F
191
0
#define OBDII_MODE01_WARM_UPS_SINCE_CLEAR       0x30
192
0
#define OBDII_MODE01_DISTANCE_TRAVELED_SINCE_CODES_CLEAR 0x31
193
0
#define OBDII_MODE01_EVAP_SYSTEM_VAPOR_PRESSURE   0x32
194
0
#define OBDII_MODE01_ABSOLUTE_BAROMETRIC_PRESSURE 0x33
195
0
#define OBDII_MODE01_OXYGEN_SENSOR1_A       0x34
196
0
#define OBDII_MODE01_OXYGEN_SENSOR2_A       0x35
197
0
#define OBDII_MODE01_OXYGEN_SENSOR3_A       0x36
198
0
#define OBDII_MODE01_OXYGEN_SENSOR4_A       0x37
199
0
#define OBDII_MODE01_OXYGEN_SENSOR5_A       0x38
200
0
#define OBDII_MODE01_OXYGEN_SENSOR6_A       0x39
201
0
#define OBDII_MODE01_OXYGEN_SENSOR7_A       0x3A
202
0
#define OBDII_MODE01_OXYGEN_SENSOR8_A       0x3B
203
0
#define OBDII_MODE01_CATALYST_TEMP11        0x3C
204
1
#define OBDII_MODE01_CATALYST_TEMP21        0x3D
205
1
#define OBDII_MODE01_CATALYST_TEMP12        0x3E
206
1
#define OBDII_MODE01_CATALYST_TEMP22        0x3F
207
208
0
#define OBDII_MODE01_PIDS_SUPPORT40                 0x40
209
0
#define OBDII_MODE01_CONTROL_MODULE_VOLTAGE         0x42
210
0
#define OBDII_MODE01_ABSOLUTE_LOAD_VALUE            0x43
211
0
#define OBDII_MODE01_FUEL_AIR_COMMANDED_EQUIV_RATIO 0x44
212
0
#define OBDII_MODE01_RELATIVE_THROTTLE_POSITION     0x45
213
0
#define OBDII_MODE01_AMBIENT_AIR_TEMP               0x46
214
0
#define OBDII_MODE01_ABSOLUTE_THROTTLE_POSITION_B   0x47
215
0
#define OBDII_MODE01_ABSOLUTE_THROTTLE_POSITION_C   0x48
216
1
#define OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_D   0x49
217
0
#define OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_E   0x4A
218
0
#define OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_F   0x4B
219
0
#define OBDII_MODE01_COMMANDED_THROTTLE_ACTUATOR    0x4C
220
1
#define OBDII_MODE01_TIME_RUN_WITH_MIL              0x4D
221
0
#define OBDII_MODE01_TIME_SINCE_TROUBLE_CODES_CLEAR 0x4E
222
0
#define OBDII_MODE01_FUEL_TYPE                      0x51
223
0
#define OBDII_MODE01_ETHANOL_FUEL                   0x52
224
1
#define OBDII_MODE01_ABSOLUTE_EVAP_SYSTEM_VAPOR_PRESSURE 0x53
225
0
#define OBDII_MODE01_SHORT_TERM_OXYGEN_BANK13       0x55
226
0
#define OBDII_MODE01_LONG_TERM_OXYGEN_BANK13        0x56
227
0
#define OBDII_MODE01_SHORT_TERM_OXYGEN_BANK24       0x57
228
0
#define OBDII_MODE01_LONG_TERM_OXYGEN_BANK24        0x58
229
0
#define OBDII_MODE01_FUEL_RAIL_ABSOLUTE_PRESSURE    0x59
230
0
#define OBDII_MODE01_RELATIVE_ACCELERATOR_PEDAL_POSITION 0x5A
231
1
#define OBDII_MODE01_HYBRID_BATTERY_REMAINING_LIFE  0x5B
232
0
#define OBDII_MODE01_ENGINE_OIL_TEMP                0x5C
233
0
#define OBDII_MODE01_FUEL_INJECTION_TIMING          0x5D
234
0
#define OBDII_MODE01_ENGINE_FUEL_RATE               0x5E
235
236
0
#define OBDII_MODE01_PIDS_SUPPORT60              0x60
237
1
#define OBDII_MODE01_TORQUE_DRIVER_DEMAND_ENGINE 0x61
238
0
#define OBDII_MODE01_TORQUE_ACTUAL_ENGINE        0x62
239
0
#define OBDII_MODE01_TORQUE_REFERENCE_ENGINE     0x63
240
241
0
#define OBDII_MODE01_PIDS_SUPPORT80         0x80
242
0
#define OBDII_MODE01_PIDS_SUPPORTA0         0xA0
243
0
#define OBDII_MODE01_PIDS_SUPPORTC0         0xC0
244
245
0
#define OBDII_MODE09_PIDS_SUPPORT00       0x00
246
0
#define OBDII_MODE09_VIN02                0x02
247
0
#define OBDII_MODE09_CALIBRATION_ID04     0x04
248
0
#define OBDII_MODE09_CAL_VER_NUMBERS06    0x06
249
0
#define OBDII_MODE09_PERFORMANCE_SPARK08  0x08
250
0
#define OBDII_MODE09_ECU_NAME0A           0x0A
251
0
#define OBDII_MODE09_PERFORMANCE_COMPRESSION0B 0x0B
252
253
/* unit_name_string for OBDII_MODE01_TIMING_ADVANCE */
254
static const unit_name_string units_degree_btdc = { UTF8_DEGREE_SIGN "BTDC", NULL };
255
256
/* value_string[] for OBDII_MODE01_FUEL_SYSTEM_STATUS */
257
static const value_string obdii_fuel_system_status_vals[] =
258
{
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 }
265
};
266
267
/* value_string[] for OBDII_MODE01_SECONDARY_AIR_STATUS */
268
static const value_string obdii_secondary_air_status_vals[] =
269
{
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 }
275
};
276
277
/* value_string[] for OBDII_MODE01_OBD_STANDARDS */
278
static const value_string obdii_standards_vals[] =
279
{
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}
316
};
317
318
/* value_string[] for OBDII_MODE01_FUEL_TYPE */
319
static const value_string obdii_fuel_type_coding_vals[] =
320
{
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 }
346
};
347
348
static const value_string obdii_mode01_pid_vals[] =
349
{
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" },
382
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)" },
415
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" },
448
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" },
481
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" },
490
491
  { OBDII_MODE01_PIDS_SUPPORTA0, "PIDs supported [A1 - C0]" },
492
493
  { OBDII_MODE01_PIDS_SUPPORTC0, "PIDs supported [C1 - E0]" },
494
495
  { 0x00, NULL }
496
};
497
498
static value_string_ext obdii_mode01_pid_vals_ext = VALUE_STRING_EXT_INIT(obdii_mode01_pid_vals);
499
500
static const value_string obdii_mode09_pid_vals[] =
501
{
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 }
510
};
511
512
static value_string_ext obdii_mode09_pid_vals_ext = VALUE_STRING_EXT_INIT(obdii_mode09_pid_vals);
513
514
static const value_string obdii_mode_vals[] =
515
{
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 }
527
};
528
529
struct obdii_packet_info
530
{
531
  packet_info *pinfo;
532
  uint32_t can_id;
533
534
  uint8_t data_bytes;
535
  uint8_t mode;
536
537
  uint8_t value_bytes;
538
  int value_offset;
539
  uint8_t valueA, valueB, valueC, valueD, valueE;
540
};
541
542
static bool
543
dissect_obdii_common_temperature(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
544
0
{
545
0
  if (oinfo->value_bytes == 1)
546
0
  {
547
0
    int16_t val = ((int) oinfo->valueA) - 40;
548
549
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %d " UTF8_DEGREE_SIGN "C", val);
550
0
    proto_tree_add_int(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
551
0
    return true;
552
0
  }
553
554
0
  return false;
555
0
}
556
557
static bool
558
dissect_obdii_common_percent(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
559
2
{
560
2
  if (oinfo->value_bytes == 1)
561
0
  {
562
0
    double val = (100 * oinfo->valueA) / 255.0;
563
564
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f %%", val);
565
0
    proto_tree_add_double(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
566
0
    return true;
567
0
  }
568
569
2
  return false;
570
2
}
571
572
static bool
573
dissect_obdii_common_percent_neg(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
574
1
{
575
1
  if (oinfo->value_bytes == 1)
576
0
  {
577
0
    double val = ((100 * oinfo->valueA) / 128.0) - 100.0;
578
579
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f %%", val);
580
0
    proto_tree_add_double(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
581
0
    return true;
582
0
  }
583
584
1
  return false;
585
1
}
586
587
static bool
588
dissect_obdii_common_fuel_rail_pressure(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
589
1
{
590
1
  if (oinfo->value_bytes == 2)
591
0
  {
592
0
    unsigned val = 10 * (256 * oinfo->valueA + oinfo->valueB);
593
594
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u kPa", val);
595
0
    proto_tree_add_uint(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
596
0
    return true;
597
0
  }
598
599
1
  return false;
600
1
}
601
602
static bool
603
dissect_obdii_common_absolute_pressure(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
604
0
{
605
0
  if (oinfo->value_bytes == 1)
606
0
  {
607
0
    uint8_t val = oinfo->valueA;
608
609
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u kPa", val);
610
0
    proto_tree_add_uint(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
611
0
    return true;
612
0
  }
613
614
0
  return false;
615
0
}
616
617
static bool
618
dissect_obdii_common_distance_travelled(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
619
0
{
620
0
  if (oinfo->value_bytes == 2)
621
0
  {
622
0
    uint16_t val = 256 * oinfo->valueA + oinfo->valueB;
623
624
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u km", val);
625
0
    proto_tree_add_uint(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
626
0
    return true;
627
0
  }
628
629
0
  return false;
630
0
}
631
632
static bool
633
dissect_obdii_common_time(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
634
1
{
635
1
  if (oinfo->value_bytes == 2)
636
0
  {
637
0
    uint16_t val = 256 * oinfo->valueA + oinfo->valueB;
638
639
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u minutes", val);
640
0
    proto_tree_add_uint(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
641
0
    return true;
642
0
  }
643
644
1
  return false;
645
1
}
646
647
static bool
648
dissect_obdii_common_torque(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree, int hf_field)
649
1
{
650
1
  if (oinfo->value_bytes == 1)
651
0
  {
652
0
    int val = ((int) oinfo->valueA) - 125;
653
654
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %d %%", val);
655
0
    proto_tree_add_int(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
656
0
    return true;
657
0
  }
658
659
1
  return false;
660
1
}
661
662
static void
663
dissect_obdii_mode_01(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree)
664
15
{
665
15
  uint8_t pid = tvb_get_uint8(tvb, OBDII_PID_POS);
666
15
  int value_offset;
667
15
  bool handled = false;
668
669
15
  col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, "- %s", val_to_str_ext(oinfo->pinfo->pool, pid, &obdii_mode01_pid_vals_ext, "Unknown (%.2x)"));
670
15
  proto_tree_add_uint(tree, hf_obdii_mode01_pid, tvb, OBDII_PID_POS, 1, pid);
671
672
15
  proto_tree_add_item(tree, hf_obdii_raw_value, tvb, OBDII_VAL_OFF, MIN(oinfo->value_bytes, 4), ENC_NA);
673
674
15
  value_offset = OBDII_VAL_OFF;
675
15
  oinfo->value_offset = value_offset;
676
677
  /* https://en.wikipedia.org/wiki/OBD-II_PIDs#Mode_01 */
678
15
  switch (pid)
679
15
  {
680
0
  case OBDII_MODE01_PIDS_SUPPORT00:
681
0
  case OBDII_MODE01_PIDS_SUPPORT20:
682
0
  case OBDII_MODE01_PIDS_SUPPORT40:
683
0
  case OBDII_MODE01_PIDS_SUPPORT60:
684
0
  case OBDII_MODE01_PIDS_SUPPORT80:
685
0
  case OBDII_MODE01_PIDS_SUPPORTA0:
686
0
  case OBDII_MODE01_PIDS_SUPPORTC0:
687
0
    if ((handled = (oinfo->value_bytes == 4)))
688
0
    {
689
0
      uint32_t val = ((oinfo->valueA << 24) | (oinfo->valueB << 16) | (oinfo->valueC << 8) | (oinfo->valueD << 0));
690
0
      int i;
691
0
      const char *sepa;
692
0
      char bits_str[33];
693
694
0
      sepa = ": ";
695
0
      for (i = 31; i >= 0; i--)
696
0
      {
697
0
        unsigned this_pid = (pid + 32 - i);
698
0
        proto_item *ti;
699
700
0
        memset(bits_str, '.', 32);
701
0
        bits_str[32] = '\0';
702
703
0
        if ((val & (1U << i)))
704
0
        {
705
0
          col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, "%s%.2X", sepa, this_pid);
706
0
          ti = proto_tree_add_uint(tree, hf_obdii_mode01_supported_pid, tvb, value_offset, oinfo->value_bytes, this_pid);
707
0
          sepa = ",";
708
0
          bits_str[31 - i] = '1';
709
0
        }
710
0
        else
711
0
        {
712
0
          ti = proto_tree_add_uint(tree, hf_obdii_mode01_unsupported_pid, tvb, value_offset, oinfo->value_bytes, this_pid);
713
0
          bits_str[31 - i] = '0';
714
0
        }
715
716
0
        proto_item_prepend_text(ti, "%s = ", bits_str);
717
0
      }
718
0
    }
719
0
    break;
720
721
0
  case OBDII_MODE01_FUEL_SYSTEM_STATUS:
722
0
    if ((handled = (oinfo->value_bytes == 2)))
723
0
    {
724
0
      uint8_t fuel_system1_val = oinfo->valueA;
725
0
      uint8_t fuel_system2_val = oinfo->valueB;
726
727
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": System 1: %s", val_to_str(oinfo->pinfo->pool, fuel_system1_val, obdii_fuel_system_status_vals, "Unknown (%.2X)"));
728
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", System 2: %s", val_to_str(oinfo->pinfo->pool, fuel_system2_val, obdii_fuel_system_status_vals, "Unknown (%.2X)"));
729
730
0
      proto_tree_add_uint(tree, hf_obdii_mode01_fuel_system1_status, tvb, value_offset + 0, 1, fuel_system1_val);
731
0
      proto_tree_add_uint(tree, hf_obdii_mode01_fuel_system2_status, tvb, value_offset + 1, 1, fuel_system2_val);
732
0
    }
733
0
    break;
734
735
0
  case OBDII_MODE01_ENGINE_LOAD:
736
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_engine_load);
737
0
    break;
738
739
0
  case OBDII_MODE01_ENGINE_COOLANT_TEMP:
740
0
    handled = dissect_obdii_common_temperature(tvb, oinfo, tree, hf_obdii_mode01_engine_coolant_temp);
741
0
    break;
742
743
0
  case OBDII_MODE01_SHORT_TERM_FUEL_BANK1:
744
0
    handled = dissect_obdii_common_percent_neg(tvb, oinfo, tree, hf_obdii_mode01_short_term_fuel_bank1);
745
0
    break;
746
747
0
  case OBDII_MODE01_LONG_TERM_FUEL_BANK1:
748
0
    handled = dissect_obdii_common_percent_neg(tvb, oinfo, tree, hf_obdii_mode01_long_term_fuel_bank1);
749
0
    break;
750
751
0
  case OBDII_MODE01_SHORT_TERM_FUEL_BANK2:
752
0
    handled = dissect_obdii_common_percent_neg(tvb, oinfo, tree, hf_obdii_mode01_short_term_fuel_bank2);
753
0
    break;
754
755
0
  case OBDII_MODE01_LONG_TERM_FUEL_BANK2:
756
0
    handled = dissect_obdii_common_percent_neg(tvb, oinfo, tree, hf_obdii_mode01_long_term_fuel_bank2);
757
0
    break;
758
759
0
  case OBDII_MODE01_FUEL_PRESSURE:
760
0
    if ((handled = (oinfo->value_bytes == 1)))
761
0
    {
762
0
      uint16_t val = 3 * oinfo->valueA;
763
764
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u kPa", val);
765
0
      proto_tree_add_uint(tree, hf_obdii_mode01_fuel_pressure, tvb, value_offset, oinfo->value_bytes, val);
766
0
    }
767
0
    break;
768
769
0
  case OBDII_MODE01_ENGINE_RPM:
770
0
    if ((handled = (oinfo->value_bytes == 2)))
771
0
    {
772
0
      double val = (256 * oinfo->valueA + oinfo->valueB) / 4.0;
773
774
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f rpm", val);
775
0
      proto_tree_add_double(tree, hf_obdii_mode01_engine_rpm, tvb, value_offset, oinfo->value_bytes, val);
776
0
    }
777
0
    break;
778
779
1
  case OBDII_MODE01_VEHICLE_SPEED:
780
1
    if ((handled = (oinfo->value_bytes == 1)))
781
0
    {
782
0
      uint8_t val = oinfo->valueA;
783
784
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u km/h", val);
785
0
      proto_tree_add_uint(tree, hf_obdii_mode01_vehicle_speed, tvb, value_offset, oinfo->value_bytes, val);
786
0
    }
787
1
    break;
788
789
0
  case OBDII_MODE01_TIMING_ADVANCE:
790
0
    if ((handled = (oinfo->value_bytes == 1)))
791
0
    {
792
0
      double val = (oinfo->valueA - 128) / 2.0;
793
794
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f " UTF8_DEGREE_SIGN "BTDC", val);
795
0
      proto_tree_add_double(tree, hf_obdii_mode01_timing_advance, tvb, value_offset, oinfo->value_bytes, val);
796
0
    }
797
0
    break;
798
799
0
  case OBDII_MODE01_INTAKE_AIR_TEMP:
800
0
    handled = dissect_obdii_common_temperature(tvb, oinfo, tree, hf_obdii_mode01_intake_air_temp);
801
0
    break;
802
803
0
  case OBDII_MODE01_MAF_AIR_FLOW_RATE:
804
0
    if ((handled = (oinfo->value_bytes == 2)))
805
0
    {
806
0
      double val = (256 * oinfo->valueA + oinfo->valueB) / 100.0;
807
808
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f g/s", val);
809
0
      proto_tree_add_double(tree, hf_obdii_mode01_maf_air_flow_rate, tvb, value_offset, oinfo->value_bytes, val);
810
0
    }
811
0
    break;
812
813
0
  case OBDII_MODE01_THROTTLE_POSITION:
814
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_throttle_position);
815
0
    break;
816
817
1
  case OBDII_MODE01_SECONDARY_AIR_STATUS:
818
1
    if ((handled = (oinfo->value_bytes == 1)))
819
0
    {
820
0
      uint8_t air_status = oinfo->valueA;
821
822
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %s", val_to_str(oinfo->pinfo->pool, air_status, obdii_secondary_air_status_vals, "Unknown (%.2X)"));
823
0
      proto_tree_add_uint(tree, hf_obdii_mode01_secondary_air_status, tvb, value_offset, oinfo->value_bytes, air_status);
824
0
    }
825
1
    break;
826
827
0
  case OBDII_MODE01_OXYGEN_SENSOR_PRESET2:
828
0
    if ((handled = (oinfo->value_bytes == 1)))
829
0
    {
830
0
      uint8_t bank1_sensor1 = (oinfo->valueA & (1 << 0));
831
0
      uint8_t bank1_sensor2 = (oinfo->valueA & (1 << 1));
832
0
      uint8_t bank1_sensor3 = (oinfo->valueA & (1 << 2));
833
0
      uint8_t bank1_sensor4 = (oinfo->valueA & (1 << 3));
834
0
      uint8_t bank2_sensor1 = (oinfo->valueA & (1 << 4));
835
0
      uint8_t bank2_sensor2 = (oinfo->valueA & (1 << 5));
836
0
      uint8_t bank2_sensor3 = (oinfo->valueA & (1 << 6));
837
0
      uint8_t bank2_sensor4 = (oinfo->valueA & (1 << 7));
838
839
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": Bank1 sensors: %s%s%s%s%s",
840
0
        bank1_sensor1 ? "1 " : "", bank1_sensor2 ? "2 " : "", bank1_sensor3 ? "3 " : "", bank1_sensor4 ? "4 " : "",
841
0
        ((bank1_sensor1 | bank1_sensor2 | bank1_sensor3 | bank1_sensor4)) ? "" : "None");
842
843
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Bank2 sensors: %s%s%s%s%s",
844
0
        bank2_sensor1 ? "1 " : "", bank2_sensor2 ? "2 " : "", bank2_sensor3 ? "3 " : "", bank2_sensor4 ? "4 " : "",
845
0
        ((bank2_sensor1 | bank2_sensor2 | bank2_sensor3 | bank2_sensor4)) ? "" : "None");
846
847
      /* TODO: proto tree */
848
0
    }
849
0
    break;
850
851
0
  case OBDII_MODE01_OXYGEN_SENSOR_PRESET4:
852
0
    if ((handled = (oinfo->value_bytes == 1)))
853
0
    {
854
0
      uint8_t bank1_sensor1 = (oinfo->valueA & (1 << 0));
855
0
      uint8_t bank1_sensor2 = (oinfo->valueA & (1 << 1));
856
0
      uint8_t bank2_sensor1 = (oinfo->valueA & (1 << 2));
857
0
      uint8_t bank2_sensor2 = (oinfo->valueA & (1 << 3));
858
0
      uint8_t bank3_sensor1 = (oinfo->valueA & (1 << 4));
859
0
      uint8_t bank3_sensor2 = (oinfo->valueA & (1 << 5));
860
0
      uint8_t bank4_sensor1 = (oinfo->valueA & (1 << 6));
861
0
      uint8_t bank4_sensor2 = (oinfo->valueA & (1 << 7));
862
863
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": Bank1 sensors: %s%s%s",
864
0
        bank1_sensor1 ? "1 " : "", bank1_sensor2 ? "2 " : "",
865
0
        ((bank1_sensor1 | bank1_sensor2)) ? "" : "None");
866
867
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Bank2 sensors: %s%s%s",
868
0
        bank2_sensor1 ? "1 " : "", bank2_sensor2 ? "2 " : "",
869
0
        ((bank2_sensor1 | bank2_sensor2)) ? "" : "None");
870
871
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Bank3 sensors: %s%s%s",
872
0
        bank3_sensor1 ? "1 " : "", bank3_sensor2 ? "2 " : "",
873
0
        ((bank3_sensor1 | bank3_sensor2)) ? "" : "None");
874
875
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Bank4 sensors: %s%s%s",
876
0
        bank4_sensor1 ? "1 " : "", bank4_sensor2 ? "2 " : "",
877
0
        ((bank4_sensor1 | bank4_sensor2)) ? "" : "None");
878
879
      /* TODO: proto tree */
880
0
    }
881
0
    break;
882
883
0
  case OBDII_MODE01_OXYGEN_SENSOR1:
884
0
  case OBDII_MODE01_OXYGEN_SENSOR2:
885
1
  case OBDII_MODE01_OXYGEN_SENSOR3:
886
1
  case OBDII_MODE01_OXYGEN_SENSOR4:
887
1
  case OBDII_MODE01_OXYGEN_SENSOR5:
888
1
  case OBDII_MODE01_OXYGEN_SENSOR6:
889
1
  case OBDII_MODE01_OXYGEN_SENSOR7:
890
2
  case OBDII_MODE01_OXYGEN_SENSOR8:
891
2
    if ((handled = (oinfo->value_bytes == 2)))
892
0
    {
893
0
      double volt_val  = (oinfo->valueA) / 200.0;
894
0
      double fuel_trim = ((100.0 * oinfo->valueB) / 128.0) - 100.0;
895
896
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": Voltage: %.3f V", volt_val);
897
0
      if (oinfo->valueB != 0xFF)
898
0
        col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Short term fuel trim: %.2f %%", fuel_trim);
899
900
0
      proto_tree_add_uint(tree, hf_obdii_mode01_oxygen_sensor_id, tvb, value_offset, oinfo->value_bytes, 1 + (pid - OBDII_MODE01_OXYGEN_SENSOR1));
901
0
      proto_tree_add_double(tree, hf_obdii_mode01_oxygen_sensor_voltage, tvb, value_offset, 1, volt_val);
902
      /* TODO: proto_tree */
903
0
    }
904
2
    break;
905
906
0
  case OBDII_MODE01_OBD_STANDARDS:
907
0
    if ((handled = (oinfo->value_bytes == 1)))
908
0
    {
909
0
      uint8_t val = oinfo->valueA;
910
911
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %s", val_to_str(oinfo->pinfo->pool, val, obdii_standards_vals, "Unknown (%u)"));
912
0
      proto_tree_add_uint(tree, hf_obdii_mode01_obd_standards, tvb, value_offset, oinfo->value_bytes, val);
913
0
    }
914
0
    break;
915
916
0
  case OBDII_MODE01_ENGINE_UPTIME:
917
0
    if ((handled = (oinfo->value_bytes == 2)))
918
0
    {
919
0
      uint16_t val = 256 * oinfo->valueA + oinfo->valueB;
920
921
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u s", val);
922
0
      proto_tree_add_uint(tree, hf_obdii_mode01_engine_uptime, tvb, value_offset, oinfo->value_bytes, val);
923
0
    }
924
0
    break;
925
926
0
  case OBDII_MODE01_FUEL_RAIL_PRESSURE:
927
0
    if ((handled = (oinfo->value_bytes == 2)))
928
0
    {
929
0
      double val = 0.079 * (256 * oinfo->valueA + oinfo->valueB);
930
931
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f kPa", val);
932
0
      proto_tree_add_double(tree, hf_obdii_mode01_fuel_rail_pressure, tvb, value_offset, oinfo->value_bytes, val);
933
0
    }
934
0
    break;
935
936
1
  case OBDII_MODE01_FUEL_RAIL_GAUGE_PRESSURE:
937
1
    handled = dissect_obdii_common_fuel_rail_pressure(tvb, oinfo, tree, hf_obdii_mode01_fuel_rail_gauge_pressure);
938
1
    break;
939
940
0
  case OBDII_MODE01_FUEL_RAIL_ABSOLUTE_PRESSURE:
941
0
    handled = dissect_obdii_common_fuel_rail_pressure(tvb, oinfo, tree, hf_obdii_mode01_fuel_rail_absolute_pressure);
942
0
    break;
943
944
0
  case OBDII_MODE01_OXYGEN_SENSOR1_:
945
0
  case OBDII_MODE01_OXYGEN_SENSOR2_:
946
0
  case OBDII_MODE01_OXYGEN_SENSOR3_:
947
0
  case OBDII_MODE01_OXYGEN_SENSOR4_:
948
0
  case OBDII_MODE01_OXYGEN_SENSOR5_:
949
0
  case OBDII_MODE01_OXYGEN_SENSOR6_:
950
0
  case OBDII_MODE01_OXYGEN_SENSOR7_:
951
1
  case OBDII_MODE01_OXYGEN_SENSOR8_:
952
1
    if ((handled = (oinfo->value_bytes == 4)))
953
0
    {
954
0
      double fuel_air_ratio = (256 * oinfo->valueA + oinfo->valueB) * (2.0 / 65536.0);
955
0
      double volt_val       = (256 * oinfo->valueC + oinfo->valueD) * (8.0 / 65536.0);
956
957
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": Fuel-Air Equivalence: %.4f ratio", fuel_air_ratio);
958
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Voltage: %.4f V", volt_val);
959
960
0
      proto_tree_add_uint(tree, hf_obdii_mode01_oxygen_sensor_id, tvb, value_offset, oinfo->value_bytes, 1 + (pid - OBDII_MODE01_OXYGEN_SENSOR1_));
961
0
      proto_tree_add_double(tree, hf_obdii_mode01_oxygen_sensor_fuel_air_ratio, tvb, value_offset, 2, fuel_air_ratio);
962
0
      proto_tree_add_double(tree, hf_obdii_mode01_oxygen_sensor_voltage, tvb, value_offset + 2, 2, volt_val);
963
0
    }
964
1
    break;
965
966
0
  case OBDII_MODE01_COMMANDED_EGR:
967
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_commanded_egr);
968
0
    break;
969
970
1
  case OBDII_MODE01_EGR_ERROR:
971
1
    handled = dissect_obdii_common_percent_neg(tvb, oinfo, tree, hf_obdii_mode01_egr_error);
972
1
    break;
973
974
0
  case OBDII_MODE01_COMMANDED_EVAP_PURGE:
975
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_commanded_evap_purge);
976
0
    break;
977
978
0
  case OBDII_MODE01_FUEL_TANK_LEVEL:
979
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_fuel_tank_level_input);
980
0
    break;
981
982
0
  case OBDII_MODE01_WARM_UPS_SINCE_CLEAR:
983
0
    if ((handled = (oinfo->value_bytes == 1)))
984
0
    {
985
0
      uint8_t val = oinfo->valueA;
986
987
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u", val);
988
0
      proto_tree_add_uint(tree, hf_obdii_mode01_warm_ups, tvb, value_offset, oinfo->value_bytes, val);
989
0
    }
990
0
    break;
991
992
0
  case OBDII_MODE01_EVAP_SYSTEM_VAPOR_PRESSURE:
993
0
    if ((handled = (oinfo->value_bytes == 2)))
994
0
    {
995
0
      double val = ((int16_t) (oinfo->valueA * 256 + oinfo->valueB)) / 4.0;
996
997
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f kPa", val);
998
0
      proto_tree_add_double(tree, hf_obdii_mode01_evap_system_vapor_pressure, tvb, value_offset, oinfo->value_bytes, val);
999
0
    }
1000
0
    break;
1001
1002
0
  case OBDII_MODE01_ABSOLUTE_BAROMETRIC_PRESSURE:
1003
0
    handled = dissect_obdii_common_absolute_pressure(tvb, oinfo, tree, hf_obdii_mode01_absolute_barometric_pressure);
1004
0
    break;
1005
1006
0
  case OBDII_MODE01_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE:
1007
0
    handled = dissect_obdii_common_absolute_pressure(tvb, oinfo, tree, hf_obdii_mode01_intake_manifold_absolute_pressure);
1008
0
    break;
1009
1010
0
  case OBDII_MODE01_OXYGEN_SENSOR1_A:
1011
0
  case OBDII_MODE01_OXYGEN_SENSOR2_A:
1012
0
  case OBDII_MODE01_OXYGEN_SENSOR3_A:
1013
0
  case OBDII_MODE01_OXYGEN_SENSOR4_A:
1014
0
  case OBDII_MODE01_OXYGEN_SENSOR5_A:
1015
0
  case OBDII_MODE01_OXYGEN_SENSOR6_A:
1016
0
  case OBDII_MODE01_OXYGEN_SENSOR7_A:
1017
0
  case OBDII_MODE01_OXYGEN_SENSOR8_A:
1018
0
    if ((handled = (oinfo->value_bytes == 4)))
1019
0
    {
1020
0
      double fuel_air_ratio = (256 * oinfo->valueA + oinfo->valueB) * (2.0 / 65536.0);
1021
0
      double current_val    = (((int) oinfo->valueC) - 128) + (oinfo->valueD / 256.0);
1022
1023
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": Fuel-Air Equivalence: %.4f ratio", fuel_air_ratio);
1024
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ", Current: %.4f mA", current_val);
1025
1026
0
      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
0
      proto_tree_add_double(tree, hf_obdii_mode01_oxygen_sensor_fuel_air_ratio, tvb, value_offset, 2, fuel_air_ratio);
1028
0
      proto_tree_add_double(tree, hf_obdii_mode01_oxygen_sensor_current, tvb, value_offset + 2, 2, current_val);
1029
0
    }
1030
0
    break;
1031
1032
0
  case OBDII_MODE01_CATALYST_TEMP11:
1033
1
  case OBDII_MODE01_CATALYST_TEMP21:
1034
1
  case OBDII_MODE01_CATALYST_TEMP12:
1035
1
  case OBDII_MODE01_CATALYST_TEMP22:
1036
1
    if ((handled = (oinfo->value_bytes == 2)))
1037
0
    {
1038
0
      int hf_field =
1039
0
        (pid == OBDII_MODE01_CATALYST_TEMP11) ? hf_obdii_mode01_catalyst_temp_11 :
1040
0
        (pid == OBDII_MODE01_CATALYST_TEMP21) ? hf_obdii_mode01_catalyst_temp_21 :
1041
0
        (pid == OBDII_MODE01_CATALYST_TEMP12) ? hf_obdii_mode01_catalyst_temp_12 :
1042
0
        (pid == OBDII_MODE01_CATALYST_TEMP22) ? hf_obdii_mode01_catalyst_temp_22 :
1043
0
        -1;
1044
1045
0
      double val = ((256 * oinfo->valueA + oinfo->valueB) / 10.0) - 40.0;
1046
1047
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f " UTF8_DEGREE_SIGN "C", val);
1048
0
      proto_tree_add_double(tree, hf_field, tvb, oinfo->value_offset, oinfo->value_bytes, val);
1049
0
    }
1050
1
    break;
1051
1052
0
  case OBDII_MODE01_CONTROL_MODULE_VOLTAGE:
1053
0
    if ((handled = (oinfo->value_bytes == 2)))
1054
0
    {
1055
0
      double val = (256 * oinfo->valueA + oinfo->valueB) / 1000.0;
1056
1057
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f V", val);
1058
0
      proto_tree_add_double(tree, hf_obdii_mode01_control_module_voltage, tvb, value_offset, oinfo->value_bytes, val);
1059
0
    }
1060
0
    break;
1061
1062
0
  case OBDII_MODE01_ABSOLUTE_LOAD_VALUE:
1063
0
    if ((handled = (oinfo->value_bytes == 2)))
1064
0
    {
1065
0
      double val = ((256 * oinfo->valueA + oinfo->valueB) * 100) / 255.0;
1066
1067
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f %%", val);
1068
0
      proto_tree_add_double(tree, hf_obdii_mode01_absolute_load_value, tvb, value_offset, oinfo->value_bytes, val);
1069
0
    }
1070
0
    break;
1071
1072
0
  case OBDII_MODE01_FUEL_AIR_COMMANDED_EQUIV_RATIO:
1073
0
    if ((handled = (oinfo->value_bytes == 2)))
1074
0
    {
1075
0
      double val = (256 * oinfo->valueA + oinfo->valueB) * (2.0 / 65536.0);
1076
1077
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f", val);
1078
0
      proto_tree_add_double(tree, hf_obdii_mode01_fuel_air_commanded_equiv_ratio, tvb, value_offset, oinfo->value_bytes, val);
1079
0
    }
1080
0
    break;
1081
1082
0
  case OBDII_MODE01_RELATIVE_THROTTLE_POSITION:
1083
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_relative_throttle_position);
1084
0
    break;
1085
1086
0
  case OBDII_MODE01_AMBIENT_AIR_TEMP:
1087
0
    handled = dissect_obdii_common_temperature(tvb, oinfo, tree, hf_obdii_mode01_ambient_air_temp);
1088
0
    break;
1089
1090
0
  case OBDII_MODE01_ABSOLUTE_THROTTLE_POSITION_B:
1091
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_absolute_throttle_position_B);
1092
0
    break;
1093
1094
0
  case OBDII_MODE01_ABSOLUTE_THROTTLE_POSITION_C:
1095
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_absolute_throttle_position_C);
1096
0
    break;
1097
1098
1
  case OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_D:
1099
1
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_accelerator_pedal_position_D);
1100
1
    break;
1101
1102
0
  case OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_E:
1103
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_accelerator_pedal_position_E);
1104
0
    break;
1105
1106
0
  case OBDII_MODE01_ACCELERATOR_PEDAL_POSITION_F:
1107
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_accelerator_pedal_position_F);
1108
0
    break;
1109
1110
0
  case OBDII_MODE01_COMMANDED_THROTTLE_ACTUATOR:
1111
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_commanded_throttle_actuator);
1112
0
    break;
1113
1114
0
  case OBDII_MODE01_DISTANCE_TRAVELED_WITH_MIL:
1115
0
    handled = dissect_obdii_common_distance_travelled(tvb, oinfo, tree, hf_obdii_mode01_distance_traveled_with_mil);
1116
0
    break;
1117
1118
0
  case OBDII_MODE01_DISTANCE_TRAVELED_SINCE_CODES_CLEAR:
1119
0
    handled = dissect_obdii_common_distance_travelled(tvb, oinfo, tree, hf_obdii_mode01_distance_traveled_since_code_clear);
1120
0
    break;
1121
1122
1
  case OBDII_MODE01_TIME_RUN_WITH_MIL:
1123
1
    handled = dissect_obdii_common_time(tvb, oinfo, tree, hf_obdii_mode01_time_run_with_mil);
1124
1
    break;
1125
1126
0
  case OBDII_MODE01_TIME_SINCE_TROUBLE_CODES_CLEAR:
1127
0
    handled = dissect_obdii_common_time(tvb, oinfo, tree, hf_obdii_mode01_time_since_trouble_code_clear);
1128
0
    break;
1129
1130
0
  case OBDII_MODE01_FUEL_TYPE:
1131
0
    if ((handled = (oinfo->value_bytes == 1)))
1132
0
    {
1133
0
      uint8_t val = oinfo->valueA;
1134
1135
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %s", val_to_str(oinfo->pinfo->pool, val, obdii_fuel_type_coding_vals, "Unknown (%u)"));
1136
0
      proto_tree_add_uint(tree, hf_obdii_mode01_fuel_type, tvb, value_offset, oinfo->value_bytes, val);
1137
0
    }
1138
0
    break;
1139
1140
0
  case OBDII_MODE01_ETHANOL_FUEL:
1141
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_ethanol_fuel);
1142
0
    break;
1143
1144
1
  case OBDII_MODE01_ABSOLUTE_EVAP_SYSTEM_VAPOR_PRESSURE:
1145
1
    if ((handled = (oinfo->value_bytes == 2)))
1146
0
    {
1147
0
      double val = (oinfo->valueA * 256 + oinfo->valueB) / 200.0;
1148
1149
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.2f kPa", val);
1150
0
      proto_tree_add_double(tree, hf_obdii_mode01_absolute_evap_system_vapor_pressure, tvb, value_offset, oinfo->value_bytes, val);
1151
0
    }
1152
1
    break;
1153
1154
0
  case OBDII_MODE01_SHORT_TERM_OXYGEN_BANK13:
1155
0
  case OBDII_MODE01_LONG_TERM_OXYGEN_BANK13:
1156
0
  case OBDII_MODE01_SHORT_TERM_OXYGEN_BANK24:
1157
0
  case OBDII_MODE01_LONG_TERM_OXYGEN_BANK24:
1158
0
    if ((handled = (oinfo->value_bytes == 2)))
1159
0
    {
1160
0
      double bankA_val = ((100.0 * oinfo->valueA) / 128.0) - 100.0;
1161
0
      double bankB_val = ((100.0 * oinfo->valueB) / 128.0) - 100.0;
1162
1163
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": { %.2f %%, %.2f %% }", bankA_val, bankB_val);
1164
1165
      /* TODO: proto tree */
1166
0
    }
1167
0
    break;
1168
1169
0
  case OBDII_MODE01_RELATIVE_ACCELERATOR_PEDAL_POSITION:
1170
0
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_relative_accelerator_pedal_position);
1171
0
    break;
1172
1173
1
  case OBDII_MODE01_HYBRID_BATTERY_REMAINING_LIFE:
1174
1
    handled = dissect_obdii_common_percent(tvb, oinfo, tree, hf_obdii_mode01_hybrid_battery_remaining_life);
1175
1
    break;
1176
1177
0
  case OBDII_MODE01_ENGINE_OIL_TEMP:
1178
0
    handled = dissect_obdii_common_temperature(tvb, oinfo, tree, hf_obdii_mode01_engine_oil_temp);
1179
0
    break;
1180
1181
0
  case OBDII_MODE01_FUEL_INJECTION_TIMING:
1182
0
    if ((handled = (oinfo->value_bytes == 2)))
1183
0
    {
1184
0
      double val = ((256 * oinfo->valueA + oinfo->valueB - (210 * 128)) / 128.0);
1185
1186
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f " UTF8_DEGREE_SIGN, val);
1187
0
      proto_tree_add_double(tree, hf_obdii_mode01_fuel_injection_timing, tvb, value_offset, oinfo->value_bytes, val);
1188
0
    }
1189
0
    break;
1190
1191
0
  case OBDII_MODE01_ENGINE_FUEL_RATE:
1192
0
    if ((handled = (oinfo->value_bytes == 2)))
1193
0
    {
1194
0
      double val = (256 * oinfo->valueA + oinfo->valueB) / 20.0;
1195
1196
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %.3f L/h", val);
1197
0
      proto_tree_add_double(tree, hf_obdii_mode01_engine_fuel_rate, tvb, value_offset, oinfo->value_bytes, val);
1198
0
    }
1199
0
    break;
1200
1201
1
  case OBDII_MODE01_TORQUE_DRIVER_DEMAND_ENGINE:
1202
1
    handled = dissect_obdii_common_torque(tvb, oinfo, tree, hf_obdii_mode01_torque_driver_demand_engine);
1203
1
    break;
1204
1205
0
  case OBDII_MODE01_TORQUE_ACTUAL_ENGINE:
1206
0
    handled = dissect_obdii_common_torque(tvb, oinfo, tree, hf_obdii_mode01_torque_actual_engine);
1207
0
    break;
1208
1209
0
  case OBDII_MODE01_TORQUE_REFERENCE_ENGINE:
1210
0
    if ((handled = (oinfo->value_bytes == 2)))
1211
0
    {
1212
0
      uint16_t val = 256 * oinfo->valueA + oinfo->valueB;
1213
1214
0
      col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, ": %u Nm", val);
1215
0
      proto_tree_add_uint(tree, hf_obdii_mode01_torque_reference_engine, tvb, value_offset, oinfo->value_bytes, val);
1216
0
    }
1217
0
    break;
1218
15
  }
1219
1220
15
  if (!handled)
1221
15
  {
1222
    /* display raw */
1223
15
    col_append_str(oinfo->pinfo->cinfo, COL_INFO, ": <");
1224
15
    if (oinfo->value_bytes >= 1) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueA);
1225
15
    if (oinfo->value_bytes >= 2) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueB);
1226
15
    if (oinfo->value_bytes >= 3) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueC);
1227
15
    if (oinfo->value_bytes >= 4) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueD);
1228
15
    col_append_str(oinfo->pinfo->cinfo, COL_INFO, " >");
1229
15
  }
1230
15
}
1231
1232
static void
1233
dissect_obdii_mode_07(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree)
1234
1
{
1235
1
  proto_tree_add_item(tree, hf_obdii_raw_value, tvb, OBDII_MODE07_DATA_OFF, oinfo->value_bytes, ENC_NA);
1236
1237
  /* display raw */
1238
1
  col_append_str(oinfo->pinfo->cinfo, COL_INFO, ": <");
1239
1
  if (oinfo->value_bytes >= 1) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueA);
1240
1
  if (oinfo->value_bytes >= 2) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueB);
1241
1
  if (oinfo->value_bytes >= 3) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueC);
1242
1
  if (oinfo->value_bytes >= 4) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueD);
1243
1
  if (oinfo->value_bytes >= 5) col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " %.2X", oinfo->valueE);
1244
1
  col_append_str(oinfo->pinfo->cinfo, COL_INFO, " >");
1245
1
}
1246
1247
static void
1248
dissect_obdii_mode_09(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree)
1249
1
{
1250
1
  uint8_t pid = tvb_get_uint8(tvb, OBDII_PID_POS);
1251
1
  int value_offset;
1252
1253
1
  col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, "- %s", val_to_str_ext(oinfo->pinfo->pool, pid, &obdii_mode09_pid_vals_ext, "Unknown (%.2x)"));
1254
1
  proto_tree_add_uint(tree, hf_obdii_mode09_pid, tvb, OBDII_PID_POS, 1, pid);
1255
1256
1
  value_offset = OBDII_VAL_OFF;
1257
1
  oinfo->value_offset = value_offset;
1258
1259
1
  switch (pid)
1260
1
  {
1261
0
  case OBDII_MODE09_PIDS_SUPPORT00:
1262
0
    proto_tree_add_item(tree, hf_obdii_raw_value, tvb, OBDII_VAL_OFF, oinfo->value_bytes, ENC_NA);
1263
0
    break;
1264
0
  case OBDII_MODE09_VIN02:
1265
0
    proto_tree_add_item(tree, hf_obdii_vin, tvb, OBDII_VAL_OFF+1, oinfo->value_bytes-1, ENC_ASCII);
1266
0
    break;
1267
0
  case OBDII_MODE09_CALIBRATION_ID04:
1268
0
  case OBDII_MODE09_CAL_VER_NUMBERS06:
1269
0
  case OBDII_MODE09_PERFORMANCE_SPARK08:
1270
0
    proto_tree_add_item(tree, hf_obdii_raw_value, tvb, OBDII_VAL_OFF, oinfo->value_bytes, ENC_NA);
1271
0
    break;
1272
0
  case OBDII_MODE09_ECU_NAME0A:
1273
0
    proto_tree_add_item(tree, hf_obdii_ecu_name, tvb, OBDII_VAL_OFF+1, oinfo->value_bytes-1, ENC_ASCII);
1274
0
    break;
1275
0
  case OBDII_MODE09_PERFORMANCE_COMPRESSION0B:
1276
1
  default:
1277
1
    proto_tree_add_item(tree, hf_obdii_raw_value, tvb, OBDII_VAL_OFF, oinfo->value_bytes, ENC_NA);
1278
1
    break;
1279
1
  }
1280
1
}
1281
1282
1283
static int
1284
dissect_obdii_query(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree)
1285
4
{
1286
4
  uint16_t pid;
1287
4
  int pid_len;
1288
4
  const char *mode_str;
1289
4
  const char *pid_str;
1290
1291
4
  pid_len = oinfo->data_bytes - 1;
1292
4
  if (pid_len == 0)
1293
1
  {
1294
1
    if (oinfo->mode != 0x04 && oinfo->mode != 0x07)
1295
1
      return 0;
1296
0
    pid = 0; /* Should never be required but set to satisfy petri-dish */
1297
0
  }
1298
3
  else if (pid_len == 1)
1299
0
    pid  = tvb_get_uint8(tvb, OBDII_PID_POS);
1300
3
  else if (pid_len == 2)
1301
1
    pid = tvb_get_ntohs(tvb, OBDII_PID_POS);
1302
2
  else
1303
2
    return 0;
1304
1305
1
  mode_str = val_to_str(oinfo->pinfo->pool, oinfo->mode, obdii_mode_vals, "Unknown (%.2x)");
1306
1307
1
  switch (oinfo->mode)
1308
1
  {
1309
0
  case 0x01:
1310
0
    pid_str = val_to_str_ext(oinfo->pinfo->pool, pid, &obdii_mode01_pid_vals_ext, "Unknown (%.2x)");
1311
0
    proto_tree_add_uint(tree, hf_obdii_mode01_pid, tvb, OBDII_PID_POS, pid_len, pid);
1312
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " Request[%.3x] %s - %s", oinfo->can_id, mode_str, pid_str);
1313
0
    break;
1314
1315
0
  case 0x04:
1316
0
  case 0x07:
1317
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " Request[%.3x] %s", oinfo->can_id, mode_str);
1318
0
    break;
1319
1320
1
  case 0x09:
1321
1
    pid_str = val_to_str_ext(oinfo->pinfo->pool, pid, &obdii_mode09_pid_vals_ext, "Unknown (%.2x)");
1322
1
    proto_tree_add_uint(tree, hf_obdii_mode09_pid, tvb, OBDII_PID_POS, pid_len, pid);
1323
1
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " Request[%.3x] %s - %s", oinfo->can_id, mode_str, pid_str);
1324
1
    break;
1325
1326
0
  default:
1327
0
    pid_str = wmem_strdup_printf(oinfo->pinfo->pool, "Unknown (%.2x)", pid);
1328
0
    col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, " Request[%.3x] %s - %s", oinfo->can_id, mode_str, pid_str);
1329
0
    break;
1330
1
  }
1331
1332
1
  return tvb_captured_length(tvb);
1333
1
}
1334
1335
static int
1336
dissect_obdii_response(tvbuff_t *tvb, struct obdii_packet_info *oinfo, proto_tree *tree)
1337
20
{
1338
20
  col_append_fstr(oinfo->pinfo->cinfo, COL_INFO, "Response[%.3x] %s ", oinfo->can_id, val_to_str(oinfo->pinfo->pool, oinfo->mode, obdii_mode_vals, "Unknown (%.2x)"));
1339
1340
20
  if (oinfo->mode == 0x04 && oinfo->data_bytes == 0x01) {
1341
0
    return tvb_captured_length(tvb);
1342
0
  }
1343
1344
20
  oinfo->value_bytes = oinfo->data_bytes - OBDII_VAL_OFF;
1345
1346
20
  if (oinfo->value_bytes >= 1) oinfo->valueA = tvb_get_uint8(tvb, OBDII_VAL_OFF);
1347
20
  if (oinfo->value_bytes >= 2) oinfo->valueB = tvb_get_uint8(tvb, OBDII_VAL_OFF + 1);
1348
20
  if (oinfo->value_bytes >= 3) oinfo->valueC = tvb_get_uint8(tvb, OBDII_VAL_OFF + 2);
1349
20
  if (oinfo->value_bytes >= 4) oinfo->valueD = tvb_get_uint8(tvb, OBDII_VAL_OFF + 3);
1350
20
  if (oinfo->value_bytes >= 5) oinfo->valueE = tvb_get_uint8(tvb, OBDII_VAL_OFF + 4);
1351
1352
20
  switch (oinfo->mode)
1353
20
  {
1354
15
  case 0x01:
1355
15
    dissect_obdii_mode_01(tvb, oinfo, tree);
1356
15
    break;
1357
1
  case 0x07:
1358
1
    dissect_obdii_mode_07(tvb, oinfo, tree);
1359
1
    break;
1360
1
  case 0x09:
1361
1
    dissect_obdii_mode_09(tvb, oinfo, tree);
1362
20
  }
1363
1364
20
  return tvb_captured_length(tvb);
1365
20
}
1366
1367
static int
1368
dissect_obdii_iso15765(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1369
0
{
1370
0
  iso15765_info_t iso15765_info;
1371
0
  uint32_t        can_id_only;
1372
0
  struct obdii_packet_info oinfo;
1373
1374
0
  proto_tree *obdii_tree;
1375
0
  proto_item *ti;
1376
1377
0
  uint8_t data_bytes;
1378
0
  uint8_t mode;
1379
0
  bool id_is_query;
1380
0
  bool id_is_response;
1381
1382
0
  DISSECTOR_ASSERT(data);
1383
1384
0
  iso15765_info = *((iso15765_info_t *) data);
1385
0
  if (iso15765_info.bus_type != ISO15765_TYPE_CAN && iso15765_info.bus_type != ISO15765_TYPE_CAN_FD) {
1386
0
    return 0;
1387
0
  }
1388
1389
0
  can_id_only = iso15765_info.id & CAN_EFF_MASK;
1390
1391
  /* If we're using 29bit extended ID's then use extended ID parameters */
1392
0
  if (iso15765_info.id & CAN_EFF_FLAG)
1393
0
  {
1394
0
    id_is_query = (can_id_only == ODBII_CAN_QUERY_ID_EFF);
1395
0
    id_is_response = ((((can_id_only & ~ODBII_CAN_RESPONSE_ID_LOWER_MASK_EFF) ^ ODBII_CAN_RESPONSE_ID_LOWER_MIN_EFF) == 0) ||
1396
0
      (((can_id_only & ~ODBII_CAN_RESPONSE_ID_UPPER_MASK_EFF) ^ ODBII_CAN_RESPONSE_ID_UPPER_MIN_EFF) == 0)) ? 1 : 0;
1397
0
  }
1398
0
  else
1399
0
  {
1400
0
    id_is_query = (can_id_only == ODBII_CAN_QUERY_ID_SFF);
1401
0
    id_is_response = ((((can_id_only & ~ODBII_CAN_RESPONSE_ID_LOWER_MASK_SFF) ^ ODBII_CAN_RESPONSE_ID_LOWER_MIN_SFF) == 0) ||
1402
0
      (((can_id_only & ~ODBII_CAN_RESPONSE_ID_UPPER_MASK_SFF) ^ ODBII_CAN_RESPONSE_ID_UPPER_MIN_SFF) == 0));
1403
0
  }
1404
1405
  /* validate */
1406
0
  if (iso15765_info.id & (CAN_ERR_FLAG | CAN_RTR_FLAG))
1407
0
    return 0;
1408
1409
0
  if (!(id_is_query || id_is_response))
1410
0
    return 0;
1411
1412
0
  data_bytes = tvb_reported_length(tvb);
1413
0
  mode = tvb_get_uint8(tvb, OBDII_MODE_POS);
1414
1415
  /* Mode 7 is a datalength of 1, all other queries either 2 or 3 bytes */
1416
0
  if (id_is_query)
1417
0
  {
1418
0
    if (iso15765_info.len != 8)
1419
0
      expert_add_info(pinfo, NULL, &ei_obdii_padding);
1420
0
    if (data_bytes == 0 || data_bytes > 3)
1421
0
      return 0;
1422
0
    if (mode > 0x0a)
1423
0
      return 0;
1424
0
  }
1425
1426
0
  if (id_is_response)
1427
0
  {
1428
0
    if (mode != 0x44 && data_bytes < 2)
1429
0
      return 0;
1430
0
    if (mode < 0x40)
1431
0
      return 0;
1432
1433
0
    mode -= 0x40;
1434
0
  }
1435
1436
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "OBD-II");
1437
0
  col_clear(pinfo->cinfo, COL_INFO);
1438
1439
0
  ti = proto_tree_add_item(tree, proto_obdii, tvb, 0, -1, ENC_NA);
1440
0
  obdii_tree = proto_item_add_subtree(ti, ett_obdii);
1441
1442
0
  proto_tree_add_uint(obdii_tree, hf_obdii_mode, tvb, OBDII_MODE_POS, 1, mode);
1443
1444
0
  memset(&oinfo, 0, sizeof(oinfo));
1445
0
  oinfo.pinfo = pinfo;
1446
0
  oinfo.can_id = can_id_only;
1447
0
  oinfo.data_bytes = data_bytes;
1448
0
  oinfo.mode = mode;
1449
1450
0
  if (id_is_query)
1451
0
    return dissect_obdii_query(tvb, &oinfo, obdii_tree);
1452
1453
0
  if (id_is_response)
1454
0
    return dissect_obdii_response(tvb, &oinfo, obdii_tree);
1455
1456
  /* never here */
1457
0
  DISSECTOR_ASSERT_NOT_REACHED();
1458
1459
0
  return tvb_captured_length(tvb);
1460
0
}
1461
1462
static int
1463
dissect_obdii_uds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1464
24
{
1465
24
    struct obdii_packet_info  oinfo;
1466
1467
24
    proto_tree               *obdii_tree;
1468
24
    proto_item               *ti;
1469
1470
24
    uint8_t                   data_bytes;
1471
24
    uint8_t                   mode;
1472
24
    bool                      response;
1473
1474
24
    data_bytes = tvb_reported_length(tvb);
1475
24
    mode = tvb_get_uint8(tvb, OBDII_MODE_POS);
1476
24
    response = (mode & 0x40) == 0x40;
1477
24
    mode = mode & 0xbf;
1478
1479
24
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "OBD-II");
1480
24
    col_clear(pinfo->cinfo, COL_INFO);
1481
1482
24
    ti = proto_tree_add_item(tree, proto_obdii, tvb, 0, -1, ENC_NA);
1483
24
    obdii_tree = proto_item_add_subtree(ti, ett_obdii);
1484
1485
24
    proto_tree_add_uint(obdii_tree, hf_obdii_mode, tvb, OBDII_MODE_POS, 1, mode);
1486
1487
24
    memset(&oinfo, 0, sizeof(oinfo));
1488
24
    oinfo.pinfo = pinfo;
1489
24
    oinfo.can_id = 0;
1490
24
    oinfo.data_bytes = data_bytes;
1491
24
    oinfo.mode = mode;
1492
1493
24
    if (!response) {
1494
4
        return dissect_obdii_query(tvb, &oinfo, obdii_tree);
1495
20
    } else {
1496
20
        return dissect_obdii_response(tvb, &oinfo, obdii_tree);
1497
20
    }
1498
1499
    /* never here */
1500
0
    DISSECTOR_ASSERT_NOT_REACHED();
1501
0
}
1502
1503
static bool
1504
dissect_obdii_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1505
0
{
1506
0
    return dissect_obdii_iso15765(tvb, pinfo, tree, data) != 0;
1507
0
}
1508
1509
void
1510
proto_register_obdii(void)
1511
16
{
1512
16
  static hf_register_info hf[] = {
1513
16
    { &hf_obdii_mode,
1514
16
      { "Mode", "obd-ii.mode", FT_UINT8, BASE_HEX, VALS(obdii_mode_vals), 0x0, NULL, HFILL },
1515
16
    },
1516
16
    { &hf_obdii_raw_value,
1517
16
      { "Raw value", "obd-ii.raw_value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL },
1518
16
    },
1519
16
    { &hf_obdii_mode01_pid,
1520
16
      { "PID", "obd-ii.mode01_pid", FT_UINT16, BASE_HEX | BASE_EXT_STRING, &obdii_mode01_pid_vals_ext, 0x0, NULL, HFILL },
1521
16
    },
1522
16
    { &hf_obdii_mode01_supported_pid,
1523
16
      { "Supported PID", "obd-ii.mode01_supported_pid", FT_UINT8, BASE_HEX | BASE_EXT_STRING, &obdii_mode01_pid_vals_ext, 0x0, NULL, HFILL },
1524
16
    },
1525
16
    { &hf_obdii_mode01_unsupported_pid,
1526
16
      { "NOT Supported PID", "obd-ii.mode01_unsupported_pid", FT_UINT8, BASE_HEX | BASE_EXT_STRING, &obdii_mode01_pid_vals_ext, 0x0, NULL, HFILL },
1527
16
    },
1528
16
    { &hf_obdii_mode01_fuel_system1_status,
1529
16
      { "Fuel system 1 status", "obd-ii.mode01_fuel_system1_status", FT_UINT8, BASE_HEX, VALS(obdii_fuel_system_status_vals), 0x0, NULL, HFILL },
1530
16
    },
1531
16
    { &hf_obdii_mode01_fuel_system2_status,
1532
16
      { "Fuel system 2 status", "obd-ii.mode01_fuel_system2_status", FT_UINT8, BASE_HEX, VALS(obdii_fuel_system_status_vals), 0x0, NULL, HFILL },
1533
16
    },
1534
16
    { &hf_obdii_mode01_engine_load,
1535
16
      { "Calculated engine load", "obd-ii.mode01_engine_load", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1536
16
    },
1537
16
    { &hf_obdii_mode01_engine_coolant_temp,
1538
16
      { "Engine coolant temperature", "obd-ii.mode01_engine_coolant_temp", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1539
16
    },
1540
16
    { &hf_obdii_mode01_short_term_fuel_bank1,
1541
16
      { "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 },
1542
16
    },
1543
16
    { &hf_obdii_mode01_short_term_fuel_bank2,
1544
16
      { "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 },
1545
16
    },
1546
16
    { &hf_obdii_mode01_long_term_fuel_bank1,
1547
16
      { "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 },
1548
16
    },
1549
16
    { &hf_obdii_mode01_long_term_fuel_bank2,
1550
16
      { "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 },
1551
16
    },
1552
16
    { &hf_obdii_mode01_fuel_pressure,
1553
16
      { "Fuel pressure", "obd-ii.mode01_fuel_pressure", FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL },
1554
16
    },
1555
16
    { &hf_obdii_mode01_engine_rpm,
1556
16
      { "Engine RPM", "obd-ii.mode01_engine_rpm", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_revolutions_per_minute), 0x0, NULL, HFILL },
1557
16
    },
1558
16
    { &hf_obdii_mode01_vehicle_speed,
1559
16
      { "Vehicle Speed", "obd-ii.mode01_vehicle_speed", FT_UINT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kmh), 0x0, NULL, HFILL },
1560
16
    },
1561
16
    { &hf_obdii_mode01_timing_advance,
1562
16
      { "Timing advance", "obd-ii.mode01_timing_advance", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_degree_btdc), 0x0, NULL, HFILL },
1563
16
    },
1564
16
    { &hf_obdii_mode01_intake_air_temp,
1565
16
      { "Intake air temperature", "obd-ii.mode01_intake_air_temp", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1566
16
    },
1567
16
    { &hf_obdii_mode01_maf_air_flow_rate,
1568
16
      { "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 },
1569
16
    },
1570
16
    { &hf_obdii_mode01_throttle_position,
1571
16
      { "Throttle position", "obd-ii.mode01_throttle_position", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1572
16
    },
1573
16
    { &hf_obdii_mode01_secondary_air_status,
1574
16
      { "Commanded secondary air status", "obd-ii.mode01_secondary_air_status", FT_UINT8, BASE_HEX, VALS(obdii_secondary_air_status_vals), 0x0, NULL, HFILL },
1575
16
    },
1576
16
    { &hf_obdii_mode01_obd_standards,
1577
16
      { "OBD Standards", "obd-ii.mode01_obd_standards", FT_UINT8, BASE_DEC, VALS(obdii_standards_vals), 0x0, NULL, HFILL }
1578
16
    },
1579
16
    { &hf_obdii_mode01_engine_uptime,
1580
16
      { "Run time since engine start", "obd-ii.mode01_engine_uptime", FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_seconds), 0x0, NULL, HFILL }
1581
16
    },
1582
16
    { &hf_obdii_mode01_fuel_rail_pressure,
1583
16
      { "Fuel Rail Pressure", "obd-ii.mode01_fuel_rail_pressure", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1584
16
    },
1585
16
    { &hf_obdii_mode01_fuel_rail_gauge_pressure,
1586
16
      { "Fuel Rail Gauge Pressure", "obd-ii.mode01_fuel_rail_gauge_pressure", FT_UINT24, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1587
16
    },
1588
16
    { &hf_obdii_mode01_fuel_rail_absolute_pressure,
1589
16
      { "Fuel rail absolute pressure", "obd-ii.mode01_fuel_rail_absolute_pressure", FT_UINT24, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1590
16
    },
1591
16
    { &hf_obdii_mode01_commanded_egr,
1592
16
      { "Commanded EGR", "obd-ii.mode01_commanded_egr", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL }
1593
16
    },
1594
16
    { &hf_obdii_mode01_egr_error,
1595
16
      { "EGR Error", "obd-ii.mode01_egr_error", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL }
1596
16
    },
1597
16
    { &hf_obdii_mode01_commanded_evap_purge,
1598
16
      { "Commanded evaporative purge", "obd-ii.mode01_commanded_evap_purge", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL }
1599
16
    },
1600
16
    { &hf_obdii_mode01_fuel_tank_level_input,
1601
16
      { "Fuel Tank Level Input", "obd-ii.mode01_fuel_tank_level_input", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL }
1602
16
    },
1603
16
    { &hf_obdii_mode01_warm_ups,
1604
16
      { "Warm-ups since codes cleared", "obd-ii.mode01_warm_ups", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1605
16
    },
1606
16
    { &hf_obdii_mode01_evap_system_vapor_pressure,
1607
16
      { "Evap. System Vapor Pressure", "obd-ii.mode01_evap_system_vapor_pressure", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1608
16
    },
1609
16
    { &hf_obdii_mode01_absolute_barometric_pressure,
1610
16
      { "Absolute Barometric Pressure", "obd-ii.mode01_absolute_barometric_pressure", FT_UINT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1611
16
    },
1612
16
    { &hf_obdii_mode01_intake_manifold_absolute_pressure,
1613
16
      { "Intake manifold absolute pressure", "obd-ii.mode01_intake_manifold_absolute_pressure", FT_UINT8, BASE_DEC | BASE_UNIT_STRING, UNS(&units_kilopascal), 0x0, NULL, HFILL }
1614
16
    },
1615
16
    { &hf_obdii_mode01_oxygen_sensor_id,
1616
16
      { "Oxygen Sensor ID", "obd-ii.mode01_oxygen_sensor_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1617
16
    },
1618
16
    { &hf_obdii_mode01_oxygen_sensor_fuel_air_ratio,
1619
16
      { "Fuel-Air Equivalence Ratio", "obd-ii.mode01_oxygen_sensor_fuel_air_ratio", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1620
16
    },
1621
16
    { &hf_obdii_mode01_oxygen_sensor_voltage,
1622
16
      { "Voltage", "obd-ii.mode01_oxygen_sensor_voltage", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_volt), 0x0, NULL, HFILL }
1623
16
    },
1624
16
    { &hf_obdii_mode01_oxygen_sensor_current,
1625
16
      { "Current", "obd-ii.mode01_oxygen_sensor_current", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_milliamps), 0x0, NULL, HFILL }
1626
16
    },
1627
16
    { &hf_obdii_mode01_distance_traveled_with_mil,
1628
16
      { "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 }
1629
16
    },
1630
16
    { &hf_obdii_mode01_distance_traveled_since_code_clear,
1631
16
      { "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 }
1632
16
    },
1633
16
    { &hf_obdii_mode01_time_run_with_mil,
1634
16
      { "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 }
1635
16
    },
1636
16
    { &hf_obdii_mode01_time_since_trouble_code_clear,
1637
16
      { "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 }
1638
16
    },
1639
16
    { &hf_obdii_mode01_fuel_type,
1640
16
      { "Fuel type", "obd-ii.mode01_fuel_type", FT_UINT8, BASE_DEC, VALS(obdii_fuel_type_coding_vals), 0x0, NULL, HFILL }
1641
16
    },
1642
16
    { &hf_obdii_mode01_control_module_voltage,
1643
16
      { "Control module voltage", "obd-ii.mode01_control_module_voltage", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_volt), 0x0, NULL, HFILL },
1644
16
    },
1645
16
    { &hf_obdii_mode01_absolute_load_value,
1646
16
      { "Absolute load value", "obd-ii.mode01_absolute_load_value", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1647
16
    },
1648
16
    { &hf_obdii_mode01_fuel_air_commanded_equiv_ratio,
1649
16
      { "Fuel-Air commanded equivalence ratio", "obd-ii.mode01_fuel_air_commanded_equiv_ratio", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL },
1650
16
    },
1651
16
    { &hf_obdii_mode01_relative_throttle_position,
1652
16
      { "Relative throttle position", "obd-ii.mode01_relative_throttle_position", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1653
16
    },
1654
16
    { &hf_obdii_mode01_catalyst_temp_11,
1655
16
      { "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 },
1656
16
    },
1657
16
    { &hf_obdii_mode01_catalyst_temp_21,
1658
16
      { "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 },
1659
16
    },
1660
16
    { &hf_obdii_mode01_catalyst_temp_12,
1661
16
      { "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 },
1662
16
    },
1663
16
    { &hf_obdii_mode01_catalyst_temp_22,
1664
16
      { "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 },
1665
16
    },
1666
16
    { &hf_obdii_mode01_ambient_air_temp,
1667
16
      { "Ambient air temperature", "obd-ii.mode01_ambient_air_temp", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1668
16
    },
1669
16
    { &hf_obdii_mode01_absolute_throttle_position_B,
1670
16
      { "Absolute throttle position B", "obd-ii.mode01_absolute_throttle_position_B", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1671
16
    },
1672
16
    { &hf_obdii_mode01_absolute_throttle_position_C,
1673
16
      { "Absolute throttle position C", "obd-ii.mode01_absolute_throttle_position_C", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1674
16
    },
1675
16
    { &hf_obdii_mode01_accelerator_pedal_position_D,
1676
16
      { "Accelerator pedal position D", "obd-ii.mode01_accelerator_pedal_position_D", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1677
16
    },
1678
16
    { &hf_obdii_mode01_accelerator_pedal_position_E,
1679
16
      { "Accelerator pedal position E", "obd-ii.mode01_accelerator_pedal_position_E", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1680
16
    },
1681
16
    { &hf_obdii_mode01_accelerator_pedal_position_F,
1682
16
      { "Accelerator pedal position F", "obd-ii.mode01_accelerator_pedal_position_F", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1683
16
    },
1684
16
    { &hf_obdii_mode01_commanded_throttle_actuator,
1685
16
      { "Commanded throttle actuator", "obd-ii.mode01_commanded_throttle_actuator", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1686
16
    },
1687
16
    { &hf_obdii_mode01_ethanol_fuel,
1688
16
      { "Ethanol fuel %", "obd-ii.mode01_ethanol_fuel", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1689
16
    },
1690
16
    { &hf_obdii_mode01_absolute_evap_system_vapor_pressure,
1691
16
      { "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 }
1692
16
    },
1693
16
    { &hf_obdii_mode01_relative_accelerator_pedal_position,
1694
16
      { "Relative accelerator pedal position", "obd-ii.mode01_relative_accelerator_pedal_position", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1695
16
    },
1696
16
    { &hf_obdii_mode01_hybrid_battery_remaining_life,
1697
16
      { "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 },
1698
16
    },
1699
16
    { &hf_obdii_mode01_engine_oil_temp,
1700
16
      { "Engine oil temperature", "obd-ii.mode01_engine_oil_temp", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL },
1701
16
    },
1702
16
    { &hf_obdii_mode01_fuel_injection_timing,
1703
16
      { "Fuel injection timing", "obd-ii.mode01_fuel_injection_timing", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_degree_degrees), 0x0, NULL, HFILL },
1704
16
    },
1705
16
    { &hf_obdii_mode01_engine_fuel_rate,
1706
16
      { "Engine fuel rate", "obd-ii.mode01_engine_fuel_rate", FT_DOUBLE, BASE_NONE | BASE_UNIT_STRING, UNS(&units_liter_per_hour), 0x0, NULL, HFILL },
1707
16
    },
1708
16
    { &hf_obdii_mode01_torque_driver_demand_engine,
1709
16
      { "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 },
1710
16
    },
1711
16
    { &hf_obdii_mode01_torque_actual_engine,
1712
16
      { "Actual engine - percent torque", "obd-ii.mode01_torque_actual_engine", FT_INT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL },
1713
16
    },
1714
16
    { &hf_obdii_mode01_torque_reference_engine,
1715
16
      { "Engine reference torque", "obd-ii.mode01_torque_reference_engine", FT_UINT16, BASE_DEC | BASE_UNIT_STRING, UNS(&units_newton_metre), 0x0, NULL, HFILL },
1716
16
    },
1717
16
    { &hf_obdii_mode09_pid,
1718
16
      { "PID", "obd-ii.mode09_pid", FT_UINT16, BASE_HEX | BASE_EXT_STRING, &obdii_mode09_pid_vals_ext, 0x0, NULL, HFILL },
1719
16
    },
1720
16
    { &hf_obdii_mode09_supported_pid,
1721
16
      { "Supported PID", "obd-ii.mode09_supported_pid", FT_UINT8, BASE_HEX | BASE_EXT_STRING, &obdii_mode09_pid_vals_ext, 0x0, NULL, HFILL },
1722
16
    },
1723
16
    { &hf_obdii_mode09_unsupported_pid,
1724
16
      { "NOT Supported PID", "obd-ii.mode09_unsupported_pid", FT_UINT8, BASE_HEX | BASE_EXT_STRING, &obdii_mode09_pid_vals_ext, 0x0, NULL, HFILL },
1725
16
    },
1726
16
    { &hf_obdii_vin,
1727
16
      { "VIN", "obd-ii.VIN", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL },
1728
16
    },
1729
16
    { &hf_obdii_ecu_name,
1730
16
      { "ECU Name", "obd-ii.ecu_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL },
1731
16
    },
1732
16
  };
1733
1734
16
  static int *ett[] = {
1735
16
    &ett_obdii
1736
16
  };
1737
1738
16
  struct expert_module *expert_obdii;
1739
1740
16
  static ei_register_info obdii_ei[] =
1741
16
  {
1742
16
    { &ei_obdii_padding,
1743
16
      { "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 }},
1744
16
  };
1745
1746
16
  proto_obdii = proto_register_protocol("OBD-II PID", "OBD-II", "obd-ii");
1747
16
  proto_register_field_array(proto_obdii, hf, array_length(hf));
1748
16
  proto_register_subtree_array(ett, array_length(ett));
1749
1750
16
  expert_obdii = expert_register_protocol(proto_obdii);
1751
16
  expert_register_field_array(expert_obdii, obdii_ei, array_length(obdii_ei));
1752
1753
16
  obdii_handle = register_dissector("obd-ii", dissect_obdii_iso15765, proto_obdii);
1754
16
  register_dissector("obd-ii-uds", dissect_obdii_uds, proto_obdii);
1755
16
}
1756
1757
void
1758
proto_reg_handoff_obdii(void)
1759
16
{
1760
16
  dissector_add_for_decode_as("iso15765.subdissector", obdii_handle);
1761
1762
  /* heuristics default off since these standardized IDs might be reused outside automotive systems */
1763
16
  heur_dissector_add("can", dissect_obdii_heur, "OBD-II Heuristic", "obd-ii_can_heur", proto_obdii, HEURISTIC_DISABLE);
1764
16
}
1765
1766
/*
1767
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1768
 *
1769
 * Local variables:
1770
 * c-basic-offset: 8
1771
 * tab-width: 8
1772
 * indent-tabs-mode: t
1773
 * End:
1774
 *
1775
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1776
 * :indentSize=8:tabSize=8:noTabs=false:
1777
 */