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

传真(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. #include "stdafx.h"
  17. #include "ModemDetect.h"
  18. //////////////////////////////////////////////////////////////////////
  19. // Construction/Destruction
  20. //////////////////////////////////////////////////////////////////////
  21. CModemDetect::CModemDetect()
  22. {
  23. pInfo = new FaxApiModemDetectMsg;
  24. pInfo->m_cbSize = sizeof(FaxApiModemDetectMsg);
  25. pInfo->m_bSuccessful = false;
  26. pInfo->m_bClass1 = false;
  27. pInfo->m_bClass1_0 = false;
  28. pInfo->m_bClass2 = false;
  29. pInfo->m_bClass2_0 = false;
  30. pInfo->m_bClass2_1 = false;
  31. pInfo->m_szClasses[0] = '';
  32. pInfo->m_szProductCode[0] = '';
  33. pInfo->m_szIDCode[0] = '';
  34. pInfo->m_szManufacturer[0] = '';
  35. pInfo->m_szModel[0] = '';
  36. ZeroMemory( pInfo->m_Class2Matrix, sizeof(bool)*FAXAPI_MAXPARAMETERS*FAXAPI_MAXPARAMVALUE );
  37. ZeroMemory( pInfo->m_Class20Matrix, sizeof(bool)*FAXAPI_MAXPARAMETERS*FAXAPI_MAXPARAMVALUE );
  38. m_nLoopCtr = 0;
  39. }
  40. CModemDetect::~CModemDetect()
  41. {
  42. }
  43. //////////////////////////////////////////////////////////////////////
  44. // OnConnect
  45. //////////////////////////////////////////////////////////////////////
  46. void CModemDetect::OnConnect(void)
  47. {
  48. SetState( STATE_INIT );
  49. m_bGotOK = false;
  50. SendCommand( COMMAND_INIT );
  51. m_nLoopCtr = 0; 
  52. }
  53. //////////////////////////////////////////////////////////////////////
  54. // OnDisconnect
  55. //////////////////////////////////////////////////////////////////////
  56. bool CModemDetect::OnDisconnect(void)
  57. {
  58. return true;
  59. }
  60. //////////////////////////////////////////////////////////////////////
  61. // OnReadLine
  62. //////////////////////////////////////////////////////////////////////
  63. void CModemDetect::OnReadLine(void)
  64. {
  65. switch( m_nState )
  66. {
  67. case STATE_INIT:
  68. PhaseInit();
  69. break;
  70. }
  71. }
  72. //////////////////////////////////////////////////////////////////////
  73. // OnTimer
  74. //////////////////////////////////////////////////////////////////////
  75. void CModemDetect::OnTimer( UINT nID )
  76. {
  77. if( (nID == TIMER_COMMAND) && (m_nState == STATE_INIT) )
  78. {
  79. if( m_nLastCommand == COMMAND_INIT )
  80. {
  81. if( m_bGotOK )
  82. {
  83. m_nLoopCtr = 0;
  84. SendCommand( COMMAND_DISABLE_ECHO );
  85. }
  86. else
  87. {
  88. if( ++m_nLoopCtr >= 3 )
  89. {
  90. KillTimer( TIMER_COMMAND );
  91. m_sLastError.assign(  (char*)LoadString(GEN_NO_RESPONSE_FROM_MODEM).c_str() );
  92. SignalEvent( EVENT_ERROR );
  93. OnDisconnectMsg();
  94. }
  95. else
  96. {
  97. SendCommand( m_nLastCommand, (char*) m_LastCommandString.c_str() );
  98. }
  99. }
  100. }
  101. else
  102. {
  103. m_sLastError.assign( (char*)LoadString(GEN_TIMEOUT_RESPONDING_TO_COMMAND).c_str() );
  104. SignalEvent( EVENT_ERROR );
  105. KillTimer( TIMER_COMMAND );
  106. OnDisconnectMsg();
  107. }
  108. }
  109. }
  110. //////////////////////////////////////////////////////////////////////
  111. // PhaseInit
  112. //////////////////////////////////////////////////////////////////////
  113. void CModemDetect::PhaseInit(void)
  114. {
  115. if( stricmp( m_szLineBuff, m_LastCommandString.c_str() ) == 0 )
  116. {
  117. // Echo - ignore
  118. return;
  119. }
  120. switch( m_nLastCommand )
  121. {
  122. case COMMAND_INIT:
  123. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  124. {
  125. m_bGotOK = true;
  126. }
  127. else 
  128. {
  129. if( ++m_nLoopCtr >= 3 )
  130. {
  131. ErrorUnexpectedResponse();
  132. KillTimer( TIMER_COMMAND );
  133. Quit( false );
  134. }
  135. }
  136. break;
  137. case COMMAND_DISABLE_ECHO:
  138. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  139. {
  140. // send next command
  141. SendCommand( COMMAND_QUERY_PRODUCT_CODE );
  142. }
  143. else 
  144. {
  145. ErrorUnexpectedResponse();
  146. Quit( false );
  147. }
  148. break;
  149. // most general stuff first
  150. case COMMAND_QUERY_PRODUCT_CODE:
  151. if( ( stricmp( m_szLineBuff, "OK" ) == 0 ) || ( stricmp( m_szLineBuff, "ERROR" ) == 0 ) )
  152. {
  153. // send next command
  154. SendCommand( COMMAND_QUERY_MANUFACTURER );
  155. }
  156. else
  157. {
  158. strncpy( pInfo->m_szProductCode, m_szLineBuff, FAXAPI_DETECTMSG_INFOLEN );
  159. }
  160. break;
  161. case COMMAND_QUERY_MANUFACTURER:
  162. if( ( stricmp( m_szLineBuff, "OK" ) == 0 ) || ( stricmp( m_szLineBuff, "ERROR" ) == 0 ) )
  163. {
  164. // send next command
  165. SendCommand( COMMAND_QUERY_FCLASS );
  166. }
  167. else 
  168. {
  169. strncpy( pInfo->m_szIDCode, m_szLineBuff, FAXAPI_DETECTMSG_INFOLEN );
  170. }
  171. break;
  172. case COMMAND_QUERY_FCLASS:
  173. if( stricmp( m_szLineBuff, "ERROR" ) == 0 )
  174. {
  175. ErrorUnexpectedResponse();
  176. Quit( false );
  177. }
  178. else if( stricmp( m_szLineBuff, "OK" ) == 0 )
  179. {
  180. if( pInfo->m_bClass1 )
  181. {
  182. SendCommand( COMMAND_SET_FCLASS_1 );
  183. }
  184. else if( pInfo->m_bClass2 )
  185. {
  186. SendCommand( COMMAND_SET_FCLASS_2 );
  187. }
  188. else if( pInfo->m_bClass2_0 )
  189. {
  190. SendCommand( COMMAND_SET_FCLASS_2_0 );
  191. }
  192. else
  193. {
  194. Quit( false );
  195. }
  196. }
  197. else 
  198. {
  199. strncpy( pInfo->m_szClasses, m_szLineBuff, FAXAPI_DETECTMSG_INFOLEN );
  200. char WorkBuffer[512];
  201. WorkBuffer[0] = '';
  202. strncpy( WorkBuffer, pInfo->m_szClasses, FAXAPI_DETECTMSG_INFOLEN );
  203. WorkBuffer[511] = '';
  204. LPSTR lpTok = strtok( WorkBuffer, ",");
  205. while( lpTok ) 
  206. {
  207. if( strcmp( lpTok, "1" ) == 0 )
  208. {
  209. pInfo->m_bClass1 = true;
  210. }
  211. else if( strcmp( lpTok, "1.0" ) == 0 )
  212. {
  213. pInfo->m_bClass1_0 = true;
  214. }
  215. else if( strcmp( lpTok, "2" ) == 0 )
  216. {
  217. pInfo->m_bClass2 = true;
  218. }
  219. else if( strcmp( lpTok, "2.0" ) == 0 )
  220. {
  221. pInfo->m_bClass2_0 = true;
  222. }
  223. else if( strcmp( lpTok, "2.1" ) == 0 )
  224. {
  225. pInfo->m_bClass2_1 = true;
  226. }
  227. lpTok = strtok( NULL, "," );
  228. }
  229. }
  230. break;
  231. case COMMAND_SET_FCLASS_1:
  232. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  233. {
  234. //OutputDebugString( "Supports class 1n" );
  235. }
  236. else 
  237. {
  238. pInfo->m_bClass1 = false;
  239. }
  240. SendCommand( COMMAND_QUERY_SEND_SPEEDS );
  241. break;
  242. case COMMAND_QUERY_SEND_SPEEDS:
  243. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  244. {
  245. SendCommand( COMMAND_QUERY_RECEIVE_SPEEDS );
  246. }
  247. else 
  248. {
  249. ProcSupportedSpeeds( m_szLineBuff, true );
  250. pInfo->m_nSendBaudRate = m_nMaxSendBaud;
  251. }
  252. break;
  253. case COMMAND_QUERY_RECEIVE_SPEEDS:
  254. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  255. {
  256. pInfo->m_bSuccessful = true;
  257. if( pInfo->m_bClass2 )
  258. {
  259. SendCommand( COMMAND_SET_FCLASS_2 );
  260. }
  261. else if( pInfo->m_bClass2_0 )
  262. {
  263. SendCommand( COMMAND_SET_FCLASS_2_0 );
  264. }
  265. else
  266. {
  267. Quit( true );
  268. }
  269. }
  270. else 
  271. {
  272. ProcSupportedSpeeds( m_szLineBuff, false );
  273. pInfo->m_nRecvBaudRate = m_nMaxRecvBaud;
  274. }
  275. break;
  276. case COMMAND_SET_FCLASS_2:
  277. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  278. {
  279. SendCommand( COMMAND_QUERY_CLASS2_CAP );
  280. }
  281. else 
  282. {
  283. pInfo->m_bClass2 = false;
  284. if( pInfo->m_bClass2_0 )
  285. {
  286. SendCommand( COMMAND_SET_FCLASS_2_0 );
  287. }
  288. else
  289. {
  290. Quit( pInfo->m_bSuccessful );
  291. }
  292. }
  293. break;
  294. case COMMAND_QUERY_CLASS2_CAP:
  295. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  296. {
  297. // send next command
  298. SendCommand( COMMAND_QUERY_CLASS2_MANUFACT );
  299. }
  300. else 
  301. {
  302. ProcCapabilities( m_szLineBuff );
  303. memcpy( pInfo->m_Class2Matrix, m_ParamMatrix, sizeof(bool)*FAXAPI_MAXPARAMETERS*FAXAPI_MAXPARAMVALUE );
  304. }
  305. break;
  306. case COMMAND_QUERY_CLASS2_MANUFACT:
  307. if( ( stricmp( m_szLineBuff, "OK" ) == 0 ) || ( stricmp( m_szLineBuff, "ERROR" ) == 0 ) )
  308. {
  309. // send next command
  310. SendCommand( COMMAND_QUERY_CLASS2_MODEL );
  311. }
  312. else 
  313. {
  314. if( pInfo->m_szManufacturer[0] == '' )
  315. {
  316. strncpy( pInfo->m_szManufacturer, m_szLineBuff, FAXAPI_DETECTMSG_INFOLEN );
  317. }
  318. }
  319. break;
  320. case COMMAND_QUERY_CLASS2_MODEL:
  321. if( ( stricmp( m_szLineBuff, "OK" ) == 0 ) || ( stricmp( m_szLineBuff, "ERROR" ) == 0 ) )
  322. {
  323. if( pInfo->m_bClass2_0 )
  324. {
  325. SendCommand( COMMAND_SET_FCLASS_2_0 );
  326. }
  327. else
  328. {
  329. Quit( pInfo->m_bSuccessful );
  330. }
  331. }
  332. else 
  333. {
  334. if( pInfo->m_szModel[0] == '' )
  335. {
  336. strncpy( pInfo->m_szModel, m_szLineBuff, FAXAPI_DETECTMSG_INFOLEN );
  337. }
  338. }
  339. break;
  340. case COMMAND_SET_FCLASS_2_0:
  341. if( stricmp( m_szLineBuff, "OK" ) == 0 )
  342. {
  343. // class 2.0 supported
  344. SendCommand( COMMAND_QUERY_CLASS2_0_CAP );
  345. }
  346. else 
  347. {
  348. pInfo->m_bClass2_0 = false;
  349. Quit( pInfo->m_bSuccessful );
  350. }
  351. break;
  352. case COMMAND_QUERY_CLASS2_0_CAP:
  353. if( ( stricmp( m_szLineBuff, "OK" ) == 0 ) || ( stricmp( m_szLineBuff, "ERROR" ) == 0 ) )
  354. {
  355. SendCommand( COMMAND_QUERY_CLASS2_0_MANUFACT );
  356. }
  357. else 
  358. {
  359. ProcCapabilities( m_szLineBuff );
  360. memcpy( pInfo->m_Class20Matrix, m_ParamMatrix, sizeof(bool)*FAXAPI_MAXPARAMETERS*FAXAPI_MAXPARAMVALUE );
  361. }
  362. break;
  363. case COMMAND_QUERY_CLASS2_0_MANUFACT:
  364. if( ( stricmp( m_szLineBuff, "OK" ) == 0 ) || ( stricmp( m_szLineBuff, "ERROR" ) == 0 ) )
  365. {
  366. // send next command
  367. SendCommand( COMMAND_QUERY_CLASS2_0_MODEL );
  368. }
  369. else 
  370. {
  371. if( pInfo->m_szManufacturer[0] == '' )
  372. {
  373. strncpy( pInfo->m_szManufacturer, m_szLineBuff, FAXAPI_DETECTMSG_INFOLEN );
  374. }
  375. }
  376. break;
  377. case COMMAND_QUERY_CLASS2_0_MODEL:
  378. if( ( stricmp( m_szLineBuff, "OK" ) == 0 ) || ( stricmp( m_szLineBuff, "ERROR" ) == 0 ) )
  379. {
  380. Quit( true );
  381. }
  382. else 
  383. {
  384. if( pInfo->m_szModel[0] == '' )
  385. {
  386. strncpy( pInfo->m_szModel, m_szLineBuff, FAXAPI_DETECTMSG_INFOLEN );
  387. }
  388. }
  389. break;
  390. }
  391. }
  392. //////////////////////////////////////////////////////////////////////
  393. // Quit
  394. //////////////////////////////////////////////////////////////////////
  395. void CModemDetect::Quit( bool bSuccessful )
  396. {
  397. strncpy( pInfo->szID, m_sPort.c_str(), FAXAPI_MODEMMSG_IDLEN );
  398. m_bSuccessful = bSuccessful;
  399. if( bSuccessful )
  400. {
  401. if( pInfo->m_szModel[0] == '' )
  402. {
  403. if( pInfo->m_szProductCode[0] )
  404. {
  405. strncpy( pInfo->m_szModel, pInfo->m_szProductCode, FAXAPI_DETECTMSG_INFOLEN );
  406. }
  407. else if( pInfo->m_szIDCode[0] )
  408. {
  409. strncpy( pInfo->m_szModel, pInfo->m_szIDCode, FAXAPI_DETECTMSG_INFOLEN );
  410. }
  411. }
  412. if( pInfo->m_szManufacturer[0] == '' )
  413. {
  414. if( pInfo->m_szIDCode[0] )
  415. {
  416. strncpy( pInfo->m_szManufacturer, pInfo->m_szIDCode, FAXAPI_DETECTMSG_INFOLEN );
  417. }
  418. else if( pInfo->m_szProductCode[0] )
  419. {
  420. strncpy( pInfo->m_szManufacturer, pInfo->m_szProductCode, FAXAPI_DETECTMSG_INFOLEN );
  421. }
  422. }
  423. }
  424. // zero terminate since strncpy doesn't do this for us
  425. pInfo->m_szClasses[FAXAPI_DETECTMSG_INFOLEN-1] = '';
  426. pInfo->m_szProductCode[FAXAPI_DETECTMSG_INFOLEN-1] = '';
  427. pInfo->m_szIDCode[FAXAPI_DETECTMSG_INFOLEN-1] = '';
  428. pInfo->m_szManufacturer[FAXAPI_DETECTMSG_INFOLEN-1] = '';
  429. pInfo->m_szModel[FAXAPI_DETECTMSG_INFOLEN-1] = '';
  430. PostThreadMessage( m_FaxThreadID, WM_MODEM_MESSAGE, (WPARAM)pInfo, FAXAPI_EVENT_DETECT_FINISHED );
  431. PhaseDisconnect();
  432. }