8 extern bool last_response_was_received;
9 extern DiagnosticResponse last_response_received;
10 extern DiagnosticShims SHIMS;
12 void response_received_handler(const DiagnosticResponse* response) {
13 last_response_was_received = true;
14 // TODO not sure if we can copy the struct like this
15 last_response_received = *response;
18 START_TEST (test_receive_wrong_arb_id)
20 DiagnosticRequest request = {
21 arbitration_id: 0x7df,
22 mode: OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST
24 DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
25 response_received_handler);
27 fail_if(last_response_was_received);
28 const uint8_t can_data[] = {0x2, request.mode + 0x40, 0x23};
29 diagnostic_receive_can_frame(&SHIMS, &handle, request.arbitration_id,
30 can_data, sizeof(can_data));
31 fail_if(last_response_was_received);
35 START_TEST (test_send_diag_request)
37 DiagnosticRequest request = {
38 arbitration_id: 0x7df,
39 mode: OBD2_MODE_POWERTRAIN_DIAGNOSTIC_REQUEST
41 DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request,
42 response_received_handler);
44 fail_if(handle.completed);
46 fail_if(last_response_was_received);
47 const uint8_t can_data[] = {0x2, request.mode + 0x40, 0x23};
48 DiagnosticResponse response = diagnostic_receive_can_frame(&SHIMS, &handle,
49 request.arbitration_id + 0x8, can_data, sizeof(can_data));
50 fail_unless(response.success);
51 fail_unless(response.completed);
52 fail_unless(handle.completed);
53 ck_assert(last_response_received.success);
54 ck_assert_int_eq(last_response_received.arbitration_id,
55 request.arbitration_id + 0x8);
56 ck_assert_int_eq(last_response_received.mode, request.mode);
57 ck_assert_int_eq(last_response_received.pid, 0);
58 ck_assert_int_eq(last_response_received.payload_length, 1);
59 ck_assert_int_eq(last_response_received.payload[0], can_data[2]);
63 START_TEST (test_request_pid_standard)
65 DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
66 DIAGNOSTIC_STANDARD_PID, 0x2, response_received_handler);
68 fail_if(last_response_was_received);
69 const uint8_t can_data[] = {0x3, 0x1 + 0x40, 0x2, 0x45};
70 // TODO need a constant for the 7df broadcast functional request
71 diagnostic_receive_can_frame(&SHIMS, &handle, 0x7df + 0x8,
72 can_data, sizeof(can_data));
73 fail_unless(last_response_was_received);
74 ck_assert(last_response_received.success);
75 ck_assert_int_eq(last_response_received.arbitration_id,
77 ck_assert_int_eq(last_response_received.mode, 0x1);
78 ck_assert_int_eq(last_response_received.pid, 0x2);
79 ck_assert_int_eq(last_response_received.payload_length, 1);
80 ck_assert_int_eq(last_response_received.payload[0], can_data[3]);
84 START_TEST (test_request_pid_enhanced)
86 DiagnosticRequestHandle handle = diagnostic_request_pid(&SHIMS,
87 DIAGNOSTIC_ENHANCED_PID, 0x2, response_received_handler);
89 fail_if(last_response_was_received);
90 const uint8_t can_data[] = {0x4, 0x1 + 0x40, 0x0, 0x2, 0x45};
91 // TODO need a constant for the 7df broadcast functional request
92 diagnostic_receive_can_frame(&SHIMS, &handle, 0x7df + 0x8, can_data,
94 fail_unless(last_response_was_received);
95 ck_assert(last_response_received.success);
96 ck_assert_int_eq(last_response_received.arbitration_id,
98 // TODO should we set it back to the original mode, or leave as mode + 0x40?
99 ck_assert_int_eq(last_response_received.mode, 0x22);
100 ck_assert_int_eq(last_response_received.pid, 0x2);
101 ck_assert_int_eq(last_response_received.payload_length, 1);
102 ck_assert_int_eq(last_response_received.payload[0], can_data[4]);
106 Suite* testSuite(void) {
107 Suite* s = suite_create("obd2");
108 TCase *tc_core = tcase_create("core");
109 tcase_add_checked_fixture(tc_core, setup, NULL);
110 tcase_add_test(tc_core, test_send_diag_request);
111 tcase_add_test(tc_core, test_receive_wrong_arb_id);
112 tcase_add_test(tc_core, test_request_pid_standard);
113 tcase_add_test(tc_core, test_request_pid_enhanced);
115 // TODO these are future work:
116 // TODO test request MIL
117 // TODO test request VIN
118 // TODO test request DTC
119 // TODO test clear DTC
120 // TODO test enumerate PIDs
121 suite_add_tcase(s, tc_core);
128 Suite* s = testSuite();
129 SRunner *sr = srunner_create(s);
130 // Don't fork so we can actually use gdb
131 srunner_set_fork_status(sr, CK_NOFORK);
132 srunner_run_all(sr, CK_NORMAL);
133 numberFailed = srunner_ntests_failed(sr);
135 return (numberFailed == 0) ? 0 : 1;