ISOTP-C
A platform-agnostic ISOTP implementation in C.
isotp.c File Reference
#include <stdint.h>
#include "assert.h"
#include "isotp.h"
Include dependency graph for isotp.c:

Go to the source code of this file.

Functions

static uint8_t isotp_us_to_st_min (uint32_t us)
 STATIC FUNCTIONS ///. More...
 
static uint32_t isotp_st_min_to_us (uint8_t st_min)
 
static int isotp_send_flow_control (IsoTpLink *link, uint8_t flow_status, uint8_t block_size, uint32_t st_min_us)
 
static int isotp_send_single_frame (IsoTpLink *link, uint32_t id)
 
static int isotp_send_first_frame (IsoTpLink *link, uint32_t id)
 
static int isotp_send_consecutive_frame (IsoTpLink *link)
 
static int isotp_receive_single_frame (IsoTpLink *link, IsoTpCanMessage *message, uint8_t len)
 
static int isotp_receive_first_frame (IsoTpLink *link, IsoTpCanMessage *message, uint8_t len)
 
static int isotp_receive_consecutive_frame (IsoTpLink *link, IsoTpCanMessage *message, uint8_t len)
 
static int isotp_receive_flow_control_frame (IsoTpLink *link, IsoTpCanMessage *message, uint8_t len)
 
int isotp_send (IsoTpLink *link, const uint8_t payload[], uint16_t size)
 PUBLIC FUNCTIONS ///. More...
 
int isotp_send_with_id (IsoTpLink *link, uint32_t id, const uint8_t payload[], uint16_t size)
 See isotp_send, with the exception that this function is used only for functional addressing. More...
 
void isotp_on_can_message (IsoTpLink *link, uint8_t *data, uint8_t len)
 Handles incoming CAN messages. Determines whether an incoming message is a valid ISO-TP frame or not and handles it accordingly. More...
 
int isotp_receive (IsoTpLink *link, uint8_t *payload, const uint16_t payload_size, uint16_t *out_size)
 Receives and parses the received data and copies the parsed data in to the internal buffer. More...
 
void isotp_init_link (IsoTpLink *link, uint32_t sendid, uint8_t *sendbuf, uint16_t sendbufsize, uint8_t *recvbuf, uint16_t recvbufsize)
 Initialises the ISO-TP library. More...
 
void isotp_poll (IsoTpLink *link)
 Polling function; call this function periodically to handle timeouts, send consecutive frames, etc. More...
 

Function Documentation

◆ isotp_init_link()

void isotp_init_link ( IsoTpLink link,
uint32_t  sendid,
uint8_t *  sendbuf,
uint16_t  sendbufsize,
uint8_t *  recvbuf,
uint16_t  recvbufsize 
)

Initialises the ISO-TP library.

Parameters
linkThe
instance used for transceiving data.
sendidThe ID used to send data to other CAN nodes.
sendbufA pointer to an area in memory which can be used as a buffer for data to be sent.
sendbufsizeThe size of the buffer area.
recvbufA pointer to an area in memory which can be used as a buffer for data to be received.
recvbufsizeThe size of the buffer area.

Definition at line 450 of file isotp.c.

450 {
451 memset(link, 0, sizeof(*link));
454 link->send_arbitration_id = sendid;
455 link->send_buffer = sendbuf;
456 link->send_buf_size = sendbufsize;
457 link->receive_buffer = recvbuf;
458 link->receive_buf_size = recvbufsize;
459
460 return;
461}
@ ISOTP_RECEIVE_STATUS_IDLE
Definition: isotp_defines.h:62
@ ISOTP_SEND_STATUS_IDLE
Definition: isotp_defines.h:55

References ISOTP_RECEIVE_STATUS_IDLE, ISOTP_SEND_STATUS_IDLE, IsoTpLink::receive_buf_size, IsoTpLink::receive_buffer, IsoTpLink::receive_status, IsoTpLink::send_arbitration_id, IsoTpLink::send_buf_size, IsoTpLink::send_buffer, and IsoTpLink::send_status.

