Increase arb IDs to uint32_t to fit extended IDs.
[apps/low-level-can-service.git] / src / uds / uds.c
index 400eedf..510cdd4 100644 (file)
@@ -32,7 +32,7 @@ DiagnosticShims diagnostic_init_shims(LogShim log,
 
 static void setup_receive_handle(DiagnosticRequestHandle* handle) {
     if(handle->request.arbitration_id == OBD2_FUNCTIONAL_BROADCAST_ID) {
-        uint16_t response_id;
+        uint32_t response_id;
         for(response_id = 0;
                 response_id < OBD2_FUNCTIONAL_RESPONSE_COUNT; ++response_id) {
             handle->isotp_receive_handles[response_id] = isotp_receive(
@@ -61,7 +61,45 @@ static uint16_t autoset_pid_length(uint8_t mode, uint16_t pid,
     return pid_length;
 }
 
-DiagnosticRequestHandle diagnostic_request(DiagnosticShims* shims,
+static void send_diagnostic_request(DiagnosticShims* shims,
+        DiagnosticRequestHandle* handle) {
+    uint8_t payload[MAX_DIAGNOSTIC_PAYLOAD_SIZE] = {0};
+    payload[MODE_BYTE_INDEX] = handle->request.mode;
+    if(handle->request.has_pid) {
+        handle->request.pid_length = autoset_pid_length(handle->request.mode,
+                handle->request.pid, handle->request.pid_length);
+        handle->request.pid_length = handle->request.pid_length;
+        set_bitfield(handle->request.pid, PID_BYTE_INDEX * CHAR_BIT,
+                handle->request.pid_length * CHAR_BIT, payload,
+                sizeof(payload));
+    }
+
+    if(handle->request.payload_length > 0) {
+        memcpy(&payload[PID_BYTE_INDEX + handle->request.pid_length],
+                handle->request.payload, handle->request.payload_length);
+    }
+
+    handle->isotp_send_handle = isotp_send(&handle->isotp_shims,
+            handle->request.arbitration_id, payload,
+            1 + handle->request.payload_length + handle->request.pid_length,
+            NULL);
+    if(shims->log != NULL) {
+        char request_string[128] = {0};
+        diagnostic_request_to_string(&handle->request, request_string,
+                sizeof(request_string));
+        shims->log("Sending diagnostic request: %s", request_string);
+    }
+}
+
+void start_diagnostic_request(DiagnosticShims* shims,
+        DiagnosticRequestHandle* handle) {
+    handle->success = false;
+    handle->completed = false;
+    send_diagnostic_request(shims, handle);
+    setup_receive_handle(handle);
+}
+
+DiagnosticRequestHandle generate_diagnostic_request(DiagnosticShims* shims,
         DiagnosticRequest* request, DiagnosticResponseReceived callback) {
     DiagnosticRequestHandle handle = {
         request: *request,
@@ -70,37 +108,12 @@ DiagnosticRequestHandle diagnostic_request(DiagnosticShims* shims,
         completed: false
     };
 
-    uint8_t payload[MAX_DIAGNOSTIC_PAYLOAD_SIZE] = {0};
-    payload[MODE_BYTE_INDEX] = request->mode;
-    if(request->has_pid) {
-        request->pid_length = autoset_pid_length(request->mode,
-                request->pid, request->pid_length);
-        handle.request.pid_length = request->pid_length;
-        set_bitfield(request->pid, PID_BYTE_INDEX * CHAR_BIT,
-                request->pid_length * CHAR_BIT, payload, sizeof(payload));
-    }
-    if(request->payload_length > 0) {
-        memcpy(&payload[PID_BYTE_INDEX + request->pid_length],
-                request->payload, request->payload_length);
-    }
-
     handle.isotp_shims = isotp_init_shims(shims->log,
             shims->send_can_message,
             shims->set_timer);
     handle.isotp_shims.frame_padding = !request->no_frame_padding;
 
-    handle.isotp_send_handle = isotp_send(&handle.isotp_shims,
-            request->arbitration_id, payload,
-            1 + request->payload_length + request->pid_length,
-            NULL);
-    if(shims->log != NULL) {
-        char request_string[128] = {0};
-        diagnostic_request_to_string(request, request_string, sizeof(request_string));
-        shims->log("Sending diagnostic request: %s", request_string);
-    }
-
-    setup_receive_handle(&handle);
-
+    return handle;
     // TODO notes on multi frame:
     // TODO what are the timers for exactly?
     //
@@ -118,11 +131,18 @@ DiagnosticRequestHandle diagnostic_request(DiagnosticShims* shims,
     // of the information but arg, memory allocation. look at how it's done in
     // the other library again
     //
+}
+
+DiagnosticRequestHandle diagnostic_request(DiagnosticShims* shims,
+        DiagnosticRequest* request, DiagnosticResponseReceived callback) {
+    DiagnosticRequestHandle handle = generate_diagnostic_request(
+            shims, request, callback);
+    start_diagnostic_request(shims, &handle);
     return handle;
 }
 
 DiagnosticRequestHandle diagnostic_request_pid(DiagnosticShims* shims,
-        DiagnosticPidRequestType pid_request_type, uint16_t arbitration_id,
+        DiagnosticPidRequestType pid_request_type, uint32_t arbitration_id,
         uint16_t pid, DiagnosticResponseReceived callback) {
     DiagnosticRequest request = {
         arbitration_id: arbitration_id,
@@ -175,17 +195,17 @@ static bool handle_positive_response(DiagnosticRequestHandle* handle,
 
         }
 
-        uint8_t payload_index = 1 + handle->request.pid_length;
-        response->payload_length = MAX(0, message->size - payload_index);
-        if(response->payload_length > 0) {
-            memcpy(response->payload, &message->payload[payload_index],
-                    response->payload_length);
-        }
-
         if((!handle->request.has_pid && !response->has_pid)
                 || response->pid == handle->request.pid) {
             response->success = true;
             response->completed = true;
+
+            uint8_t payload_index = 1 + handle->request.pid_length;
+            response->payload_length = MAX(0, message->size - payload_index);
+            if(response->payload_length > 0) {
+                memcpy(response->payload, &message->payload[payload_index],
+                        response->payload_length);
+            }
         } else {
             response_was_positive = false;
         }
@@ -194,7 +214,7 @@ static bool handle_positive_response(DiagnosticRequestHandle* handle,
 }
 
 DiagnosticResponse diagnostic_receive_can_frame(DiagnosticShims* shims,
-        DiagnosticRequestHandle* handle, const uint16_t arbitration_id,
+        DiagnosticRequestHandle* handle, const uint32_t arbitration_id,
         const uint8_t data[], const uint8_t size) {
 
     DiagnosticResponse response = {
@@ -216,34 +236,19 @@ DiagnosticResponse diagnostic_receive_can_frame(DiagnosticShims* shims,
             if(message.completed) {
                 if(message.size > 0) {
                     response.mode = message.payload[0];
-                    if(handle_negative_response(&message, &response, shims)) {
-                        if(shims->log != NULL) {
-                            char response_string[128] = {0};
-                            diagnostic_response_to_string(&response, response_string, sizeof(response_string));
-                            shims->log("Received a negative response: %s", response_string);
-                        }
-
-                        handle->success = true;
-                        handle->completed = true;
-                    } else if(handle_positive_response(handle, &message,
+                    if(handle_negative_response(&message, &response, shims) ||
+                            handle_positive_response(handle, &message,
                                 &response, shims)) {
                         if(shims->log != NULL) {
                             char response_string[128] = {0};
-                            diagnostic_response_to_string(&response, response_string, sizeof(response_string));
-                            shims->log("Received a positive response: %s", response_string);
+                            diagnostic_response_to_string(&response,
+                                    response_string, sizeof(response_string));
+                            shims->log("Diagnostic response received: %s",
+                                    response_string);
                         }
 
                         handle->success = true;
                         handle->completed = true;
-                    } else {
-                        if(shims->log != NULL) {
-                            char response_string[128] = {0};
-                            diagnostic_response_to_string(&response, response_string, sizeof(response_string));
-                            shims->log("Expected a mode 0x%x response to pid 0x%x but received: %s",
-                                    MAX(0, response.mode - MODE_RESPONSE_OFFSET),
-                                    response.pid,
-                                    response_string);
-                        }
                     }
                 } else {
                     if(shims->log != NULL) {
@@ -268,8 +273,7 @@ int diagnostic_payload_to_integer(const DiagnosticResponse* response) {
             response->payload_length * CHAR_BIT);
 }
 
-float diagnostic_decode_obd2_pid(const DiagnosticResponse* response,
-        int parsed_payload) {
+float diagnostic_decode_obd2_pid(const DiagnosticResponse* response) {
     // handles on the single number values, not the bit encoded ones
     switch(response->pid) {
         case 0xa:
@@ -305,13 +309,26 @@ float diagnostic_decode_obd2_pid(const DiagnosticResponse* response,
 void diagnostic_response_to_string(const DiagnosticResponse* response,
         char* destination, size_t destination_length) {
     int bytes_used = snprintf(destination, destination_length,
-            "arb_id: 0x%02x, mode: 0x%x, pid: 0x%x, ",
+            "arb_id: 0x%02x, mode: 0x%x, ",
             response->arbitration_id,
-            response->mode,
-            response->pid);
-    int remaining_space = destination_length - bytes_used;
+            response->mode);
+
+    if(response->has_pid) {
+        bytes_used += snprintf(destination + bytes_used,
+                destination_length - bytes_used,
+                "pid: 0x%x, ",
+                response->pid);
+    }
+
+    if(!response->success) {
+        bytes_used += snprintf(destination + bytes_used,
+                destination_length - bytes_used,
+                "nrc: 0x%x, ",
+                response->negative_response_code);
+    }
+
     if(response->payload_length > 0) {
-        snprintf(destination + bytes_used, remaining_space,
+        snprintf(destination + bytes_used, destination_length - bytes_used,
                 "payload: 0x%02x%02x%02x%02x%02x%02x%02x",
                 response->payload[0],
                 response->payload[1],
@@ -321,17 +338,25 @@ void diagnostic_response_to_string(const DiagnosticResponse* response,
                 response->payload[5],
                 response->payload[6]);
     } else {
-        snprintf(destination + bytes_used, remaining_space, "no payload");
+        snprintf(destination + bytes_used, destination_length - bytes_used,
+                "no payload");
     }
 }
 
 void diagnostic_request_to_string(const DiagnosticRequest* request,
         char* destination, size_t destination_length) {
     int bytes_used = snprintf(destination, destination_length,
-            "arb_id: 0x%02x, mode: 0x%x, pid: 0x%x, ",
+            "arb_id: 0x%02x, mode: 0x%x, ",
             request->arbitration_id,
-            request->mode,
-            request->pid);
+            request->mode);
+
+    if(request->has_pid) {
+        bytes_used += snprintf(destination + bytes_used,
+                destination_length - bytes_used,
+                "pid: 0x%x, ",
+                request->pid);
+    }
+
     int remaining_space = destination_length - bytes_used;
     if(request->payload_length > 0) {
         snprintf(destination + bytes_used, remaining_space,
@@ -348,3 +373,11 @@ void diagnostic_request_to_string(const DiagnosticRequest* request,
     }
 }
 
+bool diagnostic_request_equals(const DiagnosticRequest* ours,
+        const DiagnosticRequest* theirs) {
+    bool equals = ours->arbitration_id == theirs->arbitration_id &&
+        ours->mode == theirs->mode;
+    equals &= ours->has_pid == theirs->has_pid;
+    equals &= ours->pid == theirs->pid;
+    return equals;
+}