applicationlayer.cs

来自「zwave 无线通讯协议 PC controller 控制器源码」· CS 代码 · 共 1,676 行 · 第 1/5 页

CS
1,676
字号
//////////////////////////////////////////////////////////////////////////////////////////////// 
//
//          #######
//          #   ##    ####   #####    #####  ##  ##   #####
//             ##    ##  ##  ##  ##  ##      ##  ##  ##
//            ##  #  ######  ##  ##   ####   ##  ##   ####
//           ##  ##  ##      ##  ##      ##   #####      ##
//          #######   ####   ##  ##  #####       ##  #####
//                                           #####
//          Z-Wave, the wireless language.
//
//          Copyright Zensys A/S, 2005
//
//          All Rights Reserved
//
//          Description:   
//
//          Author:      Jette Christensen
//
//          Last Changed By:  $Author: jrm $
//          Revision:         $Revision: 1.21 $
//          Last Changed:     $Date: 2007/03/15 15:03:23 $
//
//////////////////////////////////////////////////////////////////////////////////////////////
#region Using directives

using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Threading;
using System.Resources;

#endregion

namespace Zensys.ZWave.Communication
{

    /// <summary>
    /// Summary description for ApplicationLayer.
    /// </summary>
    public class ApplicationLayer : IApplicationLayer, ISessionLayerAsyncCallback, IDisposable
    {
        #region Attributes
        private ISessionLayer sessionLayer;
        private IFrameLayer frameLayer;
        private ITransportLayer transportLayer;
        private const int DEFAULT_TIMEOUT = 10000; // How long in ms to wait for an response
        private const int TIMEOUT = 180000;  // wait 3 minuttes before timing out
        //private ZWaveLogging log = ZWaveLogging.GetInstance("ApplicationLayer", false);
        private NodeTable nodeTable = new NodeTable(100);
        public Node[] NodeList
        {
            get { return nodeTable.getList(); }
        }
        private Node removedNode;
        private Node addedNode;
        private bool disposed;

        #endregion

        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<ApplicationCommandEventArgs> ApplicationCommandEvent;
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<ApplicationSlaveCommandEventArgs> ApplicationSlaveCommandEvent;
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<UnknownCommandEventArgs> UnknownCommandEvent;
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<AddNodeEventArgs> AddNodeEvent;
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<RemoveNodeEventArgs> RemoveNodeEvent;
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<RequestNodeInfoEventArgs> RequestNodeInfoEvent;
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<UpdateEventArgs> UpdateEvent;
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<NodeFailedEventArgs> NodeFailedEvent;
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<SlaveEventArgs> SlaveEvent;
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<TestEventArgs> TestEvent;

        /// <summary>
        /// Contains a mask of which SerialAPI commands supported by connected module
        /// </summary>
        NodeBitmask serialCapabilityMask = new NodeBitmask();

        /// <summary>
        /// 
        /// </summary>
        public ApplicationLayer()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                // Dispose of resources held by this instance.
                // (This process is not shown here.)
                waitForNodeInfoTimer.Dispose();
                // Set the sentinel.
                disposed = true;

