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);
     }
 }
Example #3
0
 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);
 }
Example #4
0
 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);
        }
Example #6
0
        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);
        }
Example #12
0
        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);
        }
Example #13
0
        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);
        }
Example #14
0
        // 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);
        }
Example #15
0
        // 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);
        }
Example #16
0
        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);
        }
Example #17
0
        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);
        }
Example #18
0
        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);
        }
Example #22
0
 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);
 }