ae208eb320cf7d3fc9074b487b820cdba9f3b83b
[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(IsoTpHandler* handler, IsoTpMessage* message,
8         bool status) {
9     handler->message_sent_callback(message, status);
10 }
11
12 bool isotp_send_single_frame(IsoTpHandler* handler, IsoTpMessage* message) {
13     uint8_t can_data[CAN_MESSAGE_BYTE_SIZE] = {0};
14     if(!set_nibble(PCI_NIBBLE_INDEX, PCI_SINGLE, can_data, sizeof(can_data))) {
15         handler->shims->log("Unable to set PCI in CAN data");
16         return false;
17     }
18
19     if(!set_nibble(PAYLOAD_LENGTH_NIBBLE_INDEX, message->size, can_data,
20                 sizeof(can_data))) {
21         handler->shims->log("Unable to set payload length in CAN data");
22         return false;
23     }
24
25     if(message->size > 0) {
26         memcpy(&can_data[1], message->payload, message->size);
27     }
28
29     handler->shims->send_can_message(message->arbitration_id, can_data,
30             1 + message->size);
31     isotp_complete_send(handler, message, true);
32     return true;
33 }
34
35 bool isotp_send_multi_frame(IsoTpHandler* handler, IsoTpMessage* message) {
36     // TODO make sure to copy payload into a local buffer
37     handler->shims->log("Only single frame messages are supported");
38     return false;
39 }
40
41 bool isotp_send(IsoTpHandler* handler, const uint8_t* payload,
42         uint16_t size) {
43     // we determine if it's single/multi frame and start the send
44     IsoTpMessage message = {
45         arbitration_id: handler->arbitration_id,
46         payload: payload,
47         size: size
48     };
49
50     if(size < 8) {
51         return isotp_send_single_frame(handler, &message);
52     } else {
53         return isotp_send_multi_frame(handler, &message);
54     }
55 }