示例#1
0
        /// <summary>
        /// This method send a request for reading from ECU memory (both RAM and flash).
        /// It sets up start address and the length to read.
        /// </summary>
        /// <param name="a_address">The address to start reading from.</param>
        /// <param name="a_length">The total length to read.</param>
        /// <returns>true on success, otherwise false</returns>
        public bool sendReadRequest(uint a_address, uint a_length)
        {
            LogDataString("sendReadRequest");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            byte[] lengthAndAddress = new byte[5];
            //set length (byte 0 and 1)
            lengthAndAddress[0] = (byte)(a_length >> 8);
            lengthAndAddress[1] = (byte)(a_length);
            //set address (byte 2 to 4);
            lengthAndAddress[2] = (byte)(a_address >> 16);
            lengthAndAddress[3] = (byte)(a_address >> 8);
            lengthAndAddress[4] = (byte)(a_address);
            result = sendRequest(new KWPRequest(0x2C, 0xF0, 0x03, lengthAndAddress), out reply);
            if (result == KWPResult.OK)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#2
0
        private UInt16 getUint16(KWPReply a_reply)
        {
            UInt16 uinteger;

            uinteger = (UInt16)((a_reply.getData()[1] << 8) | (a_reply.getData()[0]));
            return(uinteger);
        }
示例#3
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);
        }
示例#4
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(uint a_method)
        {
            LogDataString("requestSequrityAccessLevel: " + a_method.ToString());
            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);

            Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() + " request for key: " + requestForKey.ToString());
            result = sendRequest(requestForKey, out reply);
            Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() + " 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];
            if (a_method == 1)
            {
                key = calculateKey(seed, 0);
            }
            else
            {
                key = calculateKey(seed, 1);
            }
            // Send key reply.
            KWPRequest sendKeyRequest = new KWPRequest(0x27, 0x06, key);

            Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() + " send Key request: " + sendKeyRequest.ToString());
            result = sendRequest(sendKeyRequest, out reply);
            Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() + " 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: " + a_method.ToString());
                return(true);
            }

            Console.WriteLine("Security access was not granted: " + reply.ToString());
            return(false);
        }
示例#5
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(0x240, 0, 8);
            uint       row = nrOfRowsToSend(a_request.getData());

            // 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.waitForMessage(0x258, timeoutPeriod);
            // Receive one or several replys and send an ack for each reply.
            if (msg.getID() == 0x258)
            {
                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--;
                while (nrOfRows > 0)
                {
                    msg = m_kwpCanListener.waitForMessage(0x258, timeoutPeriod);
                    if (msg.getID() == 0x258)
                    {
                        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);
            }
        }
示例#6
0
        /// <summary>
        /// This method sends a request for the software part number.
        /// </summary>
        /// <param name="r_swPartNo">The requested sofware part number.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getSwPartNumber(out string r_swPartNo)
        {
            LogDataString("getSwPartNumber");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            result     = sendRequest(new KWPRequest(0x1A, 0x94), out reply);
            r_swPartNo = getString(reply);
            return(result);
        }
示例#7
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 writeSymbolRequest(uint a_symbolNumber, byte[] a_data)
        {
            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"));
            Console.WriteLine("Resulttotal = " + reply.ToString());
            if (reply.getData()[0] == 0x7D)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#8
0
        /// <summary>
        /// Helper method for transforming the information in a KWPReply to a string.
        /// </summary>
        /// <param name="a_reply">The KWPReply.</param>
        /// <returns>A string representing the information in the a_reply.</returns>
        private string getString(KWPReply a_reply)
        {
            if (a_reply.getData().Length == 0)
            {
                return("");
            }
            Encoding ascii = Encoding.ASCII;

            ascii.GetChars(a_reply.getData(), 0, a_reply.getData().Length);
            return(ascii.GetString(a_reply.getData(), 0, a_reply.getData().Length));
        }
示例#9
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);
            }
        }