◆ isotp_on_can_message()

void isotp_on_can_message ( IsoTpLink link,
uint8_t *  data,
uint8_t  len 
)

Handles incoming CAN messages. Determines whether an incoming message is a valid ISO-TP frame or not and handles it accordingly.

Parameters
linkThe instance used for transceiving data.
dataThe data received via CAN.
lenThe length of the data received.

Definition at line 281 of file isotp.c.

281 {
282 IsoTpCanMessage message;
283 int ret;
284
285 if (len < 2 || len > 8) {
286 return;
287 }
288
289 memcpy(message.as.data_array.ptr, data, len);
290 memset(message.as.data_array.ptr + len, 0, sizeof(message.as.data_array.ptr) - len);
291
292 switch (message.as.common.type) {
294 /* update protocol result */
297 } else {
299 }
300
301 /* handle message */
302 ret = isotp_receive_single_frame(link, &message, len);
303
304 if (ISOTP_RET_OK == ret) {
305 /* change status */
307 }
308 break;
309 }
311 /* update protocol result */
314 } else {
316 }
317
318 /* handle message */
319 ret = isotp_receive_first_frame(link, &message, len);
320
321 /* if overflow happened */
322 if (ISOTP_RET_OVERFLOW == ret) {
323 /* update protocol result */
325 /* change status */
327 /* send error message */
329 break;
330 }
331
332 /* if receive successful */
333 if (ISOTP_RET_OK == ret) {
334 /* change status */
336 /* send fc frame */
339 /* refresh timer cs */
341 }
342
343 break;
344 }
346 /* check if in receiving status */
349 break;
350 }
351
352 /* handle message */
353 ret = isotp_receive_consecutive_frame(link, &message, len);
354
355 /* if wrong sn */
356 if (ISOTP_RET_WRONG_SN == ret) {
359 break;
360 }
361
362 /* if success */
363 if (ISOTP_RET_OK == ret) {
364 /* refresh timer cs */
366
367 /* receive finished */
368 if (link->receive_offset >= link->receive_size) {
370 } else {
371 /* send fc when bs reaches limit */
372 if (0 == --link->receive_bs_count) {
375 }
376 }
377 }
378
379 break;
380 }
382 /* handle fc frame only when sending in progress */
384 break;
385 }
386
387 /* handle message */
388 ret = isotp_receive_flow_control_frame(link, &message, len);
389
390 if (ISOTP_RET_OK == ret) {
391 /* refresh bs timer */
393
394 /* overflow */
398 }
399
400 /* wait */
401 else if (PCI_FLOW_STATUS_WAIT == message.as.flow_control.FS) {
402 link->send_wtf_count += 1;
403 /* wait exceed allowed count */
407 }
408 }
409
410 /* permit send */
411 else if (PCI_FLOW_STATUS_CONTINUE == message.as.flow_control.FS) {
412 if (0 == message.as.flow_control.BS) {
414 } else {
415 link->send_bs_remain = message.as.flow_control.BS;
416 }
417 uint32_t message_st_min_us = isotp_st_min_to_us(message.as.flow_control.STmin);
418 link->send_st_min_us = message_st_min_us > ISO_TP_DEFAULT_ST_MIN_US ? message_st_min_us : ISO_TP_DEFAULT_ST_MIN_US; // prefer as much st_min as possible for stability?
419 link->send_wtf_count = 0;
420 }
421 }
422 break;
423 default:
424 break;
425 };
426
427 return;
428}
static int isotp_receive_first_frame(IsoTpLink *link, IsoTpCanMessage *message, uint8_t len)
Definition: isotp.c:154
static int isotp_receive_consecutive_frame(IsoTpLink *link, IsoTpCanMessage *message, uint8_t len)
Definition: isotp.c:186
static int isotp_receive_flow_control_frame(IsoTpLink *link, IsoTpCanMessage *message, uint8_t len)
Definition: isotp.c:215
static int isotp_send_flow_control(IsoTpLink *link, uint8_t flow_status, uint8_t block_size, uint32_t st_min_us)
Definition: isotp.c:29
static uint32_t isotp_st_min_to_us(uint8_t st_min)
Definition: isotp.c:20
static int isotp_receive_single_frame(IsoTpLink *link, IsoTpCanMessage *message, uint8_t len)
Definition: isotp.c:140
#define ISO_TP_MAX_WFT_NUMBER
Definition: isotp_config.h:17
#define ISO_TP_DEFAULT_ST_MIN_US
Definition: isotp_config.h:12
#define ISO_TP_DEFAULT_RESPONSE_TIMEOUT_US
Definition: isotp_config.h:22
#define ISO_TP_DEFAULT_BLOCK_SIZE
Definition: isotp_config.h:7
@ ISOTP_RECEIVE_STATUS_FULL
Definition: isotp_defines.h:64
@ ISOTP_RECEIVE_STATUS_INPROGRESS
Definition: isotp_defines.h:63
#define ISOTP_PROTOCOL_RESULT_BUFFER_OVFLW
#define ISOTP_PROTOCOL_RESULT_UNEXP_PDU
#define ISOTP_INVALID_BS
Definition: isotp_defines.h:51
#define ISOTP_PROTOCOL_RESULT_OK
#define ISOTP_RET_OVERFLOW
Definition: isotp_defines.h:40
@ ISOTP_SEND_STATUS_ERROR
Definition: isotp_defines.h:57
@ ISOTP_SEND_STATUS_INPROGRESS
Definition: isotp_defines.h:56
#define ISOTP_RET_WRONG_SN
Definition: isotp_defines.h:41
#define ISOTP_PROTOCOL_RESULT_WFT_OVRN
@ PCI_FLOW_STATUS_OVERFLOW
@ PCI_FLOW_STATUS_WAIT
@ PCI_FLOW_STATUS_CONTINUE
#define ISOTP_RET_OK
Definition: isotp_defines.h:37
@ TSOTP_PCI_TYPE_CONSECUTIVE_FRAME
@ ISOTP_PCI_TYPE_SINGLE
@ ISOTP_PCI_TYPE_FIRST_FRAME
@ ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME
#define ISOTP_PROTOCOL_RESULT_WRONG_SN
uint32_t isotp_user_get_us(void)
user implemented, gets the amount of time passed since the last call in microseconds
IsoTpDataArray data_array
IsoTpPciType common
union IsoTpCanMessage::@0 as
IsoTpFlowControl flow_control
uint8_t ptr[8]

