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 + -
显示快捷键?