using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Threading;
using QCRPG.Framework;
using QCRPG.TSL.BT.Packets;

namespace QCRPG.TSL.BT;

public class BTMainWorkerThread : WorkerThreadBase
{
	public delegate void GetStatsEventHandler(object sender, List<PacketBase> packet);

	public delegate void ErrorEventHandler(object sender);

	public delegate void RxBurstSetHandler(object sender, bool btimer);

	private const uint InvalidPasskey = 1000000u;

	private ManualResetEvent writeNvmEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent patchFirmwareEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent prodTest_TxBurstEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent prodTest_SlaveEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent prodTest_MasterEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent prodTest_TXContinuousEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent prodTest_RxBurstEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent hciResetEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent prodTest_GetRxStatsEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent ACLDataPacketTransferViaFileEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent dataTransferStartEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent startupCommandsEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent startupCommandsLEOnlyEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent bdAddressAndVersionEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent bdAddressEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent localSupportedFeaturesEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent readAllBufferSizesEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent scriptEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent ACLDataFileTransferEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent remoteDataTransferStopEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent sendRawBytesEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent extendedInquiryResponseEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent authenticationAndEncryptionEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent sendPasskeyEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent holdModeActivityEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent setDecodePacketEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent setAclLogModeEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent hostBringupEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent leProdTest_TranmitterTestEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent leProdTest_EnhancedTranmitterTestEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent leProdTest_ReceiverTestEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent leProdTest_EnhancedReceiverTestEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent leProdTest_LETestEndEvent = new ManualResetEvent(initialState: false);

	private ManualResetEvent leProdTest_ContinuousTxTestEvent = new ManualResetEvent(initialState: false);

	private BTAPI btAPI;

	private string nvmFilename;

	private string patchFilename;

	private bool skipNVMResponseChecks;

	private bool skipPatchResponseChecks;

	private ProtocolHCI.SleepModeState bringupSleepMode;

	private bool convertNvmToBin;

	private byte[] sendRawBytes;

	private byte[] prodTest_bluetoothAddress;

	private int[] prodTest_channel;

	private int prodTest_packetType;

	private int prodTest_payloadLength;

	private byte prodTest_lTAddress;

	private byte prodTest_powerLevel;

	private bool prodTest_whitening;

	private bool prodTest_hoppingMode;

	private int prodTest_connectionChannel;

	private int prodTest_transmitPattern;

	private int prodTest_continuouspower;

	private int prodTest_continuouschannel;

	private int prodTest_tranmitType;

	private byte prodTest_patternlength;

	private long prodTest_pattern;

	private uint leProdTest_LeTx_Channel;

	private uint leProdTest_LeTx_TestDataLength = 1u;

	private uint leProdTest_LeTx_PacketPayload;

	private uint leProdTest_LeEnhancedTx_TxChannel;

	private uint leProdTest_LeEnhancedTx_TestDataLength = 1u;

	private uint leProdTest_LeEnhancedTx_PacketPayload;

	private uint leProdTest_LeEnhancedTx_Phy;

	private uint leProdTest_LeRx_Channel;

	private uint leProdTest_LeEnhancedRx_RxChannel;

	private uint leProdTest_LeEnhancedRx_Phy;

	private uint leProdTest_LeEnhancedRx_ModulationIndex;

	private uint leProdTest_ContinuousTxTest_ChannelNumber;

	private uint leProdTest_ContinuousTxTest_TransmitOutputPower;

	private uint leProdTest_ContinuousTxTest_TransmitType;

	private uint leProdTest_ContinuousTxTest_PatternLength = 1u;

	private uint leProdTest_ContinuousTxTest_BitPattern;

	private uint fecRequired;

	private byte[] extendedInquiryResponse;

	private uint authenticationEnable;

	private uint encryptionMode;

	private uint simplePairingMode;

	private uint simplePairingDebugMode;

	private uint secureConnectionsHostSupport;

	private ulong simplePairingBdAddr;

	private static uint passkey = 1000000u;

	private static EventWaitHandle passkeyAvailable = new EventWaitHandle(initialState: false, EventResetMode.ManualReset);

	private uint holdModeActivity = 7u;

	private int connectionhandler;

	private string scriptFileName;

	private string scriptFileLocation;

	private CombinedScripter combinedScripter;

	protected SupportedFeaturesEnumCollection localSupportedFeatures;

	protected int localACLPacketLength;

	protected int localSCOPacketLength;

	protected int localACLBufferSize;

	protected int localSCOBufferSize;

	protected int leLocalACLBufferSize;

	protected string localBDAddress;

	protected string localApplicationInfo;

	private bool decodePacket = true;

	private bool packetResponse = true;

	private bool conciseLog;

	private LocalHostDefaultOption btHostOptions;

	private WriteScanEnable.UserFieldsWrapper.ScanEnableEnum scanEnable;

	private string hostBringupPortName;

	private int hostBringupInitialDataRate;

	private int hostBringupFinalDataRate;

	private bool hostBringupSendWakeByte;

	private Handshake hostBringupInitialFlowControl;

	private Handshake hostBringupFinalFlowControl;

	private ProtocolHCI.SleepModeState hostBringupSleepMode;

	private bool hostBringupLoadNVMasBIN;

	private int eventTimeout = 2000;

	private readonly Dictionary<int, AclDataSender> connectionHandlerAclDataSenders = new Dictionary<int, AclDataSender>();

	private AclDataBufferHandler aclDataBufferHandler;

	private SpecificPacketNotifier specificPacketNotifier;

	public static uint Passkey
	{
		set
		{
			lock (passkeyAvailable)
			{
				passkey = value;
				passkeyAvailable.Set();
			}
		}
	}

	public int EventTimeout
	{
		get
		{
			return eventTimeout;
		}
		set
		{
			eventTimeout = value;
		}
	}

	public event GetStatsEventHandler GetRxStatsEventHandler;

	public event ErrorEventHandler ErrEventHandler;

	public event RxBurstSetHandler RxBurstModeReadyHandler;

	public event DataTransferTransmitHandler TransmitDataTransferHandler;

	public event FileTransferTransmitHandler TransmitFileTransferHandler;

	public event StartupCommandsEventHandler StartupEventHandler;

	public BTMainWorkerThread(Logger logger, BTAPI btAPI, SpecificPacketNotifier specificPacketNotifier)
		: base(logger)
	{
		this.btAPI = btAPI;
		this.specificPacketNotifier = specificPacketNotifier;
		aclDataBufferHandler = new AclDataBufferHandler(this.specificPacketNotifier, this.btAPI, shutdownThreadEvent);
	}

	public void ACLDataFileTransfer(int connectionHandler, string filename, bool isBTConnection)
	{
		connectionhandler = connectionHandler;
		AclDataSender aclDataSender = GetAclDataSender(connectionHandler, isBTConnection);
		aclDataSender.DataFileName = filename;
		ACLDataFileTransferEvent.Set();
	}

	public void ACLDataPacketTransferViaFile(int connectionHandler, string filename)
	{
		lock (connectionHandlerAclDataSenders)
		{
			connectionhandler = connectionHandler;
			if (!connectionHandlerAclDataSenders.ContainsKey(connectionhandler))
			{
				return;
			}
			connectionHandlerAclDataSenders[connectionHandler].DataFileName = filename;
		}
		ACLDataPacketTransferViaFileEvent.Set();
	}

	public void WriteNvm(string filename, bool skipResponseChecks, ProtocolHCI.SleepModeState sleepMode = ProtocolHCI.SleepModeState.NONE, bool convertNvmToBin = false)
	{
		nvmFilename = filename;
		skipNVMResponseChecks = skipResponseChecks;
		bringupSleepMode = sleepMode;
		this.convertNvmToBin = convertNvmToBin;
		writeNvmEvent.Set();
	}

	public void WriteNvm(string filename, bool skipResponseChecks, ConnectionSpecificProtocolInfo.SleepModeState sleepMode = ConnectionSpecificProtocolInfo.SleepModeState.NONE, bool convertNvmToBin = false)
	{
		ProtocolHCI.SleepModeState sleepMode2 = (ProtocolHCI.SleepModeState)Enum.Parse(typeof(ProtocolHCI.SleepModeState), sleepMode.ToString());
		WriteNvm(filename, skipResponseChecks, sleepMode2, convertNvmToBin);
	}

	public void SendRawBytes(byte[] rawBytes)
	{
		sendRawBytes = rawBytes;
		sendRawBytesEvent.Set();
	}

	public void PatchFirmware(string filename, bool skipResponseChecks)
	{
		patchFilename = filename;
		skipPatchResponseChecks = skipResponseChecks;
		patchFirmwareEvent.Set();
	}

	public void ReadBDAddressAndVersion()
	{
		bdAddressAndVersionEvent.Set();
	}

	public void ReadBDAddress()
	{
		bdAddressEvent.Set();
	}

	public void ReadLocalSupportedFeatures()
	{
		localSupportedFeaturesEvent.Set();
	}

	public void ReadAllBufferSizes()
	{
		readAllBufferSizesEvent.Set();
	}

