CommPort.cpp
上传用户:glass0516
上传日期:2010-01-11
资源大小:104k
文件大小:21k
源码类别:

传真(Fax)编程

开发平台:

Visual C++

  1. /*****************************************************************************
  2. * RelayFax Open Source Project
  3. * Copyright 1996-2004 Alt-N Technologies, Ltd.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted only as authorized by the RelayFax Open 
  8. * Source License.  A copy of this license is available in file LICENSE 
  9. * in the top-level directory of the distribution.
  10. *
  11. * RelayFax is a registered trademark of Alt-N Technologies, Ltd.
  12. *
  13. * Individual files and/or contributed packages may be copyright by
  14. * other parties and subject to additional restrictions.
  15. *****************************************************************************/
  16. ////////////////////////////////////////////////////////////////////////////////
  17. //
  18. // The purpose of CCommPort is to encapsulate all the Win32 communication API
  19. //
  20. ////////////////////////////////////////////////////////////////////////////////
  21. #include "stdafx.h"
  22. #include "CommPort.h"
  23. CLS1SPEEDS cls1Speeds[MAX_CLS1SPEEDS] = 
  24. 0x00, 24, 24, 2400, 0, // 2400, v.27 ter
  25. 0x04, 48, 48, 4800, 1, // 4800, v.27
  26. 0x0c, 72, 72, 7200, 2, // 7200, v.29
  27. 0x08, 96, 96, 9600, 3, // 9600, v.29
  28. 0x06, 121, 121, 12000, 4, // 12000, V.33
  29. 0x02, 145, 145, 14400, 5, // 14400, V.33
  30. 0x0d, 73, 74, 7200, 2, // 7200, v.17
  31. 0x09, 97, 98, 9600, 3, // 9600, v.17
  32. 0x05, 121, 122, 12000, 4, // 12000, v.17
  33. 0x01, 145, 146, 14400, 5, // 14400, v.17  
  34. };
  35. WORD Cls1ScanTimes_normal[8] = {20,40,10,5,10,20,40,0};
  36. WORD Cls1ScanTimes_fine[8] =   {20,40,10,5,5,10,20,0};
  37. WORD Cls2ScanTimes_normal[8] = { 0, 5, 10, 10, 20, 20, 40, 40 };
  38. WORD Cls2ScanTimes_fine[8] = { 0, 5, 5, 10, 10, 20, 20, 40 };
  39. WORD  Cls2FaxParamBitRates[6] = { 2400, 4800, 7200, 9600, 12000, 14400 };
  40. char CCommPort::s_HexDigits[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  41. //////////////////////////////////////////////////////////////////////
  42. // Construction/Destruction
  43. //////////////////////////////////////////////////////////////////////
  44. CCommPort::CCommPort()
  45. {
  46. m_hPort = NULL;
  47. m_bDSRFlowControl = true;
  48. m_bCTSFlowControl = true;
  49. m_bSoftFlowControl = true;
  50. m_BaudRate = CBR_19200;
  51. m_ByteSize = 8;
  52. m_Parity = NOPARITY;
  53. m_StopBits = ONESTOPBIT;
  54. ZeroMemory( &m_ReadOverlapped, sizeof(m_ReadOverlapped) );
  55. ZeroMemory( &m_WriteOverlapped, sizeof(m_WriteOverlapped) );
  56. ZeroMemory( &m_CommEventOverlapped, sizeof(m_CommEventOverlapped) );
  57. m_ReadOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  58. m_WriteOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  59. m_CommEventOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  60. InitLineParser();
  61. m_bWriteInProgress = false;
  62. memset( &m_dcb, 0, sizeof(m_dcb) );
  63. m_dcb.DCBlength = sizeof(m_dcb); 
  64. m_bDebugLog = false;
  65. m_pLogFile = NULL;
  66. }
  67. CCommPort::~CCommPort()
  68. {
  69. CloseHandle( m_ReadOverlapped.hEvent );
  70. CloseHandle( m_WriteOverlapped.hEvent );
  71. CloseHandle( m_CommEventOverlapped.hEvent );
  72. }
  73. //////////////////////////////////////////////////////////////////////
  74. // ConnectPort
  75. //////////////////////////////////////////////////////////////////////
  76. bool CCommPort::ConnectPort( string& sErr )
  77. {
  78. char szComDevice[16];
  79. wsprintf( szComDevice, "\\.\%s",  m_sPort.c_str() );
  80. m_hPort = CreateFile( szComDevice, GENERIC_READ | GENERIC_WRITE, 0, NULL, 
  81.   OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL );
  82. // see if this works before committing
  83. if( m_hPort == NULL || m_hPort == INVALID_HANDLE_VALUE )
  84. {
  85. if( GetLastError() == ERROR_ACCESS_DENIED )
  86. {
  87. // wait a second and try again
  88. Sleep( 1000 );
  89. m_hPort = CreateFile( szComDevice, GENERIC_READ | GENERIC_WRITE, 0, NULL, 
  90.   OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL );
  91. }
  92. }
  93. if( m_hPort != NULL && m_hPort != INVALID_HANDLE_VALUE )
  94. {
  95. PurgeComm( m_hPort, PURGE_RXCLEAR | PURGE_TXCLEAR );
  96. if( !GetCommState( m_hPort, &m_dcb ) )
  97. {
  98. sErr.assign( "Error in GetCommState" );
  99. CloseHandle( m_hPort );
  100. return false;
  101. }
  102. if( !SetupComm( m_hPort, 20000, 20000 ) )
  103. {
  104. sErr.assign( "Error in SetupComm" );
  105. CloseHandle( m_hPort );
  106. return false;
  107. }
  108. m_dcb.BaudRate = m_BaudRate;
  109. m_dcb.ByteSize=  m_ByteSize;
  110. m_dcb.fBinary = TRUE;
  111. m_dcb.Parity = m_Parity;
  112. m_dcb.StopBits = m_StopBits;
  113. m_dcb.fOutxCtsFlow = (m_bCTSFlowControl) ? TRUE : FALSE;
  114. m_dcb.fOutxDsrFlow = (m_bDSRFlowControl) ? TRUE : FALSE;
  115. m_dcb.fOutX = (m_bSoftFlowControl) ? 1 : 0;
  116. m_dcb.fInX = 0; // we shouldn't need flow control for receiving data
  117.                 // since we are using 20k buffers
  118. m_dcb.XonChar = XON;
  119. m_dcb.XoffChar = XOFF;
  120. // One of these two was causing a problem with Multitech ISI5634/8 multi-port modem card
  121. // m_dcb.fTXContinueOnXoff = TRUE;
  122. m_dcb.fRtsControl = RTS_CONTROL_ENABLE;
  123. m_dcb.fDtrControl = DTR_CONTROL_ENABLE;
  124. m_dcb.fAbortOnError = FALSE; // Make sure this is reset otherwise any 
  125.                              //line errors will cause io to terminate
  126. m_dcb.fErrorChar = FALSE;
  127. m_dcb.fParity = FALSE;
  128. // m_dcb.fDsrSensitivity = TRUE;
  129. m_dcb.fNull = FALSE;
  130. if ( !SetCommState( m_hPort, &m_dcb) ) 
  131. {
  132. sErr.assign( "Error in SetCommState" );
  133. CloseHandle( m_hPort );
  134. return false;
  135. }
  136. COMMTIMEOUTS cto;
  137. //cto.ReadIntervalTimeout = 10;
  138. //cto.ReadIntervalTimeout = (m_BaudRate / 10)
  139. cto.ReadIntervalTimeout = 2;
  140. cto.ReadTotalTimeoutMultiplier = 0;
  141. cto.ReadTotalTimeoutConstant = 0;
  142. cto.WriteTotalTimeoutMultiplier = 5;
  143. cto.WriteTotalTimeoutConstant = 5000;
  144. if( !SetCommTimeouts( m_hPort, &cto ) )
  145. {
  146. sErr.assign( "Error in SetCommTimeouts" );
  147. CloseHandle( m_hPort );
  148. return false;
  149. }
  150. COMSTAT cs = {0};
  151. DWORD dwErrs = 0;
  152. if( !ClearCommError( m_hPort, &dwErrs, &cs ) )
  153. {
  154. sErr.assign( "Error in ClearCommError" );
  155. CloseHandle( m_hPort );
  156. return false;
  157. }
  158. //DWORD dwMask = EV_CTS | EV_ERR | EV_DSR | EV_RLSD | EV_BREAK | EV_RING;
  159. DWORD dwMask = EV_ERR;
  160. if (!SetCommMask(m_hPort, dwMask))
  161. {
  162. sErr.assign( "Error in SetCommMask!" );
  163. CloseHandle( m_hPort );
  164. return false;
  165. }
  166. OpenDebugLog();
  167. DoWaitCommEventLoop();
  168. DoReadLoop();
  169. OnConnect(); //-- moved to OnWaitTimeout to let the read buffer flush
  170. return true;
  171. }
  172. else
  173. {
  174. // could not open port
  175. char szError[256];
  176. szError[0] = '';
  177. GetLastErrorText( szError, 255 );
  178. sErr.assign( szError );
  179. }
  180. return false;
  181. }
  182. //////////////////////////////////////////////////////////////////////
  183. // DisconnectPort
  184. //////////////////////////////////////////////////////////////////////
  185. void CCommPort::DisconnectPort( void )
  186. {
  187. PurgeComm( m_hPort, PURGE_RXABORT | PURGE_RXCLEAR | 
  188.                 PURGE_TXABORT | PURGE_TXCLEAR );
  189. CloseHandle( m_hPort );
  190. m_hPort = NULL;
  191. CloseDebugLog();
  192. }
  193. //////////////////////////////////////////////////////////////////////
  194. // DoRead
  195. //////////////////////////////////////////////////////////////////////
  196. bool CCommPort::DoRead( void )
  197. {
  198. BOOL bRet;
  199. m_BytesRead = 0;
  200. bRet = ReadFile( m_hPort, m_szReadBuff, READBUF_SIZE, &m_BytesRead, &m_ReadOverlapped );
  201. if( bRet )
  202. {
  203. return true;
  204. }
  205. else
  206. {
  207. DWORD  dwLastError = GetLastError();
  208. // LastError was ERROR_IO_PENDING, as expected.
  209. if (dwLastError != ERROR_IO_PENDING)
  210. {
  211. OutputDebugString("Unexpected error.n");
  212. }
  213. // Its possible for this error to occur if the 
  214. // service provider has closed the port.  Time to end.
  215. if (dwLastError == ERROR_INVALID_HANDLE)
  216. {
  217. OutputDebugString( "Likely that the Service Provider has closed the port.n");
  218. }
  219. return false;
  220. }
  221. }
  222. void CCommPort::FillWriteQueue( char* szChars, unsigned long nBytes, bool bCrLf )
  223. {
  224. bool bAddedCrLf = false;
  225. while( nBytes > 0 )
  226. {
  227. int nbuflen = MAX_WRITE;
  228. if( nbuflen > nBytes ) 
  229. {
  230. nbuflen = nBytes;
  231. }
  232. CWriteBuffer *buf = new CWriteBuffer;
  233. memcpy( buf->Buffer, szChars, nbuflen );
  234. buf->Bytes = nbuflen;
  235. if( bCrLf && (nbuflen < MAX_WRITE) )
  236. {
  237. // must be last one
  238. buf->Buffer[buf->Bytes++] = 'r';
  239. bAddedCrLf = true;
  240. }
  241. m_WriteQueue.push_back( buf );
  242. szChars += nbuflen;
  243. nBytes -= nbuflen;
  244. }
  245. if( bCrLf && !bAddedCrLf)
  246. {
  247. CWriteBuffer *buf = new CWriteBuffer;
  248. buf->Buffer[0] = 'r';
  249. buf->Bytes = 1;
  250. m_WriteQueue.push_back( buf );
  251. }
  252. }
  253. bool CCommPort::WritePacket( char* szChars, unsigned long nBytes )
  254. {
  255. m_WriteOverlapped.Offset = 0;
  256. m_WriteOverlapped.OffsetHigh = 0;
  257. if( WriteFile( m_hPort, szChars, nBytes, 
  258. &m_BytesWritten, &m_WriteOverlapped ) )
  259. {
  260. //char szMsg[80];
  261. //wsprintf( szMsg, "Wrote %d bytes 2n", m_BytesWritten );
  262. //OutputDebugString( szMsg );
  263. ResetEvent( m_WriteOverlapped.hEvent );
  264. OnWrite();
  265. if( m_bDebugLog )
  266. {
  267. WriteDebugLog( false );
  268. }
  269. }
  270. else
  271. {
  272. //char szMsg[80];
  273. //wsprintf( szMsg, "Queued up %d bytesn", nBytes );
  274. //OutputDebugString( szMsg );
  275. m_bWriteInProgress = true;
  276. DWORD  dwLastError = GetLastError();
  277. // LastError was ERROR_IO_PENDING, as expected.
  278. if (dwLastError != ERROR_IO_PENDING)
  279. {
  280. OutputDebugString("Unexpected error.n");
  281. }
  282. // Its possible for this error to occur if the 
  283. // service provider has closed the port.  Time to end.
  284. if (dwLastError == ERROR_INVALID_HANDLE)
  285. {
  286. OutputDebugString( "Likely that the Service Provider has closed the port.n");
  287. }
  288. return false;
  289. }
  290. return true;
  291. }
  292. //////////////////////////////////////////////////////////////////////
  293. // DoWrite
  294. //////////////////////////////////////////////////////////////////////
  295. bool CCommPort::DoWrite( char* szChars, unsigned long nBytes, bool bCrLf )
  296. {
  297. if( m_bWriteInProgress )
  298. {
  299. FillWriteQueue( szChars, nBytes, bCrLf );
  300. }
  301. else
  302. {
  303. if( nBytes > MAX_WRITE )
  304. {
  305. FillWriteQueue( szChars, nBytes, bCrLf );
  306. DoWriteLoop();
  307. }
  308. else
  309. {
  310. memcpy( m_szWriteBuff, szChars, nBytes );
  311. if( bCrLf )
  312. {
  313. m_szWriteBuff[nBytes++] = 'r';
  314. //m_szWriteBuff[nBytes++] = 'n';
  315. }
  316. if( WritePacket( m_szWriteBuff, nBytes ) )
  317. {
  318. //char szMsg[80];
  319. //wsprintf( szMsg, "Sent %d bytes 3n", nBytes  );
  320. //OutputDebugString( szMsg );
  321. }
  322. }
  323. }
  324. return true;
  325. }
  326. //////////////////////////////////////////////////////////////////////
  327. // DoRead
  328. //////////////////////////////////////////////////////////////////////
  329. bool CCommPort::DoWaitCommEvent( void )
  330. {
  331. BOOL bRet;
  332. m_BytesRead = 0;
  333. bRet = WaitCommEvent( m_hPort, &m_CommEvent, &m_CommEventOverlapped );
  334. if( bRet )
  335. {
  336. return true;
  337. }
  338. else
  339. {
  340. DWORD  dwLastError = GetLastError();
  341. // LastError was ERROR_IO_PENDING, as expected.
  342. if (dwLastError != ERROR_IO_PENDING)
  343. {
  344. OutputDebugString("Unexpected error.n");
  345. }
  346. // Its possible for this error to occur if the 
  347. // service provider has closed the port.  Time to end.
  348. if (dwLastError == ERROR_INVALID_HANDLE)
  349. {
  350. OutputDebugString( "Likely that the Service Provider has closed the port.n");
  351. }
  352. return false;
  353. }
  354. }
  355. //////////////////////////////////////////////////////////////////////
  356. // DoReadLoop
  357. //////////////////////////////////////////////////////////////////////
  358. void CCommPort::DoReadLoop( void )
  359. {
  360. int i;
  361. for( i = 0; i < 100; i++ )
  362. {
  363. if( m_hPort == NULL )
  364. break;
  365. if( DoRead() ) 
  366. {
  367. m_szReadBuff[m_BytesRead] = '';
  368. if( m_bDebugLog )
  369. {
  370. WriteDebugLog( true );
  371. }
  372. OnRead();
  373. }
  374. else
  375. {
  376. break;
  377. }
  378. }
  379. if( i == 100 )
  380. {
  381. OutputDebugString("DoRead loop executed 100 times.n");
  382. }
  383. }
  384. //////////////////////////////////////////////////////////////////////
  385. // DoWaitCommEventLoop
  386. //////////////////////////////////////////////////////////////////////
  387. void CCommPort::DoWaitCommEventLoop( void )
  388. {
  389. int i;
  390. for( i = 0; i < 100; i++ )
  391. {
  392. if( m_hPort == NULL )
  393. break;
  394. if( DoWaitCommEvent() )
  395. {
  396. OnCommEvent();
  397. }
  398. else
  399. {
  400. break;
  401. }
  402. }
  403. if( i == 100 )
  404. {
  405. OutputDebugString("WaitCommEvent loop executed 100 times.n");
  406. }
  407. }
  408. //////////////////////////////////////////////////////////////////////
  409. // DoWriteLoop
  410. //////////////////////////////////////////////////////////////////////
  411. void CCommPort::DoWriteLoop( void )
  412. {
  413. // char szMsg[80];
  414. int i;
  415. int nBytesToWrite;
  416. for( i = 0; i < 100; i++ )
  417. {
  418. if( m_hPort == NULL )
  419. break;
  420. if( m_WriteQueue.size() > 0 )
  421. {
  422. //wsprintf( szMsg, "DoWriteLoop(%d)n", i );
  423. //OutputDebugString( szMsg );
  424. deque<CWriteBuffer*>::iterator iter;
  425. iter = m_WriteQueue.begin();
  426. // CWriteBuffer* p = (*iter);
  427. m_WriteQueue.pop_front();
  428. memcpy( m_szWriteBuff, (*iter)->Buffer, (*iter)->Bytes );
  429.  
  430. nBytesToWrite = (*iter)->Bytes;
  431. delete (*iter);
  432. if( WritePacket( m_szWriteBuff, nBytesToWrite ) )
  433. {
  434. //wsprintf( szMsg, "Sent %d bytes 2n", (*iter)->Bytes  );
  435. //OutputDebugString( szMsg );
  436. }
  437. else
  438. {
  439. break;
  440. }
  441. if( i == 100 )
  442. {
  443. OutputDebugString("WriteEvent loop executed 100 times.n");
  444. }
  445. }
  446. else
  447. {
  448. break;
  449. }
  450. }
  451. }
  452. //////////////////////////////////////////////////////////////////////
  453. // ReadEventSignalled
  454. //////////////////////////////////////////////////////////////////////
  455. void CCommPort::ReadEventSignalled(void)
  456. {
  457. BOOL bRet;
  458. if( m_hPort == NULL )
  459. return;
  460. bRet = GetOverlappedResult( m_hPort, &m_ReadOverlapped, &m_BytesRead, FALSE );
  461. ResetEvent( m_ReadOverlapped.hEvent );
  462. if( bRet )
  463. {
  464. if(  m_BytesRead > 0 )
  465. {
  466. m_szReadBuff[m_BytesRead] = '';
  467. if( m_bDebugLog )
  468. {
  469. WriteDebugLog( true );
  470. }
  471. OnRead();
  472. }
  473. DoReadLoop();
  474. }
  475. else
  476. {
  477. DWORD dwLastError = GetLastError();
  478. // Its possible for this error to occur if the 
  479. // service provider has closed the port.  Time to end.
  480. if (dwLastError == ERROR_INVALID_HANDLE)
  481. {
  482. OutputDebugString("Likely that the Service Provider has closed the port.n");
  483. }
  484. OutputDebugString( "Unexpected GetOverlappedResult Read Error: " );
  485. }
  486. }
  487. //////////////////////////////////////////////////////////////////////
  488. // WaitCommEventSignalled
  489. //////////////////////////////////////////////////////////////////////
  490. void CCommPort::WaitCommEventSignalled(void)
  491. {
  492. BOOL bRet;
  493. DWORD dwBytes = 0;
  494. if( m_hPort == NULL )
  495. return;
  496. bRet = GetOverlappedResult( m_hPort, &m_CommEventOverlapped, &dwBytes, FALSE );
  497. ResetEvent( m_CommEventOverlapped.hEvent );
  498. if( bRet )
  499. {
  500. OnCommEvent();
  501. DoWaitCommEventLoop();
  502. }
  503. else
  504. {
  505. DWORD dwLastError = GetLastError();
  506. // Its possible for this error to occur if the 
  507. // service provider has closed the port.  Time to end.
  508. if (dwLastError == ERROR_INVALID_HANDLE)
  509. {
  510. OutputDebugString("Likely that the Service Provider has closed the port.n");
  511. }
  512. OutputDebugString( "Unexpected GetOverlappedResult Read Error: ");
  513. }
  514. }
  515. //////////////////////////////////////////////////////////////////////
  516. // OnWriteEvent
  517. //////////////////////////////////////////////////////////////////////
  518. void CCommPort::WriteEventSignalled(void)
  519. {
  520. BOOL bRet;
  521. if( m_hPort == NULL )
  522. return;
  523. bRet = GetOverlappedResult( m_hPort, &m_WriteOverlapped, &m_BytesWritten, FALSE );
  524. ResetEvent( m_WriteOverlapped.hEvent );
  525. if( bRet )
  526. {
  527. //DWORD dwErrs = 0;
  528. //COMSTAT stat;
  529. //ClearCommError( m_hPort, &dwErrs, &stat );
  530. //char szMsg[80];
  531. //wsprintf( szMsg, "Wrote %d bytes,n", m_BytesWritten);
  532. //OutputDebugString( szMsg );
  533. m_bWriteInProgress = false;
  534. OnWrite();
  535. if( m_bDebugLog )
  536. {
  537. WriteDebugLog( false );
  538. }
  539. DoWriteLoop();
  540. }
  541. else
  542. {
  543. DWORD dwLastError = GetLastError();
  544. // Its possible for this error to occur if the 
  545. // service provider has closed the port.  Time to end.
  546. if (dwLastError == ERROR_INVALID_HANDLE)
  547. {
  548. OutputDebugString("Likely that the Service Provider has closed the port.n");
  549. }
  550. OutputDebugString( "Unexpected GetOverlappedResult Read Error: " );
  551. }
  552. }
  553. //////////////////////////////////////////////////////////////////////
  554. // OnCommEvent
  555. //////////////////////////////////////////////////////////////////////
  556. void CCommPort::OnCommEvent(void)
  557. {
  558. if( m_CommEvent & EV_CTS )
  559. {
  560. OutputDebugString( "CCommPort::OnCommEvent: CTS changed staten" );
  561. }
  562. if( m_CommEvent & EV_ERR )
  563. {
  564. OutputDebugString( "CCommPort::OnCommEvent: Errorn" );
  565. }
  566. if( m_CommEvent & EV_DSR )
  567. {
  568. OutputDebugString( "CCommPort::OnCommEvent: DSR changed staten" );
  569. }
  570. if( m_CommEvent & EV_RLSD )
  571. {
  572. OutputDebugString( "CCommPort::OnCommEvent: RLSD changed staten" );
  573. }
  574. if( m_CommEvent & EV_BREAK )
  575. {
  576. OutputDebugString( "CCommPort::OnCommEvent: Break detectedn" );
  577. }
  578. }
  579. //////////////////////////////////////////////////////////////////////
  580. // OnConnect
  581. //////////////////////////////////////////////////////////////////////
  582. void CCommPort::OnConnect(void)
  583. {
  584. // OutputDebugString( "CCommPort::OnConnectn" );
  585. }
  586. //////////////////////////////////////////////////////////////////////
  587. // OnDisconnect - return true if no command sent
  588. //////////////////////////////////////////////////////////////////////
  589. bool CCommPort::OnDisconnect(void)
  590. {
  591. // OutputDebugString( "CCommPort::OnDisconnectn" );
  592. return true;
  593. }
  594. //////////////////////////////////////////////////////////////////////
  595. // OnRead
  596. //////////////////////////////////////////////////////////////////////
  597. void CCommPort::OnRead(void)
  598. {
  599. // OutputDebugString( "CCommPort::OnReadn" );
  600. }
  601. //////////////////////////////////////////////////////////////////////
  602. // OnReadLine
  603. //////////////////////////////////////////////////////////////////////
  604. void CCommPort::OnReadLine(void)
  605. {
  606. // OutputDebugString( "CModem::OnReadLinen" );
  607. }
  608. //////////////////////////////////////////////////////////////////////
  609. // OnWrite
  610. //////////////////////////////////////////////////////////////////////
  611. void CCommPort::OnWrite(void)
  612. {
  613. // OutputDebugString( "CCommPort::OnWriten" );
  614. }
  615. //////////////////////////////////////////////////////////////////////
  616. // SetCommParam
  617. //////////////////////////////////////////////////////////////////////
  618. void CCommPort::SetCommParam( DWORD BaudRate, BYTE ByteSize, BYTE Parity, BYTE StopBits )
  619. {
  620. m_BaudRate = BaudRate;
  621. m_ByteSize = ByteSize;
  622. m_Parity = Parity;
  623. m_StopBits = StopBits;
  624. }
  625. //////////////////////////////////////////////////////////////////////
  626. // SetFlowControl
  627. //////////////////////////////////////////////////////////////////////
  628. void CCommPort::SetFlowControl( bool bDSRFlowControl, bool bCTSFlowControl, bool bSoftFlowControl )
  629. {
  630. m_bDSRFlowControl = bDSRFlowControl;
  631. m_bCTSFlowControl = bCTSFlowControl;
  632. m_bSoftFlowControl = bSoftFlowControl;
  633. }
  634. //////////////////////////////////////////////////////////////////////
  635. // ParseIntoLines
  636. //////////////////////////////////////////////////////////////////////
  637. void CCommPort::ParseIntoLines(void)
  638. {
  639. DWORD i;
  640. for( i = 0; i < m_BytesRead; i++ )
  641. {
  642. if( m_bEolFlag )
  643. {
  644. if( (m_szReadBuff[i] != 'r') && (m_szReadBuff[i] != 'n') )
  645. {
  646. m_bEolFlag = false;
  647. }
  648. }
  649. if( !m_bEolFlag )
  650. {
  651. if( (m_szReadBuff[i] == 'r') || (m_szReadBuff[i] == 'n') )
  652. {
  653. m_bEolFlag = true;
  654. if( m_nLineBuffPtr > 0 )
  655. {
  656. m_szLineBuff[m_nLineBuffPtr] = '';
  657. OnReadLine();
  658. InitLineParser();
  659. }
  660. }
  661. else
  662. {
  663. if( m_nLineBuffPtr >= READBUF_SIZE )
  664. {
  665. OutputDebugString( "Line buffer overflow!n" );
  666. InitLineParser();
  667. }
  668. m_szLineBuff[m_nLineBuffPtr++] = m_szReadBuff[i];
  669. }
  670. }
  671. }
  672. }
  673. void CCommPort::EnableSoftFlowControl( bool bEnable )
  674. {
  675. if( m_bSoftFlowControl )
  676. {
  677. m_dcb.fOutX = (bEnable) ? 1 : 0;
  678. if( !SetCommState( m_hPort, &m_dcb) )
  679. {
  680. OutputDebugString( "Error in SetCommState!n" );
  681. }
  682. if( bEnable )
  683. {
  684. EscapeCommFunction( m_hPort, SETXON );
  685. }
  686. if ( bEnable )
  687. {
  688. //OutputDebugString( "Enabling software flow controln" );
  689. }
  690. else
  691. {
  692. //OutputDebugString( "Disabling software flow controln" );
  693. }
  694. }
  695. }
  696. void CCommPort::OpenDebugLog(void)
  697. {
  698. char szLogFile[MAX_PATH];
  699. if( !m_bDebugLog ) 
  700. {
  701. return;
  702. }
  703. wsprintf( szLogFile, "%sM_%s.LOG", m_sLogDir.c_str(), m_sPort.c_str() );
  704. m_pLogFile = fopen( szLogFile, "a" );
  705. }
  706. void CCommPort::WriteDebugLog( bool bRead )
  707. {
  708. DWORD dwTicks = GetTickCount();
  709. char szMsg[80];
  710. int nBytes;
  711. char* pData;
  712. int i;
  713. wsprintf( szMsg, "%11d%c", dwTicks, (bRead) ? '<' : '>' );
  714. memset( szMsg+12, ' ', sizeof(szMsg) - 12 );
  715. szMsg[78] = 'n';
  716. szMsg[79] = '';
  717. if( m_pLogFile )
  718. {
  719. if( bRead )
  720. {
  721. pData = m_szReadBuff;
  722. nBytes = m_BytesRead;
  723. }
  724. else
  725. {
  726. pData = m_szWriteBuff;
  727. nBytes = m_BytesWritten;
  728. }
  729. while( nBytes > 0 )
  730. {
  731. for( i = 0; i < 16; i++ )
  732. {
  733. if( i < nBytes )
  734. {
  735. szMsg[13+(i*3)] = s_HexDigits[(*pData & 0xf0) >> 4];
  736. szMsg[14+(i*3)] = s_HexDigits[(*pData & 0x0f)];
  737. szMsg[62+i] =  ( (*pData < 127) && (*pData > 31) ) ? *pData : '.';
  738. pData++;
  739. }
  740. else
  741. {
  742. szMsg[13+(i*3)] = ' ';
  743. szMsg[14+(i*3)] = ' ';
  744. szMsg[62+i] =  ' ';
  745. }
  746. }
  747. fputs( szMsg, m_pLogFile );
  748. nBytes -= 16;
  749. }
  750. }
  751. }
  752. void CCommPort::CloseDebugLog(void)
  753. {
  754. if( !m_bDebugLog )
  755. {
  756. return;
  757. }
  758. if( m_pLogFile )
  759. {
  760. fclose( m_pLogFile );
  761. m_pLogFile = NULL;
  762. m_bDebugLog = false;
  763. }
  764. }