Avoid hitting a NULL pointer when using callbacks.
[apps/agl-service-can-low-level.git] / src / isotp / send.c
index ae208eb..85e3574 100644 (file)
@@ -4,52 +4,70 @@
 #define PAYLOAD_LENGTH_NIBBLE_INDEX 1
 #define PAYLOAD_BYTE_INDEX 1
 
-void isotp_complete_send(IsoTpHandler* handler, IsoTpMessage* message,
-        bool status) {
-    handler->message_sent_callback(message, status);
+void isotp_complete_send(IsoTpShims* shims, IsoTpMessage* message,
+        bool status, IsoTpMessageSentHandler callback) {
+    if(callback != NULL) {
+        callback(message, status);
+    }
 }
 
-bool isotp_send_single_frame(IsoTpHandler* handler, IsoTpMessage* message) {
+IsoTpHandle isotp_send_single_frame(IsoTpShims* shims, IsoTpMessage* message,
+        IsoTpMessageSentHandler callback) {
+    IsoTpHandle handle = {
+        success: false,
+        completed: true,
+        type: ISOTP_HANDLE_SENDING
+    };
+
     uint8_t can_data[CAN_MESSAGE_BYTE_SIZE] = {0};
     if(!set_nibble(PCI_NIBBLE_INDEX, PCI_SINGLE, can_data, sizeof(can_data))) {
-        handler->shims->log("Unable to set PCI in CAN data");
-        return false;
+        shims->log("Unable to set PCI in CAN data");
+        return handle;
     }
 
     if(!set_nibble(PAYLOAD_LENGTH_NIBBLE_INDEX, message->size, can_data,
                 sizeof(can_data))) {
-        handler->shims->log("Unable to set payload length in CAN data");
-        return false;
+        shims->log("Unable to set payload length in CAN data");
+        return handle;
     }
 
     if(message->size > 0) {
         memcpy(&can_data[1], message->payload, message->size);
     }
 
-    handler->shims->send_can_message(message->arbitration_id, can_data,
+    shims->send_can_message(message->arbitration_id, can_data,
             1 + message->size);
-    isotp_complete_send(handler, message, true);
-    return true;
+    handle.success = true;
+    isotp_complete_send(shims, message, true, callback);
+    return handle;
 }
 
-bool isotp_send_multi_frame(IsoTpHandler* handler, IsoTpMessage* message) {
+IsoTpHandle isotp_send_multi_frame(IsoTpShims* shims, IsoTpMessage* message,
+        IsoTpMessageSentHandler callback) {
     // TODO make sure to copy payload into a local buffer
-    handler->shims->log("Only single frame messages are supported");
-    return false;
+    shims->log("Only single frame messages are supported");
+    IsoTpHandle handle = {
+        success: false,
+        completed: true,
+        type: ISOTP_HANDLE_SENDING
+    };
+    // TODO need to set sending and receiving arbitration IDs separately if we
+    // can't always just add 0x8 (and I think we can't)
+    return handle;
 }
 
-bool isotp_send(IsoTpHandler* handler, const uint8_t* payload,
-        uint16_t size) {
-    // we determine if it's single/multi frame and start the send
+IsoTpHandle isotp_send(IsoTpShims* shims, const uint16_t arbitration_id,
+        const uint8_t* payload, uint16_t size,
+        IsoTpMessageSentHandler callback) {
     IsoTpMessage message = {
-        arbitration_id: handler->arbitration_id,
+        arbitration_id: arbitration_id,
         payload: payload,
         size: size
     };
 
     if(size < 8) {
-        return isotp_send_single_frame(handler, &message);
+        return isotp_send_single_frame(shims, &message, callback);
     } else {
-        return isotp_send_multi_frame(handler, &message);
+        return isotp_send_multi_frame(shims, &message, callback);
     }
 }