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

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