From a08ba0d03b25f50213dcccfb2d8baa0fcb9f73e0 Mon Sep 17 00:00:00 2001 From: michael beebe Date: Mon, 28 Aug 2023 23:56:34 -0400 Subject: [PATCH] Added Obdlink EX, J2534 fully functional --- IPCHammer/MainForm.cs | 4 +- IPCLibraryWindowsForms/Devices/J2534Device.cs | 163 +++++++++++------- 2 files changed, 106 insertions(+), 61 deletions(-) diff --git a/IPCHammer/MainForm.cs b/IPCHammer/MainForm.cs index b520295..63b93c9 100644 --- a/IPCHammer/MainForm.cs +++ b/IPCHammer/MainForm.cs @@ -36,7 +36,7 @@ public partial class MainForm : MainFormBase, ILogger /// /// If not null, use a number like "004" that matches a release branch. /// - private const string AppVersion = "016.7"; + private const string AppVersion = "016.8"; /// /// We had to move some operations to a background thread for the J2534 code as the DLL functions do not have an awaiter. @@ -410,6 +410,8 @@ private async void readPropertiesButton_Click(object sender, EventArgs e) try { this.DisableUserInput(); + await this.Vehicle.SuppressChatter(); + this.Vehicle.ClearDeviceMessageQueue(); var vinResponse = await this.Vehicle.QueryVin(); if (vinResponse.Status != ResponseStatus.Success) diff --git a/IPCLibraryWindowsForms/Devices/J2534Device.cs b/IPCLibraryWindowsForms/Devices/J2534Device.cs index 41cd51c..cbcfac7 100644 --- a/IPCLibraryWindowsForms/Devices/J2534Device.cs +++ b/IPCLibraryWindowsForms/Devices/J2534Device.cs @@ -20,7 +20,7 @@ class J2534Device : Device /// /// Configuration settings /// - public int ReadTimeout = 2000; + public int ReadTimeout = 3000; public int WriteTimeout = 2000; /// @@ -34,6 +34,8 @@ class J2534Device : Device public bool IsProtocolOpen; public bool IsJ2534Open; private const string PortName = "J2534"; + private const uint MessageFilter = 0x6CF060; + private const uint MessageFilter2 = 0x8CF060; public string ToolName = ""; /// @@ -59,9 +61,12 @@ public J2534Device(J2534.J2534Device jport, ILogger logger) : base(logger) J2534Port.Functions = new J2534Extended(); J2534Port.LoadedDevice = jport; - this.MaxSendSize = 4096+10+2; // Driver or protocol limit? - this.MaxReceiveSize = 4096+10+2; // Driver or protocol limit? - this.Supports4X = true; + // Reduced from 4096+12 for the MDI2 + this.MaxSendSize = 2048 + 12; // J2534 Standard is 4KB + this.MaxReceiveSize = 2048 + 12; // J2534 Standard is 4KB + this.Supports4X = true; + //this.SupportsSingleDpidLogging = true; + //this.SupportsStreamLogging = true; } protected override void Dispose(bool disposing) @@ -88,79 +93,103 @@ private bool InitializeInternal() { Filters = new List(); - //this.Logger.AddDebugMessage("Initialize called"); - this.Logger.AddDebugMessage("Initializing " + this.ToString()); + this.Logger.AddUserMessage("Initializing " + this.ToString()); Response m; // hold returned messages for processing Response m2; Response volts; - //Check J2534 API + // Check J2534 API //this.Logger.AddDebugMessage(J2534Port.Functions.ToString()); - //Check not already loaded + // Check not already loaded if (IsLoaded == true) { - this.Logger.AddDebugMessage("DLL already loaded, unloading before proceeding"); + // Disconnect protocol before disconnecting tool. + m = DisconnectFromProtocol(); + if (m.Status != ResponseStatus.Success) + { + this.Logger.AddUserMessage("Error disconnecting from protocol."); + return false; + } + this.Logger.AddDebugMessage("Successfully disconnected from protocol."); + + // Disconnect tool before unloading DLL. + m = DisconnectTool(); + if (m.Status != ResponseStatus.Success) + { + this.Logger.AddUserMessage("Error disconnecting from tool."); + return false; + } + this.Logger.AddDebugMessage("Successfully disconnected from tool."); + + // Unload DLL. m2 = CloseLibrary(); if (m2.Status != ResponseStatus.Success) { - this.Logger.AddDebugMessage("Error closing loaded DLL"); + this.Logger.AddUserMessage("Error unloading DLL"); return false; } - this.Logger.AddDebugMessage("DLL successfully unloaded"); + this.Logger.AddDebugMessage("Successfully unloaded DLL."); } - //Connect to requested DLL + // Connect to requested DLL m2 = LoadLibrary(J2534Port.LoadedDevice); if (m2.Status != ResponseStatus.Success) { - this.Logger.AddDebugMessage("Error occured loading J2534 DLL"); + this.Logger.AddUserMessage("Unable to load the J2534 DLL."); return false; } this.Logger.AddUserMessage("Loaded DLL"); - - //connect to scantool + // Connect to scantool m = ConnectTool(); if (m.Status != ResponseStatus.Success) { - this.Logger.AddDebugMessage("Error occured connecting to scantool"); + this.Logger.AddUserMessage("Unable to connect to the device."); return false; } - this.Logger.AddUserMessage("Connected to Scantool"); - - //Optional.. read API,firmware version ect here - - - //read voltage + this.Logger.AddUserMessage("Connected to the device."); + + // Optional.. read API,firmware version ect here + + // Read voltage volts = ReadVoltage(); if (volts.Status != ResponseStatus.Success) { - this.Logger.AddDebugMessage("Error occured reading voltage"); - return false; + this.Logger.AddDebugMessage("Unable to read battery voltage."); + } + else + { + this.Logger.AddUserMessage("Battery Voltage is: " + volts.Value.ToString()); } - this.Logger.AddUserMessage("Battery Voltage is: " + volts.Value.ToString()); - this.Logger.AddDebugMessage("Battery Voltage is: " + volts.Value.ToString()); - //Set Protocol + // Set Protocol m = ConnectToProtocol(ProtocolID.J1850VPW, BaudRate.J1850VPW_10400, ConnectFlag.NONE); if (m.Status != ResponseStatus.Success) { - this.Logger.AddDebugMessage("Failed to set protocol, J2534 error code: 0x" + m.Value.ToString("X")); + this.Logger.AddUserMessage("Failed to set protocol, J2534 error code: 0x" + m.Value.ToString("X")); return false; } this.Logger.AddDebugMessage("Protocol Set"); - //Set filter - m = SetFilter(0xFEFFFF, 0x6CF060, 0, TxFlag.NONE, FilterType.PASS_FILTER); + // Set filter + m = SetFilter(0xFEFFFF, J2534Device.MessageFilter, 0, TxFlag.NONE, FilterType.PASS_FILTER); + if (m.Status != ResponseStatus.Success) + { + this.Logger.AddUserMessage("Failed to set filter, J2534 error code: 0x" + m.Value.ToString("X2")); + return false; + } + + m = SetFilter(0xFEFFFF, J2534Device.MessageFilter2, 0, TxFlag.NONE, FilterType.PASS_FILTER); if (m.Status != ResponseStatus.Success) { - this.Logger.AddDebugMessage("Failed to set filter, J2534 error code: 0x" + m.Value.ToString("X2")); + this.Logger.AddUserMessage("Failed to set filter, J2534 error code: 0x" + m.Value.ToString("X2")); return false; } - this.Logger.AddDebugMessage("Filter Set"); + + this.Logger.AddDebugMessage("Device initialization complete."); return true; } @@ -182,8 +211,10 @@ public async Task> FindResponse(Message expected) for (int iterations = 0; iterations < 5; iterations++) { Message response = await this.ReceiveMessage(); - if (Utility.CompareArraysPart(response.GetBytes(), expected.GetBytes())) - return Response.Create(ResponseStatus.Success, response); + if (Utility.CompareArraysPart(response.GetBytes(), expected.GetBytes())) + { + return Response.Create(ResponseStatus.Success, response); + } await Task.Delay(100); } @@ -198,26 +229,25 @@ protected override Task Receive() //this.Logger.AddDebugMessage("Trace: Read Network Packet"); PassThruMsg PassMess = new PassThruMsg(); - Message TempMessage = new Message(null); int NumMessages = 1; IntPtr rxMsgs = Marshal.AllocHGlobal((int)(Marshal.SizeOf(typeof(PassThruMsg)) * NumMessages)); - OBDError = 0; //Clear any previous faults + OBDError = 0; // Clear any previous faults Stopwatch sw = new Stopwatch(); sw.Start(); - while (OBDError == J2534Err.STATUS_NOERROR || sw.ElapsedMilliseconds > (long)ReadTimeout) + do { NumMessages = 1; OBDError = J2534Port.Functions.PassThruReadMsgs((int)ChannelID, rxMsgs, ref NumMessages, ReadTimeout); if (OBDError != J2534Err.STATUS_NOERROR) { - this.Logger.AddDebugMessage("ReadMsgs OBDError:1 " + OBDError); + this.Logger.AddDebugMessage("ReadMsgs OBDError: " + OBDError); + Marshal.FreeHGlobal(rxMsgs); return Task.FromResult(0); } - sw.Stop(); PassMess = rxMsgs.AsMsgList(1).Last(); if ((int)PassMess.RxStatus == (((int)RxStatus.TX_INDICATION_SUCCESS) + ((int)RxStatus.TX_MSG_TYPE)) || (PassMess.RxStatus == RxStatus.START_OF_MESSAGE)) { @@ -226,15 +256,17 @@ protected override Task Receive() else { byte[] TempBytes = PassMess.GetBytes(); - //Perform additional filter check if required here... or show to debug - break;//leave while loop + // Perform additional filter check if required here... or show to debug + break; // Exit loop } - } + } while (OBDError == J2534Err.STATUS_NOERROR || sw.ElapsedMilliseconds > (long)ReadTimeout); + sw.Stop(); + Marshal.FreeHGlobal(rxMsgs); if (OBDError != J2534Err.STATUS_NOERROR || sw.ElapsedMilliseconds > (long)ReadTimeout) { - this.Logger.AddDebugMessage("ReadMsgs OBDError:2 " + OBDError); + this.Logger.AddDebugMessage("ReadMsgs OBDError: " + OBDError); return Task.FromResult(0); } @@ -263,7 +295,7 @@ private Response SendNetworkMessage(Message message, TxFlag Flags) Marshal.FreeHGlobal(MsgPtr); if (OBDError != J2534Err.STATUS_NOERROR) { - //Debug messages here...check why failed.. + // Debug messages here...check why failed.. return Response.Create(ResponseStatus.Error, OBDError); } return Response.Create(ResponseStatus.Success, OBDError); @@ -286,7 +318,7 @@ public override Task SendMessage(Message message) } /// - /// load in dll + /// Load in dll /// private Response LoadLibrary(J2534.J2534Device TempDevice) { @@ -303,7 +335,7 @@ private Response LoadLibrary(J2534.J2534Device TempDevice) } /// - /// unload dll + /// Unload dll /// private Response CloseLibrary() { @@ -347,14 +379,14 @@ private Response DisconnectTool() OBDError = J2534Port.Functions.PassThruClose(DeviceID); if (OBDError != J2534Err.STATUS_NOERROR) { - //big problems, do something here + // Big problems, do something here } IsJ2534Open = false; return Response.Create(ResponseStatus.Success, OBDError); } /// - /// keep record if DLL has been loaded in + /// Keep record if DLL has been loaded /// public bool IsLoaded { @@ -363,13 +395,16 @@ public bool IsLoaded } /// - /// connect to selected protocol + /// Connect to selected protocol /// Must provide protocol, speed, connection flags, recommended optional is pins /// private Response ConnectToProtocol(ProtocolID ReqProtocol, BaudRate Speed, ConnectFlag ConnectFlags) { OBDError = J2534Port.Functions.PassThruConnect(DeviceID, ReqProtocol, ConnectFlags, Speed, ref ChannelID); - if (OBDError != J2534Err.STATUS_NOERROR) return Response.Create(ResponseStatus.Error, OBDError); + if (OBDError != J2534Err.STATUS_NOERROR) + { + return Response.Create(ResponseStatus.Error, OBDError); + } Protocol = ReqProtocol; IsProtocolOpen = true; return Response.Create(ResponseStatus.Success, OBDError); @@ -381,7 +416,10 @@ private Response ConnectToProtocol(ProtocolID ReqProtocol, BaudRate Sp private Response DisconnectFromProtocol() { OBDError = J2534Port.Functions.PassThruDisconnect((int)ChannelID); - if (OBDError != J2534Err.STATUS_NOERROR) return Response.Create(ResponseStatus.Error, OBDError); + if (OBDError != J2534Err.STATUS_NOERROR) + { + return Response.Create(ResponseStatus.Error, OBDError); + } IsProtocolOpen = false; return Response.Create(ResponseStatus.Success, OBDError); } @@ -429,7 +467,10 @@ private Response SetFilter(UInt32 Mask,UInt32 Pattern,UInt32 FlowContr Marshal.FreeHGlobal(MaskPtr); Marshal.FreeHGlobal(PatternPtr); Marshal.FreeHGlobal(FlowPtr); - if (OBDError != J2534Err.STATUS_NOERROR) return Response.Create(ResponseStatus.Error, OBDError); + if (OBDError != J2534Err.STATUS_NOERROR) + { + return Response.Create(ResponseStatus.Error, OBDError); + } Filters.Add((ulong)tempfilter); return Response.Create(ResponseStatus.Success, OBDError); } @@ -445,14 +486,15 @@ protected override Task SetVpwSpeedInternal(VpwSpeed newSpeed) if (newSpeed == VpwSpeed.Standard) { this.Logger.AddDebugMessage("J2534 setting VPW 1X"); - //Disconnect from current protocol + // Disconnect from current protocol DisconnectFromProtocol(); - //Connect at new speed + // Connect at new speed ConnectToProtocol(ProtocolID.J1850VPW, BaudRate.J1850VPW_10400, ConnectFlag.NONE); - //Set Filter - SetFilter(0xFEFFFF, 0x6CF060, 0, TxFlag.NONE, FilterType.PASS_FILTER); + // Set Filter + SetFilter(0xFEFFFF, J2534Device.MessageFilter, 0, TxFlag.NONE, FilterType.PASS_FILTER); + SetFilter(0xFEFFFF, J2534Device.MessageFilter2, 0, TxFlag.NONE, FilterType.PASS_FILTER); //if (m.Status != ResponseStatus.Success) //{ // this.Logger.AddDebugMessage("Failed to set filter, J2534 error code: 0x" + m.Value.ToString("X2")); @@ -464,14 +506,15 @@ protected override Task SetVpwSpeedInternal(VpwSpeed newSpeed) else { this.Logger.AddDebugMessage("J2534 setting VPW 4X"); - //Disconnect from current protocol + // Disconnect from current protocol DisconnectFromProtocol(); - //Connect at new speed + // Connect at new speed ConnectToProtocol(ProtocolID.J1850VPW, BaudRate.J1850VPW_41600, ConnectFlag.NONE); - //Set Filter - SetFilter(0xFEFFFF, 0x6CF060, 0, TxFlag.NONE, FilterType.PASS_FILTER); + // Set Filter + SetFilter(0xFEFFFF, J2534Device.MessageFilter, 0, TxFlag.NONE, FilterType.PASS_FILTER); + SetFilter(0xFEFFFF, J2534Device.MessageFilter2, 0, TxFlag.NONE, FilterType.PASS_FILTER); }