示例#10
0
        /// <summary>
        /// This method sends a request for the engine type description.
        /// </summary>
        /// <param name="r_swVersion">The requested engine type description.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getEngineType(out string r_swVersion)
        {
            LogDataString("getEngineType");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            r_swVersion = "";
            result      = sendRequest(new KWPRequest(0x1A, 0x97), out reply);
            if (result != KWPResult.OK)
            {
                return(result);
            }
            r_swVersion = getString(reply);
            return(result);
        }
示例#11
0
        /// <summary>
        /// This method sends a request for the software version using diagnostic routine 0x51.
        /// </summary>
        /// <param name="r_swVersion">The requested software version.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getSwVersionFromDR51(out string r_swVersion)
        {
            LogDataString("getSwVersionFromDR51");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            r_swVersion = "";
            result      = sendRequest(new KWPRequest(0x31, 0x51), out reply);
            if (result != KWPResult.OK)
            {
                return(result);
            }
            r_swVersion = getString(reply);
            return(result);
        }
示例#12
0
        /// <summary>
        /// This method sends a request to get the offset of the symbol table.
        /// </summary>
        /// <param name="r_immo">Start address of the symbol table.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getSymbolTableOffset(out UInt16 r_offset)
        {
            LogDataString("getSymbolTableOffset");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            r_offset = 0;
            result   = sendRequest(new KWPRequest(0x1A, 0x9B), out reply);
            if (result != KWPResult.OK)
            {
                return(result);
            }
            r_offset = getUint16(reply);
            return(result);
        }
示例#13
0
        /// <summary>
        /// This method sends a request for the immobilizer ID.
        /// </summary>
        /// <param name="r_immo">The requested immo ID.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getImmo(out string r_immo)
        {
            LogDataString("getImmo");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            r_immo = "";
            result = sendRequest(new KWPRequest(0x1A, 0x92), out reply);
            if (result != KWPResult.OK)
            {
                return(result);
            }
            r_immo = getString(reply);
            return(result);
        }
示例#14
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());

            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);
            }
        }
示例#15
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);
        }
示例#16
0
        /// <summary>
        /// This method sends a request to exit data transfer exit. It should be called when a
        /// read session has been finished.
        /// </summary>
        /// <returns>true on success, otherwise false.</returns>
        public bool sendDataTransferExitRequest()
        {
            LogDataString("sendDataTransferExitRequest");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            result = sendRequest(new KWPRequest(0x82, 0x00), out reply);
            if (result == KWPResult.OK)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#17
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);
        }
示例#18
0
        public bool ClearDTCCodes()
        {
            LogDataString("ClearDTCCodes");
            KWPReply  reply = new KWPReply();
            KWPResult result;

            byte[] data = new byte[1];
            data[0] = (byte)0xFF;
            //data[1] = (byte)0xFF;
            //data[2] = (byte)0x00;
            KWPRequest req = new KWPRequest(0x14, 0xFF, data);

            Console.WriteLine(req.ToString());
            result = sendRequest(req, out reply);
            Console.WriteLine(reply.ToString());
            return(true);
        }
