Quiet some misleading log messages.
[apps/low-level-can-service.git] / README.mkd
1 Unified Diagnostic Services (UDS) Support Library in C
2 ======================================================
3
4 This is a platform agnostic C library that implements the Unified Diagnostics
5 Services protocol for automotive electronics. UDS is documented in ISO 14229 and
6 is the underpinning for the more well-known On-board Diagnostics (OBD) standard.
7 The library currently supports UDS running over CAN (ISO 15765-4), which uses
8 the ISO-TP (ISO 15765-2) protocol for message framing.
9
10 This library doesn't assume anything about the source of your diagnostic message
11 requests or underlying interface to the CAN bus. It uses dependency injection to
12 give you complete control.
13
14 ## Usage
15
16 First, create some shim functions to let this library use your lower level
17 system:
18
19     // required, this must send a single CAN message with the given arbitration
20     // ID (i.e. the CAN message ID) and data. The size will never be more than 8
21     // bytes.
22     bool send_can(const uint16_t arbitration_id, const uint8_t* data,
23             const uint8_t size) {
24         ...
25     }
26
27     // optional, provide to receive debugging log messages
28     void debug(const char* format, ...) {
29         ...
30     }
31
32
33     // not used in the current version
34     void set_timer(uint16_t time_ms, void (*callback)) {
35         ...
36     }
37
38 With your shims in place, create a `DiagnosticShims` object to pass them around:
39
40     DiagnosticShims shims = diagnostic_init_shims(debug, send_can, set_timer);
41
42 With your shims in hand, send a simple PID request to the standard broadcast
43 address, `0x7df` (we use the constant `OBD2_FUNCTIONAL_BROADCAST_ID` here):
44
45     // Optional: This is your callback that will be called the response to your
46     // diagnostic request is received.
47     void response_received_handler(const DiagnosticResponse* response) {
48         // You received a response! Do something with it.
49     }
50
51     DiagnosticRequestHandle handle = diagnostic_request_pid(&shims,
52             DIAGNOSTIC_STANDARD_PID, // this is a standard PID request, not an extended or enhanced one
53             OBD2_FUNCTIONAL_BROADCAST_ID, // the request is going out to the broadcast arbitration ID
54             0x2, // we want PID 0x2
55             response_received_handler); // our callback (optional, use NULL if you don't have one)
56
57     if(handle.completed) {
58         if(!handle.success) {
59             // something happened and it already failed - possibly we aren't
60             // able to send CAN messages
61             return;
62         } else {
63             // this should never occur right away - you need to receive a fresh
64             // CAN message first
65         }
66     } else {
67         while(true) {
68             // Continue to read from CAN, passing off each message to the handle.
69             // This will return a 'completed' DiagnosticResponse when the when
70             // the request is completely sent and the response is received
71             // (which may take more than 1 CAN frames)
72             DiagnosticResponse response = diagnostic_receive_can_frame(&shims,
73                 &handle, can_message_id, can_data, sizeof(can_data));
74
75             if(response.completed && handle.completed) {
76                 if(handle.success) {
77                   if(response.success) {
78                       // The request was sent successfully, the response was
79                       // received successfully, and it was a positive response - we
80                       // got back some data!
81                   } else {
82                       // The request was sent successfully, the response was
83                       // received successfully, BUT it was a negative response
84                       // from the other node.
85                       printf("This is the error code: %d", response.negative_response_code);
86                   }
87                 } else {
88                     // Some other fatal error ocurred - we weren't able to send
89                     // the request or receive the response. The CAN connection
90                     // may be down.
91                 }
92             }
93         }
94     }
95
96 ### Requests for other modes
97
98 If you want to do more besides PID requests on mode 0x1 and 0x22, there's a
99 lower level API you can use. Here's how to make a mode 3 request to get DTCs.
100
101     DiagnosticRequest request = {
102         arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID,
103         mode: OBD2_MODE_EMISSIONS_DTC_REQUEST
104     };
105     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request, NULL);
106
107     if(handle.completed) {
108         if(!handle.success) {
109             // something happened and it already failed - possibly we aren't
110             // able to send CAN messages
111             return;
112         } else {
113             // this should never occur right away - you need to receive a fresh
114             // CAN message first
115         }
116     } else {
117         while(true) {
118             // Continue to read from CAN, passing off each message to the handle.
119             // This will return a 'completed' DiagnosticResponse when the when
120             // the request is completely sent and the response is received
121             // (which may take more than 1 CAN frames)
122             DiagnosticResponse response = diagnostic_receive_can_frame(&shims,
123                 &handle, can_message_id, can_data, sizeof(can_data));
124
125             if(response.completed && handle.completed) {
126                 if(handle.success) {
127                   if(response.success) {
128                       // The request was sent successfully, the response was
129                       // received successfully, and it was a positive response - we
130                       // got back some data!
131                       printf("The DTCs are: ");
132                       for(int i = 0; i < response.payload_length; i++) {
133                         printf("0x%x ", response.payload[i]);
134                       }
135                   } else {
136                       // The request was sent successfully, the response was
137                       // received successfully, BUT it was a negative response
138                       // from the other node.
139                       printf("This is the error code: %d", response.negative_response_code);
140                   }
141                 } else {
142                     // Some other fatal error ocurred - we weren't able to send
143                     // the request or receive the response. The CAN connection
144                     // may be down.
145                 }
146             }
147         }
148     }
149
150 ## Dependencies
151
152 This library requires 2 dependencies:
153
154 * [isotp-c](https://github.com/openxc/isotp-c)
155 * [bitfield-c](https://github.com/openxc/bitfield-c)
156
157 ## Testing
158
159 The library includes a test suite that uses the `check` C unit test library.
160
161     $ make test
162
163 You can also see the test coverage if you have `lcov` installed and the
164 `BROWSER` environment variable set to your choice of web browsers:
165
166     $ BROWSER=google-chrome-stable make coverage
167
168 ## OBD-II Basics
169
170 TODO diagram out a request, response and error response
171
172 * store the request arb id, mode, pid, and payload locally
173 * send a can message
174 * get all new can messages passed to it
175 * Check the incoming can message to see if it matches one of the standard ECU
176   response IDs, or our arb ID + 0x8
177 * if it matches, parse the diagnostic response and call the callback
178
179
180 ## Future Notes
181
182 you're going to request a few PIDs over and over again at some frequency
183 you're going to request DTCs once and read the response
184 you're going to clear DTCs once
185
186 we need another layer on top of that to handle the repeated requests.
187
188 ## Authors
189
190 Chris Peplin cpeplin@ford.com
191
192 ## License
193
194 Copyright (c) 2013 Ford Motor Company
195
196 Licensed under the BSD license.