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;
20 Parity parity = Parity.None;
21 StopBits stopBits = StopBits.One;
22 Handshake handshake = Handshake.None;
24 bool breakState = false;
25 bool dtr_enable = false;
26 bool rts_enable = false;
27 SerialPortStream stream;
28 Encoding encoding = Encoding.ASCII;
29 string newLine = Environment.NewLine;
31 int readTimeout = InfiniteTimeout;
32 int writeTimeout = InfiniteTimeout;
33 int readBufferSize = DefaultReadBufferSize;
34 int writeBufferSize = DefaultWriteBufferSize;
37 int writeBufferLength;
39 //byte [] writeBuffer;
40 object error_received = new object ();
41 object data_received = new object ();
42 object pin_changed = new object ();
44 static string default_port_name = "ttyS0";
48 this.portName = GetDefaultPortName ();
53 public SerialPort (IContainer container) {
57 public SerialPort (string portName)
59 this.portName = portName;
62 public SerialPort (string portName, int baudRate)
64 this.portName = portName;
65 this.baudRate = baudRate;
68 public SerialPort (string portName, int baudRate, Parity parity)
70 this.portName = portName;
71 this.baudRate = baudRate;
75 public SerialPort (string portName, int baudRate, Parity parity, int dataBits)
77 this.portName = portName;
78 this.baudRate = baudRate;
80 this.dataBits = dataBits;
83 public SerialPort (string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
85 this.portName = portName;
86 this.baudRate = baudRate;
88 this.dataBits = dataBits;
89 this.stopBits = stopBits;
92 string GetDefaultPortName ()
94 return default_port_name;
97 public Stream BaseStream {
100 throw new InvalidOperationException ();
106 public int BaudRate {
112 throw new ArgumentOutOfRangeException ("value");
116 stream.BaudRate = value;
120 public bool BreakState {
126 if (value == breakState)
127 return; // Do nothing.
134 public int BytesToRead {
137 return readBufferLength + stream.BytesToRead;
141 public int BytesToWrite {
144 return writeBufferLength + stream.BytesToWrite;
148 public bool CDHolding {
151 throw new NotImplementedException ();
155 public bool CtsHolding {
158 throw new NotImplementedException ();
162 public int DataBits {
167 if (value < 5 || value > 8)
168 throw new ArgumentOutOfRangeException ("value");
172 stream.DataBits = value;
176 public bool DiscardNull {
179 throw new NotImplementedException ();
183 throw new NotImplementedException ();
187 public bool DsrHolding {
190 throw new NotImplementedException ();
194 public bool DtrEnable {
196 throw new NotImplementedException ();
199 throw new NotImplementedException ();
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");
225 stream.Handshake = value;
235 public string NewLine {
241 throw new ArgumentNullException ("value");
247 public Parity Parity {
252 if (value < Parity.None || value > Parity.Space)
253 throw new ArgumentOutOfRangeException ("value");
257 stream.Parity = value;
261 public byte ParityReplace {
263 throw new NotImplementedException ();
266 throw new NotImplementedException ();
270 public string PortName {
276 throw new InvalidOperationException ("Port name cannot be set while port is open.");
278 throw new ArgumentNullException ("value");
279 if (value.Length == 0 || value.StartsWith ("\\\\"))
280 throw new ArgumentException ("value");
286 public int ReadBufferSize {
288 return readBufferSize;
292 throw new InvalidOperationException ();
294 throw new ArgumentOutOfRangeException ("value");
295 if (value <= DefaultReadBufferSize)
298 readBufferSize = value;
302 public int ReadTimeout {
307 if (value <= 0 && value != InfiniteTimeout)
308 throw new ArgumentOutOfRangeException ("value");
312 stream.ReadTimeout = value;
316 public int ReceivedBytesThreshold {
318 throw new NotImplementedException ();
322 throw new ArgumentOutOfRangeException ("value");
324 throw new NotImplementedException ();
328 public bool RtsEnable {
330 throw new NotImplementedException ();
333 throw new NotImplementedException ();
337 public StopBits StopBits {
342 if (value < StopBits.One || value > StopBits.OnePointFive)
343 throw new ArgumentOutOfRangeException ("value");
347 stream.StopBits = value;
351 public int WriteBufferSize {
353 return writeBufferSize;
357 throw new InvalidOperationException ();
359 throw new ArgumentOutOfRangeException ("value");
360 if (value <= DefaultWriteBufferSize)
363 writeBufferSize = value;
367 public int WriteTimeout {
372 if (value <= 0 && value != InfiniteTimeout)
373 throw new ArgumentOutOfRangeException ("value");
375 writeTimeout = value;
377 stream.WriteTimeout = value;
392 //writeBuffer = null;
395 public void DiscardInBuffer ()
398 stream.DiscardInputBuffer ();
401 public void DiscardOutBuffer ()
404 stream.DiscardOutputBuffer ();
407 public static string [] GetPortNames ()
409 int p = (int) Environment.OSVersion.Platform;
410 if (p == 4 || p == 128) // Are we on Unix?
411 return Directory.GetFiles ("/dev/", "ttyS*");
413 throw new NotImplementedException ("Detection of ports is not implemented for this platform yet.");
419 throw new InvalidOperationException ("Port is already open");
421 stream = new SerialPortStream (portName, baudRate, dataBits, parity, stopBits, dtr_enable,
422 rts_enable, handshake, readTimeout, writeTimeout);
425 readBuffer = new byte [readBufferSize];
426 //writeBuffer = new byte [writeBufferSize];
429 public int Read (byte[] buffer, int offset, int count)
433 throw new ArgumentNullException ("buffer");
434 if (offset < 0 || offset >= buffer.Length)
435 throw new ArgumentOutOfRangeException ("offset");
436 if (count < 0 || count > buffer.Length)
437 throw new ArgumentOutOfRangeException ("count");
438 if (count > buffer.Length - offset)
439 throw new ArgumentException ("count > buffer.Length - offset");
441 if (readBufferLength <= 0) {
442 readBufferOffset = 0;
443 readBufferLength = stream.Read (readBuffer, 0, readBuffer.Length);
446 if (readBufferLength == 0)
447 return 0; // No bytes left
449 if (count > readBufferLength)
450 count = readBufferLength; // Update count if needed
452 Buffer.BlockCopy (readBuffer, readBufferOffset, buffer, offset, count);
453 readBufferOffset += count;
454 readBufferLength -= count;
459 public int Read (char[] buffer, int offset, int count)
463 throw new ArgumentNullException ("buffer");
464 if (offset < 0 || offset >= buffer.Length)
465 throw new ArgumentOutOfRangeException ("offset");
466 if (count < 0 || count > buffer.Length)
467 throw new ArgumentOutOfRangeException ("count");
468 if (count > buffer.Length - offset)
469 throw new ArgumentException ("count > buffer.Length - offset");
471 byte [] bytes = encoding.GetBytes (buffer, offset, count);
472 return Read (bytes, 0, bytes.Length);
475 public int ReadByte ()
477 byte [] buff = new byte [1];
478 if (Read (buff, 0, 1) > 0)
484 public int ReadChar ()
486 throw new NotImplementedException ();
489 public string ReadExisting ()
491 throw new NotImplementedException ();
494 public string ReadLine ()
496 return ReadTo (newLine);
499 public string ReadTo (string value)
503 throw new ArgumentNullException ("value");
504 if (value.Length == 0)
505 throw new ArgumentException ("value");
507 throw new NotImplementedException ();
510 public void Write (string str)
514 throw new ArgumentNullException ("str");
516 byte [] buffer = encoding.GetBytes (str);
517 Write (buffer, 0, buffer.Length);
520 public void Write (byte [] buffer, int offset, int count)
524 throw new ArgumentNullException ("buffer");
525 if (offset < 0 || offset >= buffer.Length)
526 throw new ArgumentOutOfRangeException ("offset");
527 if (count < 0 || count > buffer.Length)
528 throw new ArgumentOutOfRangeException ("count");
529 if (count > buffer.Length - offset)
530 throw new ArgumentException ("count > buffer.Length - offset");
532 stream.Write (buffer, offset, count);
535 public void Write (char [] buffer, int offset, int count)
539 throw new ArgumentNullException ("buffer");
540 if (offset < 0 || offset >= buffer.Length)
541 throw new ArgumentOutOfRangeException ("offset");
542 if (count < 0 || count > buffer.Length)
543 throw new ArgumentOutOfRangeException ("count");
544 if (count > buffer.Length - offset)
545 throw new ArgumentException ("count > buffer.Length - offset");
547 byte [] bytes = encoding.GetBytes (buffer, offset, count);
548 stream.Write (bytes, 0, bytes.Length);
551 public void WriteLine (string str)
553 Write (str + newLine);
559 throw new InvalidOperationException ("Specified port is not open.");
562 internal void OnErrorReceived (SerialErrorReceivedEventArgs args)
564 SerialErrorReceivedEventHandler handler =
565 (SerialErrorReceivedEventHandler) Events [error_received];
568 handler (this, args);
571 internal void OnDataReceived (SerialDataReceivedEventArgs args)
573 SerialDataReceivedEventHandler handler =
574 (SerialDataReceivedEventHandler) Events [data_received];
577 handler (this, args);
580 internal void OnDataReceived (SerialPinChangedEventArgs args)
582 SerialPinChangedEventHandler handler =
583 (SerialPinChangedEventHandler) Events [pin_changed];
586 handler (this, args);
590 public event SerialErrorReceivedEventHandler ErrorReceived {
591 add { Events.AddHandler (error_received, value); }
592 remove { Events.RemoveHandler (error_received, value); }
595 public event SerialPinChangedEventHandler PinChanged {
596 add { Events.AddHandler (pin_changed, value); }
597 remove { Events.RemoveHandler (pin_changed, value); }
600 public event SerialDataReceivedEventHandler DataReceived {
601 add { Events.AddHandler (data_received, value); }
602 remove { Events.RemoveHandler (data_received, value); }
606 public delegate void SerialDataReceivedEventHandler (object sender, SerialDataReceivedEventArgs e);
607 public delegate void SerialPinChangedEventHandler (object sender, SerialPinChangedEventArgs e);
608 public delegate void SerialErrorReceivedEventHandler (object sender, SerialErrorReceivedEventArgs e);