Allocate ISO-TP message buffer on the stack.
[apps/agl-service-can-low-level.git] / src / isotp / isotp.h
1 #ifndef __ISOTP_H__
2 #define __ISOTP_H__
3
4 #include <stdint.h>
5 #include <stdbool.h>
6 #include <stdio.h>
7
8 #define CAN_MESSAGE_BYTE_SIZE 8
9 #define MAX_ISO_TP_MESSAGE_SIZE 4096
10 // TODO we want to avoid malloc, and we can't be allocated 4K on the stack for
11 // each IsoTpMessage, so for now we're setting an artificial max message size
12 // here - since we only handle single frame messages, 8 bytes is plenty.
13 #define OUR_MAX_ISO_TP_MESSAGE_SIZE 8
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 const uint8_t ISO_TP_DEFAULT_RESPONSE_TIMEOUT;
20 const bool ISO_TP_DEFAULT_FRAME_PADDING_STATUS;
21
22 typedef struct {
23     const uint16_t arbitration_id;
24     uint8_t payload[OUR_MAX_ISO_TP_MESSAGE_SIZE];
25     uint16_t size;
26     bool completed;
27 } IsoTpMessage;
28
29 typedef void (*LogShim)(const char* message, ...);
30 typedef bool (*SendCanMessageShim)(const uint16_t arbitration_id,
31         const uint8_t* data, const uint8_t size);
32 typedef bool (*SetTimerShim)(uint16_t time_ms, void (*callback));
33
34 typedef void (*IsoTpMessageReceivedHandler)(const IsoTpMessage* message);
35 typedef void (*IsoTpMessageSentHandler)(const IsoTpMessage* message,
36         const bool success);
37 typedef void (*IsoTpCanFrameSentHandler)(const IsoTpMessage* message);
38
39 typedef struct {
40     LogShim log;
41     SendCanMessageShim send_can_message;
42     SetTimerShim set_timer;
43 } IsoTpShims;
44
45 typedef struct {
46     uint16_t arbitration_id;
47     IsoTpMessageReceivedHandler message_received_callback;
48
49     // Private
50     uint16_t timeout_ms;
51     // timeout_ms: ISO_TP_DEFAULT_RESPONSE_TIMEOUT,
52     bool frame_padding;
53     // frame_padding: ISO_TP_DEFAULT_FRAME_PADDING_STATUS,
54     uint8_t* receive_buffer;
55     uint16_t received_buffer_size;
56     uint16_t incoming_message_size;
57     // TODO timer callback
58 } IsoTpReceiveHandle;
59
60 typedef struct {
61     uint16_t sending_arbitration_id;
62     uint16_t receiving_arbitration_id;
63     IsoTpMessageSentHandler message_sent_callback;
64     IsoTpCanFrameSentHandler can_frame_sent_callback;
65
66     // TODO going to need some state here for multi frame messages
67 } IsoTpSendHandle;
68
69 typedef enum {
70     ISOTP_HANDLE_SENDING,
71     ISOTP_HANDLE_RECEIVING
72 } IsoTpHandleType;
73
74 typedef struct {
75     bool success;
76     bool completed;
77     IsoTpHandleType type;
78     IsoTpReceiveHandle receive_handle;
79     IsoTpSendHandle send_handle;
80 } IsoTpHandle;
81
82
83 typedef enum {
84     PCI_SINGLE = 0x0,
85     PCI_FIRST_FRAME = 0x1,
86     PCI_CONSECUTIVE_FRAME = 0x2,
87     PCI_FLOW_CONTROL_FRAME = 0x3
88 } IsoTpProtocolControlInformation;
89
90 typedef enum {
91     PCI_FLOW_STATUS_CONTINUE = 0x0,
92     PCI_FLOW_STATUS_WAIT = 0x1,
93     PCI_FLOW_STATUS_OVERFLOW = 0x2
94 } IsoTpFlowStatus;
95
96 IsoTpShims isotp_init_shims(LogShim log,
97         SendCanMessageShim send_can_message,
98         SetTimerShim set_timer);
99
100 /* Public:
101  *
102  */
103 IsoTpMessage isotp_receive_can_frame(IsoTpShims* shims, IsoTpHandle* handle,
104         const uint16_t arbitration_id, const uint8_t data[],
105         const uint8_t size);
106
107 // TODO perhaps this makes more sense as 2 functions:
108 // bool isotp_continue_send()
109 // IsoTpMessage isotp_continue_receive()
110 // but both with the same args
111
112 /* Public: Change the timeout for waiting on an ISO-TP response frame.
113  *
114  * If this function is not used, the conventional 100ms is used by default.
115  *
116  * handler - the ISO-TP handler to modify.
117  * timeout - the new timeout in milliseconds.
118  */
119 // void isotp_set_timeout(IsoTpHandler* handler, uint16_t timeout_ms);
120
121 // void isotp_destroy(IsoTpHandler* handler);
122
123 void isotp_message_to_string(const IsoTpMessage* message, char* destination,
124         size_t destination_length);
125
126 IsoTpHandle isotp_send(IsoTpShims* shims, const uint16_t arbitration_id,
127         const uint8_t payload[], uint16_t size,
128         IsoTpMessageSentHandler callback);
129
130 IsoTpHandle isotp_receive(IsoTpShims* shims,
131         const uint16_t arbitration_id, IsoTpMessageReceivedHandler callback);
132
133 #ifdef __cplusplus
134 }
135 #endif
136
137 #endif // __ISOTP_H__