Пример #1
0
        /// <summary>
        /// Send a KWP request.
        /// </summary>
        /// <param name="a_request">A KWP request.</param>
        /// <param name="r_reply">A KWP reply.</param>
        /// <returns>The status of the request.</returns>
        public RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply)
        {
            CANMessage msg = new CANMessage(0x7E0, 0, 8);
            uint row = nrOfRowsToSend(a_request.getData());

            m_kwpCanListener.setupWaitMessage(0x7E8);

            // Send one or several request messages.
            for (; row > 0; row--)
            {
                msg.setData(createCanMessage(a_request.getData(), row - 1));
                if (!m_canDevice.sendMessage(msg))
                {
                    r_reply = new KWPReply();
                    return RequestResult.ErrorSending;
                }
            }

            msg = m_kwpCanListener.waitMessage(timeoutPeriod);
             //         msg = m_kwpCanListener.waitForMessage(0x7E8, timeoutPeriod);

            // Receive one or several replys and send an ack for each reply.
            if (msg.getID() == 0x7E8)
            {
                uint nrOfRows = (uint)(msg.getCanData(0) & 0x3F)+ 1;
                row = 0;
                if (nrOfRows == 0)
                    throw new Exception("Wrong nr of rows");
                //Assume that no KWP reply contains more than 0x200 bytes
                byte[] reply = new byte[0x200];
                reply = collectReply(reply, msg.getData(), row);
                sendAck(nrOfRows - 1);
                nrOfRows--;

                m_kwpCanListener.setupWaitMessage(0x7E8);

                while (nrOfRows > 0)
                {
            //                    msg = m_kwpCanListener.waitForMessage(0x7E8, timeoutPeriod);
                    msg = m_kwpCanListener.waitMessage(timeoutPeriod);
                    if (msg.getID() == 0x7E8)
                    {
                        row++;
                        reply = collectReply(reply, msg.getData(), row);
                        sendAck(nrOfRows - 1);
                        nrOfRows--;
                    }
                    else
                    {
                        r_reply = new KWPReply();
                        return RequestResult.Timeout;
                    }

                }
                r_reply = new KWPReply(reply, a_request.getNrOfPID());
                return RequestResult.NoError;
            }
            else
            {
                r_reply = new KWPReply();
                return RequestResult.Timeout;
            }
        }
