public bool InterfaceSendPulse(UInt64 dataBits, int length, int pulseWidth, bool setDtr, bool bothLines, int autoKeyByteDelay) { ConvertBaudResponse = false; try { UpdateAdapterInfo(); FastInit = IsFastInit(dataBits, length, pulseWidth); if (FastInit) { // send next telegram with fast init return(true); } byte[] adapterTel = CreatePulseTelegram(dataBits, length, pulseWidth, setDtr, bothLines, autoKeyByteDelay); if (adapterTel == null) { return(false); } _sendDataFunc(adapterTel, adapterTel.Length); LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); Thread.Sleep(pulseWidth * length); } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); ReconnectRequired = true; return(false); } return(true); }
private static bool ReadData(byte[] buffer, int offset, int length, int timeout) { if (_usbPort == null) { return(false); } if ((_serialIoManager == null) || !_serialIoManager.IsStarted) { return(false); } if (buffer.Length < offset + length) { return(false); } if (length <= 0) { return(true); } try { int recLen = 0; for (;;) { lock (QueueLock) { while (ReadQueue.Count > 0) { buffer[offset + recLen] = ReadQueue.Dequeue(); recLen++; if (recLen >= length) { return(true); } } DataReceiveEvent.Reset(); } DataReceiveEvent.WaitOne(timeout, false); lock (QueueLock) { if (ReadQueue.Count == 0) { return(false); } } } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", EdiabasNet.GetExceptionText(ex)); _reconnectRequired = true; return(false); } }
public static bool InterfaceSendPulse(UInt64 dataBits, int length, int pulseWidth, bool setDtr, bool bothLines, int autoKeyByteDelay) { ConvertBaudResponse = false; if (!IsInterfaceOpen()) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "*** Port closed"); return(false); } if (_reconnectRequired) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Reconnecting"); InterfaceDisconnect(); if (!InterfaceConnect(_connectPort, null)) { _reconnectRequired = true; return(false); } _reconnectRequired = false; } try { UpdateAdapterInfo(); FastInit = IsFastInit(dataBits, length, pulseWidth); if (FastInit) { // send next telegram with fast init return(true); } byte[] adapterTel = CreatePulseTelegram(dataBits, length, pulseWidth, setDtr, bothLines, autoKeyByteDelay); if (adapterTel == null) { return(false); } if (BtStream != null) { BtStream.Write(adapterTel, 0, adapterTel.Length); } else { SerialPort.Write(adapterTel, 0, adapterTel.Length); } LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); Thread.Sleep(pulseWidth * length); } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); _reconnectRequired = true; return(false); } return(true); }
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 static bool InterfacePurgeInBuffer() { if (_usbPort == null) { return(false); } try { if (_reconnectRequired) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Reconnecting"); InterfaceDisconnect(); if (!InterfaceConnect(_connectPort, _connectParameter)) { _reconnectRequired = true; return(false); } } if (!_usbPort.PurgeHwBuffers(true, false)) { return(false); } lock (QueueLock) { ReadQueue.Clear(); } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", EdiabasNet.GetExceptionText(ex)); _reconnectRequired = true; return(false); } 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 InterfaceReceiveData(byte[] receiveData, int offset, int length, int timeout, int timeoutTelEnd, EdiabasNet ediabasLog) { int timeoutOffset = _readTimeoutOffsetLong; if ((_readTimeoutOffsetShort >= 0) && (CurrentBaudRate >= 3000)) { if (((Stopwatch.GetTimestamp() - LastCommTick) < 100 * TickResolMs) && (timeout < 100)) { timeoutOffset = _readTimeoutOffsetShort; } } //Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "Timeout offset: {0}", timeoutOffset); timeout += timeoutOffset; timeoutTelEnd += timeoutOffset; bool convertBaudResponse = ConvertBaudResponse; bool autoKeyByteResponse = AutoKeyByteResponse; ConvertBaudResponse = false; AutoKeyByteResponse = false; try { if (!RawMode && SettingsUpdateRequired()) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "InterfaceReceiveData, update settings"); UpdateAdapterInfo(); byte[] adapterTel = CreatePulseTelegram(0, 0, 0, false, false, 0); if (adapterTel == null) { return(false); } _sendDataFunc(adapterTel, adapterTel.Length); LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); } if (convertBaudResponse && length == 2) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Convert baud response"); length = 1; AutoKeyByteResponse = true; } if (!_receiveDataFunc(receiveData, offset, length, timeout, timeoutTelEnd, ediabasLog)) { return(false); } if (convertBaudResponse) { ConvertStdBaudResponse(receiveData, offset); } if (autoKeyByteResponse && length == 2) { // auto key byte response for old adapter Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Auto key byte response"); byte[] keyByteResponse = { (byte)~receiveData[offset + 1] }; byte[] adapterTel = CreateAdapterTelegram(keyByteResponse, keyByteResponse.Length, true); if (adapterTel == null) { return(false); } _sendDataFunc(adapterTel, adapterTel.Length); LastCommTick = Stopwatch.GetTimestamp(); } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); ReconnectRequired = true; return(false); } return(true); }
public bool InterfaceSendData(byte[] sendData, int length, bool setDtr, double dtrTimeCorr) { ConvertBaudResponse = false; AutoKeyByteResponse = false; try { if ((CurrentProtocol == EdInterfaceObd.Protocol.Tp20) || (CurrentProtocol == EdInterfaceObd.Protocol.IsoTp)) { UpdateAdapterInfo(); byte[] adapterTel = CreateCanTelegram(sendData, length); if (adapterTel == null) { return(false); } _sendDataFunc(adapterTel, adapterTel.Length); LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); return(true); } if (RawMode || CurrentBaudRate == 115200) { // BMW-FAST if (!RawMode) { UpdateAdapterInfo(); } if (sendData.Length >= 5 && sendData[1] == 0xF1 && sendData[2] == 0xF1 && sendData[3] == 0xFA && sendData[4] == 0xFA) { // read clamp status if (RawMode || AdapterVersion < 0x000A) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "*** Read clamp status not supported"); return(false); } } if (sendData.Length >= 6 && (sendData[0] & 0x3F) == 0x00 && sendData[3] == 0x00) { // long telegram format if (!RawMode && AdapterVersion < 0x000C) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "*** Long telegrams not supported"); return(false); } } _sendDataFunc(sendData, length); LastCommTick = Stopwatch.GetTimestamp(); // remove echo byte[] receiveData = new byte[length]; if (!InterfaceReceiveData(receiveData, 0, length, _echoTimeout, _echoTimeout, null)) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "*** Echo not received"); if (_echoFailureReconnect) { ReconnectRequired = true; } return(false); } for (int i = 0; i < length; i++) { if (receiveData[i] != sendData[i]) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "*** Echo incorrect"); if (_echoFailureReconnect) { ReconnectRequired = true; } return(false); } } } else { UpdateAdapterInfo(); byte[] adapterTel = CreateAdapterTelegram(sendData, length, setDtr); FastInit = false; if (adapterTel == null) { return(false); } _sendDataFunc(adapterTel, adapterTel.Length); LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); ReconnectRequired = true; return(false); } return(true); }
public bool UpdateAdapterInfo(bool forceUpdate = false) { if (!forceUpdate && AdapterType >= 0) { // only read once return(true); } AdapterType = -1; AdapterSerial = null; try { for (int telType = 0; telType < 2; 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; } 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) { return(false); } if (CalcChecksumBmwFast(responseList.ToArray(), testTel.Length, respLen - 1) != responseList[testTel.Length + respLen - 1]) { 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; } 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; } } return(false); } } } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); ReconnectRequired = true; return(false); } if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterType: {0}", AdapterType); if (AdapterSerial != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterSerial: {0}", BitConverter.ToString(AdapterSerial).Replace("-", "")); } } return(true); }
public byte[] CreateCanTelegram(byte[] sendData, int length) { ConvertBaudResponse = false; AutoKeyByteResponse = false; if ((AdapterType < 0x0002) || (AdapterVersion < 0x0008)) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "CreateCanTelegram, invalid adapter: {0} {1}", AdapterType, AdapterVersion); } return(null); } byte protocol; switch (CurrentProtocol) { case EdInterfaceObd.Protocol.Tp20: protocol = CAN_PROT_TP20; break; case EdInterfaceObd.Protocol.IsoTp: if (AdapterVersion < 0x0009) { if (Ediabas != null) { Ediabas.LogString(EdiabasNet.EdLogLevel.Ifh, "ISO-TP not supported by adapter"); } return(null); } if (CanTxId < 0 || CanRxId < 0) { if (Ediabas != null) { Ediabas.LogString(EdiabasNet.EdLogLevel.Ifh, "No CAN IDs present for ISO-TP"); } return(null); } protocol = CAN_PROT_ISOTP; break; default: if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "CreateCanTelegram, invalid protocol: {0}", CurrentProtocol); } return(null); } if ((CurrentBaudRate != 500000) && (CurrentBaudRate != 100000)) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "CreateCanTelegram, invalid baud rate: {0}", CurrentBaudRate); } return(null); } byte telType = (byte)((AdapterVersion < 0x0009) ? 0x01 : 0x03); byte[] resultArray = new byte[length + ((telType == 0x01) ? 11 : 14)]; resultArray[0] = 0x00; // header resultArray[1] = telType; // telegram type byte flags = CANF_NO_ECHO | CANF_CAN_ERROR; if ((CanFlags & EdInterfaceObd.CanFlags.BusCheck) != 0x00) { flags |= CANF_CONNECT_CHECK; } if ((CanFlags & EdInterfaceObd.CanFlags.Disconnect) != 0x00) { flags |= CANF_DISCONNECT; } resultArray[2] = protocol; // protocol resultArray[3] = (byte)((CurrentBaudRate == 500000) ? 0x01 : 0x09); // baud rate resultArray[4] = flags; // flags if (protocol == CAN_PROT_TP20) { resultArray[5] = 0x0F; // block size resultArray[6] = 0x0A; // packet interval (1ms) resultArray[7] = 1000 / 10; // idle time (10ms) } else { resultArray[5] = 0x00; // block size (off) resultArray[6] = 0x00; // separation time (off) resultArray[7] = (byte)(CanTxId >> 8); // CAN TX ID high resultArray[8] = (byte)CanTxId; // CAN TX ID low resultArray[9] = (byte)(CanRxId >> 8); // CAN RX ID high resultArray[10] = (byte)CanRxId; // CAN RX ID low } if (telType == 0x01) { resultArray[8] = (byte)(length >> 8); // telegram length high resultArray[9] = (byte)length; // telegram length low Array.Copy(sendData, 0, resultArray, 10, length); resultArray[resultArray.Length - 1] = CalcChecksumBmwFast(resultArray, 0, resultArray.Length - 1); } else { resultArray[11] = (byte)(length >> 8); // telegram length high resultArray[12] = (byte)length; // telegram length low Array.Copy(sendData, 0, resultArray, 13, length); resultArray[resultArray.Length - 1] = CalcChecksumBmwFast(resultArray, 0, resultArray.Length - 1); } return(resultArray); }
public byte[] CreatePulseTelegram(UInt64 dataBits, int length, int pulseWidth, bool setDtr, bool bothLines, int autoKeyByteDelay) { ConvertBaudResponse = false; AutoKeyByteResponse = false; if ((AdapterType < 0x0002) || (AdapterVersion < 0x0007)) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "CreatePulseTelegram, invalid adapter: {0} {1}", AdapterType, AdapterVersion); } return(null); } if ((CurrentBaudRate != EdInterfaceBase.BaudAuto) && ((CurrentBaudRate < MinBaudRate) || (CurrentBaudRate > MaxBaudRate))) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "CreatePulseTelegram, invalid baud rate: {0}", CurrentBaudRate); } return(null); } if ((length < 0) || (length > 64)) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "CreatePulseTelegram, invalid length: {0}", length); } return(null); } if ((pulseWidth < 0) || (pulseWidth > 255)) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "CreatePulseTelegram, invalid pulse width: {0}", pulseWidth); } return(null); } ConvertBaudResponse = (AdapterVersion < 0x0008) && (CurrentBaudRate == EdInterfaceBase.BaudAuto); byte telType = (byte)((AdapterVersion < 0x0008) ? 0x00 : 0x02); int dataBytes = (length + 7) >> 3; byte[] resultArray = new byte[dataBytes + 2 + 1 + ((telType == 0x00) ? 9 : 11)]; resultArray[0] = 0x00; // header resultArray[1] = telType; // telegram type uint baudHalf = (uint)(CurrentBaudRate >> 1); byte flags1 = KLINEF1_SEND_PULSE | KLINEF1_NO_ECHO; if (bothLines) { flags1 |= KLINEF1_USE_LLINE | KLINEF1_USE_KLINE; } else if (!setDtr) { flags1 |= KLINEF1_USE_LLINE; } flags1 |= CalcParityFlags(); byte flags2 = 0x00; if (CurrentProtocol == EdInterfaceObd.Protocol.Kwp) { flags2 |= KLINEF2_KWP1281_DETECT; } resultArray[2] = (byte)(baudHalf >> 8); // baud rate / 2 high resultArray[3] = (byte)baudHalf; // baud rate / 2 low resultArray[4] = flags1; // flags 1 if (telType == 0x00) { resultArray[5] = (byte)InterByteTime; // interbyte time resultArray[6] = 0x00; // telegram length high resultArray[7] = (byte)(dataBytes + 2 + 1); // telegram length low resultArray[8] = (byte)pulseWidth; resultArray[9] = (byte)length; for (int i = 0; i < dataBytes; i++) { resultArray[10 + i] = (byte)(dataBits >> (i << 3)); } } else { resultArray[5] = flags2; // flags 2 resultArray[6] = (byte)InterByteTime; // interbyte time resultArray[7] = KWP1281_TIMEOUT; // KWP1281 timeout resultArray[8] = 0x00; // telegram length high resultArray[9] = (byte)(dataBytes + 2 + 1); // telegram length low resultArray[10] = (byte)pulseWidth; resultArray[11] = (byte)length; for (int i = 0; i < dataBytes; i++) { resultArray[12 + i] = (byte)(dataBits >> (i << 3)); } } resultArray[resultArray.Length - 2] = (byte)autoKeyByteDelay; // W4 auto key byte response delay [ms], 0 = off resultArray[resultArray.Length - 1] = CalcChecksumBmwFast(resultArray, 0, resultArray.Length - 1); return(resultArray); }
public bool UpdateAdapterInfo(bool forceUpdate = false) { if (!forceUpdate && AdapterType >= 0) { // only read once return(true); } AdapterType = -1; try { const int versionRespLen = 9; byte[] identTel = { 0x82, 0xF1, 0xF1, 0xFD, 0xFD, 0x5E }; _discardInBufferFunc(); _sendDataFunc(identTel, identTel.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 >= identTel.Length + versionRespLen) { bool validEcho = !identTel.Where((t, i) => responseList[i] != t).Any(); if (!validEcho) { return(false); } if (CalcChecksumBmwFast(responseList.ToArray(), identTel.Length, versionRespLen - 1) != responseList[identTel.Length + versionRespLen - 1]) { return(false); } AdapterType = responseList[identTel.Length + 5] + (responseList[identTel.Length + 4] << 8); AdapterVersion = responseList[identTel.Length + 7] + (responseList[identTel.Length + 6] << 8); break; } if (Stopwatch.GetTimestamp() - startTime > _readTimeoutOffsetLong * TickResolMs) { if (responseList.Count >= identTel.Length) { bool validEcho = !identTel.Where((t, i) => responseList[i] != t).Any(); if (validEcho) { AdapterType = 0; } } return(false); } } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); ReconnectRequired = true; return(false); } return(true); }
public static bool InterfaceReceiveData(byte[] receiveData, int offset, int length, int timeout, int timeoutTelEnd, EdiabasNet ediabasLog) { bool convertBaudResponse = ConvertBaudResponse; bool autoKeyByteResponse = AutoKeyByteResponse; ConvertBaudResponse = false; AutoKeyByteResponse = false; if ((_bluetoothSocket == null) || (_bluetoothInStream == null)) { return(false); } if (_elm327Device) { if (_edElmInterface == null) { return(false); } return(_edElmInterface.InterfaceReceiveData(receiveData, offset, length, timeout, timeoutTelEnd, ediabasLog)); } int timeoutOffset = ReadTimeoutOffsetLong; if (((Stopwatch.GetTimestamp() - LastCommTick) < 100 * TickResolMs) && (timeout < 100)) { timeoutOffset = ReadTimeoutOffsetShort; } //Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "Timeout offset {0}", timeoutOffset); timeout += timeoutOffset; timeoutTelEnd += timeoutOffset; try { if (!_rawMode && SettingsUpdateRequired()) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "InterfaceReceiveData, update settings"); UpdateAdapterInfo(); byte[] adapterTel = CreatePulseTelegram(0, 0, 0, false, false, 0); if (adapterTel == null) { return(false); } _bluetoothOutStream.Write(adapterTel, 0, adapterTel.Length); LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); } if (convertBaudResponse && length == 2) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Convert baud response"); length = 1; AutoKeyByteResponse = true; } int recLen = 0; long startTime = Stopwatch.GetTimestamp(); while (recLen < length) { int currTimeout = (recLen == 0) ? timeout : timeoutTelEnd; if (_bluetoothInStream.IsDataAvailable()) { int bytesRead = _bluetoothInStream.Read(receiveData, offset + recLen, length - recLen); if (bytesRead > 0) { LastCommTick = Stopwatch.GetTimestamp(); } recLen += bytesRead; } if (recLen >= length) { break; } if ((Stopwatch.GetTimestamp() - startTime) > currTimeout * TickResolMs) { ediabasLog?.LogData(EdiabasNet.EdLogLevel.Ifh, receiveData, offset, recLen, "Rec "); return(false); } Thread.Sleep(10); } if (convertBaudResponse) { ConvertStdBaudResponse(receiveData, offset); } if (autoKeyByteResponse && length == 2) { // auto key byte response for old adapter Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Auto key byte response"); byte[] keyByteResponse = { (byte)~receiveData[offset + 1] }; byte[] adapterTel = CreateAdapterTelegram(keyByteResponse, keyByteResponse.Length, true); if (adapterTel == null) { return(false); } _bluetoothOutStream.Write(adapterTel, 0, adapterTel.Length); LastCommTick = Stopwatch.GetTimestamp(); } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); _reconnectRequired = true; return(false); } return(true); }
// ReSharper disable once UnusedMethodReturnValue.Local private static bool UpdateAdapterInfo(bool forceUpdate = false) { if (!IsInterfaceOpen()) { return(false); } if (!forceUpdate && AdapterType >= 0) { // only read once return(true); } AdapterType = -1; try { const int versionRespLen = 9; byte[] identTel = { 0x82, 0xF1, 0xF1, 0xFD, 0xFD, 0x5E }; if (BtStream != null) { BtStream.ReadTimeout = 1; while (BtStream.DataAvailable) { try { BtStream.ReadByte(); } catch (Exception) { break; } } BtStream.Write(identTel, 0, identTel.Length); } else { SerialPort.DiscardInBuffer(); SerialPort.Write(identTel, 0, identTel.Length); } LastCommTick = Stopwatch.GetTimestamp(); List <byte> responseList = new List <byte>(); long startTime = Stopwatch.GetTimestamp(); for (;;) { if (BtStream != null) { BtStream.ReadTimeout = 1; while (BtStream.DataAvailable) { int data; try { data = BtStream.ReadByte(); } catch (Exception) { data = -1; } if (data >= 0) { LastCommTick = Stopwatch.GetTimestamp(); responseList.Add((byte)data); startTime = Stopwatch.GetTimestamp(); } } } else { while (SerialPort.BytesToRead > 0) { int data = SerialPort.ReadByte(); if (data >= 0) { LastCommTick = Stopwatch.GetTimestamp(); responseList.Add((byte)data); startTime = Stopwatch.GetTimestamp(); } } } if (responseList.Count >= identTel.Length + versionRespLen) { bool validEcho = !identTel.Where((t, i) => responseList[i] != t).Any(); if (!validEcho) { return(false); } if (CalcChecksumBmwFast(responseList.ToArray(), identTel.Length, versionRespLen - 1) != responseList[identTel.Length + versionRespLen - 1]) { return(false); } AdapterType = responseList[identTel.Length + 5] + (responseList[identTel.Length + 4] << 8); AdapterVersion = responseList[identTel.Length + 7] + (responseList[identTel.Length + 6] << 8); break; } if (Stopwatch.GetTimestamp() - startTime > ReadTimeoutOffsetLong * TickResolMs) { if (responseList.Count >= identTel.Length) { bool validEcho = !identTel.Where((t, i) => responseList[i] != t).Any(); if (validEcho) { AdapterType = 0; } } return(false); } } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); _reconnectRequired = true; return(false); } return(true); }
// ReSharper disable once UnusedMethodReturnValue.Local private static bool UpdateAdapterInfo(bool forceUpdate = false) { if ((_bluetoothSocket == null) || (_bluetoothOutStream == null)) { return(false); } if (_elm327Device) { return(false); } if (!forceUpdate && AdapterType >= 0) { // only read once return(true); } AdapterType = -1; try { const int versionRespLen = 9; byte[] identTel = { 0x82, 0xF1, 0xF1, 0xFD, 0xFD, 0x5E }; FlushReceiveBuffer(); _bluetoothOutStream.Write(identTel, 0, identTel.Length); LastCommTick = Stopwatch.GetTimestamp(); List <byte> responseList = new List <byte>(); long startTime = Stopwatch.GetTimestamp(); for (; ;) { while (_bluetoothInStream.IsDataAvailable()) { int data = _bluetoothInStream.ReadByte(); if (data >= 0) { LastCommTick = Stopwatch.GetTimestamp(); responseList.Add((byte)data); startTime = Stopwatch.GetTimestamp(); } } if (responseList.Count >= identTel.Length + versionRespLen) { bool validEcho = !identTel.Where((t, i) => responseList[i] != t).Any(); if (!validEcho) { return(false); } if (CalcChecksumBmwFast(responseList.ToArray(), identTel.Length, versionRespLen - 1) != responseList[identTel.Length + versionRespLen - 1]) { return(false); } AdapterType = responseList[identTel.Length + 5] + (responseList[identTel.Length + 4] << 8); AdapterVersion = responseList[identTel.Length + 7] + (responseList[identTel.Length + 6] << 8); break; } if (Stopwatch.GetTimestamp() - startTime > ReadTimeoutOffsetLong * TickResolMs) { if (responseList.Count >= identTel.Length) { bool validEcho = !identTel.Where((t, i) => responseList[i] != t).Any(); if (validEcho) { AdapterType = 0; } } return(false); } } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); _reconnectRequired = true; return(false); } return(true); }
public static bool InterfaceReceiveData(byte[] receiveData, int offset, int length, int timeout, int timeoutTelEnd, EdiabasNet ediabasLog) { bool convertBaudResponse = ConvertBaudResponse; bool autoKeyByteResponse = AutoKeyByteResponse; ConvertBaudResponse = false; AutoKeyByteResponse = false; if (!IsInterfaceOpen()) { return(false); } int timeoutOffset = ReadTimeoutOffsetLong; if (((Stopwatch.GetTimestamp() - LastCommTick) < 100 * TickResolMs) && (timeout < 100)) { timeoutOffset = ReadTimeoutOffsetShort; } //Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "Timeout offset {0}", timeoutOffset); timeout += timeoutOffset; timeoutTelEnd += timeoutOffset; try { if (SettingsUpdateRequired()) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "InterfaceReceiveData, update settings"); UpdateAdapterInfo(); byte[] adapterTel = CreatePulseTelegram(0, 0, 0, false, false, 0); if (adapterTel == null) { return(false); } if (BtStream != null) { BtStream.Write(adapterTel, 0, adapterTel.Length); } else { SerialPort.Write(adapterTel, 0, adapterTel.Length); } LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); } if (convertBaudResponse && length == 2) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Convert baud response"); length = 1; AutoKeyByteResponse = true; } int recLen = 0; if (BtStream != null) { BtStream.ReadTimeout = timeout; int data; try { data = BtStream.ReadByte(); } catch (Exception) { data = -1; } if (data < 0) { return(false); } receiveData[offset + recLen] = (byte)data; recLen++; BtStream.ReadTimeout = timeoutTelEnd; for (;;) { if (recLen >= length) { break; } try { data = BtStream.ReadByte(); } catch (Exception) { data = -1; } if (data < 0) { return(false); } receiveData[offset + recLen] = (byte)data; recLen++; } } else { // wait for first byte int lastBytesToRead; StopWatch.Reset(); StopWatch.Start(); for (;;) { lastBytesToRead = SerialPort.BytesToRead; if (lastBytesToRead > 0) { break; } if (StopWatch.ElapsedMilliseconds > timeout) { StopWatch.Stop(); return(false); } CommReceiveEvent.WaitOne(1, false); } StopWatch.Reset(); StopWatch.Start(); for (;;) { int bytesToRead = SerialPort.BytesToRead; if (bytesToRead >= length) { int bytesRead = SerialPort.Read(receiveData, offset + recLen, length - recLen); if (bytesRead > 0) { LastCommTick = Stopwatch.GetTimestamp(); } recLen += bytesRead; } if (recLen >= length) { break; } if (lastBytesToRead != bytesToRead) { // bytes received StopWatch.Reset(); StopWatch.Start(); lastBytesToRead = bytesToRead; } else { if (StopWatch.ElapsedMilliseconds > timeoutTelEnd) { break; } } CommReceiveEvent.WaitOne(1, false); } StopWatch.Stop(); } ediabasLog?.LogData(EdiabasNet.EdLogLevel.Ifh, receiveData, offset, recLen, "Rec "); if (recLen < length) { return(false); } if (convertBaudResponse) { ConvertStdBaudResponse(receiveData, offset); } if (autoKeyByteResponse && length == 2) { // auto key byte response for old adapter Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Auto key byte response"); byte[] keyByteResponse = { (byte)~receiveData[offset + 1] }; byte[] adapterTel = CreateAdapterTelegram(keyByteResponse, keyByteResponse.Length, true); if (adapterTel == null) { return(false); } if (BtStream != null) { BtStream.Write(adapterTel, 0, adapterTel.Length); } else { SerialPort.Write(adapterTel, 0, adapterTel.Length); } LastCommTick = Stopwatch.GetTimestamp(); } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); _reconnectRequired = true; return(false); } return(true); }
public static bool InterfaceConnect(string port, object parameter) { if (IsInterfaceOpen()) { return(true); } FastInit = false; ConvertBaudResponse = false; AutoKeyByteResponse = false; AdapterType = -1; AdapterVersion = -1; LastCommTick = DateTime.MinValue.Ticks; if (!port.StartsWith(PortId, StringComparison.OrdinalIgnoreCase)) { InterfaceDisconnect(); return(false); } _connectPort = port; _reconnectRequired = false; try { string portData = port.Remove(0, PortId.Length); if ((portData.Length > 0) && (portData[0] == ':')) { // special id string portName = portData.Remove(0, 1); string[] stringList = portName.Split('#', ';'); if (stringList.Length == 1) { SerialPort.PortName = portName; SerialPort.BaudRate = 115200; SerialPort.DataBits = 8; SerialPort.Parity = System.IO.Ports.Parity.None; SerialPort.StopBits = System.IO.Ports.StopBits.One; SerialPort.Handshake = System.IO.Ports.Handshake.None; SerialPort.DtrEnable = false; SerialPort.RtsEnable = false; SerialPort.ReadTimeout = 1; SerialPort.Open(); } #if BLUETOOTH else if (stringList.Length == 2) { InTheHand.Net.BluetoothEndPoint ep = new InTheHand.Net.BluetoothEndPoint(InTheHand.Net.BluetoothAddress.Parse(stringList[0]), InTheHand.Net.Bluetooth.BluetoothService.SerialPort); InTheHand.Net.Sockets.BluetoothClient cli = new InTheHand.Net.Sockets.BluetoothClient(); cli.SetPin(stringList[1]); cli.Connect(ep); BtStream = cli.GetStream(); BtStream.ReadTimeout = 1; } #endif else { InterfaceDisconnect(); return(false); } } else { InterfaceDisconnect(); return(false); } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Connect failure: {0}", ex.Message); InterfaceDisconnect(); return(false); } return(true); }
public static bool InterfaceSendData(byte[] sendData, int length, bool setDtr, double dtrTimeCorr) { ConvertBaudResponse = false; AutoKeyByteResponse = false; if (!IsInterfaceOpen()) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "*** Port closed"); return(false); } if (_reconnectRequired) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Reconnecting"); InterfaceDisconnect(); if (!InterfaceConnect(_connectPort, null)) { _reconnectRequired = true; return(false); } _reconnectRequired = false; } try { if ((CurrentProtocol == EdInterfaceObd.Protocol.Tp20) || (CurrentProtocol == EdInterfaceObd.Protocol.IsoTp)) { UpdateAdapterInfo(); byte[] adapterTel = CreateCanTelegram(sendData, length); if (adapterTel == null) { return(false); } if (BtStream != null) { BtStream.Write(adapterTel, 0, adapterTel.Length); } else { SerialPort.Write(adapterTel, 0, adapterTel.Length); } LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); return(true); } if (CurrentBaudRate == 115200) { // BMW-FAST if (sendData.Length >= 5 && sendData[1] == 0xF1 && sendData[2] == 0xF1 && sendData[3] == 0xFA && sendData[4] == 0xFA) { // read clamp status UpdateAdapterInfo(); if (AdapterVersion < 0x000A) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "*** Read clamp status not supported"); return(false); } } if (BtStream != null) { BtStream.Write(sendData, 0, length); } else { SerialPort.Write(sendData, 0, length); } LastCommTick = Stopwatch.GetTimestamp(); // remove echo byte[] receiveData = new byte[length]; if (!InterfaceReceiveData(receiveData, 0, length, EchoTimeout, EchoTimeout, null)) { return(false); } for (int i = 0; i < length; i++) { if (receiveData[i] != sendData[i]) { return(false); } } } else { UpdateAdapterInfo(); byte[] adapterTel = CreateAdapterTelegram(sendData, length, setDtr); FastInit = false; if (adapterTel == null) { return(false); } if (BtStream != null) { BtStream.Write(adapterTel, 0, adapterTel.Length); } else { SerialPort.Write(adapterTel, 0, adapterTel.Length); } LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); _reconnectRequired = true; return(false); } return(true); }
public static bool InterfaceSendData(byte[] sendData, int length, bool setDtr, double dtrTimeCorr) { if (_usbPort == null) { return(false); } if ((_serialIoManager == null) || !_serialIoManager.IsStarted) { return(false); } try { if (_reconnectRequired) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Reconnecting"); InterfaceDisconnect(); if (!InterfaceConnect(_connectPort, _connectParameter)) { _reconnectRequired = true; return(false); } } int bytesWritten; byte[] sendBuffer = new byte[length]; Array.Copy(sendData, sendBuffer, sendBuffer.Length); int bitCount = (_currentParity == EdInterfaceObd.SerialParity.None) ? (_currentWordLength + 2) : (_currentWordLength + 3); double byteTime = 1.0d / _currentBaudRate * 1000 * bitCount; if (setDtr) { long waitTime = (long)((dtrTimeCorr + byteTime * length) * TickResolMs); _usbPort.DTR = true; long startTime = Stopwatch.GetTimestamp(); bytesWritten = _usbPort.Write(sendBuffer, WriteTimeout); if (bytesWritten != length) { return(false); } while ((Stopwatch.GetTimestamp() - startTime) < waitTime) { } _usbPort.DTR = false; } else { long waitTime = (long)(byteTime * length); bytesWritten = _usbPort.Write(sendBuffer, WriteTimeout); if (bytesWritten != length) { return(false); } if (waitTime > 10) { Thread.Sleep((int)waitTime); } } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", EdiabasNet.GetExceptionText(ex)); _reconnectRequired = true; return(false); } return(true); }
public byte[] CreateAdapterTelegram(byte[] sendData, int length, bool setDtr) { ConvertBaudResponse = false; if ((AdapterType < 0x0002) || (AdapterVersion < 0x0003)) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "CreateAdapterTelegram, invalid adapter: {0} {1}", AdapterType, AdapterVersion); } return(null); } if ((CurrentBaudRate != 115200) && ((CurrentBaudRate < MinBaudRate) || (CurrentBaudRate > MaxBaudRate))) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "CreateAdapterTelegram, invalid baud rate: {0}", CurrentBaudRate); } return(null); } if ((InterByteTime < 0) || (InterByteTime > 255)) { if (Ediabas != null) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "CreateAdapterTelegram, invalid inter byte time: {0}", InterByteTime); } return(null); } byte telType = (byte)((AdapterVersion < 0x0008) ? 0x00 : 0x02); byte[] resultArray = new byte[length + ((telType == 0x00) ? 9 : 11)]; resultArray[0] = 0x00; // header resultArray[1] = telType; // telegram type uint baudHalf; byte flags1 = KLINEF1_NO_ECHO; if (CurrentBaudRate == 115200) { baudHalf = 0; } else { baudHalf = (uint)(CurrentBaudRate >> 1); if (!setDtr) { flags1 |= KLINEF1_USE_LLINE; } flags1 |= CalcParityFlags(); if (FastInit) { flags1 |= KLINEF1_FAST_INIT; } } int interByteTime = InterByteTime; byte flags2 = 0x00; if (CurrentProtocol == EdInterfaceObd.Protocol.Kwp) { flags2 |= KLINEF2_KWP1281_DETECT; if (interByteTime > 0 && AdapterType >= 0x0002 && AdapterVersion < 0x000B) { Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "Setting interbyte time {0} to 0 for adapter version: {1}", interByteTime, AdapterVersion); interByteTime = 0; } } resultArray[2] = (byte)(baudHalf >> 8); // baud rate / 2 high resultArray[3] = (byte)baudHalf; // baud rate / 2 low resultArray[4] = flags1; // flags 1 if (telType == 0x00) { resultArray[5] = (byte)interByteTime; // interbyte time resultArray[6] = (byte)(length >> 8); // telegram length high resultArray[7] = (byte)length; // telegram length low Array.Copy(sendData, 0, resultArray, 8, length); resultArray[resultArray.Length - 1] = CalcChecksumBmwFast(resultArray, 0, resultArray.Length - 1); } else { resultArray[5] = flags2; // flags 2 resultArray[6] = (byte)interByteTime; // interbyte time resultArray[7] = KWP1281_TIMEOUT; // KWP1281 timeout resultArray[8] = (byte)(length >> 8); // telegram length high resultArray[9] = (byte)length; // telegram length low Array.Copy(sendData, 0, resultArray, 10, length); resultArray[resultArray.Length - 1] = CalcChecksumBmwFast(resultArray, 0, resultArray.Length - 1); } return(resultArray); }
public static bool InterfaceConnect(string port, object parameter) { if (_usbPort != null) { return(true); } try { _connectPort = port; _connectParameter = parameter; if (!(parameter is ConnectParameterType connectParameter)) { return(false); } if (!port.StartsWith(PortId, StringComparison.OrdinalIgnoreCase)) { InterfaceDisconnect(); return(false); } List <IUsbSerialDriver> availableDrivers = GetDriverList(connectParameter.UsbManager); if (availableDrivers.Count <= 0) { InterfaceDisconnect(); return(false); } string portData = port.Remove(0, PortId.Length); int portIndex = -1; if ((portData.Length > 0) && (portData[0] == ':')) { // special id if (portData.StartsWith(":SER=", StringComparison.OrdinalIgnoreCase)) { // serial number string id = portData.Remove(0, 5); int index = 0; foreach (IUsbSerialDriver serialDriver in availableDrivers) { if (serialDriver.Ports[0] != null && string.Compare(serialDriver.Ports[0].Serial, id, StringComparison.Ordinal) == 0) { portIndex = index; break; } index++; } } } else { portIndex = Convert.ToInt32(port.Remove(0, PortId.Length)); } if ((portIndex < 0) || (portIndex >= availableDrivers.Count)) { InterfaceDisconnect(); return(false); } IUsbSerialDriver driver = availableDrivers[portIndex]; UsbDeviceConnection connection = connectParameter.UsbManager.OpenDevice(driver.Device); if (connection == null) { InterfaceDisconnect(); return(false); } if (driver.Ports.Count < 1) { InterfaceDisconnect(); return(false); } _usbPort = driver.Ports[0]; _usbPort.Open(connection); _usbPort.SetParameters(9600, 8, StopBits.One, Parity.None); if (_usbPort is FtdiSerialDriver.FtdiSerialPort ftdiPort) { ftdiPort.LatencyTimer = LatencyTime; if (ftdiPort.LatencyTimer != LatencyTime) { InterfaceDisconnect(); return(false); } } _currentWordLength = 8; _currentParity = EdInterfaceObd.SerialParity.None; _usbPort.DTR = false; _usbPort.RTS = false; lock (QueueLock) { ReadQueue.Clear(); } _serialIoManager = new SerialInputOutputManager(_usbPort); _serialIoManager.DataReceived += (sender, e) => { lock (QueueLock) { foreach (byte value in e.Data) { ReadQueue.Enqueue(value); } DataReceiveEvent.Set(); } }; _serialIoManager.Start(UsbBlockSize); if (_currentBaudRate != 0 && _currentWordLength != 0) { if (InterfaceSetConfig(EdInterfaceObd.Protocol.Uart, _currentBaudRate, _currentWordLength, _currentParity, false) != EdInterfaceObd.InterfaceErrorResult.NoError) { InterfaceDisconnect(); return(false); } InterfaceSetDtr(_currentDtr); InterfaceSetRts(_currentRts); } Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Connected"); _reconnectRequired = false; } catch (Exception) { InterfaceDisconnect(); return(false); } return(true); }
public static bool InterfaceSendData(byte[] sendData, int length, bool setDtr, double dtrTimeCorr) { ConvertBaudResponse = false; AutoKeyByteResponse = false; if ((_bluetoothSocket == null) || (_bluetoothOutStream == null)) { return(false); } if (_elm327Device) { if ((CurrentProtocol != EdInterfaceObd.Protocol.Uart) || (CurrentBaudRate != 115200) || (CurrentWordLength != 8) || (CurrentParity != EdInterfaceObd.SerialParity.None)) { return(false); } if (_edElmInterface == null) { return(false); } if (_edElmInterface.StreamFailure) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Reconnecting"); InterfaceDisconnect(); if (!InterfaceConnect(_connectPort, null)) { _edElmInterface.StreamFailure = true; return(false); } } return(_edElmInterface.InterfaceSendData(sendData, length, setDtr, dtrTimeCorr)); } if (_reconnectRequired) { Ediabas?.LogString(EdiabasNet.EdLogLevel.Ifh, "Reconnecting"); InterfaceDisconnect(); if (!InterfaceConnect(_connectPort, null)) { _reconnectRequired = true; return(false); } _reconnectRequired = false; } try { if ((CurrentProtocol == EdInterfaceObd.Protocol.Tp20) || (CurrentProtocol == EdInterfaceObd.Protocol.IsoTp)) { UpdateAdapterInfo(); byte[] adapterTel = CreateCanTelegram(sendData, length); if (adapterTel == null) { return(false); } _bluetoothOutStream.Write(adapterTel, 0, adapterTel.Length); LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); return(true); } if (_rawMode || (CurrentBaudRate == 115200)) { // BMW-FAST _bluetoothOutStream.Write(sendData, 0, length); LastCommTick = Stopwatch.GetTimestamp(); // remove echo byte[] receiveData = new byte[length]; if (!InterfaceReceiveData(receiveData, 0, length, EchoTimeout, EchoTimeout, null)) { return(false); } for (int i = 0; i < length; i++) { if (receiveData[i] != sendData[i]) { return(false); } } } else { UpdateAdapterInfo(); byte[] adapterTel = CreateAdapterTelegram(sendData, length, setDtr); FastInit = false; if (adapterTel == null) { return(false); } _bluetoothOutStream.Write(adapterTel, 0, adapterTel.Length); LastCommTick = Stopwatch.GetTimestamp(); UpdateActiveSettings(); } } catch (Exception ex) { Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", ex.Message); _reconnectRequired = true; return(false); } return(true); }