示例#19
0
        /// <summary>
        /// This method send a request to receive data from flash. The sendReadRequest
        /// method must be called before this.
        /// </summary>
        /// <param name="r_data">The requested data.</param>
        /// <returns></returns>
        public bool sendRequestDataByOffset(out byte[] r_data)
        {
            LogDataString("sendRequestDataByOffset");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            result = sendRequest(new KWPRequest(0x21, 0xF0), out reply);
            r_data = reply.getData();
            if (result == KWPResult.OK)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#20
0
        /// <summary>
        /// This method sends a request for the VIN (Vehicle ID Number).
        /// </summary>
        /// <param name="r_vin">The requested VIN.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getVIN(out string r_vin)
        {
            LogDataString("getVIN");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            result = sendRequest(new KWPRequest(0x1A, 0x90), out reply);
            if (result == KWPResult.OK)
            {
                r_vin = getString(reply);
                return(KWPResult.OK);
            }
            else
            {
                r_vin = "";
                return(KWPResult.Timeout);
            }
        }
示例#21
0
        /// <summary>
        /// This method send a request for reading a symbol.
        /// </summary>
        /// <param name="a_address">The symbol number to read [0..0xFFFF-1].</param>
        /// <returns></returns>
        public bool setSymbolRequest(uint a_symbolNumber)
        {
            LogDataString("setSymbolRequest");

            KWPReply  reply  = new KWPReply();
            KWPResult result = KWPResult.Timeout;

            byte[] symbolNumber = new byte[5];
            //First two bytes should be zero
            symbolNumber[0] = 0;
            symbolNumber[1] = 0;
            symbolNumber[2] = 0x80;
            //set symbol number (byte 2 to 3);
            symbolNumber[3] = (byte)(a_symbolNumber >> 8);
            symbolNumber[4] = (byte)(a_symbolNumber);
            //<GS-11022010>
            // check result .. it should be 2 bytes long
            int _retryCount = 0;

            while (_retryCount++ < 3 && result != KWPResult.OK)
            {
                //result = sendRequest(new KWPRequest(0x2C, 0xF0, 0x03, symbolNumber), out reply);
                result = sendRequest(new KWPRequest(0x2C, 0xF0, 0x03, symbolNumber), out reply /*, 2*/);
                if (reply.getLength() != 2)
                {
                    result = KWPResult.Timeout;
                    LogDataString("Got wrong response on sendRequest in setSymbolRequest, len = " + reply.getLength().ToString("D2"));
                    Console.WriteLine("Got wrong response on sendRequest in setSymbolRequest, len = " + reply.getLength().ToString("D2"));
                }
            }
            if (result == KWPResult.OK)
            {
                return(true);
            }
            else
            {
                LogDataString("setSymbolRequest timed out");
                Console.WriteLine("setSymbolRequest timed out");
                return(false);
            }
        }
示例#22
0
        /// <summary>
        /// Send unknown request
        /// </summary>
        /// <returns>KWPResult</returns>
        public KWPResult sendUnknownRequest()
        {
            LogDataString("sendUnknownRequest");
            //Console.WriteLine("sendUnknownRequest");
            KWPReply  reply = new KWPReply();
            KWPResult result;

            //Send request
            //Mode = 0x3E
            //PID = no PID used by this request
            //Expected result = 0x7E
            result = sendRequest(new KWPRequest(0x3E), out reply);
            if (reply.getMode() != 0x7E)
            {
                return(KWPResult.NOK);
            }
            else
            {
                return(result);
            }
        }
示例#23
0
        /// <summary>
        /// This method send a request to download the symbol map.
        /// After this request has been made data can be fetched with a data transfer request
        /// </summary>
        /// <param name="a_data">The data to be written.</param>
        /// <returns>KWPResult</returns>
        public KWPResult sendReadSymbolMapRequest()
        {
            LogDataString("sendReadSymbolMapRequest");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            //Send request
            //Mode = 0x31
            //PID = 0x50
            //Data = data to be flashed
            //Expected result = 0x71
            result = sendRequest(new KWPRequest(0x31, 0x50), out reply);
            if (reply.getMode() != 0x71)
            {
                return(KWPResult.NOK);
            }
            else
            {
                return(result);
            }
        }
示例#24
0
        /// <summary>
        /// This method send data to be written to flash. sendWriteRequest must be called before this method.
        /// </summary>
        /// <param name="a_data">The data to be written.</param>
        /// <returns>KWPResult</returns>
        public KWPResult sendWriteDataRequest(byte[] a_data)
        {
            LogDataString("sendWriteDataRequest");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            //Send request
            //Mode = 0x36
            //PID = no PID used by this request
            //Data = data to be flashed
            //Expected result = 0x76
            result = sendRequest(new KWPRequest(0x36, a_data), out reply);
            if (reply.getMode() != 0x76)
            {
                return(KWPResult.NOK);
            }
            else
            {
                return(result);
            }
        }
示例#25
0
        /// <summary>
        /// This method sets up the address and length for writing to flash. It must be called before
        /// the sendWriteDataRequest method is called.
        /// </summary>
        /// <param name="a_address">The addres to start writing to.</param>
        /// <param name="a_length">The length to write</param>
        /// <returns>KWPResult</returns>
        public KWPResult sendWriteRequest(uint a_address, uint a_length)
        {
            LogDataString("sendWriteRequest");

            KWPReply  reply = new KWPReply();
            KWPResult result;

            byte[] addressAndLength = new byte[7];
            //set address (byte 0 to 2)
            addressAndLength[0] = (byte)(a_address >> 16);
            addressAndLength[1] = (byte)(a_address >> 8);
            addressAndLength[2] = (byte)(a_address);
            //set length (byte 3 to 6);
            addressAndLength[3] = (byte)(a_length >> 24);
            addressAndLength[4] = (byte)(a_length >> 16);
            addressAndLength[5] = (byte)(a_length >> 8);
            addressAndLength[6] = (byte)(a_length);

            //Send request
            //Mode = 0x34
            //PID = no PID used by this request
            //Data = aaallll (aaa = address, llll = length)
            //Expected result = 0x74
            result = sendRequest(new KWPRequest(0x34, addressAndLength), out reply);
            if (result != KWPResult.OK)
            {
                return(result);
            }
            if (reply.getMode() != 0x74)
            {
                return(KWPResult.NOK);
            }
            else
            {
                return(result);
            }
        }
示例#26
0
        /// <summary>
        /// This method requests data to be transmitted.
        /// </summary>
        /// <param name="a_data">The data to be transmitted.</param>
        /// <returns>KWPResult</returns>
        public KWPResult sendDataTransferRequest(out byte[] a_data)
        {
            LogDataString("sendDataTransferRequest");

            KWPReply  reply = new KWPReply();
            KWPResult result;


            //Send request
            //Mode = 0x36
            //PID = no PID used by this request
            //Data = no data
            //Expected result = 0x76
            result = sendRequest(new KWPRequest(0x36), out reply);
            a_data = reply.getData();
            if (reply.getMode() != 0x76)
            {
                return(KWPResult.NOK);
            }
            else
            {
                return(result);
            }
        }
示例#27
0
 private UInt16 getUint16(KWPReply a_reply)
 {
     UInt16 uinteger;
     uinteger = (UInt16)((a_reply.getData()[1] << 8) | (a_reply.getData()[0]));
     return uinteger;
 }
示例#28
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;
            }
        }
