Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

603 lines
26 KiB

  1. /***************************************************************************
  2. Name : WHATNEXT.C
  3. Comment : T30 Decision-point Callback function
  4. Copyright (c) 1993 Microsoft Corp.
  5. Revision Log
  6. Num Date Name Description
  7. --- -------- ---------- -----------------------------------------------
  8. ***************************************************************************/
  9. #define USE_DEBUG_CONTEXT DEBUG_CONTEXT_T30_MAIN
  10. #include "prep.h"
  11. #include "efaxcb.h"
  12. #include "protocol.h"
  13. ///RSL
  14. #include "glbproto.h"
  15. #include "t30gl.h"
  16. #include "psslog.h"
  17. #define FILE_ID FILE_ID_WHATNEXT
  18. #include "pssframe.h"
  19. // used in eventPOSTPAGERESPONSE
  20. // first index got from ifrSend (MPS=0, EOM=1, EOP=2, EOMwithFastTurn=3)
  21. // second index got from ifrRecv (MCF=0, RTP=1, RTN=2)
  22. ET30ACTION PostPageAction[4][3] =
  23. {
  24. { actionGONODE_I, actionGONODE_D, actionGONODE_D },
  25. { actionGONODE_T, actionGONODE_T, actionGONODE_T },
  26. { actionDCN, actionDCN, actionGONODE_D },
  27. { actionGONODE_A, actionGONODE_A, actionGONODE_D }
  28. };
  29. DWORD PageWidthInPixelsFromDCS[] =
  30. { // This is width page in DCS
  31. 1728,
  32. 2048,
  33. 2432,
  34. 2432
  35. };
  36. /***-------------- Warning. This is called as a Vararg function --------***/
  37. ET30ACTION __cdecl FAR
  38. WhatNext
  39. (
  40. PThrdGlbl pTG,
  41. ET30EVENT event,
  42. WORD wArg1,
  43. DWORD_PTR lArg2,
  44. DWORD_PTR lArg3
  45. )
  46. {
  47. ET30ACTION action = actionERROR;
  48. NPPROT npProt = &pTG->ProtInst;
  49. DEBUG_FUNCTION_NAME(_T("WhatNext"));
  50. DebugPrintEx( DEBUG_MSG,
  51. "Called with %s. args %d, %d, %d",
  52. event_GetEventDescription(event),
  53. wArg1,
  54. lArg2,
  55. lArg3);
  56. if (pTG->fAbortRequested)
  57. {
  58. if (pTG->fOkToResetAbortReqEvent && (!pTG->fAbortReqEventWasReset))
  59. {
  60. DebugPrintEx(DEBUG_MSG,"RESETTING AbortReqEvent");
  61. pTG->fAbortReqEventWasReset = TRUE;
  62. if (!ResetEvent(pTG->AbortReqEvent))
  63. {
  64. DebugPrintEx( DEBUG_ERR,
  65. "ResetEvent(0x%lx) returns failure code: %ld",
  66. (ULONG_PTR)pTG->AbortReqEvent,
  67. (long) GetLastError());
  68. }
  69. }
  70. DebugPrintEx(DEBUG_MSG,"ABORTing");
  71. return actionERROR;
  72. }
  73. if(npProt->fAbort)
  74. {
  75. DebugPrintEx(DEBUG_ERR,"Aborting");
  76. return actionERROR;
  77. }
  78. switch(event)
  79. {
  80. case eventGOTFRAMES:
  81. {
  82. /* uCount=wArg1. This is the number of frames received.
  83. *
  84. * lplpfr=(LPLPET30FR)lArg2. Pointer to an array of pointers to
  85. * the received frames, each in an ET30FR structure whose
  86. * format is defined in ET30defs.H
  87. *
  88. * return must be actionNULL
  89. */
  90. USHORT uCount = wArg1;
  91. LPLPFR lplpfr = (LPLPFR)lArg2;
  92. LPIFR lpifr = (LPIFR)lArg3; // pointer to IFR that the "Response Recvd"
  93. // routine will return to the main body
  94. // can be modified, for example, if a bad
  95. // franes is deciphered.
  96. LPFR lpfr;
  97. USHORT i;
  98. BOOL fGotRecvCaps=FALSE, fGotRecvParams=FALSE;
  99. if(*lpifr == ifrBAD)
  100. {
  101. DebugPrintEx(DEBUG_WRN,"Callback on Bad Frame. Ignoring ALL");
  102. action = actionNULL; // only allowed response to eventGOTFRAMES
  103. break;
  104. }
  105. DebugPrintEx(DEBUG_MSG,"Got %d frames",uCount);
  106. for(i=0; i<uCount; i++)
  107. {
  108. ///////////////////////////////////////////////////////////////
  109. // Prepare to get trash (upto 2 bytes) at end of every frame //
  110. ///////////////////////////////////////////////////////////////
  111. lpfr = lplpfr[i];
  112. DebugPrintEx( DEBUG_MSG,
  113. "Frame %d is %s",
  114. i,
  115. ifr_GetIfrDescription(lpfr->ifr));
  116. switch(lpfr->ifr)
  117. {
  118. case ifrBAD: DebugPrintEx(DEBUG_ERR,"Bad Frame not caught");
  119. // ignore it
  120. break;
  121. case ifrCSI:
  122. case ifrTSI:
  123. case ifrCIG: CopyRevIDFrame(pTG, npProt->bRemoteID, lpfr, sizeof(npProt->bRemoteID));
  124. // trailing-trash removed by length limit IDFIFSIZE
  125. PSSLogEntry(PSS_MSG, 1, "%s is \"%s\"",
  126. (lpfr->ifr==ifrCSI) ? "CSI" : "TSI", npProt->bRemoteID);
  127. // prepare CSID for logging by FaxSvc
  128. // Here we get the Remote Station ID eg. 972 4 8550306
  129. pTG->RemoteID = AnsiStringToUnicodeString(pTG->ProtInst.bRemoteID);
  130. if (pTG->RemoteID)
  131. {
  132. pTG->fRemoteIdAvail = TRUE;
  133. }
  134. break;
  135. case ifrDIS: npProt->uRemoteDISlen = CopyFrame(pTG, (LPBYTE)(&npProt->RemoteDIS), lpfr, sizeof(DIS));
  136. // trailing-trash removed in ParseDISDTCDCS
  137. npProt->fRecvdDIS = TRUE;
  138. fGotRecvCaps = TRUE;
  139. break;
  140. case ifrDCS: npProt->uRemoteDCSlen = CopyFrame(pTG, (LPBYTE)(&npProt->RemoteDCS), lpfr, sizeof(DIS));
  141. // trailing-trash removed in ParseDISDTCDCS
  142. npProt->fRecvdDCS = TRUE;
  143. fGotRecvParams = TRUE;
  144. PSSLogEntry(PSS_MSG, 1, "Received DCS is as follows:");
  145. LogClass1DCSDetails(pTG, (NPDIS)(&lpfr->fif));
  146. // We save the Image Width from the DCS we got
  147. pTG->TiffInfo.ImageWidth = PageWidthInPixelsFromDCS[npProt->RemoteDCS.PageWidth];
  148. // We save the Image YResolution from the DCS we got
  149. pTG->TiffInfo.YResolution = (npProt->RemoteDCS.ResFine_200) ? TIFFF_RES_Y : TIFFF_RES_Y_DRAFT;
  150. // Also lets save the CompressionType from the fresh DCS
  151. pTG->TiffInfo.CompressionType = (npProt->RemoteDCS.MR_2D) ? TIFF_COMPRESSION_MR : TIFF_COMPRESSION_MH;
  152. break;
  153. case ifrDTC: break;
  154. case ifrNSS: fGotRecvParams = TRUE; //some OEMs send NSS w/o DCS
  155. break;
  156. case ifrNSC: break;
  157. case ifrNSF: break;
  158. case ifrCFR:
  159. case ifrFTT:
  160. case ifrEOM:
  161. case ifrMPS:
  162. case ifrEOP:
  163. case ifrPRI_EOM:
  164. case ifrPRI_MPS:
  165. case ifrPRI_EOP:
  166. case ifrMCF:
  167. case ifrRTP:
  168. case ifrRTN:
  169. case ifrPIP:
  170. case ifrPIN:
  171. case ifrDCN:
  172. case ifrCRP:
  173. /*** ECM frames below ***/
  174. case ifrCTR:
  175. case ifrERR:
  176. case ifrRR:
  177. case ifrRNR:
  178. case ifrEOR_NULL:
  179. case ifrEOR_MPS:
  180. case ifrEOR_PRI_MPS:
  181. case ifrEOR_EOM:
  182. case ifrEOR_PRI_EOM:
  183. case ifrEOR_EOP:
  184. case ifrEOR_PRI_EOP:
  185. // These have no FIF
  186. DebugPrintEx( DEBUG_WRN,
  187. "These are not supposed to be signalled");
  188. // bad frame. ignore it
  189. break;
  190. /********* New T.30 frames ******************************/
  191. case ifrSUB: break;
  192. /********* ECM stuff starts here. T.30 section A.4 ******/
  193. // These have FIFs
  194. case ifrPPR:
  195. case ifrPPS_NULL:
  196. case ifrPPS_EOM:
  197. case ifrPPS_MPS:
  198. case ifrPPS_EOP:
  199. case ifrPPS_PRI_EOM:
  200. case ifrPPS_PRI_MPS:
  201. case ifrPPS_PRI_EOP:
  202. break;
  203. case ifrCTC:
  204. if(lpfr->cb < 2)
  205. {
  206. // bad frame. FORCE A RETRANSMIT!!
  207. DebugPrintEx(DEBUG_ERR,"Bad CTC length!!");
  208. *lpifr = ifrNULL;
  209. break;
  210. }
  211. npProt->llRecvParams.Baud = ((LPDIS)(&(lpfr->fif)))->Baud;
  212. // trailing-trash removed by length limit 2
  213. break;
  214. } // End of 'switch(lpfr->ifr)'
  215. } // handle the next frame
  216. if(fGotRecvCaps)
  217. {
  218. PSSLogEntry(PSS_MSG, 1, "DIS specified the following capabilities:");
  219. LogClass1DISDetails(pTG, &npProt->RemoteDIS);
  220. GotRecvCaps(pTG);
  221. }
  222. if(fGotRecvParams)
  223. {
  224. GotRecvParams(pTG);
  225. }
  226. action = actionNULL; // only allowed response to eventGOTFRAMES
  227. break;
  228. }
  229. /****** Transmitter Phase B. Fig A-7/T.30 (sheet 1) ******/
  230. case eventNODE_T: // do nothing. Hook for abort in T1 loop
  231. action=actionNULL; break;
  232. case eventNODE_R: // do nothing. Hook for abort in T1 loop
  233. action=actionNULL; break;
  234. case eventNODE_A:
  235. {
  236. IFR ifrRecv = (IFR)wArg1; // last received frame
  237. // lArg2 & lArg3 missing
  238. if(ifrRecv != ifrDIS && ifrRecv != ifrDTC)
  239. {
  240. DebugPrintEx(DEBUG_ERR,"Unknown frames at NodeA");
  241. action = actionHANGUP; // G3 only
  242. }
  243. else if(npProt->fSendParamsInited)
  244. {
  245. action = actionGONODE_D; // sends DCS/NSS (in response to DIS or DTC)
  246. }
  247. else
  248. {
  249. DebugPrintEx(DEBUG_ERR,"NodeA: No more work...!!");
  250. action = actionDCN; // hangs up (sends DCN)
  251. }
  252. break;
  253. }
  254. case eventSENDDCS:
  255. {
  256. // 0==1st DCS 1==after NoReply 2==afterFTT
  257. USHORT uWhichDCS = (UWORD)wArg1;
  258. // where to return the number of frames returned
  259. LPUWORD lpuwN = (LPUWORD)lArg2;
  260. // where to return a pointer to an array of pointers to
  261. // return frames
  262. LPLPLPFR lplplpfr = (LPLPLPFR)lArg3;
  263. if(uWhichDCS == 2) // got FTT
  264. {
  265. if(!DropSendSpeed(pTG))
  266. {
  267. DebugPrintEx(DEBUG_ERR, "FTT: Can't Drop speed any lower");
  268. action = actionDCN;
  269. break;
  270. }
  271. }
  272. CreateNSSTSIDCS(pTG, npProt, &pTG->rfsSend);
  273. *lpuwN = pTG->rfsSend.uNumFrames;
  274. *lplplpfr = pTG->rfsSend.rglpfr;
  275. action = actionSENDDCSTCF;
  276. break;
  277. // Could also return DCN if not compatible
  278. // or SKIPTCF for Ricoh hook
  279. }
  280. case eventGOTCFR:
  281. {
  282. // wArg1, lArg2 & lArg3 are all missing
  283. // Can return GONODE_D (Ricoh hook)
  284. // or GONODE_I (Non ECM) or GONODE_IV (ECM)
  285. action = actionGONODE_I;
  286. break;
  287. }
  288. /****** Transmitter Phase C. Fig A-7/T.30 (sheet 1) ******/
  289. /****** Transmitter ECM and non-ECM Phase D1. Fig A-7/T.30 (sheet 2) ******/
  290. case eventPOSTPAGE:
  291. {
  292. USHORT uNextSend;
  293. // wArg1, lArg2 & lArg3 are all missing
  294. // Can turn Zero stuffing off here, or wait for next page....
  295. // ET30ExtFunction(npProt->het30, ET30_SET_ZEROPAD, 0);
  296. // Don't turn it off!! It is used only for Page Send
  297. // and is set only on sending a DCS, so it is set once
  298. // before a multi-page send.
  299. uNextSend = ICommNextSend(pTG);
  300. switch(uNextSend)
  301. {
  302. case NEXTSEND_MPS: action = actionSENDMPS;
  303. break;
  304. case NEXTSEND_EOM: action = actionSENDEOM;
  305. break;
  306. case NEXTSEND_EOP: action = actionSENDEOP;
  307. break;
  308. case NEXTSEND_ERROR:
  309. default: action = actionSENDEOP;
  310. break;
  311. }
  312. break;
  313. // also possible -- GOPRIEOP, PRIMPS or PRIEOM
  314. }
  315. /****** Transmitter Phase D2. Fig A-7/T.30 (sheet 2) ******/
  316. case eventGOTPOSTPAGERESP:
  317. {
  318. IFR ifrRecv = (IFR)wArg1; // last received frame
  319. IFR ifrSent = (IFR)lArg2;
  320. // the IFR was simply cast to DWORD and then to LPVOID
  321. // lArg3 is missing
  322. USHORT i, j;
  323. // change PRI commands to ordinary ones
  324. if(ifrSent >= ifrPRI_FIRST && ifrSent <= ifrPRI_LAST)
  325. ifrSent = (ifrSent + ifrMPS - ifrPRI_MPS);
  326. if(ifrRecv!=ifrMCF && ifrRecv!=ifrRTP && ifrRecv!=ifrRTN)
  327. {
  328. DebugPrintEx( DEBUG_ERR,
  329. "Unexpected Response %d",
  330. ifrRecv);
  331. action = actionDCN;
  332. break;
  333. }
  334. i = ifrSent - ifrMPS; //i: 0=MPS, 1=EOM, 2=EOP
  335. j = ifrRecv - ifrMCF; //j: 0=MCF, 1=RTP, 2=RTN
  336. // Report status + Check whether we do re-transmit
  337. if (ifrRecv==ifrRTN)
  338. {
  339. pTG->ProtParams.RTNNumOfRetries++; // increment by one the number of re-transmittions
  340. DebugPrintEx( DEBUG_MSG,
  341. "RTN: Try# %d",
  342. pTG->ProtParams.RTNNumOfRetries);
  343. if (pTG->ProtParams.RTNNumOfRetries <= gRTNRetries.RetriesBeforeDropSpeed)
  344. {
  345. // Number of retries before we start to drop speed.
  346. // Just change the number of retries, do not drop speed yet
  347. DebugPrintEx( DEBUG_MSG,
  348. "Got RTN, Resend same page with same speed");
  349. }
  350. else // We should first try to drop speed or hangup
  351. {
  352. if(pTG->ProtParams.RTNNumOfRetries > gRTNRetries.RetriesBeforeDCN) // Exceed the allowed re-transmittions.
  353. {
  354. DebugPrintEx( DEBUG_MSG,
  355. "RTN: Tried to resend same page"
  356. " %d times. Giving up (HANG-UP)",
  357. (pTG->ProtParams.RTNNumOfRetries-1));
  358. action = actionDCN;
  359. break; // set action to DCN and return
  360. }
  361. else
  362. {
  363. DebugPrintEx( DEBUG_MSG,
  364. "Got RTN, now try to drop speed one notch");
  365. if(!DropSendSpeed(pTG))
  366. {
  367. DebugPrintEx( DEBUG_ERR,
  368. "RTN: Can't Drop speed any lower,"
  369. " trying again in same speed");
  370. }
  371. }
  372. }
  373. }
  374. action = PostPageAction[i][j];
  375. if(action == actionDCN)
  376. {
  377. DebugPrintEx(DEBUG_MSG,"PostPage --> Game over");
  378. }
  379. break;
  380. // Can also return GO_D, GO_R1, GO_R2. Only restriction is
  381. // that GO_I is the only valid response to MPS sent followed
  382. // by MCF
  383. }
  384. /****** Receiver Phase B. Fig A-7/T.30 (sheet 1) ******/
  385. case eventSENDDIS:
  386. {
  387. // wArg1 is 0
  388. // where to return the number of frames returned
  389. LPUWORD lpuwN = (LPUWORD)lArg2;
  390. // where to return a pointer to an array of pointers to
  391. // return frames
  392. LPLPLPFR lplplpfr = (LPLPLPFR)lArg3;
  393. BCtoNSFCSIDIS(pTG, &pTG->rfsSend, (NPBC)&npProt->SendCaps, &npProt->llSendCaps);
  394. // We save OUR DIS in the LocalDIS.
  395. // This will help us when we want to check the DCS we got against the DIS we send.
  396. npProt->uLocalDISlen = CopyFrame(pTG, (LPBYTE)(&npProt->LocalDIS),
  397. pTG->rfsSend.rglpfr[pTG->rfsSend.uNumFrames - 1], // The DIS is always the last frame
  398. sizeof(DIS));
  399. npProt->fLocalDIS = TRUE;
  400. PSSLogEntry(PSS_MSG, 1, "Composing DIS with the following capabilities:");
  401. LogClass1DISDetails(pTG, &npProt->LocalDIS);
  402. *lpuwN = pTG->rfsSend.uNumFrames;
  403. *lplplpfr = pTG->rfsSend.rglpfr;
  404. action = actionSEND_DIS;
  405. break;
  406. }
  407. /*** Receiver Phase B. Main Command Loop. Fig A-7/T.30 (sheet 1&2) ***/
  408. case eventRECVCMD:
  409. {
  410. IFR ifrRecv = (IFR)wArg1; // last received frame
  411. // lArg2 & lArg3 missing
  412. switch(ifrRecv)
  413. {
  414. case ifrDTC:
  415. // flow chart says Goto D, but actually we need to decide if we
  416. // have anything to send. So goto NodeA first
  417. // return GONODE_D;
  418. action = actionGONODE_A;
  419. break;
  420. case ifrDIS:
  421. action = actionGONODE_A;
  422. break;
  423. case ifrDCS:
  424. {
  425. // Check the received DCS for compatibility with us
  426. // set Recv Baud rate--no need. TCF already recvd by this time
  427. // ET30ExtFunction(npProt->het30, ET30_SET_RECVDATASPEED, npProt->RemoteDCS.Baud);
  428. action = actionGETTCF;
  429. // only other valid action is HANGUP
  430. break;
  431. }
  432. case ifrNSS:
  433. {
  434. // Check the received NSS for compatibility with us
  435. // set Recv Baud rate--no need. TCF already recvd by this time
  436. // ET30ExtFunction(npProt->het30, ET30_SET_RECVDATASPEED, npProt->RemoteDCS.Baud);
  437. action = actionGETTCF;
  438. // only other valid action is HANGUP
  439. break;
  440. }
  441. default:
  442. action = actionHANGUP;
  443. break;
  444. }
  445. break;
  446. }
  447. case eventGOTTCF:
  448. {
  449. SWORD swErr = (SWORD)wArg1; // errors per 1000
  450. // lArg2 & lArg3 missing
  451. DebugPrintEx( DEBUG_MSG,
  452. "GOTTCF num of errors = %d",
  453. swErr);
  454. action = actionSENDCFR;
  455. if (!AreDCSParametersOKforDIS(&pTG->ProtInst.LocalDIS, &pTG->ProtInst.RemoteDCS))
  456. {
  457. PSSLogEntry(PSS_WRN, 1, "Received bad DCS parameters - sending FTT");
  458. action = actionSENDFTT;
  459. }
  460. if (swErr < 0) // TCF was bad
  461. {
  462. PSSLogEntry(PSS_WRN, 1, "Received bad TCF - sending FTT");
  463. action = actionSENDFTT;
  464. }
  465. break;
  466. }
  467. /****** Receiver Phase C. Fig A-7/T.30 (sheet 1) ******/
  468. /***
  469. case eventSTARTRECV:
  470. {
  471. if(!StartNextRecvPage())
  472. {
  473. action = actionDCN;
  474. }
  475. else
  476. action = actionCONTINUE;
  477. break;
  478. }
  479. ***/
  480. /****** Receiver Phase D. Fig A-7/T.30 (sheet 1) ******/
  481. case eventRECVPOSTPAGECMD:
  482. {
  483. // IFR ifrRecv = (IFR)wArg1; // last received frame
  484. // lArg2 & lArg3 missing
  485. if ((pTG->T30.fReceivedPage) && (!pTG->fPageIsBad))
  486. action = actionSENDMCF; // quality fine
  487. else
  488. action = actionSENDRTN; // quality unacceptable
  489. // can also return actionSENDPIP or actionSENDPIN in a local
  490. // interrupt is pending
  491. break;
  492. }
  493. default:
  494. {
  495. DebugPrintEx(DEBUG_ERR,"Unknown Event = %d", event);
  496. break;
  497. }
  498. }
  499. //done:
  500. DebugPrintEx( DEBUG_MSG,
  501. "event %s returned %s",
  502. event_GetEventDescription(event),
  503. action_GetActionDescription(action));
  504. return action;
  505. }