4 #include <uds/uds_types.h>
8 #define OBD2_FUNCTIONAL_BROADCAST_ID 0x7df
9 #define OBD2_FUNCTIONAL_RESPONSE_START 0x7e8
10 #define OBD2_FUNCTIONAL_RESPONSE_COUNT 8
16 /* Public: Initialize an DiagnosticShims with the given callback functions.
18 * If any callbacks are not to be used, set them to NULL. For documentation of
19 * the function type signatures, see higher up in this header file. This struct
20 * is a handy encapsulation used to pass the shims around to the various
21 * diagnostic_* functions.
23 * Returns a struct with the fields initailized to the callbacks.
25 DiagnosticShims diagnostic_init_shims(LogShim log,
26 SendCanMessageShim send_can_message,
27 SetTimerShim set_timer);
29 /* Public: Generate a new diagnostic request, send the first CAN message frame
30 * and set up the handle required to process the response via
31 * diagnostic_receive_can_frame(...).
33 * shims - Low-level shims required to send CAN messages, etc.
35 * callback - an optional function to be called when the response is receved
36 * (use NULL if no callback is required).
38 * Returns a handle to be used with diagnostic_receive_can_frame to complete
39 * sending the request and receive the response. The 'completed' field in the
40 * returned DiagnosticRequestHandle will be true when the message is completely
41 * sent. The first frame of the message will already be sent.
43 DiagnosticRequestHandle diagnostic_request(DiagnosticShims* shims,
44 DiagnosticRequest* request, DiagnosticResponseReceived callback);
46 /* Public: Generate the handle for a new diagnostic request, but do not send any
47 * data to CAN yet - you must call start_diagnostic_request(...) on the handle
48 * returned from this function actually kick off the request.
50 * shims - Low-level shims required to send CAN messages, etc.
52 * callback - an optional function to be called when the response is receved
53 * (use NULL if no callback is required).
55 * Returns a handle to be used with start_diagnostic_request and then
56 * diagnostic_receive_can_frame to complete sending the request and receive the
57 * response. The 'completed' field in the returned DiagnosticRequestHandle will
58 * be true when the message is completely sent.
60 DiagnosticRequestHandle generate_diagnostic_request(DiagnosticShims* shims,
61 DiagnosticRequest* request, DiagnosticResponseReceived callback);
63 /* Public: Send the first frame of the request to CAN for the handle, generated
64 * by generate_diagnostic_request.
66 * You can also call this method to re-do the request for a handle that has
69 void start_diagnostic_request(DiagnosticShims* shims,
70 DiagnosticRequestHandle* handle);
72 /* Public: Request a PID from the given arbitration ID, determining the mode
73 * automatically based on the PID type.
75 * shims - Low-level shims required to send CAN messages, etc.
76 * pid_request_type - either DIAGNOSTIC_STANDARD_PID (will use mode 0x1 and 1
77 * byte PIDs) or DIAGNOSTIC_ENHANCED_PID (will use mode 0x22 and 2 byte
79 * arbitration_id - The arbitration ID to send the request to.
80 * pid - The PID to request from the other node.
81 * callback - an optional function to be called when the response is receved
82 * (use NULL if no callback is required).
84 * Returns a handle to be used with diagnostic_receive_can_frame to complete
85 * sending the request and receive the response. The 'completed' field in the
86 * returned DiagnosticRequestHandle will be true when the message is completely
89 DiagnosticRequestHandle diagnostic_request_pid(DiagnosticShims* shims,
90 DiagnosticPidRequestType pid_request_type, uint32_t arbitration_id,
91 uint16_t pid, DiagnosticResponseReceived callback);
93 /* Public: Continue to send and receive a single diagnostic request, based on a
94 * freshly received CAN message.
96 * shims - Low-level shims required to send CAN messages, etc.
97 * handle - A DiagnosticRequestHandle previously returned by one of the
98 * diagnostic_request*(..) functions.
99 * arbitration_id - The arbitration_id of the received CAN message.
100 * data - The data of the received CAN message.
101 * size - The size of the data in the received CAN message.
103 * Returns true if the request was completed and response received, or the
104 * request was otherwise cancelled. Check the 'success' field of the handle to
105 * see if it was successful.
107 DiagnosticResponse diagnostic_receive_can_frame(DiagnosticShims* shims,
108 DiagnosticRequestHandle* handle,
109 const uint32_t arbitration_id, const uint8_t data[],
112 /* Public: Parse the entier payload of the reponse as a single integer.
114 * response - the received DiagnosticResponse.
116 int diagnostic_payload_to_integer(const DiagnosticResponse* response);
118 /* Public: Render a DiagnosticResponse as a string into the given buffer.
120 * response - the response to convert to a string, for debug logging.
121 * destination - the target string buffer.
122 * destination_length - the size of the destination buffer, i.e. the max size
123 * for the rendered string.
125 void diagnostic_response_to_string(const DiagnosticResponse* response,
126 char* destination, size_t destination_length);
128 /* Public: Render a DiagnosticRequest as a string into the given buffer.
130 * request - the request to convert to a string, for debug logging.
131 * destination - the target string buffer.
132 * destination_length - the size of the destination buffer, i.e. the max size
133 * for the rendered string.
135 void diagnostic_request_to_string(const DiagnosticRequest* request,
136 char* destination, size_t destination_length);
138 /* Public: For many OBD-II PIDs with a numerical result, translate a diagnostic
139 * response payload into a meaningful number using the standard formulas.
141 * Functions pulled from http://en.wikipedia.org/wiki/OBD-II_PIDs#Mode_01
143 * Returns the translated value or 0 if the PID is not in the OBD-II standard or
144 * does not use a numerical value (e.g. VIN).
146 float diagnostic_decode_obd2_pid(const DiagnosticResponse* response);
148 /* Public: Returns true if the "fingerprint" of the two diagnostic messages
149 * matches - the arbitration_id, mode and pid (or lack of pid).
151 bool diagnostic_request_equals(const DiagnosticRequest* ours,
152 const DiagnosticRequest* theirs);
154 /* Public: Returns true if the request has been completely sent - if false, make
155 * sure you called start_diagnostic_request once to start it, and then pass
156 * incoming CAN messages to it with diagnostic_receive_can_frame(...) so it can
157 * continue the ISO-TP transfer.
159 bool diagnostic_request_sent(DiagnosticRequestHandle* handle);