using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Diagnostics;
using System.Text;
using System.Runtime.InteropServices;
+using Microsoft.Win32;
namespace System.IO.Ports
{
+ [MonitoringDescription ("")]
public class SerialPort : Component
{
public const int InfiniteTimeout = -1;
object error_received = new object ();
object data_received = new object ();
object pin_changed = new object ();
-
- static string default_port_name = "ttyS0";
public SerialPort () :
this (GetDefaultPortName (), DefaultBaudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
{
}
- /*
- IContainer is in 2.0?
- public SerialPort (IContainer container) {
- }
- */
+ public SerialPort (IContainer container) : this ()
+ {
+ // TODO: What to do here?
+ }
public SerialPort (string portName) :
this (portName, DefaultBaudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
static string GetDefaultPortName ()
{
- return default_port_name;
+ string[] ports = GetPortNames();
+ if (ports.Length > 0) {
+ return ports[0];
+ } else {
+ int p = (int)Environment.OSVersion.Platform;
+ if (p == 4 || p == 128 || p == 6)
+ return "ttyS0"; // Default for Unix
+ else
+ return "COM1"; // Default for Windows
+ }
}
+ [Browsable (false)]
+ [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
public Stream BaseStream {
get {
- if (!is_open)
- throw new InvalidOperationException ();
-
+ CheckOpen ();
return (Stream) stream;
}
}
[DefaultValueAttribute (DefaultBaudRate)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public int BaudRate {
get {
return baud_rate;
}
}
+ [Browsable (false)]
+ [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
public bool BreakState {
get {
return break_state;
}
}
+ [Browsable (false)]
+ [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
public int BytesToRead {
get {
CheckOpen ();
}
}
+ [Browsable (false)]
+ [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
public int BytesToWrite {
get {
CheckOpen ();
}
}
+ [Browsable (false)]
+ [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
public bool CDHolding {
get {
CheckOpen ();
}
}
+ [Browsable (false)]
+ [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
public bool CtsHolding {
get {
CheckOpen ();
}
[DefaultValueAttribute(DefaultDataBits)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public int DataBits {
get {
return data_bits;
}
[MonoTODO("Not implemented")]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
+ [DefaultValue (false)]
public bool DiscardNull {
get {
- CheckOpen ();
throw new NotImplementedException ();
}
set {
- CheckOpen ();
+ // LAMESPEC: Msdn states that an InvalidOperationException exception
+ // is fired if the port is not open, which is *not* happening.
+
throw new NotImplementedException ();
}
}
+ [Browsable (false)]
+ [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
public bool DsrHolding {
get {
CheckOpen ();
}
[DefaultValueAttribute(false)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public bool DtrEnable {
get {
return dtr_enable;
}
}
+ [Browsable (false)]
+ [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
+ [MonitoringDescription ("")]
public Encoding Encoding {
get {
return encoding;
}
[DefaultValueAttribute(Handshake.None)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public Handshake Handshake {
get {
return handshake;
}
}
+ [Browsable (false)]
public bool IsOpen {
get {
return is_open;
}
[DefaultValueAttribute("\n")]
+ [Browsable (false)]
+ [MonitoringDescription ("")]
public string NewLine {
get {
return new_line;
set {
if (value == null)
throw new ArgumentNullException ("value");
+ if (value.Length == 0)
+ throw new ArgumentException ("NewLine cannot be null or empty.", "value");
new_line = value;
}
}
[DefaultValueAttribute(DefaultParity)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public Parity Parity {
get {
return parity;
}
[MonoTODO("Not implemented")]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
+ [DefaultValue (63)]
public byte ParityReplace {
get {
throw new NotImplementedException ();
}
+ [Browsable (true)]
+ [MonitoringDescription ("")]
+ [DefaultValue ("COM1")] // silly Windows-ism. We should ignore it.
public string PortName {
get {
return port_name;
}
[DefaultValueAttribute(DefaultReadBufferSize)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public int ReadBufferSize {
get {
return readBufferSize;
}
[DefaultValueAttribute(InfiniteTimeout)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public int ReadTimeout {
get {
return read_timeout;
[MonoTODO("Not implemented")]
[DefaultValueAttribute(1)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public int ReceivedBytesThreshold {
get {
throw new NotImplementedException ();
}
[DefaultValueAttribute(false)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public bool RtsEnable {
get {
return rts_enable;
}
[DefaultValueAttribute(DefaultStopBits)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public StopBits StopBits {
get {
return stop_bits;
}
[DefaultValueAttribute(DefaultWriteBufferSize)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public int WriteBufferSize {
get {
return writeBufferSize;
}
[DefaultValueAttribute(InfiniteTimeout)]
+ [Browsable (true)]
+ [MonitoringDescription ("")]
public int WriteTimeout {
get {
return write_timeout;
public void Close ()
{
- Dispose (false);
+ Dispose (true);
}
protected override void Dispose (bool disposing)
return;
is_open = false;
- stream.Close ();
+ // Do not close the base stream when the finalizer is run; the managed code can still hold a reference to it.
+ if (disposing)
+ stream.Close ();
stream = null;
}
public static string [] GetPortNames ()
{
int p = (int) Environment.OSVersion.Platform;
+ List<string> serial_ports = new List<string>();
// Are we on Unix?
- if (p == 4 || p == 128){
- string [] ttys = Directory.GetFiles ("/dev/", "tty*");
- List<string> serial_ports = new List<string> ();
-
- foreach (string dev in ttys){
- if (dev.StartsWith ("/dev/ttyS") || dev.StartsWith ("/dev/ttyUSB"))
- serial_ports.Add (dev);
-
+ if (p == 4 || p == 128 || p == 6) {
+ string[] ttys = Directory.GetFiles("/dev/", "tty*");
+ bool linux_style = false;
+
+ //
+ // Probe for Linux-styled devices: /dev/ttyS* or /dev/ttyUSB*
+ //
+ foreach (string dev in ttys) {
+ if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB")){
+ linux_style = true;
+ break;
+ }
+ }
+
+ foreach (string dev in ttys) {
+ if (linux_style){
+ if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB"))
+ serial_ports.Add (dev);
+ } else {
+ if (dev != "/dev/tty" && dev.StartsWith ("/dev/tty") && !dev.StartsWith ("/dev/ttyC"))
+ serial_ports.Add (dev);
+ }
+ }
+ } else {
+ using (RegistryKey subkey = Registry.LocalMachine.OpenSubKey("HARDWARE\\DEVICEMAP\\SERIALCOMM"))
+ {
+ if (subkey != null) {
+ string[] names = subkey.GetValueNames();
+ foreach (string value in names) {
+ string port = subkey.GetValue(value, "").ToString();
+ if (port != "")
+ serial_ports.Add(port);
+ }
+ }
}
- return serial_ports.ToArray ();
}
- throw new NotImplementedException ("Detection of ports is not implemented for this platform yet.");
+ return serial_ports.ToArray();
}
static bool IsWindows {
#if !TARGET_JVM
if (IsWindows) // Use windows kernel32 backend
- stream = new WinSerialStream (port_name, baud_rate, data_bits, parity, stop_bits,
- handshake, read_timeout, write_timeout, readBufferSize, writeBufferSize);
+ stream = new WinSerialStream (port_name, baud_rate, data_bits, parity, stop_bits, dtr_enable,
+ rts_enable, handshake, read_timeout, write_timeout, readBufferSize, writeBufferSize);
else // Use standard unix backend
#endif
stream = new SerialPortStream (port_name, baud_rate, data_bits, parity, stop_bits, dtr_enable,
return stream.Read (buffer, offset, count);
}
- [Obsolete("Read of char buffers is currently broken")]
- [MonoTODO("This is broken")]
+ [MonoTODO("Read of char buffers is currently broken")]
public int Read (char[] buffer, int offset, int count)
{
CheckOpen ();
public string ReadLine ()
{
- CheckOpen ();
- List<byte> bytes_read = new List<byte>();
- byte [] buff = new byte [1];
-
- while (true){
- int n = stream.Read (buff, 0, 1);
- if (n == -1 || buff [0] == '\n')
- break;
- bytes_read.Add (buff [0]);
- }
- return new String (encoding.GetChars (bytes_read.ToArray ()));
+ return ReadTo (new_line);
}
public string ReadTo (string value)
CheckOpen ();
if (buffer == null)
throw new ArgumentNullException ("buffer");
- if (offset < 0 || offset >= buffer.Length)
- throw new ArgumentOutOfRangeException ("offset");
- if (count < 0 || count > buffer.Length)
- throw new ArgumentOutOfRangeException ("count");
- if (count > buffer.Length - offset)
- throw new ArgumentException ("count > buffer.Length - offset");
+
+ if (offset < 0 || count < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (buffer.Length - offset < count)
+ throw new ArgumentException ("offset+count",
+ "The size of the buffer is less than offset + count.");
byte [] bytes = encoding.GetBytes (buffer, offset, count);
stream.Write (bytes, 0, bytes.Length);
}
// events
+ [MonitoringDescription ("")]
public event SerialErrorReceivedEventHandler ErrorReceived {
add { Events.AddHandler (error_received, value); }
remove { Events.RemoveHandler (error_received, value); }
}
+ [MonitoringDescription ("")]
public event SerialPinChangedEventHandler PinChanged {
add { Events.AddHandler (pin_changed, value); }
remove { Events.RemoveHandler (pin_changed, value); }
}
+ [MonitoringDescription ("")]
public event SerialDataReceivedEventHandler DataReceived {
add { Events.AddHandler (data_received, value); }
remove { Events.RemoveHandler (data_received, value); }