summaryrefslogtreecommitdiffstats
path: root/src/isotp
diff options
context:
space:
mode:
Diffstat (limited to 'src/isotp')
-rw-r--r--src/isotp/isotp.c76
-rw-r--r--src/isotp/isotp.h44
-rw-r--r--src/isotp/receive.c47
-rw-r--r--src/isotp/receive.h10
-rw-r--r--src/isotp/send.c54
-rw-r--r--src/isotp/send.h6
6 files changed, 146 insertions, 91 deletions
diff --git a/src/isotp/isotp.c b/src/isotp/isotp.c
index f303e214..f5b20795 100644
--- a/src/isotp/isotp.c
+++ b/src/isotp/isotp.c
@@ -7,10 +7,14 @@ 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;
+// TODO why isn't this picked up from the header?
+extern IsoTpHandle isotp_receive(IsoTpShims* shims, const uint16_t arbitration_id,
+ IsoTpMessageReceivedHandler callback);
-void isotp_set_timeout(IsoTpHandler* handler, uint16_t timeout_ms) {
- handler->timeout_ms = timeout_ms;
-}
+
+/* void isotp_set_timeout(IsoTpHandler* handler, uint16_t timeout_ms) { */
+ /* handler->timeout_ms = timeout_ms; */
+/* } */
IsoTpShims isotp_init_shims(LogShim log, SendCanMessageShim send_can_message,
SetTimerShim set_timer) {
@@ -22,26 +26,58 @@ IsoTpShims isotp_init_shims(LogShim log, SendCanMessageShim send_can_message,
return shims;
}
-IsoTpHandler isotp_init(IsoTpShims* shims, uint16_t arbitration_id,
- IsoTpMessageReceivedHandler message_received_callback,
- IsoTpMessageSentHandler message_sent_callback,
- IsoTpCanFrameSentHandler can_frame_sent_callback) {
- IsoTpHandler handler = {
- shims: shims,
- arbitration_id: arbitration_id,
- message_received_callback: message_received_callback,
- message_sent_callback: message_sent_callback,
- can_frame_sent_callback: can_frame_sent_callback,
- timeout_ms: ISO_TP_DEFAULT_RESPONSE_TIMEOUT,
- frame_padding: ISO_TP_DEFAULT_FRAME_PADDING_STATUS,
- sending: false
- };
- return handler;
-}
-
void isotp_message_to_string(const IsoTpMessage* message, char* destination,
size_t destination_length) {
snprintf(destination, destination_length,"ID: 0x%02x, Payload: 0x%llx",
// TODO the payload may be backwards here
message->arbitration_id, message->payload);
}
+
+void isotp_receive_can_frame(IsoTpShims* shims, IsoTpHandle* handle,
+ const uint16_t arbitration_id, const uint8_t data[],
+ const uint8_t data_length) {
+ if(data_length < 1) {
+ return;
+ }
+
+ if(handle->type == ISOTP_HANDLE_RECEIVING) {
+ if(handle->receive_handle.arbitration_id != arbitration_id) {
+ return;
+ }
+ } else if(handle->type == ISOTP_HANDLE_SENDING) {
+ if(handle->send_handle.receiving_arbitration_id != arbitration_id) {
+ return;
+ }
+ } else {
+ shims->log("The ISO-TP handle is corrupt");
+ }
+
+ IsoTpProtocolControlInformation pci = (IsoTpProtocolControlInformation)
+ get_nibble(data, data_length, 0);
+
+ uint8_t payload_length = get_nibble(data, data_length, 1);
+ uint8_t payload[payload_length];
+ if(payload_length > 0 && data_length > 0) {
+ memcpy(payload, &data[1], payload_length);
+ }
+
+ // TODO this is set up to handle rx a response with a payload, but not to
+ // handle flow control responses for multi frame messages that we're in the
+ // process of sending
+
+ switch(pci) {
+ case PCI_SINGLE: {
+ IsoTpMessage message = {
+ arbitration_id: arbitration_id,
+ payload: payload,
+ size: payload_length
+ };
+
+ isotp_handle_single_frame(handle, &message);
+ break;
+ }
+ default:
+ shims->log("Only single frame messages are supported");
+ break;
+ }
+}
diff --git a/src/isotp/isotp.h b/src/isotp/isotp.h
index 74a4897a..10352383 100644
--- a/src/isotp/isotp.h
+++ b/src/isotp/isotp.h
@@ -39,21 +39,42 @@ typedef struct {
} IsoTpShims;
typedef struct {
- IsoTpShims* shims;
uint16_t arbitration_id;
IsoTpMessageReceivedHandler message_received_callback;
- IsoTpMessageSentHandler message_sent_callback;
- IsoTpCanFrameSentHandler can_frame_sent_callback;
// Private
uint16_t timeout_ms;
+ // timeout_ms: ISO_TP_DEFAULT_RESPONSE_TIMEOUT,
bool frame_padding;
+ // frame_padding: ISO_TP_DEFAULT_FRAME_PADDING_STATUS,
uint8_t* receive_buffer;
uint16_t received_buffer_size;
uint16_t incoming_message_size;
- bool sending;
// TODO timer callback
-} IsoTpHandler;
+} IsoTpReceiveHandle;
+
+typedef struct {
+ uint16_t sending_arbitration_id;
+ uint16_t receiving_arbitration_id;
+ IsoTpMessageSentHandler message_sent_callback;
+ IsoTpCanFrameSentHandler can_frame_sent_callback;
+
+ // TODO going to need some state here for multi frame messages
+} IsoTpSendHandle;
+
+typedef enum {
+ ISOTP_HANDLE_SENDING,
+ ISOTP_HANDLE_RECEIVING
+} IsoTpHandleType;
+
+typedef struct {
+ bool success;
+ bool completed;
+ IsoTpHandleType type;
+ IsoTpReceiveHandle receive_handle;
+ IsoTpSendHandle send_handle;
+} IsoTpHandle;
+
typedef enum {
PCI_SINGLE = 0x0,
@@ -72,11 +93,9 @@ IsoTpShims isotp_init_shims(LogShim log,
SendCanMessageShim send_can_message,
SetTimerShim set_timer);
-IsoTpHandler isotp_init(IsoTpShims* shims,
- uint16_t arbitration_id,
- IsoTpMessageReceivedHandler message_received_callback,
- IsoTpMessageSentHandler message_sent_callback,
- IsoTpCanFrameSentHandler can_frame_sent_callback);
+void isotp_receive_can_frame(IsoTpShims* shims, IsoTpHandle* handle,
+ const uint16_t arbitration_id, const uint8_t data[],
+ const uint8_t size);
/* Public: Change the timeout for waiting on an ISO-TP response frame.
*
@@ -85,13 +104,14 @@ IsoTpHandler isotp_init(IsoTpShims* shims,
* handler - the ISO-TP handler to modify.
* timeout - the new timeout in milliseconds.
*/
-void isotp_set_timeout(IsoTpHandler* handler, uint16_t timeout_ms);
+// void isotp_set_timeout(IsoTpHandler* handler, uint16_t timeout_ms);
-void isotp_destroy(IsoTpHandler* handler);
+// void isotp_destroy(IsoTpHandler* handler);
void isotp_message_to_string(const IsoTpMessage* message, char* destination,
size_t destination_length);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/isotp/receive.c b/src/isotp/receive.c
index bd94e7aa..1d623384 100644
--- a/src/isotp/receive.c
+++ b/src/isotp/receive.c
@@ -1,42 +1,27 @@
#include <isotp/receive.h>
-void isotp_handle_single_frame(IsoTpHandler* handler, IsoTpMessage* message) {
- isotp_complete_receive(handler, message);
+void isotp_handle_single_frame(IsoTpHandle* handle,
+ IsoTpMessage* message) {
+ isotp_complete_receive(handle, message);
}
-void isotp_complete_receive(IsoTpHandler* handler, IsoTpMessage* message) {
- handler->message_received_callback(message);
+void isotp_complete_receive(IsoTpHandle* handle, IsoTpMessage* message) {
+ handle->receive_handle.message_received_callback(message);
}
-void isotp_receive_can_frame(IsoTpHandler* handler,
- const uint16_t arbitration_id, const uint8_t data[],
- const uint8_t data_length) {
- if(arbitration_id != handler->arbitration_id || data_length < 1) {
- return;
- }
-
- IsoTpProtocolControlInformation pci = (IsoTpProtocolControlInformation)
- get_nibble(data, data_length, 0);
-
- uint8_t payload_length = get_nibble(data, data_length, 1);
- uint8_t payload[payload_length];
- if(payload_length > 0 && data_length > 0) {
- memcpy(payload, &data[1], payload_length);
- }
-
- IsoTpMessage message = {
+IsoTpHandle isotp_receive(IsoTpShims* shims,
+ const uint16_t arbitration_id, IsoTpMessageReceivedHandler callback) {
+ IsoTpReceiveHandle receive_handle = {
arbitration_id: arbitration_id,
- payload: payload,
- size: payload_length
+ message_received_callback: callback
};
- switch(pci) {
- case PCI_SINGLE:
- isotp_handle_single_frame(handler, &message);
- break;
- default:
- handler->shims->log("Only single frame messages are supported");
- break;
- }
+ IsoTpHandle handle = {
+ success: false,
+ completed: true,
+ receive_handle: receive_handle,
+ type: ISOTP_HANDLE_RECEIVING
+ };
+ return handle;
}
diff --git a/src/isotp/receive.h b/src/isotp/receive.h
index feca993c..3eee89e2 100644
--- a/src/isotp/receive.h
+++ b/src/isotp/receive.h
@@ -9,13 +9,13 @@
extern "C" {
#endif
-void isotp_handle_single_frame(IsoTpHandler* handler, IsoTpMessage* message);
+void isotp_complete_receive(IsoTpHandle* handle, IsoTpMessage* message);
-void isotp_complete_receive(IsoTpHandler* handler, IsoTpMessage* message);
+void isotp_handle_single_frame(IsoTpHandle* handle,
+ IsoTpMessage* message);
-void isotp_receive_can_frame(IsoTpHandler* handler,
- const uint16_t arbitration_id, const uint8_t data[],
- const uint8_t size);
+IsoTpHandle isotp_receive(IsoTpShims* shims, const uint16_t arbitration_id,
+ IsoTpMessageReceivedHandler callback);
#ifdef __cplusplus
}
diff --git a/src/isotp/send.c b/src/isotp/send.c
index ae208eb3..67703cae 100644
--- a/src/isotp/send.c
+++ b/src/isotp/send.c
@@ -4,52 +4,66 @@
#define PAYLOAD_LENGTH_NIBBLE_INDEX 1
#define PAYLOAD_BYTE_INDEX 1
-void isotp_complete_send(IsoTpHandler* handler, IsoTpMessage* message,
- bool status) {
- handler->message_sent_callback(message, status);
+void isotp_complete_send(IsoTpShims* shims, IsoTpMessage* message,
+ bool status, IsoTpMessageSentHandler callback) {
+ callback(message, status);
}
-bool isotp_send_single_frame(IsoTpHandler* handler, IsoTpMessage* message) {
+IsoTpHandle isotp_send_single_frame(IsoTpShims* shims, IsoTpMessage* message,
+ IsoTpMessageSentHandler callback) {
+ IsoTpHandle handle = {
+ success: false,
+ completed: true,
+ type: ISOTP_HANDLE_SENDING
+ };
+
uint8_t can_data[CAN_MESSAGE_BYTE_SIZE] = {0};
if(!set_nibble(PCI_NIBBLE_INDEX, PCI_SINGLE, can_data, sizeof(can_data))) {
- handler->shims->log("Unable to set PCI in CAN data");
- return false;
+ shims->log("Unable to set PCI in CAN data");
+ return handle;
}
if(!set_nibble(PAYLOAD_LENGTH_NIBBLE_INDEX, message->size, can_data,
sizeof(can_data))) {
- handler->shims->log("Unable to set payload length in CAN data");
- return false;
+ shims->log("Unable to set payload length in CAN data");
+ return handle;
}
if(message->size > 0) {
memcpy(&can_data[1], message->payload, message->size);
}
- handler->shims->send_can_message(message->arbitration_id, can_data,
+ shims->send_can_message(message->arbitration_id, can_data,
1 + message->size);
- isotp_complete_send(handler, message, true);
- return true;
+ handle.success = true;
+ isotp_complete_send(shims, message, true, callback);
+ return handle;
}
-bool isotp_send_multi_frame(IsoTpHandler* handler, IsoTpMessage* message) {
+IsoTpHandle isotp_send_multi_frame(IsoTpShims* shims, IsoTpMessage* message,
+ IsoTpMessageSentHandler callback) {
// TODO make sure to copy payload into a local buffer
- handler->shims->log("Only single frame messages are supported");
- return false;
+ shims->log("Only single frame messages are supported");
+ IsoTpHandle handle = {
+ success: false,
+ completed: true,
+ type: ISOTP_HANDLE_SENDING
+ };
+ return handle;
}
-bool isotp_send(IsoTpHandler* handler, const uint8_t* payload,
- uint16_t size) {
- // we determine if it's single/multi frame and start the send
+IsoTpHandle isotp_send(IsoTpShims* shims, const uint16_t arbitration_id,
+ const uint8_t* payload, uint16_t size,
+ IsoTpMessageSentHandler callback) {
IsoTpMessage message = {
- arbitration_id: handler->arbitration_id,
+ arbitration_id: arbitration_id,
payload: payload,
size: size
};
if(size < 8) {
- return isotp_send_single_frame(handler, &message);
+ return isotp_send_single_frame(shims, &message, callback);
} else {
- return isotp_send_multi_frame(handler, &message);
+ return isotp_send_multi_frame(shims, &message, callback);
}
}
diff --git a/src/isotp/send.h b/src/isotp/send.h
index 2031621b..937e5320 100644
--- a/src/isotp/send.h
+++ b/src/isotp/send.h
@@ -9,9 +9,9 @@
extern "C" {
#endif
-// TODO I don't love this API
-bool isotp_send(IsoTpHandler* handler, const uint8_t* payload,
- uint16_t payload_size);
+IsoTpHandle isotp_send(IsoTpShims* shims, const uint16_t arbitration_id,
+ const uint8_t* payload, uint16_t size,
+ IsoTpMessageSentHandler callback);
#ifdef __cplusplus
}