References IsoTpCanMessage::common, IsoTpCanMessage::data_array, IsoTpCanMessage::flow_control, ISOTP_PCI_TYPE_FIRST_FRAME, ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME, ISOTP_PCI_TYPE_SINGLE, isotp_receive_consecutive_frame(), isotp_receive_first_frame(), isotp_receive_flow_control_frame(), isotp_receive_single_frame(), ISOTP_RECEIVE_STATUS_FULL, ISOTP_RECEIVE_STATUS_IDLE, ISOTP_RECEIVE_STATUS_INPROGRESS, isotp_send_flow_control(), ISOTP_SEND_STATUS_ERROR, ISOTP_SEND_STATUS_INPROGRESS, isotp_st_min_to_us(), isotp_user_get_us(), PCI_FLOW_STATUS_CONTINUE, PCI_FLOW_STATUS_OVERFLOW, PCI_FLOW_STATUS_WAIT, IsoTpDataArray::ptr, IsoTpLink::receive_bs_count, IsoTpLink::receive_offset, IsoTpLink::receive_protocol_result, IsoTpLink::receive_size, IsoTpLink::receive_status, IsoTpLink::receive_timer_cr, IsoTpLink::send_bs_remain, IsoTpLink::send_protocol_result, IsoTpLink::send_st_min_us, IsoTpLink::send_status, IsoTpLink::send_timer_bs, IsoTpLink::send_wtf_count, and TSOTP_PCI_TYPE_CONSECUTIVE_FRAME.