	public void ReadAllBufferSizesHandler()
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		modeAgnosticDataReceiver.Startup();
		try
		{
			ReadBufferSize readBufferSize = new ReadBufferSize();
			btAPI.Send(readBufferSize);
			List<PacketBase> packets = modeAgnosticDataReceiver.ReceiveAll(readBufferSize.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReadBufferSize commandCompleteForReadBufferSize = (CommandCompleteForReadBufferSize)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReadBufferSize), packets);
			if (!CheckStatusForPacket(commandCompleteForReadBufferSize, readBufferSize.GetType().ToString()))
			{
				throw new Exception("Read buffer size fails.");
			}
			localACLPacketLength = Convert.ToInt32(commandCompleteForReadBufferSize.UserFields.HcAclDataPacketLength);
			localSCOPacketLength = Convert.ToInt32(commandCompleteForReadBufferSize.UserFields.HcSynchronousDataPacketLength);
			localACLBufferSize = Convert.ToInt32(commandCompleteForReadBufferSize.UserFields.HcTotalNumAclDataPackets);
			localSCOBufferSize = Convert.ToInt32(commandCompleteForReadBufferSize.UserFields.HcTotalNumSynchronousDataPackets);
			LeReadBufferSize leReadBufferSize = new LeReadBufferSize();
			btAPI.Send(leReadBufferSize);
			packets = modeAgnosticDataReceiver.ReceiveAll(leReadBufferSize.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForLeReadBufferSize commandCompleteForLeReadBufferSize = (CommandCompleteForLeReadBufferSize)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForLeReadBufferSize), packets);
			if (!CheckStatusForPacket(commandCompleteForLeReadBufferSize, leReadBufferSize.GetType().ToString()))
			{
				throw new Exception("Read LE buffer size fails.");
			}
			leLocalACLBufferSize = Convert.ToInt32(commandCompleteForLeReadBufferSize.UserFields.HcTotalNumLeDataPackets);
			aclDataBufferHandler.SetAclBuffers(localACLBufferSize, leLocalACLBufferSize);
			if (this.StartupEventHandler != null)
			{
				this.StartupEventHandler(this, localACLPacketLength, localSCOPacketLength, localACLBufferSize, localSCOBufferSize, null, null, leLocalACLBufferSize);
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to read buffer size. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	public void StartDefaultScript(string scriptFileName, string scriptFileLocation)
	{
		this.scriptFileName = scriptFileName;
		this.scriptFileLocation = scriptFileLocation;
		scriptEvent.Set();
	}

	public void TxBurst(byte[] BluetoothAddress, int[] Channel, int PacketType, int PayloadLength, byte LTAddress, byte PowerLevel, bool Whitening, int TransmitPattern, bool hoppingMode = false, int connectionChannel = 0)
	{
		prodTest_bluetoothAddress = BluetoothAddress;
		prodTest_channel = Channel;
		prodTest_packetType = PacketType;
		prodTest_payloadLength = PayloadLength;
		prodTest_lTAddress = LTAddress;
		prodTest_powerLevel = PowerLevel;
		prodTest_whitening = Whitening;
		prodTest_transmitPattern = TransmitPattern;
		prodTest_hoppingMode = hoppingMode;
		prodTest_connectionChannel = connectionChannel;
		prodTest_TxBurstEvent.Set();
	}

	public void Slave(byte[] BluetoothAddress, int[] Channel, int PacketType, int PayloadLength, byte LTAddress, byte PowerLevel, bool Whitening, int TransmitPattern)
	{
		prodTest_bluetoothAddress = BluetoothAddress;
		prodTest_channel = Channel;
		prodTest_packetType = PacketType;
		prodTest_payloadLength = PayloadLength;
		prodTest_lTAddress = LTAddress;
		prodTest_powerLevel = PowerLevel;
		prodTest_whitening = Whitening;
		prodTest_transmitPattern = TransmitPattern;
		prodTest_SlaveEvent.Set();
	}

	public void Master(byte[] BluetoothAddress, int[] Channel, int PacketType, int PayloadLength, byte LTAddress, byte PowerLevel, bool Whitening, int TransmitPattern)
	{
		prodTest_bluetoothAddress = BluetoothAddress;
		prodTest_channel = Channel;
		prodTest_packetType = PacketType;
		prodTest_payloadLength = PayloadLength;
		prodTest_lTAddress = LTAddress;
		prodTest_powerLevel = PowerLevel;
		prodTest_whitening = Whitening;
		prodTest_transmitPattern = TransmitPattern;
		prodTest_MasterEvent.Set();
	}

	public void TxContinuous(int Power, int Channel, int TranmitType, byte Patternlength, long Pattern)
	{
		prodTest_continuouspower = Power;
		prodTest_continuouschannel = Channel;
		prodTest_tranmitType = TranmitType;
		prodTest_patternlength = Patternlength;
		prodTest_pattern = Pattern;
		prodTest_TXContinuousEvent.Set();
	}

	public void RxBurst(byte[] BluetoothAddress, int[] Channel, int PacketType, int PayloadLength, byte LTAddress, byte PowerLevel, bool Whitening, int TransmitPattern, bool hoppingMode = false, int connectionChannel = 0)
	{
		prodTest_bluetoothAddress = BluetoothAddress;
		prodTest_channel = Channel;
		prodTest_packetType = PacketType;
		prodTest_payloadLength = PayloadLength;
		prodTest_lTAddress = LTAddress;
		prodTest_powerLevel = PowerLevel;
		prodTest_whitening = Whitening;
		prodTest_transmitPattern = TransmitPattern;
		prodTest_hoppingMode = hoppingMode;
		prodTest_connectionChannel = connectionChannel;
		prodTest_RxBurstEvent.Set();
	}

	public void LeTxTest(uint frequency, uint testDataLength, uint packetPayload)
	{
		leProdTest_LeTx_Channel = (frequency - 2402) / 2;
		leProdTest_LeTx_TestDataLength = testDataLength;
		leProdTest_LeTx_PacketPayload = packetPayload;
		leProdTest_TranmitterTestEvent.Set();
	}

	public void LeEnhancedTxTest(uint frequency, uint testDataLength, uint packetPayload, uint phy)
	{
		leProdTest_LeEnhancedTx_TxChannel = (frequency - 2402) / 2;
		leProdTest_LeEnhancedTx_TestDataLength = testDataLength;
		leProdTest_LeEnhancedTx_PacketPayload = packetPayload;
		leProdTest_LeEnhancedTx_Phy = phy;
		leProdTest_EnhancedTranmitterTestEvent.Set();
	}

	public void LeRxTest(uint frequency)
	{
		leProdTest_LeRx_Channel = (frequency - 2402) / 2;
		leProdTest_ReceiverTestEvent.Set();
	}

	public void LeEnhancedRxTest(uint frequency, uint phy, uint modulationIndex)
	{
		leProdTest_LeEnhancedRx_RxChannel = (frequency - 2402) / 2;
		leProdTest_LeEnhancedRx_Phy = phy;
		leProdTest_LeEnhancedRx_ModulationIndex = modulationIndex;
		leProdTest_EnhancedReceiverTestEvent.Set();
	}

	public void LeTestEnd()
	{
		leProdTest_LETestEndEvent.Set();
	}

	public void LeContinuousTxTest(uint frequency, uint txPower, uint transmitType, uint patternLength, uint bitPattern)
	{
		leProdTest_ContinuousTxTest_ChannelNumber = (frequency - 2402) / 2;
		leProdTest_ContinuousTxTest_TransmitOutputPower = txPower;
		leProdTest_ContinuousTxTest_TransmitType = transmitType;
		leProdTest_ContinuousTxTest_PatternLength = patternLength;
		leProdTest_ContinuousTxTest_BitPattern = bitPattern;
		leProdTest_ContinuousTxTestEvent.Set();
	}

	public void Reset()
	{
		hciResetEvent.Set();
	}

	public void SendRawBytes()
	{
		sendRawBytesEvent.Set();
	}

	public void GetRxStats()
	{
		prodTest_GetRxStatsEvent.Set();
	}

	public void WriteExtendedInquiryResponse(uint fecRequired, byte[] extendedInquiryResponse)
	{
		this.fecRequired = fecRequired;
		this.extendedInquiryResponse = extendedInquiryResponse;
		extendedInquiryResponseEvent.Set();
	}

	public void WriteAuthenticationAndEncryptionParameters(uint authenticationEnable, uint encryptionMode, uint simplePairingMode, uint simplePairingDebugMode, uint secureConnectionsHostSupport)
	{
		this.authenticationEnable = authenticationEnable;
		this.encryptionMode = encryptionMode;
		this.simplePairingMode = simplePairingMode;
		this.simplePairingDebugMode = simplePairingDebugMode;
		this.secureConnectionsHostSupport = secureConnectionsHostSupport;
		authenticationAndEncryptionEvent.Set();
	}

	public void SendPasskey(ulong bdAddr)
	{
		simplePairingBdAddr = bdAddr;
		sendPasskeyEvent.Set();
	}

	public void WriteHoldModeActivity(uint holdModeActivity)
	{
		this.holdModeActivity = holdModeActivity;
		holdModeActivityEvent.Set();
	}

	public void StartDataTransfer(int connectionHandle, int l2CAPMaxLength, int channelID, int maxACLLength, bool cycleL2CAPSizeEnable, bool l2CAPSequenceNumberingEnable, int dataPattern, bool sequentialDataPatternEnable, bool checkReceiveDataIntegrityEnable, bool continuousDataEnable, int numberofL2CAPPackets, int packetDelay, int startDelay, uint data, bool flushEnable, bool nonFlushEnable, bool bothEnable, bool isBTConnection)
	{
		connectionhandler = connectionHandle;
		aclDataBufferHandler.SetAclBuffers(localACLBufferSize, leLocalACLBufferSize);
		AclDataSender aclDataSender = GetAclDataSender(connectionHandle, isBTConnection);
		aclDataSender.EventTimeout = eventTimeout;
		aclDataSender.ChannelId = channelID;
		aclDataSender.MaxACLLength = maxACLLength;
		aclDataSender.CycleL2CAPSizeEnable = cycleL2CAPSizeEnable;
		aclDataSender.L2CAPSequenceNumberingEnable = l2CAPSequenceNumberingEnable;
		aclDataSender.DataPattern = dataPattern;
		aclDataSender.SequentialDataPatternEnable = sequentialDataPatternEnable;
		aclDataSender.CheckReceiveDataIntegrityEnable = checkReceiveDataIntegrityEnable;
		aclDataSender.ContinuousDataEnable = continuousDataEnable;
		aclDataSender.NumberOfL2CAPPackets = numberofL2CAPPackets;
		aclDataSender.PacketDelay = packetDelay;
		aclDataSender.StartDelay = startDelay;
		aclDataSender.FlushEnable = flushEnable;
		aclDataSender.NonFlushEnable = nonFlushEnable;
		aclDataSender.BothEnable = bothEnable;
		aclDataSender.SendLastPacket = true;
		aclDataSender.TransmitL2CAPByteCount = 0.0;
		aclDataSender.TransmitL2CAPPktCount = 0.0;
		aclDataSender.TransmitHCIByteCount = 0.0;
		aclDataSender.L2CAPMaxLength = l2CAPMaxLength - 4;
		dataTransferStartEvent.Set();
	}

	private AclDataSender GetAclDataSender(int connectionHandle, bool isBTConnection)
	{
		lock (connectionHandlerAclDataSenders)
		{
			if (connectionHandlerAclDataSenders.ContainsKey(connectionHandle))
			{
				return connectionHandlerAclDataSenders[connectionHandle];
			}
		}
		if (isBTConnection)
		{
			aclDataBufferHandler.AddBTConnection(connectionHandle);
		}
		else
		{
			aclDataBufferHandler.AddLEConnection(connectionHandle);
		}
		ACLDataQueue aclDataQueue = aclDataBufferHandler.GetAclDataQueue(connectionHandle);
		AclDataSender aclDataSender = new AclDataSender(specificPacketNotifier, btAPI, connectionHandle, logger, aclDataQueue);
		aclDataSender.TransmitDataTransferHandler += OnHelperTransmitDataTransferHandler;
		aclDataSender.TransmitFileTransferHandler += OnHelperTransmitFileTransferHandler;
		aclDataSender.EventTimeout = eventTimeout;
		lock (connectionHandlerAclDataSenders)
		{
			connectionHandlerAclDataSenders[connectionHandle] = aclDataSender;
			return aclDataSender;
		}
	}

	private void RemoveAclDataSender(int connectionHandle)
	{
		lock (connectionHandlerAclDataSenders)
		{
			if (connectionHandlerAclDataSenders.ContainsKey(connectionHandle))
			{
				aclDataBufferHandler.RemoveConnection(connectionHandle);
				AclDataSender aclDataSender = connectionHandlerAclDataSenders[connectionHandle];
				aclDataSender.TransmitDataTransferHandler -= OnHelperTransmitDataTransferHandler;
				aclDataSender.TransmitFileTransferHandler -= OnHelperTransmitFileTransferHandler;
				connectionHandlerAclDataSenders.Remove(connectionHandle);
			}
		}
	}

	private void OnHelperTransmitDataTransferHandler(object sender, int connectionHandle, double transmitL2CAPByteCount, double transmitL2CAPPktCount, double transmitHCIByteCount, int currentAvailableBufferCount, int maximumBufferAvailable)
	{
		if (this.TransmitDataTransferHandler != null)
		{
			this.TransmitDataTransferHandler(this, connectionHandle, transmitL2CAPByteCount, transmitL2CAPPktCount, transmitHCIByteCount, currentAvailableBufferCount, maximumBufferAvailable);
		}
	}

	private void OnHelperTransmitFileTransferHandler(object sender, int connectionHandle, long totalFileData, long sendFileData)
	{
		if (this.TransmitFileTransferHandler != null)
		{
			this.TransmitFileTransferHandler(this, connectionHandle, totalFileData, sendFileData);
		}
	}

	public void StartDataTransferHandler()
	{
		AclDataSender aclDataSender = null;
		lock (connectionHandlerAclDataSenders)
		{
			if (!connectionHandlerAclDataSenders.ContainsKey(connectionhandler))
			{
				return;
			}
			aclDataSender = connectionHandlerAclDataSenders[connectionhandler];
		}
		aclDataSender.StartDataTransferHandler();
	}

	public void StopDataTransfer(int connectionHandler)
	{
		AclDataSender aclDataSender = null;
		lock (connectionHandlerAclDataSenders)
		{
			if (!connectionHandlerAclDataSenders.ContainsKey(connectionHandler))
			{
				return;
			}
			aclDataSender = connectionHandlerAclDataSenders[connectionHandler];
		}
		aclDataSender.StopDataTransfer();
		RemoveAclDataSender(connectionHandler);
	}

	public void ShutdownDataTransfer()
	{
		dataTransferStartEvent.Reset();
		int[] array = null;
		lock (connectionHandlerAclDataSenders)
		{
			array = connectionHandlerAclDataSenders.Keys.ToArray();
		}
		int[] array2 = array;
		foreach (int connectionHandler in array2)
		{
			StopDataTransfer(connectionHandler);
		}
		btAPI.SendSleepByteAfterDataTransfer();
	}

	public void StopRemoteDataTransfer(int connectionHandler)
	{
		AclDataSender aclDataSender = null;
		lock (connectionHandlerAclDataSenders)
		{
			if (!connectionHandlerAclDataSenders.ContainsKey(connectionHandler))
			{
				return;
			}
			aclDataSender = connectionHandlerAclDataSenders[connectionHandler];
		}
		aclDataSender.Start = false;
		aclDataSender.SendLastPacket = false;
		aclDataSender.StopRemoteDataTransferHandler();
		RemoveAclDataSender(connectionHandler);
	}

	public void StopRemoteDataTransfer(int currentBTConnectionHandler, int remoteL2CAPMaxLength, int remoteChannelID, bool remoteCycleL2CAPSizeEnable, bool remoteL2CAPSequenceNumberingEnable, int remoteDataPattern, bool remoteCheckReceiveDataIntegrityEnable)
	{
		AclDataSender aclDataSender = null;
		lock (connectionHandlerAclDataSenders)
		{
			connectionhandler = currentBTConnectionHandler;
			if (!connectionHandlerAclDataSenders.ContainsKey(connectionhandler))
			{
				return;
			}
			aclDataSender = connectionHandlerAclDataSenders[connectionhandler];
		}
		aclDataSender.RemoteL2CAPMaxLength = remoteL2CAPMaxLength;
		aclDataSender.RemoteChannelId = remoteChannelID;
		aclDataSender.RemoteCycleL2CAPSizeEnable = remoteCycleL2CAPSizeEnable;
		aclDataSender.RemoteL2CAPSequenceNumberingEnable = remoteL2CAPSequenceNumberingEnable;
		aclDataSender.RemoteDataPattern = remoteDataPattern;
		aclDataSender.RemoteCheckReceiveDataIntegrityEnable = remoteCheckReceiveDataIntegrityEnable;
		remoteDataTransferStopEvent.Set();
	}

	public void SetAclLogMode()
	{
		setAclLogModeEvent.Set();
	}

	public void SetDecodePacket(bool decodePacket, bool packetResponse, bool conciseLog)
	{
		this.decodePacket = decodePacket;
		this.packetResponse = packetResponse;
		this.conciseLog = conciseLog;
		setDecodePacketEvent.Set();
	}

	protected override void Run()
	{
		logger.Enqueue(new LogMessage(LogMessageType.Info, "BT main thread starting"));
		ManualResetEvent[] array = new ManualResetEvent[35]
		{
			writeNvmEvent, patchFirmwareEvent, shutdownThreadEvent, prodTest_TxBurstEvent, prodTest_SlaveEvent, prodTest_MasterEvent, prodTest_TXContinuousEvent, prodTest_RxBurstEvent, hciResetEvent, prodTest_GetRxStatsEvent,
			ACLDataPacketTransferViaFileEvent, dataTransferStartEvent, startupCommandsEvent, startupCommandsLEOnlyEvent, bdAddressAndVersionEvent, bdAddressEvent, localSupportedFeaturesEvent, readAllBufferSizesEvent, scriptEvent, ACLDataFileTransferEvent,
			remoteDataTransferStopEvent, sendRawBytesEvent, extendedInquiryResponseEvent, authenticationAndEncryptionEvent, sendPasskeyEvent, holdModeActivityEvent, setDecodePacketEvent, hostBringupEvent, setAclLogModeEvent, leProdTest_TranmitterTestEvent,
			leProdTest_EnhancedTranmitterTestEvent, leProdTest_ReceiverTestEvent, leProdTest_EnhancedReceiverTestEvent, leProdTest_LETestEndEvent, leProdTest_ContinuousTxTestEvent
		};
		while (true)
		{
			int num = WaitHandle.WaitAny(array);
			if (array[num] == writeNvmEvent)
			{
				WriteNvmHandler(nvmFilename, skipNVMResponseChecks, bringupSleepMode, convertNvmToBin);
				writeNvmEvent.Reset();
				continue;
			}
			if (array[num] == patchFirmwareEvent)
			{
				PatchFirmwareHandler(patchFilename, skipPatchResponseChecks);
				patchFirmwareEvent.Reset();
				continue;
			}
			if (array[num] == shutdownThreadEvent)
			{
				break;
			}
			if (array[num] == prodTest_TxBurstEvent)
			{
				StartTxBurstHandler(prodTest_bluetoothAddress, prodTest_channel, prodTest_packetType, prodTest_payloadLength, prodTest_lTAddress, prodTest_powerLevel, prodTest_whitening, prodTest_transmitPattern, prodTest_hoppingMode, prodTest_connectionChannel);
				prodTest_TxBurstEvent.Reset();
			}
			else if (array[num] == prodTest_SlaveEvent)
			{
				StartSlaveHandler(prodTest_bluetoothAddress, prodTest_channel, prodTest_packetType, prodTest_payloadLength, prodTest_lTAddress, prodTest_powerLevel, prodTest_whitening, prodTest_transmitPattern);
				prodTest_SlaveEvent.Reset();
			}
			else if (array[num] == prodTest_MasterEvent)
			{
				StartMasterHandler(prodTest_bluetoothAddress, prodTest_channel, prodTest_packetType, prodTest_payloadLength, prodTest_lTAddress, prodTest_powerLevel, prodTest_whitening, prodTest_transmitPattern);
				prodTest_MasterEvent.Reset();
			}
			else if (array[num] == prodTest_TXContinuousEvent)
			{
				StartTxContinuousHandler(prodTest_continuouspower, prodTest_continuouschannel, prodTest_tranmitType, prodTest_patternlength, prodTest_pattern);
				prodTest_TXContinuousEvent.Reset();
			}
			else if (array[num] == prodTest_RxBurstEvent)
			{
				StartRxBurstHandler(prodTest_bluetoothAddress, prodTest_channel, prodTest_packetType, prodTest_payloadLength, prodTest_lTAddress, prodTest_powerLevel, prodTest_whitening, prodTest_transmitPattern, prodTest_hoppingMode, prodTest_connectionChannel);
				prodTest_RxBurstEvent.Reset();
			}
			else if (array[num] == hciResetEvent)
			{
				ResetHandler();
				hciResetEvent.Reset();
			}
			else if (array[num] == prodTest_GetRxStatsEvent)
			{
				GetRxStatsHandler();
				prodTest_GetRxStatsEvent.Reset();
			}
			else if (array[num] == ACLDataPacketTransferViaFileEvent)
			{
				ACLDataPacketTransferViaFileHandler();
				ACLDataPacketTransferViaFileEvent.Reset();
			}
			else if (array[num] == dataTransferStartEvent)
			{
				StartDataTransferHandler();
				dataTransferStartEvent.Reset();
			}
			else if (array[num] == startupCommandsEvent)
			{
				StartupCommandsHandler();
				startupCommandsEvent.Reset();
			}
			else if (array[num] == startupCommandsLEOnlyEvent)
			{
				StartupCommandsLEOnlyHandler();
				startupCommandsLEOnlyEvent.Reset();
			}
			else if (array[num] == bdAddressAndVersionEvent)
			{
				BDAddrssAndVersionHandler();
				bdAddressAndVersionEvent.Reset();
			}
			else if (array[num] == bdAddressEvent)
			{
				BDAddressHandler();
				bdAddressEvent.Reset();
			}
			else if (array[num] == localSupportedFeaturesEvent)
			{
				LocalSupportedFeaturesHandler();
				localSupportedFeaturesEvent.Reset();
			}
			else if (array[num] == readAllBufferSizesEvent)
			{
				ReadAllBufferSizesHandler();
				readAllBufferSizesEvent.Reset();
			}
			else if (array[num] == scriptEvent)
			{
				RunScriptHandler();
				scriptEvent.Reset();
			}
			else if (array[num] == ACLDataFileTransferEvent)
			{
				StartFileTransferHandler();
				ACLDataFileTransferEvent.Reset();
			}
			else if (array[num] == remoteDataTransferStopEvent)
			{
				StopRemoteDataTransferHandler();
				remoteDataTransferStopEvent.Reset();
			}
			else if (array[num] == sendRawBytesEvent)
			{
				SendRawBytesHandler(sendRawBytes);
				sendRawBytesEvent.Reset();
			}
			else if (array[num] == extendedInquiryResponseEvent)
			{
				ExtendedInquiryResponseHandler(fecRequired, extendedInquiryResponse);
				extendedInquiryResponseEvent.Reset();
			}
			else if (array[num] == authenticationAndEncryptionEvent)
			{
				AuthenticationAndEncryptionHandler(authenticationEnable, encryptionMode, simplePairingMode, simplePairingDebugMode, secureConnectionsHostSupport);
				authenticationAndEncryptionEvent.Reset();
			}
			else if (array[num] == sendPasskeyEvent)
			{
				SendPasskeyHandler(simplePairingBdAddr);
				sendPasskeyEvent.Reset();
			}
			else if (array[num] == holdModeActivityEvent)
			{
				HoldModeActivityHandler(holdModeActivity);
				holdModeActivityEvent.Reset();
			}
			else if (array[num] == setDecodePacketEvent)
			{
				SetDecodePacketHandler(decodePacket, packetResponse, conciseLog);
				setDecodePacketEvent.Reset();
			}
			else if (array[num] == hostBringupEvent)
			{
				HostBringupHandler(hostBringupPortName, hostBringupInitialDataRate, hostBringupFinalDataRate, hostBringupInitialFlowControl, hostBringupFinalFlowControl, hostBringupSendWakeByte, patchFilename, nvmFilename, hostBringupSleepMode, hostBringupLoadNVMasBIN);
				hostBringupEvent.Reset();
			}
			else if (array[num] == setAclLogModeEvent)
			{
				SetAclLogModeHandler();
				setAclLogModeEvent.Reset();
			}
			else if (array[num] == leProdTest_TranmitterTestEvent)
			{
				StartLeTransmitterTest();
				leProdTest_TranmitterTestEvent.Reset();
			}
			else if (array[num] == leProdTest_EnhancedTranmitterTestEvent)
			{
				StartLeEnhancedTransmitterTest();
				leProdTest_EnhancedTranmitterTestEvent.Reset();
			}
			else if (array[num] == leProdTest_ReceiverTestEvent)
			{
				StartLeReceiverTest();
				leProdTest_ReceiverTestEvent.Reset();
			}
			else if (array[num] == leProdTest_EnhancedReceiverTestEvent)
			{
				StartLeEnhancedReceiverTest();
				leProdTest_EnhancedReceiverTestEvent.Reset();
			}
			else if (array[num] == leProdTest_LETestEndEvent)
			{
				StartLeTestEnd();
				leProdTest_LETestEndEvent.Reset();
			}
			else if (array[num] == leProdTest_ContinuousTxTestEvent)
			{
				StartProdTestLeTxContinuous();
				leProdTest_ContinuousTxTestEvent.Reset();
			}
		}
		ShutdownDataTransfer();
		logger.Enqueue(new LogMessage(LogMessageType.Info, "BT main thread ending"));
	}

	private void WriteNvmHandler(string filename, bool skipResponseChecks, ProtocolHCI.SleepModeState sleepMode = ProtocolHCI.SleepModeState.NONE, bool convertNvmToBin = false)
	{
		List<string> list = new List<string>();
		try
		{
			btAPI.WriteNVM(filename, skipResponseChecks, sleepMode, convertNvmToBin, list);
			if (!skipResponseChecks)
			{
				BDAddrssAndVersionHandler();
			}
			logger.Enqueue(new LogMessage(LogMessageType.Info, "Finished BT NVM Write"));
			if (list != null && list.Count > 0)
			{
				logger.NotifyObserver(new LogMessage(LogMessageType.Warning, "NVM Write Summary:"));
				logger.NotifyObserver(new LogMessage(LogMessageType.Warning, list.ToArray()));
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error writing BT NVM!");
		}
	}

	private void PatchFirmwareHandler(string filename, bool skipResponseChecks)
	{
		try
		{
			if (Path.GetExtension(filename) == ".img")
			{
				btAPI.PatchFirmware(filename, skipResponseChecks);
				return;
			}
			if (Path.GetExtension(filename) == ".tlv")
			{
				btAPI.PatchFirmwareTLV(filename, skipResponseChecks);
				return;
			}
			throw new Exception("Patch file is not in the correct format.");
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error writing BT Patch!");
		}
	}

	private void StartTxBurstHandler(byte[] BluetoothAddress, int[] Channel, int PacketType, int PayloadLength, byte LTAddress, byte PowerLevel, bool Whitening, int TransmitPattern, bool hoppingMode = false, int connectionChannel = 0)
	{
		try
		{
			ProdTestTxBurst prodTestTxBurst = new ProdTestTxBurst();
			prodTestTxBurst.UserFields.HopChannel1 = (uint)Channel[0];
			prodTestTxBurst.UserFields.HopChannel2 = (uint)Channel[1];
			prodTestTxBurst.UserFields.HopChannel3 = (uint)Channel[2];
			prodTestTxBurst.UserFields.HopChannel4 = (uint)Channel[3];
			prodTestTxBurst.UserFields.HopChannel5 = (uint)Channel[4];
			prodTestTxBurst.UserFields.PacketType = (uint)PacketType;
			prodTestTxBurst.UserFields.PayloadLength = (uint)PayloadLength;
			prodTestTxBurst.UserFields.LogicalTransportAddress = LTAddress;
			if (Whitening)
			{
				prodTestTxBurst.UserFields.DataWhitening = 1u;
			}
			else
			{
				prodTestTxBurst.UserFields.DataWhitening = 0u;
			}
			if (hoppingMode)
			{
				prodTestTxBurst.UserFields.HoppingFunctionality = 1u;
				prodTestTxBurst.UserFields.HopChannel1 = (uint)connectionChannel;
			}
			else
			{
				prodTestTxBurst.UserFields.HoppingFunctionality = 0u;
			}
			prodTestTxBurst.UserFields.BluetoothTargetDeviceAddress = Convert.ToUInt64(Conversions.ByteArrayToHexString(BluetoothAddress), 16);
			prodTestTxBurst.UserFields.TransmitOutputPower = PowerLevel;
			prodTestTxBurst.UserFields.TxPatternPayload = (uint)TransmitPattern;
			btAPI.Send(prodTestTxBurst);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Error Start Tx Burst Handler: " + ex));
			this.ErrEventHandler(this);
		}
	}

	private void StartSlaveHandler(byte[] BluetoothAddress, int[] Channel, int PacketType, int PayloadLength, byte LTAddress, byte PowerLevel, bool Whitening, int TransmitPattern)
	{
		try
		{
			ProdTestSlave prodTestSlave = new ProdTestSlave();
			prodTestSlave.UserFields.HopChannel1 = (uint)Channel[0];
			prodTestSlave.UserFields.HopChannel2 = (uint)Channel[1];
			prodTestSlave.UserFields.HopChannel3 = (uint)Channel[2];
			prodTestSlave.UserFields.HopChannel4 = (uint)Channel[3];
			prodTestSlave.UserFields.HopChannel5 = (uint)Channel[4];
			prodTestSlave.UserFields.PacketType = (uint)PacketType;
			prodTestSlave.UserFields.PayloadLength = (uint)PayloadLength;
			prodTestSlave.UserFields.LogicalTransportAddress = LTAddress;
			prodTestSlave.UserFields.HoppingFunctionality = 0u;
			if (Whitening)
			{
				prodTestSlave.UserFields.DataWhitening = 1u;
			}
			else
			{
				prodTestSlave.UserFields.DataWhitening = 0u;
			}
			prodTestSlave.UserFields.BluetoothTargetDeviceAddress = Convert.ToUInt64(Conversions.ByteArrayToHexString(BluetoothAddress), 16);
			prodTestSlave.UserFields.TransmitOutputPower = PowerLevel;
			prodTestSlave.UserFields.TxPatternPayload = (uint)TransmitPattern;
			btAPI.Send(prodTestSlave);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Error Start Slave Handler: " + ex));
		}
	}

	private void StartMasterHandler(byte[] BluetoothAddress, int[] Channel, int PacketType, int PayloadLength, byte LTAddress, byte PowerLevel, bool Whitening, int TransmitPattern)
	{
		try
		{
			ProdTestMaster prodTestMaster = new ProdTestMaster();
			prodTestMaster.UserFields.HopChannel1 = (uint)Channel[0];
			prodTestMaster.UserFields.HopChannel2 = (uint)Channel[1];
			prodTestMaster.UserFields.HopChannel3 = (uint)Channel[2];
			prodTestMaster.UserFields.HopChannel4 = (uint)Channel[3];
			prodTestMaster.UserFields.HopChannel5 = (uint)Channel[4];
			prodTestMaster.UserFields.PacketType = (uint)PacketType;
			prodTestMaster.UserFields.PayloadLength = (uint)PayloadLength;
			prodTestMaster.UserFields.LogicalTransportAddress = LTAddress;
			prodTestMaster.UserFields.HoppingFunctionality = 0u;
			if (Whitening)
			{
				prodTestMaster.UserFields.DataWhitening = 1u;
			}
			else
			{
				prodTestMaster.UserFields.DataWhitening = 0u;
			}
			prodTestMaster.UserFields.BluetoothTargetDeviceAddress = Convert.ToUInt64(Conversions.ByteArrayToHexString(BluetoothAddress), 16);
			prodTestMaster.UserFields.TransmitOutputPower = PowerLevel;
			prodTestMaster.UserFields.TxPatternPayload = (uint)TransmitPattern;
			btAPI.Send(prodTestMaster);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Error Start Master Handler: " + ex));
		}
	}

	private void StartTxContinuousHandler(int Power, int Channel, int TransmitType, byte PatternLength, long Pattern)
	{
		try
		{
			ProdTestTxContinuous prodTestTxContinuous = new ProdTestTxContinuous();
			prodTestTxContinuous.UserFields.TransmitOutputPower = (uint)Power;
			prodTestTxContinuous.UserFields.ChannelNumber = (uint)Channel;
			prodTestTxContinuous.UserFields.TransmitType = (uint)TransmitType;
			prodTestTxContinuous.UserFields.PatternLength = PatternLength;
			prodTestTxContinuous.UserFields.BitPattern = (uint)Pattern;
			btAPI.Send(prodTestTxContinuous);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Error Tx Continuous Handler: " + ex));
			this.ErrEventHandler(this);
		}
	}

	private void StartRxBurstHandler(byte[] BluetoothAddress, int[] Channel, int PacketType, int PayloadLength, byte LTAddress, byte PowerLevel, bool Whitening, int TransmitPattern, bool hoppingMode = false, int connectionChannel = 0)
	{
		try
		{
			ProdTestRxBurst prodTestRxBurst = new ProdTestRxBurst();
			prodTestRxBurst.UserFields.HopChannel1 = (uint)Channel[0];
			prodTestRxBurst.UserFields.HopChannel2 = (uint)Channel[1];
			prodTestRxBurst.UserFields.HopChannel3 = (uint)Channel[2];
			prodTestRxBurst.UserFields.HopChannel4 = (uint)Channel[3];
			prodTestRxBurst.UserFields.HopChannel5 = (uint)Channel[4];
			prodTestRxBurst.UserFields.PacketType = (uint)PacketType;
			prodTestRxBurst.UserFields.PayloadLength = (uint)PayloadLength;
			prodTestRxBurst.UserFields.LogicalTransportAddress = LTAddress;
			if (hoppingMode)
			{
				prodTestRxBurst.UserFields.HoppingFunctionality = 1u;
				prodTestRxBurst.UserFields.HopChannel1 = (uint)connectionChannel;
			}
			else
			{
				prodTestRxBurst.UserFields.HoppingFunctionality = 0u;
			}
			prodTestRxBurst.UserFields.BluetoothTargetDeviceAddress = Convert.ToUInt64(Conversions.ByteArrayToHexString(BluetoothAddress), 16);
			prodTestRxBurst.UserFields.TransmitOutputPower = PowerLevel;
			prodTestRxBurst.UserFields.TxPatternPayload = (uint)TransmitPattern;
			btAPI.Send(prodTestRxBurst);
			this.RxBurstModeReadyHandler(this, btimer: true);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Error Start Rx Burst Handler: " + ex));
			this.ErrEventHandler(this);
			this.RxBurstModeReadyHandler(this, btimer: false);
		}
	}

	private void ResetHandler()
	{
		try
		{
			Reset packet = new Reset();
			btAPI.Send(packet);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Error Reset Handler: " + ex));
		}
	}

	private void SendRawBytesHandler(byte[] rawBytes)
	{
		try
		{
			btAPI.Send(rawBytes, performValidPacketCheck: true);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "SendRawBytesHandler Handler: " + ex));
		}
	}

	private void ExtendedInquiryResponseHandler(uint fecRequired, byte[] extendedInquiryResponse)
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			WriteExtendedInquiryResponse writeExtendedInquiryResponse = new WriteExtendedInquiryResponse();
			writeExtendedInquiryResponse.UserFields.FecRequired = fecRequired;
			IEnumerator enumerator = extendedInquiryResponse.GetEnumerator();
			if (enumerator.MoveNext())
			{
				for (int i = 0; i < writeExtendedInquiryResponse.UserFields.EirDataCount; i++)
				{
					WriteExtendedInquiryResponse.ExtendedInquiryResponseSubField extendedInquiryResponseSubField = writeExtendedInquiryResponse.UserFields.ExtendedInquiryResponseList[i];
					extendedInquiryResponseSubField.Length = (byte)enumerator.Current;
					extendedInquiryResponseSubField.DataType = (byte)(enumerator.MoveNext() ? enumerator.Current : ((object)0));
					int count = extendedInquiryResponseSubField.DataList.Count;
					for (int j = 0; j < count; j++)
					{
						extendedInquiryResponseSubField.DataList[j] = (byte)(enumerator.MoveNext() ? enumerator.Current : ((object)0));
					}
					if (enumerator.MoveNext())
					{
						writeExtendedInquiryResponse.UserFields.EirDataCount = (uint)(writeExtendedInquiryResponse.UserFields.ExtendedInquiryResponseList.Count + 1);
					}
				}
			}
			btAPI.Send(writeExtendedInquiryResponse);
			list = modeAgnosticDataReceiver.ReceiveAll(writeExtendedInquiryResponse.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteExtendedInquiryResponse packet = (CommandCompleteForWriteExtendedInquiryResponse)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteExtendedInquiryResponse), list);
			if (!CheckStatusForPacket(packet, writeExtendedInquiryResponse.GetType().ToString()))
			{
				throw new Exception("Write extended inquiry response fails.");
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Extended Inquiry Response Handler: " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void AuthenticationAndEncryptionHandler(uint authenticationEnable, uint encryptionMode, uint simplePairingMode, uint simplePairingDebugMode, uint secureConnectionsHostSupport)
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			WriteAuthenticationEnable writeAuthenticationEnable = new WriteAuthenticationEnable();
			writeAuthenticationEnable.UserFields.AuthenticationEnable = authenticationEnable;
			btAPI.Send(writeAuthenticationEnable);
			list = modeAgnosticDataReceiver.ReceiveAll(writeAuthenticationEnable.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteAuthenticationEnable packet = (CommandCompleteForWriteAuthenticationEnable)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteAuthenticationEnable), list);
			if (!CheckStatusForPacket(packet, writeAuthenticationEnable.GetType().ToString()))
			{
				throw new Exception("Write authentication enable fails.");
			}
			WriteEncryptionMode writeEncryptionMode = new WriteEncryptionMode();
			writeEncryptionMode.UserFields.EncryptionMode = encryptionMode;
			btAPI.Send(writeEncryptionMode);
			list = modeAgnosticDataReceiver.ReceiveAll(writeEncryptionMode.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteEncryptionMode packet2 = (CommandCompleteForWriteEncryptionMode)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteEncryptionMode), list);
			if (!CheckStatusForPacket(packet2, writeEncryptionMode.GetType().ToString()))
			{
				throw new Exception("Write encryption mode fails.");
			}
			if (localSupportedFeatures.SecureSimplePairing == SupportBitEnum.Supported)
			{
				WriteSimplePairingMode writeSimplePairingMode = new WriteSimplePairingMode();
				writeSimplePairingMode.UserFields.SimplePairingMode = simplePairingMode;
				btAPI.Send(writeSimplePairingMode);
				list = modeAgnosticDataReceiver.ReceiveAll(writeSimplePairingMode.ExpectedResponseTypes, eventTimeout);
				CommandCompleteForWriteSimplePairingMode packet3 = (CommandCompleteForWriteSimplePairingMode)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteSimplePairingMode), list);
				if (!CheckStatusForPacket(packet3, writeSimplePairingMode.GetType().ToString()))
				{
					throw new Exception("Write simple pairing mode fails.");
				}
				WriteSimplePairingDebugMode writeSimplePairingDebugMode = new WriteSimplePairingDebugMode();
				writeSimplePairingDebugMode.UserFields.SimplePairingDebugMode = simplePairingDebugMode;
				btAPI.Send(writeSimplePairingDebugMode);
				list = modeAgnosticDataReceiver.ReceiveAll(writeSimplePairingDebugMode.ExpectedResponseTypes, eventTimeout);
				CommandCompleteForWriteSimplePairingDebugMode packet4 = (CommandCompleteForWriteSimplePairingDebugMode)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteSimplePairingDebugMode), list);
				if (!CheckStatusForPacket(packet4, writeSimplePairingDebugMode.GetType().ToString()))
				{
					throw new Exception("Write simple pairing debug mode fails.");
				}
				WriteSecureConnectionsHostSupport writeSecureConnectionsHostSupport = new WriteSecureConnectionsHostSupport();
				writeSecureConnectionsHostSupport.UserFields.SecureConnectionsHostSupport = secureConnectionsHostSupport;
				btAPI.Send(writeSecureConnectionsHostSupport);
				list = modeAgnosticDataReceiver.ReceiveAll(writeSecureConnectionsHostSupport.ExpectedResponseTypes, eventTimeout);
				CommandCompleteForWriteSecureConnectionsHostSupport packet5 = (CommandCompleteForWriteSecureConnectionsHostSupport)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteSecureConnectionsHostSupport), list);
				if (!CheckStatusForPacket(packet5, writeSecureConnectionsHostSupport.GetType().ToString()))
				{
					throw new Exception("Write secure connections host support fails.");
				}
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Authentication and Encryption Handler: " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void SendPasskeyHandler(ulong bdAddr)
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			if (!passkeyAvailable.WaitOne(2000))
			{
				lock (passkeyAvailable)
				{
					if (passkey == 1000000)
					{
						passkey = (uint)new Random().Next(1000000);
						passkeyAvailable.Set();
					}
				}
			}
			KeypressNotificationTypeEnum[] array = new KeypressNotificationTypeEnum[2]
			{
				KeypressNotificationTypeEnum.Passkey_entry_started,
				KeypressNotificationTypeEnum.Passkey_entry_completed
			};
			KeypressNotificationTypeEnum[] array2 = array;
			foreach (KeypressNotificationTypeEnum notificationTypeAsKeypressNotificationTypeEnum in array2)
			{
				SendKeypressNotification sendKeypressNotification = new SendKeypressNotification();
				sendKeypressNotification.UserFields.BdAddr = bdAddr;
				sendKeypressNotification.UserFields.SetNotificationTypeAsKeypressNotificationTypeEnum(notificationTypeAsKeypressNotificationTypeEnum);
				btAPI.Send(sendKeypressNotification);
				list = modeAgnosticDataReceiver.ReceiveAll(sendKeypressNotification.ExpectedResponseTypes, eventTimeout);
				CommandCompleteForSendKeypressNotification packet = (CommandCompleteForSendKeypressNotification)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForSendKeypressNotification), list);
				if (!CheckStatusForPacket(packet, sendKeypressNotification.GetType().ToString()))
				{
					throw new Exception("User passkey request reply fails.");
				}
			}
			UserPasskeyRequestReply userPasskeyRequestReply = new UserPasskeyRequestReply();
			userPasskeyRequestReply.UserFields.BdAddr = bdAddr;
			userPasskeyRequestReply.UserFields.NumericValue = passkey;
			btAPI.Send(userPasskeyRequestReply);
			list = modeAgnosticDataReceiver.ReceiveAll(userPasskeyRequestReply.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForUserPasskeyRequestReply packet2 = (CommandCompleteForUserPasskeyRequestReply)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForUserPasskeyRequestReply), list);
			if (!CheckStatusForPacket(packet2, userPasskeyRequestReply.GetType().ToString()))
			{
				throw new Exception("User passkey request reply fails.");
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Error Send Passkey Handler: " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
			passkey = 1000000u;
			passkeyAvailable.Reset();
		}
	}

	private void HoldModeActivityHandler(uint holdModeActivity)
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			WriteHoldModeActivity writeHoldModeActivity = new WriteHoldModeActivity();
			writeHoldModeActivity.UserFields.HoldModeActivity = holdModeActivity;
			btAPI.Send(writeHoldModeActivity);
			list = modeAgnosticDataReceiver.ReceiveAll(writeHoldModeActivity.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteHoldModeActivity packet = (CommandCompleteForWriteHoldModeActivity)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteHoldModeActivity), list);
			if (!CheckStatusForPacket(packet, writeHoldModeActivity.GetType().ToString()))
			{
				throw new Exception("Write hold mode activity fails.");
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Error Hold Mode Activity Handler: " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void GetRxStatsHandler()
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		try
		{
			ProdTestStats packet = new ProdTestStats();
			btAPI.Send(packet);
			modeAgnosticDataReceiver.Startup();
			List<PacketBase> list = new List<PacketBase>();
			Type[] packetTypes = new Type[2]
			{
				typeof(CommandCompleteForProdTestStats),
				typeof(ProdTestStatsEvent)
			};
			PacketBase item = modeAgnosticDataReceiver.Receive(packetTypes, 1000);
			list.Add(item);
			this.GetRxStatsEventHandler(this, list);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Error Get Rx Stats Handler: " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void ACLDataPacketTransferViaFileHandler()
	{
		try
		{
			string filename = null;
			lock (connectionHandlerAclDataSenders)
			{
				filename = connectionHandlerAclDataSenders[connectionhandler].DataFileName;
			}
			btAPI.ACLDataPacketTransferViaFile((uint)connectionhandler, filename);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error Sending ACL Data Via File");
		}
	}

	private void StartFileTransferHandler()
	{
		AclDataSender aclDataSender = null;
		lock (connectionHandlerAclDataSenders)
		{
			if (!connectionHandlerAclDataSenders.ContainsKey(connectionhandler))
			{
				return;
			}
			aclDataSender = connectionHandlerAclDataSenders[connectionhandler];
		}
		aclDataBufferHandler.SetAclBuffers(localACLBufferSize, leLocalACLBufferSize);
		aclDataSender.StartFileTransferHandler();
	}

	private void StopRemoteDataTransferHandler()
	{
		AclDataSender aclDataSender = null;
		lock (connectionHandlerAclDataSenders)
		{
			if (!connectionHandlerAclDataSenders.ContainsKey(connectionhandler))
			{
				return;
			}
			aclDataSender = connectionHandlerAclDataSenders[connectionhandler];
		}
		aclDataSender.StopRemoteDataTransferHandler();
		RemoveAclDataSender(connectionhandler);
	}

	public void CancelTxDataTransfer(bool yesNo, int connectionHandle)
	{
		lock (connectionHandlerAclDataSenders)
		{
			if (!connectionHandlerAclDataSenders.ContainsKey(connectionHandle))
			{
				return;
			}
			connectionHandlerAclDataSenders[connectionHandle].AbortTxDataTransfer = yesNo;
		}
		RemoveAclDataSender(connectionHandle);
	}

	public void SetCombinedScripter(CombinedScripter combinedScripter)
	{
		this.combinedScripter = combinedScripter;
	}

	public void StartupCommands(LocalHostDefaultOption btOptions, WriteScanEnable.UserFieldsWrapper.ScanEnableEnum scanEnable)
	{
		btHostOptions = btOptions;
		this.scanEnable = scanEnable;
		startupCommandsEvent.Set();
	}

	public void StartupCommandsLEOnly()
	{
		startupCommandsLEOnlyEvent.Set();
	}

	public void HostBringup(string portName, int initialDataRate, int finalDataRate, Handshake initialFlowControl, Handshake finalFlowControl, bool sendWakeByte, string patchFile, string nvmFile, ConnectionSpecificProtocolInfo.SleepModeState sleepMode, bool loadNVMasBIN)
	{
		ProtocolHCI.SleepModeState sleepMode2 = (ProtocolHCI.SleepModeState)Enum.Parse(typeof(ProtocolHCI.SleepModeState), sleepMode.ToString());
		HostBringup(portName, initialDataRate, finalDataRate, initialFlowControl, finalFlowControl, sendWakeByte, patchFile, nvmFile, sleepMode2, loadNVMasBIN);
	}

	public void HostBringup(string portName, int initialDataRate, int finalDataRate, Handshake initialFlowControl, Handshake finalFlowControl, bool sendWakeByte, string patchFile, string nvmFile, ProtocolHCI.SleepModeState sleepMode, bool loadNVMasBIN)
	{
		hostBringupPortName = portName;
		hostBringupInitialDataRate = initialDataRate;
		hostBringupFinalDataRate = finalDataRate;
		hostBringupInitialFlowControl = initialFlowControl;
		hostBringupFinalFlowControl = finalFlowControl;
		hostBringupSendWakeByte = sendWakeByte;
		hostBringupSleepMode = sleepMode;
		patchFilename = patchFile;
		nvmFilename = nvmFile;
		hostBringupLoadNVMasBIN = loadNVMasBIN;
		hostBringupEvent.Set();
	}

	private void HostBringupHandler(string portName, int initialDataRate, int finalDataRate, Handshake initialFlowControl, Handshake finalFlowControl, bool sendWakeByte, string patchFile, string nvmFile, ProtocolHCI.SleepModeState sleepMode, bool loadNVMasBIN)
	{
		int num = 0;
		num = finalDataRate switch
		{
			115200 => 0, 
			57600 => 1, 
			38400 => 2, 
			19200 => 3, 
			9600 => 4, 
			230400 => 5, 
			250000 => 6, 
			460800 => 7, 
			500000 => 8, 
			720000 => 9, 
			921600 => 10, 
			1000000 => 11, 
			125000 => 12, 
			2000000 => 13, 
			3000000 => 14, 
			4000000 => 15, 
			1600000 => 16, 
			3200000 => 17, 
			3500000 => 18, 
			_ => 0, 
		};
		try
		{
			lock (btAPI)
			{
				btAPI.SetSleepMode(ProtocolHCI.SleepModeState.NONE);
				btAPI.CloseConnection();
				btAPI.OpenSerialConnection(portName, initialDataRate, initialFlowControl);
				if (sendWakeByte)
				{
					byte[] bytes = new byte[1] { 252 };
					btAPI.Send(bytes);
					Thread.Sleep(100);
				}
				HciVsSetBaudrate hciVsSetBaudrate = new HciVsSetBaudrate();
				hciVsSetBaudrate._UserFields.BaudRate = (uint)num;
				btAPI.Send(hciVsSetBaudrate);
				btAPI.CloseConnection();
				btAPI.OpenSerialConnection(portName, finalDataRate, finalFlowControl);
				btAPI.SetSleepMode(ProtocolHCI.SleepModeState.NONE);
				if (!patchFile.Trim().Equals(""))
				{
					PatchFirmwareHandler(patchFile, skipPatchResponseChecks);
				}
				if (!nvmFile.Trim().Equals(""))
				{
					WriteNvmHandler(nvmFile, skipNVMResponseChecks, sleepMode, loadNVMasBIN);
				}
				logger.Enqueue(new LogMessage(LogMessageType.Info, "Platform bringup completed"));
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Failed to Bringup Platform. " + ex));
		}
	}

	private void StartupCommandsHandler()
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			Reset reset = new Reset();
			btAPI.Send(reset);
			list = modeAgnosticDataReceiver.ReceiveAll(reset.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReset packet = (CommandCompleteForReset)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReset), list);
			if (!CheckStatusForPacket(packet, reset.GetType().ToString()))
			{
				throw new Exception("Reset fails.");
			}
			ReadBufferSize readBufferSize = new ReadBufferSize();
			btAPI.Send(readBufferSize);
			list = modeAgnosticDataReceiver.ReceiveAll(readBufferSize.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReadBufferSize commandCompleteForReadBufferSize = (CommandCompleteForReadBufferSize)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReadBufferSize), list);
			if (!CheckStatusForPacket(commandCompleteForReadBufferSize, readBufferSize.GetType().ToString()))
			{
				throw new Exception("Read buffer size fails.");
			}
			localACLPacketLength = Convert.ToInt32(commandCompleteForReadBufferSize.UserFields.HcAclDataPacketLength);
			localSCOPacketLength = Convert.ToInt32(commandCompleteForReadBufferSize.UserFields.HcSynchronousDataPacketLength);
			localACLBufferSize = Convert.ToInt32(commandCompleteForReadBufferSize.UserFields.HcTotalNumAclDataPackets);
			localSCOBufferSize = Convert.ToInt32(commandCompleteForReadBufferSize.UserFields.HcTotalNumSynchronousDataPackets);
			LeReadBufferSize leReadBufferSize = new LeReadBufferSize();
			btAPI.Send(leReadBufferSize);
			list = modeAgnosticDataReceiver.ReceiveAll(leReadBufferSize.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForLeReadBufferSize commandCompleteForLeReadBufferSize = (CommandCompleteForLeReadBufferSize)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForLeReadBufferSize), list);
			if (!CheckStatusForPacket(commandCompleteForLeReadBufferSize, leReadBufferSize.GetType().ToString()))
			{
				throw new Exception("Read LE buffer size fails.");
			}
			leLocalACLBufferSize = Convert.ToInt32(commandCompleteForLeReadBufferSize.UserFields.HcTotalNumLeDataPackets);
			ReadLocalVersionInformation readLocalVersionInformation = new ReadLocalVersionInformation();
			btAPI.Send(readLocalVersionInformation);
			list = modeAgnosticDataReceiver.ReceiveAll(readLocalVersionInformation.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReadLocalVersionInformation packet2 = (CommandCompleteForReadLocalVersionInformation)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReadLocalVersionInformation), list);
			if (!CheckStatusForPacket(packet2, readLocalVersionInformation.GetType().ToString()))
			{
				throw new Exception("Read local version information fails.");
			}
			ReadLocalSupportedFeatures readLocalSupportedFeatures = new ReadLocalSupportedFeatures();
			btAPI.Send(readLocalSupportedFeatures);
			list = modeAgnosticDataReceiver.ReceiveAll(readLocalSupportedFeatures.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReadLocalSupportedFeatures commandCompleteForReadLocalSupportedFeatures = (CommandCompleteForReadLocalSupportedFeatures)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReadLocalSupportedFeatures), list);
			if (!CheckStatusForPacket(commandCompleteForReadLocalSupportedFeatures, readLocalSupportedFeatures.GetType().ToString()))
			{
				throw new Exception("Read local supported features fails.");
			}
			localSupportedFeatures = commandCompleteForReadLocalSupportedFeatures.UserFields.GetLmpFeaturesAsSupportedFeaturesEnumCollection();
			SetEventMask setEventMask = new SetEventMask();
			setEventMask.UserFields.EventMask = ulong.MaxValue;
			btAPI.Send(setEventMask);
			list = modeAgnosticDataReceiver.ReceiveAll(setEventMask.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForSetEventMask packet3 = (CommandCompleteForSetEventMask)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForSetEventMask), list);
			if (!CheckStatusForPacket(packet3, setEventMask.GetType().ToString()))
			{
				throw new Exception("Set event mask fails.");
			}
			WriteSimplePairingMode writeSimplePairingMode = new WriteSimplePairingMode();
			writeSimplePairingMode.UserFields.SimplePairingMode = (btHostOptions.simplePairingEnable ? 1u : 0u);
			btAPI.Send(writeSimplePairingMode);
			list = modeAgnosticDataReceiver.ReceiveAll(writeSimplePairingMode.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteSimplePairingMode packet4 = (CommandCompleteForWriteSimplePairingMode)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteSimplePairingMode), list);
			if (!CheckStatusForPacket(packet4, writeSimplePairingMode.GetType().ToString()))
			{
				throw new Exception("Write simple pairing mode fails.");
			}
			WriteSecureConnectionsHostSupport writeSecureConnectionsHostSupport = new WriteSecureConnectionsHostSupport();
			writeSecureConnectionsHostSupport.UserFields.SecureConnectionsHostSupport = (btHostOptions.secureConnectionsHostSupportEnable ? 1u : 0u);
			btAPI.Send(writeSecureConnectionsHostSupport);
			list = modeAgnosticDataReceiver.ReceiveAll(writeSecureConnectionsHostSupport.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteSecureConnectionsHostSupport packet5 = (CommandCompleteForWriteSecureConnectionsHostSupport)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteSecureConnectionsHostSupport), list);
			if (!CheckStatusForPacket(packet5, writeSecureConnectionsHostSupport.GetType().ToString()))
			{
				throw new Exception("Write secure connections host support fails.");
			}
			WriteAuthenticationEnable writeAuthenticationEnable = new WriteAuthenticationEnable();
			writeAuthenticationEnable.UserFields.AuthenticationEnable = (btHostOptions.authenticationEnable ? 1u : 0u);
			btAPI.Send(writeAuthenticationEnable);
			list = modeAgnosticDataReceiver.ReceiveAll(writeAuthenticationEnable.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteAuthenticationEnable packet6 = (CommandCompleteForWriteAuthenticationEnable)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteAuthenticationEnable), list);
			if (!CheckStatusForPacket(packet6, writeAuthenticationEnable.GetType().ToString()))
			{
				throw new Exception("Write authentication enable fails.");
			}
			WriteHoldModeActivity writeHoldModeActivity = new WriteHoldModeActivity();
			if (btHostOptions.maintainCurrentPower)
			{
				holdModeActivity = 0u;
			}
			else
			{
				holdModeActivity = (btHostOptions.suspendPageScan ? 1u : 0u);
				holdModeActivity += (uint)(btHostOptions.suspendInquiryScan ? 2 : 0);
				holdModeActivity += (uint)(btHostOptions.suspendPeriodicInquiries ? 4 : 0);
			}
			writeHoldModeActivity.UserFields.HoldModeActivity = holdModeActivity;
			btAPI.Send(writeHoldModeActivity);
			list = modeAgnosticDataReceiver.ReceiveAll(writeHoldModeActivity.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteHoldModeActivity packet7 = (CommandCompleteForWriteHoldModeActivity)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteHoldModeActivity), list);
			if (!CheckStatusForPacket(packet7, writeHoldModeActivity.GetType().ToString()))
			{
				throw new Exception("Write hold mode activity fails.");
			}
			WriteExtendedInquiryResponse writeExtendedInquiryResponse = new WriteExtendedInquiryResponse();
			writeExtendedInquiryResponse.UserFields.FecRequired = (btHostOptions.fecRequired ? 1u : 0u);
			btAPI.Send(writeExtendedInquiryResponse);
			list = modeAgnosticDataReceiver.ReceiveAll(writeExtendedInquiryResponse.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteExtendedInquiryResponse packet8 = (CommandCompleteForWriteExtendedInquiryResponse)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteExtendedInquiryResponse), list);
			if (!CheckStatusForPacket(packet8, writeExtendedInquiryResponse.GetType().ToString()))
			{
				throw new Exception("Write extended inquiry response fails.");
			}
			WriteInquiryMode writeInquiryMode = new WriteInquiryMode();
			writeInquiryMode.UserFields.InquiryMode = 1u;
			btAPI.Send(writeInquiryMode);
			list = modeAgnosticDataReceiver.ReceiveAll(writeInquiryMode.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteInquiryMode packet9 = (CommandCompleteForWriteInquiryMode)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteInquiryMode), list);
			if (!CheckStatusForPacket(packet9, writeInquiryMode.GetType().ToString()))
			{
				throw new Exception("Write inquiry mode fails.");
			}
			WriteInquiryScanType writeInquiryScanType = new WriteInquiryScanType();
			writeInquiryScanType.UserFields.InquiryScanType = 1u;
			btAPI.Send(writeInquiryScanType);
			list = modeAgnosticDataReceiver.ReceiveAll(writeInquiryScanType.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteInquiryScanType packet10 = (CommandCompleteForWriteInquiryScanType)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteInquiryScanType), list);
			if (!CheckStatusForPacket(packet10, writeInquiryScanType.GetType().ToString()))
			{
				throw new Exception("Write inquiry scan type fails.");
			}
			WritePageScanType writePageScanType = new WritePageScanType();
			writePageScanType.UserFields.PageScanType = 1u;
			btAPI.Send(writePageScanType);
			list = modeAgnosticDataReceiver.ReceiveAll(writePageScanType.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWritePageScanType packet11 = (CommandCompleteForWritePageScanType)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWritePageScanType), list);
			if (!CheckStatusForPacket(packet11, writePageScanType.GetType().ToString()))
			{
				throw new Exception("Write page scan type fails.");
			}
			WriteScanEnable writeScanEnable = new WriteScanEnable();
			writeScanEnable.UserFields.SetScanEnableAsScanEnableEnum(scanEnable);
			btAPI.Send(writeScanEnable);
			list = modeAgnosticDataReceiver.ReceiveAll(writeScanEnable.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForWriteScanEnable packet12 = (CommandCompleteForWriteScanEnable)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForWriteScanEnable), list);
			if (!CheckStatusForPacket(packet12, writeScanEnable.GetType().ToString()))
			{
				throw new Exception("Write scan enable fails.");
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to set startup commands. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void StartupCommandsLEOnlyHandler()
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			Reset reset = new Reset();
			btAPI.Send(reset);
			list = modeAgnosticDataReceiver.ReceiveAll(reset.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReset packet = (CommandCompleteForReset)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReset), list);
			if (!CheckStatusForPacket(packet, reset.GetType().ToString()))
			{
				throw new Exception("Reset fails.");
			}
			ReadLocalVersionInformation readLocalVersionInformation = new ReadLocalVersionInformation();
			btAPI.Send(readLocalVersionInformation);
			list = modeAgnosticDataReceiver.ReceiveAll(readLocalVersionInformation.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReadLocalVersionInformation packet2 = (CommandCompleteForReadLocalVersionInformation)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReadLocalVersionInformation), list);
			if (!CheckStatusForPacket(packet2, readLocalVersionInformation.GetType().ToString()))
			{
				throw new Exception("Read local version information fails.");
			}
			ReadLocalSupportedFeatures readLocalSupportedFeatures = new ReadLocalSupportedFeatures();
			btAPI.Send(readLocalSupportedFeatures);
			list = modeAgnosticDataReceiver.ReceiveAll(readLocalSupportedFeatures.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReadLocalSupportedFeatures commandCompleteForReadLocalSupportedFeatures = (CommandCompleteForReadLocalSupportedFeatures)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReadLocalSupportedFeatures), list);
			if (!CheckStatusForPacket(commandCompleteForReadLocalSupportedFeatures, readLocalSupportedFeatures.GetType().ToString()))
			{
				throw new Exception("Read local supported features fails.");
			}
			localSupportedFeatures = commandCompleteForReadLocalSupportedFeatures.UserFields.GetLmpFeaturesAsSupportedFeaturesEnumCollection();
			LeSetEventMask leSetEventMask = new LeSetEventMask();
			leSetEventMask.UserFields.LeEventMask = ulong.MaxValue;
			btAPI.Send(leSetEventMask);
			list = modeAgnosticDataReceiver.ReceiveAll(leSetEventMask.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForLeSetEventMask packet3 = (CommandCompleteForLeSetEventMask)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForLeSetEventMask), list);
			if (!CheckStatusForPacket(packet3, leSetEventMask.GetType().ToString()))
			{
				throw new Exception("LE Set event mask fails.");
			}
			LeReadBufferSize leReadBufferSize = new LeReadBufferSize();
			btAPI.Send(leReadBufferSize);
			list = modeAgnosticDataReceiver.ReceiveAll(leReadBufferSize.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForLeReadBufferSize commandCompleteForLeReadBufferSize = (CommandCompleteForLeReadBufferSize)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForLeReadBufferSize), list);
			if (!CheckStatusForPacket(commandCompleteForLeReadBufferSize, leReadBufferSize.GetType().ToString()))
			{
				throw new Exception("Read LE buffer size fails.");
			}
			leLocalACLBufferSize = Convert.ToInt32(commandCompleteForLeReadBufferSize.UserFields.HcTotalNumLeDataPackets);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to set startup commands. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void BDAddrssAndVersionHandler()
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			ReadBdAddr readBdAddr = new ReadBdAddr();
			btAPI.Send(readBdAddr);
			list = modeAgnosticDataReceiver.ReceiveAll(readBdAddr.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReadBdAddr commandCompleteForReadBdAddr = (CommandCompleteForReadBdAddr)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReadBdAddr), list);
			if (!CheckStatusForPacket(commandCompleteForReadBdAddr, readBdAddr.GetType().ToString()))
			{
				throw new Exception("Read BD address fails.");
			}
			localBDAddress = $"{commandCompleteForReadBdAddr.UserFields.BdAddr:X12}";
			EdlGetAppVerRequest packet = new EdlGetAppVerRequest();
			btAPI.Send(packet);
			PacketBase packetBase = modeAgnosticDataReceiver.Receive(2000);
			if (packetBase is EdlGetAppVerResponse)
			{
				EdlGetAppVerResponse edlGetAppVerResponse = (EdlGetAppVerResponse)packetBase;
				localApplicationInfo = "";
				for (int i = 0; i < edlGetAppVerResponse.UserFields.VersionStringList.Count; i++)
				{
					char c = Convert.ToChar(edlGetAppVerResponse.UserFields.VersionStringList[i]);
					localApplicationInfo += c;
				}
			}
			else
			{
				CommandCompleteForEdlGetAppVerRequest commandCompleteForEdlGetAppVerRequest = (CommandCompleteForEdlGetAppVerRequest)packetBase;
				localApplicationInfo = "";
				for (int j = 0; j < commandCompleteForEdlGetAppVerRequest.UserFields.VersionStringList.Count; j++)
				{
					char c2 = Convert.ToChar(commandCompleteForEdlGetAppVerRequest.UserFields.VersionStringList[j]);
					localApplicationInfo += c2;
				}
			}
			if (this.StartupEventHandler != null)
			{
				this.StartupEventHandler(this, localACLPacketLength, localSCOPacketLength, localACLBufferSize, localSCOBufferSize, localBDAddress, localApplicationInfo, leLocalACLBufferSize);
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to set startup commands. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void BDAddressHandler()
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			ReadBdAddr readBdAddr = new ReadBdAddr();
			btAPI.Send(readBdAddr);
			list = modeAgnosticDataReceiver.ReceiveAll(readBdAddr.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReadBdAddr commandCompleteForReadBdAddr = (CommandCompleteForReadBdAddr)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReadBdAddr), list);
			if (!CheckStatusForPacket(commandCompleteForReadBdAddr, readBdAddr.GetType().ToString()))
			{
				throw new Exception("Read BD address fails.");
			}
			localBDAddress = $"{commandCompleteForReadBdAddr.UserFields.BdAddr:X12}";
			if (this.StartupEventHandler != null)
			{
				this.StartupEventHandler(this, localACLPacketLength, localSCOPacketLength, localACLBufferSize, localSCOBufferSize, localBDAddress, localApplicationInfo, leLocalACLBufferSize);
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to set startup commands. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void LocalSupportedFeaturesHandler()
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(btAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			ReadLocalSupportedFeatures readLocalSupportedFeatures = new ReadLocalSupportedFeatures();
			btAPI.Send(readLocalSupportedFeatures);
			list = modeAgnosticDataReceiver.ReceiveAll(readLocalSupportedFeatures.ExpectedResponseTypes, eventTimeout);
			CommandCompleteForReadLocalSupportedFeatures commandCompleteForReadLocalSupportedFeatures = (CommandCompleteForReadLocalSupportedFeatures)PacketHelper.GetPacketTypeFromList(typeof(CommandCompleteForReadLocalSupportedFeatures), list);
			if (!CheckStatusForPacket(commandCompleteForReadLocalSupportedFeatures, readLocalSupportedFeatures.GetType().ToString()))
			{
				throw new Exception("Read local supported features fails.");
			}
			localSupportedFeatures = commandCompleteForReadLocalSupportedFeatures.UserFields.GetLmpFeaturesAsSupportedFeaturesEnumCollection();
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to read local supported features. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void RunScriptHandler()
	{
		combinedScripter.RunScriptAsync(scriptFileName, scriptFileLocation);
	}

	private void SetAclLogModeHandler()
	{
		btAPI.SetAclDataDisplay();
	}

	private void StartLeTransmitterTest()
	{
		LeTransmitterTest leTransmitterTest = new LeTransmitterTest();
		leTransmitterTest.UserFields.TxFrequency = leProdTest_LeTx_Channel;
		leTransmitterTest.UserFields.LengthOfTestData = leProdTest_LeTx_TestDataLength;
		leTransmitterTest.UserFields.PacketPayload = leProdTest_LeTx_PacketPayload;
		btAPI.Send(leTransmitterTest);
	}

	private void StartLeEnhancedTransmitterTest()
	{
		LeEnhancedTransmitterTest leEnhancedTransmitterTest = new LeEnhancedTransmitterTest();
		leEnhancedTransmitterTest.UserFields.TxChannel = leProdTest_LeEnhancedTx_TxChannel;
		leEnhancedTransmitterTest.UserFields.LengthOfTestData = leProdTest_LeEnhancedTx_TestDataLength;
		leEnhancedTransmitterTest.UserFields.PacketPayload = leProdTest_LeEnhancedTx_PacketPayload;
		leEnhancedTransmitterTest.UserFields.Phy = leProdTest_LeEnhancedTx_Phy;
		btAPI.Send(leEnhancedTransmitterTest);
	}

	private void StartLeReceiverTest()
	{
		LeReceiverTest leReceiverTest = new LeReceiverTest();
		leReceiverTest.UserFields.RxFrequency = leProdTest_LeRx_Channel;
		btAPI.Send(leReceiverTest);
	}

	private void StartLeEnhancedReceiverTest()
	{
		LeEnhancedReceiverTest leEnhancedReceiverTest = new LeEnhancedReceiverTest();
		leEnhancedReceiverTest.UserFields.RxChannel = leProdTest_LeEnhancedRx_RxChannel;
		leEnhancedReceiverTest.UserFields.Phy = leProdTest_LeEnhancedRx_Phy;
		leEnhancedReceiverTest.UserFields.ModulationIndex = leProdTest_LeEnhancedRx_ModulationIndex;
		btAPI.Send(leEnhancedReceiverTest);
	}

	private void StartLeTestEnd()
	{
		LeTestEnd packet = new LeTestEnd();
		btAPI.Send(packet);
	}

	private void StartProdTestLeTxContinuous()
	{
		ProdTestLeTxContinuous prodTestLeTxContinuous = new ProdTestLeTxContinuous();
		prodTestLeTxContinuous.UserFields.ChannelNumber = leProdTest_ContinuousTxTest_ChannelNumber;
		prodTestLeTxContinuous.UserFields.TransmitOutputPower = leProdTest_ContinuousTxTest_TransmitOutputPower;
		prodTestLeTxContinuous.UserFields.TransmitType = leProdTest_ContinuousTxTest_TransmitType;
		prodTestLeTxContinuous.UserFields.PatternLength = leProdTest_ContinuousTxTest_PatternLength;
		prodTestLeTxContinuous.UserFields.BitPattern = leProdTest_ContinuousTxTest_BitPattern;
		btAPI.Send(prodTestLeTxContinuous);
	}

	private void SetDecodePacketHandler(bool decodePacket, bool packetResponse, bool conciseLog)
	{
		btAPI.SetDecodePacket(decodePacket, packetResponse, conciseLog);
	}

	private bool CheckStatusForPacket(PacketBase packet, string packetName)
	{
		foreach (PacketFieldInfo fieldInfo in packet.Info.FieldInfoList)
		{
			if (fieldInfo.ParameterName == "Status")
			{
				ErrorCodeEnum errorCodeEnum = ErrorCodeInfo.ValueToErrorCode(Convert.ToUInt32(fieldInfo.Value, 16));
				if (errorCodeEnum != 0)
				{
					logger.Enqueue(new LogMessage(LogMessageType.Error, packetName + " status field indicates error: " + errorCodeEnum));
				}
				return true;
			}
		}
		logger.Enqueue(new LogMessage(LogMessageType.Error, "Packet type doesn't have a status field: " + packetName));
		return false;
	}
}
