/ *
* Author: Marcus Lorentzon, 2001 * d98malor@dtek.chalmers.se * * Freeware: Please do not remove this header * * File: SerialStream.cs * * Description:. Implements a Stream for asynchronous * transfers and COMM Stream version *. * Version: 2.4 *
* /
#REGION
Using
Using
System;
Using
System.IO;
Using
System.Threading;
Using
System.Runtime.InteropServices;
Using
System.componentmodel;
#ndregion
Using
Namespace
Loman.io {
public
Class
SerialStream: stream {
#REGION
Attributes
Private
IOCOMPLETIONCALLBACK M_IOCOMPLETIONCALLBACK;
Private
INTPTR M_HFILE
=
INTPTR.ZERO;
Private
String
m_sport;
Private
Bool
m_bread;
Private
Bool
m_bwrite;
#ndregion
Attributes
#REGION
PROPERTIES
public
String
Port {
get
{
Return
m_sport;
set
{
IF
(m_sport
! =
Value) {close (); open (value);}}}
public
Override
Bool
Canread {
get
{
Return
m_bread;}}}
public
Override
Bool
Canwrite {
get
{
Return
m_bwrite;}}
public
Override
Bool
Canseek {
get
{
Return
False
}}
public
Bool
Closed {
get
{
Return
m_hfile.toint32 ()
0
}}
public
Bool
DSR {
get
{
Uint
STATUS;
IF
(
!
GetcommmodemStatus (m_hfile,
OUT
Status)) {
Throw
New
Win32Exception ();
Return
(Status)
&
MS_DSR_ON)
>
0
}}
public
Bool
Ring {
get
{
Uint
STATUS;
IF
(
!
GetcommmodemStatus (m_hfile,
OUT
Status)) {
Throw
New
Win32Exception ();
Return
(Status)
&
MS_RING_ON)
>
0
}}
public
Bool
RLSD {
get
{
Uint
STATUS;
IF
(
!
GetcommmodemStatus (m_hfile,
OUT
Status)) {
Throw
New
Win32Exception ();
Return
(Status)
&
MS_RLSD_ON)
>
0
}}
#ndregion
PROPERTIES
#REGION
Constructors
public
SerialStream ():
THIS
FileAccess.Readwrite {}
public
SerialStream (FileAccess Access) {m_bread
=
(("
int
Access
&
(
int
) FileAccess.read)
! =
0
M_BWRITE
=
(("
int
Access
&
(
int
) FileAccess.write)
! =
0
;
Unsafe
{M_IOCOMPLETIONCALLBACK
=
New
Iocompletioncallback;}}
public
SerialStream
String
Port):
THIS
FileAccess.readwrite) {Open (port);
public
SerialStream
String
Port, FileAccess Access:
THIS
(Access) {Open (port);
#ndregion
Constructors
#REGION
Methods
public
Void
Open
String
Port) {
IF
(m_hfile
! =
INTPTR.ZERO) {
Throw
New
IOEXCEPTION
"
Stream already OPENED.
"
} M_sport
=
Port; m_hfile
=
Createfile (port,
Uint
(m_bread
?
Generic_read:
0
)
|
(m_bwrite
?
Generic_Write:
0
))
0
,
0
Open_existing, file_flag_overlapped,
0
);
IF
(m_hfile.toint32 ()
==
INVALID_HANDLE_VALUE) {m_hfile
=
INTPTR.ZERO;
Throw
New
FilenotFoundException
"
Unable to open
"
Port);} threadpool.bindhandle (M_HFILE); setTimeouts (
0
,
0
,
0
,
0
,
0
}
public
Override
Void
Close () {closeHandle (M_HFILE); M_HFILE
=
INTPTR.ZERO; M_SPORT
=
NULL
}
public
IASYNCRESULT BEGINREAD
Byte
[] buffer {
Return
Beginread (buffer,
0
Buffer.length,
NULL
,
NULL
}
public
Override
IASYNCRESULT BEGINREAD
Byte
[] buffer,
int
OFFSET,
int
Count, AsyncCallback Callback,
Object
State) {gchandle gchbuffer
=
Gchandle.alloc (buffer, gchandletype.pinned); SerialAlaAlasyncResult Sar
=
New
SerialAlaAlaAlasyncResult
THIS
State, Callback,
True
, gchbuffer; overlapped OV
=
New
Overlapped
0
,
0
Sar.asyncwaithandle.handle.Toint32 (), SAR);
Unsafe
{NativeOverlapped
*
NOV
=
Ov.pack (m_iocompletioncallback);
Byte
*
Data
=
(
Byte
*
((("
int
Gchbuffer.AddrofpinnedObject ()
OFFSET;
Uint
reta
=
0
;
IF
(Readfile (M_HFILE, DATA)
Uint
Count,
OUT
Read, NOV) {sar.m_bcompletedsynchronously
=
True
;
Return
SAR;
Else
IF
(GetLastError ()
==
ERROR_IO_PENDING) {
Return
SAR;
Else
Throw
New
EXCEPTION
"
Unable to initialize read. ErrorCode:
"
GetLastError (). TOSTRING ());}}
public
IASYNCRESULT BEGINWRITE
Byte
[] buffer {
Return
Beginwrite (buffer,
0
Buffer.length,
NULL
,
NULL
}
public
Override
IASYNCRESULT BEGINWRITE
Byte
[] buffer,
int
OFFSET,
int
Count, AsyncCallback Callback,
Object
State) {gchandle gchbuffer
=
Gchandle.alloc (buffer, gchandletype.pinned); SerialAlaAlasyncResult Sar
=
New
SerialAlaAlaAlasyncResult
THIS
State, Callback,
False
, gchbuffer; overlapped OV
=
New
Overlapped
0
,
0
Sar.asyncwaithandle.handle.Toint32 (), SAR);
Unsafe
{NativeOverlapped
*
NOV
=
Ov.pack (m_iocompletioncallback);
Byte
*
Data
=
(
Byte
*
((("
int
Gchbuffer.AddrofpinnedObject ()
OFFSET;
Uint
Written
=
0
;
IF
(Writefile (M_HFILE, DATA,
Uint
Count,
OUT
Written, NOV)) {sar.m_bcompletedsynchronously
=
True
;
Return
SAR;
Else
IF
(GetLastError ()
==
ERROR_IO_PENDING) {
Return
SAR;
Else
Throw
New
EXCEPTION
"
Unable to initialize write. ErrorCode:
"
GetLastError (). TOSTRING ());}}
Private
int
Endoperation (IASYNCRESULT AsyncRESULT,
Bool
Isread) {SerialAlasyncResult Sar
=
AsyncRESULT;
IF
(SAR.M_BISREAD
! =
Isread)
Throw
New
IOEXCEPTION
"
Invalid Parameter: IASYNCRESULT IS NOT FROM A
"
(Isread
?
"
reta
"
:
"
Write
"
));
IF
SAR.EndoperationCalled) {
Throw
New
IOEXCEPTION
"
End
"
(Isread
?
"
Reta
"
:
"
Write
"
)
"
Called twice for the same operation.
"
}
Else
{SAR.M_BENDOPERATIONCALLED
=
True
}
While
(
!
SAR.M_BCOMPLED) {sar.asyncwaithandle.waitone ();} sar.dispose ();
IF
(SAR.M_NERRORCODE
! =
Error_Success
&&&&
SAR.M_NERRORCODE
! =
ERROR_OPERATION_ABORTED) {
Throw
New
IOEXCEPTION
"
Operation finished with error:
"
SAR.M_NERRORCODE);
Return
SAR.M_NREADWRITTEN;
public
Override
int
Endread (IASYNCRESULT asyncRESULT) {
Return
Endoperation (AsyncResult,
True
}
public
Overridevoid
Endwrite (IASYNCRESULT asyncRESULT) {endoperation (asyncResult,
False
}
public
int
ENDWRITEEX (IASYNCRESULT asyncRESULT) {
Return
Endoperation (AsyncResult,
False
}
public
Override
int
READ
Byte
[] buffer,
int
OFFSET,
int
COUNT) {
Return
EndRead (Buffer, Offset, Count,
NULL
,
NULL
));
public
Override
Void
Write
Byte
[] buffer,
int
OFFSET,
int
Count) {Endwrite (Buffer, Offset, Count,
NULL
,
NULL
));
public
int
Writeex
Byte
[] buffer,
int
OFFSET,
int
COUNT) {
Return
ENDWRITEEX (BEGINWRITE (Buffer, Offset, Count,
NULL
,
NULL
));
public
int
READ
Byte
[] buffer {
Return
EndRead (Buffer,
0
Buffer.length,
NULL
,
NULL
));
public
int
Write
Byte
[] buffer {
Return
Endoperation (BeginWrite (Buffer,
0
Buffer.length,
NULL
,
NULL
),
False
}
public
Override
Void
Flush () {flushfilebuffers (m_hfile);
public
Bool
PurgeRead () {
Return
PurgeComm (M_HFILE, PURGE_RXCLEAR);
public
Bool
Purgewrite () {
Return
PurgeComm (M_HFILE, PURGE_TXCLEAR);
public
Bool
Purge () {
Return
Purgeread ()
&&&&
Purgewrite ();
public
Bool
CANCELREAD () {
Return
PurgeComm (M_HFILE, PURGE_RXABORT);
public
Bool
Cancelwrite () {
Return
PurgeComm (m_hfile, purge_txabort);
public
Bool
Cancelall () {
Return
Cancelread ()
&&&&
Cancelwrite ();
public
Override
Void
SetLength
Long
NLENGTH) {
Throw
New
NotSupportedException
"
SetLength Isn't Supported on Serial Ports.
"
}
public
Override
Long
Seek
Long
Offset, seekorigin origin) {throw
New
NotSupportedException
"
Seek isn't Supported on Serial Ports.
"
}
public
Void
Settimeouts
int
Readintervaltimeout,
int
ReadtotalTimeOutmultiplier,
int
ReadtotalTimeoutConstant,
int
WriteTotalTimeoutmultiplier,
int
WriteTotalTimeoutConstant) {SerialTimeouts Timeouts
=
New
SerialTimeouts (ReadtotaltimeoutMultiPlier, ReadtotaltimeoutMultane, WriteTotalTimeoutMultiPlier, WriteTotalTimeoutConstant);
Unsafe
{Setcommtimeouts (m_hfile,
Ref
Timeouts);}}
public
Bool
SetPortSettings
Uint
Baudrate) {
Return
SetPortSettings (Baudrate, FlowControl.hardware);
public
Bool
SetPortSettings
Uint
Baudrate, FlowControl flowcontrol) {
Return
SetPortSettings (Baudrate, FlowControl, Parity.none);
public
Bool
SetPortSettings
Uint
Baudrate, FlowControl FlowControl, Parity Parity {
Return
SetPortSettings (Baudrate, FlowControl, Parity,
8
, Stopbits.one);
public
Bool
SetPortSettings
Uint
Baudrate, FlowControl FlowControl, Parity Parity,
Byte
DataBits, Stopbits Stopbits) {
Unsafe
{DCB DCB
=
New
DCB (); DCB.DCBLENGTH
=
Sizeof
(DCB); dcb.baudrate
=
Baudrate; dcb.bytesize
=
Database; dcb.stopbits
=
(
Byte
); DCB.PARITY
=
(
Byte
) Parity; dcb.fparity
=
(Parity)
>
0
)
?
1U
:
0u; dcb.fbinary
=
DCB.FDTRCONTROL
=
Dcb.ftxcontinueonxoff
=
1
Dcb.foutxctsflow
=
DCB.FABORTONERRORROR
=
(FlowControl
==
FlowControl.hardware)
?
1U
:
0u
DCB.FOUTX
=
Dcb.finx
=
(FlowControl
==
FlowControl.xonxoff)
?
1U
:
0u
DCB.FRTSCONTROL
=
(FlowControl
==
FlowControl.hardware)
?
2U
:
1U
DCB.xonlim
=
2048
DCB.XOfflim
=
512
Dcb.xonchar
=
0x11
;
//
Ctrl-q
Dcb.xoffchar
=
0x13
;
//
Ctrl-s
Return
Setcommstate (M_HFILE,
Ref
DCB);}}
public
Bool
SetPortSettings (DCB DCB) {
Return
Setcommstate (M_HFILE,
Ref
DCB);
public
Bool
GetPortSettings
OUT
DCB DCB) {
Unsafe
{DCB DCB2
=
New
DCB (); DCB2.DCBLENGTH
=
Sizeof
(DCB);
Bool
RET
=
Getcommstate (M_HFILE,
Ref
DCB2); DCB
=
DCB2;
Return
Ret;}}
public
Bool
Setxon () {
Return
EscapeCommfunction (M_HFILE, SETXON);
public
Bool
SetXoff () {
Return
Escapecommfunction (m_hfile, setxoff);
Private
Unsafe
Void
Asyncfscallback
Uint
Errorcode,
Uint
Numbytes, NativeOverlapped
*
Poverlapped) {serialasyncResult Sar
=
(SerialasyncResult) overlapped.unpack (Poverlapped) .asyncResult; sar.m_nerrorcode
=
ErrorCode; sar.m_nreadwritten
=
(
int
NumBytes; sar.m_bcompleted
=
True
;
IF
(SAR.Callback
! =
NULL
SAR.Callback.invoke (SAR); overlapped.free (Poverlapped);
#ndregion
Methods
#RegionConstants
Private
Const
Uint
PURGE_TXABORT
=
0x0001
;
//
Kill The Pending / Current Writes to The Comm Port.
Private
Const
Uint
Purge_Rxabort
=
0x0002
;
//
Kill The Pending / Current Reads to The Comm Port.
Private
Const
Uint
Purge_txclear
=
0x0004
;
//
Kill The Transmit Queueness.
Private
Const
Uint
Purge_Rxclear
=
0x0008
;
//
Kill The Typeahead Buffer if There.
Private
Const
Uint
Setxoff
=
1
;
//
Simulate Xoff Received
Private
Const
Uint
Setxon
=
2
;
//
Simulate Xon Received
Private
Const
Uint
SetRTS
=
3
;
//
SET RTS HIGH
Private
Const
Uint
CLRRTS
=
4
;
//
SET RTS LOW
Private
Const
Uint
Setdtr
=
5
;
//
SET DTR HIGH
Private
Const
Uint
CLRDTR
=
6
;
//
SET DTR LOW
Private
Const
Uint
Setbreak
=
8
;
//
Set The Device Break Line.
Private
Const
Uint
CLRBREAK
=
9
;
//
Clear The Device Break Line.
Private
Const
Uint
MS_CTS_ON
=
0x0010
;
Private
Const
Uint
MS_DSR_ON
=
0x0020
;
Private
Const
Uint
MS_RING_ON
=
0x0040
;
Private
Const
Uint
MS_RLSD_ON
=
0x0080
;
Private
Const
Uint
File_flag_overlapped
=
0x40000000
;
Private
Const
Uint
Open_existing
=
3
;
Private
Const
int
INVALID_HANDLE_VALUE
=
-
1
;
Private
Const
Uint
Generic_read
=
0x80000000
;
Private
Const
Uint
Generic_Write
=
0x40000000
;
Private
Const
Uint
Error_Success
=
0
;
Private
Const
Uint
Error_operation_aborted
=
995
;
Private
Const
Uint
ERROR_IO_PENDING
=
997
;
#ndregion
Constants
#REGION
ENUMS
public
ENUM
Parity {None, ODD, Even, Mark, Space};
public
ENUM
Stopbits {One, OneAndhalf, Two}; PUBLIC
ENUM
FlowControl {none, xonxoff, hardware};
#ndregion
ENUMS
#REGION
Classes
[Structlayout (layoutkind.sequential)]
public
Struct
DCB {
#REGION
Attributes
public
int
Dcbbleth;
public
Uint
Baudrate;
public
Uint
Flags;
public
Ushort
WRESERVED;
public
Ushort
Xonlim;
public
Ushort
Xofflim;
public
Byte
BYTESIZE;
public
Byte
Parity;
public
Byte
STOPBITS;
public
Sbyte
Xonchar;
public
Sbyte
Xoffchar;
public
Sbyte
ErrorChar;
public
Sbyte
EOFCHAR;
public
Sbyte
Evtchar;
public
Ushort
WRESERVED1;
#ndregion
Attributes
#REGION
PROPERTIES
public
Uint
Fbinary {
get
{
Return
Flags
&
0x0001
}
set
{Flags
=
Flags
&
~
1U
|
Value;}}
public
Uint
Fparity {
get
{
Return
(Flags
>>
1
)
&
1
}
set
{Flags
=
Flags
&
~
(
1U
>
2
)
&
1
}
set
{Flags
=
Flags
&
~
(
1U
>
3
)
&
1
}
set
{Flags
=
Flags
&
~
(
1U
>
4
)
&
3
}
set
{Flags
=
Flags
&
~
(
3u
>
6
)
&
1
}
set
{Flags
=
Flags
&
~
(
1U
>
Seduce
)
&
1
}
set
{Flags
=
Flags
&
~
(
1U
>
8
)
&
1
}
set
{Flags
=
Flags
&
~
(
1U
>
9
)
&
1
}
set
{Flags
=
Flags
&
~
(
1U
>
10
)
&
1
}
set
{Flags
=
Flags
&
~
(
1U
>
11
)
&
1
}
set
{Flags
=
Flags
&
~
(
1U
>
12
)
&
3
}
set
{Flags
=
Flags
&
~
(
3u
>
14
)
&
1
}
set
{Flags
=
Flags
&
~
(
1U
<<
14
)
|
(Value
<<
14
}}
#ndregion
PROPERTIES
#REGION
Methods
public
Override
String
Tostring () {
Return
"
Dcboughth:
"
Dcbleth
"
/ r / n
"
"
Baudrate:
"
Baudrate
"
/ r / n
"
"
Fbinary:
"
Fbinary
"
/ r / n
"
"
Fparity:
"
Fparity
"
/ r / n
"
"
Foutxctsflow:
"
Foutxctsflow
"
/ r / n
"
"
Foutxdsrflow:
"
Foutxdsrflow
"
/ r / n
"
"
FDTRCONTROL:
"
FDTRControl
"
/ r / n
"
"
FDSRSENSITIVITY:
"
FDSRSENSITIVITY
"
/ r / n
"
"
ftxcontinueonxoff:
"
ftxcontinueonxoff
"
/ r / n
"
"
Foutx:
"
foutx
"
/ r / n
"
"
FINX:
"
FINX
"
/ r / n
"
"
FerrorChar:
"
Ferrorchar
"
/ r / n
"
"
Fnull:
"
Fnull
"
/ r / n
"
"
FRTSCONTROL:
"
FRTSControl
"
/ r / n
"
"
Fabortonerror:
"
Fabortonerror
"
/ r / n
"
"
Xonlim:
"
Xonlim
"
/ r / n
"
"
Xofflim:
"
Xofflim
"
/ r / n
"
"
BYTESIZE:
"
BYTESIZE
"
/ r / n
"
"
Parity:
"
Parity
"
/ r / n
"
"
STOPBITS:
"
STOPBITS
"
/ r / n
"
"
Xonchar:
"
Xonchar
"
/ r / n
"
"
Xoffchar:
"
Xoffchar
"
/ r / n
"
"
EOFCHAR:
"
EOFCHAR
"
/ r / n
"
"
Evtchar:
"
Evtchar
"
/ r / n
"
}
#ndregion
Methods
}
Private
Class
SerialAlasyncResult: IASYNCRESULT, IDISPOSABLE {
#REGION
Attributes
Internal
Bool
m_bendopertycalled
=
False
;
Internal
Bool
m_bisread;
Internal
int
m_nreadwritten
=
0
;
Internal
Bool
m_bcompleted
=
False
;
Internal
Bool
m_bcompletedsynchronously
=
False
;
Internal
Uint
M_NERRORCODE
=
Error_suCcess;
Private
Object
M_AsyncObject;
Private
Object
M_StateObject;
Private
ManualRetevent M_WaitHandle
=
New
ManualRetevent
False
);
Private
AsyncCallback m_callback;
Private
Gchandle m_gchbuffer;
#ndregion
Attributes
#REGION
PROPERTIES
Internal
Bool
Endoperationcalled {
get
{
Return
m_bendopertycalled;}}
public
Bool
IScompleted {
get
{
Return
m_bcompleted;}}
public
Bool
Completedsynchronously {
get
{
Return
m_bcompletedsynchronously;}}
public
Object
AsyncObject {
get
{
Return
m_asyncObject;}}
public
Object
AskYNCSTATE {
get
{
Return
M_StateObject;}}
public
Waithandle asyncwaithandle {
get
{
Return
m_waithandle;}}
Internal
ManualRevent Waithandle {
get
{
Return
m_waithandle;}}
public
AsyncCallback Callback {
get
{
Return
m_callback;}}
#ndregion
PROPERTIES
#REGION
Constructors
public
SerialAlaAlaAlasyncResult
Object
AsyncObject,
Object
StateObject, AsyncCallback Callback,
Bool
Bisread, gchandle gchbuffer {m_asyncObject
=
AsyncObject; m_stateObject
=
StateObject; m_callback =
Callback; m_bisread
=
Bisread; m_gchbuffer
=
gchbuffer;
#ndregion
Constructors
#REGION
Methods
public
Void
Dispose () {m_waithandle.close (); m_gchbuffer.free ();
#ndregion
Methods
}
#ndregion
Classes
#REGION
Imports
[DLLIMPORT
"
Kernel32.dll
"
, EntryPoint
=
"
Createfilew
"
, SetLastError
=
True
Charset
=
Charset.unicode, Exactspelling
=
True
)]]
Static
Extern
INTPTR CREATEFILE
String
Filename,
Uint
Access,
Uint
Sharemode,
Uint
Security_attributes,
Uint
Creation,
Uint
Flags,
Uint
Template); [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
Bool
CloseHandle (INTPTR HANDLE); [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
Unsafe
Bool
Readfile (INTPTR HFILE,
Byte
*
lpbuffer,
Uint
NNumberofbytestoread,
OUT
Uint
LpnumberofbytesRead, NativeOverlapped
*
LPOVERLAPPED; [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
Unsafe
Bool
Writefile (INTPTR HFILE,
Byte
*
lpbuffer,
Uint
NNumberofbytestowrite,
OUT
Uint
lpnumberofbyteswritten, NativeOverlapped
*
LPOVERLAPPED; [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
Bool
Setcommtimeouts (INTPTR HFILE,
Ref
SerialTimeouts lpcommtimeouts); [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
Bool
SetCommState (INTPTR HFILE,
Ref
DCB LPDCB); [DLLIMPORT
"
Kernel32.dll
"
SetLasterror =
True
)]]
Static
Extern
Bool
Getcommstate (INTPTR HFILE,
Ref
DCB LPDCB); [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
Bool
Buildcommdcb (
String
DEF,
Ref
DCB LPDCB); [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
int
GetLastError (); [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
Bool
FlushfileBuffers (INTPTR HFILE); [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
Bool
PurgeComm (INTPTR HFILE,
Uint
DWFLAGS); [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
Bool
EscapeCommfunction (INTPTR HFILE,
Uint
DWFUNC); [DLLIMPORT
"
Kernel32.dll
"
, SetLastError
=
True
)]]
Static
Extern
Bool
GetcommmodemStatus (INTPTR HFILE,
OUT
Uint
Modemstat);
#ndregion
Imports
} [Structlayout (layoutkind.sequential)]
public
Struct
SERIALTIMEOUTS {
#REGION
Attributes
public
int
Readintervaltimeout;
public
int
ReadtotalTimeOutmultiplier;
public
int
ReadtotalTimeoutConstant;
public
int
WriteTotalTimeoutmultiplier;
public
int
WriteTotalTimeoutConstant;
#ndregion
Attributes
#REGION
Constructors
public
SerialTimeouts
int
R1,
int
R2,
int
R3,
int
W1,
int
W2) {readintervaltimeout
=
R1; ReadTotalTimeoutMultiplier
=
R2; ReadTotalTimeoutConstant
=
R3; WriteTotalTimeoutmultiplier
=
W1; WriteTotalTimeoutConstant
=
W2;}
#ndregion
Constructors
#REGION
Methods
public
Override
String
Tostring () {
Return
"
ReadintervalTimeout:
"
Readintervaltimeout
"
/ r / n
"
"
ReadtotalTimeOutmultiplier:
"
ReadtotalTimeOutmultiplier
"
/ r / n
"
"
ReadtotalTimeoutConstant:
"
ReadtotalTimeoutConstant
"
/ r / n
"
"
WriteTotalTimeoutmultiplier:
"
WriteTotalTimeoutmultiplier
"
/ r / n
"
"
WriteTotalTimeoutConstant:
"
WriteTotalTimeoutConstant
"
/ r / n
"
}
#ndregion
Methods
}
Using
System;
Using
System.IO;
Using
System.Threading;
Using
Loman.io;
Namespace
SerialStreamReader {
Class
App {
//
The main serial stream
Static
SerialStream SS; [Stathread]
Static
Void
Main
String
[] args) {
//
Create a serial port
SS
=
New
SerialStream ();
Try
{Ss.open
"
Com3
"
}
Catch
(Exception E) {Console.writeLine
"
Error:
"
E.MESSAGE);
Return
}
//
SET port settings
ss.setportSettings
9600
);
//
SET TIMEOUT SO READS AFTER 20MS OF SILENCE AFTER A Response
SS.SETTIMEOUTS
20
,
0
,
0
,
0
,
0
);
//
Create the streamwriter used to send commands
Streetwriter SW
=
New
StreamWriter (SS, System.Text.Encoding.ascii);
//
Create The Thread Used to Read Responses
Thread ResponseReaderthread
=
New
THREAD
New
ThreadStart (ReadResponsethread); responsereaderthread.start ();
//
Read All Returned Lines
for
(;;) {
//
Read Command from Console
String
Command
=
Console.readline ();
//
Check for EXIT COMMAND
IF
(Command.trim (). TOLOWER ()
==
"
exit
"
) {ResponseReaderthread.abort (); BREAK
}
//
Write Command to MODEM
SW.writeLine (Command); sw.flush ();}}
//
Main loop forreading responses
Static
Void
ReadResponsethread () {StreetReader SR
=
New
StreamReader (SS, System.Text.Encoding.ascii);
Try
{
for
(;;) {
//
Read Response from MODEM
String
Response
=
sr.readline (); console.writeline
"
Response:
"
Response);
Catch
Threadabortext {}}}}}