using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using QCRPG.Framework;

namespace QCRPG.TSL.BT;

public class ConnectionUsbAtheros : ConnectionUsbBase
{
	private enum SendMode
	{
		COMMAND,
		ACL_DATA,
		SCO_DATA
	}

	private const uint IOCTL_CSRBC01_SEND_HCI_COMMAND = 2228226u;

	private const uint IOCTL_CSRBC01_GET_HCI_EVENT = 2228228u;

	private const uint IOCTL_CSRBC01_RESET_PIPE = 2228252u;

	private const uint IOCTL_CSRBC01_BLOCK_HCI_EVENT = 2228272u;

	private const uint IOCTL_CSRBC01_BLOCK_HCI_DATA = 2228276u;

	private const int MAX_HCI_EVENT_PACKET_LENGTH = 757;

	private const int MAX_ACL_PACKET_LENGTH = 66039;

	private Thread readEventDataThread;

	private bool readEventDataThreadStarted;

	private Thread readAclDataThread;

	private bool readAclDataThreadStarted;

	private NativeOverlapped osEventDataRead;

	private NativeOverlapped osAclDataRead;

	private NativeOverlapped osCommandDataWrite;

	private NativeOverlapped osAclDataWrite;

	private string deviceInfoPath = "";

	private IntPtr deviceHandle = new IntPtr(-1);

	private bool keepRunning;

	private PacketDataNotification lastOutgoingModeSwitchNotification;

	private SendMode sendMode;

	private bool enableAcl = true;

	public ConnectionUsbAtheros()
	{
	}

	public ConnectionUsbAtheros(UsbDeviceInfo deviceInfo)
	{
		deviceInfoPath = deviceInfo.path;
	}

	public override List<UsbDeviceInfo> FindDevices()
	{
		List<UsbDeviceInfo> list = new List<UsbDeviceInfo>();
		for (int i = 0; i < 64; i++)
		{
			string text = "\\\\.\\ATH" + i;
			IntPtr intPtr = ConnectionUsbBase.CreateFile(text, 3221225472u, FileShare.None, IntPtr.Zero, FileMode.Open, 128u, IntPtr.Zero);
			if (IsHandleValid(intPtr))
			{
				if (!ConnectionUsbBase.CloseHandle(intPtr))
				{
					throw new Exception($"CloseHandle failed for device {text} with error '{GetLastErrorMessage()}'");
				}
				list.Add(new UsbDeviceInfo(text, GetType(), "Qualcomm Atheros"));
			}
		}
		for (int j = 0; j < 64; j++)
		{
			string text2 = "\\\\.\\QCA" + j;
			IntPtr intPtr2 = ConnectionUsbBase.CreateFile(text2, 3221225472u, FileShare.None, IntPtr.Zero, FileMode.Open, 128u, IntPtr.Zero);
			if (IsHandleValid(intPtr2))
			{
				if (!ConnectionUsbBase.CloseHandle(intPtr2))
				{
					throw new Exception($"CloseHandle failed for device {text2} with error '{GetLastErrorMessage()}'");
				}
				list.Add(new UsbDeviceInfo(text2, GetType()));
			}
		}
		return list;
	}

	public override void Open(UsbDeviceInfo deviceInfo)
	{
		Open(deviceInfo, enableAcl: true);
	}

