1 #include <isotp/send.h>
3 #define PCI_START_BIT 0
5 #define PAYLOAD_LENGTH_START_BIT PCI_START_BIT + PCI_WIDTH
6 #define PAYLOAD_LENGTH_WIDTH 4
7 #define PAYLOAD_START_BIT PAYLOAD_LENGTH_START_BIT + PAYLOAD_LENGTH_WIDTH
9 void isotp_complete_send(IsoTpHandler* handler, IsoTpMessage* message,
11 handler->message_sent_callback(message, status);
14 bool isotp_send_single_frame(IsoTpHandler* handler, IsoTpMessage* message) {
16 setBitField(&data, PCI_SINGLE, PCI_START_BIT, PCI_WIDTH);
17 setBitField(&data, message->size, PAYLOAD_LENGTH_START_BIT, PAYLOAD_LENGTH_WIDTH);
18 // TODO need a better bitfield API to support this - use byte array instead
19 // of uint64_t and specify desired total width
20 for(int i = 0; i < message->size; i++) {
21 setBitField(&data, message->payload[i], PAYLOAD_START_BIT + i * 8, 8);
24 uint8_t data_array[message->size + 1];
25 for(int i = 0; i < sizeof(data_array); i++) {
26 // TODO need getByte(x) function
27 data_array[i] = getBitField(data, i * 8, 8, false);
29 handler->shims->send_can_message(message->arbitration_id, data_array, sizeof(data_array));
30 isotp_complete_send(handler, message, true);
34 bool isotp_send_multi_frame(IsoTpHandler* handler, IsoTpMessage* message) {
35 // TODO make sure to copy payload into a local buffer
36 handler->shims->log("Only single frame messages are supported");
40 bool isotp_send(IsoTpHandler* handler, const uint8_t* payload,
42 // we determine if it's single/multi frame and start the send
43 IsoTpMessage message = {
44 arbitration_id: handler->arbitration_id,
50 return isotp_send_single_frame(handler, &message);
52 return isotp_send_multi_frame(handler, &message);