Split up functions in send/receive files for clarity.

This commit is contained in:
Christopher Peplin 2014-01-03 13:44:39 -05:00
parent 330358c978
commit a5e9107147
7 changed files with 178 additions and 166 deletions

View File

@ -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;
}

View File

@ -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
}

79
src/isotp/isotp_types.h Normal file
View File

@ -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__

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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
}