	public unsafe void Open(UsbDeviceInfo deviceInfo, bool enableAcl)
	{
		this.enableAcl = enableAcl;
		deviceInfoPath = deviceInfo.path;
		Close();
		deviceHandle = ConnectionUsbBase.CreateFile(deviceInfoPath, 3221225472u, FileShare.None, IntPtr.Zero, FileMode.Open, 1073741824u, IntPtr.Zero);
		if (!IsHandleValid(deviceHandle))
		{
			throw new Exception($"Handle creation failed for USB device {deviceInfoPath} with error '{GetLastErrorMessage()}'");
		}
		if (!ConnectionUsbBase.CancelIoEx(deviceHandle, IntPtr.Zero) && Marshal.GetLastWin32Error() != 1168)
		{
			throw new Exception($"Failed to cancel IO for USB device path {deviceInfoPath} with error '{GetLastErrorMessage()}'");
		}
		CreateEvent("EventDataRead", out osEventDataRead);
		CreateEvent("CommandDataWrite", out osCommandDataWrite);
		if (this.enableAcl)
		{
			CreateEvent("AclDataRead", out osAclDataRead);
			CreateEvent("AclDataWrite", out osAclDataWrite);
		}
		int num = default(int);
		int* ptr = &num;
		fixed (NativeOverlapped* ptr2 = &osEventDataRead)
		{
			if (!ConnectionUsbBase.DeviceIoControl(deviceHandle, 2228252u, IntPtr.Zero, 0, IntPtr.Zero, 0, ptr, ptr2))
			{
				if (Marshal.GetLastWin32Error() != 997)
				{
					string lastErrorMessage = GetLastErrorMessage();
					Close();
					throw new Exception($"Reset pipe failed for USB device {deviceInfoPath} with error '{lastErrorMessage}'");
				}
				if (!ConnectionUsbBase.GetOverlappedResult(deviceHandle, ptr2, ptr, bWait: true))
				{
					string lastErrorMessage2 = GetLastErrorMessage();
					Close();
					throw new Exception($"Event Data Read GetOverlappedResult failed for USB device path {deviceInfoPath} with error '{lastErrorMessage2}'");
				}
				if (!ConnectionUsbBase.ResetEvent(osEventDataRead.EventHandle))
				{
					string lastErrorMessage3 = GetLastErrorMessage();
					Close();
					throw new Exception($"Event Data Read ResetEvent failed for USB device path {deviceInfoPath} with error '{lastErrorMessage3}'");
				}
			}
		}
		if (enableAcl)
		{
			fixed (NativeOverlapped* ptr3 = &osAclDataRead)
			{
				if (!ConnectionUsbBase.DeviceIoControl(deviceHandle, 2228252u, IntPtr.Zero, 0, IntPtr.Zero, 0, ptr, ptr3))
				{
					if (Marshal.GetLastWin32Error() != 997)
					{
						string lastErrorMessage4 = GetLastErrorMessage();
						Close();
						throw new Exception($"Reset pipe failed for USB device {deviceInfoPath} with error '{lastErrorMessage4}'");
					}
					if (!ConnectionUsbBase.GetOverlappedResult(deviceHandle, ptr3, ptr, bWait: true))
					{
						string lastErrorMessage5 = GetLastErrorMessage();
						Close();
						throw new Exception($"Acl Data Read GetOverlappedResult failed for USB device path {deviceInfoPath} with error '{lastErrorMessage5}'");
					}
					if (!ConnectionUsbBase.ResetEvent(osAclDataRead.EventHandle))
					{
						string lastErrorMessage6 = GetLastErrorMessage();
						Close();
						throw new Exception($"Acl Data Read ResetEvent failed for USB device path {deviceInfoPath} with error '{lastErrorMessage6}'");
					}
				}
			}
		}
		SetupEventAsyncRead();
		keepRunning = false;
		if (readEventDataThread != null && readEventDataThread.ThreadState == ThreadState.Background)
		{
			readEventDataThread.Join();
			readEventDataThread = null;
		}
		if (readAclDataThread != null && readAclDataThread.ThreadState == ThreadState.Background)
		{
			readAclDataThread.Join();
			readAclDataThread = null;
		}
		keepRunning = true;
		readEventDataThread = new Thread(ReadEventDataThread);
		readEventDataThread.Name = "ConnectionUSBAthreos-Read Event Data";
		readEventDataThread.IsBackground = true;
		readEventDataThread.Start();
		readEventDataThreadStarted = true;
		if (enableAcl)
		{
			SetupAclAsyncRead();
			readAclDataThread = new Thread(ReadAclDataThread);
			readAclDataThread.Name = "ConnectionUSBAthreos-ACL Read Data";
			readAclDataThread.IsBackground = true;
			readAclDataThread.Start();
			readAclDataThreadStarted = true;
		}
		ConnectionStateChangeInfo connectionStateChangeInfo = new ConnectionStateChangeInfo();
		connectionStateChangeInfo.openStateChanged = true;
		connectionStateChangeInfo.openState = true;
		connectionStateChangeInfo.dataRate = 10000000;
		connectionStateChangeInfoNotifier.NotifyObservers(connectionStateChangeInfo);
	}

	private void CreateEvent(string eventName, out NativeOverlapped nativeOverlapped)
	{
		IntPtr intPtr = ConnectionUsbBase.CreateEvent(IntPtr.Zero, bManualReset: true, bInitialState: false, eventName);
		if (!IsHandleValid(intPtr))
		{
			throw new Exception($"{eventName} event creation failed for USB device {deviceInfoPath} with error '{GetLastErrorMessage()}'");
		}
		nativeOverlapped = new NativeOverlapped
		{
			EventHandle = intPtr
		};
	}

	private void InitializeOffsets(ref NativeOverlapped nativeOverlapped)
	{
		nativeOverlapped.InternalHigh = IntPtr.Zero;
		nativeOverlapped.InternalLow = IntPtr.Zero;
		nativeOverlapped.OffsetHigh = 0;
		nativeOverlapped.OffsetLow = 0;
	}

	public override void Close()
	{
		if (keepRunning)
		{
			keepRunning = false;
			if (readEventDataThreadStarted)
			{
				readEventDataThread.Join();
				readEventDataThreadStarted = false;
			}
			if (enableAcl && readAclDataThreadStarted)
			{
				readAclDataThread.Join();
				readAclDataThreadStarted = false;
			}
			if (osEventDataRead.EventHandle != IntPtr.Zero && !ConnectionUsbBase.CloseHandle(osEventDataRead.EventHandle))
			{
				throw new Exception($"Event Data Read CloseHandle failed for USB device path {deviceInfoPath} with error '{GetLastErrorMessage()}'");
			}
			if (osAclDataRead.EventHandle != IntPtr.Zero && !ConnectionUsbBase.CloseHandle(osAclDataRead.EventHandle))
			{
				throw new Exception($"Acl Data Read CloseHandle failed for USB device path {deviceInfoPath} with error '{GetLastErrorMessage()}'");
			}
			if (osCommandDataWrite.EventHandle != IntPtr.Zero && !ConnectionUsbBase.CloseHandle(osCommandDataWrite.EventHandle))
			{
				throw new Exception($"Command Data Write CloseHandle failed for USB device path {deviceInfoPath} with error '{GetLastErrorMessage()}'");
			}
			if (osAclDataWrite.EventHandle != IntPtr.Zero && !ConnectionUsbBase.CloseHandle(osAclDataWrite.EventHandle))
			{
				throw new Exception($"Acl Data Write CloseHandle failed for USB device path {deviceInfoPath} with error '{GetLastErrorMessage()}'");
			}
			if (IsHandleValid(deviceHandle) && !ConnectionUsbBase.CancelIoEx(deviceHandle, IntPtr.Zero) && Marshal.GetLastWin32Error() != 1168)
			{
				throw new Exception($"Failed to cancel IO for USB device path {deviceInfoPath} with error '{GetLastErrorMessage()}'");
			}
			if (IsHandleValid(deviceHandle) && !ConnectionUsbBase.CloseHandle(deviceHandle))
			{
				throw new Exception($"CloseHandle failed for USB device path {deviceInfoPath} with error '{GetLastErrorMessage()}'");
			}
			deviceHandle = InvalidHandle;
			ConnectionStateChangeInfo connectionStateChangeInfo = new ConnectionStateChangeInfo();
			connectionStateChangeInfo.openStateChanged = true;
			connectionStateChangeInfo.openState = false;
			connectionStateChangeInfoNotifier.NotifyObservers(connectionStateChangeInfo);
		}
	}

	public override bool IsOpen()
	{
		return keepRunning;
	}

	public override void Send(OutgoingPacketData packetData)
	{
		if (!keepRunning)
		{
			throw new Exception("The connection is closed");
		}
		if (packetData.type == PacketDataType.Data)
		{
			if (sendMode == SendMode.COMMAND)
			{
				SendCommandData(packetData);
				return;
			}
			if (sendMode != SendMode.ACL_DATA)
			{
				throw new Exception("Unsupported send mode: " + sendMode);
			}
			if (!enableAcl)
			{
				throw new Exception("ACL not enabled'");
			}
			SendAclData(packetData);
		}
		else
		{
			if (packetData.type != PacketDataType.Notification)
			{
				return;
			}
			if (packetData.bytes[0] == 5)
			{
				sendMode = SendMode.COMMAND;
			}
			else if (packetData.bytes[0] == 6)
			{
				if (!enableAcl)
				{
					throw new Exception("ACL not enabled'");
				}
				sendMode = SendMode.ACL_DATA;
			}
			else if (packetData.bytes[0] == 7)
			{
				sendMode = SendMode.SCO_DATA;
			}
			else if (packetData.bytes[0] != 11)
			{
				throw new Exception("Unsupported packet data notification: " + packetData.bytes[0]);
			}
		}
	}

