1 /* -*- Mode: Csharp; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
6 using System.ComponentModel;
8 using System.Runtime.InteropServices;
10 namespace System.IO.Ports
12 public class SerialPort : Component
14 public const int InfiniteTimeout = -1;
15 const int DefaultReadBufferSize = 4096;
16 const int DefaultWriteBufferSize = 2048;
17 const int DefaultBaudRate = 9600;
18 const int DefaultDataBits = 8;
19 const Parity DefaultParity = Parity.None;
20 const StopBits DefaultStopBits = StopBits.One;
28 bool break_state = false;
29 bool dtr_enable = false;
30 bool rts_enable = false;
32 Encoding encoding = Encoding.ASCII;
33 string new_line = Environment.NewLine;
35 int read_timeout = InfiniteTimeout;
36 int write_timeout = InfiniteTimeout;
37 int readBufferSize = DefaultReadBufferSize;
38 int writeBufferSize = DefaultWriteBufferSize;
39 object error_received = new object ();
40 object data_received = new object ();
41 object pin_changed = new object ();
43 static string default_port_name = "ttyS0";
45 public SerialPort () :
46 this (GetDefaultPortName (), DefaultBaudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
52 public SerialPort (IContainer container) {
56 public SerialPort (string portName) :
57 this (portName, DefaultBaudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
61 public SerialPort (string portName, int baudRate) :
62 this (portName, baudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
66 public SerialPort (string portName, int baudRate, Parity parity) :
67 this (portName, baudRate, parity, DefaultDataBits, DefaultStopBits)
71 public SerialPort (string portName, int baudRate, Parity parity, int dataBits) :
72 this (portName, baudRate, parity, dataBits, DefaultStopBits)
76 public SerialPort (string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
85 static string GetDefaultPortName ()
87 return default_port_name;
90 public Stream BaseStream {
93 throw new InvalidOperationException ();
95 return (Stream) stream;
105 throw new ArgumentOutOfRangeException ("value");
108 stream.SetAttributes (value, parity, data_bits, stop_bits, handshake);
114 public bool BreakState {
120 if (value == break_state)
121 return; // Do nothing.
128 public int BytesToRead {
131 return stream.BytesToRead;
135 public int BytesToWrite {
138 return stream.BytesToWrite;
142 public bool CDHolding {
145 return (stream.GetSignals () & SerialSignal.Cd) != 0;
149 public bool CtsHolding {
152 return (stream.GetSignals () & SerialSignal.Cts) != 0;
156 public int DataBits {
161 if (value < 5 || value > 8)
162 throw new ArgumentOutOfRangeException ("value");
165 stream.SetAttributes (baud_rate, parity, value, stop_bits, handshake);
171 public bool DiscardNull {
174 throw new NotImplementedException ();
178 throw new NotImplementedException ();
182 public bool DsrHolding {
185 return (stream.GetSignals () & SerialSignal.Dsr) != 0;
189 public bool DtrEnable {
194 if (value == dtr_enable)
197 stream.SetSignal (SerialSignal.Dtr, value);
203 public Encoding Encoding {
209 throw new ArgumentNullException ("value");
215 public Handshake Handshake {
220 if (value < Handshake.None || value > Handshake.RequestToSendXOnXOff)
221 throw new ArgumentOutOfRangeException ("value");
224 stream.SetAttributes (baud_rate, parity, data_bits, stop_bits, value);
236 public string NewLine {
242 throw new ArgumentNullException ("value");
248 public Parity Parity {
253 if (value < Parity.None || value > Parity.Space)
254 throw new ArgumentOutOfRangeException ("value");
257 stream.SetAttributes (baud_rate, value, data_bits, stop_bits, handshake);
263 public byte ParityReplace {
265 throw new NotImplementedException ();
268 throw new NotImplementedException ();
272 public string PortName {
278 throw new InvalidOperationException ("Port name cannot be set while port is open.");
280 throw new ArgumentNullException ("value");
281 if (value.Length == 0 || value.StartsWith ("\\\\"))
282 throw new ArgumentException ("value");
288 public int ReadBufferSize {
290 return readBufferSize;
294 throw new InvalidOperationException ();
296 throw new ArgumentOutOfRangeException ("value");
297 if (value <= DefaultReadBufferSize)
300 readBufferSize = value;
304 public int ReadTimeout {
309 if (value <= 0 && value != InfiniteTimeout)
310 throw new ArgumentOutOfRangeException ("value");
313 stream.ReadTimeout = value;
315 read_timeout = value;
319 public int ReceivedBytesThreshold {
321 throw new NotImplementedException ();
325 throw new ArgumentOutOfRangeException ("value");
327 throw new NotImplementedException ();
331 public bool RtsEnable {
336 if (value == rts_enable)
339 stream.SetSignal (SerialSignal.Rts, value);
345 public StopBits StopBits {
350 if (value < StopBits.One || value > StopBits.OnePointFive)
351 throw new ArgumentOutOfRangeException ("value");
354 stream.SetAttributes (baud_rate, parity, data_bits, value, handshake);
360 public int WriteBufferSize {
362 return writeBufferSize;
366 throw new InvalidOperationException ();
368 throw new ArgumentOutOfRangeException ("value");
369 if (value <= DefaultWriteBufferSize)
372 writeBufferSize = value;
376 public int WriteTimeout {
378 return write_timeout;
381 if (value <= 0 && value != InfiniteTimeout)
382 throw new ArgumentOutOfRangeException ("value");
385 stream.WriteTimeout = value;
387 write_timeout = value;
398 protected override void Dispose (bool disposing)
408 public void DiscardInBuffer ()
411 stream.DiscardInBuffer ();
414 public void DiscardOutBuffer ()
417 stream.DiscardOutBuffer ();
420 public static string [] GetPortNames ()
422 int p = (int) Environment.OSVersion.Platform;
423 if (p == 4 || p == 128) // Are we on Unix?
424 return Directory.GetFiles ("/dev/", "ttyS*");
426 throw new NotImplementedException ("Detection of ports is not implemented for this platform yet.");
429 static bool IsWindows {
431 PlatformID id = Environment.OSVersion.Platform;
432 return id == PlatformID.Win32Windows || id == PlatformID.Win32NT; // WinCE not supported
439 throw new InvalidOperationException ("Port is already open");
441 if (IsWindows) // Use windows kernel32 backend
442 stream = new WinSerialStream (port_name, baud_rate, data_bits, parity, stop_bits,
443 handshake, read_timeout, write_timeout, readBufferSize, writeBufferSize);
444 else // Use standard unix backend
445 stream = new SerialPortStream (port_name, baud_rate, data_bits, parity, stop_bits, dtr_enable,
446 rts_enable, handshake, read_timeout, write_timeout, readBufferSize, writeBufferSize);
451 public int Read (byte[] buffer, int offset, int count)
455 throw new ArgumentNullException ("buffer");
456 if (offset < 0 || offset >= buffer.Length)
457 throw new ArgumentOutOfRangeException ("offset");
458 if (count < 0 || count > buffer.Length)
459 throw new ArgumentOutOfRangeException ("count");
460 if (count > buffer.Length - offset)
461 throw new ArgumentException ("count > buffer.Length - offset");
463 return stream.Read (buffer, offset, count);
466 public int Read (char[] buffer, int offset, int count)
470 throw new ArgumentNullException ("buffer");
471 if (offset < 0 || offset >= buffer.Length)
472 throw new ArgumentOutOfRangeException ("offset");
473 if (count < 0 || count > buffer.Length)
474 throw new ArgumentOutOfRangeException ("count");
475 if (count > buffer.Length - offset)
476 throw new ArgumentException ("count > buffer.Length - offset");
478 byte [] bytes = encoding.GetBytes (buffer, offset, count);
479 return stream.Read (bytes, 0, bytes.Length);
482 public int ReadByte ()
484 byte [] buff = new byte [1];
485 if (Read (buff, 0, 1) > 0)
491 public int ReadChar ()
493 throw new NotImplementedException ();
496 public string ReadExisting ()
498 throw new NotImplementedException ();
501 public string ReadLine ()
503 return ReadTo (new_line);
506 public string ReadTo (string value)
510 throw new ArgumentNullException ("value");
511 if (value.Length == 0)
512 throw new ArgumentException ("value");
514 throw new NotImplementedException ();
517 public void Write (string str)
521 throw new ArgumentNullException ("str");
523 byte [] buffer = encoding.GetBytes (str);
524 Write (buffer, 0, buffer.Length);
527 public void Write (byte [] buffer, int offset, int count)
531 throw new ArgumentNullException ("buffer");
532 if (offset < 0 || offset >= buffer.Length)
533 throw new ArgumentOutOfRangeException ("offset");
534 if (count < 0 || count > buffer.Length)
535 throw new ArgumentOutOfRangeException ("count");
536 if (count > buffer.Length - offset)
537 throw new ArgumentException ("count > buffer.Length - offset");
539 stream.Write (buffer, offset, count);
542 public void Write (char [] buffer, int offset, int count)
546 throw new ArgumentNullException ("buffer");
547 if (offset < 0 || offset >= buffer.Length)
548 throw new ArgumentOutOfRangeException ("offset");
549 if (count < 0 || count > buffer.Length)
550 throw new ArgumentOutOfRangeException ("count");
551 if (count > buffer.Length - offset)
552 throw new ArgumentException ("count > buffer.Length - offset");
554 byte [] bytes = encoding.GetBytes (buffer, offset, count);
555 stream.Write (bytes, 0, bytes.Length);
558 public void WriteLine (string str)
560 Write (str + new_line);
566 throw new InvalidOperationException ("Specified port is not open.");
569 internal void OnErrorReceived (SerialErrorReceivedEventArgs args)
571 SerialErrorReceivedEventHandler handler =
572 (SerialErrorReceivedEventHandler) Events [error_received];
575 handler (this, args);
578 internal void OnDataReceived (SerialDataReceivedEventArgs args)
580 SerialDataReceivedEventHandler handler =
581 (SerialDataReceivedEventHandler) Events [data_received];
584 handler (this, args);
587 internal void OnDataReceived (SerialPinChangedEventArgs args)
589 SerialPinChangedEventHandler handler =
590 (SerialPinChangedEventHandler) Events [pin_changed];
593 handler (this, args);
597 public event SerialErrorReceivedEventHandler ErrorReceived {
598 add { Events.AddHandler (error_received, value); }
599 remove { Events.RemoveHandler (error_received, value); }
602 public event SerialPinChangedEventHandler PinChanged {
603 add { Events.AddHandler (pin_changed, value); }
604 remove { Events.RemoveHandler (pin_changed, value); }
607 public event SerialDataReceivedEventHandler DataReceived {
608 add { Events.AddHandler (data_received, value); }
609 remove { Events.RemoveHandler (data_received, value); }
613 public delegate void SerialDataReceivedEventHandler (object sender, SerialDataReceivedEventArgs e);
614 public delegate void SerialPinChangedEventHandler (object sender, SerialPinChangedEventArgs e);
615 public delegate void SerialErrorReceivedEventHandler (object sender, SerialErrorReceivedEventArgs e);