zwavers232.cs
来自「zwave 无线通讯协议 PC controller 控制器源码」· CS 代码 · 共 868 行 · 第 1/3 页
CS
868 行
////////////////////////////////////////////////////////////////////////////////////////////////
//
// #######
// # ## #### ##### ##### ## ## #####
// ## ## ## ## ## ## ## ## ##
// ## # ###### ## ## #### ## ## ####
// ## ## ## ## ## ## ##### ##
// ####### #### ## ## ##### ## #####
// #####
// Z-Wave, the wireless language.
//
// Copyright Zensys A/S, 2005
//
// All Rights Reserved
//
// Description:
//
// Author: Morten Damsgaard, Linkage A/S
//
// Last Changed By: $Author: jrm $
// Revision: $Revision: 1.6 $
// Last Changed: $Date: 2007/01/24 10:24:41 $
//
//////////////////////////////////////////////////////////////////////////////////////////////
#region Using directives
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
using System.Globalization;
#endregion
namespace Zensys.ZWave.Communication
{
/// <summary>
///
/// </summary>
public class ZWaveRS232 : ITransportLayer , IDisposable
{
private CommAPI comm;
private TransportStatistics stats;
private IntPtr txOverlapped = IntPtr.Zero;
private IntPtr rxOverlapped = IntPtr.Zero;
private bool isOpen;
private IntPtr unmanagedResource;
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Release managed resources.
}
// Free the unmanaged resource ...
unmanagedResource = IntPtr.Zero;
disposed = true;
}
}
/// <summary>
///
/// </summary>
/// <param name="connectionString"></param>
public void Open(String connectionString)
{
string port = "COM1";
uint baudRate = 9600;
string[] con = connectionString.ToLower(CultureInfo.CurrentCulture).Split(';');
for (int i = 0; i < con.Length; i++)
{
int idx = con[i].LastIndexOf('=');
string key = con[i].Substring(0, idx);
string val = con[i].Substring(idx+1);
switch(key)
{
case "port": port = val; break;
case "baudrate": baudRate = Convert.ToUInt32(val,CultureInfo.InvariantCulture); break;
default: break;
}
}
// for Windows CE, ensure the port name is colon terminated "COMx:"
if (!CommAPI.isFullFramework && !port.EndsWith(":")) port += ":";
Open(port, baudRate);
}
/// <summary>
///
/// </summary>
/// <param name="port"></param>
/// <param name="baudrate"></param>
public void Open(String port, uint baudRate)
{
isOpen = true;
comm = CommAPI.getCommAPI();
// Open the serial port.
if (!comm.CreateFile("\\\\.\\"+port))
throw new ITransportLayerException("CreateFile failed: err: " + Marshal.GetLastWin32Error() + "Port: " + port);
// Get the default port setting information.
DCB dcb = new DCB();
if( !comm.GetCommState(dcb) )
throw new ITransportLayerException("GetCommState failed: err: " + Marshal.GetLastWin32Error());
// Change the DCB structure settings.
dcb.BaudRate = baudRate; // Current baud
dcb.fBinary = true; // Binary mode; no EOF check
dcb.fParity = false; // Disable parity checking
dcb.fOutxCtsFlow = false; // No CTS output flow control
dcb.fOutxDsrFlow = false; // No DSR output flow control
dcb.fDtrControl = (byte)CommAPI.DTRControlFlows.ENABLE;
// DTR flow control type
dcb.fDsrSensitivity = false; // DSR sensitivity
dcb.fTXContinueOnXoff = true; // XOFF continues Tx
dcb.fOutX = false; // No XON/XOFF out flow control
dcb.fInX = false; // No XON/XOFF in flow control
dcb.fErrorChar = false; // Disable error replacement
dcb.fNull = false; // Disable null stripping
dcb.fRtsControl = (byte)CommAPI.RTSControlFlows.DISABLE; // RTS flow control disabled
dcb.fAbortOnError = false; // Do not abort reads/writes on
// error
dcb.ByteSize = 8; // Number of bits/byte, 4-8
dcb.Parity = 0; // 0-4=no,odd,even,mark,space
dcb.StopBits = 0; // 0,1,2 = 1, 1.5, 2
// Configure the port according to the specifications of the DCB structure.
if( !comm.SetCommState(dcb) )
throw new ITransportLayerException("SetCommState failed: err: " + Marshal.GetLastWin32Error());
// MDA - test
// ReadIntervalTimeout
// Specifies the maximum acceptable time, in milliseconds, to elapse
// between the arrival of two characters on the communication line.
// In Windows CE, during a ReadFile operation, the time period begins
// immediately. If the interval between the arrivals of two characters
// exceeds the time amount specified in ReadIntervalTimeout, the
// ReadFile operation is completed and buffered data is returned.
// A value of zero indicates that interval timeouts are not used.
// ReadTotalTimeoutMultiplier
// Specifies the multiplier, in milliseconds, used to calculate the
// total timeout period for read operations.
// For each read operation, this value is multiplied by the requested
// number of bytes to be read.
// ReadTotalTimeoutConstant
// Specifies the constant, in milliseconds, used to calculate the total
// timeout period for read operations.
// For each read operation, this value is added to the product of the
// ReadTotalTimeoutMultiplier member and the requested number of bytes.
// A value of zero for the ReadTotalTimeoutMultiplier and
// ReadTotalTimeoutConstant members indicates that total timeouts are
// not used for read operations.
// WriteTotalTimeoutMultiplier
// Specifies the multiplier, in milliseconds, used to calculate the
// total timeout period for write operations.
// For each write operation, this value is multiplied by the number
// of bytes to be written.
// WriteTotalTimeoutConstant
// Specifies the constant, in milliseconds, used to calculate the total
// timeout period for write operations.
// For each write operation, this value is added to the product of the
// WriteTotalTimeoutMultiplier member and the number of bytes to be written.
// A value of zero for the WriteTotalTimeoutMultiplier and
// WriteTotalTimeoutConstant members indicates that total timeouts are
// not used for write operations.
// read delay = ReadTotalTimeoutConstant + ReadTotalTimeoutMultiplier x "bytes read"
// causes read operations to complete immediately without
// waiting for any new data to arrive
CommAPI.CommTimeouts timeouts = new CommAPI.CommTimeouts();
timeouts.ReadIntervalTimeout = UInt32.MaxValue;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if( !comm.SetCommTimeouts(timeouts) )
throw new ITransportLayerException("SetCommTimeouts failed: err: " + Marshal.GetLastWin32Error());
if( !comm.SetCommMask(CommAPI.CommEventFlags.RXCHAR) ) // rx
throw new ITransportLayerException("SetCommMask failed: err: " + Marshal.GetLastWin32Error());
stats = new TransportStatistics();
if (CommAPI.isFullFramework)
{
// set up the overlapped tx IO
CommAPI.OVERLAPPED tx = new CommAPI.OVERLAPPED();
txOverlapped = CommAPI.LocalAlloc(0x40, Marshal.SizeOf(tx));
tx.Offset = 0;
tx.OffsetHigh = 0;
tx.hEvent = comm.CreateEvent(true, false, "tx");
Marshal.StructureToPtr(tx, txOverlapped, true);
// set up the overlapped rx IO
CommAPI.OVERLAPPED rx = new CommAPI.OVERLAPPED();
rxOverlapped = CommAPI.LocalAlloc(0x40, Marshal.SizeOf(rx));
rx.Offset = 0;
rx.OffsetHigh = 0;
rx.hEvent = comm.CreateEvent(true, false, "rx");
Marshal.StructureToPtr(rx, rxOverlapped, true);
}
}
/// <summary>
///
/// </summary>
public void Close()
{
isOpen = false;
comm.Close();
if (txOverlapped != IntPtr.Zero)
{
CommAPI.LocalFree(txOverlapped);
txOverlapped = IntPtr.Zero;
}
if (rxOverlapped != IntPtr.Zero)
{
CommAPI.LocalFree(rxOverlapped);
rxOverlapped = IntPtr.Zero;
}
}
/// <summary>
///
/// </summary>
public void Purge()
{
if( comm.PurgeComm(CommAPI.PurgeFlags.PURGE_RXCLEAR | CommAPI.PurgeFlags.PURGE_TXCLEAR) )
throw new ITransportLayerException("PurgeComm failed: err: " + Marshal.GetLastWin32Error());
}
/// <summary>
///
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public int Read(byte[] buffer)
{
int bytesRead = 0;
CommAPI.CommEventFlags eventFlags = new CommAPI.CommEventFlags();
bool waitEvent = false;
while (bytesRead == 0 && this.isOpen)
{
waitEvent = comm.WaitCommEvent(ref eventFlags);
if (waitEvent && (eventFlags & CommAPI.CommEventFlags.RXCHAR) != 0)
bytesRead = ReadFile(buffer);
if (!comm.IsValid() )
throw new ITransportLayerException("Handle invalid: " + Marshal.GetLastWin32Error());
}
return bytesRead;
}
private int ReadFile(byte[] buffer)
{
int bytesRead = 0;
if (!comm.ReadFile(buffer, buffer.Length, ref bytesRead, rxOverlapped))
{
if (!comm.IsValid() || Marshal.GetLastWin32Error() != (int)CommAPI.APIErrors.ERROR_IO_PENDING)
throw new ITransportLayerException("ReadFile failed: err: " + Marshal.GetLastWin32Error());
else
{
Debug.WriteLine("Overlapped read...");
if (!comm.GetOverlappedResult(rxOverlapped, out bytesRead, true)) // false
throw new ITransportLayerException("ReadFile failed: err: " + Marshal.GetLastWin32Error());
}
}
lock (stats) { stats.ReceivedBytes += bytesRead; }
return bytesRead;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?