示例#29
0
        /// <summary>
        /// This method send a request for reading a symbol. 
        /// </summary>
        /// <param name="a_address">The symbol number to read [0..0xFFFF-1].</param>
        /// <returns></returns>
        public bool setSymbolRequest(uint a_symbolNumber)
        {
            LogDataString("setSymbolRequest");

            KWPReply reply = new KWPReply();
            KWPResult result = KWPResult.Timeout;
            byte[] symbolNumber = new byte[5];
            //First two bytes should be zero
            symbolNumber[0] = 0;
            symbolNumber[1] = 0;
            symbolNumber[2] = 0x80;
            //set symbol number (byte 2 to 3);
            symbolNumber[3] = (byte)(a_symbolNumber >> 8);
            symbolNumber[4] = (byte)(a_symbolNumber);
            //<GS-11022010>
            // check result .. it should be 2 bytes long
            int _retryCount = 0;
            while (_retryCount++ < 3 && result != KWPResult.OK)
            {
                //result = sendRequest(new KWPRequest(0x2C, 0xF0, 0x03, symbolNumber), out reply);
                result = sendRequest(new KWPRequest(0x2C, 0xF0, 0x03, symbolNumber), out reply/*, 2*/);
                if (reply.getLength() != 2)
                {
                    result = KWPResult.Timeout;
                    LogDataString("Got wrong response on sendRequest in setSymbolRequest, len = " + reply.getLength().ToString("D2"));
                    Console.WriteLine("Got wrong response on sendRequest in setSymbolRequest, len = " + reply.getLength().ToString("D2"));
                }
            }
            if (result == KWPResult.OK)
            {
                return true;
            }
            else
            {
                LogDataString("setSymbolRequest timed out");
                Console.WriteLine("setSymbolRequest timed out");
                return false;
            }
        }
