1 #include <isotp/send.h>
3 #define PCI_NIBBLE_INDEX 0
4 #define PAYLOAD_LENGTH_NIBBLE_INDEX 1
5 #define PAYLOAD_BYTE_INDEX 1
7 void isotp_complete_send(IsoTpShims* shims, IsoTpMessage* message,
8 bool status, IsoTpMessageSentHandler callback) {
10 callback(message, status);
14 IsoTpHandle isotp_send_single_frame(IsoTpShims* shims, IsoTpMessage* message,
15 IsoTpMessageSentHandler callback) {
16 IsoTpHandle handle = {
19 type: ISOTP_HANDLE_SENDING
22 uint8_t can_data[CAN_MESSAGE_BYTE_SIZE] = {0};
23 if(!set_nibble(PCI_NIBBLE_INDEX, PCI_SINGLE, can_data, sizeof(can_data))) {
24 shims->log("Unable to set PCI in CAN data");
28 if(!set_nibble(PAYLOAD_LENGTH_NIBBLE_INDEX, message->size, can_data,
30 shims->log("Unable to set payload length in CAN data");
34 if(message->size > 0) {
35 memcpy(&can_data[1], message->payload, message->size);
38 shims->send_can_message(message->arbitration_id, can_data,
40 handle.success = true;
41 isotp_complete_send(shims, message, true, callback);
45 IsoTpHandle isotp_send_multi_frame(IsoTpShims* shims, IsoTpMessage* message,
46 IsoTpMessageSentHandler callback) {
47 // TODO make sure to copy payload into a local buffer
48 shims->log("Only single frame messages are supported");
49 IsoTpHandle handle = {
52 type: ISOTP_HANDLE_SENDING
54 // TODO need to set sending and receiving arbitration IDs separately if we
55 // can't always just add 0x8 (and I think we can't)
59 IsoTpHandle isotp_send(IsoTpShims* shims, const uint16_t arbitration_id,
60 const uint8_t* payload, uint16_t size,
61 IsoTpMessageSentHandler callback) {
62 IsoTpMessage message = {
63 arbitration_id: arbitration_id,
69 return isotp_send_single_frame(shims, &message, callback);
71 return isotp_send_multi_frame(shims, &message, callback);