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