2006-04-04 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / System / System.IO.Ports / SerialPort.cs
1 /* -*- Mode: Csharp; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 #if NET_2_0
4
5 using System;
6 using System.ComponentModel;
7 using System.Text;
8 using System.Runtime.InteropServices;
9
10 namespace System.IO.Ports
11 {
12         public class SerialPort : Component
13         {
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;
21
22                 bool isOpen;
23                 int baudRate;
24                 Parity parity;
25                 StopBits stopBits;
26                 Handshake handshake = Handshake.None;
27                 int dataBits;
28                 bool breakState = false;
29                 bool dtr_enable = false;
30                 bool rts_enable = false;
31                 SerialPortStream stream;
32                 Encoding encoding = Encoding.ASCII;
33                 string newLine = Environment.NewLine;
34                 string portName;
35                 int readTimeout = InfiniteTimeout;
36                 int writeTimeout = 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 ();
42                 
43                 static string default_port_name = "ttyS0";
44
45                 public SerialPort () : 
46                         this (GetDefaultPortName (), DefaultBaudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
47                 {
48                 }
49
50                 /*
51                   IContainer is in 2.0?
52                   public SerialPort (IContainer container) {
53                   }
54                 */
55
56                 public SerialPort (string portName) :
57                         this (portName, DefaultBaudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
58                 {
59                 }
60
61                 public SerialPort (string portName, int baudRate) :
62                         this (portName, baudRate, DefaultParity, DefaultDataBits, DefaultStopBits)
63                 {
64                 }
65
66                 public SerialPort (string portName, int baudRate, Parity parity) :
67                         this (portName, baudRate, parity, DefaultDataBits, DefaultStopBits)
68                 {
69                 }
70
71                 public SerialPort (string portName, int baudRate, Parity parity, int dataBits) :
72                         this (portName, baudRate, parity, dataBits, DefaultStopBits)
73                 {
74                 }
75
76                 public SerialPort (string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits) 
77                 {
78                         this.portName = portName;
79                         this.baudRate = baudRate;
80                         this.parity = parity;
81                         this.dataBits = dataBits;
82                         this.stopBits = stopBits;
83                 }
84
85                 static string GetDefaultPortName ()
86                 {
87                         return default_port_name;
88                 }
89
90                 public Stream BaseStream {
91                         get {
92                                 if (!isOpen)
93                                         throw new InvalidOperationException ();
94
95                                 return stream;
96                         }
97                 }
98
99                 public int BaudRate {
100                         get {
101                                 return baudRate;
102                         }
103                         set {
104                                 if (value <= 0)
105                                         throw new ArgumentOutOfRangeException ("value");
106                                 
107                                 baudRate = value;
108                                 if (isOpen)
109                                         stream.BaudRate = value;
110                         }
111                 }
112
113                 public bool BreakState {
114                         get {
115                                 return breakState;
116                         }
117                         set {
118                                 CheckOpen ();
119                                 if (value == breakState)
120                                         return; // Do nothing.
121
122                                 breakState = value;
123                                 // Update the state
124                         }
125                 }
126
127                 public int BytesToRead {
128                         get {
129                                 CheckOpen ();
130                                 return stream.BytesToRead;
131                         }
132                 }
133
134                 public int BytesToWrite {
135                         get {
136                                 CheckOpen ();
137                                 return stream.BytesToWrite;
138                         }
139                 }
140
141                 public bool CDHolding {
142                         get {
143                                 CheckOpen ();
144                                 throw new NotImplementedException ();
145                         }
146                 }
147
148                 public bool CtsHolding {
149                         get {
150                                 CheckOpen ();
151                                 throw new NotImplementedException ();
152                         }
153                 }
154
155                 public int DataBits {
156                         get {
157                                 return dataBits;
158                         }
159                         set {
160                                 if (value < 5 || value > 8)
161                                         throw new ArgumentOutOfRangeException ("value");
162
163                                 dataBits = value;
164                                 if (isOpen)
165                                         stream.DataBits = value;
166                         }
167                 }
168
169                 public bool DiscardNull {
170                         get {
171                                 CheckOpen ();
172                                 throw new NotImplementedException ();
173                         }
174                         set {
175                                 CheckOpen ();
176                                 throw new NotImplementedException ();
177                         }
178                 }
179
180                 public bool DsrHolding {
181                         get {
182                                 CheckOpen ();
183                                 throw new NotImplementedException ();
184                         }
185                 }
186
187                 public bool DtrEnable {
188                         get {
189                                 throw new NotImplementedException ();
190                         }
191                         set {
192                                 throw new NotImplementedException ();
193                         }
194                 }
195
196                 public Encoding Encoding {
197                         get {
198                                 return encoding;
199                         }
200                         set {
201                                 if (value == null)
202                                         throw new ArgumentNullException ("value");
203
204                                 encoding = value;
205                         }
206                 }
207
208                 public Handshake Handshake {
209                         get {
210                                 return handshake;
211                         }
212                         set {
213                                 if (value < Handshake.None || value > Handshake.RequestToSendXOnXOff)
214                                         throw new ArgumentOutOfRangeException ("value");
215
216                                 handshake = value;
217                                 if (isOpen)
218                                         stream.Handshake = value;
219                         }
220                 }
221
222                 public bool IsOpen {
223                         get {
224                                 return isOpen;
225                         }
226                 }
227
228                 public string NewLine {
229                         get {
230                                 return newLine;
231                         }
232                         set {
233                                 if (value == null)
234                                         throw new ArgumentNullException ("value");
235                                 
236                                 newLine = value;
237                         }
238                 }
239
240                 public Parity Parity {
241                         get {
242                                 return parity;
243                         }
244                         set {
245                                 if (value < Parity.None || value > Parity.Space)
246                                         throw new ArgumentOutOfRangeException ("value");
247
248                                 parity = value;
249                                 if (isOpen)
250                                         stream.Parity = value;
251                         }
252                 }
253
254                 public byte ParityReplace {
255                         get {
256                                 throw new NotImplementedException ();
257                         }
258                         set {
259                                 throw new NotImplementedException ();
260                         }
261                 }
262
263                 public string PortName {
264                         get {
265                                 return portName;
266                         }
267                         set {
268                                 if (isOpen)
269                                         throw new InvalidOperationException ("Port name cannot be set while port is open.");
270                                 if (value == null)
271                                         throw new ArgumentNullException ("value");
272                                 if (value.Length == 0 || value.StartsWith ("\\\\"))
273                                         throw new ArgumentException ("value");
274
275                                 portName = value;
276                         }
277                 }
278
279                 public int ReadBufferSize {
280                         get {
281                                 return readBufferSize;
282                         }
283                         set {
284                                 if (isOpen)
285                                         throw new InvalidOperationException ();
286                                 if (value <= 0)
287                                         throw new ArgumentOutOfRangeException ("value");
288                                 if (value <= DefaultReadBufferSize)
289                                         return;
290
291                                 readBufferSize = value;
292                         }
293                 }
294
295                 public int ReadTimeout {
296                         get {
297                                 return readTimeout;
298                         }
299                         set {
300                                 if (value <= 0 && value != InfiniteTimeout)
301                                         throw new ArgumentOutOfRangeException ("value");
302
303                                 readTimeout = value;
304                                 if (isOpen)
305                                         stream.ReadTimeout = value;
306                         }
307                 }
308
309                 public int ReceivedBytesThreshold {
310                         get {
311                                 throw new NotImplementedException ();
312                         }
313                         set {
314                                 if (value <= 0)
315                                         throw new ArgumentOutOfRangeException ("value");
316
317                                 throw new NotImplementedException ();
318                         }
319                 }
320
321                 public bool RtsEnable {
322                         get {
323                                 throw new NotImplementedException ();
324                         }
325                         set {
326                                 throw new NotImplementedException ();
327                         }
328                 }
329
330                 public StopBits StopBits {
331                         get {
332                                 return stopBits;
333                         }
334                         set {
335                                 if (value < StopBits.One || value > StopBits.OnePointFive)
336                                         throw new ArgumentOutOfRangeException ("value");
337                                 
338                                 stopBits = value;
339                                 if (isOpen)
340                                         stream.StopBits = value;
341                         }
342                 }
343
344                 public int WriteBufferSize {
345                         get {
346                                 return writeBufferSize;
347                         }
348                         set {
349                                 if (isOpen)
350                                         throw new InvalidOperationException ();
351                                 if (value <= 0)
352                                         throw new ArgumentOutOfRangeException ("value");
353                                 if (value <= DefaultWriteBufferSize)
354                                         return;
355
356                                 writeBufferSize = value;
357                         }
358                 }
359
360                 public int WriteTimeout {
361                         get {
362                                 return writeTimeout;
363                         }
364                         set {
365                                 if (value <= 0 && value != InfiniteTimeout)
366                                         throw new ArgumentOutOfRangeException ("value");
367
368                                 writeTimeout = value;
369                                 if (isOpen)
370                                         stream.WriteTimeout = value;
371                         }
372                 }
373
374                 // methods
375
376                 public void Close ()
377                 {
378                         isOpen = false;
379
380                         if (stream != null)
381                                 stream.Close ();
382                         
383                         stream = null;
384                 }
385
386                 public void DiscardInBuffer ()
387                 {
388                         CheckOpen ();
389                         stream.DiscardInputBuffer ();
390                 }
391
392                 public void DiscardOutBuffer ()
393                 {
394                         CheckOpen ();
395                         stream.DiscardOutputBuffer ();
396                 }
397
398                 public static string [] GetPortNames ()
399                 {
400                         int p = (int) Environment.OSVersion.Platform;
401                         if (p == 4 || p == 128) // Are we on Unix?
402                                 return Directory.GetFiles ("/dev/", "ttyS*");
403
404                         throw new NotImplementedException ("Detection of ports is not implemented for this platform yet.");
405                 }
406
407                 public void Open ()
408                 {
409                         if (isOpen)
410                                 throw new InvalidOperationException ("Port is already open");
411                         
412                         stream = new SerialPortStream (portName, baudRate, dataBits, parity, stopBits, dtr_enable,
413                                         rts_enable, handshake, readTimeout, writeTimeout, readBufferSize, writeBufferSize);
414                         isOpen = true;
415                 }
416
417                 public int Read (byte[] buffer, int offset, int count)
418                 {
419                         CheckOpen ();
420                         if (buffer == null)
421                                 throw new ArgumentNullException ("buffer");
422                         if (offset < 0 || offset >= buffer.Length)
423                                 throw new ArgumentOutOfRangeException ("offset");
424                         if (count < 0 || count > buffer.Length)
425                                 throw new ArgumentOutOfRangeException ("count");
426                         if (count > buffer.Length - offset)
427                                 throw new ArgumentException ("count > buffer.Length - offset");
428                         
429                         return stream.Read (buffer, offset, count);
430                 }
431
432                 public int Read (char[] buffer, int offset, int count)
433                 {
434                         CheckOpen ();
435                         if (buffer == null)
436                                 throw new ArgumentNullException ("buffer");
437                         if (offset < 0 || offset >= buffer.Length)
438                                 throw new ArgumentOutOfRangeException ("offset");
439                         if (count < 0 || count > buffer.Length)
440                                 throw new ArgumentOutOfRangeException ("count");
441                         if (count > buffer.Length - offset)
442                                 throw new ArgumentException ("count > buffer.Length - offset");
443
444                         byte [] bytes = encoding.GetBytes (buffer, offset, count);
445                         return stream.Read (bytes, 0, bytes.Length);
446                 }
447
448                 public int ReadByte ()
449                 {
450                         byte [] buff = new byte [1];
451                         if (Read (buff, 0, 1) > 0)
452                                 return buff [0];
453
454                         return -1;
455                 }
456
457                 public int ReadChar ()
458                 {
459                         throw new NotImplementedException ();
460                 }
461
462                 public string ReadExisting ()
463                 {
464                         throw new NotImplementedException ();
465                 }
466
467                 public string ReadLine ()
468                 {
469                         return ReadTo (newLine);
470                 }
471
472                 public string ReadTo (string value)
473                 {
474                         CheckOpen ();
475                         if (value == null)
476                                 throw new ArgumentNullException ("value");
477                         if (value.Length == 0)
478                                 throw new ArgumentException ("value");
479
480                         throw new NotImplementedException ();
481                 }
482
483                 public void Write (string str)
484                 {
485                         CheckOpen ();
486                         if (str == null)
487                                 throw new ArgumentNullException ("str");
488                         
489                         byte [] buffer = encoding.GetBytes (str);
490                         Write (buffer, 0, buffer.Length);
491                 }
492
493                 public void Write (byte [] buffer, int offset, int count)
494                 {
495                         CheckOpen ();
496                         if (buffer == null)
497                                 throw new ArgumentNullException ("buffer");
498                         if (offset < 0 || offset >= buffer.Length)
499                                 throw new ArgumentOutOfRangeException ("offset");
500                         if (count < 0 || count > buffer.Length)
501                                 throw new ArgumentOutOfRangeException ("count");
502                         if (count > buffer.Length - offset)
503                                 throw new ArgumentException ("count > buffer.Length - offset");
504
505                         stream.Write (buffer, offset, count);
506                 }
507
508                 public void Write (char [] buffer, int offset, int count)
509                 {
510                         CheckOpen ();
511                         if (buffer == null)
512                                 throw new ArgumentNullException ("buffer");
513                         if (offset < 0 || offset >= buffer.Length)
514                                 throw new ArgumentOutOfRangeException ("offset");
515                         if (count < 0 || count > buffer.Length)
516                                 throw new ArgumentOutOfRangeException ("count");
517                         if (count > buffer.Length - offset)
518                                 throw new ArgumentException ("count > buffer.Length - offset");
519
520                         byte [] bytes = encoding.GetBytes (buffer, offset, count);
521                         stream.Write (bytes, 0, bytes.Length);
522                 }
523
524                 public void WriteLine (string str)
525                 {
526                         Write (str + newLine);
527                 }
528
529                 void CheckOpen ()
530                 {
531                         if (!isOpen)
532                                 throw new InvalidOperationException ("Specified port is not open.");
533                 }
534
535                 internal void OnErrorReceived (SerialErrorReceivedEventArgs args)
536                 {
537                         SerialErrorReceivedEventHandler handler =
538                                 (SerialErrorReceivedEventHandler) Events [error_received];
539
540                         if (handler != null)
541                                 handler (this, args);
542                 }
543
544                 internal void OnDataReceived (SerialDataReceivedEventArgs args)
545                 {
546                         SerialDataReceivedEventHandler handler =
547                                 (SerialDataReceivedEventHandler) Events [data_received];
548
549                         if (handler != null)
550                                 handler (this, args);
551                 }
552                 
553                 internal void OnDataReceived (SerialPinChangedEventArgs args)
554                 {
555                         SerialPinChangedEventHandler handler =
556                                 (SerialPinChangedEventHandler) Events [pin_changed];
557
558                         if (handler != null)
559                                 handler (this, args);
560                 }
561
562                 // events
563                 public event SerialErrorReceivedEventHandler ErrorReceived {
564                         add { Events.AddHandler (error_received, value); }
565                         remove { Events.RemoveHandler (error_received, value); }
566                 }
567                 
568                 public event SerialPinChangedEventHandler PinChanged {
569                         add { Events.AddHandler (pin_changed, value); }
570                         remove { Events.RemoveHandler (pin_changed, value); }
571                 }
572                 
573                 public event SerialDataReceivedEventHandler DataReceived {
574                         add { Events.AddHandler (data_received, value); }
575                         remove { Events.RemoveHandler (data_received, value); }
576                 }
577         }
578
579         public delegate void SerialDataReceivedEventHandler (object sender, SerialDataReceivedEventArgs e);
580         public delegate void SerialPinChangedEventHandler (object sender, SerialPinChangedEventArgs e);
581         public delegate void SerialErrorReceivedEventHandler (object sender, SerialErrorReceivedEventArgs e);
582
583 }
584
585 #endif