	private unsafe void SendCommandData(OutgoingPacketData packetData)
	{
		byte[] bytes = packetData.bytes;
		int num = bytes.Length;
		fixed (NativeOverlapped* ptr2 = &osCommandDataWrite)
		{
			fixed (byte* inBuffer = bytes)
			{
				int num2 = default(int);
				int* ptr = &num2;
				if (!ConnectionUsbBase.DeviceIoControl(deviceHandle, 2228226u, inBuffer, num, IntPtr.Zero, 0, ptr, ptr2))
				{
					if (Marshal.GetLastWin32Error() != 997)
					{
						string lastErrorMessage = GetLastErrorMessage();
						Close();
						throw new Exception("Write error: " + lastErrorMessage);
					}
					if (!ConnectionUsbBase.GetOverlappedResult(deviceHandle, ptr2, ptr, bWait: true))
					{
						string lastErrorMessage2 = GetLastErrorMessage();
						Close();
						throw new Exception($"Wait operation failed while waiting to write data for USB device {deviceInfoPath} with error '{lastErrorMessage2}'");
					}
				}
				if (num != num2)
				{
					Close();
					throw new Exception($"Write length mismatch, expected {num} and wrote {num2}");
				}
				if (!ConnectionUsbBase.ResetEvent(osCommandDataWrite.EventHandle))
				{
					string lastErrorMessage3 = GetLastErrorMessage();
					Close();
					throw new Exception($"ResetEvent failed for USB device path {deviceInfoPath} with error '{lastErrorMessage3}'");
				}
			}
		}
	}

	private unsafe void SendAclData(OutgoingPacketData packetData)
	{
		int num = packetData.bytes.Length;
		int num2 = default(int);
		fixed (byte* bytes = packetData.bytes)
		{
			fixed (NativeOverlapped* lpOverlapped = &osAclDataWrite)
			{
				int* ptr = &num2;
				if (!ConnectionUsbBase.WriteFile(deviceHandle, bytes, num, ptr, lpOverlapped))
				{
					if (Marshal.GetLastWin32Error() != 997)
					{
						string lastErrorMessage = GetLastErrorMessage();
						Close();
						throw new Exception("Write error: " + lastErrorMessage);
					}
					if (!ConnectionUsbBase.GetOverlappedResult(deviceHandle, lpOverlapped, ptr, bWait: true))
					{
						string lastErrorMessage2 = GetLastErrorMessage();
						Close();
						throw new Exception($"Wait operation failed while waiting to write data for USB device {deviceInfoPath} with error '{lastErrorMessage2}'");
					}
				}
			}
		}
		if (num != num2)
		{
			Close();
			throw new Exception($"Write length mismatch, expected {num} and wrote {num2}");
		}
		if (!ConnectionUsbBase.ResetEvent(osAclDataWrite.EventHandle))
		{
			string lastErrorMessage3 = GetLastErrorMessage();
			Close();
			throw new Exception($"ResetEvent failed for USB device path {deviceInfoPath} with error '{lastErrorMessage3}'");
		}
	}

