using System; using System.Data; using System.Configuration; using System.Collections.Specialized; using System.Runtime.InteropServices; using System.IO.Ports; namespace InfraredSerial { public class UnmanagedIRSerialPort : IIRSerialPort { IntPtr portHandle; DCB dcb = new DCB(); string port = String.Empty; public UnmanagedIRSerialPort(string portString) { port = portString; } public void Open() { portHandle = CreateFile("COM1", EFileAccess.GenericRead | EFileAccess.GenericWrite, EFileShare.None, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.Overlapped, IntPtr.Zero); GetCommState(portHandle, ref dcb); dcb.RtsControl = RtsControl.Enable; dcb.DtrControl = DtrControl.Disable; dcb.BaudRate = 115200; SetCommState(portHandle, ref dcb); } public void On() { EscapeCommFunction(portHandle, SETDTR); //dcb.DtrControl = DtrControl.Enable; //SetCommState(portHandle, ref dcb); } public void Off() { EscapeCommFunction(portHandle, CLRDTR); //dcb.DtrControl = DtrControl.Disable; //SetCommState(portHandle, ref dcb); } public void Close() { CloseHandle(portHandle); } #region Interop Serial Port Stuff const int SETDTR = 5; const int CLRDTR = 6; [DllImport("kernel32.dll")] static extern bool GetCommState(IntPtr hFile, ref DCB lpDCB); [DllImport("kernel32.dll")] static extern bool SetCommState(IntPtr hFile, [In] ref DCB lpDCB); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool CloseHandle(IntPtr handle); [DllImport("kernel32.dll", SetLastError = true)] static extern bool EscapeCommFunction(IntPtr hFile, int dwFunc); [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr CreateFile( string lpFileName, EFileAccess dwDesiredAccess, EFileShare dwShareMode, IntPtr lpSecurityAttributes, ECreationDisposition dwCreationDisposition, EFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile); [Flags] public enum EFileAccess : uint { GenericRead = 0x80000000, GenericWrite = 0x40000000, GenericExecute = 0x20000000, GenericAll = 0x10000000, } [Flags] public enum EFileShare : uint { None = 0x00000000, Read = 0x00000001, Write = 0x00000002, Delete = 0x00000004, } public enum ECreationDisposition : uint { New = 1, CreateAlways = 2, OpenExisting = 3, OpenAlways = 4, TruncateExisting = 5, } [Flags] public enum EFileAttributes : uint { Readonly = 0x00000001, Hidden = 0x00000002, System = 0x00000004, Directory = 0x00000010, Archive = 0x00000020, Device = 0x00000040, Normal = 0x00000080, Temporary = 0x00000100, SparseFile = 0x00000200, ReparsePoint = 0x00000400, Compressed = 0x00000800, Offline = 0x00001000, NotContentIndexed = 0x00002000, Encrypted = 0x00004000, Write_Through = 0x80000000, Overlapped = 0x40000000, NoBuffering = 0x20000000, RandomAccess = 0x10000000, SequentialScan = 0x08000000, DeleteOnClose = 0x04000000, BackupSemantics = 0x02000000, PosixSemantics = 0x01000000, OpenReparsePoint = 0x00200000, OpenNoRecall = 0x00100000, FirstPipeInstance = 0x00080000 } public enum RtsControl : int { Disable = 0, Enable = 1, Handshake = 2, Toggle = 3 }; public enum DtrControl : int { Disable = 0, Enable = 1, Handshake = 2 }; [StructLayout(LayoutKind.Sequential)] public struct DCB { internal uint DCBLength; internal uint BaudRate; private BitVector32 Flags; //I've missed some members... private uint wReserved; // not currently used internal uint XonLim; // transmit XON threshold internal uint XoffLim; // transmit XOFF threshold internal byte ByteSize; internal Parity Parity; internal StopBits StopBits; //...and some more internal char XonChar; // Tx and Rx XON character internal char XoffChar; // Tx and Rx XOFF character internal char ErrorChar; // error replacement character internal char EofChar; // end of input character internal char EvtChar; // received event character private uint wReserved1; // reserved; do not use private static readonly int fBinary; private static readonly int fParity; private static readonly int fOutxCtsFlow; private static readonly int fOutxDsrFlow; private static readonly BitVector32.Section fDtrControl; private static readonly int fDsrSensitivity; private static readonly int fTXContinueOnXoff; private static readonly int fOutX; private static readonly int fInX; private static readonly int fErrorChar; private static readonly int fNull; private static readonly BitVector32.Section fRtsControl; private static readonly int fAbortOnError; static DCB() { // Create Boolean Mask int previousMask; fBinary = BitVector32.CreateMask(); fParity = BitVector32.CreateMask(fBinary); fOutxCtsFlow = BitVector32.CreateMask(fParity); fOutxDsrFlow = BitVector32.CreateMask(fOutxCtsFlow); previousMask = BitVector32.CreateMask(fOutxDsrFlow); previousMask = BitVector32.CreateMask(previousMask); fDsrSensitivity = BitVector32.CreateMask(previousMask); fTXContinueOnXoff = BitVector32.CreateMask(fDsrSensitivity); fOutX = BitVector32.CreateMask(fTXContinueOnXoff); fInX = BitVector32.CreateMask(fOutX); fErrorChar = BitVector32.CreateMask(fInX); fNull = BitVector32.CreateMask(fErrorChar); previousMask = BitVector32.CreateMask(fNull); previousMask = BitVector32.CreateMask(previousMask); fAbortOnError = BitVector32.CreateMask(previousMask); // Create section Mask BitVector32.Section previousSection; previousSection = BitVector32.CreateSection(1); previousSection = BitVector32.CreateSection(1, previousSection); previousSection = BitVector32.CreateSection(1, previousSection); previousSection = BitVector32.CreateSection(1, previousSection); fDtrControl = BitVector32.CreateSection(2, previousSection); previousSection = BitVector32.CreateSection(1, fDtrControl); previousSection = BitVector32.CreateSection(1, previousSection); previousSection = BitVector32.CreateSection(1, previousSection); previousSection = BitVector32.CreateSection(1, previousSection); previousSection = BitVector32.CreateSection(1, previousSection); previousSection = BitVector32.CreateSection(1, previousSection); fRtsControl = BitVector32.CreateSection(3, previousSection); previousSection = BitVector32.CreateSection(1, fRtsControl); } public bool Binary { get { return Flags[fBinary]; } set { Flags[fBinary] = value; } } public bool CheckParity { get { return Flags[fParity]; } set { Flags[fParity] = value; } } public bool OutxCtsFlow { get { return Flags[fOutxCtsFlow]; } set { Flags[fOutxCtsFlow] = value; } } public bool OutxDsrFlow { get { return Flags[fOutxDsrFlow]; } set { Flags[fOutxDsrFlow] = value; } } public DtrControl DtrControl { get { return (DtrControl)Flags[fDtrControl]; } set { Flags[fDtrControl] = (int)value; } } public bool DsrSensitivity { get { return Flags[fDsrSensitivity]; } set { Flags[fDsrSensitivity] = value; } } public bool TxContinueOnXoff { get { return Flags[fTXContinueOnXoff]; } set { Flags[fTXContinueOnXoff] = value; } } public bool OutX { get { return Flags[fOutX]; } set { Flags[fOutX] = value; } } public bool InX { get { return Flags[fInX]; } set { Flags[fInX] = value; } } public bool ReplaceErrorChar { get { return Flags[fErrorChar]; } set { Flags[fErrorChar] = value; } } public bool Null { get { return Flags[fNull]; } set { Flags[fNull] = value; } } public RtsControl RtsControl { get { return (RtsControl)Flags[fRtsControl]; } set { Flags[fRtsControl] = (int)value; } } public bool AbortOnError { get { return Flags[fAbortOnError]; } set { Flags[fAbortOnError] = value; } } } #endregion } }