Пример #1
0
        private void QueryDTC()
        {
            GenericLoader loader = new GenericLoader();

            loader.Text = "Querying DTCs";
            loader.Show();
            Application.DoEvents();

            // fetch the base dtc value first
            DTCContexts = Connection.ConnectionProtocol.ReportDtcsByStatusMask(Connection, Variant);
            loader.SetProgressMax(DTCContexts.Count);
            Application.DoEvents();

            // query individual dtcs to retrieve the environment context
            for (int j = 0; j < DTCContexts.Count; j++)
            {
                DTCContext dtcCtx = DTCContexts[j];
                loader.Text = $"Querying DTC {dtcCtx.DTC.Qualifier} [{j + 1}/{DTCContexts.Count}]";
                loader.SetProgressValue(j);
                Application.DoEvents();

                if (!Connection.ConnectionProtocol.GetDtcSnapshot(dtcCtx.DTC, Connection, out byte[] snapshot))
Пример #2
0
        private void StartDownload()
        {
            int sumBytesTransferred = 0;
            int sumBytes            = 0;

            foreach (FlashBlock block in FlashBlocks)
            {
                sumBytes += block.Payload.Length;
            }

            GenericLoader loader = new GenericLoader();

            loader.Text    = "Reading from ECU";
            loader.TopMost = true;
            loader.Show();
            Application.DoEvents();

            foreach (FlashBlock block in FlashBlocks)
            {
                byte[] startDownloadCmd = CreateDownloadRequest(block.Address, (uint)block.Payload.Length);

                byte[] response = connection.SendMessage(startDownloadCmd); // comment this, uncomment below if dryrun
                //byte[] response = BitUtility.BytesFromHex("74 20 00 03");
                if (response.Length < 2)
                {
                    MessageBox.Show($"Error: ECU sent an incorrectly sized response when initiating download for block {Path.GetFileNameWithoutExtension(block.Path)}");
                    break;
                }
                if (response[0] != startDownloadCmd[0] + 0x40)
                {
                    MessageBox.Show($"Error: ECU sent a non-positive response ({BitUtility.BytesToHex(response)}) for block {Path.GetFileNameWithoutExtension(block.Path)}");
                    break;
                }
                // read alfid to know memory size description's width
                byte rxAlfid = response[1];
                // we are only expecting a size value
                if ((rxAlfid & 0xF) > 0)
                {
                    MessageBox.Show($"Error: Could not understand ECU ALFID response ({BitUtility.BytesToHex(response)}) for block {Path.GetFileNameWithoutExtension(block.Path)}");
                    break;
                }
                // find out how wide the memory size description is
                int         memSize  = rxAlfid >> 4;
                List <byte> memBytes = response.Skip(2).Take(memSize).ToList();
                if (memBytes.Count != memSize)
                {
                    MessageBox.Show($"Error: Could not understand ECU ALFID response (size mismatch) ({BitUtility.BytesToHex(response)}) for block {Path.GetFileNameWithoutExtension(block.Path)}");
                    break;
                }
                // parse the memory size desc as a BE integer
                uint messageSize = 0;
                for (int i = 0; i < memBytes.Count; i++)
                {
                    messageSize <<= 8;
                    messageSize  |= memBytes[i];
                }
                // debug: uncomment to cap msg size at 0x100, normally 0xF02, blocksize = 0xF00
                // messageSize = 0x102;
                int blockSize       = (int)messageSize - 2;
                int totalBlockCount = (int)(block.Payload.Length / blockSize);
                int remainderBytes  = block.Payload.Length % blockSize;
                if (remainderBytes != 0)
                {
                    totalBlockCount++;
                }

                // reconfigure connection for block transfer
                connection.TesterPresentTimer.Enabled = false;
                RaiseSTMin();

                byte[] dataBlock = new byte[messageSize];

                loader.SetProgressMax(totalBlockCount);

                for (int blockCounter = 0; blockCounter < totalBlockCount; blockCounter++)
                {
                    dataBlock[0] = 0x36;
                    dataBlock[1] = (byte)((blockCounter + 1) & 0xFF);

                    // if this is the last block, and there is a remainder block, write only the remainder
                    if (((blockCounter + 1) == totalBlockCount) && (remainderBytes != 0))
                    {
                        Array.ConstrainedCopy(block.Payload, blockCounter * blockSize, dataBlock, 2, remainderBytes);
                        dataBlock = dataBlock.Take(2 + remainderBytes).ToArray();
                    }
                    else
                    {
                        Array.ConstrainedCopy(block.Payload, blockCounter * blockSize, dataBlock, 2, blockSize);
                    }

                    byte[] transferResponse = connection.SendMessage(dataBlock); // comment this, uncomment below if dryrun
                    //byte[] transferResponse = new byte[] { 0x76, 0x00 };
                    if ((transferResponse.Length > 0) && (transferResponse[0] == 0x76))
                    {
                        // no need to check block index, if the ecu accepts it, continue
                    }
                    else
                    {
                        MessageBox.Show($"Error: Data transfer rejected by ECU ({BitUtility.BytesToHex(transferResponse)}) for block {Path.GetFileNameWithoutExtension(block.Path)}");
                        break;
                    }

                    // update progress
                    sumBytesTransferred += dataBlock.Length - 2;
                    // loader.Text = $"Writing to ECU : 0x{sumBytesTransferred:X8} of 0x{sumBytes:X8}";
                    loader.Text = $"Writing to ECU : block {blockCounter} of 0x{totalBlockCount}";
                    loader.SetProgressValue(blockCounter);
                    Application.DoEvents();
                    // fixme: show two progressbars, one for the block# and another for the individual block's %
                }

                byte[] exitTransferResponse = connection.SendMessage(new byte[] { 0x37 });// ------------------ patch if debugging
                if (!((exitTransferResponse.Length > 0) && (exitTransferResponse[0] == 0x77)))
                {
                    MessageBox.Show($"Error: Exit transfer rejected by ECU ({BitUtility.BytesToHex(exitTransferResponse)}) for block {Path.GetFileNameWithoutExtension(block.Path)}");
                    break;
                }
            }

            // restore prior connection status
            connection.TesterPresentTimer.Enabled = true;
            ResetSTMin();

            loader.Close();
            MessageBox.Show("Download completed");
        }
Пример #3
0
        private void btnRead_Click(object sender, EventArgs e)
        {
            if (!FetchAndValidateInput(out uint sourceAddress, out uint destinationAddress, out uint bufferSize))
            {
                return;
            }

            int  strideWidth      = decimal.ToInt32(nudIOWidth.Value);
            int  addressWidth     = decimal.ToInt32(nudAddressWidth.Value);
            int  ioDigitCount     = GetMemoryDigitCount(strideWidth);
            byte readCmd          = decimal.ToByte(nudReadCmd.Value);
            byte positiveResponse = (byte)(readCmd + 0x40);

            byte alfid = GetAddressAndLengthFormatIdentifier(
                addressWidth,
                ioDigitCount
                );

            GenericLoader loader = new GenericLoader();

            loader.Text = "Reading from ECU";
            loader.SetProgressMax((int)(destinationAddress - sourceAddress));
            loader.SetProgressValue(0);
            loader.TopMost = true;
            loader.Show();
            Application.DoEvents();

            byte[] memoryBuffer = new byte[bufferSize];
            uint   readCursor   = sourceAddress;
            int    bufferCursor = 0;
            bool   hasBadReads  = false;

            while (readCursor < destinationAddress)
            {
                loader.Text = $"Reading from ECU : 0x{readCursor:X8}";
                loader.SetProgressValue((int)(readCursor - sourceAddress));
                Application.DoEvents();

                uint remainder = destinationAddress - readCursor;
                int  readSize  = strideWidth;
                if (readSize > remainder)
                {
                    readSize = (int)remainder;
                }
                List <byte> readCommand = CreateReadCommand(readCmd, alfid, readCursor, addressWidth, readSize);

                byte[] response = Connection.SendMessage(readCommand);
                if (response[0] == positiveResponse)
                {
                    Array.ConstrainedCopy(response, 1, memoryBuffer, bufferCursor, readSize);
                }
                else
                {
                    hasBadReads = true;
                }

                readCursor   += (uint)readSize;
                bufferCursor += readSize;
            }

            loader.Close();
            Application.DoEvents();

            OriginalBuffer = memoryBuffer;

            Hexbox.LineInfoOffset = sourceAddress;
            Hexbox.ByteProvider   = new DynamicByteProvider(OriginalBuffer);

            if (hasBadReads)
            {
                MessageBox.Show("One or more read requests were rejected by the ECU, and the empty blocks were substituted with zeros. \r\n\r\n" +
                                "Please check if the memory address is valid to the ECU, and if the ECU has been unlocked if required.\r\n\r\n" +
                                "If the memory region has protected bytes, consider loading a smaller, more specific range with a I/O width of 1 to skip past the protected bytes.",
                                "Warning: Invalid reads");
            }
        }