	private unsafe void SetupEventAsyncRead()
	{
		int num = default(int);
		int* ptr = &num;
		if (!ConnectionUsbBase.ResetEvent(osEventDataRead.EventHandle))
		{
			string lastErrorMessage = GetLastErrorMessage();
			Close();
			receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error '" + lastErrorMessage + "' in SetupEventAsyncRead()"));
		}
		fixed (NativeOverlapped* ptr2 = &osEventDataRead)
		{
			if (ConnectionUsbBase.DeviceIoControl(deviceHandle, 2228272u, IntPtr.Zero, 0, IntPtr.Zero, 0, ptr, ptr2))
			{
				return;
			}
			int lastWin32Error = Marshal.GetLastWin32Error();
			if (lastWin32Error == 997)
			{
				InitializeOffsets(ref osEventDataRead);
				if (!ConnectionUsbBase.GetOverlappedResult(deviceHandle, ptr2, ptr, bWait: true))
				{
					lastWin32Error = Marshal.GetLastWin32Error();
					receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error code 0x" + lastWin32Error.ToString("X") + " in SetupEventAsyncRead() when getting overlapped result"));
					Close();
				}
			}
			else
			{
				receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error code 0x" + lastWin32Error.ToString("X") + " in SetupEventAsyncRead()"));
				Close();
			}
		}
	}

	private unsafe void ReadEventDataThread()
	{
		byte[] array = new byte[757];
		while (keepRunning)
		{
			switch (ConnectionUsbBase.WaitForSingleObject(osEventDataRead.EventHandle, 10))
			{
			case uint.MaxValue:
			{
				int lastWin32Error = Marshal.GetLastWin32Error();
				receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error code 0x" + lastWin32Error.ToString("X") + " in ReadEventDataThread() waiting for event handle"));
				return;
			}
			case 258u:
				continue;
			}
			fixed (NativeOverlapped* ptr2 = &osEventDataRead)
			{
				fixed (byte* outBuffer = array)
				{
					int bytesRead = 0;
					int* ptr = &bytesRead;
					if (!ConnectionUsbBase.DeviceIoControl(deviceHandle, 2228228u, IntPtr.Zero, 0, outBuffer, 757, ptr, ptr2))
					{
						int lastWin32Error2 = Marshal.GetLastWin32Error();
						if (lastWin32Error2 != 997)
						{
							receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error code 0x" + lastWin32Error2.ToString("X") + " in ReadEventDataThread() on DeviceIoControl()"));
							return;
						}
						if (!ConnectionUsbBase.GetOverlappedResult(deviceHandle, ptr2, ptr, bWait: true))
						{
							lastWin32Error2 = Marshal.GetLastWin32Error();
							receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error code 0x" + lastWin32Error2.ToString("X") + " in ReadEventDataThread() on GetOverlappedResult()"));
							return;
						}
						ProcessReadEventBytes(array, bytesRead);
					}
					else
					{
						ProcessReadEventBytes(array, bytesRead);
					}
				}
			}
			SetupEventAsyncRead();
		}
	}