◆ isotp_poll()

void isotp_poll ( IsoTpLink link)

Polling function; call this function periodically to handle timeouts, send consecutive frames, etc.

Parameters
linkThe instance used.

Definition at line 463 of file isotp.c.

463 {
464 int ret;
465
466 /* only polling when operation in progress */
468
469 /* continue send data */
470 if (/* send data if bs_remain is invalid or bs_remain large than zero */
471 (ISOTP_INVALID_BS == link->send_bs_remain || link->send_bs_remain > 0) &&
472 /* and if st_min is zero or go beyond interval time */
474
476 if (ISOTP_RET_OK == ret) {
477 if (ISOTP_INVALID_BS != link->send_bs_remain) {
478 link->send_bs_remain -= 1;
479 }
482
483 /* check if send finish */
484 if (link->send_offset >= link->send_size) {
486 }
487 } else if (ISOTP_RET_NOSPACE == ret) {
488 /* shim reported that it isn't able to send a frame at present, retry on next call */
489 } else {
491 }
492 }
493
494 /* check timeout */
498 }
499 }
500
501 /* only polling when operation in progress */
503
504 /* check timeout */
508 }
509 }
510
511 return;
512}
static int isotp_send_consecutive_frame(IsoTpLink *link)
Definition: isotp.c:103
#define ISOTP_RET_NOSPACE
Definition: isotp_defines.h:45
#define ISOTP_PROTOCOL_RESULT_TIMEOUT_CR
#define ISOTP_PROTOCOL_RESULT_TIMEOUT_BS
#define IsoTpTimeAfter(a, b)
Definition: isotp_defines.h:48

References ISOTP_RECEIVE_STATUS_IDLE, ISOTP_RECEIVE_STATUS_INPROGRESS, isotp_send_consecutive_frame(), ISOTP_SEND_STATUS_ERROR, ISOTP_SEND_STATUS_IDLE, ISOTP_SEND_STATUS_INPROGRESS, isotp_user_get_us(), IsoTpLink::receive_protocol_result, IsoTpLink::receive_status, IsoTpLink::receive_timer_cr, IsoTpLink::send_bs_remain, IsoTpLink::send_offset, IsoTpLink::send_protocol_result, IsoTpLink::send_size, IsoTpLink::send_st_min_us, IsoTpLink::send_status, IsoTpLink::send_timer_bs, and IsoTpLink::send_timer_st.

◆ isotp_receive()

int isotp_receive ( IsoTpLink link,
uint8_t *  payload,
const uint16_t  payload_size,
uint16_t *  out_size 
)

Receives and parses the received data and copies the parsed data in to the internal buffer.

Parameters
linkThe IsoTpLink instance used to transceive data.
payloadA pointer to an area in memory where the raw data is copied from.
payload_sizeThe size of the received (raw) CAN data.
out_sizeA reference to a variable which will contain the size of the actual (parsed) data.
Returns
Possible return values:

Definition at line 430 of file isotp.c.

430 {
431 uint16_t copylen;
432
434 return ISOTP_RET_NO_DATA;
435 }
436
437 copylen = link->receive_size;
438 if (copylen > payload_size) {
439 copylen = payload_size;
440 }
441
442 memcpy(payload, link->receive_buffer, copylen);
443 *out_size = copylen;
444
446
447 return ISOTP_RET_OK;
448}
#define ISOTP_RET_NO_DATA
Definition: isotp_defines.h:42

