4 #include <isotp/isotp.h>
12 // TODO This isn't true for multi frame messages - we may need to dynamically
13 // allocate this in the future
14 #define MAX_OBD2_PAYLOAD_LENGTH 7
18 DIAGNOSTIC_REQUEST_TYPE_PID,
19 DIAGNOSTIC_REQUEST_TYPE_DTC,
20 DIAGNOSTIC_REQUEST_TYPE_MIL_STATUS,
21 DIAGNOSTIC_REQUEST_TYPE_VIN
22 } DiagnosticRequestType;
25 DiagnosticRequestType type;
26 uint16_t arbitration_id;
30 uint8_t payload[MAX_OBD2_PAYLOAD_LENGTH];
31 uint8_t payload_length;
35 // http://www.canbushack.com/blog/index.php?title=scanning-for-diagnostic-data&more=1&c=1&tb=1&pb=1
36 // for the list of NRCs
39 NRC_SERVICE_NOT_SUPPORTED = 0x11,
40 NRC_SUB_FUNCTION_NOT_SUPPORTED = 0x12,
41 NRC_CONDITIONS_NOT_CORRECT = 0x22,
42 NRC_REQUEST_OUT_OF_RANGE = 0x31,
43 NRC_SECURITY_ACCESS_DENIED = 0x33,
44 NRC_INVALID_KEY = 0x35,
45 NRC_TOO_MANY_ATTEMPS = 0x36,
46 NRC_TIME_DELAY_NOT_EXPIRED = 0x37,
47 NRC_RESPONSE_PENDING = 0x78
48 } DiagnosticNegativeResponseCode;
51 OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST = 0x1,
52 OBD2_MODE_POWERTRAIN_FREEZE_FRAME_REQUEST = 0x2,
53 OBD2_MODE_EMISSIONS_DTC_REQUEST = 0x3,
54 OBD2_MODE_EMISSIONS_DTC_CLEAR = 0x4,
55 // 0x5 is for non-CAN only
56 // OBD2_MODE_OXYGEN_SENSOR_TEST = 0x5,
57 OBD2_MODE_TEST_RESULTS = 0x6,
58 OBD2_MODE_DRIVE_CYCLE_DTC_REQUEST = 0x7,
59 OBD2_MODE_CONTROL = 0x8,
60 OBD2_MODE_VEHICLE_INFORMATION = 0x9,
61 OBD2_MODE_PERMANENT_DTC_REQUEST = 0xa,
62 // this one isn't technically in OBD2, but both of the enhanced standards
63 // have their PID requests at 0x22
64 OBD2_MODE_ENHANCED_DIAGNOSTIC_REQUEST = 0x22
71 } DiagnosticTroubleCodeType;
74 uint16_t arbitration_id;
79 DiagnosticNegativeResponseCode negative_response_code;
80 uint8_t payload[MAX_OBD2_PAYLOAD_LENGTH];
81 uint8_t payload_length;
89 } DiagnosticTroubleCodeGroup;
92 DiagnosticTroubleCodeGroup group;
95 } DiagnosticTroubleCode;
97 typedef void (*DiagnosticResponseReceived)(const DiagnosticResponse* response);
98 typedef void (*DiagnosticMilStatusReceived)(bool malfunction_indicator_status);
99 typedef void (*DiagnosticVinReceived)(uint8_t vin[]);
100 typedef void (*DiagnosticTroubleCodesReceived)(
101 DiagnosticMode mode, DiagnosticTroubleCode* codes);
102 typedef void (*DiagnosticPidEnumerationReceived)(
103 const DiagnosticResponse* response, uint16_t* pids);
105 // TODO should we enumerate every OBD-II PID? need conversion formulas, too
108 uint8_t bytes_returned;
111 } DiagnosticParameter;
114 DiagnosticRequest request;
118 IsoTpShims isotp_shims;
119 IsoTpSendHandle isotp_send_handle;
120 IsoTpReceiveHandle isotp_receive_handle;
121 DiagnosticResponseReceived callback;
122 DiagnosticMilStatusReceived mil_status_callback;
123 DiagnosticVinReceived vin_callback;
124 } DiagnosticRequestHandle;
127 DIAGNOSTIC_STANDARD_PID,
128 DIAGNOSTIC_ENHANCED_PID
129 } DiagnosticPidRequestType;
133 SendCanMessageShim send_can_message;
134 SetTimerShim set_timer;
137 DiagnosticShims diagnostic_init_shims(LogShim log,
138 SendCanMessageShim send_can_message,
139 SetTimerShim set_timer);
141 DiagnosticRequestHandle diagnostic_request(DiagnosticShims* shims,
142 DiagnosticRequest* request, DiagnosticResponseReceived callback);
144 // decide mode 0x1 / 0x22 based on pid type
145 DiagnosticRequestHandle diagnostic_request_pid(DiagnosticShims* shims,
146 DiagnosticPidRequestType pid_request_type, uint16_t arbitration_id,
147 uint16_t pid, DiagnosticResponseReceived callback);
149 DiagnosticRequestHandle diagnostic_request_malfunction_indicator_status(
150 DiagnosticShims* shims,
151 DiagnosticMilStatusReceived callback);
153 DiagnosticRequestHandle diagnostic_request_vin(DiagnosticShims* shims,
154 DiagnosticVinReceived callback);
156 DiagnosticRequestHandle diagnostic_request_dtc(DiagnosticShims* shims,
157 DiagnosticTroubleCodeType dtc_type,
158 DiagnosticTroubleCodesReceived callback);
160 bool diagnostic_clear_dtc(DiagnosticShims* shims);
162 DiagnosticRequestHandle diagnostic_enumerate_pids(DiagnosticShims* shims,
163 DiagnosticRequest* request, DiagnosticPidEnumerationReceived callback);
165 DiagnosticResponse diagnostic_receive_can_frame(DiagnosticShims* shims,
166 DiagnosticRequestHandle* handle,
167 const uint16_t arbitration_id, const uint8_t data[],