private int GetProgrammingStateNormal() { Console.WriteLine("Get programming state"); CANMessage msg = new CANMessage(0x7E0, 0, 2);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x000000000000A201; // 0x02 0x10 0x02 msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); Console.WriteLine("Get programming state response: " + data.ToString("X16")); //\__ 00 00 03 11 02 e2 01 00 00 00 00 00 Magic reply, T8 replies with 0311 and programming state 01(recovery state?) if (getCanData(data, 1) != 0xE2 || getCanData(data, 0) != 0x02) { return 0; } return Convert.ToInt32(getCanData(data, 2)); }
/// <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(0x7E0, 0, 8); uint row = nrOfRowsToSend(a_request.getData()); m_kwpCanListener.setupWaitMessage(0x7E8); // 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(0x7E8, timeoutPeriod); // Receive one or several replys and send an ack for each reply. if (msg.getID() == 0x7E8) { 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(0x7E8); while (nrOfRows > 0) { // msg = m_kwpCanListener.waitForMessage(0x7E8, timeoutPeriod); msg = m_kwpCanListener.waitMessage(timeoutPeriod); if (msg.getID() == 0x7E8) { 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 an acknowledgement message. /// </summary> /// <param name="a_rowNr">The row number that should be acknowledged.</param> private void sendAck(uint a_rowNr) { CANMessage msg = new CANMessage(0x266,0,8); uint i = 0; ulong data = 0; data = setCanData(data, (byte)0x40, i++); // ? data = setCanData(data, (byte)0xA1, i++); data = setCanData(data, (byte)0x3F, i++); data = setCanData(data, (byte)(0x80 | (int)(a_rowNr)), i++); msg.setData(data); if (!m_canDevice.sendMessage(msg)) throw new Exception("Error sending ack"); }
//--------------------------------------------------------------------------------------------- /** Waits for arrival of a specific CAN message or any message if ID = 0. @param a_canID message ID @param timeout timeout, ms @param canMsg message @return message ID */ public override uint waitForMessage(uint a_canID, uint timeout, out CANMessage canMsg) { canMsg = new CANMessage(); Debug.Assert(canMsg != null); canMsg.setID(0); caCombiAdapter.caCANFrame frame = new caCombiAdapter.caCANFrame(); if (this.combi.CAN_GetMessage(ref frame, timeout) && (frame.id == a_canID || a_canID == 0)) { // message received canMsg.setID(frame.id); canMsg.setLength(frame.length); canMsg.setData(frame.data); return frame.id; } // timed out return 0; }
/// <summary> /// waitForMessage waits for a specific CAN message give by a CAN id. /// </summary> /// <param name="a_canID">The CAN id to listen for</param> /// <param name="timeout">Listen timeout</param> /// <param name="r_canMsg">The CAN message with a_canID that we where listening for.</param> /// <returns>The CAN id for the message we where listening for, otherwise 0.</returns> public override uint waitForMessage(uint a_canID, uint timeout, out CANMessage canMsg) { /* int readResult = 0; int nrOfWait = 0; while (nrOfWait < timeout) { LAWICEL.CANMsg r_canMsg = new LAWICEL.CANMsg(); canMsg = new CANMessage(); readResult = LAWICEL.canusb_Read(m_deviceHandle, out r_canMsg); if (readResult == LAWICEL.ERROR_CANUSB_OK) { //Console.WriteLine("rx id: 0x" + r_canMsg.id.ToString("X4")); if (r_canMsg.id != a_canID) { nrOfWait++; continue; } else { canMsg.setID(r_canMsg.id); canMsg.setData(r_canMsg.data); canMsg.setFlags(r_canMsg.flags); return (uint)r_canMsg.id; } } else if (readResult == LAWICEL.ERROR_CANUSB_NO_MESSAGE) { Thread.Sleep(1); nrOfWait++; } } canMsg = new CANMessage(); return 0;*/ LAWICEL.CANMsg r_canMsg; canMsg = new CANMessage(); int readResult = 0; int nrOfWait = 0; while (nrOfWait < timeout) { r_canMsg = new LAWICEL.CANMsg(); readResult = LAWICEL.canusb_Read(m_deviceHandle, out r_canMsg); if (readResult == LAWICEL.ERROR_CANUSB_OK) { Thread.Sleep(1); AddToCanTrace("rx: 0x" + r_canMsg.id.ToString("X4") + r_canMsg.data.ToString("X16")); if (r_canMsg.id == 0x00) { nrOfWait++; } else if (r_canMsg.id != a_canID) continue; canMsg.setData(r_canMsg.data); canMsg.setID(r_canMsg.id); canMsg.setLength(r_canMsg.len); return (uint)r_canMsg.id; } else if (readResult == LAWICEL.ERROR_CANUSB_NO_MESSAGE) { Thread.Sleep(1); nrOfWait++; } } r_canMsg = new LAWICEL.CANMsg(); return 0; }
private bool StartBootloader011() { CANMessage msg = new CANMessage(0x11, 0, 7); //<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x0060241000803606; msg.setData(cmd); m_canListener.setupWaitMessage(0x311); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); if (getCanData(data, 0) != 0x01 || getCanData(data, 1) != 0x76) { return false; } return true; }
private bool UploadBootloaderProg011() { int startAddress = 0x102400; Bootloader btloaderdata = new Bootloader(); int txpnt = 0; byte iFrameNumber = 0x21; if (requestDownload011()) { for (int i = 0; i < 0x46; i++) { iFrameNumber = 0x21; //10 F0 36 00 00 10 24 00 //Console.WriteLine("Sending bootloader: " + startAddress.ToString("X8")); // cast event float percentage = ((float)i * 100) / 70F; CastProgressWriteEvent(percentage); if (SendTransferData011(0xF0, startAddress, 0x311)) { // send 0x22 (34) frames with data from bootloader CANMessage msg = new CANMessage(0x11, 0, 8); for (int j = 0; j < 0x22; j++) { ulong cmd = 0x0000000000000000; // 0x34 = upload data to ECU msg.setData(cmd); msg.setCanData(iFrameNumber, 0); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 1); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 2); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 3); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 4); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 5); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 6); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 7); iFrameNumber++; if (iFrameNumber > 0x2F) iFrameNumber = 0x20; if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } Thread.Sleep(2); } // send the remaining data m_canListener.setupWaitMessage(0x311); // now wait for 01 76 00 00 00 00 00 00 CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); if (getCanData(data, 0) != 0x01 || getCanData(data, 1) != 0x76) { return false; } BroadcastKeepAlive(); startAddress += 0xEA; } else { Console.WriteLine("Did not receive correct response from SendTransferData"); } } iFrameNumber = 0x21; if (SendTransferData011(0x0A, startAddress, 0x311)) { // send 0x22 (34) frames with data from bootloader CANMessage msg = new CANMessage(0x11, 0, 8); ulong cmd = 0x0000000000000000; // 0x34 = upload data to ECU msg.setData(cmd); msg.setCanData(iFrameNumber, 0); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 1); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 2); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 3); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 4); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 5); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 6); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 7); iFrameNumber++; if (iFrameNumber > 0x2F) iFrameNumber = 0x20; if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } Thread.Sleep(2); // send the remaining data m_canListener.setupWaitMessage(0x311); // now wait for 01 76 00 00 00 00 00 00 CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); if (getCanData(data, 0) != 0x01 || getCanData(data, 1) != 0x76) { return false; } BroadcastKeepAlive(); startAddress += 0x06; } else { Console.WriteLine("Did not receive correct response from SendTransferData"); } CastProgressWriteEvent(100); } return true; }
private bool SendA503011() { // expect no response CANMessage msg = new CANMessage(0x11, 0, 3);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x000000000003A502; msg.setData(cmd); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } return true; }
private void SendCommandNoResponse(uint destID, ulong data) { CANMessage msg = new CANMessage(destID, 0, 8); ulong cmd = data; msg.setData(cmd); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } }
private bool RequestSecurityAccess011(int millisecondsToWaitWithResponse) { int secondsToWait = millisecondsToWaitWithResponse / 1000; ulong cmd = 0x0000000000FD2702; // request security access if (_securityLevel == AccessLevel.AccessLevel01) { cmd = 0x0000000000012702; // request security access } else if (_securityLevel == AccessLevel.AccessLevelFB) { cmd = 0x0000000000FB2702; // request security access } CANMessage msg = new CANMessage(0x11, 0, 3); //<GS-18052011> ELM327 support requires the length byte msg.setData(cmd); m_canListener.setupWaitMessage(0x311); CastInfoEvent("Requesting security access", ActivityType.ConvertingFile); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = m_canListener.waitMessage(1000); //ulong data = response.getData(); Console.WriteLine("---" + response.getData().ToString("X16")); if (response.getCanData(1) == 0x67) { if (response.getCanData(2) == 0xFD || response.getCanData(2) == 0xFB || response.getCanData(2) == 0x01) { CastInfoEvent("Got seed value from ECU", ActivityType.ConvertingFile); while (secondsToWait > 0) { CastInfoEvent("Waiting for " + secondsToWait.ToString() + " seconds...", ActivityType.UploadingBootloader); Thread.Sleep(1000); SendKeepAlive(); secondsToWait--; } byte[] seed = new byte[2]; seed[0] = response.getCanData(3); seed[1] = response.getCanData(4); if (seed[0] == 0x00 && seed[1] == 0x00) { return true; // security access was already granted } else { SeedToKey s2k = new SeedToKey(); byte[] key = s2k.calculateKey(seed, _securityLevel); CastInfoEvent("Security access : Key (" + key[0].ToString("X2") + key[1].ToString("X2") + ") calculated from seed (" + seed[0].ToString("X2") + seed[1].ToString("X2") + ")", ActivityType.ConvertingFile); ulong keydata = 0x0000000000FE2704; if (_securityLevel == AccessLevel.AccessLevel01) { keydata = 0x0000000000022704; } else if (_securityLevel == AccessLevel.AccessLevelFB) { keydata = 0x0000000000FC2704; } ulong key1 = key[1]; key1 *= 0x100000000; keydata ^= key1; ulong key2 = key[0]; key2 *= 0x1000000; keydata ^= key2; msg = new CANMessage(0x11, 0, 5);//<GS-18052011> ELM327 support requires the length byte msg.setData(keydata); m_canListener.setupWaitMessage(0x311); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } response = new CANMessage(); response = m_canListener.waitMessage(1000); // is it ok or not if (response.getCanData(1) == 0x67 && (response.getCanData(2) == 0xFE || response.getCanData(2) == 0xFC || response.getCanData(2) == 0x02)) { CastInfoEvent("Security access granted", ActivityType.ConvertingFile); return true; } } } else if (response.getCanData(2) == 0xFE || response.getCanData(2) == 0x02) { CastInfoEvent("Security access granted", ActivityType.ConvertingFile); return true; } } else if (response.getCanData(1) == 0x7F && response.getCanData(2) == 0x27) { Console.WriteLine("Casting error"); string info = TranslateErrorCode(response.getCanData(3)); Console.WriteLine("Casting error: " + info); CastInfoEvent("Error: " + info, ActivityType.ConvertingFile); } return false; }
private bool RequestSecurityAccessCIM(int millisecondsToWaitWithResponse) { int secondsToWait = millisecondsToWaitWithResponse / 1000; ulong cmd = 0x0000000000012702; // request security access CANMessage msg = new CANMessage(0x245, 0, 8); msg.setData(cmd); m_canListener.setupWaitMessage(0x645); CastInfoEvent("Requesting security access to CIM", ActivityType.ConvertingFile); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = m_canListener.waitMessage(1000); //ulong data = response.getData(); Console.WriteLine("---" + response.getData().ToString("X16")); if (response.getCanData(1) == 0x67) { if (response.getCanData(2) == 0x01) { CastInfoEvent("Got seed value from CIM", ActivityType.ConvertingFile); while (secondsToWait > 0) { CastInfoEvent("Waiting for " + secondsToWait.ToString() + " seconds...", ActivityType.UploadingBootloader); Thread.Sleep(1000); SendKeepAlive(); secondsToWait--; } byte[] seed = new byte[2]; seed[0] = response.getCanData(3); seed[1] = response.getCanData(4); if (seed[0] == 0x00 && seed[1] == 0x00) { return true; // security access was already granted } else { SeedToKey s2k = new SeedToKey(); byte[] key = s2k.calculateKeyForCIM(seed); CastInfoEvent("Security access CIM : Key (" + key[0].ToString("X2") + key[1].ToString("X2") + ") calculated from seed (" + seed[0].ToString("X2") + seed[1].ToString("X2") + ")", ActivityType.ConvertingFile); ulong keydata = 0x0000000000022704; ulong key1 = key[1]; key1 *= 0x100000000; keydata ^= key1; ulong key2 = key[0]; key2 *= 0x1000000; keydata ^= key2; msg = new CANMessage(0x245, 0, 8); msg.setData(keydata); m_canListener.setupWaitMessage(0x645); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } response = new CANMessage(); response = m_canListener.waitMessage(1000); // is it ok or not if (response.getCanData(1) == 0x67 && response.getCanData(2) == 0x02) { CastInfoEvent("Security access to CIM granted", ActivityType.ConvertingFile); return true; } } } else if (response.getCanData(2) == 0x02) { CastInfoEvent("Security access to CIM granted", ActivityType.ConvertingFile); return true; } } else if (response.getCanData(1) == 0x7F && response.getCanData(2) == 0x27) { Console.WriteLine("Casting error"); string info = TranslateErrorCode(response.getCanData(3)); Console.WriteLine("Casting error: " + info); CastInfoEvent("Error: " + info, ActivityType.ConvertingFile); } return false; }
private bool requestDownload011() { CANMessage msg = new CANMessage(0x11, 0, 7); //<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x0000000000003406; msg.setData(cmd); m_canListener.setupWaitMessage(0x311); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(2000); ulong data = response.getData(); //CastInfoEvent("rx requestDownload: " + data.ToString("X16"), ActivityType.UploadingBootloader); if (getCanData(data, 0) != 0x01 || getCanData(data, 1) != 0x74) { return false; } return true; }
private bool readDataByPacketID(byte command, uint responseID) { //SendCommandNoResponse(0x7E0, 0x000000006201AA03); CANMessage msg = new CANMessage(0x7E0, 0, 3);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x000000000001AA03; ulong lcommand = command; cmd |= (lcommand * 0x1000000); msg.setData(cmd); m_canListener.setupWaitMessage(responseID); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage ECMresponse = new CANMessage(); ECMresponse = m_canListener.waitMessage(1000); return true; }
private bool MarryCIMAndECU() { //0000000000633B02 CANMessage msg = new CANMessage(0x245, 0, 8); ulong cmd = 0x0000000000633B02; msg.setData(cmd); m_canListener.setupWaitMessage(0x645); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } int waitMsgCount = 0; while (waitMsgCount < 10) { CANMessage ECMresponse = new CANMessage(); ECMresponse = m_canListener.waitMessage(1000); ulong rxdata = ECMresponse.getData(); // response might be 00000000783B7F03 for some time // final result should be 0000000000637B02 if (getCanData(rxdata, 1) == 0x7B && getCanData(rxdata, 2) == 0x63) { return true; } else if (getCanData(rxdata, 1) == 0x7F && getCanData(rxdata, 2) == 0x3B && getCanData(rxdata, 3) == 0x78) { CastInfoEvent("Waiting for marry process to complete between CIM and car", ActivityType.ConvertingFile); } waitMsgCount++; } return false; }
private bool SendSecretCodetoCIM() { //0044585349603B06 CANMessage msg = new CANMessage(0x245, 0, 8); ulong cmd = 0x0044585349603B06; msg.setData(cmd); m_canListener.setupWaitMessage(0x645); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage ECMresponse = new CANMessage(); ECMresponse = m_canListener.waitMessage(1000); ulong rxdata = ECMresponse.getData(); if(getCanData(rxdata, 1) == 0x7B && getCanData(rxdata, 2) == 0x60) { return true; } return false; }
private void SendDeviceControlMessage(byte command) { CANMessage msg = new CANMessage(0x7E0, 0, 3);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x000000000000AE02; ulong lcommand = command; cmd |= (lcommand * 0x10000); msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage ECMresponse = new CANMessage(); ECMresponse = m_canListener.waitMessage(1000); }
private bool SendTransferData011(int length, int address, uint waitforResponseID) { CANMessage msg = new CANMessage(0x11, 0, 8); // <GS-24052011> test for ELM327, set length to 16 (0x10) ulong cmd = 0x0000000000360010; // 0x36 = transferData ulong addressHigh = (uint)address & 0x0000000000FF0000; addressHigh /= 0x10000; ulong addressMiddle = (uint)address & 0x000000000000FF00; addressMiddle /= 0x100; ulong addressLow = (uint)address & 0x00000000000000FF; ulong len = (ulong)length; cmd |= (addressLow * 0x100000000000000); cmd |= (addressMiddle * 0x1000000000000); cmd |= (addressHigh * 0x10000000000); cmd |= (len * 0x100); //Console.WriteLine("send: " + cmd.ToString("X16")); msg.setData(cmd); m_canListener.setupWaitMessage(waitforResponseID); if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); //Console.WriteLine("Received in SendTransferData: " + data.ToString("X16")); if (getCanData(data, 0) != 0x30 || getCanData(data, 1) != 0x00) { return false; } return true; }
private void SendDeviceControlMessageWithCode(byte command, string secretcode /*ulong code*/) { CANMessage msg = new CANMessage(0x7E0, 0, 7);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x000000000000AE07; ulong lcommand = command; cmd |= (lcommand * 0x10000); ulong code = 0; //0x4D4E415100000000 code |= Convert.ToByte(secretcode[3]); code = code << 8; code |= Convert.ToByte(secretcode[2]); code = code << 8; code |= Convert.ToByte(secretcode[1]); code = code << 8; code |= Convert.ToByte(secretcode[0]); code = code << 4 * 8; cmd |= code; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage ECMresponse = new CANMessage(); ECMresponse = m_canListener.waitMessage(1000); }
private bool StartSession20() { CANMessage msg = new CANMessage(0x7E0, 0, 2);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x0000000000002001; // 0x02 0x10 0x02 msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); if (getCanData(data, 0) != 0x01 || getCanData(data, 1) != 0x60) { return false; } return true; }
private void SendKeepAlive() { CANMessage msg = new CANMessage(0x7E0, 0, 2);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x0000000000003E01; // always 2 bytes msg.setData(cmd); //Console.WriteLine("KA sent"); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); //Console.WriteLine("received KA: " + response.getCanData(1).ToString("X2")); }
public void InitializeSession() { CANMessage response = new CANMessage(); //101 8 FE 01 3E 00 00 00 00 00 CANMessage msg = new CANMessage(0x11, 0, 2); ulong cmd = 0x0000000000003E01; msg.setData(cmd); if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } /* // first send ulong data = 0; CANMessage msg = new CANMessage(0x7E0, 0, 8); ulong cmd = 0x0000000000005001; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!m_canDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); Console.WriteLine("Received1: " + data.ToString("X8")); cmd = 0x0000000000006801; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!m_canDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); Console.WriteLine("Received2: " + data.ToString("X8")); response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); Console.WriteLine("Received3: " + data.ToString("X8")); cmd = 0x000000000000E501; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!m_canDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); Console.WriteLine("Received4: " + data.ToString("X8"));*/ }
private void SendMessage(uint id, ulong data) { if(canUsbDevice is CANELM327Device) return; CANMessage msg = new CANMessage(); msg.setID(id); msg.setLength(8); msg.setData(data); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Failed to send message"); } }
/// <summary> /// readMessages is the "run" method of this class. It reads all incomming messages /// and publishes them to registered ICANListeners. /// </summary> public void readMessages() { int readResult = 0; LAWICEL.CANMsg r_canMsg = new LAWICEL.CANMsg(); CANMessage canMessage = new CANMessage(); Console.WriteLine("readMessages started"); while (true) { lock (m_synchObject) { if (m_endThread) { Console.WriteLine("readMessages ended"); return; } } readResult = LAWICEL.canusb_Read(m_deviceHandle, out r_canMsg); if (readResult == LAWICEL.ERROR_CANUSB_OK) { // Console.WriteLine(r_canMsg.id.ToString("X3") + " " + r_canMsg.data.ToString("X8")); if (MessageContainsInformationForRealtime(r_canMsg.id)) { canMessage.setID(r_canMsg.id); canMessage.setLength(r_canMsg.len); canMessage.setTimeStamp(r_canMsg.timestamp); canMessage.setFlags(r_canMsg.flags); canMessage.setData(r_canMsg.data); lock (m_listeners) { AddToCanTrace("RX: " + r_canMsg.id.ToString("X4") + " " + r_canMsg.data.ToString("X16")); foreach (ICANListener listener in m_listeners) { //while (listener.messagePending()) ; // dirty, make this better listener.handleMessage(canMessage); } //CastInformationEvent(canMessage); // <GS-05042011> re-activated this function } //Thread.Sleep(1); } // cast event to application to process message //if (MessageContainsInformationForRealtime(r_canMsg.id)) //{ //TODO: process all other known msg id's into the realtime view // CastInformationEvent(canMessage); // <GS-05042011> re-activated this function //} } else if (readResult == LAWICEL.ERROR_CANUSB_NO_MESSAGE) { Thread.Sleep(1); } } }
private byte[] sendReadDataByLocalIdentifier(int address, int length, out bool success) { // we send: 0040000000002106 // .. send: 06 21 80 00 00 00 00 00 success = false; byte[] retData = new byte[length]; if (!canUsbDevice.isOpen()) return retData; CANMessage msg = new CANMessage(0x7E0, 0, 7);//<GS-18052011> ELM327 support requires the length byte //Console.WriteLine("Reading " + address.ToString("X8") + " len: " + length.ToString("X2")); ulong cmd = 0x0000000000002106; // always 2 bytes ulong addressHigh = (uint)address & 0x0000000000FF0000; addressHigh /= 0x10000; ulong addressMiddle = (uint)address & 0x000000000000FF00; addressMiddle /= 0x100; ulong addressLow = (uint)address & 0x00000000000000FF; ulong len = (ulong)length; cmd |= (addressLow * 0x1000000000000); cmd |= (addressMiddle * 0x10000000000); cmd |= (addressHigh * 0x100000000); cmd |= (len * 0x10000); // << 2 * 8 //Console.WriteLine("send: " + cmd.ToString("X16")); /*cmd |= (ulong)(byte)(address & 0x000000FF) << 4 * 8; cmd |= (ulong)(byte)((address & 0x0000FF00) >> 8) << 3 * 8; cmd |= (ulong)(byte)((address & 0x00FF0000) >> 2 * 8) << 2 * 8; cmd |= (ulong)(byte)((address & 0xFF000000) >> 3 * 8) << 8;*/ msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } // wait for max two messages to get rid of the alive ack message CANMessage response = new CANMessage(); ulong data = 0; response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); if (getCanData(data, 0) == 0x7E) { AddToCanTrace("Got 0x7E message as response to 0x21, ReadDataByLocalIdentifier command"); success = false; return retData; } else if (response.getData() == 0x00000000) { AddToCanTrace("Get blank response message to 0x21, ReadDataByLocalIdentifier"); success = false; return retData; } else if (getCanData(data, 0) == 0x03 && getCanData(data, 1) == 0x7F && getCanData(data, 2) == 0x23) { // reason was 0x31 AddToCanTrace("No security access granted"); RequestSecurityAccess(0); success = false; return retData; } else if (getCanData(data, 2) != 0x61 && getCanData(data, 1) != 0x61) { if (data == 0x0000000000007E01) { // was a response to a KA. } AddToCanTrace("Incorrect response to 0x23, sendReadDataByLocalIdentifier. Byte 2 was " + getCanData(data, 2).ToString("X2")); success = false; return retData; } //TODO: Check whether we need more than 2 bytes of data and wait for that many records after sending an ACK int rx_cnt = 0; byte frameIndex = 0x21; if (length > 4) { retData[rx_cnt++] = getCanData(data, 4); retData[rx_cnt++] = getCanData(data, 5); retData[rx_cnt++] = getCanData(data, 6); retData[rx_cnt++] = getCanData(data, 7); // in that case, we need more records from the ECU // Thread.Sleep(1); SendMessage(0x7E0, 0x0000000000000030); // send ack to request more bytes //Thread.Sleep(1); // now we wait for the correct number of records to be received int m_nrFrameToReceive = ((length - 4) / 7); if ((len - 4) % 7 > 0) m_nrFrameToReceive++; //AddToCanTrace("Number of frames: " + m_nrFrameToReceive.ToString()); while (m_nrFrameToReceive > 0) { // response = new CANMessage(); //response.setData(0); //response.setID(0); // m_canListener.setupWaitMessage(0x7E8); response = m_canListener.waitMessage(1000); data = response.getData(); //AddToCanTrace("frame " + frameIndex.ToString("X2") + ": " + data.ToString("X16")); if (frameIndex != getCanData(data, 0)) { // sequence broken AddToCanTrace("Received invalid sequenced frame " + frameIndex.ToString("X2") + ": " + data.ToString("X16")); m_canListener.dumpQueue(); success = false; return retData; } else if (data == 0x0000000000000000) { AddToCanTrace("Received blank message while waiting for data"); success = false; return retData; } frameIndex++; if (frameIndex > 0x2F) frameIndex = 0x20; // additional check for sequencing of frames m_nrFrameToReceive--; //AddToCanTrace("frames left: " + m_nrFrameToReceive.ToString()); // add the bytes to the receive buffer //string checkLine = string.Empty; for (uint fi = 1; fi < 8; fi++) { //checkLine += getCanData(data, fi).ToString("X2"); if (rx_cnt < retData.Length) // prevent overrun { retData[rx_cnt++] = getCanData(data, fi); } } //AddToCanTrace("frame(2): " + checkLine); //Thread.Sleep(1); } } else { if (retData.Length > rx_cnt) retData[rx_cnt++] = getCanData(data, 4); if (retData.Length > rx_cnt) retData[rx_cnt++] = getCanData(data, 5); if (retData.Length > rx_cnt) retData[rx_cnt++] = getCanData(data, 6); if (retData.Length > rx_cnt) retData[rx_cnt++] = getCanData(data, 7); //AddToCanTrace("received data: " + retData[0].ToString("X2")); } /*string line = address.ToString("X8") + " "; foreach (byte b in retData) { line += b.ToString("X2") + " "; } AddToCanTrace(line);*/ success = true; return retData; }
/// <summary> /// Send a message that starts a session. This is used to test if there is /// a connection. /// </summary> /// <returns></returns> private bool sendSessionRequest() { Console.WriteLine("Sending session request"); // 0x220 is for T7 // 0x7E0 is for T8 CANMessage msg1 = new CANMessage(0x7E0, 0, 8); LAWICEL.CANMsg msg = new LAWICEL.CANMsg(); msg1.setData(0x000040021100813f); if (!sendMessage(msg1)) { Console.WriteLine("Unable to send session request"); return false; } if (waitForMessage(0x7E8, 1000, out msg) == 0x7E8) { Console.WriteLine("Message 0x7E8 seen"); //Ok, there seems to be a ECU somewhere out there. //Now, sleep for 10 seconds to get a session timeout. This is needed for //applications on higher level. Otherwise there will be no reply when the //higher level application tries to start a session. Thread.Sleep(10000); Console.WriteLine("sendSessionRequest: TRUE"); return true; } Console.WriteLine("sendSessionRequest: FALSE"); return false; }
private bool SendrequestDownload(bool recoveryMode) { CANMessage msg = new CANMessage(0x7E0, 0, 7);//<GS-18052011> ELM327 support requires the length byte //06 34 01 00 00 00 00 00 ulong cmd = 0x0000000000013406; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } bool eraseDone = false; int eraseCount = 0; int waitCount = 0; while (!eraseDone) { m_canListener.setupWaitMessage(0x7E8); // TEST ELM327 31082011 CANMessage response = new CANMessage(); response = m_canListener.waitMessage(500); // 1 seconds! ulong data = response.getData(); if (data == 0) { m_canListener.setupWaitMessage(0x311); // TEST ELM327 31082011 response = new CANMessage(); response = m_canListener.waitMessage(500); // 1 seconds! data = response.getData(); } // response will be 03 7F 34 78 00 00 00 00 a couple of times while erasing if (getCanData(data, 0) == 0x03 && getCanData(data, 1) == 0x7F && getCanData(data, 2) == 0x34 && getCanData(data, 3) == 0x78 ) { if (recoveryMode) BroadcastKeepAlive(); else SendKeepAlive(); eraseCount ++; string info = "Erasing flash"; for(int i = 0; i < eraseCount; i ++) info += "."; CastInfoEvent(info, ActivityType.ErasingFlash); } else if (getCanData(data, 0) == 0x01 && getCanData(data, 1) == 0x74) { if (recoveryMode) BroadcastKeepAlive(); else SendKeepAlive(); eraseDone = true; return true; } else if (getCanData(data, 0) == 0x03 && getCanData(data, 1) == 0x7F && getCanData(data, 2) == 0x34 && getCanData(data, 3) == 0x11) { CastInfoEvent("Erase cannot be performed", ActivityType.ErasingFlash); return false; } else { Console.WriteLine("Rx: " + data.ToString("X16")); if (!recoveryMode && canUsbDevice is CANELM327Device) SendKeepAlive(); } waitCount++; if (waitCount > 30) { CastInfoEvent("Erase timed out after 30 seconds", ActivityType.ErasingFlash); // ELM327 seem to be unable to wait long enough for this response // Instead we assume its finnished ok after 30 seconds if (canUsbDevice is CANELM327Device) { return true; } else { return false; } } Thread.Sleep(2); } return true; }
/// <summary> /// Start a KWP session. /// </summary> /// <remarks> /// A KWP session must be started before any requests can be sent. /// </remarks> /// <returns>True if the session was started, otherwise false.</returns> public bool startSession() { CANMessage msg = new CANMessage(0x7E0, 0, 8); msg.setData(0x000040021100813F); // what is this stuff??? msg.setData(0x0000000000008102); // startCommunication AddToCanTrace("Sending 0x0000000000008102 message"); m_kwpCanListener.setupWaitMessage(0x7E8); if (!m_canDevice.sendMessage(msg)) { AddToCanTrace("Unable to send 0x0000000000008102 message"); return false; } Console.WriteLine("Init msg sent"); if (m_kwpCanListener.waitMessage(timeoutPeriod).getID() == 0x7E8) { AddToCanTrace("Successfully sent 0x0000000000008102 message and received reply 0x7E8"); return true; } else { AddToCanTrace("Didn't receive 0x7E8 message as reply on 0x0000000000008102 message"); return false; } }
private bool SendSecretCode2() { //44585349006EAE07 CANMessage msg = new CANMessage(0x7E0, 0, 8); ulong cmd = 0x44585349006EAE07; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage ECMresponse = new CANMessage(); ECMresponse = m_canListener.waitMessage(1000); ulong rxdata = ECMresponse.getData(); if (getCanData(rxdata, 1) == 0xEE && getCanData(rxdata, 2) == 0x6E) { return true; } return false; }
public void readMessages() { CANMessage canMessage = new CANMessage(); byte[] receiveBuffer = new byte[1024]; // circular buffer for reception of data string receiveString = string.Empty; Console.WriteLine("readMessages started"); while (true) { lock (m_synchObject) { if (m_endThread) { Console.WriteLine("readMessages ended"); return; } } if (m_serialPort != null) { if (m_serialPort.IsOpen) { if (m_serialPort.BytesToRead > 0) { string rxString = m_serialPort.ReadExisting(); if (rxString.Length > 0) AddToSerialTrace("SERRX: " + rxString); receiveString += rxString; //Console.WriteLine("BUF1: " + receiveString); receiveString = receiveString.Replace(">", ""); // remove prompt characters... we don't need that stuff receiveString = receiveString.Replace("NO DATA", ""); // remove prompt characters... we don't need that stuff while (receiveString.StartsWith("\n") || receiveString.StartsWith("\r")) { receiveString = receiveString.Substring(1, receiveString.Length - 1); } while (receiveString.Contains('\r')) { // process the line int idx = receiveString.IndexOf('\r'); string rxMessage = receiveString.Substring(0, idx); receiveString = receiveString.Substring(idx + 1, receiveString.Length - idx - 1); while (receiveString.StartsWith("\n") || receiveString.StartsWith("\r")) { receiveString = receiveString.Substring(1, receiveString.Length - 1); } //Console.WriteLine("BUF2: " + receiveString); // is it a valid line if (rxMessage.Length >= 6) { try { uint id = Convert.ToUInt32(rxMessage.Substring(0, 3), 16); if (MessageContainsInformationForRealtime(id)) { canMessage.setID(id); canMessage.setLength(8); // TODO: alter to match data canMessage.setData(0x0000000000000000); // reset message content byte b1 = Convert.ToByte(rxMessage.Substring(4, 2), 16); if (b1 < 7) { canMessage.setCanData(b1, 0); //Console.WriteLine("Byte 1: " + Convert.ToByte(rxMessage.Substring(4, 2), 16).ToString("X2")); if (b1 >= 1) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(7, 2), 16), 1); if (b1 >= 2) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(10, 2), 16), 2); if (b1 >= 3) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(13, 2), 16), 3); if (b1 >= 4) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(16, 2), 16), 4); if (b1 >= 5) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(19, 2), 16), 5); if (b1 >= 6) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(22, 2), 16), 6); if (b1 >= 7) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(25, 2), 16), 7); } else { canMessage.setCanData(b1, 0); //Console.WriteLine("Byte 1: " + Convert.ToByte(rxMessage.Substring(4, 2), 16).ToString("X2")); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(7, 2), 16), 1); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(10, 2), 16), 2); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(13, 2), 16), 3); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(16, 2), 16), 4); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(19, 2), 16), 5); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(22, 2), 16), 6); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(25, 2), 16), 7); } lock (m_listeners) { AddToCanTrace("RX: " + canMessage.getData().ToString("X16")); //Console.WriteLine("MSG: " + rxMessage); foreach (ICANListener listener in m_listeners) { listener.handleMessage(canMessage); } } } } catch (Exception) { Console.WriteLine("MSG: " + rxMessage); } } } } else { Thread.Sleep(1); // give others some air } } } } // parse the receive string /*int readResult = 0; LAWICEL.CANMsg r_canMsg = new LAWICEL.CANMsg(); CANMessage canMessage = new CANMessage(); Console.WriteLine("readMessages started"); while (true) { lock (m_synchObject) { if (m_endThread) { Console.WriteLine("readMessages ended"); return; } } readResult = LAWICEL.canusb_Read(m_deviceHandle, out r_canMsg); if (readResult == LAWICEL.ERROR_CANUSB_OK) { //Console.WriteLine(r_canMsg.id.ToString("X3") + " " + r_canMsg.data.ToString("X8")); if (MessageContainsInformationForRealtime(r_canMsg.id)) { canMessage.setID(r_canMsg.id); canMessage.setLength(r_canMsg.len); canMessage.setTimeStamp(r_canMsg.timestamp); canMessage.setFlags(r_canMsg.flags); canMessage.setData(r_canMsg.data); lock (m_listeners) { AddToCanTrace("RX: " + r_canMsg.data.ToString("X16")); foreach (ICANListener listener in m_listeners) { //while (listener.messagePending()) ; // dirty, make this better listener.handleMessage(canMessage); } //CastInformationEvent(canMessage); // <GS-05042011> re-activated this function } //Thread.Sleep(1); } // cast event to application to process message //if (MessageContainsInformationForRealtime(r_canMsg.id)) //{ //TODO: process all other known msg id's into the realtime view // CastInformationEvent(canMessage); // <GS-05042011> re-activated this function //} } else if (readResult == LAWICEL.ERROR_CANUSB_NO_MESSAGE) { Thread.Sleep(1); } } */ }
public float GetE85Percentage() { float retval = 0; GetDiagnosticDataIdentifier(); CastInfoEvent("Request 0xAA", ActivityType.ConvertingFile); CANMessage msg = new CANMessage(0x7E0, 0, 3);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x000000007A01AA03;// <dpid=7A> <level=sendOneResponse> <service=AA> <length> msg.setData(cmd); m_canListener.setupWaitMessage(0x5E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = m_canListener.waitMessage(1000); // 7A 00 52 04 00 16 DC 00 // <dpid><6 datavalues> if (response.getCanData(0) == 0x7A) { retval = Convert.ToInt32(response.getCanData(2)); } // Negative Response 0x7F Service <nrsi> <service> <returncode> // Bug: this is never handled because its sent with id=0x7E8 else if (response.getCanData(1) == 0x7F && response.getCanData(2) == 0xAA) { string info = TranslateErrorCode(response.getCanData(3)); CastInfoEvent("Error: " + info, ActivityType.ConvertingFile); } return retval; }