Advertisement
Guest User

Serial_Port.cpp

a guest
Jul 12th, 2012
8,144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.08 KB | None | 0 0
  1. ///////////////////////////////// Includes //////////////////////////////////
  2. #include "stdafx.h"
  3. #include "Serial_Port.h"
  4. #include "winerror.h"
  5.  
  6. ///////////////////////////////// defines /////////////////////////////////////
  7.  
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13.  
  14. //////////////////////////////// Implementation ///////////////////////////////
  15.  
  16. //Class which handles CancelIo function which must be constructed at run time
  17. //since it is not imeplemented on NT 3.51 or Windows 95. To avoid the loader
  18. //bringing up a message such as "Failed to load due to missing export...", the
  19. //function is constructed using GetProcAddress. The Serial_Port::CancelIo
  20. //function then checks to see if the function pointer is NULL and if it is it
  21. //throws an exception using the error code ERROR_CALL_NOT_IMPLEMENTED which
  22. //is what 95 would have done if it had implemented a stub for it in the first
  23. //place !!
  24.  
  25. class _SERIAL_PORT_DATA
  26. {
  27. public:
  28. //Constructors /Destructors
  29. _SERIAL_PORT_DATA();
  30. ~_SERIAL_PORT_DATA();
  31.  
  32. HINSTANCE m_hKernel32;
  33. typedef BOOL (CANCELIO)(HANDLE);
  34. typedef CANCELIO* LPCANCELIO;
  35. LPCANCELIO m_lpfnCancelIo;
  36. };
  37.  
  38. _SERIAL_PORT_DATA::_SERIAL_PORT_DATA()
  39. {
  40. m_hKernel32 = LoadLibrary(_T("KERNEL32.DLL"));
  41. VERIFY(m_hKernel32 != NULL);
  42. m_lpfnCancelIo = (LPCANCELIO) GetProcAddress(m_hKernel32, "CancelIo");
  43. }
  44.  
  45. _SERIAL_PORT_DATA::~_SERIAL_PORT_DATA()
  46. {
  47. FreeLibrary(m_hKernel32);
  48. m_hKernel32 = NULL;
  49. }
  50.  
  51.  
  52. //The local variable which handle the function pointers
  53. _SERIAL_PORT_DATA _SerialPortData;
  54.  
  55. ////////// Exception handling code
  56.  
  57. void AfxThrowSerialException(DWORD dwError)
  58. {
  59. if (dwError == 0)
  60. dwError = ::GetLastError();
  61.  
  62. CSerialException* pException = new CSerialException(dwError);
  63.  
  64. TRACE(_T("Warning: throwing CSerialException for error %d\n"), dwError);
  65. THROW(pException);
  66. }
  67.  
  68. BOOL CSerialException::GetErrorMessage(LPTSTR pstrError, UINT nMaxError, PUINT pnHelpContext)
  69. {
  70. ASSERT(pstrError != NULL && AfxIsValidString(pstrError, nMaxError));
  71.  
  72. if (pnHelpContext != NULL)
  73. *pnHelpContext = 0;
  74.  
  75. LPTSTR lpBuffer;
  76. BOOL bRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  77. NULL, m_dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
  78. (LPTSTR) &lpBuffer, 0, NULL);
  79.  
  80. if (bRet == FALSE)
  81. *pstrError = '\0';
  82. else
  83. {
  84. lstrcpyn(pstrError, lpBuffer, nMaxError);
  85. bRet = TRUE;
  86.  
  87. LocalFree(lpBuffer);
  88. }
  89.  
  90. return bRet;
  91. }
  92.  
  93. CString CSerialException::GetErrorMessage()
  94. {
  95. CString rVal;
  96. LPTSTR pstrError = rVal.GetBuffer(4096);
  97. GetErrorMessage(pstrError, 4096, NULL);
  98. rVal.ReleaseBuffer();
  99. return rVal;
  100. }
  101.  
  102. CSerialException::CSerialException(DWORD dwError)
  103. {
  104. m_dwError = dwError;
  105. }
  106.  
  107. CSerialException::~CSerialException()
  108. {
  109. }
  110.  
  111. IMPLEMENT_DYNAMIC(CSerialException, CException)
  112.  
  113. #ifdef _DEBUG
  114. void CSerialException::Dump(CDumpContext& dc) const
  115. {
  116. CObject::Dump(dc);
  117.  
  118. dc << "m_dwError = " << m_dwError;
  119. }
  120. #endif
  121.  
  122. Serial_Port::Serial_Port()
  123. {
  124. m_hComm = INVALID_HANDLE_VALUE;
  125. m_bOverlapped = FALSE;
  126. }
  127.  
  128. Serial_Port::~Serial_Port()
  129. {
  130. close_port();
  131. }
  132.  
  133. IMPLEMENT_DYNAMIC(Serial_Port, CObject)
  134.  
  135. #ifdef _DEBUG
  136. void Serial_Port::Dump(CDumpContext& dc) const
  137. {
  138. CObject::Dump(dc);
  139.  
  140. dc << _T("m_hComm = ") << m_hComm << _T("\n");
  141. dc << _T("m_bOverlapped = ") << m_bOverlapped;
  142. }
  143. #endif
  144.  
  145. void Serial_Port::open_port(int nPort,
  146. unsigned int dwBaud,
  147. Parity parity,
  148. unsigned char DataBits,
  149. StopBits stopbits,
  150. FlowControl fc,
  151. int bOverlapped)
  152. {
  153. //Validate our parameters
  154. ASSERT(nPort>0 && nPort<=255);
  155.  
  156. //Call CreateFile to open up the comms port
  157. CString sPort;
  158. sPort.Format(_T("\\\\.\\COM%d"), nPort);
  159. m_hComm = CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, bOverlapped ? FILE_FLAG_OVERLAPPED : 0, NULL);
  160. if (m_hComm == INVALID_HANDLE_VALUE)
  161. {
  162. TRACE(_T("Failed to open up the comms port\n"));
  163. AfxThrowSerialException();
  164. }
  165.  
  166. m_bOverlapped = bOverlapped;
  167.  
  168. //Get the current state prior to changing it
  169. DCB dcb;
  170. GetState(dcb);
  171.  
  172. //Setup the baud rate
  173. dcb.BaudRate = dwBaud;
  174.  
  175. //Setup the Parity
  176. switch (parity)
  177. {
  178. case EvenParity: dcb.Parity = EVENPARITY; break;
  179. case MarkParity: dcb.Parity = MARKPARITY; break;
  180. case NoParity: dcb.Parity = NOPARITY; break;
  181. case OddParity: dcb.Parity = ODDPARITY; break;
  182. case SpaceParity: dcb.Parity = SPACEPARITY; break;
  183. default: ASSERT(FALSE); break;
  184. }
  185.  
  186. //Setup the data bits
  187. dcb.ByteSize = DataBits;
  188.  
  189. //Setup the stop bits
  190. switch (stopbits)
  191. {
  192. case OneStopBit: dcb.StopBits = ONESTOPBIT; break;
  193. case OnePointFiveStopBits: dcb.StopBits = ONE5STOPBITS; break;
  194. case TwoStopBits: dcb.StopBits = TWOSTOPBITS; break;
  195. default: ASSERT(FALSE); break;
  196. }
  197.  
  198. //Setup the flow control
  199. dcb.fDsrSensitivity = FALSE;
  200. switch (fc)
  201. {
  202. case NoFlowControl:
  203. {
  204. dcb.fOutxCtsFlow = FALSE;
  205. dcb.fOutxDsrFlow = FALSE;
  206. dcb.fOutX = FALSE;
  207. dcb.fInX = FALSE;
  208. break;
  209. }
  210. case CtsRtsFlowControl:
  211. {
  212. dcb.fOutxCtsFlow = TRUE;
  213. dcb.fOutxDsrFlow = FALSE;
  214. dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
  215. dcb.fOutX = FALSE;
  216. dcb.fInX = FALSE;
  217. break;
  218. }
  219. case CtsDtrFlowControl:
  220. {
  221. dcb.fOutxCtsFlow = TRUE;
  222. dcb.fOutxDsrFlow = FALSE;
  223. dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
  224. dcb.fOutX = FALSE;
  225. dcb.fInX = FALSE;
  226. break;
  227. }
  228. case DsrRtsFlowControl:
  229. {
  230. dcb.fOutxCtsFlow = FALSE;
  231. dcb.fOutxDsrFlow = TRUE;
  232. dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
  233. dcb.fOutX = FALSE;
  234. dcb.fInX = FALSE;
  235. break;
  236. }
  237. case DsrDtrFlowControl:
  238. {
  239. dcb.fOutxCtsFlow = FALSE;
  240. dcb.fOutxDsrFlow = TRUE;
  241. dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
  242. dcb.fOutX = FALSE;
  243. dcb.fInX = FALSE;
  244. break;
  245. }
  246. case XonXoffFlowControl:
  247. {
  248. dcb.fOutxCtsFlow = FALSE;
  249. dcb.fOutxDsrFlow = FALSE;
  250. dcb.fOutX = TRUE;
  251. dcb.fInX = TRUE;
  252. dcb.XonChar = 0x11;
  253. dcb.XoffChar = 0x13;
  254. dcb.XoffLim = 100;
  255. dcb.XonLim = 100;
  256. break;
  257. }
  258. default:
  259. {
  260. ASSERT(FALSE);
  261. break;
  262. }
  263. }
  264.  
  265. //Now that we have all the settings in place, make the changes
  266. SetState(dcb);
  267. }
  268.  
  269. void Serial_Port::close_port()
  270. {
  271. if (IsOpen())
  272. {
  273. BOOL bSuccess = CloseHandle(m_hComm);
  274. m_hComm = INVALID_HANDLE_VALUE;
  275. if (!bSuccess)
  276. TRACE(_T("Failed to close up the comms port, GetLastError:%d\n"), GetLastError());
  277. m_bOverlapped = FALSE;
  278. }
  279. }
  280.  
  281. void Serial_Port::Attach(HANDLE hComm)
  282. {
  283. close_port();
  284. m_hComm = hComm;
  285. }
  286.  
  287. HANDLE Serial_Port::Detach()
  288. {
  289. HANDLE hrVal = m_hComm;
  290. m_hComm = INVALID_HANDLE_VALUE;
  291. return hrVal;
  292. }
  293.  
  294. DWORD Serial_Port::Read(void* lpBuf, DWORD dwCount)
  295. {
  296. ASSERT(IsOpen());
  297. ASSERT(!m_bOverlapped);
  298.  
  299. DWORD dwBytesRead = 0;
  300. if (!ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, NULL))
  301. {
  302. TRACE(_T("Failed in call to ReadFile\n"));
  303. AfxThrowSerialException();
  304. }
  305.  
  306. return dwBytesRead;
  307. }
  308.  
  309. BOOL Serial_Port::Read(void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped)
  310. {
  311. ASSERT(IsOpen());
  312. ASSERT(m_bOverlapped);
  313. ASSERT(overlapped.hEvent);
  314.  
  315. DWORD dwBytesRead = 0;
  316. BOOL bSuccess = ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, &overlapped);
  317. if (!bSuccess)
  318. {
  319. if (GetLastError() != ERROR_IO_PENDING)
  320. {
  321. TRACE(_T("Failed in call to ReadFile\n"));
  322. AfxThrowSerialException();
  323. }
  324. }
  325. return bSuccess;
  326. }
  327.  
  328. DWORD Serial_Port::Write(const void* lpBuf, DWORD dwCount)
  329. {
  330. ASSERT(IsOpen());
  331. ASSERT(!m_bOverlapped);
  332.  
  333. DWORD dwBytesWritten = 0;
  334. if (!WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, NULL))
  335. {
  336. TRACE(_T("Failed in call to WriteFile\n"));
  337. AfxThrowSerialException();
  338. }
  339.  
  340. return dwBytesWritten;
  341. }
  342.  
  343. BOOL Serial_Port::Write(const void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped)
  344. {
  345. ASSERT(IsOpen());
  346. ASSERT(m_bOverlapped);
  347. ASSERT(overlapped.hEvent);
  348.  
  349. DWORD dwBytesWritten = 0;
  350. BOOL bSuccess = WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, &overlapped);
  351. if (!bSuccess)
  352. {
  353. if (GetLastError() != ERROR_IO_PENDING)
  354. {
  355. TRACE(_T("Failed in call to WriteFile\n"));
  356. AfxThrowSerialException();
  357. }
  358. }
  359. return bSuccess;
  360. }
  361.  
  362. void Serial_Port::GetOverlappedResult(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait)
  363. {
  364. ASSERT(IsOpen());
  365. ASSERT(m_bOverlapped);
  366. ASSERT(overlapped.hEvent);
  367.  
  368. DWORD dwBytesWritten = 0;
  369. if (!::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait))
  370. {
  371. if (GetLastError() != ERROR_IO_PENDING)
  372. {
  373. TRACE(_T("Failed in call to GetOverlappedResult\n"));
  374. AfxThrowSerialException();
  375. }
  376. }
  377. }
  378.  
  379. void Serial_Port::_OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped)
  380. {
  381. //Validate our parameters
  382. ASSERT(lpOverlapped);
  383.  
  384. //Convert back to the C++ world
  385. Serial_Port* pSerialPort = (Serial_Port*) lpOverlapped->hEvent;
  386. ASSERT(pSerialPort->IsKindOf(RUNTIME_CLASS(Serial_Port)));
  387.  
  388. //Call the C++ function
  389. pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped);
  390. }
  391.  
  392. void Serial_Port::OnCompletion(DWORD /*dwErrorCode*/, DWORD /*dwCount*/, LPOVERLAPPED lpOverlapped)
  393. {
  394. //Just free up the memory which was previously allocated for the OVERLAPPED structure
  395. delete lpOverlapped;
  396.  
  397. //Your derived classes can do something useful in OnCompletion, but don't forget to
  398. //call Serial_Port::OnCompletion to ensure the memory is freed up
  399. }
  400.  
  401. void Serial_Port::CancelIo()
  402. {
  403. ASSERT(IsOpen());
  404.  
  405. if (_SerialPortData.m_lpfnCancelIo == NULL)
  406. {
  407. TRACE(_T("CancelIo function is not supported on this OS. You need to be running at least NT 4 or Win 98 to use this function\n"));
  408. AfxThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
  409. }
  410.  
  411. if (!::_SerialPortData.m_lpfnCancelIo(m_hComm))
  412. {
  413. TRACE(_T("Failed in call to CancelIO\n"));
  414. AfxThrowSerialException();
  415. }
  416. }
  417.  
  418. void Serial_Port::WriteEx(const void* lpBuf, DWORD dwCount)
  419. {
  420. ASSERT(IsOpen());
  421.  
  422. OVERLAPPED* pOverlapped = new OVERLAPPED;
  423. ZeroMemory(pOverlapped, sizeof(OVERLAPPED));
  424. pOverlapped->hEvent = (HANDLE) this;
  425. if (!WriteFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
  426. {
  427. delete pOverlapped;
  428. TRACE(_T("Failed in call to WriteFileEx\n"));
  429. AfxThrowSerialException();
  430. }
  431. }
  432.  
  433. void Serial_Port::ReadEx(void* lpBuf, DWORD dwCount)
  434. {
  435. ASSERT(IsOpen());
  436.  
  437. OVERLAPPED* pOverlapped = new OVERLAPPED;
  438. ZeroMemory(pOverlapped, sizeof(OVERLAPPED));
  439. pOverlapped->hEvent = (HANDLE) this;
  440. if (!ReadFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
  441. {
  442. delete pOverlapped;
  443. TRACE(_T("Failed in call to ReadFileEx\n"));
  444. AfxThrowSerialException();
  445. }
  446. }
  447.  
  448. void Serial_Port::TransmitChar(char cChar)
  449. {
  450. ASSERT(IsOpen());
  451.  
  452. if (!TransmitCommChar(m_hComm, cChar))
  453. {
  454. TRACE(_T("Failed in call to TransmitCommChar\n"));
  455. AfxThrowSerialException();
  456. }
  457. }
  458.  
  459. void Serial_Port::GetConfig(COMMCONFIG& config)
  460. {
  461. ASSERT(IsOpen());
  462.  
  463. DWORD dwSize = sizeof(COMMCONFIG);
  464. if (!GetCommConfig(m_hComm, &config, &dwSize))
  465. {
  466. TRACE(_T("Failed in call to GetCommConfig\n"));
  467. AfxThrowSerialException();
  468. }
  469. }
  470.  
  471. void Serial_Port::SetConfig(COMMCONFIG& config)
  472. {
  473. ASSERT(IsOpen());
  474.  
  475. DWORD dwSize = sizeof(COMMCONFIG);
  476. if (!SetCommConfig(m_hComm, &config, dwSize))
  477. {
  478. TRACE(_T("Failed in call to SetCommConfig\n"));
  479. AfxThrowSerialException();
  480. }
  481. }
  482.  
  483. void Serial_Port::SetBreak()
  484. {
  485. ASSERT(IsOpen());
  486.  
  487. if (!SetCommBreak(m_hComm))
  488. {
  489. TRACE(_T("Failed in call to SetCommBreak\n"));
  490. AfxThrowSerialException();
  491. }
  492. }
  493.  
  494. void Serial_Port::ClearBreak()
  495. {
  496. ASSERT(IsOpen());
  497.  
  498. if (!ClearCommBreak(m_hComm))
  499. {
  500. TRACE(_T("Failed in call to SetCommBreak\n"));
  501. AfxThrowSerialException();
  502. }
  503. }
  504.  
  505. void Serial_Port::ClearError(DWORD& dwErrors)
  506. {
  507. ASSERT(IsOpen());
  508.  
  509. if (!ClearCommError(m_hComm, &dwErrors, NULL))
  510. {
  511. TRACE(_T("Failed in call to ClearCommError\n"));
  512. AfxThrowSerialException();
  513. }
  514. }
  515.  
  516. void Serial_Port::GetDefaultConfig(int nPort, COMMCONFIG& config)
  517. {
  518. //Validate our parameters
  519. ASSERT(nPort>0 && nPort<=255);
  520.  
  521. //Create the device name as a string
  522. CString sPort;
  523. sPort.Format(_T("COM%d"), nPort);
  524.  
  525. DWORD dwSize = sizeof(COMMCONFIG);
  526. if (!GetDefaultCommConfig(sPort, &config, &dwSize))
  527. {
  528. TRACE(_T("Failed in call to GetDefaultCommConfig\n"));
  529. AfxThrowSerialException();
  530. }
  531. }
  532.  
  533. void Serial_Port::SetDefaultConfig(int nPort, COMMCONFIG& config)
  534. {
  535. //Validate our parameters
  536. ASSERT(nPort>0 && nPort<=255);
  537.  
  538. //Create the device name as a string
  539. CString sPort;
  540. sPort.Format(_T("COM%d"), nPort);
  541.  
  542. DWORD dwSize = sizeof(COMMCONFIG);
  543. if (!SetDefaultCommConfig(sPort, &config, dwSize))
  544. {
  545. TRACE(_T("Failed in call to GetDefaultCommConfig\n"));
  546. AfxThrowSerialException();
  547. }
  548. }
  549.  
  550. void Serial_Port::GetStatus(COMSTAT& stat)
  551. {
  552. ASSERT(IsOpen());
  553.  
  554. DWORD dwErrors;
  555. if (!ClearCommError(m_hComm, &dwErrors, &stat))
  556. {
  557. TRACE(_T("Failed in call to ClearCommError\n"));
  558. AfxThrowSerialException();
  559. }
  560. }
  561.  
  562. void Serial_Port::GetState(DCB& dcb)
  563. {
  564. ASSERT(IsOpen());
  565.  
  566. if (!GetCommState(m_hComm, &dcb))
  567. {
  568. TRACE(_T("Failed in call to GetCommState\n"));
  569. AfxThrowSerialException();
  570. }
  571. }
  572.  
  573. void Serial_Port::SetState(DCB& dcb)
  574. {
  575. ASSERT(IsOpen());
  576.  
  577. if (!SetCommState(m_hComm, &dcb))
  578. {
  579. TRACE(_T("Failed in call to SetCommState\n"));
  580. AfxThrowSerialException();
  581. }
  582. }
  583.  
  584. void Serial_Port::Escape(DWORD dwFunc)
  585. {
  586. ASSERT(IsOpen());
  587.  
  588. if (!EscapeCommFunction(m_hComm, dwFunc))
  589. {
  590. TRACE(_T("Failed in call to EscapeCommFunction\n"));
  591. AfxThrowSerialException();
  592. }
  593. }
  594.  
  595. void Serial_Port::ClearDTR()
  596. {
  597. Escape(CLRDTR);
  598. }
  599.  
  600. void Serial_Port::ClearRTS()
  601. {
  602. Escape(CLRRTS);
  603. }
  604.  
  605. void Serial_Port::SetDTR()
  606. {
  607. Escape(SETDTR);
  608. }
  609.  
  610. void Serial_Port::SetRTS()
  611. {
  612. Escape(SETRTS);
  613. }
  614.  
  615. void Serial_Port::SetXOFF()
  616. {
  617. Escape(SETXOFF);
  618. }
  619.  
  620. void Serial_Port::SetXON()
  621. {
  622. Escape(SETXON);
  623. }
  624.  
  625. void Serial_Port::GetProperties(COMMPROP& properties)
  626. {
  627. ASSERT(IsOpen());
  628.  
  629. if (!GetCommProperties(m_hComm, &properties))
  630. {
  631. TRACE(_T("Failed in call to GetCommProperties\n"));
  632. AfxThrowSerialException();
  633. }
  634. }
  635.  
  636. void Serial_Port::GetModemStatus(DWORD& dwModemStatus)
  637. {
  638. ASSERT(IsOpen());
  639.  
  640. if (!GetCommModemStatus(m_hComm, &dwModemStatus))
  641. {
  642. TRACE(_T("Failed in call to GetCommModemStatus\n"));
  643. AfxThrowSerialException();
  644. }
  645. }
  646.  
  647. void Serial_Port::SetMask(DWORD dwMask)
  648. {
  649. ASSERT(IsOpen());
  650.  
  651. if (!SetCommMask(m_hComm, dwMask))
  652. {
  653. TRACE(_T("Failed in call to SetCommMask\n"));
  654. AfxThrowSerialException();
  655. }
  656. }
  657.  
  658. void Serial_Port::GetMask(DWORD& dwMask)
  659. {
  660. ASSERT(IsOpen());
  661.  
  662. if (!GetCommMask(m_hComm, &dwMask))
  663. {
  664. TRACE(_T("Failed in call to GetCommMask\n"));
  665. AfxThrowSerialException();
  666. }
  667. }
  668.  
  669. void Serial_Port::Flush()
  670. {
  671. ASSERT(IsOpen());
  672.  
  673. if (!FlushFileBuffers(m_hComm))
  674. {
  675. TRACE(_T("Failed in call to FlushFileBuffers\n"));
  676. AfxThrowSerialException();
  677. }
  678. }
  679.  
  680. void Serial_Port::Purge(DWORD dwFlags)
  681. {
  682. ASSERT(IsOpen());
  683.  
  684. if (!PurgeComm(m_hComm, dwFlags))
  685. {
  686. TRACE(_T("Failed in call to PurgeComm\n"));
  687. AfxThrowSerialException();
  688. }
  689. }
  690.  
  691. void Serial_Port::TerminateOutstandingWrites()
  692. {
  693. Purge(PURGE_TXABORT);
  694. }
  695.  
  696. void Serial_Port::TerminateOutstandingReads()
  697. {
  698. Purge(PURGE_RXABORT);
  699. }
  700.  
  701. void Serial_Port::ClearWriteBuffer()
  702. {
  703. Purge(PURGE_TXCLEAR);
  704. }
  705.  
  706. void Serial_Port::ClearReadBuffer()
  707. {
  708. Purge(PURGE_RXCLEAR);
  709. }
  710.  
  711. void Serial_Port::Setup(DWORD dwInQueue, DWORD dwOutQueue)
  712. {
  713. ASSERT(IsOpen());
  714.  
  715. if (!SetupComm(m_hComm, dwInQueue, dwOutQueue))
  716. {
  717. TRACE(_T("Failed in call to SetupComm\n"));
  718. AfxThrowSerialException();
  719. }
  720. }
  721.  
  722. void Serial_Port::SetTimeouts(COMMTIMEOUTS& timeouts)
  723. {
  724. ASSERT(IsOpen());
  725.  
  726. if (!SetCommTimeouts(m_hComm, &timeouts))
  727. {
  728. TRACE(_T("Failed in call to SetCommTimeouts\n"));
  729. AfxThrowSerialException();
  730. }
  731. }
  732.  
  733. void Serial_Port::GetTimeouts(COMMTIMEOUTS& timeouts)
  734. {
  735. ASSERT(IsOpen());
  736.  
  737. if (!GetCommTimeouts(m_hComm, &timeouts))
  738. {
  739. TRACE(_T("Failed in call to GetCommTimeouts\n"));
  740. AfxThrowSerialException();
  741. }
  742. }
  743.  
  744. void Serial_Port::Set0Timeout()
  745. {
  746. COMMTIMEOUTS Timeouts;
  747. ZeroMemory(&Timeouts, sizeof(COMMTIMEOUTS));
  748. Timeouts.ReadIntervalTimeout = MAXDWORD;
  749. Timeouts.ReadTotalTimeoutMultiplier = 0;
  750. Timeouts.ReadTotalTimeoutConstant = 0;
  751. Timeouts.WriteTotalTimeoutMultiplier = 0;
  752. Timeouts.WriteTotalTimeoutConstant = 0;
  753. SetTimeouts(Timeouts);
  754. }
  755.  
  756. void Serial_Port::Set0WriteTimeout()
  757. {
  758. COMMTIMEOUTS Timeouts;
  759. GetTimeouts(Timeouts);
  760. Timeouts.WriteTotalTimeoutMultiplier = 0;
  761. Timeouts.WriteTotalTimeoutConstant = 0;
  762. SetTimeouts(Timeouts);
  763. }
  764.  
  765. void Serial_Port::Set0ReadTimeout()
  766. {
  767. COMMTIMEOUTS Timeouts;
  768. GetTimeouts(Timeouts);
  769. Timeouts.ReadIntervalTimeout = MAXDWORD;
  770. Timeouts.ReadTotalTimeoutMultiplier = 0;
  771. Timeouts.ReadTotalTimeoutConstant = 0;
  772. SetTimeouts(Timeouts);
  773. }
  774.  
  775. void Serial_Port::WaitEvent(DWORD& dwMask)
  776. {
  777. ASSERT(IsOpen());
  778. ASSERT(!m_bOverlapped);
  779.  
  780. if (!WaitCommEvent(m_hComm, &dwMask, NULL))
  781. {
  782. TRACE(_T("Failed in call to WaitCommEvent\n"));
  783. AfxThrowSerialException();
  784. }
  785. }
  786.  
  787. void Serial_Port::WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped)
  788. {
  789. ASSERT(IsOpen());
  790. ASSERT(m_bOverlapped);
  791. ASSERT(overlapped.hEvent);
  792.  
  793. if (!WaitCommEvent(m_hComm, &dwMask, &overlapped))
  794. {
  795. if (GetLastError() != ERROR_IO_PENDING)
  796. {
  797. TRACE(_T("Failed in call to WaitCommEvent\n"));
  798. AfxThrowSerialException();
  799. }
  800. }
  801. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement