From e005f2f4898742b486e577a7abc216ccd3403d15 Mon Sep 17 00:00:00 2001 From: Markus Lideck Date: Tue, 4 Jun 2019 00:10:54 +0200 Subject: [PATCH] started work on issue #46 --- .../ZigBeeDongleXBee.cs | 3 +- .../ZigBeeNet.Hardware.Digi.XBee.csproj | 5 +- .../Network/NetworkManager.cs | 34 ++++++++-- .../Network/NetworkStateListener.cs | 36 ----------- .../ZigBeeDongleTiCc2531.cs | 64 ++++++++++++++----- .../Transport/IZigBeeTransportTransmit.cs | 3 +- libraries/ZigBeeNet/ZigBeeNetworkManager.cs | 4 +- samples/ZigBeeNet.PlayGround/Program.cs | 2 +- 8 files changed, 87 insertions(+), 64 deletions(-) delete mode 100644 libraries/ZigBeeNet.Hardware.TI.CC2531/Network/NetworkStateListener.cs diff --git a/libraries/ZigBeeNet.Hardware.Digi.XBee/ZigBeeDongleXBee.cs b/libraries/ZigBeeNet.Hardware.Digi.XBee/ZigBeeDongleXBee.cs index 01c04bb7..76486e17 100644 --- a/libraries/ZigBeeNet.Hardware.Digi.XBee/ZigBeeDongleXBee.cs +++ b/libraries/ZigBeeNet.Hardware.Digi.XBee/ZigBeeDongleXBee.cs @@ -8,6 +8,7 @@ using ZigBeeNet.Hardware.Digi.XBee.Internal.Protocol; using ZigBeeNet.Security; using ZigBeeNet.Transport; +using System.Threading.Tasks; namespace ZigBeeNet.Hardware.Digi.XBee { @@ -199,7 +200,7 @@ public ZigBeeStatus Initialize() return ZigBeeStatus.SUCCESS; } - public ZigBeeStatus Startup(bool reinitialize) + public async Task Startup(bool reinitialize) { Log.Debug("XBee dongle startup."); diff --git a/libraries/ZigBeeNet.Hardware.Digi.XBee/ZigBeeNet.Hardware.Digi.XBee.csproj b/libraries/ZigBeeNet.Hardware.Digi.XBee/ZigBeeNet.Hardware.Digi.XBee.csproj index d7d1122c..7e56078e 100644 --- a/libraries/ZigBeeNet.Hardware.Digi.XBee/ZigBeeNet.Hardware.Digi.XBee.csproj +++ b/libraries/ZigBeeNet.Hardware.Digi.XBee/ZigBeeNet.Hardware.Digi.XBee.csproj @@ -6,6 +6,9 @@ - + + + + \ No newline at end of file diff --git a/libraries/ZigBeeNet.Hardware.TI.CC2531/Network/NetworkManager.cs b/libraries/ZigBeeNet.Hardware.TI.CC2531/Network/NetworkManager.cs index 3e5418dc..ab3a6b2c 100644 --- a/libraries/ZigBeeNet.Hardware.TI.CC2531/Network/NetworkManager.cs +++ b/libraries/ZigBeeNet.Hardware.TI.CC2531/Network/NetworkManager.cs @@ -17,7 +17,7 @@ namespace ZigBeeNet.Hardware.TI.CC2531.Network { - public class NetworkManager + public class NetworkManager : IAsynchronousCommandListener { private const int DEFAULT_TIMEOUT = 8000; private const string TIMEOUT_KEY = "zigbee.driver.cc2531.timeout"; @@ -77,6 +77,8 @@ public class NetworkManager private static ManualResetEventSlim _hardwareSync = new ManualResetEventSlim(false); + public event EventHandler OnStateChanged; + private byte[] _ep; private byte[] _prof; private byte[] _dev; @@ -84,8 +86,6 @@ public class NetworkManager private ushort[][] _inp; private ushort[][] _out; - private NetworkStateListener _announceListenerFilter = new NetworkStateListener(); - private List _messageListeners = new List(); private AFMessageListenerFilter _afMessageListenerFilter; @@ -97,9 +97,8 @@ public class NetworkManager private object _hardwareWaitSync = new object(); private object _networkSync = new object(); - public NetworkManager(ICommandInterface commandInterface, NetworkMode mode, long timeout) + public NetworkManager(ICommandInterface commandInterface, NetworkMode mode) { - _announceListenerFilter.OnStateChanged += (object sender, DriverStatus status) => SetState(status); _afMessageListenerFilter = new AFMessageListenerFilter(_messageListeners); _mode = mode; @@ -113,6 +112,29 @@ public NetworkManager(ICommandInterface commandInterface, NetworkMode mode, long _state = DriverStatus.CLOSED; } + public void ReceivedAsynchronousCommand(ZToolPacket packet) + { + if (packet is ZDO_STATE_CHANGE_IND stateInd) + { + switch (stateInd.Status) + { + case DeviceState.Started_as_ZigBee_Coordinator: + Log.Debug("Started as Zigbee Coordinator"); + SetState(DriverStatus.NETWORK_READY); + OnStateChanged?.Invoke(this, DriverStatus.NETWORK_READY); + break; + default: + break; + } + } + } + + public void ReceivedUnclaimedSynchronousCommandResponse(ZToolPacket packet) + { + // Processing not requiered + throw new NotImplementedException(); // TODO: Realy throwing an exception ? + } + /// /// Different hardware may use a different "Magic Number" to skip waiting in the bootloader. Otherwise /// the dongle may wait in the bootloader for 60 seconds after it's powered on or reset. @@ -424,7 +446,7 @@ private void PostHardwareEnabled() _commandInterface.AddAsynchronousCommandListener(_afMessageListenerFilter); //} // if (!announceListeners.contains(announceListenerFilter)) { - _commandInterface.AddAsynchronousCommandListener(_announceListenerFilter); + _commandInterface.AddAsynchronousCommandListener(this); // } } diff --git a/libraries/ZigBeeNet.Hardware.TI.CC2531/Network/NetworkStateListener.cs b/libraries/ZigBeeNet.Hardware.TI.CC2531/Network/NetworkStateListener.cs deleted file mode 100644 index 3194b4bd..00000000 --- a/libraries/ZigBeeNet.Hardware.TI.CC2531/Network/NetworkStateListener.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using ZigBeeNet.Hardware.TI.CC2531.Packet; -using ZigBeeNet.Hardware.TI.CC2531.Packet.ZDO; -using Serilog; - -namespace ZigBeeNet.Hardware.TI.CC2531.Network -{ - internal class NetworkStateListener : IAsynchronousCommandListener - { - public event EventHandler OnStateChanged; - - public void ReceivedAsynchronousCommand(ZToolPacket packet) - { - if(packet is ZDO_STATE_CHANGE_IND stateInd) - { - switch(stateInd.Status) - { - case DeviceState.Started_as_ZigBee_Coordinator: - Log.Debug("Started as Zigbee Coordinator"); - OnStateChanged?.Invoke(this, DriverStatus.NETWORK_READY); - break; - default: - break; - } - } - } - - public void ReceivedUnclaimedSynchronousCommandResponse(ZToolPacket packet) - { - // Processing not requiered - throw new NotImplementedException(); // TODO: Realy throwing an exception ? - } - } -} diff --git a/libraries/ZigBeeNet.Hardware.TI.CC2531/ZigBeeDongleTiCc2531.cs b/libraries/ZigBeeNet.Hardware.TI.CC2531/ZigBeeDongleTiCc2531.cs index 8d201d72..28439c7f 100644 --- a/libraries/ZigBeeNet.Hardware.TI.CC2531/ZigBeeDongleTiCc2531.cs +++ b/libraries/ZigBeeNet.Hardware.TI.CC2531/ZigBeeDongleTiCc2531.cs @@ -13,6 +13,7 @@ using ZigBeeNet.Transport; using ZigBeeNet.ZCL; using static ZigBeeNet.ZigBeeNetworkManager; +using System.Threading.Tasks; namespace ZigBeeNet.Hardware.TI.CC2531 { @@ -27,6 +28,8 @@ public class ZigBeeDongleTiCc2531 : IZigBeeTransportTransmit, IApplicationFramew private List _supportedInputClusters = new List(); private List _supportedOutputClusters = new List(); + private TaskCompletionSource _startupTask; + public string VersionString { get; set; } public IeeeAddress IeeeAddress { get; set; } @@ -76,7 +79,18 @@ public ZigBeeKey TcLinkKey public ZigBeeDongleTiCc2531(IZigBeePort serialPort) { - _networkManager = new NetworkManager(new CommandInterfaceImpl(serialPort), NetworkMode.Coordinator, 2500); + _networkManager = new NetworkManager(new CommandInterfaceImpl(serialPort), NetworkMode.Coordinator); + _networkManager.OnStateChanged += NetworkManager_OnStateChanged; + } + + private void NetworkManager_OnStateChanged(object sender, DriverStatus e) + { + if (e == DriverStatus.NETWORK_READY) + { + CreateEndpoint(1, 0x104); + + _startupTask?.SetResult(ZigBeeStatus.SUCCESS); + } } public void SetMagicNumber(byte magicNumber) @@ -216,7 +230,7 @@ public void Shutdown() _networkManager.Shutdown(); } - public ZigBeeStatus Startup(bool reinitialize) + public async Task Startup(bool reinitialize) { Log.Debug("CC2531 transport startup"); @@ -229,25 +243,43 @@ public ZigBeeStatus Startup(bool reinitialize) return ZigBeeStatus.INVALID_STATE; } - // TODO: ugly ugly ugly - // See: https://github.com/zigbeenet/ZigbeeNet/issues/46 - while (true) + _startupTask = new TaskCompletionSource(); + + var t = _startupTask.Task; + var timeoutTask = Task.Delay(10000); + + if (t == await Task.WhenAny(t, timeoutTask).ConfigureAwait(false)) { - if (_networkManager.GetDriverStatus() == DriverStatus.NETWORK_READY) - { - break; - } - if (_networkManager.GetDriverStatus() == DriverStatus.CLOSED) - { - return ZigBeeStatus.BAD_RESPONSE; - } + return ZigBeeStatus.SUCCESS; + } + else + { + /* Timeout */ + Log.Debug("Startup timeout"); - Thread.Sleep(50); + return ZigBeeStatus.BAD_RESPONSE; } - CreateEndpoint(1, 0x104); - return ZigBeeStatus.SUCCESS; + //// TODO: ugly ugly ugly + //// See: https://github.com/zigbeenet/ZigbeeNet/issues/46 + //while (true) + //{ + // if (_networkManager.GetDriverStatus() == DriverStatus.NETWORK_READY) + // { + // break; + // } + // if (_networkManager.GetDriverStatus() == DriverStatus.CLOSED) + // { + // return ZigBeeStatus.BAD_RESPONSE; + // } + + // Thread.Sleep(50); + //} + + //CreateEndpoint(1, 0x104); + + //return ZigBeeStatus.SUCCESS; } private byte GetSendingEndpoint(ushort profileId) diff --git a/libraries/ZigBeeNet/Transport/IZigBeeTransportTransmit.cs b/libraries/ZigBeeNet/Transport/IZigBeeTransportTransmit.cs index 082e667d..91b04377 100644 --- a/libraries/ZigBeeNet/Transport/IZigBeeTransportTransmit.cs +++ b/libraries/ZigBeeNet/Transport/IZigBeeTransportTransmit.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using System.Threading.Tasks; using ZigBeeNet.Security; using ZigBeeNet.ZCL; @@ -28,7 +29,7 @@ public interface IZigBeeTransportTransmit /// /// /// true if startup was success - ZigBeeStatus Startup(bool reinitialize); + Task Startup(bool reinitialize); /// /// Shuts down a transport interface. diff --git a/libraries/ZigBeeNet/ZigBeeNetworkManager.cs b/libraries/ZigBeeNet/ZigBeeNetworkManager.cs index c196f5fd..ca33fcb7 100644 --- a/libraries/ZigBeeNet/ZigBeeNetworkManager.cs +++ b/libraries/ZigBeeNet/ZigBeeNetworkManager.cs @@ -470,7 +470,7 @@ public ZigBeeStatus SetZigBeeInstallKey(ZigBeeKey key) /// /// with the status of function /// - public ZigBeeStatus Startup(bool reinitialize) + public async Task Startup(bool reinitialize) { lock (_networkStateSync) { @@ -480,7 +480,7 @@ public ZigBeeStatus Startup(bool reinitialize) } } - ZigBeeStatus status = Transport.Startup(reinitialize); + ZigBeeStatus status = await Transport.Startup(reinitialize); if (status != ZigBeeStatus.SUCCESS) { diff --git a/samples/ZigBeeNet.PlayGround/Program.cs b/samples/ZigBeeNet.PlayGround/Program.cs index 0ac2075b..bf6a9a40 100644 --- a/samples/ZigBeeNet.PlayGround/Program.cs +++ b/samples/ZigBeeNet.PlayGround/Program.cs @@ -112,7 +112,7 @@ static async Task Main(string[] args) ((ZigBeeDongleTiCc2531)dongle).SetLedMode(2, false); // red led } - ZigBeeStatus startupSucceded = networkManager.Startup(false); + ZigBeeStatus startupSucceded = await networkManager.Startup(false); if (startupSucceded == ZigBeeStatus.SUCCESS) {