示例#30
0
        /// <summary>
        /// This method send data to be written to flash. sendWriteRequest must be called before this method.
        /// </summary>
        /// <param name="a_data">The data to be written.</param>
        /// <returns>KWPResult</returns>
        public KWPResult sendWriteDataRequest(byte[] a_data)
        {
            LogDataString("sendWriteDataRequest");

            KWPReply reply = new KWPReply();
            KWPResult result;

            //Send request
            //Mode = 0x36
            //PID = no PID used by this request
            //Data = data to be flashed
            //Expected result = 0x76
            result = sendRequest(new KWPRequest(0x36, a_data), out reply);
            if (reply.getMode() != 0x76)
                return KWPResult.NOK;
            else
                return result;
        }
示例#31
0
        /// <summary>
        /// This method send a request to receive data from flash. The sendReadRequest
        /// method must be called before this.
        /// </summary>
        /// <param name="r_data">The requested data.</param>
        /// <returns></returns>
        public bool sendRequestDataByOffset(out byte[] r_data)
        {
            LogDataString("sendRequestDataByOffset");

            KWPReply reply = new KWPReply();
            KWPResult result;
            result = sendRequest(new KWPRequest(0x21, 0xF0), out reply);
            r_data = reply.getData();
            if (result == KWPResult.OK)
                return true;
            else
                return false;
        }
示例#32
0
        /// <summary>
        /// This method send a request for reading from ECU memory (both RAM and flash). 
        /// It sets up start address and the length to read.
        /// </summary>
        /// <param name="a_address">The address to start reading from.</param>
        /// <param name="a_length">The total length to read.</param>
        /// <returns>true on success, otherwise false</returns>
        public bool sendReadRequest(uint a_address, uint a_length)
        {
            LogDataString("sendReadRequest");

            KWPReply reply = new KWPReply();
            KWPResult result;
            byte[] lengthAndAddress = new byte[5];
            //set length (byte 0 and 1)
            lengthAndAddress[0] = (byte)(a_length >> 8);
            lengthAndAddress[1] = (byte)(a_length);
            //set address (byte 2 to 4);
            lengthAndAddress[2] = (byte)(a_address >> 16);
            lengthAndAddress[3] = (byte)(a_address >> 8);
            lengthAndAddress[4] = (byte)(a_address);
            result = sendRequest(new KWPRequest(0x2C, 0xF0, 0x03, lengthAndAddress), out reply);
            if (result == KWPResult.OK)
                return true;
            else
                return false;
        }
示例#33
0
        /// <summary>
        /// This method requests data to be transmitted.
        /// </summary>
        /// <param name="a_data">The data to be transmitted.</param>
        /// <returns>KWPResult</returns>
        public KWPResult sendDataTransferRequest(out byte[] a_data)
        {
            LogDataString("sendDataTransferRequest");

            KWPReply reply = new KWPReply();
            KWPResult result;

            //Send request
            //Mode = 0x36
            //PID = no PID used by this request
            //Data = no data
            //Expected result = 0x76
            result = sendRequest(new KWPRequest(0x36), out reply);
            a_data = reply.getData();
            if (reply.getMode() != 0x76)
                return KWPResult.NOK;
            else
                return result;
        }
示例#34
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;
 }
示例#35
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());

            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;
            }
        }
