public void GivenNativeSerialPort_WhenDisposeTwice_ThenInnerPortDisposedOnce() { // Arrange var sut = new NativeSerialPort( "COM1", 9600, Parity.None, 8, StopBits.One, Handshake.None, new TimeSpan(0, 0, 5), new TimeSpan(0, 0, 5)); var disposeCount = 0; sut.InnerPort.Disposed += (object sender, EventArgs e) => { disposeCount += 1; }; // Act sut.Dispose(); sut.Dispose(); // Assert Assert.Equal(1, disposeCount); }
public void GivenNativeSerialPort_WhenDispose_ThenInnerPortDisposed() { // Arrange var sut = new NativeSerialPort( "COM1", 9600, Parity.None, 8, StopBits.One, Handshake.None, new TimeSpan(0, 0, 5), new TimeSpan(0, 0, 5)); var disposed = false; sut.InnerPort.Disposed += (object sender, EventArgs e) => { disposed = true; }; // Act sut.Dispose(); // Assert Assert.True(disposed); }
private void SerialPortIo_CommEvent(object sender, NativeSerialPort.CommOverlappedIo.CommEventArgs e) { if (IsDisposed || DataReceived == null && PinChanged == null) { m_CommEvent = 0; return; } else { lock (m_EventCheck) { m_CommEvent |= e.EventType; } CallEvent(); } }
/// <summary> /// Get the properties of the specified serial port. /// </summary> /// <remarks> /// If no instance to a NativeSerialPort is created, we instantiate a new one /// and get the properties. The port is closed afterwards. /// <para>If an instance to a NativeSerialPort exists, then the properties of the /// serial port are reread. If the port is open, it remains open, else the port /// is temporarily opened and then closed.</para> /// <para>Note, the windows feature RTS_CONTROL_TOGGLE is not supported by this class.</para> /// </remarks> /// <param name="port">The port to open.</param> private void GetPortSettings(string port) { bool setPort = false; if (m_SerialPort == null) { // We need to create a new instance. This is called from the constructor. if (port == null) { m_SerialPort = new NativeSerialPort(); // Set the default properties of the DCB. We must do this here, so that // this object has decent defaults, as we don't query the OS at all on // what normal values should be. BaudRate = 115200; DataBits = 8; Parity = Ports.Parity.None; StopBits = Ports.StopBits.One; Handshake = Ports.Handshake.None; TxContinueOnXOff = false; DiscardNull = false; XOnLimit = 2048; XOffLimit = 512; ParityReplace = 0; } else { try { m_SerialPort = new NativeSerialPort(port); m_SerialPort.SerialPortCommState.GetCommState(); m_SerialPort.SerialPortCommProperties.GetCommProperties(); m_SerialPort.SerialPortModemStatus.GetCommModemStatus(); m_SerialPort.Close(); } catch { m_SerialPort = new NativeSerialPort(); m_SerialPort.Port = port; BaudRate = 115200; DataBits = 8; Parity = Ports.Parity.None; StopBits = Ports.StopBits.One; } } m_BreakState = false; m_SerialPort.SerialPortIo.CommEvent += SerialPortIo_CommEvent; m_SerialPort.SerialPortIo.CommErrorEvent += SerialPortIo_CommErrorEvent; } else { if (m_SerialPort.IsOpen) { if (port == null || m_SerialPort.Port == port) { // Port is already open, no change in port specified, so just get the state m_SerialPort.SerialPortCommState.GetCommState(); m_SerialPort.SerialPortCommProperties.GetCommProperties(); m_SerialPort.SerialPortModemStatus.GetCommModemStatus(); // The break state isn't affected here } else { // Port is already open, but port should change. Strange situation, probably // not what is wanted, so ensure in the rest of the class this case is avoided. m_SerialPort.Close(); m_SerialPort.Open(port); m_SerialPort.SerialPortCommState.GetCommState(); m_SerialPort.SerialPortCommProperties.GetCommProperties(); m_SerialPort.SerialPortModemStatus.GetCommModemStatus(); if (m_BreakState) { m_SerialPort.SerialPortModemStatus.SetCommBreak(); } else { m_SerialPort.SerialPortModemStatus.ClearCommBreak(); } } } else { if (port == null || m_SerialPort.Port == port) { // Port is not open, reopen it, get the state and close it again m_SerialPort.Open(); } else { // Port is not open, user wants to change the port. Get the state, close it m_SerialPort.Open(port); } m_SerialPort.SerialPortCommState.GetCommState(); m_SerialPort.SerialPortCommProperties.GetCommProperties(); m_SerialPort.SerialPortModemStatus.GetCommModemStatus(); m_SerialPort.SerialPortModemStatus.ClearCommBreak(); m_BreakState = false; m_SerialPort.Close(); } } // Binary mode must always be set per MSDN m_SerialPort.SerialPortCommState.Binary = true; // Ensure the parity settings are consistent if (!m_SerialPort.SerialPortCommState.ParityEnable) { if (m_SerialPort.SerialPortCommState.Parity != Ports.Parity.None) { m_SerialPort.SerialPortCommState.Parity = Ports.Parity.None; setPort = true; } } // Get the Error Char. Only if it is zero and parity is enabled, we change it to 126 // This is because the interface can't provide for an error char of zero and active. // This is a limitation of the API as taken over from the System.IO.Ports.SerialPort // implementation by Microsoft. m_ParityReplace = m_SerialPort.SerialPortCommState.ErrorChar; if (m_ParityReplace == 0 && m_SerialPort.SerialPortCommState.ErrorCharEnabled && m_SerialPort.SerialPortCommState.ParityEnable && m_SerialPort.SerialPortCommState.Parity != Ports.Parity.None) { m_ParityReplace = 126; } // The function fAbortOnError should be disabled if (m_SerialPort.SerialPortCommState.AbortOnError) { m_SerialPort.SerialPortCommState.AbortOnError = false; setPort = true; } // Event and EOF chars, compatible with MS implementation if (m_SerialPort.SerialPortCommState.EventChar != 26) { m_SerialPort.SerialPortCommState.EventChar = 26; setPort = true; } if (m_SerialPort.SerialPortCommState.EofChar != 26) { m_SerialPort.SerialPortCommState.EofChar = 26; setPort = true; } // We don't support RTS_CONTROL_TOGGLE if (m_SerialPort.SerialPortCommState.RtsControl == NativeSerialPort.RtsControl.Toggle) { m_SerialPort.SerialPortCommState.RtsControl = NativeSerialPort.RtsControl.Disable; setPort = true; } // Set the XOn and XOff characters if (m_SerialPort.SerialPortCommState.XOnChar != 17) { m_SerialPort.SerialPortCommState.XOnChar = 17; setPort = true; } if (m_SerialPort.SerialPortCommState.XOffChar != 19) { m_SerialPort.SerialPortCommState.XOffChar = 19; setPort = true; } if (m_SerialPort.IsOpen && setPort) m_SerialPort.SerialPortCommState.SetCommState(); }