diff --git a/AUTHORS.txt b/AUTHORS.txt index 54e074a..2349f5d 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1,2 +1,3 @@ Nick James Kirkby Mark Corbin +Jens Fernández Mühlke diff --git a/src/tp/isotp_sock.c b/src/tp/isotp_sock.c index fdffa29..fde9c9b 100644 --- a/src/tp/isotp_sock.c +++ b/src/tp/isotp_sock.c @@ -147,17 +147,21 @@ static int LinuxSockBind(const char *if_name, uint32_t rxid, uint32_t txid, bool perror("setsockopt"); return -1; } - + + struct can_isotp_options opts; + memset(&opts, 0, sizeof(opts)); + // configure socket to wait for tx completion to catch FC frame timeouts + opts.flags |= CAN_ISOTP_WAIT_TX_DONE; + if (functional) { printf("configuring fd: %d as functional\n", fd); // configure the socket as listen-only to avoid sending FC frames - struct can_isotp_options opts; - memset(&opts, 0, sizeof(opts)); opts.flags |= CAN_ISOTP_LISTEN_MODE; - if (setsockopt(fd, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts)) < 0) { - perror("setsockopt (isotp_options):"); - return -1; - } + } + + if (setsockopt(fd, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts)) < 0) { + perror("setsockopt (isotp_options):"); + return -1; } struct ifreq ifr; diff --git a/test/test_tp_compliance.c b/test/test_tp_compliance.c index 36bd85a..fddee30 100644 --- a/test/test_tp_compliance.c +++ b/test/test_tp_compliance.c @@ -95,6 +95,23 @@ void TestISOTPSendRecvMaxLen(void **state) { assert_memory_equal(UDSTpGetRecvBuf(srv, NULL), MSG, sizeof(MSG)); } +void TestISOTPFlowControlFrameTimeout(void **state) { + if (!IsISOTP()) { + skip(); + } + + // killing server so that no response is sent to client + ENV_TpFree(srv); + + // sending multiframe to wait for Flow Control frame + // which will not arrive since no server is running + const uint8_t MSG[] = {1, 2, 3, 4, 5, 6, 7, 8}; + ssize_t ret = UDSTpSend(client, MSG, sizeof(MSG), NULL); + + // failure is expected as the elapsed 1s timeout raises an error on the ISOTP socket + assert_true(ret < 0); +} + int main() { const struct CMUnitTest tests[] = { // cmocka_unit_test_setup_teardown(TestSendRecv, setup, teardown), @@ -102,6 +119,7 @@ int main() { cmocka_unit_test_setup_teardown(TestISOTPSendLargestSingleFrame, setup, teardown), cmocka_unit_test_setup_teardown(TestISOTPSendLargerThanSingleFrameFails, setup, teardown), cmocka_unit_test_setup_teardown(TestISOTPSendRecvMaxLen, setup, teardown), + cmocka_unit_test_setup_teardown(TestISOTPFlowControlFrameTimeout, setup, teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); }