using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using QCRPG.Framework;
using QCRPG.TSL.ZigBee.Packets;

namespace QCRPG.TSL.ZigBee;

public class ZigBeeMainWorkerThread : WorkerThreadBase
{
	public delegate void DataTransferTransmitHandler(object sender, int transmitByteCount, int transmitPacketCount);

	public delegate void EndDataTransferHandler(object sender);

	public delegate void StartupCommandsEventHandler(object sender, string DUTAddress, string ApplicationInfo);

	public delegate void UpdateNoAckPacketsHandler(object sender);

	public delegate void UpdateChAccessFailPacketsHandler(object sender);

	private ZigBeeAPI ZigBeeAPI;

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

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

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

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

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

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

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

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

	private int connectionhandler;

	private DutaddressmodeEnum localAddrMode = DutaddressmodeEnum.ShortAddress_16_BIT;

	private DutaddressmodeEnum dstAddrMode = DutaddressmodeEnum.ShortAddress_16_BIT;

	private string localAddr;

	private long dstAddr;

	private uint panId;

	private uint packetLength;

	private uint channelID;

	private int dataPattern = 85;

	private int numPacketsToSend;

	private bool sequentialDataPatternEnable;

	private bool checkReceiveDataIntegrityEnable = true;

	private bool continuousDataEnabled = true;

	private bool ackTx = true;

	private bool gtsTx;

	private bool indirectTx;

	private int dataTimeout = 3000;

	protected string localApplicationInfo;

	private bool bStart = true;

	private bool bSendLastPacket = true;

	private int msduPacketsSent;

	private int bytesSent;

	private bool decodePacket = true;

	private bool packetResponse = true;

	private bool conciseLog;

	private byte[] sendRawBytes;

	private string nvmFilename;

	public event DataTransferTransmitHandler TransmitDataTransferHandler;

	public event EndDataTransferHandler EndDataTransferEventHandler;

	public event StartupCommandsEventHandler StartupEventHandler;

	public event UpdateNoAckPacketsHandler UpdatePacketsMissingAckHandler;

	public event UpdateChAccessFailPacketsHandler UpdatePacketsChAccessFailureHandler;

	public ZigBeeMainWorkerThread(Logger logger, ZigBeeAPI ZigBeeAPI)
		: base(logger)
	{
		this.ZigBeeAPI = ZigBeeAPI;
	}

	protected override void Run()
	{
		logger.Enqueue(new LogMessage(LogMessageType.Info, "15.4 main thread starting"));
		ManualResetEvent[] array = new ManualResetEvent[9] { shutdownThreadEvent, sendRawBytesEvent, writeNvmEvent, mlmeResetEvent, dataTransferStartEvent, enableRxIdleEvent, setDecodePacketEvent, stopRemoteDataTransferEvent, writeAddressEvent };
		while (true)
		{
			int num = WaitHandle.WaitAny(array);
			if (array[num] == shutdownThreadEvent)
			{
				break;
			}
			if (array[num] == sendRawBytesEvent)
			{
				SendRawBytesHandler(sendRawBytes);
				sendRawBytesEvent.Reset();
			}
			else if (array[num] == writeNvmEvent)
			{
				WriteNvmHandler(nvmFilename);
				writeNvmEvent.Reset();
			}
			else if (array[num] == dataTransferStartEvent)
			{
				bStart = true;
				StartDataTransferHandler();
				dataTransferStartEvent.Reset();
			}
			else if (array[num] == enableRxIdleEvent)
			{
				ZigBeeEnableRxIdleHandler();
				enableRxIdleEvent.Reset();
			}
			else if (array[num] == setDecodePacketEvent)
			{
				SetDecodePacketHandler(decodePacket, packetResponse, conciseLog);
				setDecodePacketEvent.Reset();
			}
			else if (array[num] == stopRemoteDataTransferEvent)
			{
				StopRemoteDataTransferHandler();
				stopRemoteDataTransferEvent.Reset();
			}
			else if (array[num] == writeAddressEvent)
			{
				ZigBeeWriteLocalAddressHandler(localAddrMode, localAddr);
				writeAddressEvent.Reset();
			}
		}
		logger.Enqueue(new LogMessage(LogMessageType.Info, "15.4 main thread ending"));
	}

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

	public void WriteNvm(string filename)
	{
		nvmFilename = filename;
		writeNvmEvent.Set();
	}

	public void EnableRxIdle()
	{
		enableRxIdleEvent.Set();
	}

