mirror of https://github.com/rusefi/isotp-c.git
Split up functions in send/receive files for clarity.
This commit is contained in:
parent
330358c978
commit
a5e9107147
|
@ -1,5 +1,4 @@
|
|||
#include <isotp/isotp.h>
|
||||
#include <isotp/receive.h>
|
||||
#include <bitfield/bitfield.h>
|
||||
|
||||
const uint8_t ISO_TP_DEFAULT_RESPONSE_TIMEOUT = 100;
|
||||
|
@ -32,74 +31,3 @@ void isotp_message_to_string(const IsoTpMessage* message, char* destination,
|
|||
message->payload[6],
|
||||
message->payload[7]);
|
||||
}
|
||||
|
||||
IsoTpMessage isotp_continue_receive(IsoTpShims* shims,
|
||||
IsoTpReceiveHandle* handle, const uint16_t arbitration_id,
|
||||
const uint8_t data[], const uint8_t size) {
|
||||
IsoTpMessage message = {
|
||||
arbitration_id: arbitration_id,
|
||||
completed: false,
|
||||
payload: {0},
|
||||
size: 0
|
||||
};
|
||||
|
||||
if(size < 1) {
|
||||
return message;
|
||||
}
|
||||
|
||||
if(handle->arbitration_id != arbitration_id) {
|
||||
if(shims->log != NULL) {
|
||||
shims->log("The arb ID 0x%x doesn't match the expected rx ID 0x%x",
|
||||
arbitration_id, handle->arbitration_id);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
IsoTpProtocolControlInformation pci = (IsoTpProtocolControlInformation)
|
||||
get_nibble(data, size, 0);
|
||||
|
||||
uint8_t payload_length = get_nibble(data, size, 1);
|
||||
uint8_t payload[payload_length];
|
||||
if(payload_length > 0 && size > 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: {
|
||||
if(payload_length > 0) {
|
||||
memcpy(message.payload, payload, payload_length);
|
||||
}
|
||||
message.size = payload_length;
|
||||
message.completed = true;
|
||||
handle->success = true;
|
||||
handle->completed = true;
|
||||
isotp_handle_single_frame(handle, &message);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
shims->log("Only single frame messages are supported");
|
||||
break;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
bool isotp_continue_send(IsoTpShims* shims, IsoTpSendHandle* handle,
|
||||
const uint16_t arbitration_id, const uint8_t data[],
|
||||
const uint8_t size) {
|
||||
// TODO this will need to be tested when we add multi-frame support,
|
||||
// which is when it'll be necessary to pass in CAN messages to SENDING
|
||||
// handles.
|
||||
if(handle->receiving_arbitration_id != arbitration_id) {
|
||||
if(shims->log != NULL) {
|
||||
shims->log("The arb ID 0x%x doesn't match the expected tx continuation ID 0x%x",
|
||||
arbitration_id, handle->receiving_arbitration_id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,103 +1,23 @@
|
|||
#ifndef __ISOTP_H__
|
||||
#define __ISOTP_H__
|
||||
|
||||
#include <isotp/isotp_types.h>
|
||||
#include <isotp/send.h>
|
||||
#include <isotp/receive.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define CAN_MESSAGE_BYTE_SIZE 8
|
||||
#define MAX_ISO_TP_MESSAGE_SIZE 4096
|
||||
// TODO we want to avoid malloc, and we can't be allocated 4K on the stack for
|
||||
// each IsoTpMessage, so for now we're setting an artificial max message size
|
||||
// here - since we only handle single frame messages, 8 bytes is plenty.
|
||||
#define OUR_MAX_ISO_TP_MESSAGE_SIZE 8
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const uint8_t ISO_TP_DEFAULT_RESPONSE_TIMEOUT;
|
||||
const bool ISO_TP_DEFAULT_FRAME_PADDING_STATUS;
|
||||
|
||||
typedef struct {
|
||||
const uint16_t arbitration_id;
|
||||
uint8_t payload[OUR_MAX_ISO_TP_MESSAGE_SIZE];
|
||||
uint16_t size;
|
||||
bool completed;
|
||||
} IsoTpMessage;
|
||||
|
||||
typedef void (*LogShim)(const char* message, ...);
|
||||
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 IsoTpMessage* message);
|
||||
typedef void (*IsoTpMessageSentHandler)(const IsoTpMessage* message,
|
||||
const bool success);
|
||||
typedef void (*IsoTpCanFrameSentHandler)(const IsoTpMessage* message);
|
||||
|
||||
typedef struct {
|
||||
LogShim log;
|
||||
SendCanMessageShim send_can_message;
|
||||
SetTimerShim set_timer;
|
||||
} IsoTpShims;
|
||||
|
||||
typedef struct {
|
||||
bool success;
|
||||
bool completed;
|
||||
uint16_t arbitration_id;
|
||||
IsoTpMessageReceivedHandler message_received_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;
|
||||
// TODO timer callback for multi frame
|
||||
} IsoTpReceiveHandle;
|
||||
|
||||
typedef struct {
|
||||
bool success;
|
||||
bool completed;
|
||||
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 enum {
|
||||
PCI_SINGLE = 0x0,
|
||||
PCI_FIRST_FRAME = 0x1,
|
||||
PCI_CONSECUTIVE_FRAME = 0x2,
|
||||
PCI_FLOW_CONTROL_FRAME = 0x3
|
||||
} IsoTpProtocolControlInformation;
|
||||
|
||||
typedef enum {
|
||||
PCI_FLOW_STATUS_CONTINUE = 0x0,
|
||||
PCI_FLOW_STATUS_WAIT = 0x1,
|
||||
PCI_FLOW_STATUS_OVERFLOW = 0x2
|
||||
} IsoTpFlowStatus;
|
||||
|
||||
IsoTpShims isotp_init_shims(LogShim log,
|
||||
SendCanMessageShim send_can_message,
|
||||
SetTimerShim set_timer);
|
||||
|
||||
IsoTpMessage isotp_continue_receive(IsoTpShims* shims,
|
||||
IsoTpReceiveHandle* handle, const uint16_t arbitration_id,
|
||||
const uint8_t data[], const uint8_t size);
|
||||
|
||||
bool isotp_continue_send(IsoTpShims* shims, IsoTpSendHandle* handle,
|
||||
const uint16_t arbitration_id, const uint8_t data[],
|
||||
const uint8_t size);
|
||||
void isotp_message_to_string(const IsoTpMessage* message, char* destination,
|
||||
size_t destination_length);
|
||||
|
||||
/* Public: Change the timeout for waiting on an ISO-TP response frame.
|
||||
*
|
||||
|
@ -108,15 +28,6 @@ bool isotp_continue_send(IsoTpShims* shims, IsoTpSendHandle* handle,
|
|||
*/
|
||||
// void isotp_set_timeout(IsoTpHandler* handler, uint16_t timeout_ms);
|
||||
|
||||
void isotp_message_to_string(const IsoTpMessage* message, char* destination,
|
||||
size_t destination_length);
|
||||
|
||||
IsoTpSendHandle isotp_send(IsoTpShims* shims, const uint16_t arbitration_id,
|
||||
const uint8_t payload[], uint16_t size,
|
||||
IsoTpMessageSentHandler callback);
|
||||
|
||||
IsoTpReceiveHandle isotp_receive(IsoTpShims* shims,
|
||||
const uint16_t arbitration_id, IsoTpMessageReceivedHandler callback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
#ifndef __ISOTP_TYPES__
|
||||
#define __ISOTP_TYPES__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define CAN_MESSAGE_BYTE_SIZE 8
|
||||
#define MAX_ISO_TP_MESSAGE_SIZE 4096
|
||||
// TODO we want to avoid malloc, and we can't be allocated 4K on the stack for
|
||||
// each IsoTpMessage, so for now we're setting an artificial max message size
|
||||
// here - since we only handle single frame messages, 8 bytes is plenty.
|
||||
#define OUR_MAX_ISO_TP_MESSAGE_SIZE 8
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const uint8_t ISO_TP_DEFAULT_RESPONSE_TIMEOUT;
|
||||
const bool ISO_TP_DEFAULT_FRAME_PADDING_STATUS;
|
||||
|
||||
typedef struct {
|
||||
const uint16_t arbitration_id;
|
||||
uint8_t payload[OUR_MAX_ISO_TP_MESSAGE_SIZE];
|
||||
uint16_t size;
|
||||
bool completed;
|
||||
} IsoTpMessage;
|
||||
|
||||
typedef void (*LogShim)(const char* message, ...);
|
||||
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 IsoTpMessage* message);
|
||||
typedef void (*IsoTpMessageSentHandler)(const IsoTpMessage* message,
|
||||
const bool success);
|
||||
typedef void (*IsoTpCanFrameSentHandler)(const IsoTpMessage* message);
|
||||
|
||||
typedef struct {
|
||||
LogShim log;
|
||||
SendCanMessageShim send_can_message;
|
||||
SetTimerShim set_timer;
|
||||
} IsoTpShims;
|
||||
|
||||
typedef struct {
|
||||
bool success;
|
||||
bool completed;
|
||||
uint16_t arbitration_id;
|
||||
IsoTpMessageReceivedHandler message_received_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;
|
||||
// TODO timer callback for multi frame
|
||||
} IsoTpReceiveHandle;
|
||||
|
||||
typedef enum {
|
||||
PCI_SINGLE = 0x0,
|
||||
PCI_FIRST_FRAME = 0x1,
|
||||
PCI_CONSECUTIVE_FRAME = 0x2,
|
||||
PCI_FLOW_CONTROL_FRAME = 0x3
|
||||
} IsoTpProtocolControlInformation;
|
||||
|
||||
typedef enum {
|
||||
PCI_FLOW_STATUS_CONTINUE = 0x0,
|
||||
PCI_FLOW_STATUS_WAIT = 0x1,
|
||||
PCI_FLOW_STATUS_OVERFLOW = 0x2
|
||||
} IsoTpFlowStatus;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __ISOTP_TYPES__
|
|
@ -22,3 +22,57 @@ IsoTpReceiveHandle isotp_receive(IsoTpShims* shims,
|
|||
|
||||
return handle;
|
||||
}
|
||||
|
||||
IsoTpMessage isotp_continue_receive(IsoTpShims* shims,
|
||||
IsoTpReceiveHandle* handle, const uint16_t arbitration_id,
|
||||
const uint8_t data[], const uint8_t size) {
|
||||
IsoTpMessage message = {
|
||||
arbitration_id: arbitration_id,
|
||||
completed: false,
|
||||
payload: {0},
|
||||
size: 0
|
||||
};
|
||||
|
||||
if(size < 1) {
|
||||
return message;
|
||||
}
|
||||
|
||||
if(handle->arbitration_id != arbitration_id) {
|
||||
if(shims->log != NULL) {
|
||||
shims->log("The arb ID 0x%x doesn't match the expected rx ID 0x%x",
|
||||
arbitration_id, handle->arbitration_id);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
IsoTpProtocolControlInformation pci = (IsoTpProtocolControlInformation)
|
||||
get_nibble(data, size, 0);
|
||||
|
||||
uint8_t payload_length = get_nibble(data, size, 1);
|
||||
uint8_t payload[payload_length];
|
||||
if(payload_length > 0 && size > 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: {
|
||||
if(payload_length > 0) {
|
||||
memcpy(message.payload, payload, payload_length);
|
||||
}
|
||||
message.size = payload_length;
|
||||
message.completed = true;
|
||||
handle->success = true;
|
||||
handle->completed = true;
|
||||
isotp_handle_single_frame(handle, &message);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
shims->log("Only single frame messages are supported");
|
||||
break;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,13 @@ void isotp_complete_receive(IsoTpReceiveHandle* handle, IsoTpMessage* message);
|
|||
|
||||
bool isotp_handle_single_frame(IsoTpReceiveHandle* handle, IsoTpMessage* message);
|
||||
|
||||
IsoTpReceiveHandle isotp_receive(IsoTpShims* shims,
|
||||
const uint16_t arbitration_id, IsoTpMessageReceivedHandler callback);
|
||||
|
||||
IsoTpMessage isotp_continue_receive(IsoTpShims* shims,
|
||||
IsoTpReceiveHandle* handle, const uint16_t arbitration_id,
|
||||
const uint8_t data[], const uint8_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -69,3 +69,19 @@ IsoTpSendHandle isotp_send(IsoTpShims* shims, const uint16_t arbitration_id,
|
|||
return isotp_send_multi_frame(shims, &message, callback);
|
||||
}
|
||||
}
|
||||
|
||||
bool isotp_continue_send(IsoTpShims* shims, IsoTpSendHandle* handle,
|
||||
const uint16_t arbitration_id, const uint8_t data[],
|
||||
const uint8_t size) {
|
||||
// TODO this will need to be tested when we add multi-frame support,
|
||||
// which is when it'll be necessary to pass in CAN messages to SENDING
|
||||
// handles.
|
||||
if(handle->receiving_arbitration_id != arbitration_id) {
|
||||
if(shims->log != NULL) {
|
||||
shims->log("The arb ID 0x%x doesn't match the expected tx continuation ID 0x%x",
|
||||
arbitration_id, handle->receiving_arbitration_id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,23 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
bool success;
|
||||
bool completed;
|
||||
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;
|
||||
|
||||
bool isotp_continue_send(IsoTpShims* shims, IsoTpSendHandle* handle,
|
||||
const uint16_t arbitration_id, const uint8_t data[],
|
||||
const uint8_t size);
|
||||
|
||||
IsoTpSendHandle isotp_send(IsoTpShims* shims, const uint16_t arbitration_id,
|
||||
const uint8_t payload[], uint16_t size,
|
||||
IsoTpMessageSentHandler callback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue