/// <summary> /// This method sends a KWP request and returns a KWPReply. The method returns /// when a reply has been received, after a failure or after a timeout. /// The open and startSession methods must be called and returned possitive result /// before this method is used. /// </summary> /// <param name="a_request">The KWPRequest.</param> /// <param name="r_reply">The reply to the KWPRequest.</param> /// <returns>RequestResult.</returns> public override RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply) { string sendString = ""; string receiveString = ""; byte[] reply = new byte[0xFF]; try { for (int i = 1; i < a_request.getData().Length; i++) { string tmpStr = a_request.getData()[i].ToString("X"); if (tmpStr.Length == 1) { sendString += "0" + tmpStr + " "; } else { sendString += tmpStr + " "; } } sendString += "\r"; m_serialPort.Write(sendString); //receiveString = "5A 90 59 53 33 45 46 35 39 45 32 33 33 30 32 30 38 32 37 \r\n\r\n";// m_serialPort.ReadTo(">"); receiveString = m_serialPort.ReadTo(">"); string tmpString = receiveString; int insertPos = 1; string subString = ""; while (receiveString.Length > 4) { int index = receiveString.IndexOf(" "); subString = receiveString.Substring(0, index); reply[insertPos] = (byte)Convert.ToInt16("0x" + subString, 16); insertPos++; receiveString = receiveString.Remove(0, index + 1); } insertPos--; reply[0] = (byte)insertPos; //Length r_reply = new KWPReply(reply, a_request.getNrOfPID()); return(RequestResult.NoError); } catch (Exception) { r_reply = new KWPReply(reply, a_request.getNrOfPID()); return(RequestResult.ErrorSending); } }
/// <summary> /// This method sends a KWP request and returns a KWPReply. The method returns /// when a reply has been received, after a failure or after a timeout. /// The open and startSession methods must be called and returned possitive result /// before this method is used. /// </summary> /// <param name="a_request">The KWPRequest.</param> /// <param name="r_reply">The reply to the KWPRequest.</param> /// <returns>RequestResult.</returns> public RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply) { string sendString = ""; string receiveString = ""; for (int i = 1; i < a_request.getData().Length; i++) { sendString += a_request.getData()[i].ToString("X") + " "; } sendString += "\r"; m_serialPort.Write(sendString); //receiveString = "49 01 01 00 00 00 31 \n\r49 02 02 44 34 47 50 \n\r49 02 03 30 30 52 35 \n\r49 02 04 25 42";// m_serialPort.ReadTo(">"); receiveString = m_serialPort.ReadTo(">"); char[] chrArray = receiveString.ToCharArray(); byte[] reply = new byte[0xFF]; int insertPos = 1; int index = 0; string subString = ""; while (receiveString.Length > 4) { //Remove first three bytes //TODO. Remove Mode and PIDs for (int i = 0; i < 3; i++) { index = receiveString.IndexOf(" "); receiveString = receiveString.Remove(0, index + 1); } //Read data for the rest of the row. for (int i = 0; i < 4; i++) { index = receiveString.IndexOf(" "); if (index == 0) //Last row not 4 bytes of data. { continue; } subString = receiveString.Substring(0, index); reply[insertPos] = (byte)Convert.ToInt16("0x" + subString, 16); insertPos++; receiveString = receiveString.Remove(0, index + 1); } } reply[0] = (byte)insertPos; //Length r_reply = new KWPReply(reply, a_request.getNrOfPID()); return(RequestResult.NoError); }
/// <summary> /// Send a request for a sequrity access with one out of two methods to /// calculate the key. /// </summary> /// <param name="a_method">Key calculation method [1,2]</param> /// <returns>true if sequrity access was granted, otherwise false</returns> private bool requestSequrityAccessLevel(uint a_method) { LogDataString("requestSequrityAccessLevel: " + a_method.ToString()); KWPReply reply = new KWPReply(); KWPResult result; byte[] seed = new byte[2]; byte[] key = new byte[2]; // Send a seed request. KWPRequest requestForKey = new KWPRequest(0x27, 0x05); Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() + " request for key: " + requestForKey.ToString()); result = sendRequest(requestForKey, out reply); Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() + " request for key result: " + reply.ToString()); if (result != KWPResult.OK) return false; if (reply.getData().Length < 2) return false; seed[0] = reply.getData()[0]; seed[1] = reply.getData()[1]; if (a_method == 1) key = calculateKey(seed, 0); else key = calculateKey(seed, 1); // Send key reply. KWPRequest sendKeyRequest = new KWPRequest(0x27, 0x06, key); Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() + " send Key request: " + sendKeyRequest.ToString()); result = sendRequest(sendKeyRequest, out reply); Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() + " send Key reply: " + reply.ToString()); if (result != KWPResult.OK) { Console.WriteLine("Security access request was not send"); return false; } //Check if sequrity was granted. Console.WriteLine("Mode: " + reply.getMode().ToString("X2")); Console.WriteLine("Data: " + reply.getData()[0].ToString("X2")); if ((reply.getMode() == 0x67) && (reply.getData()[0] == 0x34)) // WAS [0] { Console.WriteLine("Security access granted: " + a_method.ToString()); return true; } Console.WriteLine("Security access was not granted: " + reply.ToString()); return false; }
public bool ClearDTCCode(int dtccode) { LogDataString("ClearDTCCode: " + dtccode.ToString("X4")); KWPReply reply = new KWPReply(); KWPResult result; byte[] data = new byte[1]; data[0] = (byte)(dtccode & 0x00FF); //data[1] = (byte)0xFF; //data[2] = (byte)0x00; KWPRequest req = new KWPRequest(0x14, (byte)(dtccode >> 8), data); Console.WriteLine(req.ToString()); result = sendRequest(req, out reply); Console.WriteLine(reply.ToString()); return true; }
/// <summary> /// This method sends a KWP request and returns a KWPReply. The method returns /// when a reply has been received, after a failure or after a timeout. /// The open and startSession methods must be called and returned possitive result /// before this method is used. /// </summary> /// <param name="a_request">The KWPRequest.</param> /// <param name="r_reply">The reply to the KWPRequest.</param> /// <returns>RequestResult.</returns> public RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply) { string sendString = ""; string receiveString = ""; for (int i = 1; i < a_request.getData().Length; i++) sendString += a_request.getData()[i].ToString("X") + " "; sendString += "\r"; m_serialPort.Write(sendString); //receiveString = "49 01 01 00 00 00 31 \n\r49 02 02 44 34 47 50 \n\r49 02 03 30 30 52 35 \n\r49 02 04 25 42";// m_serialPort.ReadTo(">"); receiveString = m_serialPort.ReadTo(">"); char[] chrArray = receiveString.ToCharArray(); byte[] reply = new byte[0xFF]; int insertPos = 1; int index = 0; string subString = ""; while(receiveString.Length > 4) { //Remove first three bytes //TODO. Remove Mode and PIDs for (int i = 0; i < 3; i++) { index = receiveString.IndexOf(" "); receiveString = receiveString.Remove(0, index + 1); } //Read data for the rest of the row. for (int i = 0; i < 4; i++) { index = receiveString.IndexOf(" "); if (index == 0) //Last row not 4 bytes of data. { continue; } subString = receiveString.Substring(0, index); reply[insertPos] = (byte)Convert.ToInt16("0x"+subString, 16); insertPos++; receiveString = receiveString.Remove(0, index + 1); } } reply[0] = (byte)insertPos; //Length r_reply = new KWPReply(reply, a_request.getNrOfPID()); return RequestResult.NoError; }
/// <summary> /// This method writes to a symbol in RAM. /// The ECU must not be write protected for this to work. /// </summary> /// <param name="a_symbolNumber">Symbol number to write to.</param> /// <param name="a_data">Data to write.</param> /// <returns></returns> public bool writeSymbolRequestAddress(uint a_address, byte[] a_data) { LogDataString("writeSymbolRequest: " + a_address.ToString("X8") + "len: " + a_data.Length.ToString("X4")); KWPReply reply = new KWPReply(); KWPResult result; byte[] symbolNumberAndData = new byte[4 + a_data.Length]; //symbolNumberAndData[0] = (byte)(a_address >> 24); symbolNumberAndData[0] = (byte)(a_address >> 16); symbolNumberAndData[1] = (byte)(a_address >> 8); symbolNumberAndData[2] = (byte)(a_address); symbolNumberAndData[3] = (byte)(a_data.Length); // len len // adr adr adr for (int i = 0; i < a_data.Length; i++) symbolNumberAndData[i + 4] = a_data[i]; string requestString = "RequestString: "; foreach (byte b in symbolNumberAndData) { requestString += b.ToString("X2") + " "; } Console.WriteLine(requestString); // end dump to console Console.WriteLine("SymbolNumberAndData length: " + symbolNumberAndData.Length.ToString("X8")); KWPRequest t_request = new KWPRequest(0x3D, /*0x81, */symbolNumberAndData); Console.WriteLine(t_request.ToString()); result = sendRequest(t_request, out reply); if (result != KWPResult.OK) { Console.WriteLine("Result != KWPResult.OK"); return false; } Console.WriteLine("Result = " + reply.getData()[0].ToString("X2")); Console.WriteLine("Result-total = " + reply.ToString()); if (reply.getData()[0] == 0x7D) { return true; } else { return false; } }
public KWPResult sendEraseMemorySpaceRequest(Int32 StartAddress, Int32 Length) { /*02 FLASH memory erasure 1 start address (high byte) 2 start address (middle byte) 3 start address (low byte) 4 stop address (high byte) 5 stop address (middle byte) 6 stop address (low byte) */ Int32 StopAddress = StartAddress + Length; LogDataString("sendEraseRequest"); KWPReply reply = new KWPReply(); KWPReply reply2 = new KWPReply(); KWPResult result = KWPResult.Timeout; //First erase message. Up to 5 retries. //Mode = 0x31 //PID = 0x51 //Expected result is 0x71 byte[] a_data = new byte[6]; int bt = 0; //a_data[0] = (byte)(StartAddress >> 24); a_data[bt++] = (byte)(StartAddress >> 16); a_data[bt++] = (byte)(StartAddress >> 8); a_data[bt++] = (byte)(StartAddress); //a_data[4] = (byte)(Length >> 24); a_data[bt++] = (byte)(StopAddress >> 16); a_data[bt++] = (byte)(StopAddress >> 8); a_data[bt++] = (byte)(StopAddress); requestSequrityAccess(true); KWPRequest req = new KWPRequest(0x31, 0x50, a_data); result = sendRequest(req, out reply); Console.WriteLine("Erase(1) " + reply.ToString()); /*if (result != KWPResult.OK) return result; System.Threading.Thread.Sleep(10000); result = sendRequest(new KWPRequest(0x31, 0x53, a_data), out reply); Console.WriteLine("Erase(2:" + i.ToString() + ") " + reply.ToString()); */ if (result != KWPResult.OK) return result; result = sendRequest(new KWPRequest(0x3E, 0x50), out reply2); // tester present??? Console.WriteLine("reply on exit " + reply2.ToString()); return result; }
public bool ReadFreezeFrameData(uint frameNumber) { LogDataString("ReadFreezeFrameData"); KWPReply reply = new KWPReply(); KWPResult result; byte[] data = new byte[1]; data[0] = (byte)0x00; //data[1] = (byte)0x00; //data[2] = (byte)0x00; KWPRequest req = new KWPRequest(0x12, Convert.ToByte(frameNumber), data); Console.WriteLine(req.ToString()); result = sendRequest(req, out reply); Console.WriteLine(reply.ToString()); return true; }
/// <summary> /// This method sends a KWPRequest and returns a KWPReply. /// </summary> /// <param name="a_request">The request.</param> /// <param name="a_reply">The reply.</param> /// <returns>KWPResult</returns> private KWPResult sendRequest(KWPRequest a_request, out KWPReply a_reply, int expectedLength) { int _maxSendRetries = 3; KWPResult _kwpResult = KWPResult.Timeout; LogDataString("sendRequest"); KWPReply reply = new KWPReply(); RequestResult result; a_reply = new KWPReply(); //<GS-11012010> was allemaal 1000 int keepAliveTimeout = 1000; //Console.WriteLine("Checking KWP device open"); if (!m_kwpDevice.isOpen()) return KWPResult.DeviceNotConnected; // reset the timer for keep alive (set to 1 seconds now) if (stateTimer == null) stateTimer = new System.Threading.Timer(sendKeepAlive, new Object(), keepAliveTimeout, keepAliveTimeout); stateTimer.Change(keepAliveTimeout, keepAliveTimeout); m_requestMutex.WaitOne(); int _retryCount = 0; result = RequestResult.Unknown; // <GS-11022010> while (_retryCount < _maxSendRetries && result != RequestResult.NoError) { LogDataString(a_request.ToString()); result = m_kwpDevice.sendRequest(a_request, out reply); if ((int)reply.getLength() != expectedLength) { result = RequestResult.InvalidLength; } if (result == RequestResult.NoError) { a_reply = reply; LogDataString(reply.ToString()); LogDataString(""); // empty line m_requestMutex.ReleaseMutex(); //return KWPResult.OK; _kwpResult = KWPResult.OK; } else { LogDataString("Timeout in KWPHandler::sendRequest"); m_requestMutex.ReleaseMutex(); //return KWPResult.Timeout; _kwpResult = KWPResult.Timeout; } } return _kwpResult; }
/// <summary> /// Send a KWP request. /// </summary> /// <param name="a_request">A KWP request.</param> /// <param name="r_reply">A KWP reply.</param> /// <returns>The status of the request.</returns> public override RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply) { uint row; uint all_rows = row = nrOfRowsToSend(a_request.getData()); m_kwpCanListener.setupWaitMessage(0x258); // Send one or several request messages. for (; row > 0; row--) { CANMessage msg = new CANMessage(0x240, 0, 8); msg.elmExpectedResponses = a_request.ElmExpectedResponses; msg.setData(createCanMessage(a_request.getData(), row - 1)); if ((msg.getData() & 0xFFFFUL) == 0xA141UL) msg.elmExpectedResponses = 0; if (all_rows == 22) { msg.elmExpectedResponses = row == 1 ? 1 : 0; // on last message (expect 1 reply) } if (!m_canDevice.sendMessage(msg)) { r_reply = new KWPReply(); return RequestResult.ErrorSending; } } var response = m_kwpCanListener.waitMessage(getTimeout()); // Receive one or several replys and send an ack for each reply. if (response.getID() == 0x258) { uint nrOfRows = (uint)(response.getCanData(0) & 0x3F) + 1; row = 0; if (nrOfRows == 0) throw new Exception("Wrong nr of rows"); //Assume that no KWP reply contains more than 0x200 bytes byte[] reply = new byte[0x200]; reply = collectReply(reply, response.getData(), row); sendAck(nrOfRows - 1); nrOfRows--; m_kwpCanListener.setupWaitMessage(0x258); while (nrOfRows > 0) { response = m_kwpCanListener.waitMessage(getTimeout()); if (response.getID() == 0x258) { row++; reply = collectReply(reply, response.getData(), row); sendAck(nrOfRows - 1); nrOfRows--; } else { logger.Debug("1response.getID == " + response.getID()); r_reply = new KWPReply(); return RequestResult.Timeout; } } r_reply = new KWPReply(reply, a_request.getNrOfPID()); return RequestResult.NoError; } else { logger.Debug("2response.getID == " + response.getID()); r_reply = new KWPReply(); return RequestResult.Timeout; } }
/// <summary> /// This method send a request to receive data from flash. The sendReadRequest /// method must be called before this. /// </summary> /// <param name="r_data">The requested data.</param> /// <returns></returns> public bool sendRequestDataByOffset(out byte[] r_data) { logger.Trace("sendRequestDataByOffset"); KWPReply reply = new KWPReply(); KWPResult result; var request = new KWPRequest(0x21, 0xF0); request.ElmExpectedResponses=1; result = sendRequest(request, out reply); if (result == KWPResult.OK) { r_data = reply.getData(); return true; } else { r_data = new byte[0]; return false; } }
/// <summary> /// This method send a request for reading from ECU memory (both RAM and flash). /// It sets up start address and the length to read. /// </summary> /// <param name="a_address">The address to start reading from.</param> /// <param name="a_length">The total length to read.</param> /// <returns>true on success, otherwise false</returns> public bool sendReadRequest(uint a_address, uint a_length) { logger.Trace("sendReadRequest"); KWPReply reply = new KWPReply(); KWPResult result; byte[] lengthAndAddress = new byte[5]; //set length (byte 0 and 1) lengthAndAddress[0] = (byte)(a_length >> 8); lengthAndAddress[1] = (byte)(a_length); //set address (byte 2 to 4); lengthAndAddress[2] = (byte)(a_address >> 16); lengthAndAddress[3] = (byte)(a_address >> 8); lengthAndAddress[4] = (byte)(a_address); var request = new KWPRequest(0x2C, 0xF0, 0x03, lengthAndAddress); request.ElmExpectedResponses = 1; result = sendRequest(request, out reply); if (result == KWPResult.OK) return true; else return false; }
/// <summary> /// This method send a request for reading from ECU memory (both RAM and flash). /// It sets up start address and the length to read. The resulting response contains the requested values. /// </summary> /// <param name="a_address">The address to start reading from.</param> /// <param name="a_length">The total length to read.</param> /// <returns>true on success, otherwise false</returns> public bool sendReadRequest(uint a_address, uint a_length, out byte[] data) { logger.Debug("sendReadRequest"); KWPReply reply = new KWPReply(); KWPResult result; data = new byte[a_length]; byte[] lengthAndAddress = new byte[6]; //set address and length (byte 0) lengthAndAddress[0] = (byte)(a_address >> 16); lengthAndAddress[1] = (byte)(a_address >> 8); lengthAndAddress[2] = (byte)(a_address); lengthAndAddress[3] = (byte)(a_length); lengthAndAddress[4] = 0x01; lengthAndAddress[5] = 0; KWPRequest request = new KWPRequest(0x23, lengthAndAddress); request.ElmExpectedResponses = 1; result = sendRequest(request, out reply); data = reply.getData(); if (result == KWPResult.OK) return true; else return false; }
/// <summary> /// This method sends a KWPRequest and returns a KWPReply. /// </summary> /// <param name="a_request">The request.</param> /// <param name="a_reply">The reply.</param> /// <returns>KWPResult</returns> private KWPResult sendRequest(KWPRequest a_request, out KWPReply a_reply, int expectedLength) { int _maxSendRetries = 3; KWPResult _kwpResult = KWPResult.Timeout; logger.Trace("sendRequest"); KWPReply reply = new KWPReply(); RequestResult result; a_reply = new KWPReply(); //Console.WriteLine("Checking KWP device open"); if (!m_kwpDevice.isOpen()) return KWPResult.DeviceNotConnected; // reset the timer for keep alive (set to 1 seconds now) if (stateTimer != null) { stateTimer.Change(keepAliveTimeout, keepAliveTimeout); } m_requestMutex.WaitOne(); int _retryCount = 0; result = RequestResult.Unknown; // <GS-11022010> while (_retryCount < _maxSendRetries && result != RequestResult.NoError) { logger.Trace(a_request.ToString()); result = m_kwpDevice.sendRequest(a_request, out reply); if ((int)reply.getLength() != expectedLength) { result = RequestResult.InvalidLength; } if (result == RequestResult.NoError) { a_reply = reply; logger.Trace(reply.ToString()); logger.Trace(""); // empty line m_requestMutex.ReleaseMutex(); //return KWPResult.OK; _kwpResult = KWPResult.OK; } else { logger.Trace("Error in KWPHandler::sendRequest" + result.ToString() + " " + reply.ToString()); m_requestMutex.ReleaseMutex(); //return KWPResult.Timeout; _kwpResult = KWPResult.Timeout; } } return _kwpResult; }
/// <summary> /// This method sends a KWPRequest and returns a KWPReply. /// </summary> /// <param name="a_request">The request.</param> /// <param name="a_reply">The reply.</param> /// <returns>KWPResult</returns> private KWPResult sendRequest(KWPRequest a_request, out KWPReply a_reply) { logger.Trace("sendRequest"); KWPReply reply = new KWPReply(); RequestResult result; a_reply = new KWPReply(); //Console.WriteLine("Checking KWP device open"); if (!m_kwpDevice.isOpen()) return KWPResult.DeviceNotConnected; // reset the timer for keep alive (set to 1 seconds now) if (stateTimer != null) { stateTimer.Change(keepAliveTimeout, keepAliveTimeout); } m_requestMutex.WaitOne(); logger.Trace(a_request.ToString()); for (int retry = 0; retry < 3; retry++) { result = m_kwpDevice.sendRequest(a_request, out reply); a_reply = reply; if (result == RequestResult.NoError) { logger.Trace(reply.ToString()); logger.Trace(""); // empty line m_requestMutex.ReleaseMutex(); return KWPResult.OK; } else { logger.Trace("Error in KWPHandler::sendRequest: " + result.ToString() + " " + retry.ToString()); Console.WriteLine("Error in KWPHandler::sendRequest: " + result.ToString() + " " + retry.ToString()); } } m_requestMutex.ReleaseMutex(); return KWPResult.Timeout; }
/// <summary> /// This method sends a KWPRequest and returns a KWPReply. /// </summary> /// <param name="a_request">The request.</param> /// <param name="a_reply">The reply.</param> /// <returns>KWPResult</returns> private KWPResult sendRequest(KWPRequest a_request, out KWPReply a_reply) { LogDataString("sendRequest"); KWPReply reply = new KWPReply(); RequestResult result; a_reply = new KWPReply(); //<GS-11012010> was allemaal 1000 int keepAliveTimeout = 1000; //Console.WriteLine("Checking KWP device open"); if (!m_kwpDevice.isOpen()) return KWPResult.DeviceNotConnected; // reset the timer for keep alive (set to 1 seconds now) if (stateTimer == null) stateTimer = new System.Threading.Timer(sendKeepAlive, new Object(), keepAliveTimeout, keepAliveTimeout); stateTimer.Change(keepAliveTimeout, keepAliveTimeout); m_requestMutex.WaitOne(); LogDataString(a_request.ToString()); result = m_kwpDevice.sendRequest(a_request, out reply); a_reply = reply; if (result == RequestResult.NoError) { LogDataString(reply.ToString()); LogDataString(""); // empty line m_requestMutex.ReleaseMutex(); return KWPResult.OK; } else { LogDataString("Timeout in KWPHandler::sendRequest: " + result.ToString()); Console.WriteLine("Timeout in KWPHandler::sendRequest: " + result.ToString()); m_requestMutex.ReleaseMutex(); return KWPResult.Timeout; } }
public bool ClearDTCCodes() { LogDataString("ClearDTCCodes"); KWPReply reply = new KWPReply(); KWPResult result; byte[] data = new byte[1]; data[0] = (byte)0xFF; //data[1] = (byte)0xFF; //data[2] = (byte)0x00; KWPRequest req = new KWPRequest(0x14, 0xFF, data); Console.WriteLine(req.ToString()); result = sendRequest(req, out reply); Console.WriteLine(reply.ToString()); return true; }
/// <summary> /// This method sends a KWP request and returns a KWPReply. The method returns /// when a reply has been received, after a failure or after a timeout. /// The open and startSession methods must be called and returned possitive result /// before this method is used. /// </summary> /// <param name="a_request">The KWPRequest.</param> /// <param name="r_reply">The reply to the KWPRequest.</param> /// <returns>RequestResult.</returns> public abstract RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply);
public bool ReadDTCCodes(out List<string> list) { list = new List<string>(); LogDataString("ReadDTCCodes"); KWPReply reply = new KWPReply(); KWPResult result; byte[] data = new byte[2]; data[0] = (byte)0xFF; data[1] = (byte)0xFF; //data[2] = (byte)0x00; // Status byte // 7 Warning lamp illuminated for this code // 6 Warning lamp pending for this code, not illuminate but malfunction was detected // 5 Warning lamp was previously illuminated for this code, malfunction not currently detected, code not yet erased // 4 Stored trouble code // 3 Manufacturer specific status // 2 Manufacturer specific status // 1 Current code - present at time of request // 0 Maturing/intermittent code - insufficient data to consider as a malfunction KWPRequest req = new KWPRequest(0x18 , 0x02); // Request Diagnostic Trouble Codes by Status Console.WriteLine(req.ToString()); result = sendRequest(req, out reply); Console.WriteLine(reply.ToString()); // J2190 // Multiple Mode $58 response messages may be reported to a single request, depending on the number of diagnostic // trouble codes stored in the module. Each response message will report up to three DTCs for // which at least one of the requested status bits is set. If no codes are stored in the module that meet the // requested status, then the module will respond with the following: // Reply: 58,00 if (reply.getMode() == 0x58) { if (reply.getPid() == 0x00) { Console.WriteLine("No DTC's"); list.Add("No DTC's"); return true; } else { //P0605 //P1231 //P1230 //P1530 //P1606 //P1460 //+ reply {Reply: 14,58, // 06, // 06,05,E4, // 12,31,48, // 12,30,E8, // 15,30,E1, // 16,06,E8, // 14,60,41} TrionicCANLib.KWP.KWPReply uint number = reply.getPid(); byte[] dtc = new byte[number*2]; byte[] read = reply.getData(); int j = 0; int i = 0; while(i < read.Length) { dtc[j++] = read[i++]; dtc[j++] = read[i++]; i++; } for (int n = 0; n < dtc.Length; n = n + 2) { list.Add("DTC: P" + dtc[n].ToString("X2") + dtc[n+1].ToString("X2")); } } } return false; }
/// <summary> /// This method sends a KWP request and returns a KWPReply. The method returns /// when a reply has been received, after a failure or after a timeout. /// The open and startSession methods must be called and returned possitive result /// before this method is used. /// </summary> /// <param name="a_request">The KWPRequest.</param> /// <param name="r_reply">The reply to the KWPRequest.</param> /// <returns>RequestResult.</returns> public override RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply) { string sendString = ""; string receiveString = ""; byte[] reply = new byte[0xFF]; try { for (int i = 1; i < a_request.getData().Length; i++) { string tmpStr = a_request.getData()[i].ToString("X"); if (tmpStr.Length == 1) sendString += "0" + tmpStr + " "; else sendString += tmpStr + " "; } sendString += "\r"; m_serialPort.Write(sendString); //receiveString = "5A 90 59 53 33 45 46 35 39 45 32 33 33 30 32 30 38 32 37 \r\n\r\n";// m_serialPort.ReadTo(">"); receiveString = m_serialPort.ReadTo(">"); string tmpString = receiveString; int insertPos = 1; string subString = ""; while (receiveString.Length > 4) { int index = receiveString.IndexOf(" "); subString = receiveString.Substring(0, index); reply[insertPos] = (byte)Convert.ToInt16("0x" + subString, 16); insertPos++; receiveString = receiveString.Remove(0, index + 1); } insertPos--; reply[0] = (byte)insertPos; //Length r_reply = new KWPReply(reply, a_request.getNrOfPID()); return RequestResult.NoError; } catch (Exception) { r_reply = new KWPReply(reply, a_request.getNrOfPID()); return RequestResult.ErrorSending; } }
public bool ResetECU() { LogDataString("ResetECU"); KWPReply reply = new KWPReply(); KWPResult result; byte[] data = new byte[1]; data[0] = (byte)0x00; KWPRequest req = new KWPRequest(0x11, 0x01, data); Console.WriteLine(req.ToString()); result = sendRequest(req, out reply); if (reply.getMode() == 0x51) { Console.WriteLine("Reset Success: " + reply.ToString()); return true; } else if (reply.getMode() == 0x7F) { Console.WriteLine("Reset Failed: " + reply.ToString()); } return false; }
/// <summary> /// This method writes to a symbol in RAM. /// The ECU must not be write protected for this to work. /// </summary> /// <param name="a_symbolNumber">Symbol number to write to.</param> /// <param name="a_data">Data to write.</param> /// <returns></returns> public bool writeSymbolRequest(uint a_symbolNumber, byte[] a_data) { LogDataString("writeSymbolRequest: " + a_symbolNumber.ToString()); KWPReply reply = new KWPReply(); KWPResult result; int LengthToTx = a_data.Length; if (LengthToTx > 0x41) LengthToTx = 0x41; // FA byte[] symbolNumberAndData = new byte[3 + /*a_data.Length*/ LengthToTx]; //First two bytes should be the symbol number symbolNumberAndData[0] = (byte)(a_symbolNumber >> 8); symbolNumberAndData[1] = (byte)(a_symbolNumber); symbolNumberAndData[2] = (byte)(0); // len len // adr adr adr for (int i = 0; i < /*a_data.Length*/ LengthToTx; i++) symbolNumberAndData[i + 3] = a_data[i]; string requestString = "RequestString: "; foreach (byte b in symbolNumberAndData) { requestString += b.ToString("X2") + " "; } Console.WriteLine(requestString); // end dump to console Console.WriteLine("SymbolNumberAndData length: " + symbolNumberAndData.Length.ToString("X8")); KWPRequest t_request = new KWPRequest(0x3D, 0x80, symbolNumberAndData); Console.WriteLine(t_request.ToString()); result = sendRequest(t_request, out reply); if (result != KWPResult.OK) { Console.WriteLine("Result != KWPResult.OK"); return false; } Console.WriteLine("Result = " + reply.getData()[0].ToString("X2")); Console.WriteLine("Resulttotal = " + reply.ToString()); if (reply.getData()[0] == 0x7D) { return true; } else { return false; } }
/// <summary> /// Send a KWP request. /// </summary> /// <param name="a_request">A KWP request.</param> /// <param name="r_reply">A KWP reply.</param> /// <returns>The status of the request.</returns> public override RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply) { uint row; uint all_rows = row = nrOfRowsToSend(a_request.getData()); m_kwpCanListener.setupWaitMessage(0x258); // Send one or several request messages. for (; row > 0; row--) { CANMessage msg = new CANMessage(0x240, 0, 8); msg.elmExpectedResponses = a_request.ElmExpectedResponses; msg.setData(createCanMessage(a_request.getData(), row - 1)); if ((msg.getData() & 0xFFFFUL) == 0xA141UL) { msg.elmExpectedResponses = 0; } if (all_rows == 22) { msg.elmExpectedResponses = row == 1 ? 1 : 0; // on last message (expect 1 reply) } if (!m_canDevice.sendMessage(msg)) { r_reply = new KWPReply(); return(RequestResult.ErrorSending); } } var response = m_kwpCanListener.waitMessage(getTimeout()); // Receive one or several replys and send an ack for each reply. if (response.getID() == 0x258) { uint nrOfRows = (uint)(response.getCanData(0) & 0x3F) + 1; row = 0; if (nrOfRows == 0) { throw new Exception("Wrong nr of rows"); } //Assume that no KWP reply contains more than 0x200 bytes byte[] reply = new byte[0x200]; reply = collectReply(reply, response.getData(), row); sendAck(nrOfRows - 1); nrOfRows--; m_kwpCanListener.setupWaitMessage(0x258); while (nrOfRows > 0) { response = m_kwpCanListener.waitMessage(getTimeout()); if (response.getID() == 0x258) { row++; reply = collectReply(reply, response.getData(), row); sendAck(nrOfRows - 1); nrOfRows--; } else { logger.Debug("1response.getID == " + response.getID()); r_reply = new KWPReply(); return(RequestResult.Timeout); } } r_reply = new KWPReply(reply, a_request.getNrOfPID()); return(RequestResult.NoError); } else { logger.Debug("2response.getID == " + response.getID()); r_reply = new KWPReply(); return(RequestResult.Timeout); } }
/// <summary> /// Send a KWP request. /// </summary> /// <param name="a_request">A KWP request.</param> /// <param name="r_reply">A KWP reply.</param> /// <returns>The status of the request.</returns> public RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply) { CANMessage msg = new CANMessage(0x240, 0, 8); uint row = nrOfRowsToSend(a_request.getData()); m_kwpCanListener.setupWaitMessage(0x258); // Send one or several request messages. for (; row > 0; row--) { msg.setData(createCanMessage(a_request.getData(), row - 1)); if (!m_canDevice.sendMessage(msg)) { r_reply = new KWPReply(); return(RequestResult.ErrorSending); } } msg = m_kwpCanListener.waitMessage(timeoutPeriod); // msg = m_kwpCanListener.waitForMessage(0x258, timeoutPeriod); // Receive one or several replys and send an ack for each reply. if (msg.getID() == 0x258) { uint nrOfRows = (uint)(msg.getCanData(0) & 0x3F) + 1; row = 0; if (nrOfRows == 0) { throw new Exception("Wrong nr of rows"); } //Assume that no KWP reply contains more than 0x200 bytes byte[] reply = new byte[0x200]; reply = collectReply(reply, msg.getData(), row); sendAck(nrOfRows - 1); nrOfRows--; m_kwpCanListener.setupWaitMessage(0x258); while (nrOfRows > 0) { // msg = m_kwpCanListener.waitForMessage(0x258, timeoutPeriod); msg = m_kwpCanListener.waitMessage(timeoutPeriod); if (msg.getID() == 0x258) { row++; reply = collectReply(reply, msg.getData(), row); sendAck(nrOfRows - 1); nrOfRows--; } else { r_reply = new KWPReply(); return(RequestResult.Timeout); } } r_reply = new KWPReply(reply, a_request.getNrOfPID()); return(RequestResult.NoError); } else { r_reply = new KWPReply(); return(RequestResult.Timeout); } }
/// <summary> /// Send a KWP request. /// </summary> /// <param name="a_request">A KWP request.</param> /// <param name="r_reply">A KWP reply.</param> /// <returns>The status of the request.</returns> public RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply) { CANMessage msg = new CANMessage(0x240, 0, 8); uint row = nrOfRowsToSend(a_request.getData()); m_kwpCanListener.setupWaitMessage(0x258); // Send one or several request messages. for (; row > 0; row--) { msg.setData(createCanMessage(a_request.getData(), row - 1)); if (!m_canDevice.sendMessage(msg)) { r_reply = new KWPReply(); return RequestResult.ErrorSending; } } msg = m_kwpCanListener.waitMessage(timeoutPeriod); // msg = m_kwpCanListener.waitForMessage(0x258, timeoutPeriod); // Receive one or several replys and send an ack for each reply. if (msg.getID() == 0x258) { uint nrOfRows = (uint)(msg.getCanData(0) & 0x3F)+ 1; row = 0; if (nrOfRows == 0) throw new Exception("Wrong nr of rows"); //Assume that no KWP reply contains more than 0x200 bytes byte[] reply = new byte[0x200]; reply = collectReply(reply, msg.getData(), row); sendAck(nrOfRows - 1); nrOfRows--; m_kwpCanListener.setupWaitMessage(0x258); while (nrOfRows > 0) { // msg = m_kwpCanListener.waitForMessage(0x258, timeoutPeriod); msg = m_kwpCanListener.waitMessage(timeoutPeriod); if (msg.getID() == 0x258) { row++; reply = collectReply(reply, msg.getData(), row); sendAck(nrOfRows - 1); nrOfRows--; } else { r_reply = new KWPReply(); return RequestResult.Timeout; } } r_reply = new KWPReply(reply, a_request.getNrOfPID()); return RequestResult.NoError; } else { r_reply = new KWPReply(); return RequestResult.Timeout; } }