	private void ProcessReadEventBytes(byte[] bytes, int bytesRead)
	{
		if (bytesRead == 0)
		{
			return;
		}
		byte[] array = new byte[bytesRead];
		Array.Copy(bytes, 0, array, 0, bytesRead);
		if (!ConnectionUsbBase.ResetEvent(osEventDataRead.EventHandle))
		{
			string lastErrorMessage = GetLastErrorMessage();
			Close();
			receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, $"ResetEvent failed for USB device path {deviceInfoPath} with error '{lastErrorMessage}'"));
		}
		lock (receiveDataNotifier)
		{
			if (enableReceiveModeSwitchNotifications && lastOutgoingModeSwitchNotification != PacketDataNotification.SwitchToReceiveModeA)
			{
				lastOutgoingModeSwitchNotification = PacketDataNotification.SwitchToReceiveModeA;
				IncomingPacketData arg = new IncomingPacketData(PacketDataType.Notification, new byte[1] { (byte)lastOutgoingModeSwitchNotification });
				receiveDataNotifier.NotifyObservers(arg);
			}
			receiveDataNotifier.NotifyObservers(new IncomingPacketData(array));
		}
	}

	private unsafe void SetupAclAsyncRead()
	{
		int num = default(int);
		int* ptr = &num;
		if (!ConnectionUsbBase.ResetEvent(osAclDataRead.EventHandle))
		{
			string lastErrorMessage = GetLastErrorMessage();
			Close();
			receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, $"Acl Data Read ResetEvent failed for USB device path {deviceInfoPath} with error '{lastErrorMessage}'"));
		}
		fixed (NativeOverlapped* ptr2 = &osAclDataRead)
		{
			if (ConnectionUsbBase.DeviceIoControl(deviceHandle, 2228276u, IntPtr.Zero, 0, IntPtr.Zero, 0, ptr, ptr2))
			{
				return;
			}
			int lastWin32Error = Marshal.GetLastWin32Error();
			if (lastWin32Error == 997)
			{
				InitializeOffsets(ref osAclDataRead);
				if (!ConnectionUsbBase.GetOverlappedResult(deviceHandle, ptr2, ptr, bWait: true))
				{
					lastWin32Error = Marshal.GetLastWin32Error();
					receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error code 0x" + lastWin32Error.ToString("X") + " in SetupAclAsyncRead() in GetOverlappedResult()"));
					Close();
				}
			}
			else
			{
				receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error code 0x" + lastWin32Error.ToString("X") + " in SetupAclAsyncRead()"));
				Close();
			}
		}
	}

	private unsafe void ReadAclDataThread()
	{
		byte[] array = new byte[66039];
		int bytesRead = default(int);
		while (keepRunning)
		{
			switch (ConnectionUsbBase.WaitForSingleObject(osAclDataRead.EventHandle, 10))
			{
			case uint.MaxValue:
			{
				int lastWin32Error = Marshal.GetLastWin32Error();
				receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error code 0x" + lastWin32Error.ToString("X") + " in ReadAclDataThread() waiting for event handle"));
				return;
			}
			case 258u:
				continue;
			}
			fixed (byte* bytes = array)
			{
				fixed (NativeOverlapped* ptr2 = &osAclDataRead)
				{
					int* ptr = &bytesRead;
					if (!ConnectionUsbBase.ReadFile(deviceHandle, bytes, 66039, ptr, ptr2))
					{
						int lastWin32Error2 = Marshal.GetLastWin32Error();
						if (lastWin32Error2 != 997)
						{
							receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error code 0x" + lastWin32Error2.ToString("X") + " in ReadAclDataThread() on DeviceIoControl()"));
							return;
						}
						if (!ConnectionUsbBase.GetOverlappedResult(deviceHandle, ptr2, ptr, bWait: true))
						{
							lastWin32Error2 = Marshal.GetLastWin32Error();
							receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, "Got error code 0x" + lastWin32Error2.ToString("X") + " in ReadAclDataThread() on GetOverlappedResult()"));
							return;
						}
						ProcessReadAclBytes(array, bytesRead);
					}
					else
					{
						ProcessReadAclBytes(array, bytesRead);
					}
				}
			}
			SetupAclAsyncRead();
		}
	}

	private void ProcessReadAclBytes(byte[] readDataBuffer, int bytesRead)
	{
		if (bytesRead == 0)
		{
			return;
		}
		if (!ConnectionUsbBase.ResetEvent(osAclDataRead.EventHandle))
		{
			string lastErrorMessage = GetLastErrorMessage();
			Close();
			receiveDataNotifier.NotifyObservers(new IncomingPacketData(PacketDataType.WarningMessage, $"ResetEvent failed for USB device path {deviceInfoPath} with error '{lastErrorMessage}'"));
		}
		lock (receiveDataNotifier)
		{
			if (enableReceiveModeSwitchNotifications && lastOutgoingModeSwitchNotification != PacketDataNotification.SwitchToReceiveModeB)
			{
				lastOutgoingModeSwitchNotification = PacketDataNotification.SwitchToReceiveModeB;
				IncomingPacketData arg = new IncomingPacketData(PacketDataType.Notification, new byte[1] { (byte)lastOutgoingModeSwitchNotification });
				receiveDataNotifier.NotifyObservers(arg);
			}
			receiveDataNotifier.NotifyObservers(new IncomingPacketData(readDataBuffer, bytesRead));
		}
	}

	private string GetLastErrorMessage()
	{
		return new Win32Exception(Marshal.GetLastWin32Error()).Message;
	}

	public override bool Equals(object obj)
	{
		if (!(obj is ConnectionUsbAtheros connectionUsbAtheros))
		{
			return false;
		}
		if (!base.Equals((ConnectionUsbAtheros)obj))
		{
			return deviceInfoPath == connectionUsbAtheros.deviceInfoPath;
		}
		return true;
	}

	public override int GetHashCode()
	{
		return deviceInfoPath.GetHashCode();
	}
}
