Add an option to pad outgoing CAN frames to 8 bytes (on by default).
[apps/low-level-can-service.git] / src / uds / uds_types.h
1 #ifndef __UDS_TYPES_H__
2 #define __UDS_TYPES_H__
3
4 #include <isotp/isotp.h>
5 #include <stdint.h>
6 #include <stdbool.h>
7
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11
12 // TODO This isn't true for multi frame messages - we may need to dynamically
13 // allocate this in the future
14 #define MAX_UDS_PAYLOAD_LENGTH 7
15 #define MAX_RESPONDING_ECU_COUNT 8
16 #define VIN_LENGTH 17
17
18 /* Private: The four main types of diagnositc requests that determine how the
19  * request should be parsed and what type of callback should be used.
20  *
21  * TODO this may not be used...yet?
22  */
23 typedef enum {
24     DIAGNOSTIC_REQUEST_TYPE_PID,
25     DIAGNOSTIC_REQUEST_TYPE_DTC,
26     DIAGNOSTIC_REQUEST_TYPE_MIL_STATUS,
27     DIAGNOSTIC_REQUEST_TYPE_VIN
28 } DiagnosticRequestType;
29
30 /* Public: A container for a single diagnostic request.
31  *
32  * The only required fields are the arbitration_id and mode.
33  *
34  * arbitration_id - The arbitration ID to send the request.
35  * mode - The OBD-II mode for the request.
36  * has_pid - (optional) If the requests uses a PID, this should be true.
37  * pid - (optional) The PID to request, if the mode requires one. has_pid must
38  *      be true.
39  * pid_length - The length of the PID field, either 1 (standard) or 2 bytes
40  *      (extended). If 0, it will be set automatically based on the request
41  *      mode.
42  * payload - (optional) The payload for the request, if the request requires
43  *      one. If payload_length is 0 this field is ignored.
44  * payload_length - The length of the payload, or 0 if no payload is used.
45  * no_frame_padding - false if sent CAN payloads should *not* be padded out to a
46  *      full 8 byte CAN frame. Many ECUs require this, but others require the
47  *      size of the CAN message to only be the actual data. By default padding
48  *      is enabled (so this struct value can default to 0).
49  * type - the type of the request (TODO unused)
50  */
51 typedef struct {
52     uint16_t arbitration_id;
53     uint8_t mode;
54     bool has_pid;
55     uint16_t pid;
56     uint8_t pid_length;
57     uint8_t payload[MAX_UDS_PAYLOAD_LENGTH];
58     uint8_t payload_length;
59     bool no_frame_padding;
60     DiagnosticRequestType type;
61 } DiagnosticRequest;
62
63 /* Public: All possible negative response codes that could be received from a
64  * requested node.
65  *
66  * When a DiagnosticResponse is received and the 'completed' field is true, but
67  * the 'success' field is false, the 'negative_response_code' field will contain
68  * one of these values as reported by the requested node.
69  *
70  * Thanks to canbushack.com for the list of NRCs.
71  */
72 typedef enum {
73     NRC_SUCCESS = 0x0,
74     NRC_SERVICE_NOT_SUPPORTED = 0x11,
75     NRC_SUB_FUNCTION_NOT_SUPPORTED = 0x12,
76     NRC_CONDITIONS_NOT_CORRECT = 0x22,
77     NRC_REQUEST_OUT_OF_RANGE = 0x31,
78     NRC_SECURITY_ACCESS_DENIED = 0x33,
79     NRC_INVALID_KEY = 0x35,
80     NRC_TOO_MANY_ATTEMPS = 0x36,
81     NRC_TIME_DELAY_NOT_EXPIRED = 0x37,
82     NRC_RESPONSE_PENDING = 0x78
83 } DiagnosticNegativeResponseCode;
84
85 /* Public: A partially or fully completed response to a diagnostic request.
86  *
87  * completed - True if the request is complete - some functions return a
88  *      DiagnosticResponse even when it's only partially completed, so be sure
89  *      to check this field.
90  * success - True if the request was successful. The value if this
91  *      field isn't valid if 'completed' isn't true. If this is 'false', check
92  *      the negative_response_code field for the reason.
93  * arbitration_id - The arbitration ID the response was received on.
94  * mode - The OBD-II mode for the original request.
95  * has_pid - If this is a response to a PID request, this will be true and the
96  *      'pid' field will be valid.
97  * pid - If the request was for a PID, this is the PID echo. Only valid if
98  *      'has_pid' is true.
99  * negative_response_code - If the request was not successful, 'success' will be
100  *      false and this will be set to a DiagnosticNegativeResponseCode returned
101  *      by the other node.
102  * payload - An optional payload for the response - NULL if no payload.
103  * payload_length - The length of the payload or 0 if none.
104  */
105 typedef struct {
106     bool completed;
107     bool success;
108     uint16_t arbitration_id;
109     uint8_t mode;
110     bool has_pid;
111     uint16_t pid;
112     DiagnosticNegativeResponseCode negative_response_code;
113     uint8_t payload[MAX_UDS_PAYLOAD_LENGTH];
114     uint8_t payload_length;
115 } DiagnosticResponse;
116
117 /* Public: Friendly names for all OBD-II modes.
118  */
119 typedef enum {
120     OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST = 0x1,
121     OBD2_MODE_POWERTRAIN_FREEZE_FRAME_REQUEST = 0x2,
122     OBD2_MODE_EMISSIONS_DTC_REQUEST = 0x3,
123     OBD2_MODE_EMISSIONS_DTC_CLEAR = 0x4,
124     // 0x5 is for non-CAN only
125     // OBD2_MODE_OXYGEN_SENSOR_TEST = 0x5,
126     OBD2_MODE_TEST_RESULTS = 0x6,
127     OBD2_MODE_DRIVE_CYCLE_DTC_REQUEST = 0x7,
128     OBD2_MODE_CONTROL = 0x8,
129     OBD2_MODE_VEHICLE_INFORMATION = 0x9,
130     OBD2_MODE_PERMANENT_DTC_REQUEST = 0xa,
131     // this one isn't technically in uds, but both of the enhanced standards
132     // have their PID requests at 0x22
133     OBD2_MODE_ENHANCED_DIAGNOSTIC_REQUEST = 0x22
134 } DiagnosticMode;
135
136 /* Public the signature for an optional function to be called when a diagnostic
137  * request is complete, and a response is received or there is a fatal error.
138  *
139  * response - the completed DiagnosticResponse.
140  */
141 typedef void (*DiagnosticResponseReceived)(const DiagnosticResponse* response);
142
143 typedef float (*DiagnosticResponseDecoder)(const DiagnosticResponse* response);
144
145 /* Public: A handle for initiating and continuing a single diagnostic request.
146  *
147  * A diagnostic request requires one or more CAN messages to be sent, and one
148  * or more CAN messages to be received before it is completed. This struct
149  * encapsulates the local state required to track the request while it is in
150  * progress.
151  *
152  * request - The original DiagnosticRequest that this handle was created for.
153  * completed - True if the request was completed successfully, or was otherwise
154  *      cancelled.
155  * success - True if the request send and receive process was successful. The
156  *      value if this field isn't valid if 'completed' isn't true.
157  */
158 typedef struct {
159     DiagnosticRequest request;
160     bool success;
161     bool completed;
162
163     // Private
164     IsoTpShims isotp_shims;
165     IsoTpSendHandle isotp_send_handle;
166     IsoTpReceiveHandle isotp_receive_handles[MAX_RESPONDING_ECU_COUNT];
167     uint8_t isotp_receive_handle_count;
168     DiagnosticResponseReceived callback;
169     // DiagnosticMilStatusReceived mil_status_callback;
170     // DiagnosticVinReceived vin_callback;
171 } DiagnosticRequestHandle;
172
173 /* Public: The two major types of PIDs that determine the OBD-II mode and PID
174  * field length.
175  */
176 typedef enum {
177     DIAGNOSTIC_STANDARD_PID,
178     DIAGNOSTIC_ENHANCED_PID
179 } DiagnosticPidRequestType;
180
181 /* Public: A container for the 3 shim functions used by the library to interact
182  * with the wider system.
183  *
184  * Use the diagnostic_init_shims(...) function to create an instance of this
185  * struct.
186  */
187 typedef struct {
188     LogShim log;
189     SendCanMessageShim send_can_message;
190     SetTimerShim set_timer;
191 } DiagnosticShims;
192
193 #ifdef __cplusplus
194 }
195 #endif
196
197 #endif // __UDS_TYPES_H__