References ISOTP_RECEIVE_STATUS_FULL, ISOTP_RECEIVE_STATUS_IDLE, IsoTpLink::receive_buffer, IsoTpLink::receive_size, and IsoTpLink::receive_status.

◆ isotp_receive_consecutive_frame()

static int isotp_receive_consecutive_frame ( IsoTpLink link,
IsoTpCanMessage message,
uint8_t  len 
)
static

Definition at line 186 of file isotp.c.

186 {
187 uint16_t remaining_bytes;
188
189 /* check sn */
190 if (link->receive_sn != message->as.consecutive_frame.SN) {
191 return ISOTP_RET_WRONG_SN;
192 }
193
194 /* check data length */
195 remaining_bytes = link->receive_size - link->receive_offset;
196 if (remaining_bytes > sizeof(message->as.consecutive_frame.data)) {
197 remaining_bytes = sizeof(message->as.consecutive_frame.data);
198 }
199 if (remaining_bytes > len - 1) {
200 isotp_user_debug("Consecutive frame too short.");
201 return ISOTP_RET_LENGTH;
202 }
203
204 /* copying data */
205 (void) memcpy(link->receive_buffer + link->receive_offset, message->as.consecutive_frame.data, remaining_bytes);
206
207 link->receive_offset += remaining_bytes;
208 if (++(link->receive_sn) > 0x0F) {
209 link->receive_sn = 0;
210 }
211
212 return ISOTP_RET_OK;
213}
#define ISOTP_RET_LENGTH
Definition: isotp_defines.h:44
void isotp_user_debug(const char *message,...)
user implemented, print debug message
IsoTpConsecutiveFrame consecutive_frame

References IsoTpCanMessage::consecutive_frame, isotp_user_debug(), IsoTpLink::receive_buffer, IsoTpLink::receive_offset, IsoTpLink::receive_size, and IsoTpLink::receive_sn.

Referenced by isotp_on_can_message().

◆ isotp_receive_first_frame()

static int isotp_receive_first_frame ( IsoTpLink link,
IsoTpCanMessage message,
uint8_t  len 
)
static

Definition at line 154 of file isotp.c.

154 {
155 uint16_t payload_length;
156
157 if (8 != len) {
158 isotp_user_debug("First frame should be 8 bytes in length.");
159 return ISOTP_RET_LENGTH;
160 }
161
162 /* check data length */
163 payload_length = message->as.first_frame.FF_DL_high;
164 payload_length = (payload_length << 8) + message->as.first_frame.FF_DL_low;
165
166 /* should not use multiple frame transmition */
167 if (payload_length <= 7) {
168 isotp_user_debug("Should not use multiple frame transmission.");
169 return ISOTP_RET_LENGTH;
170 }
171
172 if (payload_length > link->receive_buf_size) {
173 isotp_user_debug("Multi-frame response too large for receiving buffer.");
174 return ISOTP_RET_OVERFLOW;
175 }
176
177 /* copying data */
178 (void) memcpy(link->receive_buffer, message->as.first_frame.data, sizeof(message->as.first_frame.data));
179 link->receive_size = payload_length;
180 link->receive_offset = sizeof(message->as.first_frame.data);
181 link->receive_sn = 1;
182
183 return ISOTP_RET_OK;
184}
IsoTpFirstFrame first_frame
uint8_t data[6]

References IsoTpCanMessage::first_frame, isotp_user_debug(), IsoTpLink::receive_buf_size, IsoTpLink::receive_buffer, IsoTpLink::receive_offset, IsoTpLink::receive_size, and IsoTpLink::receive_sn.

Referenced by isotp_on_can_message().

◆ isotp_receive_flow_control_frame()

static int isotp_receive_flow_control_frame ( IsoTpLink link,
IsoTpCanMessage message,
uint8_t  len 
)
static

Definition at line 215 of file isotp.c.

