zwavers232.cs
来自「zwave 无线通讯协议 PC controller 控制器源码」· CS 代码 · 共 868 行 · 第 1/3 页
CS
868 行
/// <summary>
///
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public int Write(byte[] buffer)
{
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
int bytesWritten = 0;
if (!comm.WriteFile(buffer, buffer.Length, ref bytesWritten, txOverlapped))
{
if (Marshal.GetLastWin32Error() != (int)CommAPI.APIErrors.ERROR_IO_PENDING)
throw new ITransportLayerException("WriteFile failed: err: " + Marshal.GetLastWin32Error());
else
{
if (!comm.GetOverlappedResult(txOverlapped, out bytesWritten, true)) // false
throw new ITransportLayerException("WriteFile failed: err: " + Marshal.GetLastWin32Error());
}
}
lock (stats) { stats.TransmittedBytes += bytesWritten; }
return bytesWritten;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public TransportStatistics GetStatistics()
{
lock (stats)
{
return new TransportStatistics(stats);
}
}
/// <summary>
/// Returns whether or not the port is currently open
/// </summary>
public bool IsOpen()
{
return isOpen;
}
}
#region CommAPI base class
internal abstract class CommAPI : IDisposable
{
#region --- Methods ---
static internal CommAPI getCommAPI()
{
return isFullFramework ? (CommAPI)new WinCommAPI() : (CommAPI)new CECommAPI();
}
static internal bool isFullFramework
{
get { return System.Environment.OSVersion.Platform != PlatformID.WinCE; }
}
internal bool IsValid()
{
return hPort != (System.IntPtr)INVALID_HANDLE_VALUE;
}
internal abstract bool CreateFile(string port);
internal abstract bool ReadFile(byte[] buffer, int cbToRead, ref Int32 cbRead, IntPtr lpOverlapped);
internal abstract bool WriteFile(byte[] buffer, Int32 cbToWrite, ref Int32 cbWritten, IntPtr lpOverlapped);
internal abstract bool Close();
internal abstract bool SetCommState(DCB dcb);
internal abstract bool GetCommState(DCB dcb);
internal abstract bool SetCommTimeouts(CommTimeouts timeouts);
internal abstract bool PurgeComm(PurgeFlags dwFlags);
internal abstract bool WaitCommEvent(ref CommEventFlags flags);
internal abstract bool SetCommMask(CommEventFlags dwEvtMask);
internal abstract bool GetOverlappedResult(IntPtr lpOverlapped, out Int32 lpNumberOfBytesTransferred, bool bWait);
internal abstract int WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
internal abstract IntPtr CreateEvent(bool bManualReset, bool bInitialState, string lpName);
#endregion
#region Serialport communication structures and enumerations used for configuration
[StructLayout(LayoutKind.Sequential)]
internal class CommTimeouts
{
public UInt32 ReadIntervalTimeout;
public UInt32 ReadTotalTimeoutMultiplier;
public UInt32 ReadTotalTimeoutConstant;
public UInt32 WriteTotalTimeoutMultiplier;
public UInt32 WriteTotalTimeoutConstant;
}
[StructLayout(LayoutKind.Sequential)]
internal struct OVERLAPPED
{
internal UIntPtr Internal;
internal UIntPtr InternalHigh;
internal UInt32 Offset;
internal UInt32 OffsetHigh;
internal IntPtr hEvent;
}
/// <summary>
/// DTR Flow Control
/// </summary>
internal enum DTRControlFlows : byte
{
DISABLE = 0x00,
ENABLE = 0x01,
HANDSHAKE = 0x02
}
[Flags]
internal enum PurgeFlags : int
{
PURGE_RXABORT = 0x0002, // Terminates all outstanding overlapped read operations and returns immediately, even if the read operations have not been completed.
PURGE_RXCLEAR = 0x0008, // Clears the input buffer (if the device driver has one).
PURGE_TXABORT = 0x0001, // Terminates all outstanding overlapped write operations and returns immediately, even if the write operations have not been completed.
PURGE_TXCLEAR = 0x0004 // Clears the output buffer (if the device driver has one).
}
/// <summary>
/// RTS Flow Control
/// </summary>
internal enum RTSControlFlows : byte
{
DISABLE = 0x00,
ENABLE = 0x01,
HANDSHAKE = 0x02,
TOGGLE = 0x03
}
/// <summary>
/// Event Flags
/// </summary>
[Flags]
internal enum CommEventFlags : int
{
/// <summary>
/// No flags
/// </summary>
NONE = 0x0000, //
/// <summary>
/// Event on receive
/// </summary>
RXCHAR = 0x0001, // Any Character received
/// <summary>
/// Event when specific character is received
/// </summary>
RXFLAG = 0x0002, // Received specified flag character
/// <summary>
/// Event when the transmit buffer is empty
/// </summary>
TXEMPTY = 0x0004, // Tx buffer Empty
/// <summary>
/// Event on CTS state change
/// </summary>
CTS = 0x0008, // CTS changed
/// <summary>
/// Event on DSR state change
/// </summary>
DSR = 0x0010, // DSR changed
/// <summary>
/// Event on RLSD state change
/// </summary>
RLSD = 0x0020, // RLSD changed
/// <summary>
/// Event on BREAK
/// </summary>
BREAK = 0x0040, // BREAK received
/// <summary>
/// Event on line error
/// </summary>
ERR = 0x0080, // Line status error
/// <summary>
/// Event on ring detect
/// </summary>
RING = 0x0100, // ring detected
/// <summary>
/// Event on printer error
/// </summary>
PERR = 0x0200, // printer error
/// <summary>
/// Event on 80% high-water
/// </summary>
RX80FULL = 0x0400, // rx buffer is at 80%
/// <summary>
/// Provider event 1
/// </summary>
EVENT1 = 0x0800, // provider event
/// <summary>
/// Provider event 2
/// </summary>
EVENT2 = 0x1000, // provider event
/// <summary>
/// Event on CE power notification
/// </summary>
POWER = 0x2000, // wince power notification
/// <summary>
/// Mask for all flags under CE
/// </summary>
ALLCE = 0x3FFF, // mask of all flags for CE
ALLCE_2 = BREAK | CTS | DSR | ERR | RING | RLSD | RXCHAR | RXFLAG,
/// <summary>
/// Mask for all flags under desktop Windows
/// </summary>
ALLPC = BREAK | CTS | DSR | ERR | RING | RLSD | RXCHAR | RXFLAG | TXEMPTY
}
/// <summary>
/// Error values from serial API calls
/// </summary>
internal enum APIErrors : int
{
/// <summary>
/// Port not found
/// </summary>
ERROR_FILE_NOT_FOUND = 2,
/// <summary>
/// Invalid port name
/// </summary>
ERROR_INVALID_NAME = 123,
/// <summary>
/// Access denied
/// </summary>
ERROR_ACCESS_DENIED = 5,
/// <summary>
/// invalid handle
/// </summary>
ERROR_INVALID_HANDLE = 6,
/// <summary>
/// IO pending
/// </summary>
ERROR_IO_PENDING = 997
}
internal enum APIConstants : uint
{
WAIT_OBJECT_0 = 0x00000000,
WAIT_ABANDONED = 0x00000080,
WAIT_ABANDONED_0 = 0x00000080,
WAIT_FAILED = 0xffffffff,
INFINITE = 0xffffffff
}
internal const Int32 INVALID_HANDLE_VALUE = -1;
internal const UInt32 OPEN_EXISTING = 3;
internal const UInt32 GENERIC_READ = 0x80000000;
internal const UInt32 GENERIC_WRITE = 0x40000000;
internal const UInt32 FILE_FLAG_OVERLAPPED = 0x40000000;
#endregion
protected IntPtr hPort;
private bool disposed;
#region Dispose function
/// <summary>
/// Dispose(bool disposing) executes in two distinct scenarios.
/// If disposing equals true, the method has been called directly or indirectly
/// by user code. Managed and unmanaged resources can be disposed.
/// If disposing equals false, the method has been called by the
/// runtime from inside the finalizer and you should not reference
/// other objects. Only unmanaged resources should be disposed.
/// </summary>
/// <param name="disposing">Called directly (true) or indirectly (false)</param>
// private void Dispose(bool disposing)
// {
// Check to see if Dispose has already been called.
// if(!this.disposed)
// {
// We don't really have managed resources to dispose, so just
// remove the unmanaged resources, meaning closing the handle.
// Close();
// }
// disposed = true;
// }
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
disposed = true;
if (disposing)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?