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

传真(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 CClassTwo is contain the protocol specifics of EIA
  19. // fax modem class 2
  20. //
  21. ////////////////////////////////////////////////////////////////////////////////
  22. #include "stdafx.h"
  23. #include "ClassTwo.h"
  24. #define CLASSTWO_CONNECT "+FCON"
  25. #define CLASSTWO_CONNECT_SIZE 5
  26. #define CLASSTWO_TSI "+FTSI"
  27. #define CLASSTWO_TSI_SIZE 5
  28. #define CLASSTWO_DCS "+FDCS"
  29. #define CLASSTWO_DCS_SIZE 5
  30. #define CLASSTWO_NSS " +FNSS"
  31. #define CLASSTWO_NSS_SIZE 5
  32. #define CLASSTWO_HNGUP "+FHNG"
  33. #define CLASSTWO_HNGUP_SIZE 5
  34. #define CLASSTWO_CSI "+FCSI"
  35. #define CLASSTWO_CSI_SIZE 5
  36. #define CLASSTWO_DIS "+FDIS"
  37. #define CLASSTWO_DIS_SIZE 5
  38. #define CLASSTWO_NSF "+FNSF"
  39. #define CLASSTWO_NSF_SIZE 5
  40. #define CLASSTWO_PTS "+FPTS"
  41. #define CLASSTWO_PTS_SIZE 5
  42. #define CLASSTWO_ET "+FET"
  43. #define CLASSTWO_ET_SIZE 4
  44. #define CLASSTWO_DR "AT+FDR"
  45. #define CLASSTWO_DR_SIZE 6
  46. #define CLASSTWO_DT "AT+FDT"
  47. #define CLASSTWO_DT_SIZE 6
  48. #define CLASSTWO_FK "AT+FK"
  49. #define CLASSTWO_FK_SIZE 5
  50. #define CLASSTWO_SETID "AT+FLID="%s""
  51. #define CLASSTWO_SETRECV "AT+FCR=%d"
  52. #define CLASSTWO_SETBOR "AT+FBOR=0"
  53. #define CLASSTWO_SETPARAMS "AT+FDIS=%d,%d,%d,%d,%d,%d,0,%d"
  54. #define CLASSTWO_SENDET "AT+FET=%d"
  55. //////////////////////////////////////////////////////////////////////
  56. // Construction/Destruction
  57. //////////////////////////////////////////////////////////////////////
  58. CClassTwo::CClassTwo()
  59. {
  60. m_sEIAClass = "2";
  61. m_nScanTime = 0;
  62. }
  63. CClassTwo::~CClassTwo()
  64. {
  65. }
  66. void CClassTwo::OnConnect(void)
  67. {
  68. SetState( STATE_INIT );
  69. m_bGotOK = false;
  70. SendCommand( COMMAND_INIT );
  71. m_nLoopCtr = 0; 
  72. }
  73. bool CClassTwo::OnDisconnect(void)
  74. {
  75. switch( m_nState )
  76. {
  77. case STATE_INIT:
  78. SignalEvent( EVENT_ERROR );
  79. return true;
  80. case STATE_PHASE_A:
  81. case STATE_PHASE_B:
  82. case STATE_PHASE_C:
  83.   case STATE_PHASE_D:
  84.     case STATE_PHASE_E:
  85. Abort( true );
  86. return false;
  87. }
  88. return true;
  89. }
  90. //////////////////////////////////////////////////////////////////////
  91. // OnWrite
  92. //////////////////////////////////////////////////////////////////////
  93. void CClassTwo::OnWrite(void)
  94. {
  95. m_dwActivityTimer = GetTickCount();
  96. if( m_nState == STATE_PHASE_C && !m_bReceiving  && m_bGotDCS )
  97. {
  98. m_nPageBytes += m_BytesWritten;
  99. int nPercent = 100 * m_nPageBytes / m_FaxFile.GetPageBytes();
  100. if( nPercent > 100 )
  101. nPercent = 100;
  102. SignalEvent( EVENT_PAGE_DATA, nPercent );
  103. }
  104. }
  105. //////////////////////////////////////////////////////////////////////
  106. // OnReadLine
  107. //////////////////////////////////////////////////////////////////////
  108. void CClassTwo::OnReadLine(void)
  109. {
  110. //char szMsg[256];
  111. //wsprintf( szMsg, "CClassTwo::OnReadLine: %s %dn", m_szLineBuff, m_nLineBuffPtr );
  112. //OutputDebugString( szMsg );
  113. switch( m_nState )
  114. {
  115. case STATE_IDLE:
  116. PhaseIdle();
  117. break;
  118. case STATE_INIT:
  119. PhaseInit();
  120. break;
  121. case STATE_PHASE_A:
  122. PhaseA();
  123. break;
  124. case STATE_PHASE_B:
  125. PhaseB();
  126. break;
  127. case STATE_PHASE_C:
  128. PhaseC();
  129. break;
  130. case STATE_PHASE_D:
  131. PhaseD();
  132. break;
  133. case STATE_PHASE_E:
  134. PhaseE();
  135. break;
  136. case STATE_RINGING:
  137. PhaseRinging();
  138. break;
  139. case STATE_DISCONNECT:
  140. PhaseDisconnect();
  141. break;
  142. }
  143. }
  144. //////////////////////////////////////////////////////////////////////
  145. // PhaseInit
  146. //////////////////////////////////////////////////////////////////////
  147. void CClassTwo::PhaseInit(void)
  148. {
  149. if( stricmp( m_szLineBuff, m_LastCommandString.c_str() ) == 0 )
  150. {
  151. // Echo - ignore
  152. return;
  153. }
  154. if( IsRing() )
  155. {
  156. // RING
  157. m_nRingCount++;
  158. return;
  159. }
  160. switch( m_nLastCommand )
  161. {
  162. case COMMAND_INIT:
  163. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  164. {
  165. m_bGotOK = true;
  166. }
  167. else 
  168. {
  169. if( ++m_nLoopCtr >= 3 )
  170. {
  171. ErrorUnexpectedResponse();
  172. KillTimer( TIMER_COMMAND );
  173. OnDisconnectMsg();
  174. }
  175. }
  176. break;
  177. case COMMAND_SETUP_STRING:
  178. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  179. {
  180. SendCommand( COMMAND_DISABLE_ECHO );
  181. }
  182. else
  183. {
  184. ErrorUnexpectedResponse();
  185. KillTimer( TIMER_COMMAND );
  186. OnDisconnectMsg();
  187. }
  188. break;
  189. case COMMAND_DISABLE_ECHO:
  190. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  191. {
  192. SendCommand( COMMAND_SET_SPKR_VOL );
  193. }
  194. else
  195. {
  196. ErrorUnexpectedResponse();
  197. KillTimer( TIMER_COMMAND );
  198. OnDisconnectMsg();
  199. }
  200. break;
  201. case COMMAND_SET_SPKR_VOL:
  202. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  203. {
  204. SendCommand( COMMAND_SET_SPKR_MODE );
  205. }
  206. else
  207. {
  208. ErrorUnexpectedResponse();
  209. KillTimer( TIMER_COMMAND );
  210. OnDisconnectMsg();
  211. }
  212. break;
  213. case COMMAND_SET_SPKR_MODE:
  214. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  215. {
  216. SendCommand( COMMAND_SET_FCLASS_2 );
  217. }
  218. else
  219. {
  220. ErrorUnexpectedResponse();
  221. KillTimer( TIMER_COMMAND );
  222. OnDisconnectMsg();
  223. }
  224. break;
  225. case COMMAND_SET_FCLASS_2:
  226. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  227. {
  228. SendCommand( COMMAND_QUERY_CLASS2_CAP );
  229. }
  230. else
  231. {
  232. ErrorUnexpectedResponse();
  233. KillTimer( TIMER_COMMAND );
  234. OnDisconnectMsg();
  235. }
  236. break;
  237. case COMMAND_QUERY_CLASS2_CAP:
  238. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  239. {
  240. SendCommand( COMMAND_QUERY_SEND_SPEEDS );
  241. }
  242. else if( stricmp( m_szLineBuff, "ERROR" ) == 0 )
  243. {
  244. ErrorUnexpectedResponse();
  245. KillTimer( TIMER_COMMAND );
  246. OnDisconnectMsg();
  247. }
  248. else
  249. {
  250. ProcCapabilities( m_szLineBuff );
  251. VerifyOptions();
  252. }
  253. break;
  254. case COMMAND_QUERY_SEND_SPEEDS:
  255. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  256. {
  257. SendCommand( COMMAND_QUERY_RECEIVE_SPEEDS );
  258. }
  259. else
  260. {
  261. ProcSupportedSpeeds( m_szLineBuff, true );
  262. }
  263. break;
  264. case COMMAND_QUERY_RECEIVE_SPEEDS:
  265. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  266. {
  267. SetLocalID();
  268. }
  269. else
  270. {
  271. ProcSupportedSpeeds( m_szLineBuff, false );
  272. }
  273. break;
  274. case COMMAND_SET_LOCAL_ID:
  275. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  276. {
  277. SetRecv();
  278. }
  279. else
  280. {
  281. ErrorUnexpectedResponse();
  282. KillTimer( TIMER_COMMAND );
  283. OnDisconnectMsg();
  284. }
  285. break;
  286. case COMMAND_SET_RECV:
  287. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  288. {
  289. SetBitOrder();
  290. }
  291. else
  292. {
  293. ErrorUnexpectedResponse();
  294. KillTimer( TIMER_COMMAND );
  295. OnDisconnectMsg();
  296. }
  297. break;
  298. case COMMAND_SET_BIT_ORDER:
  299. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  300. {
  301. m_nScanTime = 0;
  302. SetFaxParams( false );
  303. }
  304. else
  305. {
  306. ErrorUnexpectedResponse();
  307. KillTimer( TIMER_COMMAND );
  308. OnDisconnectMsg();
  309. }
  310. break;
  311. case COMMAND_SET_FAX_PARAMS:
  312. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  313. {
  314. SetState( STATE_IDLE );
  315. KillTimer( TIMER_COMMAND );
  316. }
  317. else
  318. {
  319. ErrorUnexpectedResponse();
  320. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_REDUCE_COMPRESSION_BAUD_RATE_OR_DISABLE_ECM).c_str() );
  321. KillTimer( TIMER_COMMAND );
  322. OnDisconnectMsg();
  323. }
  324. break;
  325. }
  326. }
  327. //////////////////////////////////////////////////////////////////////
  328. // PhaseIdle
  329. //////////////////////////////////////////////////////////////////////
  330. void CClassTwo::PhaseIdle(void)
  331. {
  332. if( IsRing() )
  333. {
  334. m_nRingCount = 1;
  335. SetState( STATE_RINGING );
  336. SignalEvent( EVENT_RING, m_nRingCount );
  337. }
  338. }
  339. //////////////////////////////////////////////////////////////////////
  340. // Phase Ringing
  341. //////////////////////////////////////////////////////////////////////
  342. void CClassTwo::PhaseRinging(void)
  343. {
  344. if( IsRing() )
  345. {
  346. m_nRingCount++;
  347. SignalEvent( EVENT_RING, m_nRingCount );
  348. /*
  349. if( OkToAnswer() )
  350. {
  351. m_bReceiving = true;
  352. m_bSuccessful = false;
  353. SendCommand( COMMAND_ANSWER );
  354. SetState( STATE_PHASE_B, STATE_RECEIVING );
  355. }
  356. */
  357. }
  358. else if( strnicmp( m_szLineBuff, CLASSTWO_CONNECT, CLASSTWO_CONNECT_SIZE ) == 0 )
  359. {
  360. EnableSoftFlowControl( false );
  361. m_FaxFile.SetSendEncoding( m_nSendEncoding );
  362. m_bReceiving = true;
  363. m_bSuccessful = false;
  364. SignalEvent( EVENT_START_RECV );
  365. SetState( STATE_PHASE_B, STATE_RECEIVING );
  366. }
  367. else
  368. {
  369. SignalEvent( EVENT_CALLERID );
  370. }
  371. }
  372. //////////////////////////////////////////////////////////////////////
  373. // Phase A - call setup
  374. //////////////////////////////////////////////////////////////////////
  375. void CClassTwo::PhaseA(void)
  376. {
  377. switch( m_nPhaseState )
  378. {
  379. case STATE_SET_PARAMS:
  380. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  381. {
  382. SetLocalID();
  383. m_nPhaseState = STATE_SET_CSID;
  384. }
  385. else
  386. {
  387. // Error setting fax params
  388. m_sLastError.assign( (char*)LoadString(GEN_ERROR_SETTING_FAX_PARAMETERS).c_str() );
  389. //SignalEvent( EVENT_ERROR );
  390. Terminate();
  391. PhaseDisconnect();
  392. }
  393. break;
  394. case STATE_SET_CSID:
  395. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  396. {
  397. if( m_bReceiving )
  398. {
  399. SendCommand( COMMAND_ANSWER );
  400. SetState( STATE_PHASE_B, STATE_RECEIVING );
  401. }
  402. else
  403. {
  404. SendCommand( COMMAND_DIAL );
  405. m_nPhaseState = STATE_DIALING;
  406. }
  407. }
  408. else
  409. {
  410. // Error setting ID
  411. m_sLastError.assign( (char*)LoadString(GEN_ERROR_SETTING_ID).c_str() );
  412. //SignalEvent( EVENT_ERROR );
  413. Terminate();
  414. PhaseDisconnect();
  415. }
  416. break;
  417. case STATE_DIALING:
  418. if( strnicmp( m_szLineBuff, CLASSTWO_CONNECT, CLASSTWO_CONNECT_SIZE ) == 0 )
  419. {
  420. m_nLoopCtr = 0;
  421. SetState( STATE_PHASE_B, STATE_SENDING );
  422. m_bGotDIS = false;
  423. SignalEvent( EVENT_START_SEND );
  424. }
  425. else if( strnicmp( m_szLineBuff, CLASSTWO_HNGUP, CLASSTWO_HNGUP_SIZE ) == 0 )
  426. {
  427. OnFHNG();
  428. }
  429. else
  430. {
  431. ErrorConnectResponse();
  432. Terminate();
  433. PhaseDisconnect();
  434. }
  435. break;
  436. }
  437. }
  438. //////////////////////////////////////////////////////////////////////
  439. // Phase B - negotiation and training
  440. //////////////////////////////////////////////////////////////////////
  441. void CClassTwo::PhaseB(void)
  442. {
  443. switch( m_nPhaseState )
  444. {
  445. case STATE_RECEIVING:
  446. if( strnicmp( m_szLineBuff, "OK", 2 ) == 0 )
  447. {
  448. m_bGotEOP = false;
  449. m_bGotMPS = false;
  450. m_bGotEOM = false;
  451. // On to phase C
  452. DoWrite( CLASSTWO_DR, CLASSTWO_DR_SIZE, true );
  453. SetState( STATE_PHASE_C );
  454. m_FaxFile.WriteFileHeader();
  455. SignalEvent( EVENT_START_TRAINING );
  456. else if( strnicmp( m_szLineBuff, CLASSTWO_CONNECT, CLASSTWO_CONNECT_SIZE ) == 0 )
  457. {
  458. SignalEvent( EVENT_START_RECV );
  459. }
  460. else if( strnicmp( m_szLineBuff, CLASSTWO_TSI, CLASSTWO_TSI_SIZE ) == 0 )
  461. {
  462. OnCSI();
  463. }
  464. else if( strnicmp( m_szLineBuff, CLASSTWO_DCS, CLASSTWO_DCS_SIZE ) == 0 )
  465. {
  466. OnDCS();
  467. }
  468. else if( strnicmp( m_szLineBuff, CLASSTWO_NSS, CLASSTWO_NSS_SIZE ) == 0 )
  469. {
  470. OnNSS();
  471. }
  472. else if( strnicmp( m_szLineBuff, CLASSTWO_HNGUP, CLASSTWO_HNGUP_SIZE ) == 0 )
  473. {
  474. OnFHNG();
  475. }
  476. break;
  477. case STATE_SENDING:
  478. if( strnicmp( m_szLineBuff, "OK", 2 ) == 0 )
  479. {
  480. // Check DIS and re-set parameters if necessar
  481. if( m_bGotDIS && m_bResendFaxParams )
  482. {
  483. SetFaxParams( true );
  484. m_nPhaseState = STATE_RESET_PARAMS;
  485. }
  486. else
  487. {
  488. // On to Phase C
  489. DoWrite( CLASSTWO_DT, CLASSTWO_DT_SIZE, true );
  490. SetState( STATE_PHASE_C );
  491. m_bGotDCS = false;
  492. SignalEvent( EVENT_START_TRAINING );
  493. m_bLastPageGood = false;
  494. }
  495. else if( strnicmp( m_szLineBuff, CLASSTWO_CSI, CLASSTWO_CSI_SIZE ) == 0 )
  496. {
  497. OnCSI();
  498. }
  499. else if( strnicmp( m_szLineBuff, CLASSTWO_DIS, CLASSTWO_DIS_SIZE ) == 0 )
  500. {
  501. OnDIS();
  502. }
  503. else if( strnicmp( m_szLineBuff, CLASSTWO_NSF, CLASSTWO_NSF_SIZE ) == 0 )
  504. {
  505. OnNSF();
  506. }
  507. else if( strnicmp( m_szLineBuff, CLASSTWO_HNGUP, CLASSTWO_HNGUP_SIZE ) == 0 )
  508. {
  509. OnFHNG();
  510. }
  511. break;
  512. case STATE_RESET_PARAMS:
  513. if( strnicmp( m_szLineBuff, "OK", 2 ) == 0 )
  514. {
  515. // On to Phase C
  516. DoWrite( CLASSTWO_DT, CLASSTWO_DT_SIZE, true );
  517. SetState( STATE_PHASE_C );
  518. m_bGotDCS = false;
  519. KillTimer( TIMER_COMMAND );
  520. SignalEvent( EVENT_START_TRAINING );
  521. m_bLastPageGood = false;
  522. }
  523. else
  524. {
  525. ErrorUnexpectedResponse();
  526. KillTimer( TIMER_COMMAND );
  527. Terminate();
  528. PhaseDisconnect();
  529. }
  530. break;
  531. }
  532. }
  533. //////////////////////////////////////////////////////////////////////
  534. // Phase C - transmit/receive data
  535. //////////////////////////////////////////////////////////////////////
  536. void CClassTwo::PhaseC(void)
  537. {
  538. if( m_bReceiving )
  539. {
  540. if( strnicmp( m_szLineBuff, "CONNECT", 7 ) == 0 )
  541. {
  542. if( !m_bGotDCS )
  543. {
  544. char can = CAN;
  545. DoWrite( &can, 1, false );
  546. m_sLastError.assign( (char*)LoadString(GEN_ERROR_DCS_NOT_RECEIVED).c_str() );
  547. //SignalEvent( EVENT_ERROR );
  548. Terminate();
  549. SetState( STATE_PHASE_E, STATE_WAIT_FOR_OK );
  550. }
  551. else
  552. {
  553. char dc2 = DC2;
  554. DoWrite( &dc2, 1, false );
  555. InitHDLC();
  556. //EnableSoftFlowControl( false );
  557. m_bFirstFrame = true;
  558. SignalEvent( EVENT_START_PAGE );
  559. }
  560. }
  561. else if( stricmp( m_szLineBuff, "OK" ) == 0 )
  562. {
  563. m_nLoopCtr = 0;
  564. m_bLastPageGood = m_FaxFile.WriteIFD();
  565. //EnableSoftFlowControl( true );
  566. if( m_bGotEOP || (!m_bGotEOP && !m_bGotEOM && !m_bGotMPS ))
  567. {
  568. SetState( STATE_PHASE_E, STATE_WAIT_FOR_OK );
  569. }
  570. DoWrite( CLASSTWO_DR, CLASSTWO_DR_SIZE, true );
  571. m_bGotEOP = false;
  572. m_bGotMPS = false;
  573. m_bGotEOM = false;
  574. }
  575. else if( strnicmp( m_szLineBuff, CLASSTWO_PTS, CLASSTWO_PTS_SIZE ) == 0 )
  576. {
  577. OnFPTS();
  578. }
  579. else if( strnicmp( m_szLineBuff, CLASSTWO_ET, CLASSTWO_ET_SIZE ) == 0 )
  580. {
  581. OnFET();
  582. }
  583. else if( strnicmp( m_szLineBuff, CLASSTWO_HNGUP, CLASSTWO_HNGUP_SIZE ) == 0 )
  584. {
  585. OnFHNG();
  586. }
  587. }
  588. else
  589. {
  590. if( strnicmp( m_szLineBuff, "CONNECT", 7 ) == 0 )
  591. {
  592. char xon = XON;
  593. DoWrite( &xon, 1, false );
  594. m_nPageBytes = 0;
  595. DoWrite( m_FaxFile.GetPageData(), m_FaxFile.GetPageBytes(), false );
  596. SignalEvent( EVENT_START_PAGE );
  597. SetMaxPageRetriesTimer();
  598. }
  599. else if( stricmp( m_szLineBuff, "OK" ) == 0 )
  600. {
  601. char szCmdBuff[64];
  602. wsprintf( szCmdBuff, CLASSTWO_SENDET, m_FaxFile.MorePages() ? 0 : 2 );
  603. // on to phase D
  604. DoWrite( szCmdBuff, strlen(szCmdBuff), true );
  605. SetState( STATE_PHASE_D );
  606. }
  607. else if( strnicmp( m_szLineBuff, CLASSTWO_DCS, CLASSTWO_DCS_SIZE ) == 0 )
  608. {
  609. OnDCS();
  610. }
  611. else if( strnicmp( m_szLineBuff, CLASSTWO_HNGUP, CLASSTWO_HNGUP_SIZE ) == 0 )
  612. {
  613. OnFHNG();
  614. }
  615. }
  616. }
  617. //////////////////////////////////////////////////////////////////////
  618. // Phase D - post-page messages
  619. //////////////////////////////////////////////////////////////////////
  620. void CClassTwo::PhaseD(void)
  621. {
  622. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  623. {
  624. if( m_bLastPageGood )
  625. {
  626. if( m_FaxFile.MorePages() )
  627. {
  628. DoWrite( CLASSTWO_DT, CLASSTWO_DT_SIZE, true );
  629. SetState( STATE_PHASE_C );
  630. if( m_FaxFile.ReadNextHeader() == false )
  631. {
  632. m_sLastError.assign( (char*)LoadString(GEN_ERROR_READING_TIFF_FILE).c_str() );
  633. //SignalEvent( EVENT_ERROR );
  634. Terminate();
  635. SetState( STATE_PHASE_E, STATE_WAIT_FOR_OK );
  636. }
  637. else
  638. {
  639. if( m_FaxFile.ReadPage( false, 0, m_wMinLineChars, false, true ) == false )
  640. {
  641. m_sLastError.assign( (char*)LoadString(GEN_ERROR_READING_TIFF_FILE).c_str() );
  642. //SignalEvent( EVENT_ERROR );
  643. Terminate();
  644. SetState( STATE_PHASE_E, STATE_WAIT_FOR_OK );
  645. }
  646. }
  647. }
  648. else
  649. {
  650. m_FaxFile.IncrementPageCount();
  651. m_bSuccessful = true;
  652. DoWrite( CLASSTWO_FK, CLASSTWO_FK_SIZE, true );
  653. SetState( STATE_PHASE_E, STATE_WAIT_FOR_FK_RESP );
  654. KillTimer( TIMER_MAXPAGERETRIES );
  655. }
  656. }
  657. else
  658. {
  659. DoWrite( CLASSTWO_DT, CLASSTWO_DT_SIZE, true );
  660. SetState( STATE_PHASE_C );
  661. }
  662. m_bLastPageGood = false;
  663. }
  664. else if( strnicmp( m_szLineBuff, CLASSTWO_PTS, CLASSTWO_PTS_SIZE ) == 0 )
  665. {
  666. OnFPTS();
  667. }
  668. else if( strnicmp( m_szLineBuff, CLASSTWO_HNGUP, CLASSTWO_HNGUP_SIZE ) == 0 )
  669. {
  670. OnFHNG();
  671. }
  672. }
  673. //////////////////////////////////////////////////////////////////////
  674. // Phase E - Disconnect
  675. //////////////////////////////////////////////////////////////////////
  676. void CClassTwo::PhaseE(void)
  677. {
  678. switch( m_nPhaseState )
  679. {
  680. case STATE_WAIT_FOR_OK:
  681. if( strnicmp( m_szLineBuff, "OK", 2 ) == 0 )
  682. {
  683. DoWrite( CLASSTWO_FK, CLASSTWO_FK_SIZE, true );
  684. m_nPhaseState = STATE_WAIT_FOR_FK_RESP;
  685. }
  686. else if( strnicmp( m_szLineBuff, CLASSTWO_HNGUP, CLASSTWO_HNGUP_SIZE ) == 0 )
  687. {
  688. OnFHNG();
  689. }
  690. break;
  691. case STATE_WAIT_FOR_FK_RESP:
  692. Terminate();
  693. if( strnicmp( m_szLineBuff, "NO CARRIER", 2 ) == 0 )
  694. {
  695. PhaseDisconnect();
  696. }
  697. else
  698. {
  699. DoHangup();
  700. }
  701. break;
  702. }
  703. }
  704. //////////////////////////////////////////////////////////////////////
  705. // OnSendFaxMsg
  706. //////////////////////////////////////////////////////////////////////
  707. void CClassTwo::OnSendFaxMsg(MSG* pMsg)
  708. {
  709. CModem::OnSendFaxMsg( pMsg );
  710. if( !m_bConnected )
  711. {
  712. // Error!
  713. return;
  714. }
  715. if( m_nState != STATE_IDLE )
  716. {
  717. // Error!
  718. return;
  719. }
  720. m_FaxFile.SetSendEncoding( m_nSendEncoding );
  721. int nRet = m_FaxFile.ReadFirstHeader();
  722. if( nRet == 1 )
  723. {
  724. //OutputDebugString( "Error reading first headern" );
  725. m_sLastError.assign( (char*)LoadString(GEN_ERROR_READING_TIFF_FILE).c_str() );
  726. //SignalEvent( EVENT_ERROR );
  727. SignalEvent( EVENT_TERMINATE );
  728. SignalEvent( EVENT_IDLE );
  729. return;
  730. }
  731. else if( nRet == 2 )
  732. {
  733. //OutputDebugString( "Error reading first headern" );
  734. m_sLastError.assign( (char*)LoadString(GEN_ERROR_INCOMPAT_TIFF_FILE).c_str() );
  735. //SignalEvent( EVENT_ERROR );
  736. SignalEvent( EVENT_TERMINATE );
  737. SignalEvent( EVENT_IDLE );
  738. return;
  739. }
  740. m_bReceiving = false;
  741. m_bHDLCMode = false;
  742. m_bSuccessful = false;
  743. SetState( STATE_PHASE_A, STATE_SET_PARAMS );
  744. EnableSoftFlowControl( true );
  745. m_nScanTime = 0;
  746. m_DISParams.p.BitRate = m_nSendBaud;
  747. m_DISParams.p.PageLength = 2;
  748. SetFaxParams( true );
  749. }
  750. void CClassTwo::OnRecvFaxMsg(MSG* pMsg)
  751. {
  752. CModem::OnRecvFaxMsg( pMsg );
  753. if( m_nState == STATE_IDLE || m_nState == STATE_RINGING )
  754. {
  755. EnableSoftFlowControl( false );
  756. m_FaxFile.Clear();
  757. m_FaxFile.SetSendEncoding( m_nSendEncoding );
  758. m_bReceiving = true;
  759. m_bSuccessful = false;
  760. SetState( STATE_PHASE_A, STATE_SET_CSID );
  761. SetLocalID();
  762. }
  763. }
  764. //////////////////////////////////////////////////////////////////////
  765. // Handle wait timeout - do periodic processing
  766. //////////////////////////////////////////////////////////////////////
  767. bool CClassTwo::OnWaitTimeout( void )
  768. {
  769. CModem::OnWaitTimeout();
  770. /*
  771. if( m_nState == STATE_INIT )
  772. {
  773. DWORD dwElapsed = GetTickCount() - m_nLastCommandTickCount;
  774. // In case the modem doesn't respond with an OK
  775. if( dwElapsed > 1000 )
  776. {
  777. if( m_nLastCommand == COMMAND_QUERY_SEND_SPEEDS )
  778. {
  779. SendCommand( COMMAND_QUERY_RECEIVE_SPEEDS );
  780. }
  781. else if( m_nLastCommand == COMMAND_QUERY_RECEIVE_SPEEDS )
  782. {
  783. SetState( STATE_IDLE );
  784. }
  785. }
  786. if( dwElapsed > 4000 )
  787. {
  788. char szMsg[256];
  789. wsprintf( szMsg, "Timeout: %d ms waiting for responsen", dwElapsed );
  790. //OutputDebugString( szMsg );
  791. OnDisconnectMsg();
  792. }
  793. }
  794. */
  795. return false;
  796. }
  797. void CClassTwo::SetState( int nNewState, int nNewPhaseState )
  798. {
  799. /*
  800. bool bSignalIt = false;
  801. if( m_nState != nNewState )
  802. {
  803. bSignalIt = true;
  804. }
  805. */
  806. m_nState = nNewState;
  807. m_nPhaseState = nNewPhaseState;
  808. if( nNewState == STATE_IDLE )
  809. {
  810. SignalEvent( EVENT_IDLE );
  811. }
  812. }
  813. void CClassTwo::Abort( bool bUserCancelled )
  814. {
  815. char endofframe[2] = { DLE, ETX };
  816. char byteCancel = CAN;
  817. if( bUserCancelled ) 
  818. {
  819. m_sLastError.assign(  (char*)LoadString(GEN_FAX_CANCELLED).c_str() );
  820. }
  821. Terminate();
  822. switch( m_nState )
  823. {
  824. case STATE_PHASE_A:
  825. switch( m_nPhaseState )
  826. {
  827. case STATE_SET_PARAMS:
  828. case STATE_SET_CSID:
  829. SetState( STATE_PHASE_E, STATE_WAIT_FOR_FK_RESP );
  830. break;
  831. case STATE_DIALING:
  832. DoWrite( &byteCancel, 1, false );
  833. SetState( STATE_PHASE_E, STATE_WAIT_FOR_FK_RESP );
  834. break;
  835. }
  836. break;
  837. case STATE_PHASE_B:
  838. SetState( STATE_PHASE_E, STATE_WAIT_FOR_OK );
  839. break;
  840. case STATE_PHASE_C:
  841. if ( m_bReceiving )
  842. {
  843. DoWrite( &byteCancel, 1, false );
  844. SetState( STATE_PHASE_E, STATE_WAIT_FOR_OK );
  845. m_bHDLCMode = false;
  846. }
  847. else
  848. {
  849. DoWrite( endofframe, 2, false );
  850. SetState( STATE_PHASE_E, STATE_WAIT_FOR_OK );
  851. }
  852. break;
  853.   case STATE_PHASE_D:
  854. SetState( STATE_PHASE_E, STATE_WAIT_FOR_OK );
  855. break;
  856.     //case STATE_PHASE_E:
  857. // break;
  858. }
  859. }
  860. void CClassTwo::SetLocalID( void )
  861. {
  862. char szCmdBuff[256];
  863. wsprintf( szCmdBuff, CLASSTWO_SETID, m_sLocalCSID.c_str() );
  864. SendCommand( COMMAND_SET_LOCAL_ID, szCmdBuff );
  865. }
  866. void CClassTwo::SetRecv(void)
  867. {
  868. char szCmdBuff[256];
  869. wsprintf( szCmdBuff, CLASSTWO_SETRECV, m_bEnableReceive ? 1 : 0 );
  870. SendCommand( COMMAND_SET_RECV, szCmdBuff );
  871. }
  872. void CClassTwo::SetBitOrder(void)
  873. {
  874. SendCommand( COMMAND_SET_BIT_ORDER, CLASSTWO_SETBOR );
  875. }
  876. void CClassTwo::SetFaxParams( bool bSending )
  877. {
  878. char szCmdBuff[256];
  879. m_DCSParams.p.VertRes = m_bFineSupported ? 1 : 0;
  880. m_DCSParams.p.BitRate = m_nRecvBaud;
  881. m_DCSParams.p.PageWidth = 0;
  882. m_DCSParams.p.PageLength = m_bUnlimitedSupported ? 2 : 0;
  883. m_DCSParams.p.DataFormat = m_FaxFile.GetSendEncoding();
  884. m_DCSParams.p.ECM = m_bECMSupported ? 2 : 0;
  885. // TODO: Check if ECM enabled for modem and maximum bit rate
  886. if( bSending )
  887. {
  888. if( m_DISParams.p.BitRate > m_nSendBaud )
  889. {
  890. m_DCSParams.p.BitRate = m_nSendBaud;
  891. }
  892. else
  893. {
  894. m_DCSParams.p.BitRate = m_DISParams.p.BitRate;
  895. }
  896. if( m_FaxFile.IsHiRes() == false )
  897. {
  898. m_DCSParams.p.VertRes = 0;
  899. }
  900. if( m_DISParams.p.PageLength == 0 )
  901. {
  902. m_DCSParams.p.PageLength = 0;
  903. }
  904. }
  905. wsprintf( szCmdBuff, CLASSTWO_SETPARAMS,
  906.       m_DCSParams.p.VertRes, // resolution
  907.   m_DCSParams.p.BitRate, // bit rate
  908.   m_DCSParams.p.PageWidth, // page width
  909.   m_DCSParams.p.PageLength, // page length
  910.   m_DCSParams.p.DataFormat, // format
  911.   m_DCSParams.p.ECM,  // error checking
  912.   m_nScanTime );
  913. SendCommand( COMMAND_SET_FAX_PARAMS, szCmdBuff );
  914. }
  915. void CClassTwo::OnDIS(void)
  916. {
  917. ParseFaxParams( 8, m_DISParams.n );
  918. m_bGotDIS = true;
  919. m_bResendFaxParams = false;
  920. m_nScanTime = m_DISParams.p.ScanTime;
  921. if( m_DISParams.p.ScanTime > 0 )
  922. {
  923. m_bResendFaxParams = true;
  924. }
  925. /*
  926. if(    (m_DISParams.p.DataFormat != FAXAPI_ENC_CCITT_1D)
  927. && (m_DISParams.p.DataFormat < m_nSendEncoding ) )
  928. {
  929. //
  930. //OutputDebugString( "Need to re-set fax parameters!n" );
  931. m_bResendFaxParams = true;
  932. m_FaxFile.SetSendEncoding( FAXAPI_ENC_CCITT_1D );
  933. }
  934. // else if( m_DISParams.p.BitRate > 0 )
  935. // {
  936. // m_bResendFaxParams = true;
  937. // }
  938. */
  939. SignalEvent( EVENT_RECV_DIS );
  940. }
  941. void CClassTwo::OnDCS(void)
  942. {
  943. m_bGotDCS = true;
  944. ParseFaxParams( 8, m_DCSParams.n );
  945. if( m_bReceiving )
  946. {
  947. m_FaxFile.SetImageRes( m_DCSParams.p.VertRes != 0 );
  948. switch( m_DCSParams.p.PageWidth )
  949. {
  950. case 1:
  951. m_FaxFile.SetImageWidth( 2048 );
  952. break;
  953. case 2:
  954. m_FaxFile.SetImageWidth( 2432 );
  955. break;
  956. case 3:
  957. m_FaxFile.SetImageWidth( 1216 );
  958. break;
  959. case 4:
  960. m_FaxFile.SetImageWidth( 864 );
  961. break;
  962. default:
  963. m_FaxFile.SetImageWidth( 1728 );
  964. break;
  965. }
  966. switch( m_DCSParams.p.DataFormat )
  967. {
  968. case FAXAPI_ENC_CCITT_2D: // 2D modified Read
  969. m_FaxFile.SetImageCompression( 3 );
  970. m_FaxFile.SetT4Options( 0x01 );
  971. break;
  972. case FAXAPI_ENC_CCITT_UNC: // 2D uncompressed
  973. m_FaxFile.SetImageCompression( 3 );
  974. m_FaxFile.SetT4Options( 0 );
  975. break;
  976. case FAXAPI_ENC_CCITT_T6: // T.6
  977. m_FaxFile.SetImageCompression( 4 );
  978. m_FaxFile.SetT4Options( 0 );
  979. break;
  980. default: // CFaxFile::CCITT_1D = 1D modified huffman
  981. m_FaxFile.SetImageCompression( 3 );
  982. m_FaxFile.SetT4Options( 0 );
  983. break;
  984. }
  985. SignalEvent( EVENT_RECV_DCS );
  986. m_FaxFile.SetImageLength( 0 );
  987. }
  988. else
  989. {
  990. // TODO: What if we get multiple DCS (e.g. training failed)
  991. int nBaud = Cls2FaxParamBitRates[m_DCSParams.p.BitRate];
  992. int nScanTimeMs = (m_DCSParams.p.VertRes == 0) ? 
  993.   Cls2ScanTimes_normal[ m_DCSParams.p.ScanTime ] :
  994.               Cls2ScanTimes_fine[ m_DCSParams.p.ScanTime ];
  995. m_wMinLineChars = ((nBaud/8) * nScanTimeMs)/1000;
  996. m_FaxFile.SelectEncoding( m_DCSParams.p.DataFormat );
  997. SignalEvent( EVENT_SENT_DCS );
  998. if( m_FaxFile.ReadPage( false, 0, m_wMinLineChars, false, true ) == false )
  999. {
  1000. m_sLastError.assign( (char*)LoadString(GEN_ERROR_READING_TIFF_FILE).c_str() );
  1001. //SignalEvent( EVENT_ERROR );
  1002. Terminate();
  1003. SetState( STATE_PHASE_E, STATE_WAIT_FOR_OK );
  1004. }
  1005. }
  1006. }
  1007. void CClassTwo::OnCSI(void)
  1008. {
  1009. char szID[21];
  1010. int i = 0;
  1011. bool bNoQuotes = false;
  1012. m_sRemoteCSID = "";
  1013. //OutputDebugString( "OnCSIn" );
  1014. char* p = m_szLineBuff + 5; // skip +FTSI
  1015. if ( *p == ':' ) // skip the colon
  1016. {
  1017. p++;
  1018. }
  1019. while (*p && *p != '"' ) // skip white space before first quote
  1020. {
  1021. p++;
  1022. }
  1023. if( *p == 0 )
  1024. {
  1025. bNoQuotes = true;
  1026. // Uh-oh! no quotes found, back up and try w/o quotes
  1027. p = m_szLineBuff + 5;
  1028. if ( *p == ':' ) // skip the colon
  1029. {
  1030. p++;
  1031. }
  1032. while (*p && *p == ' ' ) // skip white space
  1033. {
  1034. p++;
  1035. }
  1036. return;
  1037. }
  1038. else
  1039. {
  1040. p++; // skip first quote
  1041. }
  1042. while( *p && (*p != '"') && (i < 20) )
  1043. {
  1044. szID[i] = *p;
  1045. p++;
  1046. i++;
  1047. }
  1048. szID[i] = 0;
  1049. m_sRemoteCSID.assign( szID );
  1050. SignalEvent( EVENT_GOT_REMOTEID );
  1051. }
  1052. void CClassTwo::OnNSF(void)
  1053. {
  1054. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_RECEIVED_NSF).c_str() );
  1055. }
  1056. void CClassTwo::OnNSS(void)
  1057. {
  1058. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_RECEIVED_NSS).c_str() );
  1059. }
  1060. // Page Status Report
  1061. void CClassTwo::OnFPTS(void)
  1062. {
  1063. int n[2];
  1064. // OutputDebugString( "OnFPTSn" );
  1065. int nParams = ParseFaxParams( 2, n );
  1066. if( nParams > 0 )
  1067. {
  1068. switch( n[0] )
  1069. {
  1070. case 1:
  1071. if( m_bReceiving )
  1072. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_SENT_MCF).c_str() );
  1073. else
  1074. {
  1075. m_bLastPageGood = true;
  1076. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_RECEIVED_MCF).c_str() );
  1077. }
  1078. break;
  1079. case 2:
  1080. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_RECEIVED_RTN).c_str() );
  1081. m_bLastPageGood = false;
  1082. break;
  1083. case 3:
  1084. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_RECEIVED_RTP).c_str() );
  1085. m_bLastPageGood = true;
  1086. break;
  1087. case 4:
  1088. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_RECEIVED_PIN).c_str() );
  1089. m_bLastPageGood = true;
  1090. break;
  1091. case 5:
  1092. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_RECEIVED_PIP).c_str() );
  1093. m_bLastPageGood = true;
  1094. break;
  1095. }
  1096. }
  1097. //if( nParams > 1 )
  1098. //{
  1099. // m_FaxFile.SetImageLength( n[1] );
  1100. //}
  1101. }
  1102. void CClassTwo::OnFET(void)
  1103. {
  1104. int n;
  1105. //OutputDebugString( "OnFETn" );
  1106. ParseFaxParams( 1, &n );
  1107. switch( n )
  1108. {
  1109. case 0:
  1110. OnMPS();
  1111. break;
  1112. case 1:
  1113. OnEOM();
  1114. break;
  1115. case 2:
  1116. OnEOP();
  1117. break;
  1118. }
  1119. }
  1120. void CClassTwo::OnEOP(void)
  1121. {
  1122. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_RECEIVED_EOP).c_str() );
  1123. m_bGotEOP = true;
  1124. }
  1125. void CClassTwo::OnEOM(void)
  1126. {
  1127. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_RECEIVED_EOM).c_str() );
  1128. m_bGotEOM = true;
  1129. }
  1130. void CClassTwo::OnMPS(void)
  1131. {
  1132. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_RECEIVED_MPS).c_str() );
  1133. m_bGotMPS = true;
  1134. }
  1135. void CClassTwo::OnFHNG( void )
  1136. {
  1137. int n;
  1138. //OutputDebugString( "OnFHNGn" );
  1139. ParseFaxParams( 1, &n );
  1140. // char szCode[32];
  1141. // wsprintf( szCode, "==> %dn", n );
  1142. // OutputDebugString( szCode );
  1143. switch( n )
  1144. {
  1145. case 0:
  1146. m_bSuccessful = true;
  1147. if( !m_bReceiving )
  1148. {
  1149. m_FaxFile.IncrementPageCount();
  1150. }
  1151. break;
  1152. case 1:
  1153. m_sLastError.assign( (char*)LoadString(GEN_CALL_ANSWERED_WO_FAX_HANDSHAKE).c_str() );
  1154. break;
  1155. case 2:
  1156. m_sLastError.assign( (char*)LoadString(GEN_CALL_ABORTED_BY_USER).c_str() );
  1157. break;
  1158. case 3:
  1159. m_sLastError.assign( (char*)LoadString(GEN_NO_LOOP_CURRENT).c_str() );
  1160. break;
  1161. case 10:
  1162. m_sLastError.assign( (char*)LoadString(GEN_UNSPECIFIED_PHASE_A_ERROR).c_str() );
  1163. break;
  1164. case 11:
  1165. m_sLastError.assign( (char*)LoadString(GEN_NO_ANSWER_OR_NO_DIS).c_str() );
  1166. break;
  1167. case 20:
  1168. m_sLastError.assign( (char*)LoadString(GEN_UNSPECIFIED_PHASE_B_TRANSMIT_ERROR).c_str() );
  1169. break;
  1170. case 21:
  1171. m_sLastError.assign( (char*)LoadString(GEN_REMOTE_CANNOT_RECEIVE_OR_SEND).c_str() );
  1172. break;
  1173. case 22:
  1174. m_sLastError.assign( (char*)LoadString(GEN_PHASE_B_TRANSMIT_COMMAND_FRAME_ERROR).c_str() );
  1175. break;
  1176. case 23:
  1177. m_sLastError.assign( (char*)LoadString(GEN_PHASE_B_TRANSMIT_INVALID_COMMAND_RECEIVED).c_str() );
  1178. break;
  1179. case 24:
  1180. m_sLastError.assign( (char*)LoadString(GEN_PHASE_B_TRANSMIT_RESPONSE_FRAME_ERROR).c_str() );
  1181. break;
  1182. case 25:
  1183. m_sLastError.assign( (char*)LoadString(GEN_DCS_SENT_THREE_TIMES_WITHOUT_RESPONSE).c_str() );
  1184. break;
  1185. case 26:
  1186. m_sLastError.assign( (char*)LoadString(GEN_DISDTC_RECEIVED_3_TIMES_DCS_NOT_RECOGNISED).c_str() );
  1187. break;
  1188. case 27:
  1189. m_sLastError.assign( (char*)LoadString(GEN_FAILURE_TO_TRAIN_AT_2400_BPS).c_str() );
  1190. break;
  1191. case 28:
  1192. m_sLastError.assign( (char*)LoadString(GEN_PHASE_B_TRANSMIT_INVALID_RESPONSE_RECEIVED).c_str() );
  1193. break;
  1194. case 40:
  1195. m_sLastError.assign( (char*)LoadString(GEN_UNSPECIFIED_PHASE_C_TRANSMIT_ERROR).c_str() );
  1196. break;
  1197. case 43:
  1198. m_sLastError.assign( (char*)LoadString(GEN_DTE_TO_DCE_DATA_UNDERFLOW).c_str() );
  1199. break;
  1200. case 50:
  1201. m_sLastError.assign( (char*)LoadString(GEN_UNSPECIFIED_PHASE_D_TRANSMIT_ERROR).c_str() );
  1202. break;
  1203. case 51:
  1204. m_sLastError.assign( (char*)LoadString(GEN_PHASE_D_TRANSMIT_RESPONSE_FRAME_ERROR).c_str() );
  1205. break;
  1206. case 52:
  1207. m_sLastError.assign( (char*)LoadString(GEN_NO_RESPONSE_TO_MPS_REPEATED_3_TIMES).c_str() );
  1208. break;
  1209. case 53:
  1210. m_sLastError.assign( (char*)LoadString(GEN_INVALID_RESPONSE_TO_MPS).c_str() );
  1211. break;
  1212. case 54:
  1213. m_sLastError.assign( (char*)LoadString(GEN_NO_RESPONSE_TO_EOP_REPEATED_3_TIMES).c_str() );
  1214. break;
  1215. case 55:
  1216. m_sLastError.assign( (char*)LoadString(GEN_INVALID_RESPONSE_TO_EOP).c_str() );
  1217. break;
  1218. case 56:
  1219. m_sLastError.assign( (char*)LoadString(GEN_NO_RESPONSE_TO_EOM_REPEATED_3_TIMES).c_str() );
  1220. break;
  1221. case 57:
  1222. m_sLastError.assign( (char*)LoadString(GEN_INVALID_RESPONSE_TO_EOM).c_str() );
  1223. break;
  1224. case 58:
  1225. m_sLastError.assign( (char*)LoadString(GEN_UNABLE_TO_CONTINUE_AFTER_PIN_OR_PIP).c_str() );
  1226. break;
  1227. case 70:
  1228. m_sLastError.assign( (char*)LoadString(GEN_UNSPECIFIED_PHASE_B_RECEIVE_ERROR).c_str() );
  1229. break;
  1230. case 71:
  1231. m_sLastError.assign( (char*)LoadString(GEN_PHASE_B_RECEIVE_RESPONSE_FRAME_ERROR).c_str() );
  1232. break;
  1233. case 72:
  1234. m_sLastError.assign( (char*)LoadString(GEN_PHASE_B_RECEIVE_COMMAND_FRAME_ERROR).c_str() );
  1235. break;
  1236. case 73:
  1237. m_sLastError.assign( (char*)LoadString(GEN_T30_T2_TIMEOUT).c_str() );
  1238. break;
  1239. case 74:
  1240. m_sLastError.assign( (char*)LoadString(GEN_FAILURE_TO_RESUME_PHASE_B_AFTER_EOM).c_str() );
  1241. break;
  1242. case 90:
  1243. m_sLastError.assign( (char*)LoadString(GEN_UNSPECIFIED_PHASE_C_RECEIVE_ERROR).c_str() );
  1244. break;
  1245. case 91:
  1246. m_sLastError.assign( (char*)LoadString(GEN_MISSING_EOL_AFTER_5_SEC).c_str() );
  1247. break;
  1248. case 93:
  1249. m_sLastError.assign( (char*)LoadString(GEN_MODEM_RECEIVE_BUFFER_OVERFLOWED).c_str() );
  1250. break;
  1251. case 94:
  1252. m_sLastError.assign( (char*)LoadString(GEN_CRC_OR_FRAME_ERROR_IN_ECM_MODE).c_str() );
  1253. break;
  1254. case 100:
  1255. m_sLastError.assign( (char*)LoadString(GEN_UNSPECIFIED_PHASE_D_RECEIVE_ERROR).c_str() );
  1256. break;
  1257. case 101:
  1258. m_sLastError.assign( (char*)LoadString(GEN_PHASE_D_RECEIVE_RESPONSE_FRAME_ERROR).c_str() );
  1259. break;
  1260. case 102:
  1261. m_sLastError.assign( (char*)LoadString(GEN_PHASE_D_RECEIVE_COMMAND_FRAME_ERROR).c_str() );
  1262. break;
  1263. case 103:
  1264. m_sLastError.assign( (char*)LoadString(GEN_UNABLE_TO_CONTINUE_AFTER_PIN_OR_PIP).c_str() );
  1265. break;
  1266. default:
  1267. m_sLastError.assign( (char*)LoadString(GEN_UNSPECIFIED_ERROR).c_str() );
  1268. break;
  1269. }
  1270. SetState( STATE_PHASE_E, STATE_WAIT_FOR_FK_RESP );
  1271. }
  1272. void CClassTwo::OnHDLCFrame(void)
  1273. {
  1274. //OutputDebugString( "OnHDLCFramen" );
  1275. if( m_nHDLCBuffPtr == 0 )
  1276. {
  1277. //OutputDebugString( "Empty HDLC Framen" );
  1278. return;
  1279. }
  1280. if( m_nState == STATE_PHASE_C && m_bReceiving )
  1281. {
  1282. m_FaxFile.WriteBuffer( m_szHDLCBuff, m_nHDLCBuffPtr, false );
  1283. }
  1284. }
  1285. void CClassTwo::OnPartialHDLCFrame(void)
  1286. {
  1287. //OutputDebugString( "OnPartialHDLCFramen" );
  1288. if( m_nState == STATE_PHASE_C && m_bReceiving )
  1289. {
  1290. if( m_bFirstFrame )
  1291. {
  1292. m_bFirstFrame = false;
  1293. if( m_szHDLCBuff[0] == XON )
  1294. {
  1295. //OutputDebugString( "Skipping XONn" );
  1296. m_FaxFile.WriteBuffer( m_szHDLCBuff+1, m_nHDLCBuffPtr-1, false );
  1297. }
  1298. else
  1299. {
  1300. m_FaxFile.WriteBuffer( m_szHDLCBuff, m_nHDLCBuffPtr, false );
  1301. }
  1302. }
  1303. else
  1304. {
  1305. m_FaxFile.WriteBuffer( m_szHDLCBuff, m_nHDLCBuffPtr, false );
  1306. }
  1307. }
  1308. else
  1309. {
  1310. //OutputDebugString( "HDLC buffer overflow!n" );
  1311. }
  1312. }
  1313. /*
  1314. int CClassTwo::ParseFaxParams( int nMaxParams )
  1315. {
  1316. char szNumBuff[21];
  1317. int* pParams = (int*)&m_Params;
  1318. int j;
  1319. int i;
  1320. ZeroMemory( &m_Params, sizeof(m_Params) );
  1321. char* p = m_szLineBuff + 5; // Skip +XXXX
  1322. if ( *p == ':' ) // skip the colon
  1323. {
  1324. p++;
  1325. }
  1326. // advance to first digit
  1327. while( *p && (*p < '0') && (*p > '9') && (*p != ',') )
  1328. {
  1329. p++;
  1330. }
  1331. for( i = 0; i < nMaxParams; i++ )
  1332. {
  1333. // check for end of string
  1334. if( *p == '' )
  1335. {
  1336. return i;
  1337. }
  1338. j = 0;
  1339. // advance to next comma
  1340. while( *p && (*p >='0') && (*p <= '9') && (j < 20) )
  1341. {
  1342. szNumBuff[j++] = *p++;
  1343. }
  1344. szNumBuff[j] = '';
  1345. pParams[i] = atoi( szNumBuff );
  1346. if( *p ) // advance past comma
  1347. p++;
  1348. }
  1349. return i;
  1350. }
  1351. */
  1352. void CClassTwo::OnTimer( UINT nID )
  1353. {
  1354. //OutputDebugString( "CClassTwo::OnTimern" );
  1355. if( nID == TIMER_COMMAND )
  1356. {
  1357. switch( m_nLastCommand )
  1358. {
  1359. case COMMAND_QUERY_SEND_SPEEDS:
  1360. SendCommand( COMMAND_QUERY_RECEIVE_SPEEDS );
  1361. break;
  1362. case COMMAND_QUERY_RECEIVE_SPEEDS:
  1363. SetLocalID();
  1364. break;
  1365. case COMMAND_HANGUP:
  1366. SetState( STATE_INIT );
  1367. SendCommand( COMMAND_INIT );
  1368. m_nLoopCtr = 0; 
  1369. break;
  1370. default:
  1371. if( m_bGotOK )
  1372. {
  1373. m_nLoopCtr = 0;
  1374. KillTimer( TIMER_COMMAND );
  1375. SendCommand( COMMAND_SETUP_STRING );
  1376. }
  1377. else
  1378. {
  1379. if( ++m_nLoopCtr >= 3 )
  1380. {
  1381. KillTimer( TIMER_COMMAND );
  1382. m_sLastError.assign( (char*)LoadString(GEN_NO_RESPONSE_FROM_MODEM).c_str() );
  1383. OnDisconnectMsg();
  1384. }
  1385. else
  1386. {
  1387. SendCommand( m_nLastCommand, (char*) m_LastCommandString.c_str() );
  1388. }
  1389. }
  1390. break;
  1391. }
  1392. }
  1393. }
  1394. void CClassTwo::OnAbortFaxMsg(void)
  1395. {
  1396. Abort( true );
  1397. }
  1398. void CClassTwo::VerifyOptions(void)
  1399. {
  1400. bool bModemFine = m_ParamMatrix[0][1] ? true : false;
  1401. bool bModemUnlimited = m_ParamMatrix[3][2] ? true : false;
  1402. int nModemCompression = m_ParamMatrix[4][3] ? 3 : (m_ParamMatrix[4][1] ? 1 : 0 );
  1403. bool bModemECM = m_ParamMatrix[5][2]  ? true : false;
  1404. if( nModemCompression < m_nSendEncoding )
  1405. {
  1406. char szMsg[FAXAPI_MODEMMSG_INFOLEN];
  1407. wsprintf( szMsg,(char*)LoadString(GEN_FORMAT_UNSUPPORTED_IN_CLASS_2).c_str(), 
  1408.  (m_nSendEncoding==3) ? "2D Group 4" : (m_nSendEncoding == 1 ? "2D Group 3" : "1D Group 3" ),
  1409.  (nModemCompression==3) ? "2D Group 4" : (nModemCompression == 1 ? "2D Group 3" : "1D Group 3" ) );
  1410. SetSendEncoding( nModemCompression );
  1411. SignalEventString( EVENT_INFO, szMsg );
  1412. }
  1413. if( !bModemECM && m_bECMSupported )
  1414. {
  1415. SetSendECM( false );
  1416. SignalEventString( EVENT_INFO, (char*)LoadString(GEN_ECM_UNSUPPORTED_IN_CLASS_2).c_str() );
  1417. }
  1418. SetSendFine( bModemFine );
  1419. SetSendUnlimited( bModemUnlimited );
  1420. }
  1421. void CClassTwo::CheckTimeouts( DWORD dwInActive )
  1422. {
  1423. switch( m_nState )
  1424. {
  1425. case STATE_PHASE_A:
  1426. if( dwInActive > 90000 )
  1427. {
  1428. m_sLastError.assign( (char*)LoadString(GEN_TIMEOUT_CONNECTING_TO_REMOTE_FAX).c_str()  );
  1429. //SignalEvent( EVENT_ERROR );
  1430. Abort( false );
  1431. m_dwActivityTimer = GetTickCount();
  1432. }
  1433. break;
  1434. case STATE_PHASE_E:
  1435. if( dwInActive > 5000 )
  1436. {
  1437. Terminate();
  1438. PhaseDisconnect();
  1439. }
  1440. break;
  1441. case STATE_DISCONNECT:
  1442. if( dwInActive > 1000 )
  1443. {
  1444. PhaseDisconnect();
  1445. }
  1446. break;
  1447. default:
  1448. if( m_nState > STATE_IDLE && m_nState != STATE_RINGING )
  1449. {
  1450. int nInActive = GetTickCount() - m_dwActivityTimer;
  1451. if( nInActive > 60000 )
  1452. {
  1453. m_sLastError.assign(  (char*)LoadString(GEN_TIMEOUT_IN_SENDRECEIVE).c_str() );
  1454. //SignalEvent( EVENT_ERROR );
  1455. Abort( false );
  1456. m_dwActivityTimer = GetTickCount();
  1457. }
  1458. }
  1459. break;
  1460. }
  1461. }