diff options
-rw-r--r-- | src/isotp/isotp.c | 40 | ||||
-rw-r--r-- | src/isotp/isotp.h | 12 | ||||
-rw-r--r-- | tests/common.c | 18 | ||||
-rw-r--r-- | tests/test_send.c | 24 |
4 files changed, 80 insertions, 14 deletions
diff --git a/src/isotp/isotp.c b/src/isotp/isotp.c index af9c2631..1514625d 100644 --- a/src/isotp/isotp.c +++ b/src/isotp/isotp.c @@ -7,6 +7,12 @@ const uint16_t MAX_CAN_FRAME_SIZE = 8; const uint8_t ISO_TP_DEFAULT_RESPONSE_TIMEOUT = 100; const bool ISO_TP_DEFAULT_FRAME_PADDING_STATUS = true; +const uint8_t PCI_START_BIT = 0; +const uint8_t PCI_WIDTH = 4; +const uint8_t PAYLOAD_LENGTH_START_BIT = 4; +const uint8_t PAYLOAD_LENGTH_WIDTH = 4; +const uint8_t PAYLOAD_START_BIT = 8; + void isotp_receive_can_frame(IsoTpHandler* handler, const uint16_t arbitration_id, const uint64_t data, const uint8_t length) { @@ -39,10 +45,42 @@ void isotp_receive_can_frame(IsoTpHandler* handler, } } -bool isotp_send(const uint8_t* payload, uint16_t size) { +void isotp_complete_send(IsoTpHandler* handler, const uint8_t* payload, + uint8_t size, bool status) { + handler->message_sent_callback(handler->arbitration_id, payload, size, + status); +} + +bool isotp_send_single_frame(IsoTpHandler* handler, const uint8_t* payload, + uint8_t size) { + uint64_t data; + setBitField(&data, PCI_SINGLE, PCI_START_BIT, PCI_WIDTH); + setBitField(&data, size, PAYLOAD_LENGTH_START_BIT, PAYLOAD_LENGTH_WIDTH); + // TODO this is probably wrong + if(size > 0) { + setBitField(&data, *payload, PAYLOAD_START_BIT, size * 8); + } + handler->shims->send_can_message(handler->arbitration_id, payload, size); + isotp_complete_send(handler, payload, size, true); + return true; +} + +bool isotp_send_multi_frame(IsoTpHandler* handler, const uint8_t* payload, + uint16_t size) { + return false; +} + +bool isotp_send(IsoTpHandler* handler, const uint8_t* payload, + uint16_t size) { // we determine if it's single/multi frame and start the send + if(size < 8) { + return isotp_send_single_frame(handler, payload, size); + } else { + return isotp_send_multi_frame(handler, payload, size); + } } + void isotp_set_timeout(IsoTpHandler* handler, uint16_t timeout_ms) { handler->timeout_ms = timeout_ms; } diff --git a/src/isotp/isotp.h b/src/isotp/isotp.h index f1719548..7ea0190c 100644 --- a/src/isotp/isotp.h +++ b/src/isotp/isotp.h @@ -14,15 +14,14 @@ const uint8_t ISO_TP_DEFAULT_RESPONSE_TIMEOUT; const bool ISO_TP_DEFAULT_FRAME_PADDING_STATUS; typedef void (*LogShim)(const char* message); -typedef bool (*SendCanMessageShim)(const uint16_t arbitration_id, const uint8_t* data, - const uint8_t size); +typedef bool (*SendCanMessageShim)(const uint16_t arbitration_id, + const uint8_t* data, const uint8_t size); typedef bool (*SetTimerShim)(uint16_t time_ms, void (*callback)); typedef void (*IsoTpMessageReceivedHandler)(const uint16_t arbitration_id, const uint8_t* payload, const uint16_t size); -typedef void (*IsoTpMessageSentHandler)(const bool success, - const uint16_t arbitration_id, const uint8_t* payload, - const uint16_t size); +typedef void (*IsoTpMessageSentHandler)(const uint16_t arbitration_id, + const uint8_t* payload, const uint16_t size, const bool success); typedef void (*IsoTpCanFrameSentHandler)(const uint16_t arbitration_id, const uint8_t* payload, const uint8_t size); @@ -91,7 +90,8 @@ void isotp_set_timeout(IsoTpHandler* handler, uint16_t timeout_ms); // TODO we have to make sure to copy the payload internall if it's more than 1 // frame, the soure could go out of scope -bool isotp_send(const uint8_t* payload, uint16_t payload_size); +bool isotp_send(IsoTpHandler* handler, const uint8_t* payload, + uint16_t payload_size); void isotp_receive_can_frame(IsoTpHandler* handler, const uint16_t arbitration_id, const uint64_t data, diff --git a/tests/common.c b/tests/common.c index 9aff39a1..512adfbc 100644 --- a/tests/common.c +++ b/tests/common.c @@ -44,11 +44,13 @@ void message_received(const uint16_t arbitration_id, const uint8_t* payload, log_isotp_message(arbitration_id, payload, size); last_message_received_arb_id = arbitration_id; last_message_received_payload_size = size; - memcpy(last_message_received_payload, payload, size); + if(size > 0) { + memcpy(last_message_received_payload, payload, size); + } } -void message_sent(const bool success, const uint16_t arbitration_id, - const uint8_t* payload, const uint16_t size) { +void message_sent(const uint16_t arbitration_id, const uint8_t* payload, + const uint16_t size, const bool success) { if(success) { debug("Sent ISO-TP message:"); } else { @@ -58,7 +60,10 @@ void message_sent(const bool success, const uint16_t arbitration_id, last_message_sent_arb_id = arbitration_id; last_message_sent_payload_size = size; - memcpy(last_message_sent_payload, payload, size); + last_message_sent_status = success; + if(size > 0) { + memcpy(last_message_sent_payload, payload, size); + } } void can_frame_sent(const uint16_t arbitration_id, @@ -72,13 +77,16 @@ void can_frame_sent(const uint16_t arbitration_id, can_frame_was_sent = true; last_can_frame_sent_arb_id = arbitration_id; last_can_payload_sent = size; - memcpy(last_can_payload_sent, payload, size); + if(size > 0) { + memcpy(last_can_payload_sent, payload, size); + } } void setup() { SHIMS = isotp_init_shims(debug, mock_send_can, mock_set_timer); ISOTP_HANDLER = isotp_init(&SHIMS, 0x2a, message_received, message_sent, can_frame_sent); + last_message_sent_payload = malloc(MAX_ISO_TP_MESSAGE_SIZE); last_message_received_payload = malloc(MAX_ISO_TP_MESSAGE_SIZE); last_message_sent_status = false; message_was_received = false; diff --git a/tests/test_send.c b/tests/test_send.c index 144e040f..c2293c21 100644 --- a/tests/test_send.c +++ b/tests/test_send.c @@ -25,15 +25,34 @@ extern uint8_t last_message_sent_payload_size; extern void setup(); +START_TEST (test_send_empty_payload) +{ + fail_unless(isotp_send(&ISOTP_HANDLER, NULL, 0)); + ck_assert_int_eq(last_message_sent_arb_id, ISOTP_HANDLER.arbitration_id); + fail_unless(last_message_sent_status); + ck_assert_int_eq(last_message_sent_payload[0], NULL); + ck_assert_int_eq(last_message_sent_payload_size, 0); +} +END_TEST + START_TEST (test_send_single_frame) { - fail_if(true); + const uint8_t payload[] = {0x12, 0x34}; + fail_unless(isotp_send(&ISOTP_HANDLER, &payload, sizeof(payload))); + ck_assert_int_eq(last_message_sent_arb_id, ISOTP_HANDLER.arbitration_id); + fail_unless(last_message_sent_status); + ck_assert_int_eq(last_message_sent_payload[0], 0x12); + ck_assert_int_eq(last_message_sent_payload[1], 0x34); + ck_assert_int_eq(last_message_sent_payload_size, 2); } END_TEST START_TEST (test_send_multi_frame) { - fail_if(true); + const uint8_t payload[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0x01, 0x23, + 0x45, 0x67, 0x89}; + bool status = isotp_send(&ISOTP_HANDLER, &payload, sizeof(payload)); + fail_if(status); } END_TEST @@ -41,6 +60,7 @@ Suite* testSuite(void) { Suite* s = suite_create("iso15765"); TCase *tc_core = tcase_create("send"); tcase_add_checked_fixture(tc_core, setup, NULL); + tcase_add_test(tc_core, test_send_empty_payload); tcase_add_test(tc_core, test_send_single_frame); tcase_add_test(tc_core, test_send_multi_frame); suite_add_tcase(s, tc_core); |