Пример #2
0
        /// <summary>
        /// This method writes to a symbol in RAM.
        /// The ECU must not be write protected for this to work.
        /// </summary>
        /// <param name="a_symbolNumber">Symbol number to write to.</param>
        /// <param name="a_data">Data to write.</param> 
        /// <returns></returns>
        public bool writeSymbolRequestAddress(uint a_address, byte[] a_data)
        {
            LogDataString("writeSymbolRequest: " + a_address.ToString("X8") + "len: " + a_data.Length.ToString("X4"));

            KWPReply reply = new KWPReply();
            KWPResult result;
            byte[] symbolNumberAndData = new byte[4 + a_data.Length];
            //symbolNumberAndData[0] = (byte)(a_address >> 24);
            symbolNumberAndData[0] = (byte)(a_address >> 16);
            symbolNumberAndData[1] = (byte)(a_address >> 8);
            symbolNumberAndData[2] = (byte)(a_address);
            symbolNumberAndData[3] = (byte)(a_data.Length);
            // len len
            // adr adr adr

            for (int i = 0; i < a_data.Length; i++)
                symbolNumberAndData[i + 4] = a_data[i];

            //string requestString = "RequestString: ";
            //foreach (byte b in symbolNumberAndData)
            //{
            //    requestString += b.ToString("X2") + " ";
            //}
            //Console.WriteLine(requestString);
            // end dump to console
            //Console.WriteLine("SymbolNumberAndData length: " + symbolNumberAndData.Length.ToString("X8"));
            KWPRequest t_request = new KWPRequest(0x3D, /*0x81, */symbolNumberAndData);
            //Console.WriteLine(t_request.ToString());
            result = sendRequest(t_request, out reply);
            if (result != KWPResult.OK)
            {
                Console.WriteLine("Result != KWPResult.OK");
                return false;
            }
               // Console.WriteLine("Result = " + reply.getData()[0].ToString("X2"));
            //Console.WriteLine("Result-total = " + reply.ToString());
            if (reply.getData()[0] == 0x7D)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
Пример #3
0
        /// <summary>
        /// This method writes to a symbol in RAM.
        /// The ECU must not be write protected for this to work.
        /// </summary>
        /// <param name="a_symbolNumber">Symbol number to write to.</param>
        /// <param name="a_data">Data to write.</param> 
        /// <returns></returns>
        public bool writeSymbolRequestTest(uint a_symbolNumber, byte[] a_data, int idx)
        {
            LogDataString("writeSymbolRequest: " + a_symbolNumber.ToString());

            KWPReply reply = new KWPReply();
            KWPResult result;
            int LengthToTx = a_data.Length;
            if (LengthToTx > 0x41) LengthToTx = 0x41; // FA
            byte[] symbolNumberAndData = new byte[3 + /*a_data.Length*/ LengthToTx];
            //First two bytes should be the symbol number
            symbolNumberAndData[0] = (byte)(a_symbolNumber >> 8);
            symbolNumberAndData[1] = (byte)(a_symbolNumber);
            symbolNumberAndData[2] = (byte)(0);
            // len len
            // adr adr adr

            for (int i = 0; i < /*a_data.Length*/ LengthToTx; i++)
                symbolNumberAndData[i + 3] = a_data[i];

            //string requestString = "RequestString: ";
            //foreach (byte b in symbolNumberAndData)
            //{
            //    requestString += b.ToString("X2") + " ";
            //}
            //Console.WriteLine(requestString);
            // end dump to console
            //Console.WriteLine("SymbolNumberAndData length: " + symbolNumberAndData.Length.ToString("X8"));
            KWPRequest t_request = new KWPRequest(0x3D, 0x80, symbolNumberAndData);
            //Console.WriteLine(t_request.ToString());
            result = sendRequest(t_request, out reply);
            if (result != KWPResult.OK)
            {
                Console.WriteLine("Result != KWPResult.OK");
                return false;
            }
            //Console.WriteLine("Result = " + reply.getData()[0].ToString("X2"));
            if (reply.getData()[0] == 0x7D)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
Пример #4
0
 public bool ResetECU()
 {
     LogDataString("ResetECU");
     KWPReply reply = new KWPReply();
     KWPResult result;
     byte[] data = new byte[1];
     data[0] = (byte)0x00;
     KWPRequest req = new KWPRequest(0x11, 0x01, data);
     //Console.WriteLine(req.ToString());
     result = sendRequest(req, out reply);
     //Console.WriteLine(reply.ToString());
     return true;
 }
Пример #5
0
        public KWPResult sendEraseMemorySpaceRequest(Int32 StartAddress, Int32 Length)
        {
            /*02 FLASH memory erasure
            1 start address (high byte)
            2 start address (middle byte)
            3 start address (low byte)
            4 stop address (high byte)
            5 stop address (middle byte)
            6 stop address (low byte)
            */
            Int32 StopAddress = StartAddress + Length;
            LogDataString("sendEraseRequest");

            KWPReply reply = new KWPReply();
            KWPReply reply2 = new KWPReply();
            KWPResult result = KWPResult.Timeout;
            int i = 0;

            //First erase message. Up to 5 retries.
            //Mode = 0x31
            //PID = 0x51
            //Expected result is 0x71
            byte[] a_data = new byte[6];
            int bt = 0;
            //a_data[0] = (byte)(StartAddress >> 24);
            a_data[bt++] = (byte)(StartAddress >> 16);
            a_data[bt++] = (byte)(StartAddress >> 8);
            a_data[bt++] = (byte)(StartAddress);
            //a_data[4] = (byte)(Length >> 24);
            a_data[bt++] = (byte)(StopAddress >> 16);
            a_data[bt++] = (byte)(StopAddress >> 8);
            a_data[bt++] = (byte)(StopAddress);

            requestSequrityAccess(true);
            KWPRequest req = new KWPRequest(0x31, 0x50, a_data);

            result = sendRequest(req, out reply);
            Console.WriteLine("Erase(1) " + reply.ToString());
            /*if (result != KWPResult.OK)
                return result;
            System.Threading.Thread.Sleep(10000);
            result = sendRequest(new KWPRequest(0x31, 0x53, a_data), out reply);
            Console.WriteLine("Erase(2:" + i.ToString() + ") " + reply.ToString());
            */
            if (result != KWPResult.OK)
                return result;

            result = sendRequest(new KWPRequest(0x3E, 0x50), out reply2); // tester present???
            Console.WriteLine("reply on exit " + reply2.ToString());

            return result;
        }
Пример #6
0
 public bool ReadDTCCodes()
 {
     LogDataString("ReadDTCCodes");
     KWPReply reply = new KWPReply();
     KWPResult result;
     byte[] data = new byte[2];
     data[0] = (byte)0xFF;
     data[1] = (byte)0xFF;
     //data[2] = (byte)0x00;
     KWPRequest req = new KWPRequest(0x18, 0x02/*, data*/);
     //Console.WriteLine(req.ToString());
     result = sendRequest(req, out reply);
     //Console.WriteLine(reply.ToString());
     return true;
 }
Пример #7
0
 public bool ReadFreezeFrameData(uint frameNumber)
 {
     LogDataString("ReadFreezeFrameData");
     KWPReply reply = new KWPReply();
     KWPResult result;
     byte[] data = new byte[1];
     data[0] = (byte)0x00;
     //data[1] = (byte)0x00;
     //data[2] = (byte)0x00;
     KWPRequest req = new KWPRequest(0x12, Convert.ToByte(frameNumber), data);
     //Console.WriteLine(req.ToString());
     result = sendRequest(req, out reply);
     //Console.WriteLine(reply.ToString());
     return true;
 }
Пример #8
0
 public bool ClearDTCCode(int dtccode)
 {
     LogDataString("ClearDTCCode: " + dtccode.ToString("X4"));
     KWPReply reply = new KWPReply();
     KWPResult result;
     byte[] data = new byte[1];
     data[0] = (byte)(dtccode & 0x00FF);
     //data[1] = (byte)0xFF;
     //data[2] = (byte)0x00;
     KWPRequest req = new KWPRequest(0x14, (byte)(dtccode >> 8), data);
     //Console.WriteLine(req.ToString());
     result = sendRequest(req, out reply);
     //Console.WriteLine(reply.ToString());
     return true;
 }
Пример #9
0
        /// <summary>
        /// This method sends a KWPRequest and returns a KWPReply.
        /// </summary>
        /// <param name="a_request">The request.</param>
        /// <param name="a_reply">The reply.</param>
        /// <returns>KWPResult</returns>
        private KWPResult sendRequest(KWPRequest a_request, out KWPReply a_reply, int expectedLength)
        {
            int _maxSendRetries = 3;
            KWPResult _kwpResult = KWPResult.Timeout;
            LogDataString("sendRequest");

            KWPReply reply = new KWPReply();
            RequestResult result;
            a_reply = new KWPReply();
            //<GS-11012010> was allemaal 1000
            int keepAliveTimeout = 1000;
            //Console.WriteLine("Checking KWP device open");
            if (!m_kwpDevice.isOpen())
                return KWPResult.DeviceNotConnected;

            // reset the timer for keep alive (set to 1 seconds now)
            if (stateTimer == null)
                stateTimer = new System.Threading.Timer(sendKeepAlive, new Object(), keepAliveTimeout, keepAliveTimeout);
            stateTimer.Change(keepAliveTimeout, keepAliveTimeout);

            m_requestMutex.WaitOne();
            int _retryCount = 0;
            result = RequestResult.Unknown; // <GS-11022010>
            while (_retryCount < _maxSendRetries && result != RequestResult.NoError)
            {
                LogDataString(a_request.ToString());
                result = m_kwpDevice.sendRequest(a_request, out reply);
                if ((int)reply.getLength() != expectedLength)
                {
                    result = RequestResult.InvalidLength;

                }
                if (result == RequestResult.NoError)
                {
                    a_reply = reply;
                    LogDataString(reply.ToString());
                    LogDataString(""); // empty line
                    m_requestMutex.ReleaseMutex();
                    //return KWPResult.OK;
                    _kwpResult = KWPResult.OK;
                }
                else
                {
                    LogDataString("Timeout in KWPHandler::sendRequest");
                    m_requestMutex.ReleaseMutex();
                    //return KWPResult.Timeout;
                    _kwpResult = KWPResult.Timeout;
                }
            }
            return _kwpResult;
        }
Пример #10
0
        /// <summary>
        /// This method sends a KWPRequest and returns a KWPReply.
        /// </summary>
        /// <param name="a_request">The request.</param>
        /// <param name="a_reply">The reply.</param>
        /// <returns>KWPResult</returns>
        private KWPResult sendRequest(KWPRequest a_request, out KWPReply a_reply)
        {
            LogDataString("sendRequest");

            KWPReply reply = new KWPReply();
            RequestResult result;
            a_reply = new KWPReply();
            //<GS-11012010> was allemaal 1000
            int keepAliveTimeout = 1000;
            //Console.WriteLine("Checking KWP device open");
            if (!m_kwpDevice.isOpen())
                return KWPResult.DeviceNotConnected;

            // reset the timer for keep alive (set to 1 seconds now)
            if (stateTimer == null)
                stateTimer = new System.Threading.Timer(sendKeepAlive, new Object(), keepAliveTimeout, keepAliveTimeout);
            stateTimer.Change(keepAliveTimeout, keepAliveTimeout);

            m_requestMutex.WaitOne();

            LogDataString(a_request.ToString());
            Console.WriteLine("KWP send request: " + a_request.ToString());
            result = m_kwpDevice.sendRequest(a_request, out reply);
            a_reply = reply;
            if (result == RequestResult.NoError)
            {
                LogDataString(reply.ToString());
                LogDataString(""); // empty line

                m_requestMutex.ReleaseMutex();
                return KWPResult.OK;
            }
            else
            {
                LogDataString("Timeout in KWPHandler::sendRequest: " + result.ToString());
                Console.WriteLine("Timeout in KWPHandler::sendRequest: " + result.ToString());
                m_requestMutex.ReleaseMutex();
                return KWPResult.Timeout;
            }
        }
Пример #11
0
        /// <summary>
        /// Send a request for a sequrity access with one out of two methods to 
        /// calculate the key.
        /// </summary>
        /// <param name="a_method">Key calculation method [1,2]</param>
        /// <returns>true if sequrity access was granted, otherwise false</returns>
        private bool requestSequrityAccessLevel()
        {
            LogDataString("requestSequrityAccessLevel");
            KWPReply reply = new KWPReply();
            KWPResult result;
            byte[] seed = new byte[2];
            byte[] key = new byte[2];
            // Send a seed request.
            KWPRequest requestForKey = new KWPRequest(0x27, 0x05); // TODO: What is this for T8?
            Console.WriteLine("requestSequrityAccessLevel request for key: " + requestForKey.ToString());
            result = sendRequest(requestForKey, out reply);
            Console.WriteLine("requestSequrityAccessLevel request for key result: " + reply.ToString());

            if (result != KWPResult.OK)
                return false;
            if (reply.getData().Length < 2)
                return false;
            seed[0] = reply.getData()[0];
            seed[1] = reply.getData()[1];
            key = calculateKey(seed);
            // Send key reply.
            KWPRequest sendKeyRequest = new KWPRequest(0x27, 0x06, key);
            Console.WriteLine("requestSequrityAccessLevel send Key request: " + sendKeyRequest.ToString());
            result = sendRequest(sendKeyRequest, out reply);
            Console.WriteLine("requestSequrityAccessLevel send Key reply: " + reply.ToString());
            if (result != KWPResult.OK)
            {
                Console.WriteLine("Security access request was not send");
                return false;
            }

            //Check if sequrity was granted.
            Console.WriteLine("Mode: " + reply.getMode().ToString("X2"));
            Console.WriteLine("Data: " + reply.getData()[0].ToString("X2"));
            if ((reply.getMode() == 0x67) && (reply.getData()[0] == 0x34)) // WAS [0]
            {
                Console.WriteLine("Security access granted");
                return true;
            }

            Console.WriteLine("Security access was not granted: " + reply.ToString());
            return false;
        }
Пример #12
0
        /// <summary>
        /// This method sends a KWP request and returns a KWPReply. The method returns
        /// when a reply has been received, after a failure or after a timeout.
        /// The open and startSession methods must be called and returned possitive result
        /// before this method is used.
        /// </summary>
        /// <param name="a_request">The KWPRequest.</param>
        /// <param name="r_reply">The reply to the KWPRequest.</param>
        /// <returns>RequestResult.</returns>
        public RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply)
        {
            string sendString = "";
            string receiveString = "";
            for (int i = 1; i < a_request.getData().Length; i++)
                sendString += a_request.getData()[i].ToString("X") + " ";
            sendString += "\r";
            m_serialPort.Write(sendString);
            //receiveString = "49 01 01 00 00 00 31 \n\r49 02 02 44 34 47 50 \n\r49 02 03 30 30 52 35 \n\r49 02 04 25 42";// m_serialPort.ReadTo(">");
            receiveString = m_serialPort.ReadTo(">");
            char[] chrArray = receiveString.ToCharArray();
            byte[] reply = new byte[0xFF];
            int insertPos = 1;
            int index = 0;
            string subString = "";
            while(receiveString.Length > 4)
            {
                //Remove first three bytes

                //TODO. Remove Mode and PIDs
                for (int i = 0; i < 3; i++)
                {
                    index = receiveString.IndexOf(" ");
                    receiveString = receiveString.Remove(0, index + 1);
                }
                //Read data for the rest of the row.
                for (int i = 0; i < 4; i++)
                {
                    index = receiveString.IndexOf(" ");
                    if (index == 0) //Last row not 4 bytes of data.
                    {
                        continue;
                    }
                    subString = receiveString.Substring(0, index);
                    reply[insertPos] = (byte)Convert.ToInt16("0x"+subString, 16);
                    insertPos++;
                    receiveString = receiveString.Remove(0, index + 1);
                }

            }

            reply[0] = (byte)insertPos; //Length

            r_reply = new KWPReply(reply, a_request.getNrOfPID());
            return RequestResult.NoError;
        }