                // Suppress finalization of this disposed instance.
                if (disposing)
                {
                    GC.SuppressFinalize(this);
                }
            }
        }

        /// <summary>
        /// Open Port
        /// </summary>
        /// <param name="transportLayerLibrary"></param>
        /// <param name="connectionString"></param>
        public void Open(String transportLayerLibrary, String connectionString)
        {
            System.Reflection.Assembly a = System.Reflection.Assembly.Load(transportLayerLibrary);
            transportLayer = (ITransportLayer)FindInterface(a, "ITransportLayer");
            frameLayer = new FrameLayer();
            frameLayer.EnableTracing(false); //TODO DEBUG
            sessionLayer = new SessionLayer();
            sessionLayer.SetCallbackHandler(this);
#if !WIN_CE
      DataPacketFunc = new DataPacketReceivedDelegate(DataPacketRX);
#endif
            sessionLayer.Open(frameLayer, transportLayer, connectionString);
        }

        /// <summary>
        /// Close Port
        /// </summary>
        public void Close()
        {
            if (sessionLayer != null)
            {
                sessionLayer.Close();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public ISessionLayer GetSessionLayer
        {
            get
            {
                return sessionLayer;
            }
        }

        /// <summary>
        /// GetFrameLayer
        /// </summary>
        /// <returns>frameLayer</returns>
        public IFrameLayer GetFrameLayer()
        {
            return frameLayer;
        }

        /// <summary>
        /// GetTransportLayer
        /// </summary>
        /// <returns>transportLayer</returns>
        public ITransportLayer GetTransportLayer
        {
            get
            {
                return transportLayer;
            }
        }


        /// <summary>
        /// Statistic of frame transmitted and received
        /// </summary>
        /// <returns></returns>
        public ZWStatistics GetStatistics()
        {
            ZWStatistics stats = new ZWStatistics();

            TransportStatistics tstats = transportLayer.GetStatistics();
            stats.bytesReceived = tstats.ReceivedBytes;
            stats.bytesTransmitted = tstats.TransmittedBytes;

            FrameStatistics fstats = frameLayer.GetStatistics();
            stats.receivedAcks = fstats.receivedAcks;
            stats.receivedNaks = fstats.receivedNaks;

            stats.transmittedAcks = fstats.transmittedAcks;
            stats.transmittedNaks = fstats.transmittedNaks;

            stats.droppedFrames = fstats.droppedFrames;
            stats.receivedFrames = fstats.receivedFrames;
            stats.transmittedFrames = fstats.transmittedFrames;
            stats.retransmittedFrames = fstats.retransmittedFrames;

            SessionStatistics sstats = sessionLayer.GetStatistics();
            stats.asyncPackets = sstats.asyncPackets;
            stats.duplicatePackets = sstats.duplicatePackets;
            stats.transmittedPackets = sstats.transmittedPackets;
            stats.receivedPackets = sstats.receivedPackets;
            stats.receiveTimeouts = sstats.receiveTimeouts;

            return stats;
        }

        private delegate void DataPacketReceivedDelegate(DataFrame.CommandType cmd, DataPacket packet);

#if !WIN_CE
    private DataPacketReceivedDelegate DataPacketFunc;

    private void DataPacketDone(IAsyncResult ar)
    {
      //Make sure we have a clean exit
      DataPacketFunc.EndInvoke(ar);
    }
#endif

        /// <summary>
        /// This class is used to pass the command and packet when they are processed asynchronously in
        /// DataPacketRX_CF
        /// </summary>
        private class cmdpacket
        {
            /// <summary>
            /// The command
            /// </summary>
            public DataFrame.CommandType cmd;
            /// <summary>
            /// The packet
            /// </summary>
            public DataPacket packet;
        }

        /// <summary>
        /// Handles a data frame that is received from the session layer. The data frame is queued for
        /// processing using the threadpool. When the assigned thread in the threadpool is executed
        /// the callback function DataPacketRX_CF is executed.
        /// </summary>
        /// <param name="cmd">The command received</param>
        /// <param name="packet">The datapacket received</param>

        public void DataPacketReceived(DataFrame.CommandType cmd, DataPacket packet)
        {
#if WIN_CE
            cmdpacket cmdp = new cmdpacket();

            cmdp.cmd = cmd;
            cmdp.packet = packet;

            ThreadPool.QueueUserWorkItem(new WaitCallback(DataPacketRX_CF), (object)cmdp);
#else
        DataPacketFunc.BeginInvoke(cmd, packet, new AsyncCallback(DataPacketDone), null);
#endif
        }

#if WIN_CE
        /// <summary>
        /// This function handles asynchronously the receiving of datapackets from the session layer and
        /// is executed as a callback function after a packet has been queued for processing in DataPacketReceived
        /// using the threadpool.
        /// </summary>
        /// <param name="commandpacket">The command and the packet to be processed is passed as an object</param>
        private void DataPacketRX_CF(object commandpacket)
        {
            DataFrame.CommandType cmd;
            DataPacket packet;
            cmdpacket cmdp = new cmdpacket();

            cmdp = (cmdpacket)commandpacket;

            cmd = (DataFrame.CommandType)cmdp.cmd;
            packet = (DataPacket)cmdp.packet;

#else
    /// <summary>
    /// Data frame received 
    /// </summary>
    /// <param name="cmd"></param>
    /// <param name="packet"></param>
    public void DataPacketRX(DataFrame.CommandType cmd, DataPacket packet)
    {
#endif
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            byte[] payload = packet.GetPayload();
            switch (cmd)
            {
                case DataFrame.CommandType.CmdApplicationCommandHandler:
                    {
                        ApplicationCommandEventArgs e = new ApplicationCommandEventArgs(packet);
                        if (ApplicationCommandEvent != null) ApplicationCommandEvent(this, e);
                    }
                    break;

                case DataFrame.CommandType.CmdApplicationSlaveCommandHandler:
                    {
                        ApplicationSlaveCommandEventArgs e = new ApplicationSlaveCommandEventArgs(packet);
                        if (ApplicationSlaveCommandEvent != null) ApplicationSlaveCommandEvent(this, e);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?