Split up functions in send/receive files for clarity.
[apps/agl-service-can-low-level.git] / src / isotp / receive.c
1 #include <isotp/receive.h>
2
3 bool isotp_handle_single_frame(IsoTpReceiveHandle* handle, IsoTpMessage* message) {
4     isotp_complete_receive(handle, message);
5     return true;
6 }
7
8 void isotp_complete_receive(IsoTpReceiveHandle* handle, IsoTpMessage* message) {
9     if(handle->message_received_callback != NULL) {
10         handle->message_received_callback(message);
11     }
12 }
13
14 IsoTpReceiveHandle isotp_receive(IsoTpShims* shims,
15         const uint16_t arbitration_id, IsoTpMessageReceivedHandler callback) {
16     IsoTpReceiveHandle handle = {
17         success: false,
18         completed: false,
19         arbitration_id: arbitration_id,
20         message_received_callback: callback
21     };
22
23     return handle;
24 }
25
26 IsoTpMessage isotp_continue_receive(IsoTpShims* shims,
27         IsoTpReceiveHandle* handle, const uint16_t arbitration_id,
28         const uint8_t data[], const uint8_t size) {
29     IsoTpMessage message = {
30         arbitration_id: arbitration_id,
31         completed: false,
32         payload: {0},
33         size: 0
34     };
35
36     if(size < 1) {
37         return message;
38     }
39
40     if(handle->arbitration_id != arbitration_id) {
41         if(shims->log != NULL)  {
42             shims->log("The arb ID 0x%x doesn't match the expected rx ID 0x%x",
43                     arbitration_id, handle->arbitration_id);
44         }
45         return message;
46     }
47
48     IsoTpProtocolControlInformation pci = (IsoTpProtocolControlInformation)
49             get_nibble(data, size, 0);
50
51     uint8_t payload_length = get_nibble(data, size, 1);
52     uint8_t payload[payload_length];
53     if(payload_length > 0 && size > 0) {
54         memcpy(payload, &data[1], payload_length);
55     }
56
57     // TODO this is set up to handle rx a response with a payload, but not to
58     // handle flow control responses for multi frame messages that we're in the
59     // process of sending
60
61     switch(pci) {
62         case PCI_SINGLE: {
63             if(payload_length > 0) {
64                 memcpy(message.payload, payload, payload_length);
65             }
66             message.size = payload_length;
67             message.completed = true;
68             handle->success = true;
69             handle->completed = true;
70             isotp_handle_single_frame(handle, &message);
71             break;
72          }
73         default:
74             shims->log("Only single frame messages are supported");
75             break;
76     }
77     return message;
78 }