215 {
216 /* check message length */
217 if (len < 3) {
218 isotp_user_debug("Flow control frame too short.");
219 return ISOTP_RET_LENGTH;
220 }
221
222 return ISOTP_RET_OK;
223}

References isotp_user_debug().

Referenced by isotp_on_can_message().

◆ isotp_receive_single_frame()

static int isotp_receive_single_frame ( IsoTpLink link,
IsoTpCanMessage message,
uint8_t  len 
)
static

Definition at line 140 of file isotp.c.

140 {
141 /* check data length */
142 if ((0 == message->as.single_frame.SF_DL) || (message->as.single_frame.SF_DL > (len - 1))) {
143 isotp_user_debug("Single-frame length too small.");
144 return ISOTP_RET_LENGTH;
145 }
146
147 /* copying data */
148 (void) memcpy(link->receive_buffer, message->as.single_frame.data, message->as.single_frame.SF_DL);
149 link->receive_size = message->as.single_frame.SF_DL;
150
151 return ISOTP_RET_OK;
152}
IsoTpSingleFrame single_frame

References isotp_user_debug(), IsoTpLink::receive_buffer, IsoTpLink::receive_size, and IsoTpCanMessage::single_frame.

Referenced by isotp_on_can_message().

◆ isotp_send()

int isotp_send ( IsoTpLink link,
const uint8_t  payload[],
uint16_t  size 
)

PUBLIC FUNCTIONS ///.

Sends ISO-TP frames via CAN, using the ID set in the initialising function.

Definition at line 229 of file isotp.c.

229 {
230 return isotp_send_with_id(link, link->send_arbitration_id, payload, size);
231}
int isotp_send_with_id(IsoTpLink *link, uint32_t id, const uint8_t payload[], uint16_t size)
See isotp_send, with the exception that this function is used only for functional addressing.
Definition: isotp.c:233

References isotp_send_with_id(), and IsoTpLink::send_arbitration_id.

◆ isotp_send_consecutive_frame()

static int isotp_send_consecutive_frame ( IsoTpLink link)
static

Definition at line 103 of file isotp.c.

103 {
104
105 IsoTpCanMessage message;
106 uint16_t data_length;
107 int ret;
108
109 /* multi frame message length must greater than 7 */
110 assert(link->send_size > 7);
111
112 /* setup message */
114 message.as.consecutive_frame.SN = link->send_sn;
115 data_length = link->send_size - link->send_offset;
116 if (data_length > sizeof(message.as.consecutive_frame.data)) {
117 data_length = sizeof(message.as.consecutive_frame.data);
118 }
119 (void) memcpy(message.as.consecutive_frame.data, link->send_buffer + link->send_offset, data_length);
120
121 /* send message */
122#ifdef ISO_TP_FRAME_PADDING
123 (void) memset(message.as.consecutive_frame.data + data_length, ISO_TP_FRAME_PADDING_VALUE, sizeof(message.as.consecutive_frame.data) - data_length);
124 ret = isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, sizeof(message));
125#else
127 message.as.data_array.ptr,
128 data_length + 1);
129#endif
130 if (ISOTP_RET_OK == ret) {
131 link->send_offset += data_length;
132 if (++(link->send_sn) > 0x0F) {
133 link->send_sn = 0;
134 }
135 }
136
137 return ret;
138}
#define ISO_TP_FRAME_PADDING_VALUE
Definition: isotp_config.h:31
int isotp_user_send_can(const uint32_t arbitration_id, const uint8_t *data, const uint8_t size)
user implemented, send can message. should return ISOTP_RET_OK when success.

References IsoTpCanMessage::consecutive_frame, IsoTpCanMessage::data_array, isotp_user_send_can(), IsoTpDataArray::ptr, IsoTpLink::send_arbitration_id, IsoTpLink::send_buffer, IsoTpLink::send_offset, IsoTpLink::send_size, IsoTpLink::send_sn, and TSOTP_PCI_TYPE_CONSECUTIVE_FRAME.

