448c0cd623983d17b7b32c010fae9500ab410036
[apps/agl-service-can-low-level.git] / tests / test_core.c
1 #include <uds/uds.h>
2 #include <check.h>
3 #include <stdint.h>
4 #include <stdio.h>
5 #include <stdbool.h>
6
7 extern bool can_frame_was_sent;
8 extern void setup();
9 extern bool last_response_was_received;
10 extern DiagnosticResponse last_response_received;
11 extern DiagnosticShims SHIMS;
12 extern uint16_t last_can_frame_sent_arb_id;
13 extern uint8_t last_can_payload_sent[8];
14 extern uint8_t last_can_payload_size;
15
16 void response_received_handler(const DiagnosticResponse* response) {
17     last_response_was_received = true;
18     last_response_received = *response;
19 }
20
21 START_TEST (test_receive_wrong_arb_id)
22 {
23     DiagnosticRequest request = {
24         arbitration_id: 0x100,
25         mode: OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST
26     };
27     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
28             response_received_handler);
29
30     fail_if(last_response_was_received);
31     const uint8_t can_data[] = {0x2, request.mode + 0x40, 0x23};
32     diagnostic_receive_can_frame(&SHIMS, &handle, request.arbitration_id,
33             can_data, sizeof(can_data));
34     fail_if(last_response_was_received);
35 }
36 END_TEST
37
38 START_TEST (test_send_diag_request_with_payload)
39 {
40     DiagnosticRequest request = {
41         arbitration_id: 0x100,
42         mode: OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST,
43         payload: {0x12, 0x34},
44         payload_length: 2,
45         no_frame_padding: true
46     };
47     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
48             response_received_handler);
49
50     fail_if(handle.completed);
51     // TODO it'd be better to check the ISO-TP message instead of the CAN frame,
52     // but we don't have a good way to do that
53     ck_assert_int_eq(last_can_frame_sent_arb_id, request.arbitration_id);
54     ck_assert_int_eq(last_can_payload_sent[1], request.mode);
55     ck_assert_int_eq(last_can_payload_size, 4);
56     ck_assert_int_eq(last_can_payload_sent[2], request.payload[0]);
57     ck_assert_int_eq(last_can_payload_sent[3], request.payload[1]);
58 }
59 END_TEST
60
61 START_TEST (test_send_functional_request)
62 {
63     DiagnosticRequest request = {
64         arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID,
65         mode: OBD2_MODE_EMISSIONS_DTC_REQUEST,
66         no_frame_padding: true
67     };
68     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
69             response_received_handler);
70
71     fail_if(handle.completed);
72     ck_assert_int_eq(last_can_frame_sent_arb_id, request.arbitration_id);
73     ck_assert_int_eq(last_can_payload_sent[1], request.mode);
74     ck_assert_int_eq(last_can_payload_size, 2);
75
76     fail_if(last_response_was_received);
77     const uint8_t can_data[] = {0x2, request.mode + 0x40, 0x23};
78     for(uint16_t filter = OBD2_FUNCTIONAL_RESPONSE_START; filter <
79             OBD2_FUNCTIONAL_RESPONSE_START + OBD2_FUNCTIONAL_RESPONSE_COUNT;
80             filter++) {
81         DiagnosticResponse response = diagnostic_receive_can_frame(&SHIMS,
82                 &handle, filter, can_data, sizeof(can_data));
83         fail_unless(response.success);
84         fail_unless(response.completed);
85         fail_unless(handle.completed);
86         ck_assert(last_response_received.success);
87         ck_assert_int_eq(last_response_received.arbitration_id,
88                 filter);
89         ck_assert_int_eq(last_response_received.mode, request.mode);
90         fail_if(last_response_received.has_pid);
91         ck_assert_int_eq(last_response_received.payload_length, 1);
92         ck_assert_int_eq(last_response_received.payload[0], can_data[2]);
93     }
94 }
95 END_TEST
96
97 START_TEST (test_sent_message_no_padding)
98 {
99     DiagnosticRequest request = {
100         arbitration_id: 0x100,
101         mode: OBD2_MODE_EMISSIONS_DTC_REQUEST,
102         no_frame_padding: true
103     };
104     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
105             response_received_handler);
106
107     fail_if(handle.completed);
108     ck_assert_int_eq(last_can_frame_sent_arb_id, request.arbitration_id);
109     ck_assert_int_eq(last_can_payload_size, 2);
110 }
111 END_TEST
112
113 START_TEST (test_sent_message_is_padded_by_default)
114 {
115     DiagnosticRequest request = {
116         arbitration_id: 0x100,
117         mode: OBD2_MODE_EMISSIONS_DTC_REQUEST
118     };
119     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
120             response_received_handler);
121
122     fail_if(handle.completed);
123     ck_assert_int_eq(last_can_frame_sent_arb_id, request.arbitration_id);
124     ck_assert_int_eq(last_can_payload_size, 8);
125 }
126 END_TEST
127
128 START_TEST (test_sent_message_is_padded)
129 {
130     DiagnosticRequest request = {
131         arbitration_id: 0x100,
132         mode: OBD2_MODE_EMISSIONS_DTC_REQUEST,
133         no_frame_padding: false
134     };
135     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
136             response_received_handler);
137
138     fail_if(handle.completed);
139     ck_assert_int_eq(last_can_frame_sent_arb_id, request.arbitration_id);
140     ck_assert_int_eq(last_can_payload_size, 8);
141 }
142 END_TEST
143
144 START_TEST (test_send_diag_request)
145 {
146     DiagnosticRequest request = {
147         arbitration_id: 0x100,
148         mode: OBD2_MODE_EMISSIONS_DTC_REQUEST,
149         no_frame_padding: true
150     };
151     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
152             response_received_handler);
153
154     fail_if(handle.completed);
155     fail_unless(can_frame_was_sent);
156     ck_assert_int_eq(last_can_frame_sent_arb_id, request.arbitration_id);
157     ck_assert_int_eq(last_can_payload_sent[1], request.mode);
158     ck_assert_int_eq(last_can_payload_size, 2);
159
160     fail_if(last_response_was_received);
161     const uint8_t can_data[] = {0x2, request.mode + 0x40, 0x23};
162     DiagnosticResponse response = diagnostic_receive_can_frame(&SHIMS, &handle,
163             request.arbitration_id + 0x8, can_data, sizeof(can_data));
164     fail_unless(response.success);
165     fail_unless(response.completed);
166     fail_unless(handle.completed);
167     ck_assert(last_response_received.success);
168     ck_assert_int_eq(last_response_received.arbitration_id,
169             request.arbitration_id + 0x8);
170     ck_assert_int_eq(last_response_received.mode, request.mode);
171         fail_if(last_response_received.has_pid);
172     ck_assert_int_eq(last_response_received.payload_length, 1);
173     ck_assert_int_eq(last_response_received.payload[0], can_data[2]);
174 }
175 END_TEST
176
177 START_TEST (test_generate_then_send_request)
178 {
179     DiagnosticRequest request = {
180         arbitration_id: 0x100,
181         mode: OBD2_MODE_EMISSIONS_DTC_REQUEST,
182         no_frame_padding: true
183     };
184     DiagnosticRequestHandle handle = generate_diagnostic_request(&SHIMS,
185             &request, response_received_handler);
186
187     fail_if(handle.completed);
188     fail_if(can_frame_was_sent);
189
190     start_diagnostic_request(&SHIMS, &handle);
191     fail_unless(can_frame_was_sent);
192     ck_assert_int_eq(last_can_frame_sent_arb_id, request.arbitration_id);
193     ck_assert_int_eq(last_can_payload_sent[1], request.mode);
194     ck_assert_int_eq(last_can_payload_size, 2);
195
196     fail_if(last_response_was_received);
197     const uint8_t can_data[] = {0x2, request.mode + 0x40, 0x23};
198     DiagnosticResponse response = diagnostic_receive_can_frame(&SHIMS, &handle,
199             request.arbitration_id + 0x8, can_data, sizeof(can_data));
200     fail_unless(response.success);
201     fail_unless(response.completed);
202     fail_unless(handle.completed);
203     ck_assert(last_response_received.success);
204     ck_assert_int_eq(last_response_received.arbitration_id,
205             request.arbitration_id + 0x8);
206     ck_assert_int_eq(last_response_received.mode, request.mode);
207         fail_if(last_response_received.has_pid);
208     ck_assert_int_eq(last_response_received.payload_length, 1);
209     ck_assert_int_eq(last_response_received.payload[0], can_data[2]);
210 }
211 END_TEST
212
213 START_TEST (test_generate_diag_request)
214 {
215     DiagnosticRequest request = {
216         arbitration_id: 0x100,
217         mode: OBD2_MODE_EMISSIONS_DTC_REQUEST,
218         no_frame_padding: true
219     };
220     DiagnosticRequestHandle handle = generate_diagnostic_request(&SHIMS,
221             &request, response_received_handler);
222
223     fail_if(handle.completed);
224     fail_if(can_frame_was_sent);
225 }
226 END_TEST
227
228 START_TEST (test_autoset_pid_length)
229 {
230     uint16_t arb_id = OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST;
231     diagnostic_request_pid(&SHIMS, DIAGNOSTIC_STANDARD_PID, arb_id, 0x2,
232             response_received_handler);
233
234     ck_assert_int_eq(last_can_frame_sent_arb_id, arb_id);
235     ck_assert_int_eq(last_can_payload_sent[1], 0x1);
236     ck_assert_int_eq(last_can_payload_sent[2], 0x2);
237     // padding is on for the diagnostic_request_pid helper function - if you
238     // need to turn it off, use the more manual diagnostic_request(...)
239     ck_assert_int_eq(last_can_payload_size, 8);
240
241     DiagnosticRequest request = {
242         arbitration_id: 0x100,
243         mode: 0x22,
244         has_pid: true,
245         pid: 2,
246         no_frame_padding: true
247     };
248     diagnostic_request(&SHIMS, &request, response_received_handler);
249
250     ck_assert_int_eq(last_can_frame_sent_arb_id, request.arbitration_id);
251     ck_assert_int_eq(last_can_payload_sent[1], request.mode);
252     ck_assert_int_eq(last_can_payload_size, 4);
253 }
254 END_TEST
255
256 START_TEST (test_request_pid_standard)
257 {
258     uint16_t arb_id = OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST;
259     DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
260             DIAGNOSTIC_STANDARD_PID, arb_id, 0x2, response_received_handler);
261
262     fail_if(last_response_was_received);
263     const uint8_t can_data[] = {0x3, 0x1 + 0x40, 0x2, 0x45};
264     diagnostic_receive_can_frame(&SHIMS, &handle, arb_id + 0x8,
265             can_data, sizeof(can_data));
266     fail_unless(last_response_was_received);
267     ck_assert(last_response_received.success);
268     ck_assert_int_eq(last_response_received.arbitration_id,
269             arb_id + 0x8);
270     ck_assert_int_eq(last_response_received.mode, 0x1);
271     fail_unless(last_response_received.has_pid);
272     ck_assert_int_eq(last_response_received.pid, 0x2);
273     ck_assert_int_eq(last_response_received.payload_length, 1);
274     ck_assert_int_eq(last_response_received.payload[0], can_data[3]);
275 }
276 END_TEST
277
278 START_TEST (test_request_pid_enhanced)
279 {
280     uint16_t arb_id = 0x100;
281     DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
282             DIAGNOSTIC_ENHANCED_PID, arb_id, 0x2, response_received_handler);
283
284     fail_if(last_response_was_received);
285     const uint8_t can_data[] = {0x4, 0x22 + 0x40, 0x0, 0x2, 0x45};
286     diagnostic_receive_can_frame(&SHIMS, &handle, arb_id + 0x8, can_data,
287             sizeof(can_data));
288     fail_unless(last_response_was_received);
289     ck_assert(last_response_received.success);
290     ck_assert_int_eq(last_response_received.arbitration_id,
291             arb_id + 0x8);
292     ck_assert_int_eq(last_response_received.mode, 0x22);
293     fail_unless(last_response_received.has_pid);
294     ck_assert_int_eq(last_response_received.pid, 0x2);
295     ck_assert_int_eq(last_response_received.payload_length, 1);
296     ck_assert_int_eq(last_response_received.payload[0], can_data[4]);
297 }
298 END_TEST
299
300 START_TEST (test_wrong_mode_response)
301 {
302     uint16_t arb_id = 0x100;
303     DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
304             DIAGNOSTIC_ENHANCED_PID, arb_id, 0x2, response_received_handler);
305
306     fail_if(last_response_was_received);
307     const uint8_t can_data[] = {0x4, 0x1 + 0x40, 0x0, 0x2, 0x45};
308     diagnostic_receive_can_frame(&SHIMS, &handle, arb_id + 0x8, can_data,
309             sizeof(can_data));
310     fail_if(last_response_was_received);
311     fail_if(handle.completed);
312 }
313 END_TEST
314
315 START_TEST (test_missing_pid)
316 {
317     uint16_t arb_id = 0x100;
318     DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
319             DIAGNOSTIC_ENHANCED_PID, arb_id, 0x2, response_received_handler);
320
321     fail_if(last_response_was_received);
322     const uint8_t can_data[] = {0x1, 0x22 + 0x40};
323     diagnostic_receive_can_frame(&SHIMS, &handle, arb_id + 0x8, can_data,
324             sizeof(can_data));
325     fail_if(last_response_was_received);
326     fail_if(handle.completed);
327 }
328 END_TEST
329
330 START_TEST (test_wrong_pid_response)
331 {
332     uint16_t arb_id = 0x100;
333     DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
334             DIAGNOSTIC_ENHANCED_PID, arb_id, 0x2, response_received_handler);
335
336     fail_if(last_response_was_received);
337     const uint8_t can_data[] = {0x4, 0x22 + 0x40, 0x0, 0x3, 0x45};
338     diagnostic_receive_can_frame(&SHIMS, &handle, arb_id + 0x8, can_data,
339             sizeof(can_data));
340     fail_if(last_response_was_received);
341     fail_if(handle.completed);
342 }
343 END_TEST
344
345 START_TEST (test_wrong_pid_then_right_completes)
346 {
347     uint16_t arb_id = 0x100;
348     DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
349             DIAGNOSTIC_ENHANCED_PID, arb_id, 0x2, response_received_handler);
350
351     fail_if(last_response_was_received);
352     uint8_t can_data[] = {0x4, 0x22 + 0x40, 0x0, 0x3, 0x45};
353     diagnostic_receive_can_frame(&SHIMS, &handle, arb_id + 0x8, can_data,
354             sizeof(can_data));
355     fail_if(last_response_was_received);
356     fail_if(handle.completed);
357
358     can_data[3] = 0x2;
359     diagnostic_receive_can_frame(&SHIMS, &handle, arb_id + 0x8, can_data,
360             sizeof(can_data));
361     fail_unless(last_response_was_received);
362     fail_unless(handle.completed);
363     fail_unless(handle.success);
364     fail_unless(last_response_received.success);
365     ck_assert_int_eq(last_response_received.pid, 0x2);
366 }
367 END_TEST
368
369 START_TEST (test_negative_response)
370 {
371     DiagnosticRequest request = {
372         arbitration_id: 0x100,
373         mode: OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST
374     };
375     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
376             response_received_handler);
377     const uint8_t can_data[] = {0x3, 0x7f, request.mode,
378         NRC_SERVICE_NOT_SUPPORTED};
379     DiagnosticResponse response = diagnostic_receive_can_frame(&SHIMS, &handle,
380             request.arbitration_id + 0x8, can_data, sizeof(can_data));
381     fail_unless(response.completed);
382     fail_if(response.success);
383     fail_unless(handle.completed);
384
385     fail_if(last_response_received.success);
386     ck_assert_int_eq(last_response_received.arbitration_id,
387             request.arbitration_id + 0x8);
388     ck_assert_int_eq(last_response_received.mode, request.mode);
389     ck_assert_int_eq(last_response_received.pid, 0);
390     ck_assert_int_eq(last_response_received.negative_response_code,
391             NRC_SERVICE_NOT_SUPPORTED);
392     ck_assert_int_eq(last_response_received.payload_length, 0);
393 }
394 END_TEST
395
396 START_TEST (test_payload_to_integer)
397 {
398     uint16_t arb_id = OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST;
399     DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
400             DIAGNOSTIC_STANDARD_PID, arb_id, 0x2, response_received_handler);
401
402     fail_if(last_response_was_received);
403     const uint8_t can_data[] = {0x4, 0x1 + 0x40, 0x2, 0x45, 0x12};
404     DiagnosticResponse response = diagnostic_receive_can_frame(&SHIMS, &handle,
405             arb_id + 0x8, can_data, sizeof(can_data));
406     ck_assert_int_eq(diagnostic_payload_to_integer(&response), 0x4512);
407 }
408 END_TEST
409
410 Suite* testSuite(void) {
411     Suite* s = suite_create("uds");
412     TCase *tc_core = tcase_create("core");
413     tcase_add_checked_fixture(tc_core, setup, NULL);
414     tcase_add_test(tc_core, test_sent_message_no_padding);
415     tcase_add_test(tc_core, test_sent_message_is_padded);
416     tcase_add_test(tc_core, test_sent_message_is_padded_by_default);
417     tcase_add_test(tc_core, test_generate_diag_request);
418     tcase_add_test(tc_core, test_generate_then_send_request);
419     tcase_add_test(tc_core, test_send_diag_request);
420     tcase_add_test(tc_core, test_send_functional_request);
421     tcase_add_test(tc_core, test_send_diag_request_with_payload);
422     tcase_add_test(tc_core, test_receive_wrong_arb_id);
423     tcase_add_test(tc_core, test_autoset_pid_length);
424     tcase_add_test(tc_core, test_request_pid_standard);
425     tcase_add_test(tc_core, test_request_pid_enhanced);
426     tcase_add_test(tc_core, test_wrong_mode_response);
427     tcase_add_test(tc_core, test_wrong_pid_response);
428     tcase_add_test(tc_core, test_missing_pid);
429     tcase_add_test(tc_core, test_wrong_pid_then_right_completes);
430     tcase_add_test(tc_core, test_negative_response);
431     tcase_add_test(tc_core, test_payload_to_integer);
432
433     // TODO these are future work:
434     // TODO test request MIL
435     // TODO test request VIN
436     // TODO test request DTC
437     // TODO test clear DTC
438     // TODO test enumerate PIDs
439     suite_add_tcase(s, tc_core);
440
441     return s;
442 }
443
444 int main(void) {
445     int numberFailed;
446     Suite* s = testSuite();
447     SRunner *sr = srunner_create(s);
448     // Don't fork so we can actually use gdb
449     srunner_set_fork_status(sr, CK_NOFORK);
450     srunner_run_all(sr, CK_NORMAL);
451     numberFailed = srunner_ntests_failed(sr);
452     srunner_free(sr);
453     return (numberFailed == 0) ? 0 : 1;
454 }