Example #1
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);
 }
Example #2
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);
        }
Example #3
0
        public bool UpdateAdapterInfo(bool forceUpdate = false)
        {
            if (!forceUpdate && AdapterType >= 0)
            {
                // only read once
                return(true);
            }
            AdapterType    = -1;
            AdapterSerial  = null;
            AdapterVoltage = -1;
            try
            {
                for (int telType = 0; telType < 3; telType++)
                {
                    int    respLen = 0;
                    byte[] testTel = null;
                    switch (telType)
                    {
                    case 0:
                        respLen = 9;
                        testTel = new byte [] { 0x82, 0xF1, 0xF1, 0xFD, 0xFD, 0x5E };
                        break;

                    case 1:
                        if (AdapterType < 0x0002)
                        {       // no id support
                            break;
                        }
                        respLen = 13;
                        testTel = new byte[] { 0x82, 0xF1, 0xF1, 0xFB, 0xFB, 0x5A };
                        break;

                    case 2:
                        if (AdapterType < 0x0002)
                        {       // no voltage support
                            break;
                        }
                        respLen = 6;
                        testTel = new byte[] { 0x82, 0xF1, 0xF1, 0xFC, 0xFC, 0x5C };
                        break;
                    }

                    if (testTel == null)
                    {
                        break;
                    }
                    _discardInBufferFunc();
                    _sendDataFunc(testTel, testTel.Length);
                    LastCommTick = Stopwatch.GetTimestamp();

                    List <byte> responseList = new List <byte>();
                    long        startTime    = Stopwatch.GetTimestamp();
                    for (; ;)
                    {
                        List <byte> newList = _readInBufferFunc();
                        if (newList.Count > 0)
                        {
                            responseList.AddRange(newList);
                            startTime = Stopwatch.GetTimestamp();
                        }
                        if (responseList.Count >= testTel.Length + respLen)
                        {
                            bool validEcho = !testTel.Where((t, i) => responseList[i] != t).Any();
                            if (!validEcho)
                            {
                                if (Ediabas != null)
                                {
                                    Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo Type={0}: Echo invalid", telType);
                                    Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, responseList.ToArray(), 0, responseList.Count, "Resp");
                                }
                                return(false);
                            }
                            if (CalcChecksumBmwFast(responseList.ToArray(), testTel.Length, respLen - 1) !=
                                responseList[testTel.Length + respLen - 1])
                            {
                                if (Ediabas != null)
                                {
                                    Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo Type={0}: Checksum invalid", telType);
                                    Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, responseList.ToArray(), 0, responseList.Count, "Resp");
                                }
                                return(false);
                            }
                            switch (telType)
                            {
                            case 0:
                                AdapterType    = responseList[testTel.Length + 5] + (responseList[testTel.Length + 4] << 8);
                                AdapterVersion = responseList[testTel.Length + 7] + (responseList[testTel.Length + 6] << 8);
                                break;

                            case 1:
                                AdapterSerial = responseList.GetRange(testTel.Length + 4, 8).ToArray();
                                break;

                            case 2:
                                AdapterVoltage = responseList[testTel.Length + 4];
                                break;
                            }
                            break;
                        }
                        if (Stopwatch.GetTimestamp() - startTime > _readTimeoutOffsetLong * TickResolMs)
                        {
                            if (responseList.Count >= testTel.Length)
                            {
                                bool validEcho = !testTel.Where((t, i) => responseList[i] != t).Any();
                                if (telType == 0 && validEcho)
                                {
                                    AdapterType = 0;
                                }
                            }

                            if (Ediabas != null)
                            {
                                Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "UpdateAdapterInfo Type={0}: Response timeout", telType);
                                Ediabas.LogData(EdiabasNet.EdLogLevel.Ifh, responseList.ToArray(), 0, responseList.Count, "Resp");
                            }
                            return(false);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Ediabas?.LogFormat(EdiabasNet.EdLogLevel.Ifh, "*** Stream failure: {0}", EdiabasNet.GetExceptionText(ex));
                ReconnectRequired = true;
                return(false);
            }

            if (Ediabas != null)
            {
                Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterType: {0}", AdapterType);
                Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterVersion: {0}.{1}", AdapterVersion >> 8, AdapterVersion & 0xFF);
                if (AdapterSerial != null)
                {
                    Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterSerial: {0}", BitConverter.ToString(AdapterSerial).Replace("-", ""));
                }
                if (AdapterVoltage >= 0)
                {
                    Ediabas.LogFormat(EdiabasNet.EdLogLevel.Ifh, "AdapterVoltage: {0,4:0.0}", AdapterVoltage * AdapterVoltageScale);
                }
            }

            return(true);
        }