protected bool ReadCachedTransmission(byte[] request, out byte[] response, out EdiabasNet.ErrorCodes errorCode) { response = null; errorCode = EdiabasNet.ErrorCodes.EDIABAS_IFH_0009; if (!EnableTransmitCache) { return(false); } if (request.Length > 0) { StoreWriteTransaction(); ReadTransaction = null; ReadTransactionPos = 0; TransmitCacheDict.TryGetValue(BitConverter.ToString(request), out ReadTransaction); } if (ReadTransaction == null) { return(false); } if (request.Length > 0) { Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, request, 0, request.Length, "Send Cache"); } if ((ReadTransaction.Request.Length > 0) && ((ReadTransaction.Request[0] & 0xC0) == 0xC0)) { // functional address if (ReadTransaction.ErrorCode == EdiabasNet.ErrorCodes.EDIABAS_ERR_NONE) { // transmission not completed Ediabas.LogString(EdiabasNet.EdLogLevel.Ifh, "Incomplete cached response"); return(false); } } if (ReadTransaction.ResponseList.Count > ReadTransactionPos) { response = ReadTransaction.ResponseList[ReadTransactionPos++]; errorCode = EdiabasNet.ErrorCodes.EDIABAS_ERR_NONE; Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, response, 0, response.Length, "Resp Cache"); } else { if (ReadTransaction.ErrorCode != EdiabasNet.ErrorCodes.EDIABAS_ERR_NONE) { errorCode = ReadTransaction.ErrorCode; } } return(true); }
public bool UpdateAdapterInfo(bool forceUpdate = false) { if (!forceUpdate && AdapterType >= 0) { // only read once return(true); } if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo: {0}", forceUpdate); } IgnitionStatus = -1; AdapterType = -1; AdapterSerial = null; AdapterVoltage = -1; try { for (int telType = 0; telType < 5; telType++) { int respLen = 0; byte[] testTel = null; switch (telType) { case 0: // read ignition respLen = 6; testTel = new byte[] { 0x82, 0xF1, 0xF1, 0xFE, 0xFE, 0x00 }; break; case 1: // escape mode respLen = 8; testTel = new byte[] { 0x84, 0xF1, 0xF1, 0x06, (byte)((EscapeMode ? 0x03 : 0x00) ^ EscapeXor), EscapeCodeDefault ^ EscapeXor, EscapeMaskDefault ^ EscapeXor, 0x00 }; break; case 2: // read firmware version respLen = 9; testTel = new byte [] { 0x82, 0xF1, 0xF1, 0xFD, 0xFD, 0x00 }; break; case 3: if (AdapterType < 0x0002) { // no id support break; } respLen = 13; testTel = new byte[] { 0x82, 0xF1, 0xF1, 0xFB, 0xFB, 0x00 }; break; case 4: if (AdapterType < 0x0002) { // no voltage support break; } respLen = 6; testTel = new byte[] { 0x82, 0xF1, 0xF1, 0xFC, 0xFC, 0x00 }; break; } if (testTel == null) { break; } testTel[testTel.Length - 1] = CalcChecksumBmwFast(testTel, 0, testTel.Length - 1); if (Ediabas != null) { Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, testTel, 0, testTel.Length, "AdSend"); } _discardInBufferFunc(); _sendDataFunc(testTel, testTel.Length); LastCommTick = Stopwatch.GetTimestamp(); List <byte> responseList = new List <byte>(); long startTime = Stopwatch.GetTimestamp(); for (; ;) { List <byte> newList = _readInBufferFunc(); if (newList.Count > 0) { responseList.AddRange(newList); startTime = Stopwatch.GetTimestamp(); } if (responseList.Count >= testTel.Length + respLen) { if (Ediabas != null) { Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, responseList.ToArray(), 0, responseList.Count, "AdResp"); } bool validEcho = !testTel.Where((t, i) => responseList[i] != t).Any(); if (!validEcho) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo Type={0}: Echo invalid", telType); } return(false); } if (CalcChecksumBmwFast(responseList.ToArray(), testTel.Length, respLen - 1) != responseList[testTel.Length + respLen - 1]) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo Type={0}: Checksum invalid", telType); } return(false); } switch (telType) { case 0: IgnitionStatus = responseList[testTel.Length + 4]; break; case 1: EscapeMode = (responseList[testTel.Length + 4] ^ EscapeXor) == 0x03; break; case 2: AdapterType = responseList[testTel.Length + 5] + (responseList[testTel.Length + 4] << 8); AdapterVersion = responseList[testTel.Length + 7] + (responseList[testTel.Length + 6] << 8); break; case 3: AdapterSerial = responseList.GetRange(testTel.Length + 4, 8).ToArray(); break; case 4: AdapterVoltage = responseList[testTel.Length + 4]; break; } break; } if (Stopwatch.GetTimestamp() - startTime > _readTimeoutOffsetLong * TickResolMs) { if (Ediabas != null) { Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, responseList.ToArray(), 0, responseList.Count, "AdResp"); Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo Type={0}: Response timeout", telType); } bool failure = true; if (responseList.Count >= testTel.Length) { bool validEcho = !testTel.Where((t, i) => responseList[i] != t).Any(); if (validEcho) { switch (telType) { case 0: AdapterType = 0; break; case 1: EscapeMode = false; failure = false; break; } } } if (failure) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo Type={0}: Response failure", telType); } return(false); } break; } } } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", EdiabasNet.GetExceptionText(ex)); ReconnectRequired = true; return(false); } if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "IgnitionStatus: {0:X02}", IgnitionStatus); Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "EscapeMode: {0}", EscapeMode); Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterType: {0}", AdapterType); Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterVersion: {0}.{1}", AdapterVersion >> 8, AdapterVersion & 0xFF); if (AdapterSerial != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterSerial: {0}", BitConverter.ToString(AdapterSerial).Replace("-", "")); } if (AdapterVoltage >= 0) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterVoltage: {0,4:0.0}", AdapterVoltage * AdapterVoltageScale); } } return(true); }
public bool UpdateAdapterInfo(bool forceUpdate = false) { if (!forceUpdate && AdapterType >= 0) { // only read once return(true); } AdapterType = -1; AdapterSerial = null; AdapterVoltage = -1; try { for (int telType = 0; telType < 3; telType++) { int respLen = 0; byte[] testTel = null; switch (telType) { case 0: respLen = 9; testTel = new byte [] { 0x82, 0xF1, 0xF1, 0xFD, 0xFD, 0x5E }; break; case 1: if (AdapterType < 0x0002) { // no id support break; } respLen = 13; testTel = new byte[] { 0x82, 0xF1, 0xF1, 0xFB, 0xFB, 0x5A }; break; case 2: if (AdapterType < 0x0002) { // no voltage support break; } respLen = 6; testTel = new byte[] { 0x82, 0xF1, 0xF1, 0xFC, 0xFC, 0x5C }; break; } if (testTel == null) { break; } _discardInBufferFunc(); _sendDataFunc(testTel, testTel.Length); LastCommTick = Stopwatch.GetTimestamp(); List <byte> responseList = new List <byte>(); long startTime = Stopwatch.GetTimestamp(); for (; ;) { List <byte> newList = _readInBufferFunc(); if (newList.Count > 0) { responseList.AddRange(newList); startTime = Stopwatch.GetTimestamp(); } if (responseList.Count >= testTel.Length + respLen) { bool validEcho = !testTel.Where((t, i) => responseList[i] != t).Any(); if (!validEcho) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo Type={0}: Echo invalid", telType); Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, responseList.ToArray(), 0, responseList.Count, "Resp"); } return(false); } if (CalcChecksumBmwFast(responseList.ToArray(), testTel.Length, respLen - 1) != responseList[testTel.Length + respLen - 1]) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo Type={0}: Checksum invalid", telType); Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, responseList.ToArray(), 0, responseList.Count, "Resp"); } return(false); } switch (telType) { case 0: AdapterType = responseList[testTel.Length + 5] + (responseList[testTel.Length + 4] << 8); AdapterVersion = responseList[testTel.Length + 7] + (responseList[testTel.Length + 6] << 8); break; case 1: AdapterSerial = responseList.GetRange(testTel.Length + 4, 8).ToArray(); break; case 2: AdapterVoltage = responseList[testTel.Length + 4]; break; } break; } if (Stopwatch.GetTimestamp() - startTime > _readTimeoutOffsetLong * TickResolMs) { if (responseList.Count >= testTel.Length) { bool validEcho = !testTel.Where((t, i) => responseList[i] != t).Any(); if (telType == 0 && validEcho) { AdapterType = 0; } } if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo Type={0}: Response timeout", telType); Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, responseList.ToArray(), 0, responseList.Count, "Resp"); } return(false); } } } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", EdiabasNet.GetExceptionText(ex)); ReconnectRequired = true; return(false); } if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterType: {0}", AdapterType); Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterVersion: {0}.{1}", AdapterVersion >> 8, AdapterVersion & 0xFF); if (AdapterSerial != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterSerial: {0}", BitConverter.ToString(AdapterSerial).Replace("-", "")); } if (AdapterVoltage >= 0) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterVoltage: {0,4:0.0}", AdapterVoltage * AdapterVoltageScale); } } return(true); }