Main Page   Namespace List   Compound List   File List   Namespace Members   Compound Members   Related Pages  

serialPAL.hpp

Go to the documentation of this file.
00001 
00002 #ifndef __SERIAL_WIN32_PAL_HPP__
00003 #define __SERIAL_WIN32_PAL_HPP__
00004 
00005 //#include <winbase.h>
00006 #include <assert.h>
00007 #include <ctype.h>
00008 #include <stdio.h>
00009 #include <windows.h>
00010 
00011 namespace lfc
00012 {
00013 namespace win32PAL
00014 {
00015 
00017 
00021 namespace serial
00022 {
00023 
00024 const int MAX_ERROR_CODE = 2;
00025 
00026 enum ErrorCodes
00027 {
00028     errOk,
00029     errGeneric,
00030     errNotSupported,
00031 };
00032 
00033 extern const char *messagesTable[MAX_ERROR_CODE + 1];
00034 
00035 
00037 typedef ::HANDLE Handle;
00038 
00040 const Handle NULL_HANDLE = INVALID_HANDLE_VALUE;
00041 
00042 
00044 struct PortSettings
00045 {
00046     DCB dcb;
00047     COMMTIMEOUTS commTimeouts;
00048 };
00049 
00050 
00052 const int
00053     purgeInput      = 0x0001,
00054     purgeOutput     = 0x0002;
00055 
00057 const int
00058     mstatusDSR      = 0x0001,
00059     mstatusDTR      = 0x0002,//$ not supported!
00060     mstatusRTS      = 0x0004,//$ not supported!
00061     mstatusCTS      = 0x0008,
00062     mstatusDCD      = 0x0010,
00063     mstatusRNG      = 0x0020;
00064 
00065 
00067 
00070 inline int init()
00071 {
00072     return errOk;
00073 }
00074 
00075 
00077 
00080 inline int cleanup()
00081 {
00082     return errOk;
00083 }
00084 
00085 
00087 
00092 inline int open(Handle &handle, const char *name)
00093 {
00094     assert(handle == NULL_HANDLE);
00095 
00096     HANDLE h = ::CreateFile(name, GENERIC_READ | GENERIC_WRITE,
00097         0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00098     if(h != INVALID_HANDLE_VALUE)
00099     {
00100         handle = h;
00101         return errOk;
00102     }
00103     else
00104         return errGeneric;
00105 }
00106 
00107 
00109 
00113 inline int close(Handle handle)
00114 {
00115     assert(handle != NULL_HANDLE);
00116     return ::CloseHandle(handle) ? errOk : errGeneric;
00117 }
00118 
00119 
00121 
00128 inline int write(Handle handle, const void *buff, long count, long &writtenCount)
00129 {
00130     assert(handle != NULL_HANDLE);
00131 
00132     DWORD dwCount = static_cast<DWORD>(count);
00133     DWORD dwWritten = 0;
00134 
00135     if(::WriteFile(handle, buff, dwCount, &dwWritten, NULL))
00136     {
00137         writtenCount = static_cast<long>(dwWritten);
00138         return errOk;
00139     }
00140     else
00141         return errGeneric;
00142 }
00143 
00145 
00152 inline int read(Handle handle, void *buff, long count, long &readCount)
00153 {
00154     assert(handle != NULL_HANDLE);
00155 
00156     DWORD dwCount = static_cast<DWORD>(count);
00157     DWORD dwRead = 0;
00158 
00159     if(::ReadFile(handle, buff, dwCount, &dwRead, NULL))
00160     {
00161         readCount = static_cast<long>(dwRead);
00162         return errOk;
00163     }
00164     else
00165         return errGeneric;
00166 }
00167 
00168 
00170 
00174 inline int flush(Handle handle)
00175 {
00176     assert(handle != NULL_HANDLE);
00177     return ::FlushFileBuffers(handle) ? errOk : errGeneric;
00178 }
00179 
00180 
00182 
00194 inline int setup(Handle handle, const char *portSettings)
00195 {
00196     assert(handle != NULL_HANDLE);
00197     assert(portSettings != NULL);
00198 
00199     const char *p = portSettings;
00200     long baud = 0;
00201     long byteSize = 0;
00202     long stopBits = 0;
00203     char parity = '#';
00204     
00205     // parse settings
00206     while( isdigit(*p) )
00207         baud = baud * 10 + *p++ - '0';
00208     if(*p++ != ',')
00209         return errGeneric;
00210     byteSize = *p++ - '0';
00211     if(byteSize < 5 || byteSize > 8)
00212         return errGeneric;
00213     parity = toupper(*p++);
00214     if(::strchr("NOES", parity) == NULL)
00215         return errGeneric;
00216     stopBits = *p++ - '0';
00217     if(stopBits != 1 && stopBits != 2)
00218         return errGeneric;
00219     if(*p != 0)
00220         return errGeneric;
00221         
00222     // setup DCB
00223     char buff[1024];
00224     ::sprintf(buff, "%ld,%c,%ld,%ld", baud, parity, byteSize, stopBits);
00225     
00226     DCB dcb = {0};
00227     dcb.DCBlength = sizeof(DCB);
00228     
00229     // warning: under win9x first BuildCommDCB must not be r/o!
00230     if(!::BuildCommDCB(buff, &dcb))
00231         return errGeneric;
00232         
00233     return ::SetCommState(handle, &dcb) ? errOk : errGeneric;
00234 }
00235 
00236 
00238 
00244 inline int availableCount(Handle handle, long &count)
00245 {
00246     assert(handle != NULL_HANDLE);
00247 
00248     DWORD dwErrors;
00249     COMSTAT comStat = {0};
00250 
00251     ::ClearCommError(handle, &dwErrors, &comStat);
00252     assert(dwErrors == 0);
00253 
00254     count = static_cast<long>(comStat.cbInQue);
00255     return errOk;
00256 }
00257 
00258 
00260 
00265 inline int setHardwareFlowControl(Handle handle, bool bEnable)
00266 {
00267     assert(handle != NULL_HANDLE);
00268 
00269     DCB dcb = {0};
00270     dcb.DCBlength = sizeof(DCB);
00271 
00272     if(!::GetCommState(handle, &dcb))
00273         return errGeneric;
00274 
00275     if(bEnable)
00276     {
00277         dcb.fOutxCtsFlow = true;
00278         dcb.fOutxDsrFlow = true;
00279         dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;//$?
00280         dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;//$?
00281     }
00282     else
00283     {
00284         dcb.fOutxCtsFlow = false;
00285         dcb.fOutxDsrFlow = false;
00286         dcb.fDtrControl = DTR_CONTROL_ENABLE;
00287         dcb.fRtsControl = RTS_CONTROL_ENABLE;
00288     }
00289 
00290     return ::SetCommState(handle, &dcb) ? errOk : errGeneric;
00291 }
00292 
00293 
00295 
00302 inline int setSoftwareFlowControl(Handle handle, bool bEnable, char Xon, char Xoff)
00303 {
00304     assert(handle != NULL_HANDLE);
00305 
00306     DCB dcb = {0};
00307     dcb.DCBlength = sizeof(DCB);
00308 
00309     if(!::GetCommState(handle, &dcb))
00310         return errGeneric;
00311 
00312     if(bEnable)
00313     {
00314         dcb.fOutX = true;
00315         dcb.fInX = true;
00316         dcb.fTXContinueOnXoff = false;//$?
00317         dcb.XonLim = 256;//$?
00318         dcb.XoffLim = 512;//$?
00319     }
00320     else
00321     {
00322         dcb.fOutX = false;
00323         dcb.fInX = false;
00324     }
00325 
00326     return ::SetCommState(handle, &dcb) ? errOk : errGeneric;
00327 }
00328 
00329 
00331 
00336 inline int setReadTimeouts(Handle handle, long timeout)
00337 {
00338     assert(handle != NULL_HANDLE);
00339 
00340     COMMTIMEOUTS to = {0};
00341 
00342     if(!::GetCommTimeouts(handle, &to))
00343         return errGeneric;
00344 
00345     to.ReadIntervalTimeout = MAXDWORD;
00346     to.ReadTotalTimeoutMultiplier = MAXDWORD;
00347     to.ReadTotalTimeoutConstant = timeout;
00348 
00349     return ::SetCommTimeouts(handle, &to) ? errOk : errGeneric;
00350 }
00351 
00352 
00354 
00361 inline int setBlockingRead(Handle handle, bool bBlocking)
00362 {
00363     assert(handle != NULL_HANDLE);
00364 
00365     COMMTIMEOUTS to = {0};
00366 
00367     if(!::GetCommTimeouts(handle, &to))
00368         return errGeneric;
00369 
00370     if(bBlocking)
00371     {
00372         to.ReadIntervalTimeout = 0;
00373         to.ReadTotalTimeoutMultiplier = 0;
00374         to.ReadTotalTimeoutConstant = 0;
00375     }
00376     else
00377     {
00378         to.ReadIntervalTimeout = MAXDWORD;
00379         to.ReadTotalTimeoutMultiplier = 0;
00380         to.ReadTotalTimeoutConstant = 0;
00381     }
00382 
00383     return ::SetCommTimeouts(handle, &to) ? errOk : errGeneric;
00384 }
00385 
00386 
00388 
00395 inline int purgeBuffer(Handle handle, int flags)
00396 {
00397     assert(handle != NULL_HANDLE);
00398     
00399     DWORD win32flags = 0;
00400     win32flags |= flags & purgeInput ? PURGE_RXCLEAR : 0;
00401     win32flags |= flags & purgeOutput ? PURGE_TXCLEAR : 0;
00402 
00403     return ::PurgeComm(handle, win32flags) ? errOk : errGeneric;
00404 }
00405 
00406 
00408 
00412 inline int sendBreak(Handle handle)
00413 {
00414     assert(handle != NULL_HANDLE);
00415 
00416     if(!::SetCommBreak(handle))
00417         return errGeneric;
00418     ::Sleep(500);
00419     if(!::ClearCommBreak(handle))
00420         return errGeneric;
00421         
00422     return errOk;
00423 }
00424 
00425 
00427 
00437 inline int getModemStatus(Handle handle, int &status)
00438 {
00439     assert(handle != NULL_HANDLE);
00440     
00441     DWORD win32status = 0;
00442     
00443     if(!::GetCommModemStatus(handle, &win32status))
00444         return errGeneric;
00445         
00446     status = 0;
00447     status |= win32status & MS_CTS_ON ? mstatusCTS : 0;
00448     status |= win32status & MS_DSR_ON ? mstatusDSR : 0;
00449     status |= win32status & MS_RING_ON ? mstatusRNG : 0;
00450     status |= win32status & MS_RLSD_ON ? mstatusDCD : 0;
00451     
00452     return errOk;
00453 }
00454 
00455 
00457 
00463 inline int setDTR(Handle handle, bool bEnable)
00464 {
00465     assert(handle != NULL_HANDLE);
00466     return ::EscapeCommFunction(handle, bEnable ? SETDTR : CLRDTR) ?
00467         errOk : errGeneric;
00468 }
00469 
00470 
00472 
00478 inline int setRTS(Handle handle, bool bEnable)
00479 {
00480     assert(handle != NULL_HANDLE);
00481     return ::EscapeCommFunction(handle, bEnable ? SETRTS : CLRRTS) ?
00482         errOk : errGeneric;
00483 }
00484 
00485 
00487 
00492 inline int saveSettings(Handle handle, PortSettings &settings)
00493 {
00494     assert(handle != NULL_HANDLE);
00495     
00496     // get current DCB
00497     DCB dcb = {0};
00498     dcb.DCBlength = sizeof(DCB);
00499     if(!::GetCommState(handle, &dcb))
00500         return errGeneric;
00501 
00502     // get current comm timeouts
00503     COMMTIMEOUTS to = {0};
00504     if(!::GetCommTimeouts(handle, &to))
00505         return errGeneric;
00506         
00507     settings.dcb = dcb;
00508     settings.commTimeouts = to;
00509     return errOk;
00510 }
00511 
00512 
00514 
00519 inline int restoreSettings(Handle handle, const PortSettings &settings)
00520 {
00521     assert(handle != NULL_HANDLE);
00522     
00523     DCB dcb = settings.dcb;
00524     COMMTIMEOUTS commTimeouts = settings.commTimeouts;
00525     
00526     // restore DCB
00527     if(!::SetCommState(handle, &dcb))
00528         return errGeneric;
00529     
00530     // restore comm timeouts
00531     if(!::SetCommTimeouts(handle, &commTimeouts))
00532         return errGeneric;
00533         
00534     return errOk;
00535 }
00536 
00537 
00539 
00542 inline const char *message(int index)
00543 {
00544     assert(index >= 0 && index <= MAX_ERROR_CODE);
00545     return messagesTable[index];
00546 }
00547 
00548 
00549 } // namespace win32PAL::serial
00550 } // namespace win32PAL
00551 
00552 namespace pal = win32PAL;
00553 
00554 } // namespace lfc
00555 
00556 
00557 #endif  // __SERIAL_WIN32_PAL_HPP__
00558 

Generated on Sat Jan 26 00:34:58 2002 for LFC2 PAL by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001