Referenced by isotp_poll().

◆ isotp_send_first_frame()

static int isotp_send_first_frame ( IsoTpLink link,
uint32_t  id 
)
static

Definition at line 79 of file isotp.c.

79 {
80
81 IsoTpCanMessage message;
82 int ret;
83
84 /* multi frame message length must greater than 7 */
85 assert(link->send_size > 7);
86
87 /* setup message */
89 message.as.first_frame.FF_DL_low = (uint8_t) link->send_size;
90 message.as.first_frame.FF_DL_high = (uint8_t) (0x0F & (link->send_size >> 8));
91 (void) memcpy(message.as.first_frame.data, link->send_buffer, sizeof(message.as.first_frame.data));
92
93 /* send message */
94 ret = isotp_user_send_can(id, message.as.data_array.ptr, sizeof(message));
95 if (ISOTP_RET_OK == ret) {
96 link->send_offset += sizeof(message.as.first_frame.data);
97 link->send_sn = 1;
98 }
99
100 return ret;
101}

References IsoTpCanMessage::data_array, IsoTpCanMessage::first_frame, ISOTP_PCI_TYPE_FIRST_FRAME, isotp_user_send_can(), IsoTpDataArray::ptr, IsoTpLink::send_buffer, IsoTpLink::send_offset, IsoTpLink::send_size, and IsoTpLink::send_sn.

Referenced by isotp_send_with_id().

◆ isotp_send_flow_control()

static int isotp_send_flow_control ( IsoTpLink link,
uint8_t  flow_status,
uint8_t  block_size,
uint32_t  st_min_us 
)
static

Definition at line 29 of file isotp.c.

29 {
30
31 IsoTpCanMessage message;
32 int ret;
33
34 /* setup message */
36 message.as.flow_control.FS = flow_status;
37 message.as.flow_control.BS = block_size;
38 message.as.flow_control.STmin = isotp_us_to_st_min(st_min_us);
39
40 /* send message */
41#ifdef ISO_TP_FRAME_PADDING
42 (void) memset(message.as.flow_control.reserve, ISO_TP_FRAME_PADDING_VALUE, sizeof(message.as.flow_control.reserve));
43 ret = isotp_user_send_can(link->send_arbitration_id, message.as.data_array.ptr, sizeof(message));
44#else
46 message.as.data_array.ptr,
47 3);
48#endif
49
50 return ret;
51}
static uint8_t isotp_us_to_st_min(uint32_t us)
STATIC FUNCTIONS ///.
Definition: isotp.c:10
uint8_t reserve[5]

References IsoTpCanMessage::data_array, IsoTpCanMessage::flow_control, ISOTP_PCI_TYPE_FLOW_CONTROL_FRAME, isotp_us_to_st_min(), isotp_user_send_can(), IsoTpDataArray::ptr, and IsoTpLink::send_arbitration_id.

Referenced by isotp_on_can_message().

◆ isotp_send_single_frame()

static int isotp_send_single_frame ( IsoTpLink link,
uint32_t  id 
)
static

Definition at line 53 of file isotp.c.

53 {
54
55 IsoTpCanMessage message;
56 int ret;
57
58 /* multi frame message length must greater than 7 */
59 assert(link->send_size <= 7);
60
61 /* setup message */
63 message.as.single_frame.SF_DL = (uint8_t) link->send_size;
64 (void) memcpy(message.as.single_frame.data, link->send_buffer, link->send_size);
65
66 /* send message */
67#ifdef ISO_TP_FRAME_PADDING
68 (void) memset(message.as.single_frame.data + link->send_size, ISO_TP_FRAME_PADDING_VALUE, sizeof(message.as.single_frame.data) - link->send_size);
69 ret = isotp_user_send_can(id, message.as.data_array.ptr, sizeof(message));
70#else
71 ret = isotp_user_send_can(id,
72 message.as.data_array.ptr,
73 link->send_size + 1);
74#endif
75
76 return ret;
77}

