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)) { CastInfoEvent("Couldn't send message", ActivityType.ConvertingFile); return false; } CANMessage response = new CANMessage(); response = m_canListener.waitMessage(timeoutP2ct); //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)) { CastInfoEvent("Couldn't send message", ActivityType.ConvertingFile); return false; } response = new CANMessage(); response = m_canListener.waitMessage(timeoutP2ct); // 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(1) == 0x7F && response.getCanData(2) == 0x27) { CastInfoEvent("Error: " + TranslateErrorCode(response.getCanData(3)), ActivityType.ConvertingFile); } } } 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) { CastInfoEvent("Error: " + TranslateErrorCode(response.getCanData(3)), ActivityType.ConvertingFile); } return false; }
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; }