51dff33f76b2f20eb49bbeef5ce7665ed5acb802
[apps/agl-service-can-low-level.git] / tests / test_core.c
1 #include <obd2/obd2.h>
2 #include <check.h>
3 #include <stdint.h>
4 #include <stdio.h>
5 #include <stdbool.h>
6
7 extern void setup();
8 extern bool last_response_was_received;
9 extern DiagnosticResponse last_response_received;
10 extern DiagnosticShims SHIMS;
11 extern uint16_t last_can_frame_sent_arb_id;
12 extern uint8_t last_can_payload_sent[8];
13 extern uint8_t last_can_payload_size;
14
15 void response_received_handler(const DiagnosticResponse* response) {
16     last_response_was_received = true;
17     last_response_received = *response;
18 }
19
20 START_TEST (test_receive_wrong_arb_id)
21 {
22     DiagnosticRequest request = {
23         arbitration_id: 0x7df,
24         mode: OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST
25     };
26     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
27             response_received_handler);
28
29     fail_if(last_response_was_received);
30     const uint8_t can_data[] = {0x2, request.mode + 0x40, 0x23};
31     diagnostic_receive_can_frame(&SHIMS, &handle, request.arbitration_id,
32             can_data, sizeof(can_data));
33     fail_if(last_response_was_received);
34 }
35 END_TEST
36
37 START_TEST (test_send_diag_request_with_payload)
38 {
39     DiagnosticRequest request = {
40         arbitration_id: 0x7df,
41         mode: OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST,
42         payload: {0x12, 0x34},
43         payload_length: 2
44     };
45     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
46             response_received_handler);
47
48     fail_if(handle.completed);
49     // TODO it'd be better to check the ISO-TP message instead of the CAN frame,
50     // but we don't have a good way to do that
51     ck_assert_int_eq(last_can_frame_sent_arb_id, request.arbitration_id);
52     ck_assert_int_eq(last_can_payload_sent[1], request.mode);
53     ck_assert_int_eq(last_can_payload_size, 4);
54     ck_assert_int_eq(last_can_payload_sent[2], request.payload[0]);
55     ck_assert_int_eq(last_can_payload_sent[3], request.payload[1]);
56 }
57 END_TEST
58
59 START_TEST (test_send_diag_request)
60 {
61     DiagnosticRequest request = {
62         arbitration_id: 0x7df,
63         mode: OBD2_MODE_EMISSIONS_DTC_REQUEST
64     };
65     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
66             response_received_handler);
67
68     fail_if(handle.completed);
69     ck_assert_int_eq(last_can_frame_sent_arb_id, request.arbitration_id);
70     ck_assert_int_eq(last_can_payload_sent[1], request.mode);
71     ck_assert_int_eq(last_can_payload_size, 2);
72
73     fail_if(last_response_was_received);
74     const uint8_t can_data[] = {0x2, request.mode + 0x40, 0x23};
75     DiagnosticResponse response = diagnostic_receive_can_frame(&SHIMS, &handle,
76             request.arbitration_id + 0x8, can_data, sizeof(can_data));
77     fail_unless(response.success);
78     fail_unless(response.completed);
79     fail_unless(handle.completed);
80     ck_assert(last_response_received.success);
81     ck_assert_int_eq(last_response_received.arbitration_id,
82             request.arbitration_id + 0x8);
83     ck_assert_int_eq(last_response_received.mode, request.mode);
84     ck_assert_int_eq(last_response_received.pid, 0);
85     ck_assert_int_eq(last_response_received.payload_length, 1);
86     ck_assert_int_eq(last_response_received.payload[0], can_data[2]);
87 }
88 END_TEST
89
90 START_TEST (test_request_pid_standard)
91 {
92     // TODO need a constant for the 7df broadcast functional request
93     uint16_t arb_id = 0x7df;
94     DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
95             DIAGNOSTIC_STANDARD_PID, arb_id, 0x2, response_received_handler);
96
97     fail_if(last_response_was_received);
98     const uint8_t can_data[] = {0x3, 0x1 + 0x40, 0x2, 0x45};
99     diagnostic_receive_can_frame(&SHIMS, &handle, arb_id + 0x8,
100             can_data, sizeof(can_data));
101     fail_unless(last_response_was_received);
102     ck_assert(last_response_received.success);
103     ck_assert_int_eq(last_response_received.arbitration_id,
104             arb_id + 0x8);
105     ck_assert_int_eq(last_response_received.mode, 0x1);
106     ck_assert_int_eq(last_response_received.pid, 0x2);
107     ck_assert_int_eq(last_response_received.payload_length, 1);
108     ck_assert_int_eq(last_response_received.payload[0], can_data[3]);
109 }
110 END_TEST
111
112 START_TEST (test_request_pid_enhanced)
113 {
114     uint16_t arb_id = 0x7df;
115     DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
116             DIAGNOSTIC_ENHANCED_PID, arb_id, 0x2, response_received_handler);
117
118     fail_if(last_response_was_received);
119     const uint8_t can_data[] = {0x4, 0x22 + 0x40, 0x0, 0x2, 0x45};
120     diagnostic_receive_can_frame(&SHIMS, &handle, arb_id + 0x8, can_data,
121             sizeof(can_data));
122     fail_unless(last_response_was_received);
123     ck_assert(last_response_received.success);
124     ck_assert_int_eq(last_response_received.arbitration_id,
125             arb_id + 0x8);
126     ck_assert_int_eq(last_response_received.mode, 0x22);
127     ck_assert_int_eq(last_response_received.pid, 0x2);
128     ck_assert_int_eq(last_response_received.payload_length, 1);
129     ck_assert_int_eq(last_response_received.payload[0], can_data[4]);
130 }
131 END_TEST
132
133 START_TEST (test_wrong_mode_response)
134 {
135     uint16_t arb_id = 0x7df;
136     DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
137             DIAGNOSTIC_ENHANCED_PID, arb_id, 0x2, response_received_handler);
138
139     fail_if(last_response_was_received);
140     const uint8_t can_data[] = {0x4, 0x1 + 0x40, 0x0, 0x2, 0x45};
141     diagnostic_receive_can_frame(&SHIMS, &handle, arb_id + 0x8, can_data,
142             sizeof(can_data));
143     // TODO change this if we even re-request a message receipt on a mode or PID
144     // mismatch
145     fail_unless(last_response_was_received);
146     fail_unless(handle.completed);
147     fail_if(last_response_received.success);
148 }
149 END_TEST
150
151 START_TEST (test_handle_completed)
152 {
153     DiagnosticRequest request = {
154         arbitration_id: 0x7df,
155         mode: OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST
156     };
157     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
158             response_received_handler);
159
160     fail_if(handle.completed);
161
162     const uint8_t can_data[] = {0x2, request.mode + 0x40, 0x23};
163     DiagnosticResponse response = diagnostic_receive_can_frame(&SHIMS, &handle,
164             request.arbitration_id + 0x8, can_data, sizeof(can_data));
165     fail_unless(response.success);
166     fail_unless(response.completed);
167     fail_unless(handle.completed);
168
169     response = diagnostic_receive_can_frame(&SHIMS, &handle,
170             request.arbitration_id + 0x8, can_data, sizeof(can_data));
171     fail_if(response.success);
172     fail_if(response.completed);
173     fail_unless(handle.completed);
174
175     ck_assert(last_response_received.success);
176     ck_assert_int_eq(last_response_received.arbitration_id,
177             request.arbitration_id + 0x8);
178     ck_assert_int_eq(last_response_received.mode, request.mode);
179     ck_assert_int_eq(last_response_received.pid, 0);
180     ck_assert_int_eq(last_response_received.payload_length, 1);
181     ck_assert_int_eq(last_response_received.payload[0], can_data[2]);
182 }
183 END_TEST
184
185 START_TEST (test_negative_response)
186 {
187     DiagnosticRequest request = {
188         arbitration_id: 0x7df,
189         mode: OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST
190     };
191     DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
192             response_received_handler);
193     const uint8_t can_data[] = {0x3, 0x7f, request.mode, NRC_SERVICE_NOT_SUPPORTED};
194     DiagnosticResponse response = diagnostic_receive_can_frame(&SHIMS, &handle,
195             request.arbitration_id + 0x8, can_data, sizeof(can_data));
196     fail_unless(response.completed);
197     fail_if(response.success);
198     fail_unless(handle.completed);
199
200     fail_if(last_response_received.success);
201     ck_assert_int_eq(last_response_received.arbitration_id,
202             request.arbitration_id + 0x8);
203     ck_assert_int_eq(last_response_received.mode, request.mode);
204     ck_assert_int_eq(last_response_received.pid, 0);
205     ck_assert_int_eq(last_response_received.negative_response_code, NRC_SERVICE_NOT_SUPPORTED);
206     ck_assert_int_eq(last_response_received.payload_length, 0);
207 }
208 END_TEST
209
210 Suite* testSuite(void) {
211     Suite* s = suite_create("obd2");
212     TCase *tc_core = tcase_create("core");
213     tcase_add_checked_fixture(tc_core, setup, NULL);
214     tcase_add_test(tc_core, test_send_diag_request);
215     tcase_add_test(tc_core, test_send_diag_request_with_payload);
216     tcase_add_test(tc_core, test_receive_wrong_arb_id);
217     tcase_add_test(tc_core, test_request_pid_standard);
218     tcase_add_test(tc_core, test_request_pid_enhanced);
219     tcase_add_test(tc_core, test_wrong_mode_response);
220     tcase_add_test(tc_core, test_handle_completed);
221     tcase_add_test(tc_core, test_negative_response);
222
223     // TODO these are future work:
224     // TODO test request MIL
225     // TODO test request VIN
226     // TODO test request DTC
227     // TODO test clear DTC
228     // TODO test enumerate PIDs
229     suite_add_tcase(s, tc_core);
230
231     return s;
232 }
233
234 int main(void) {
235     int numberFailed;
236     Suite* s = testSuite();
237     SRunner *sr = srunner_create(s);
238     // Don't fork so we can actually use gdb
239     srunner_set_fork_status(sr, CK_NOFORK);
240     srunner_run_all(sr, CK_NORMAL);
241     numberFailed = srunner_ntests_failed(sr);
242     srunner_free(sr);
243     return (numberFailed == 0) ? 0 : 1;
244 }