	public void SetChannel(uint chId)
	{
		channelID = chId;
		ZigBeeSetChannelHandler();
	}

	public void StopRemoteDataTransfer()
	{
		bStart = false;
		bSendLastPacket = false;
	}

	public void StopRemoteDataTransfer(int connectionHandle, DutaddressmodeEnum srcAddrMode, DutaddressmodeEnum dstAddrMode, uint dstAddr, uint dstPanId, uint channelID, uint packetLength, int dataPattern, bool continuousDataEnabled, bool sequentialDataPatternEnable, bool checkReceiveDataIntegrityEnable)
	{
		connectionhandler = connectionHandle;
		localAddrMode = srcAddrMode;
		this.dstAddrMode = dstAddrMode;
		this.dstAddr = dstAddr;
		panId = dstPanId;
		this.channelID = channelID;
		this.packetLength = packetLength;
		this.dataPattern = dataPattern;
		this.sequentialDataPatternEnable = sequentialDataPatternEnable;
		this.continuousDataEnabled = continuousDataEnabled;
		bStart = false;
		bSendLastPacket = false;
		stopRemoteDataTransferEvent.Set();
	}

	private void StopRemoteDataTransferHandler()
	{
		SendEndDataPacket(abortTransfer: true);
	}

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

	private void WriteNvmHandler(string filename)
	{
		try
		{
			ZigBeeAPI.WriteNVM(filename);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error writing 15.4 NVM!");
		}
	}

	public void ReadAddress(DutaddressmodeEnum localAddressMode)
	{
		ZigBeeReadAddressHandler(localAddressMode);
	}