示例#36
0
        /// <summary>
        /// sendEraseRequest sends an erase request to the ECU.
        /// This method must be called before the ECU can be flashed.
        /// </summary>
        /// <returns>KWPResult</returns>
        public KWPResult sendEraseRequest()
        {
            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 = 0x52
            //Expected result is 0x71
            result = sendRequest(new KWPRequest(0x31, 0x52), out reply);
            Console.WriteLine("Erase(1) " + reply.ToString());
            if (result != KWPResult.OK)
            {
                return(result);
            }
            while (reply.getMode() != 0x71)
            {
                System.Threading.Thread.Sleep(1000);
                result = sendRequest(new KWPRequest(0x31, 0x52), out reply);
                Console.WriteLine("Erase(2:" + i.ToString() + ") " + reply.ToString());
                if (i++ > 15)
                {
                    return(KWPResult.Timeout);
                }
            }
            if (result != KWPResult.OK)
            {
                return(result);
            }

            //Second erase message. Up to 10 retries.
            //Mode = 0x31
            //PID = 0x53
            //Expected result is 0x71
            i      = 0;
            result = sendRequest(new KWPRequest(0x31, 0x53), out reply2);
            Console.WriteLine("Erase(3) " + reply2.ToString());
            if (result != KWPResult.OK)
            {
                return(result);
            }
            while (reply2.getMode() != 0x71)
            {
                System.Threading.Thread.Sleep(1000);
                result = sendRequest(new KWPRequest(0x31, 0x53), out reply2);
                Console.WriteLine("Erase(4:" + i.ToString() + ") " + reply2.ToString());
                if (i++ > 20)
                {
                    return(KWPResult.Timeout);
                }
            }

            //Erase confirm message
            //Mode = 0x3E
            //Expected result is 0x7E
            result = sendRequest(new KWPRequest(0x3E, 0x53), out reply2);
            Console.WriteLine("Erase(5) " + reply2.ToString());

            return(result);
        }
示例#37
0
        /// <summary>
        /// This method sends a request to exit data transfer exit. It should be called when a 
        /// read session has been finished.
        /// </summary>
        /// <returns>true on success, otherwise false.</returns>
        public bool sendDataTransferExitRequest()
        {
            LogDataString("sendDataTransferExitRequest");

            KWPReply reply = new KWPReply();
            KWPResult result;
            result = sendRequest(new KWPRequest(0x82, 0x00), out reply);
            if (result == KWPResult.OK)
                return true;
            else
                return false;
        }
示例#38
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;
 }
示例#39
0
        /// <summary>
        /// sendEraseRequest sends an erase request to the ECU.
        /// This method must be called before the ECU can be flashed.
        /// </summary>
        /// <returns>KWPResult</returns>
        public KWPResult sendEraseRequest()
        {
            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 = 0x52
            //Expected result is 0x71
            result = sendRequest(new KWPRequest(0x31, 0x52), out reply);
            Console.WriteLine("Erase(1) " + reply.ToString());
            if (result != KWPResult.OK)
                return result;
            while (reply.getMode() != 0x71)
            {
                System.Threading.Thread.Sleep(1000);
                result = sendRequest(new KWPRequest(0x31, 0x52), out reply);
                Console.WriteLine("Erase(2:" + i.ToString() + ") " + reply.ToString());
                if (i++ > 15) return KWPResult.Timeout;
            }
            if (result != KWPResult.OK)
                return result;

            //Second erase message. Up to 10 retries.
            //Mode = 0x31
            //PID = 0x53
            //Expected result is 0x71
            i = 0;
            result = sendRequest(new KWPRequest(0x31, 0x53), out reply2);
            Console.WriteLine("Erase(3) " + reply2.ToString());
            if (result != KWPResult.OK)
                return result;
            while (reply2.getMode() != 0x71)
            {
                System.Threading.Thread.Sleep(1000);
                result = sendRequest(new KWPRequest(0x31, 0x53), out reply2);
                Console.WriteLine("Erase(4:" + i.ToString() + ") " + reply2.ToString());
                if (i++ > 20) return KWPResult.Timeout;
            }

            //Erase confirm message
            //Mode = 0x3E
            //Expected result is 0x7E
            result = sendRequest(new KWPRequest(0x3E, 0x53), out reply2);
            Console.WriteLine("Erase(5) " + reply2.ToString());

            return result;
        }