References IsoTpCanMessage::data_array, ISOTP_PCI_TYPE_SINGLE, isotp_user_send_can(), IsoTpDataArray::ptr, IsoTpLink::send_buffer, IsoTpLink::send_size, and IsoTpCanMessage::single_frame.

Referenced by isotp_send_with_id().

◆ isotp_send_with_id()

int isotp_send_with_id ( IsoTpLink link,
uint32_t  id,
const uint8_t  payload[],
uint16_t  size 
)

See isotp_send, with the exception that this function is used only for functional addressing.

Definition at line 233 of file isotp.c.

233 {
234 int ret;
235
236 if (link == 0x0) {
237 isotp_user_debug("Link is null!");
238 return ISOTP_RET_ERROR;
239 }
240
241 if (size > link->send_buf_size) {
242 isotp_user_debug("Message size too large. Increase ISO_TP_MAX_MESSAGE_SIZE to set a larger buffer\n");
243 char message[128];
244 sprintf(&message[0], "Attempted to send %d bytes; max size is %d!\n", size, link->send_buf_size);
245 isotp_user_debug(message);
246 return ISOTP_RET_OVERFLOW;
247 }
248
250 isotp_user_debug("Abort previous message, transmission in progress.\n");
252 }
253
254 /* copy into local buffer */
255 link->send_size = size;
256 link->send_offset = 0;
257 (void) memcpy(link->send_buffer, payload, size);
258
259 if (link->send_size < 8) {
260 /* send single frame */
261 ret = isotp_send_single_frame(link, id);
262 } else {
263 /* send multi-frame */
264 ret = isotp_send_first_frame(link, id);
265
266 /* init multi-frame control flags */
267 if (ISOTP_RET_OK == ret) {
268 link->send_bs_remain = 0;
269 link->send_st_min_us = 0;
270 link->send_wtf_count = 0;
275 }
276 }
277
278 return ret;
279}
static int isotp_send_single_frame(IsoTpLink *link, uint32_t id)
Definition: isotp.c:53
static int isotp_send_first_frame(IsoTpLink *link, uint32_t id)
Definition: isotp.c:79
#define ISOTP_RET_INPROGRESS
Definition: isotp_defines.h:39
#define ISOTP_RET_ERROR
Definition: isotp_defines.h:38

References isotp_send_first_frame(), isotp_send_single_frame(), ISOTP_SEND_STATUS_INPROGRESS, isotp_user_debug(), isotp_user_get_us(), IsoTpLink::send_bs_remain, IsoTpLink::send_buf_size, IsoTpLink::send_buffer, IsoTpLink::send_offset, IsoTpLink::send_protocol_result, IsoTpLink::send_size, IsoTpLink::send_st_min_us, IsoTpLink::send_status, IsoTpLink::send_timer_bs, IsoTpLink::send_timer_st, and IsoTpLink::send_wtf_count.

Referenced by isotp_send().

◆ isotp_st_min_to_us()

static uint32_t isotp_st_min_to_us ( uint8_t  st_min)
static

Definition at line 20 of file isotp.c.

20 {
21 if (st_min <= 0x7F) {
22 return st_min * 1000;
23 } else if (st_min >= 0xF1 && st_min <= 0xF9) {
24 return (st_min - 0xF0) * 100;
25 }
26 return 0;
27}

Referenced by isotp_on_can_message().

◆ isotp_us_to_st_min()

static uint8_t isotp_us_to_st_min ( uint32_t  us)
static

STATIC FUNCTIONS ///.

Definition at line 10 of file isotp.c.

10 {
11 if (us <= 127000) {
12 return us / 1000;
13 } else if (us >= 100 && us <= 900) {
14 return 0xF0 + (us / 100);
15 }
16 return 0;
17}

Referenced by isotp_send_flow_control().