SerialPort.cs (prima metà)
codice:
#region Using
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
#endregion
namespace TestAppConsole
{
sealed internal class SerialPort
{
#region Class definition
public SerialPort()
{
}
#endregion
#region Methods
public void Connect()
{
fileHandle = Win32Methods.CreateFile(PortName,
Win32Methods.GENERIC_READ | Win32Methods.GENERIC_WRITE,
0, (IntPtr)0, Win32Methods.OPEN_EXISTING, Win32Methods.FILE_FLAG_OVERLAPPED,
Win32Methods.NULL);
if (fileHandle == Win32Methods.INVALID_HANDLE_VALUE)
{
throw new Exception("Connection not estabilished!");
}
SetHandFlow();
SetQueueSize();
SetTimeOut();
SetFifoControl();
ClearRts();
SetDtr();
SetBaudRate(BaudRate);
SetLineControl();
}
public void Disconnect()
{
Win32Methods.CloseHandle(fileHandle);
}
public void OverlapCommMask(OverlappedFunction[] overlappedFunctions, uint setCommMask)
{
bool fWaitingOnStat = false;
bool cycleActive = true;
NativeOverlapped osStatus = new NativeOverlapped();
osStatus.EventHandle = Win32Methods.CreateEvent((IntPtr)null, true, false, null);
if (osStatus.EventHandle == (IntPtr)null)
{
// error creating event; abort
cycleActive = false;
}
for (; cycleActive; )
{
// Issue a status event check if one hasn't been issued already.
if (!fWaitingOnStat)
{
int lpEvtMask = 0;
SetCommMask(setCommMask);
if (WaitCommEvent(ref lpEvtMask, ref osStatus) == 0)
{
if (Marshal.GetLastWin32Error() == Win32Methods.ERROR_IO_PENDING)
{
fWaitingOnStat = true;
}
else
{
// error in WaitCommEvent; abort
break;
}
}
}
// Check on overlapped operation.
if (fWaitingOnStat)
{
// Wait a little while for an event to occur.
UInt32 waitForSingleObjectResponse =
Win32Methods.WaitForSingleObject(osStatus.EventHandle, 14);
if (waitForSingleObjectResponse == Win32Methods.WAIT_OBJECT_0)
{
fWaitingOnStat = false;
}
else if (waitForSingleObjectResponse == Win32Methods.WAIT_TIMEOUT)
{
foreach (OverlappedFunction overlappedFunction in overlappedFunctions)
{
executeOverlappedFunction(overlappedFunction);
}
break;
}
}
}
Win32Methods.CloseHandle((int)osStatus.EventHandle);
}
public void TransmitCharOverlap(byte charToSend)
{
bool fWaitingOnStat = false;
bool cycleActive = true;
NativeOverlapped osStatus = new NativeOverlapped();
NativeOverlapped osStatus_2 = new NativeOverlapped();
osStatus.EventHandle = Win32Methods.CreateEvent((IntPtr)null, true, false, null);
if (osStatus.EventHandle == (IntPtr)null)
{
// error creating event; abort
cycleActive = false;
}
for ( ; cycleActive; )
{
// Issue a status event check if one hasn't been issued already.
if (!fWaitingOnStat)
{
if (TransmitCommCharDeviceIO(charToSend, ref osStatus))
{
// end of the operation
break;
}
else
{
if (Marshal.GetLastWin32Error() == Win32Methods.ERROR_IO_PENDING)
{
fWaitingOnStat = true;
}
else
{
// error in TransmitCommCharDeviceIO; abort
break;
}
}
}
// Check on overlapped operation.
if (fWaitingOnStat)
{
// Wait a little while for an event to occur.
UInt32 waitForSingleObjectResponse = Win32Methods.WaitForSingleObject(osStatus.EventHandle, 0);
if (waitForSingleObjectResponse == Win32Methods.WAIT_OBJECT_0)
{
fWaitingOnStat = false;
}
else if (waitForSingleObjectResponse == Win32Methods.WAIT_TIMEOUT)
{
osStatus_2.EventHandle = Win32Methods.CreateEvent((IntPtr)null, true, false, null);
int lpEvtMask = 0;
WaitCommEvent(ref lpEvtMask, ref osStatus_2);
Win32Methods.CloseHandle((int)osStatus_2.EventHandle);
break;
}
}
}
Win32Methods.CloseHandle((int)osStatus.EventHandle);
Win32Methods.CloseHandle((int)osStatus_2.EventHandle);
}
public bool TransmitCommCharDeviceIO(byte charToSend, ref NativeOverlapped osStatus)
{
byte[] buffer = new byte[1];
buffer[0] = charToSend;
int controlCode = Win32Methods.CTL_CODE(
Win32Methods.FILE_DEVICE_SERIAL_PORT, 6, Win32Methods.METHOD_BUFFERED,
Win32Methods.FILE_ANY_ACCESS);
return WriteChar(buffer, controlCode, 0, ref osStatus);
}
public bool WriteChar(byte[] buffer, int controlCode, int outputBufferLength,
ref NativeOverlapped osStatus)
{
byte[] outputBuffer = new byte[outputBufferLength];
int bytesReturned = new int();
return Win32Methods.DeviceIoControl(fileHandle, controlCode, buffer, buffer.Length,
outputBuffer, outputBufferLength, ref bytesReturned, ref osStatus);
}