	private void ZigBeeReadAddressHandler(DutaddressmodeEnum localAddressMode)
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(ZigBeeAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			MlmeGet mlmeGet = new MlmeGet();
			if (localAddressMode == DutaddressmodeEnum.ShortAddress_16_BIT)
			{
				mlmeGet._UserFields.Pibattribute = PibattributeInfo.PibattributeToValue(PibattributeEnum.WPAN_PIB_MAC_SHORT_ADDRESS);
			}
			else
			{
				mlmeGet._UserFields.Pibattribute = PibattributeInfo.PibattributeToValue(PibattributeEnum.WPAN_PIB_MAC_EXT_ADDRESS);
			}
			mlmeGet._UserFields.Pibattributeindex = 0u;
			ZigBeeAPI.Send(mlmeGet);
			list = modeAgnosticDataReceiver.ReceiveAll(mlmeGet.ExpectedResponseTypes, dataTimeout);
			MlmeGetConfirmation mlmeGetConfirmation = (MlmeGetConfirmation)PacketHelper.GetPacketTypeFromList(typeof(MlmeGetConfirmation), list);
			if (!CheckStatusForPacket(mlmeGetConfirmation, mlmeGet.GetType().ToString()))
			{
				throw new Exception("Read 15.4 address fails.");
			}
			localAddr = "";
			for (int i = 0; i < mlmeGetConfirmation.UserFields.PibattributevalueList.Count; i++)
			{
				localAddr += mlmeGetConfirmation.UserFields.PibattributevalueList[i].ToString("X2");
			}
			localApplicationInfo = "";
			this.StartupEventHandler(this, localAddr, localApplicationInfo);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to read address. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	public void WriteLocalAddress(DutaddressmodeEnum localAddressMode, string address)
	{
		localAddrMode = localAddressMode;
		localAddr = address;
		writeAddressEvent.Set();
	}

	private void ZigBeeWriteLocalAddressHandler(DutaddressmodeEnum localAddressMode, string address)
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(ZigBeeAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			MlmeSet mlmeSet = new MlmeSet();
			mlmeSet._UserFields.Pibattributeindex = 0u;
			ulong.TryParse(localAddr, NumberStyles.HexNumber, null, out var result);
			mlmeSet._UserFields.PibattributevalueList.Clear();
			if (localAddressMode == DutaddressmodeEnum.ShortAddress_16_BIT)
			{
				mlmeSet._UserFields.Pibattribute = PibattributeInfo.PibattributeToValue(PibattributeEnum.WPAN_PIB_MAC_SHORT_ADDRESS);
				mlmeSet._UserFields.Pibattributelength = 2u;
			}
			else
			{
				mlmeSet._UserFields.Pibattribute = PibattributeInfo.PibattributeToValue(PibattributeEnum.WPAN_PIB_MAC_EXT_ADDRESS);
				mlmeSet._UserFields.Pibattributelength = 8u;
			}
			for (int num = (int)(mlmeSet._UserFields.Pibattributelength - 1); num > -1; num--)
			{
				mlmeSet._UserFields.PibattributevalueList.Add((uint)((result >> 8 * num) & 0xFF));
			}
			ZigBeeAPI.Send(mlmeSet);
			list = modeAgnosticDataReceiver.ReceiveAll(mlmeSet.ExpectedResponseTypes, dataTimeout);
			MlmeSetConfirmation packet = (MlmeSetConfirmation)PacketHelper.GetPacketTypeFromList(typeof(MlmeSetConfirmation), list);
			if (!CheckStatusForPacket(packet, mlmeSet.GetType().ToString()))
			{
				throw new Exception("Read 15.4 address fails.");
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to write address. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void ZigBeeEnableRxIdleHandler()
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(ZigBeeAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			MlmeSet mlmeSet = new MlmeSet();
			mlmeSet._UserFields.Pibattributeindex = 0u;
			mlmeSet._UserFields.Pibattribute = PibattributeInfo.PibattributeToValue(PibattributeEnum.WPAN_PIB_MAC_RX_ON_WHEN_IDLE);
			mlmeSet._UserFields.Pibattributelength = 1u;
			mlmeSet._UserFields.PibattributevalueList.Add(1u);
			ZigBeeAPI.Send(mlmeSet);
			list = modeAgnosticDataReceiver.ReceiveAll(mlmeSet.ExpectedResponseTypes, dataTimeout);
			MlmeSetConfirmation packet = (MlmeSetConfirmation)PacketHelper.GetPacketTypeFromList(typeof(MlmeSetConfirmation), list);
			if (!CheckStatusForPacket(packet, mlmeSet.GetType().ToString()))
			{
				throw new Exception("Enable 15.4 Rx on idle fails.");
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to enable Rx on idle. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	private void ZigBeeSetChannelHandler()
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(ZigBeeAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			MlmeSet mlmeSet = new MlmeSet();
			mlmeSet._UserFields.Pibattributeindex = 0u;
			mlmeSet._UserFields.Pibattribute = PibattributeInfo.PibattributeToValue(PibattributeEnum.WPAN_PIB_PHY_CURRENT_CHANNEL);
			mlmeSet._UserFields.Pibattributelength = 1u;
			mlmeSet._UserFields.PibattributevalueList.Add(channelID);
			ZigBeeAPI.Send(mlmeSet);
			list = modeAgnosticDataReceiver.ReceiveAll(mlmeSet.ExpectedResponseTypes, dataTimeout);
			MlmeSetConfirmation packet = (MlmeSetConfirmation)PacketHelper.GetPacketTypeFromList(typeof(MlmeSetConfirmation), list);
			if (!CheckStatusForPacket(packet, mlmeSet.GetType().ToString()))
			{
				throw new Exception("Set 15.4 channel fails.");
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to set channel. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

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

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

	public void SetPanId(uint panId)
	{
		this.panId = panId;
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(ZigBeeAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		try
		{
			bool flag = false;
			MlmeSet mlmeSet = new MlmeSet();
			mlmeSet._UserFields.Pibattributeindex = 0u;
			mlmeSet._UserFields.Pibattribute = PibattributeInfo.PibattributeToValue(PibattributeEnum.WPAN_PIB_MAC_PAN_ID);
			mlmeSet._UserFields.Pibattributelength = 2u;
			mlmeSet._UserFields.PibattributevalueList.Add(panId >> 8);
			mlmeSet._UserFields.PibattributevalueList.Add(panId & 0xFFu);
			ZigBeeAPI.Send(mlmeSet);
			list = modeAgnosticDataReceiver.ReceiveAll(mlmeSet.ExpectedResponseTypes, dataTimeout);
			MlmeSetConfirmation packet = (MlmeSetConfirmation)PacketHelper.GetPacketTypeFromList(typeof(MlmeSetConfirmation), list);
			if (!CheckStatusForPacket(packet, mlmeSet.GetType().ToString()))
			{
				throw new Exception("Read 15.4 address fails.");
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to set PAN ID. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
	}

	public void StartDataTransfer(int connectionHandle, DutaddressmodeEnum srcAddrMode, DutaddressmodeEnum dstAddrMode, long dstAddr, uint dstPanId, uint channelID, uint packetLength, int dataPattern, int numPacketsToSend, bool continuousDataEnabled, bool sequentialDataPatternEnable, bool checkReceiveDataIntegrityEnable, bool ackTx, bool gtsTx, bool indirectTx)
	{
		connectionhandler = connectionHandle;
		localAddrMode = srcAddrMode;
		this.dstAddrMode = dstAddrMode;
		this.dstAddr = dstAddr;
		panId = dstPanId;
		this.channelID = channelID;
		this.packetLength = packetLength;
		this.dataPattern = dataPattern;
		this.sequentialDataPatternEnable = sequentialDataPatternEnable;
		this.numPacketsToSend = numPacketsToSend;
		this.continuousDataEnabled = continuousDataEnabled;
		this.ackTx = ackTx;
		this.gtsTx = gtsTx;
		this.indirectTx = indirectTx;
		msduPacketsSent = 0;
		bytesSent = 0;
		dataTransferStartEvent.Set();
		ZigBeeAPI.SetDecodePacket(decodePacket: false, packetResponse: false, conciseLog: true);
	}

	public void SendFirstDataPacket()
	{
		byte b = 0;
		List<byte> list = new List<byte>();
		List<byte> list2 = new List<byte>();
		list2.Add(221);
		list2.Add(221);
		list2.Add(0);
		list2.Add(0);
		list2.Add(0);
		list2.Add(0);
		list2.Add((byte)(packetLength & 0xFFu));
		list2.Add((byte)((uint)dataPattern & 0xFFu));
		b = (byte)(sequentialDataPatternEnable ? 1u : 0u);
		list2.Add(b);
		b = (byte)(checkReceiveDataIntegrityEnable ? 1u : 0u);
		list2.Add(b);
		list2.Add(1);
		list2.Add(0);
		list2.Add(0);
		int num = list2.Count - 2;
		list.Add((byte)((uint)num & 0xFFu));
		list.Add((byte)(num >> 8));
		list.AddRange(list2);
		byte[] array = list.ToArray();
		McpsDataRequest mcpsDataRequest = new McpsDataRequest();
		mcpsDataRequest.UserFields.Msduhandle = (uint)connectionhandler;
		mcpsDataRequest.UserFields.Dstaddr = (ulong)dstAddr;
		mcpsDataRequest.UserFields.Dstaddrmode = (uint)dstAddrMode;
		mcpsDataRequest.UserFields.Dstpanid = panId;
		mcpsDataRequest.UserFields.Srcaddrmode = (uint)localAddrMode;
		mcpsDataRequest.UserFields.Msdulength = (uint)array.Length;
		uint num2 = 0u;
		if (ackTx)
		{
			num2++;
		}
		if (gtsTx)
		{
			num2 += 2;
		}
		if (indirectTx)
		{
			num2 += 4;
		}
		mcpsDataRequest.UserFields.Txoptions = num2;
		for (int i = 0; i < array.Length; i++)
		{
			mcpsDataRequest.UserFields.MsdudataList[i] = array[i];
		}
		SendDataPacket(mcpsDataRequest);
	}

	public void SendEndDataPacket(bool abortTransfer)
	{
		byte b = 0;
		List<byte> list = new List<byte>();
		List<byte> list2 = new List<byte>();
		list2.Add(221);
		list2.Add(221);
		list2.Add(0);
		list2.Add(0);
		list2.Add(0);
		list2.Add(0);
		list2.Add((byte)(packetLength & 0xFFu));
		list2.Add((byte)((uint)dataPattern & 0xFFu));
		b = (byte)(sequentialDataPatternEnable ? 1u : 0u);
		list2.Add(b);
		b = (byte)(checkReceiveDataIntegrityEnable ? 1u : 0u);
		list2.Add(b);
		if (abortTransfer)
		{
			list2.Add(2);
		}
		else
		{
			list2.Add(0);
		}
		list2.Add(0);
		list2.Add(0);
		int num = list2.Count - 2;
		list.Add((byte)((uint)num & 0xFFu));
		list.Add((byte)(num >> 8));
		list.AddRange(list2);
		byte[] array = list.ToArray();
		McpsDataRequest mcpsDataRequest = new McpsDataRequest();
		mcpsDataRequest.UserFields.Msduhandle = (uint)connectionhandler;
		mcpsDataRequest.UserFields.Dstaddr = (ulong)dstAddr;
		mcpsDataRequest.UserFields.Dstaddrmode = (uint)dstAddrMode;
		mcpsDataRequest.UserFields.Dstpanid = panId;
		mcpsDataRequest.UserFields.Srcaddrmode = (uint)localAddrMode;
		mcpsDataRequest.UserFields.Msdulength = (uint)array.Length;
		uint num2 = 0u;
		if (ackTx)
		{
			num2++;
		}
		if (gtsTx)
		{
			num2 += 2;
		}
		if (indirectTx)
		{
			num2 += 4;
		}
		mcpsDataRequest.UserFields.Txoptions = num2;
		for (int i = 0; i < array.Length; i++)
		{
			mcpsDataRequest.UserFields.MsdudataList[i] = array[i];
		}
		SendDataPacket(mcpsDataRequest);
	}

	private void StartDataTransferHandler()
	{
		int i = 0;
		byte b = 0;
		SendFirstDataPacket();
		for (; continuousDataEnabled || i < numPacketsToSend; i++)
		{
			if (!bStart)
			{
				break;
			}
			b = ((!sequentialDataPatternEnable) ? ((byte)dataPattern) : ((byte)(b + 1)));
			SendData(b);
		}
		this.EndDataTransferEventHandler(this);
		SetDecodePacket(decodePacket: true, packetResponse: true, conciseLog: false);
		if (bSendLastPacket)
		{
			SendEndDataPacket(abortTransfer: false);
		}
	}

	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 == ErrorCodeEnum.WPAN_STATUS_CODE_NO_ACK)
				{
					this.UpdatePacketsMissingAckHandler(this);
				}
				if (errorCodeEnum == ErrorCodeEnum.WPAN_STATUS_CODE_CHANNEL_ACCESS_FAILURE)
				{
					this.UpdatePacketsChAccessFailureHandler(this);
				}
				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;
	}

	private void SendData(byte data)
	{
		McpsDataRequest mcpsDataRequest = new McpsDataRequest();
		mcpsDataRequest._UserFields.Srcaddrmode = (uint)localAddrMode;
		mcpsDataRequest._UserFields.Dstaddrmode = (uint)dstAddrMode;
		mcpsDataRequest._UserFields.Dstaddr = (ulong)dstAddr;
		mcpsDataRequest._UserFields.Dstpanid = panId;
		mcpsDataRequest._UserFields.Msdulength = packetLength;
		mcpsDataRequest._UserFields.Msduhandle = (uint)connectionhandler;
		uint num = 0u;
		if (ackTx)
		{
			num++;
		}
		if (gtsTx)
		{
			num += 2;
		}
		if (indirectTx)
		{
			num += 4;
		}
		mcpsDataRequest._UserFields.Txoptions = num;
		mcpsDataRequest._UserFields.MsdudataList.Clear();
		for (int i = 0; i < packetLength; i++)
		{
			if (sequentialDataPatternEnable)
			{
				mcpsDataRequest._UserFields.MsdudataList.Add((uint)i);
			}
			else
			{
				mcpsDataRequest._UserFields.MsdudataList.Add((uint)dataPattern);
			}
		}
		if (SendDataPacket(mcpsDataRequest))
		{
			msduPacketsSent++;
			bytesSent += (int)packetLength;
			this.TransmitDataTransferHandler(this, bytesSent, msduPacketsSent);
		}
	}

	private bool SendDataPacket(McpsDataRequest dataPacket)
	{
		ModeAgnosticDataReceiver modeAgnosticDataReceiver = new ModeAgnosticDataReceiver(ZigBeeAPI);
		modeAgnosticDataReceiver.Startup();
		List<PacketBase> list = null;
		bool flag = false;
		try
		{
			ZigBeeAPI.Send(dataPacket);
			list = modeAgnosticDataReceiver.ReceiveAll(dataPacket.ExpectedResponseTypes, dataTimeout);
			McpsDataConfirmation packet = (McpsDataConfirmation)PacketHelper.GetPacketTypeFromList(typeof(McpsDataConfirmation), list);
			flag = CheckStatusForPacket(packet, dataPacket.GetType().ToString());
			if (!flag)
			{
				throw new Exception("Send 15.4 data packet fails.");
			}
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, "Fail to send data packet. " + ex));
		}
		finally
		{
			modeAgnosticDataReceiver.Shutdown();
		}
		return flag;
	}

	public void StopDataTransfer()
	{
		bStart = false;
		bSendLastPacket = true;
	}
}
