/// <summary> /// This method send data to be written to flash. sendWriteRequest must be called before this method. /// </summary> /// <param name="a_data">The data to be written.</param> /// <returns>KWPResult</returns> public KWPResult sendWriteDataRequest(byte[] a_data) { LogDataString("sendWriteDataRequest"); KWPReply reply = new KWPReply(); KWPResult result; //Send request //Mode = 0x36 //PID = no PID used by this request //Data = data to be flashed //Expected result = 0x76 result = sendRequest(new KWPRequest(0x36, a_data), out reply); if (reply.getMode() != 0x76) return KWPResult.NOK; else return result; }
/// <summary> /// This method sets up the address and length for writing to flash. It must be called before /// the sendWriteDataRequest method is called. /// </summary> /// <param name="a_address">The addres to start writing to.</param> /// <param name="a_length">The length to write</param> /// <returns>KWPResult</returns> public KWPResult sendWriteRequest(uint a_address, uint a_length) { LogDataString("sendWriteRequest"); KWPReply reply = new KWPReply(); KWPResult result; byte[] addressAndLength = new byte[7]; //set address (byte 0 to 2) addressAndLength[0] = (byte)(a_address >> 16); addressAndLength[1] = (byte)(a_address >> 8); addressAndLength[2] = (byte)(a_address); //set length (byte 3 to 6); addressAndLength[3] = (byte)(a_length >> 24); addressAndLength[4] = (byte)(a_length >> 16); addressAndLength[5] = (byte)(a_length >> 8); addressAndLength[6] = (byte)(a_length); //Send request //Mode = 0x34 //PID = no PID used by this request //Data = aaallll (aaa = address, llll = length) //Expected result = 0x74 result = sendRequest(new KWPRequest(0x34, addressAndLength), out reply); if (result != KWPResult.OK) return result; if (reply.getMode() != 0x74) return KWPResult.NOK; else return result; }
/// <summary> /// Send unknown request /// </summary> /// <returns>KWPResult</returns> public KWPResult sendUnknownRequest() { LogDataString("sendUnknownRequest"); //Console.WriteLine("sendUnknownRequest"); KWPReply reply = new KWPReply(); KWPResult result; //Send request //Mode = 0x3E //PID = no PID used by this request //Expected result = 0x7E result = sendRequest(new KWPRequest(0x3E), out reply); if (reply.getMode() != 0x7E) return KWPResult.NOK; else return result; }
/// <summary> /// This method send a request to download the symbol map. /// After this request has been made data can be fetched with a data transfer request /// </summary> /// <param name="a_data">The data to be written.</param> /// <returns>KWPResult</returns> public KWPResult sendReadSymbolMapRequest() { LogDataString("sendReadSymbolMapRequest"); KWPReply reply = new KWPReply(); KWPResult result; //Send request //Mode = 0x31 //PID = 0x50 //Data = data to be flashed //Expected result = 0x71 result = sendRequest(new KWPRequest(0x31, 0x50), out reply); if (reply.getMode() != 0x71) return KWPResult.NOK; else return result; }
/// <summary> /// sendEraseRequest sends an erase request to the ECU. /// This method must be called before the ECU can be flashed. /// </summary> /// <returns>KWPResult</returns> public KWPResult sendEraseRequest() { LogDataString("sendEraseRequest"); KWPReply reply = new KWPReply(); KWPReply reply2 = new KWPReply(); KWPResult result = KWPResult.Timeout; int i = 0; //First erase message. Up to 5 retries. //Mode = 0x31 //PID = 0x52 //Expected result is 0x71 result = sendRequest(new KWPRequest(0x31, 0x52), out reply); Console.WriteLine("Erase(1) " + reply.ToString()); if (result != KWPResult.OK) return result; while (reply.getMode() != 0x71) { System.Threading.Thread.Sleep(1000); result = sendRequest(new KWPRequest(0x31, 0x52), out reply); Console.WriteLine("Erase(2:" + i.ToString() + ") " + reply.ToString()); if (i++ > 15) return KWPResult.Timeout; } if (result != KWPResult.OK) return result; //Second erase message. Up to 10 retries. //Mode = 0x31 //PID = 0x53 //Expected result is 0x71 i = 0; result = sendRequest(new KWPRequest(0x31, 0x53), out reply2); Console.WriteLine("Erase(3) " + reply2.ToString()); if (result != KWPResult.OK) return result; while (reply2.getMode() != 0x71) { System.Threading.Thread.Sleep(1000); result = sendRequest(new KWPRequest(0x31, 0x53), out reply2); Console.WriteLine("Erase(4:" + i.ToString() + ") " + reply2.ToString()); if (i++ > 20) return KWPResult.Timeout; } //Erase confirm message //Mode = 0x3E //Expected result is 0x7E result = sendRequest(new KWPRequest(0x3E, 0x53), out reply2); Console.WriteLine("Erase(5) " + reply2.ToString()); return result; }
/// <summary> /// This method requests data to be transmitted. /// </summary> /// <param name="a_data">The data to be transmitted.</param> /// <returns>KWPResult</returns> public KWPResult sendDataTransferRequest(out byte[] a_data) { LogDataString("sendDataTransferRequest"); KWPReply reply = new KWPReply(); KWPResult result; //Send request //Mode = 0x36 //PID = no PID used by this request //Data = no data //Expected result = 0x76 result = sendRequest(new KWPRequest(0x36), out reply); a_data = reply.getData(); if (reply.getMode() != 0x76) return KWPResult.NOK; else return result; }
/// <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; }