6cce5c9298a7143d1231d377ce3fcec100f1b915
[apps/agl-service-can-low-level.git] / src / isotp / send.c
1 #include <isotp/send.h>
2
3 #define PCI_NIBBLE_INDEX 0
4 #define PAYLOAD_LENGTH_NIBBLE_INDEX 1
5 #define PAYLOAD_BYTE_INDEX 1
6
7 void isotp_complete_send(IsoTpShims* shims, IsoTpMessage* message,
8         bool status, IsoTpMessageSentHandler callback) {
9     callback(message, status);
10 }
11
12 IsoTpHandle isotp_send_single_frame(IsoTpShims* shims, IsoTpMessage* message,
13         IsoTpMessageSentHandler callback) {
14     IsoTpHandle handle = {
15         success: false,
16         completed: true,
17         type: ISOTP_HANDLE_SENDING
18     };
19
20     uint8_t can_data[CAN_MESSAGE_BYTE_SIZE] = {0};
21     if(!set_nibble(PCI_NIBBLE_INDEX, PCI_SINGLE, can_data, sizeof(can_data))) {
22         shims->log("Unable to set PCI in CAN data");
23         return handle;
24     }
25
26     if(!set_nibble(PAYLOAD_LENGTH_NIBBLE_INDEX, message->size, can_data,
27                 sizeof(can_data))) {
28         shims->log("Unable to set payload length in CAN data");
29         return handle;
30     }
31
32     if(message->size > 0) {
33         memcpy(&can_data[1], message->payload, message->size);
34     }
35
36     shims->send_can_message(message->arbitration_id, can_data,
37             1 + message->size);
38     handle.success = true;
39     isotp_complete_send(shims, message, true, callback);
40     return handle;
41 }
42
43 IsoTpHandle isotp_send_multi_frame(IsoTpShims* shims, IsoTpMessage* message,
44         IsoTpMessageSentHandler callback) {
45     // TODO make sure to copy payload into a local buffer
46     shims->log("Only single frame messages are supported");
47     IsoTpHandle handle = {
48         success: false,
49         completed: true,
50         type: ISOTP_HANDLE_SENDING
51     };
52     // TODO need to set sending and receiving arbitration IDs separately if we
53     // can't always just add 0x8 (and I think we can't)
54     return handle;
55 }
56
57 IsoTpHandle isotp_send(IsoTpShims* shims, const uint16_t arbitration_id,
58         const uint8_t* payload, uint16_t size,
59         IsoTpMessageSentHandler callback) {
60     IsoTpMessage message = {
61         arbitration_id: arbitration_id,
62         payload: payload,
63         size: size
64     };
65
66     if(size < 8) {
67         return isotp_send_single_frame(shims, &message, callback);
68     } else {
69         return isotp_send_multi_frame(shims, &message, callback);
70     }
71 }