示例#40
0
        /// <summary>
        /// This method sends a request for the engine type description.
        /// </summary>
        /// <param name="r_swVersion">The requested engine type description.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getEngineType(out string r_swVersion)
        {
            LogDataString("getEngineType");

            KWPReply reply = new KWPReply();
            KWPResult result;
            r_swVersion = "";
            result = sendRequest(new KWPRequest(0x1A, 0x97), out reply);
            if (result != KWPResult.OK)
                return result;
            r_swVersion = getString(reply);
            return result;
        }
示例#41
0
        /// <summary>
        /// This method send a request to download the symbol map.
        /// After this request has been made data can be fetched with a data transfer request
        /// </summary>
        /// <param name="a_data">The data to be written.</param>
        /// <returns>KWPResult</returns>
        public KWPResult sendReadSymbolMapRequest()
        {
            LogDataString("sendReadSymbolMapRequest");

            KWPReply reply = new KWPReply();
            KWPResult result;

            //Send request
            //Mode = 0x31
            //PID = 0x50
            //Data = data to be flashed
            //Expected result = 0x71
            result = sendRequest(new KWPRequest(0x31, 0x50), out reply);
            if (reply.getMode() != 0x71)
                return KWPResult.NOK;
            else
                return result;
        }
示例#42
0
        /// <summary>
        /// This method sends a request for the immobilizer ID.
        /// </summary>
        /// <param name="r_immo">The requested immo ID.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getImmo(out string r_immo)
        {
            LogDataString("getImmo");

            KWPReply reply = new KWPReply();
            KWPResult result;
            r_immo = "";
            result = sendRequest(new KWPRequest(0x1A, 0x92), out reply);
            if (result != KWPResult.OK)
                return result;
            r_immo = getString(reply);
            return result;
        }
示例#43
0
        /// <summary>
        /// Send unknown request
        /// </summary>
        /// <returns>KWPResult</returns>
        public KWPResult sendUnknownRequest()
        {
            LogDataString("sendUnknownRequest");
            //Console.WriteLine("sendUnknownRequest");
            KWPReply reply = new KWPReply();
            KWPResult result;

            //Send request
            //Mode = 0x3E
            //PID = no PID used by this request
            //Expected result = 0x7E
            result = sendRequest(new KWPRequest(0x3E), out reply);
            if (reply.getMode() != 0x7E)
                return KWPResult.NOK;
            else
                return result;
        }
示例#44
0
        /// <summary>
        /// This method sends a request for the software part number.
        /// </summary>
        /// <param name="r_swPartNo">The requested sofware part number.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getSwPartNumber(out string r_swPartNo)
        {
            LogDataString("getSwPartNumber");

            KWPReply reply = new KWPReply();
            KWPResult result;
            result = sendRequest(new KWPRequest(0x1A, 0x94), out reply);
            r_swPartNo = getString(reply);
            return result;
        }
示例#45
0
        /// <summary>
        /// This method sets up the address and length for writing to flash. It must be called before
        /// the sendWriteDataRequest method is called.
        /// </summary>
        /// <param name="a_address">The addres to start writing to.</param>
        /// <param name="a_length">The length to write</param>
        /// <returns>KWPResult</returns>
        public KWPResult sendWriteRequest(uint a_address, uint a_length)
        {
            LogDataString("sendWriteRequest");

            KWPReply reply = new KWPReply();
            KWPResult result;
            byte[] addressAndLength = new byte[7];
            //set address (byte 0 to 2)
            addressAndLength[0] = (byte)(a_address >> 16);
            addressAndLength[1] = (byte)(a_address >> 8);
            addressAndLength[2] = (byte)(a_address);
            //set length (byte 3 to 6);
            addressAndLength[3] = (byte)(a_length >> 24);
            addressAndLength[4] = (byte)(a_length >> 16);
            addressAndLength[5] = (byte)(a_length >> 8);
            addressAndLength[6] = (byte)(a_length);

            //Send request
            //Mode = 0x34
            //PID = no PID used by this request
            //Data = aaallll (aaa = address, llll = length)
            //Expected result = 0x74
            result = sendRequest(new KWPRequest(0x34, addressAndLength), out reply);
            if (result != KWPResult.OK)
                return result;
            if (reply.getMode() != 0x74)
                return KWPResult.NOK;
            else
                return result;
        }
