<commit_before>﻿namespace x360NANDManager.SPI {
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Threading;
    using LibUsbDotNet;
    using LibUsbDotNet.Info;
    using LibUsbDotNet.Main;

    internal class ARMFlasher: FlasherOutput, ISPIFlasher, IDisposable {
        #region Private Data Fields

        protected bool AbortRequested;
        protected UsbDevice Device;
        protected UsbConfigInfo DeviceConfigInfo;
        private bool _flashInitialized;
        private int _productID;
        private UsbEndpointReader _reader;
        private int _vendorID;
        private UsbEndpointWriter _writer;
        private XConfig _xcfg;

        #endregion Private Data Fields

        public ARMFlasher(int vendorID, int productID) {
            if(DeviceInit(vendorID, productID))
                return;
            Release();
            throw new X360NANDManagerException(X360NANDManagerException.ErrorLevels.NoDeviceFound);
        }

        /// <summary>
        ///     Arm Version reported by the device
        /// </summary>
        protected uint ArmVersion { get; private set; }

        #region IDisposable Members

        /// <summary>
        ///     Release the USB Device
        /// </summary>
        public void Dispose() {
            GC.SuppressFinalize(this);
            Release();
        }

        #endregion

        #region Private methods

        private void UsbDeviceOnUsbErrorEvent(object sender, UsbError usbError) {
            Main.SendDebug(String.Format("A USB Error Occured: {0}", usbError));
            if(Device == null || !Device.IsOpen)
                throw new X360NANDManagerException(X360NANDManagerException.ErrorLevels.DeviceCrashed);
        }

        protected void CheckDeviceState() {
            if(Device == null || !Device.IsOpen)
                throw new X360NANDManagerException(X360NANDManagerException.ErrorLevels.DeviceNotInitialized);
        }

        private void CheckFlashState() {
            CheckDeviceState();
            if(!_flashInitialized)
                throw new X360NANDManagerException(X360NANDManagerException.ErrorLevels.FlashNotInitialized);
        }

        protected void SendCMD(Commands cmd, uint argA = 0, uint argB = 0) {
            CheckDeviceState();
            Main.SendDebug(String.Format("Sending CMD: {0} (0x{0:X}) 0x{1:X08} 0x{2:X08}", cmd, argA, argB));
            var buf = BitConverter.GetBytes(argA);
            var tmp = BitConverter.GetBytes(argB);
            Array.Resize(ref buf, buf.Length + tmp.Length);
            Array.Copy(tmp, 0, buf, buf.Length - tmp.Length, tmp.Length);
            var packet = new UsbSetupPacket((byte)UsbRequestType.TypeVendor, (byte)cmd, 0, 0, 0);
            int sent;
            Device.ControlTransfer(ref packet, buf, buf.Length, out sent);
        }

        private bool DeviceInit(int vendorID, int productID, bool deviceReset = true) {
            try {
                _vendorID = vendorID;
                _productID = productID;
                Device = UsbDevice.OpenUsbDevice(new UsbDeviceFinder(vendorID, productID));
                if(Device == null) {
                    Main.SendDebug(string.Format("No Device Found with VendorID: 0x{0:X04} and ProductID: 0x{1:X04}", vendorID, productID));
                    Release();
                    return false;
                }
                if(deviceReset) {
                    Release();
                    Thread.Sleep(1000);
                    return DeviceInit(vendorID, productID, false);
                }
                DeviceConfigInfo = Device.Configs[0];
                var wholeUsbDevice = Device as IUsbDevice;
                if(!ReferenceEquals(wholeUsbDevice, null)) {
                    wholeUsbDevice.SetConfiguration(DeviceConfigInfo.Descriptor.ConfigID);
                    wholeUsbDevice.ClaimInterface(0);
                }
                _reader = Device.OpenEndpointReader((ReadEndpointID)0x82);
                ClearReadBuffer();
                _writer = Device.OpenEndpointWriter((WriteEndpointID)0x05);
                UsbDevice.UsbErrorEvent += UsbDeviceOnUsbErrorEvent;
                return true;
            }
            catch(Exception ex) {
                Main.SendDebug(String.Format("Device Init exception occured: {0}", ex.Message));
                throw;
            }
        }

        private void DeviceReset() {
            var wholeUsbDevice = Device as IUsbDevice;
            if(ReferenceEquals(wholeUsbDevice, null))
                return;
            wholeUsbDevice.ReleaseInterface(0);
            wholeUsbDevice.ResetDevice();
            Main.SendDebug("Device Successfully reset!");
        }

        private ErrorCode ReadFromDevice(ref byte[] buf, int tries = 10) {
            // ReSharper disable RedundantAssignment
            var maxtries = tries;
            // ReSharper restore RedundantAssignment
            var totalread = 0;
            var err = ErrorCode.None;
            Main.SendDebug(string.Format("Reading 0x{0:X} Bytes from device", buf.Length));
            while(totalread < buf.Length && tries > 0) {
                int read;
                if(totalread > 0) {
                    var tmp = new byte[buf.Length - totalread];
                    err = _reader.Read(tmp, 1000, out read);
                    if(read < buf.Length)
                        Buffer.BlockCopy(tmp, 0, buf, totalread, tmp.Length);
                }
                else
                    err = _reader.Read(buf, 1000, out read);
                if(err != ErrorCode.None && err != ErrorCode.IoTimedOut)
                    Main.SendDebug(String.Format("Error: {0}", err));
                if(read == buf.Length)
                    break;
                totalread += read;
                tries--;
                Main.SendDebug(string.Format("Read 0x{0:X} Attempt: {1} Total read data: 0x{2:X}", read, Math.Abs(tries - maxtries), totalread));
            }
            return tries > 0 ? ErrorCode.Success : err;
        }

        protected ErrorCode WriteToDevice(byte[] buf, int tries = 10) {
            if(buf == null)
                throw new ArgumentNullException("buf");
            Main.SendDebug(string.Format("Writing 0x{0:X} Bytes to device", buf.Length));
#if DEBUG
            Main.SendDebug(string.Format("Data: \n{0}", ArrayToHex(buf)));
#endif
            var totalwrote = 0;
            var err = ErrorCode.None;
            while(totalwrote < buf.Length && tries > 0) {
                int wrote;
                if(totalwrote > 0) {
                    var tmp = new byte[buf.Length - totalwrote];
                    Buffer.BlockCopy(buf, buf.Length - tmp.Length, tmp, 0, tmp.Length);
                    err = _writer.Write(tmp, 1000, out wrote);
                }
                else
                    err = _writer.Write(buf, 1000, out wrote);
                if(err != ErrorCode.None && err != ErrorCode.IoTimedOut)
                    Main.SendDebug(String.Format("Error: {0}", err));
                totalwrote += wrote;
                tries--;
                Main.SendDebug(string.Format("Wrote 0x{0:X} Attempt: {1} Total written data: 0x{2:X}", wrote, Math.Abs(tries - 10), totalwrote));
            }
            return tries > 0 ? ErrorCode.Success : err;
        }

        private uint GetARMStatus(Commands cmd) {
            CheckDeviceState();
            SendCMD(cmd);
            return GetARMStatus();
        }

        protected uint GetARMStatus() {
            CheckDeviceState();
            return ReadUInt32();
        }

        private uint ReadUInt32() {
            CheckDeviceState();
            var buf = new byte[4];
            var err = ReadFromDevice(ref buf);
            var val = BitConverter.ToUInt32(buf, 0);
            if(err != ErrorCode.None) {
                Main.SendDebug(String.Format("ReadUInt32 Failed! Error: {0} Value read: {1}", err, val));<commit_msg>Increase timeout for read/write operations<commit_after>﻿namespace x360NANDManager.SPI {
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Threading;
    using LibUsbDotNet;
    using LibUsbDotNet.Info;
    using LibUsbDotNet.Main;

    internal class ARMFlasher: FlasherOutput, ISPIFlasher, IDisposable {
        #region Private Data Fields

        protected bool AbortRequested;
        protected UsbDevice Device;
        protected UsbConfigInfo DeviceConfigInfo;
        private bool _flashInitialized;
        private int _productID;
        private UsbEndpointReader _reader;
        private int _vendorID;
        private UsbEndpointWriter _writer;
        private XConfig _xcfg;

        #endregion Private Data Fields

        public ARMFlasher(int vendorID, int productID) {
            if(DeviceInit(vendorID, productID))
                return;
            Release();
            throw new X360NANDManagerException(X360NANDManagerException.ErrorLevels.NoDeviceFound);
        }

        /// <summary>
        ///     Arm Version reported by the device
        /// </summary>
        protected uint ArmVersion { get; private set; }

        #region IDisposable Members

        /// <summary>
        ///     Release the USB Device
        /// </summary>
        public void Dispose() {
            GC.SuppressFinalize(this);
            Release();
        }

        #endregion

        #region Private methods

        private void UsbDeviceOnUsbErrorEvent(object sender, UsbError usbError) {
            Main.SendDebug(String.Format("A USB Error Occured: {0}", usbError));
            if(Device == null || !Device.IsOpen)
                throw new X360NANDManagerException(X360NANDManagerException.ErrorLevels.DeviceCrashed);
        }

        protected void CheckDeviceState() {
            if(Device == null || !Device.IsOpen)
                throw new X360NANDManagerException(X360NANDManagerException.ErrorLevels.DeviceNotInitialized);
        }

        private void CheckFlashState() {
            CheckDeviceState();
            if(!_flashInitialized)
                throw new X360NANDManagerException(X360NANDManagerException.ErrorLevels.FlashNotInitialized);
        }

        protected void SendCMD(Commands cmd, uint argA = 0, uint argB = 0) {
            CheckDeviceState();
            Main.SendDebug(String.Format("Sending CMD: {0} (0x{0:X}) 0x{1:X08} 0x{2:X08}", cmd, argA, argB));
            var buf = BitConverter.GetBytes(argA);
            var tmp = BitConverter.GetBytes(argB);
            Array.Resize(ref buf, buf.Length + tmp.Length);
            Array.Copy(tmp, 0, buf, buf.Length - tmp.Length, tmp.Length);
            var packet = new UsbSetupPacket((byte)UsbRequestType.TypeVendor, (byte)cmd, 0, 0, 0);
            int sent;
            Device.ControlTransfer(ref packet, buf, buf.Length, out sent);
        }

        private bool DeviceInit(int vendorID, int productID, bool deviceReset = true) {
            try {
                _vendorID = vendorID;
                _productID = productID;
                Device = UsbDevice.OpenUsbDevice(new UsbDeviceFinder(vendorID, productID));
                if(Device == null) {
                    Main.SendDebug(string.Format("No Device Found with VendorID: 0x{0:X04} and ProductID: 0x{1:X04}", vendorID, productID));
                    Release();
                    return false;
                }
                if(deviceReset) {
                    Release();
                    Thread.Sleep(1000);
                    return DeviceInit(vendorID, productID, false);
                }
                DeviceConfigInfo = Device.Configs[0];
                var wholeUsbDevice = Device as IUsbDevice;
                if(!ReferenceEquals(wholeUsbDevice, null)) {
                    wholeUsbDevice.SetConfiguration(DeviceConfigInfo.Descriptor.ConfigID);
                    wholeUsbDevice.ClaimInterface(0);
                }
                _reader = Device.OpenEndpointReader((ReadEndpointID)0x82);
                ClearReadBuffer();
                _writer = Device.OpenEndpointWriter((WriteEndpointID)0x05);
                UsbDevice.UsbErrorEvent += UsbDeviceOnUsbErrorEvent;
                return true;
            }
            catch(Exception ex) {
                Main.SendDebug(String.Format("Device Init exception occured: {0}", ex.Message));
                throw;
            }
        }

        private void DeviceReset() {
            var wholeUsbDevice = Device as IUsbDevice;
            if(ReferenceEquals(wholeUsbDevice, null))
                return;
            wholeUsbDevice.ReleaseInterface(0);
            wholeUsbDevice.ResetDevice();
            Main.SendDebug("Device Successfully reset!");
        }

        private ErrorCode ReadFromDevice(ref byte[] buf, int tries = 10) {
            // ReSharper disable RedundantAssignment
            var maxtries = tries;
            // ReSharper restore RedundantAssignment
            var totalread = 0;
            var err = ErrorCode.None;
            Main.SendDebug(string.Format("Reading 0x{0:X} Bytes from device", buf.Length));
            while(totalread < buf.Length && tries > 0) {
                int read;
                if(totalread > 0) {
                    var tmp = new byte[buf.Length - totalread];
                    err = _reader.Read(tmp, 2000, out read);
                    if(read < buf.Length)
                        Buffer.BlockCopy(tmp, 0, buf, totalread, tmp.Length);
                }
                else
                    err = _reader.Read(buf, 2000, out read);
                if(err != ErrorCode.None && err != ErrorCode.IoTimedOut)
                    Main.SendDebug(String.Format("Error: {0}", err));
                if(read == buf.Length)
                    break;
                totalread += read;
                tries--;
                Main.SendDebug(string.Format("Read 0x{0:X} Attempt: {1} Total read data: 0x{2:X}", read, Math.Abs(tries - maxtries), totalread));
            }
            return tries > 0 ? ErrorCode.Success : err;
        }

        protected ErrorCode WriteToDevice(byte[] buf, int tries = 10) {
            if(buf == null)
                throw new ArgumentNullException("buf");
            Main.SendDebug(string.Format("Writing 0x{0:X} Bytes to device", buf.Length));
#if DEBUG
            Main.SendDebug(string.Format("Data: \n{0}", ArrayToHex(buf)));
#endif
            var totalwrote = 0;
            var err = ErrorCode.None;
            while(totalwrote < buf.Length && tries > 0) {
                int wrote;
                if(totalwrote > 0) {
                    var tmp = new byte[buf.Length - totalwrote];
                    Buffer.BlockCopy(buf, buf.Length - tmp.Length, tmp, 0, tmp.Length);
                    err = _writer.Write(tmp, 2000, out wrote);
                }
                else
                    err = _writer.Write(buf, 2000, out wrote);
                if(err != ErrorCode.None && err != ErrorCode.IoTimedOut)
                    Main.SendDebug(String.Format("Error: {0}", err));
                totalwrote += wrote;
                tries--;
                Main.SendDebug(string.Format("Wrote 0x{0:X} Attempt: {1} Total written data: 0x{2:X}", wrote, Math.Abs(tries - 10), totalwrote));
            }
            return tries > 0 ? ErrorCode.Success : err;
        }

        private uint GetARMStatus(Commands cmd) {
            CheckDeviceState();
            SendCMD(cmd);
            return GetARMStatus();
        }

        protected uint GetARMStatus() {
            CheckDeviceState();
            return ReadUInt32();
        }

        private uint ReadUInt32() {
            CheckDeviceState();
            var buf = new byte[4];
            var err = ReadFromDevice(ref buf);
            var val = BitConverter.ToUInt32(buf, 0);
            if(err != ErrorCode.None) {
                Main.SendDebug(String.Format("ReadUInt32 Failed! Error: {0} Value read: {1}", err, val));
{'fraction_non_alphanumeric': 0.09820591360880165, 'fraction_numerical': 0.01600300056260549, 'mean_word_length': 1.7431412894375857, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5319069', 'n_tokens_mistral': 4485, 'n_tokens_neox': 4141, 'n_words': 987}