示例#46
0
        /// <summary>
        /// This method sends a request for the software version using diagnostic routine 0x51.
        /// </summary>
        /// <param name="r_swVersion">The requested software version.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getSwVersionFromDR51(out string r_swVersion)
        {
            LogDataString("getSwVersionFromDR51");

            KWPReply reply = new KWPReply();
            KWPResult result;
            r_swVersion = "";
            result = sendRequest(new KWPRequest(0x31, 0x51), out reply);
            if (result != KWPResult.OK)
                return result;
            r_swVersion = getString(reply);
            return result;
        }
示例#47
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;
            }
        }
示例#48
0
        /// <summary>
        /// This method sends a request to get the offset of the symbol table.
        /// </summary>
        /// <param name="r_immo">Start address of the symbol table.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getSymbolTableOffset(out UInt16 r_offset)
        {
            LogDataString("getSymbolTableOffset");

            KWPReply reply = new KWPReply();
            KWPResult result;
            r_offset = 0;
            result = sendRequest(new KWPRequest(0x1A, 0x9B), out reply);
            if (result != KWPResult.OK)
                return result;
            r_offset = getUint16(reply);
            return result;
        }
示例#49
0
 /// <summary>
 /// Helper method for transforming the information in a KWPReply to a string.
 /// </summary>
 /// <param name="a_reply">The KWPReply.</param>
 /// <returns>A string representing the information in the a_reply.</returns>
 private string getString(KWPReply a_reply)
 {
     if (a_reply.getData().Length == 0)
         return "";
     Encoding ascii = Encoding.ASCII;
     ascii.GetChars(a_reply.getData(), 0, a_reply.getData().Length);
     return ascii.GetString(a_reply.getData(), 0, a_reply.getData().Length);
 }
示例#50
0
        /// <summary>
        /// This method sends a request for the VIN (Vehicle ID Number).
        /// </summary>
        /// <param name="r_vin">The requested VIN.</param>
        /// <returns>KWPResult</returns>
        public KWPResult getVIN(out string r_vin)
        {
            LogDataString("getVIN");

            KWPReply reply = new KWPReply();
            KWPResult result;
            result = sendRequest(new KWPRequest(0x1A,0x90), out reply);
            if (result == KWPResult.OK)
            {
                r_vin = getString(reply);
                return KWPResult.OK;
            }
            else
            {
                r_vin = "";
                return KWPResult.Timeout;
            }
        }
示例#51
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(uint a_method)
        {
            LogDataString("requestSequrityAccessLevel: " + a_method.ToString());
            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);
            Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() +  " request for key: " + requestForKey.ToString());
            result = sendRequest(requestForKey, out reply);
            Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() + " 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];
            if (a_method == 1)
                key = calculateKey(seed, 0);
            else
                key = calculateKey(seed, 1);
            // Send key reply.
            KWPRequest sendKeyRequest = new KWPRequest(0x27, 0x06, key);
            Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() +  " send Key request: " + sendKeyRequest.ToString());
            result = sendRequest(sendKeyRequest, out reply);
            Console.WriteLine("requestSequrityAccessLevel " + a_method.ToString() + " 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: " + a_method.ToString());
                return true;
            }

            Console.WriteLine("Security access was not granted: " + reply.ToString());
            return false;
        }
示例#52
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;
 }
示例#53
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(0x240, 0, 8);
            uint row = nrOfRowsToSend(a_request.getData());
            // 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.waitForMessage(0x258, timeoutPeriod);
            // Receive one or several replys and send an ack for each reply.
            if (msg.getID() == 0x258)
            {
                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--;
                while (nrOfRows > 0)
                {
                    msg = m_kwpCanListener.waitForMessage(0x258, timeoutPeriod);
                    if (msg.getID() == 0x258)
                    {
                        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;
            }
        }
示例#54
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;
        }