Source code of Windows XP (NT5)
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.

367 lines
13 KiB

  1. /***************************************************************************
  2. Name : RECVFR.C
  3. Comment :
  4. Functions: (see Prototypes just below)
  5. Copyright (c) 1993 Microsoft Corp.
  6. Revision Log
  7. Date Name Description
  8. -------- ----- ---------------------------------------------------------
  9. ***************************************************************************/
  10. #include "prep.h"
  11. #include "efaxcb.h"
  12. #include "protocol.h"
  13. ///RSL
  14. #include "glbproto.h"
  15. #define faxTlog(m) DEBUGMSG(ZONE_RECVFR, m)
  16. #define FILEID FILEID_RECVFR
  17. USHORT FindMSNSx(PThrdGlbl pTG, NPRFS npRecvd)
  18. {
  19. USHORT i;
  20. for(i=0; i<npRecvd->uNumFrames; i++)
  21. {
  22. BG_CHK(i < MAXFRAMES);
  23. if(IsAtWorkNSx(npRecvd->rglpfr[i]->fif, npRecvd->rglpfr[i]->cb))
  24. {
  25. faxTlog((SZMOD "Found MS NSx!!\r\n"));
  26. return i+1;
  27. }
  28. }
  29. return 0;
  30. }
  31. void GotRecvFrames(PThrdGlbl pTG, IFR ifr, NPRFS npRecvd, NPDIS npdis, LPBYTE lpbRecvdID,
  32. LPBYTE lpbRecipSubAddr, BCTYPE bctype, NPBC npbc, USHORT wBCSize,
  33. NPLLPARAMS npll)
  34. {
  35. USHORT uRet1=0, uRet2=0;
  36. InitBC(npbc, wBCSize, bctype);
  37. // RSL remove NSF processing.
  38. uRet1 = 0;
  39. if(npRecvd->uNumFrames) // recvd some NSXs
  40. {
  41. // scope out NSXs
  42. if(uRet1) // RSL = FindMSNSx(pTG, npRecvd))
  43. {
  44. // found MS NSXs
  45. BG_CHK((ifr!=ifrNSF) ? (pTG->ProtInst.llSendCaps.fECM && uRet1==1) : TRUE);
  46. // if we got MS NSCs or NSSs then we must be able to do ECM
  47. // and we can't get can't get other peoples NSSs/NSCs at same time
  48. // setup BC first
  49. npbc->bctype = bctype;
  50. // all short ptrs into DGROUP get correctly cast to LPs we hope...
  51. if(uRet2 = NSX_TO_BC(pTG, ifr, npRecvd->rglpfr, npRecvd->uNumFrames, npbc, wBCSize))
  52. {
  53. (MyDebugPrint(pTG, LOG_ERR, "<<ERROR>> got error %d parsing NSX\r\n", uRet2));
  54. // forget we got an NSX
  55. // zero out BC again
  56. InitBC( npbc, wBCSize, bctype);
  57. uRet1 = 0;
  58. }
  59. #ifndef NOCHALL
  60. else
  61. {
  62. if(ifr==ifrNSF)
  63. {
  64. USHORT uChallLen;
  65. // Poll challenge string is the first POLL_CHALLENGE_LEN
  66. // bytes (following the B5 00 76 signature) of the first
  67. // MS NSF _received_ or the whole thing if it is shorter
  68. // than that
  69. BG_CHK(npRecvd->rglpfr[uRet1-1]->cb > 3);
  70. uChallLen = min(npRecvd->rglpfr[uRet1-1]->cb-3, POLL_CHALLENGE_LEN);
  71. AppendToBCLen( npbc, wBCSize, npRecvd->rglpfr[uRet1-1]->fif+3,
  72. uChallLen, wChallenge, wChallengeLen);
  73. }
  74. else if(ifr==ifrNSC)
  75. {
  76. // for NSC append _our_ challenge string, i.e.
  77. // first POLL_CHALLENGE_LEN bytes (following the B5 00 76
  78. // signature) of the first MS NSF that _we_sent_out
  79. // or the whole thing if it is shorter than that
  80. AppendToBCLen(npbc, wBCSize, pTG->bSavedChallenge,
  81. pTG->uSavedChallengeLen, wChallenge, wChallengeLen);
  82. }
  83. // for NSS wChallenge==NULL
  84. }
  85. #endif //!NOCHALL
  86. }
  87. #ifdef OEMNSF
  88. else if(wOEMFlags && lpfnOEMNSxToBC)
  89. {
  90. #pragma message("WARNING: OEMNsxToBC: The code here for removing and restoring the FCS bytes hasn't been tested!!!")
  91. USHORT uRet3;
  92. USHORT iFrame;
  93. // OEM NSX DLL exists --> do something for(iFrame=0; iFrame<wNumFrame; iFrame++)
  94. for(iFrame=0; iFrame < npRecvd->uNumFrames; iFrame++)
  95. npRecvd->rglpfr[iFrame]->cb -= 2; // Subtract 2 to lop off the FCS
  96. if(!(uRet3 = lpfnOEMNSxToBC(ifr, npRecvd->rglpfr, npRecvd->uNumFrames, npbc, wBCSize, npll)))
  97. {
  98. //It might be a modem that doesn't pass us the FCS, try again
  99. for(iFrame=0; iFrame < npRecvd->uNumFrames; iFrame++)
  100. npRecvd->rglpfr[iFrame]->cb += 2; // Put last two bytes back on
  101. // zero out BC again
  102. InitBC(pTG, npbc, wBCSize, bctype);
  103. if(!(uRet3 = lpfnOEMNSxToBC(ifr, npRecvd->rglpfr, npRecvd->uNumFrames, npbc, wBCSize, npll)))
  104. {
  105. (MyDebugPrint(pTG, LOG_ERR, "<<ERROR>> got error parsing OEM NSF\r\n"));
  106. // zero out BC again
  107. InitBC(pTG, npbc, wBCSize, bctype);
  108. }
  109. }
  110. else
  111. {
  112. faxTlog((SZMOD "Using OEM Protocol\r\n"));
  113. fUsingOEMProt = TRUE;
  114. if(uRet3 & OEMNSF_IGNORE_DIS)
  115. npdis = NULL;
  116. if(uRet3 & OEMNSF_IGNORE_CSI)
  117. lpbRecvdID = NULL;
  118. }
  119. }
  120. #endif
  121. }
  122. if(npdis)
  123. {
  124. // extract DIS caps into BC and LL
  125. ParseDISorDCSorDTC(pTG, npdis, &(npbc->Fax), npll, (ifr==ifrNSS ? TRUE : FALSE));
  126. }
  127. // If an ID is recvd in NSF/NSS/NSC the CSI/TSI/CIG should NOT overwrite it
  128. if(lpbRecvdID && !HasTextId(npbc))
  129. {
  130. PutTextId(npbc, wBCSize, lpbRecvdID, (int)_fstrlen(lpbRecvdID), TEXTCODE_ASCII);
  131. //PutNumId(npbc, wBCSize, lpbRecvdID, (int) _fstrlen(lpbRecvdID), TEXTCODE_ASCII);
  132. }
  133. // If a subaddress is recvd in NSF/NSS/NSC the SUB frame should NOT overwrite it
  134. if(lpbRecipSubAddr && !HasRecipSubAddr( npbc))
  135. {
  136. PutRecipSubAddr( npbc, wBCSize, lpbRecipSubAddr, (int)_fstrlen(lpbRecipSubAddr));
  137. }
  138. if(uRet1 > 0)
  139. {
  140. npll->fECM = TRUE; // ignore ECM bit in DIS, if MS NSF present
  141. }
  142. }
  143. BOOL AwaitSendParamsAndDoNegot(PThrdGlbl pTG, BOOL fSleep)
  144. {
  145. // This does actual negotiation & gets SENDPARAMS. It could potentially
  146. // return SEND_POLLREQ instead.
  147. if(!ProtGetBC(pTG, SEND_PARAMS, fSleep))
  148. {
  149. if(fSleep)
  150. {
  151. // ICommFailureCode already set
  152. MyDebugPrint(pTG, LOG_ALL, "ATTENTION: AwaitSendParamsAndDoNegot pTG->ProtInst.fAbort = TRUE\n");
  153. pTG->ProtInst.fAbort = TRUE;
  154. }
  155. return FALSE;
  156. }
  157. // negotiate low-level params here. (a) because this is where
  158. // high-level params are negotiated (b) because it's inefficient to
  159. // do it on each DCS (c) because RTN breaks otherwise--see bug#731
  160. // llRecvCaps and llSendParams are set only at startup
  161. // SendParams are set in ProtGetBC just above
  162. // llNegot is the return value. So this can be called
  163. // only at the end of this function
  164. // negot lowlevel params if we are sending and not polling
  165. if(!pTG->ProtInst.fAbort && pTG->ProtInst.fSendParamsInited)
  166. {
  167. NegotiateLowLevelParams(pTG, &pTG->ProtInst.llRecvCaps, &pTG->ProtInst.llSendParams,
  168. pTG->ProtInst.SendParams.Fax.AwRes,
  169. pTG->ProtInst.SendParams.Fax.Encoding,
  170. &pTG->ProtInst.llNegot);
  171. pTG->ProtInst.fllNegotiated = TRUE;
  172. // This chnages llNegot->Baud according to the MaxSpeed settings
  173. EnforceMaxSpeed(pTG);
  174. }
  175. return TRUE;
  176. }
  177. void GotRecvCaps(PThrdGlbl pTG)
  178. {
  179. BG_CHK(pTG->ProtInst.fRecvdDIS);
  180. if(!pTG->ProtInst.llSendParams.fECM)
  181. {
  182. // if we can't do ECM on send, ignore the received NSFs
  183. // zap the ECM bits of the received DTC
  184. pTG->ProtInst.RemoteDIS.ECM = 0;
  185. pTG->ProtInst.RemoteDIS.SmallFrame = 0;
  186. }
  187. GotRecvFrames(pTG, ifrNSF, &pTG->ProtInst.RecvdNS,
  188. (pTG->ProtInst.fRecvdDIS ? &pTG->ProtInst.RemoteDIS : NULL),
  189. (pTG->ProtInst.fRecvdID ? pTG->ProtInst.bRemoteID : NULL),
  190. (pTG->ProtInst.fRecvdSUB ? pTG->ProtInst.bRecipSubAddr : NULL),
  191. RECV_CAPS, (NPBC)&pTG->ProtInst.RecvCaps, sizeof(pTG->ProtInst.RecvCaps),
  192. &pTG->ProtInst.llRecvCaps);
  193. pTG->ProtInst.fRecvCapsGot = TRUE;
  194. pTG->ProtInst.fllRecvCapsGot = TRUE;
  195. #ifdef FILET30
  196. // Send up raw caps.
  197. ICommRawCaps(
  198. pTG,
  199. (LPBYTE) (pTG->ProtInst.fRecvdID ? pTG->ProtInst.bRemoteID: NULL),
  200. (LPBYTE) (pTG->ProtInst.fRecvdDIS ? (LPBYTE) (&(pTG->ProtInst.RemoteDIS)):NULL),
  201. (USHORT) (pTG->ProtInst.fRecvdDIS ? pTG->ProtInst.uRemoteDISlen:0),
  202. (LPFR FAR *) (pTG->ProtInst.RecvdNS.uNumFrames ? pTG->ProtInst.RecvdNS.rglpfr:NULL),
  203. (USHORT) (pTG->ProtInst.RecvdNS.uNumFrames)
  204. );
  205. #endif
  206. // send off BC struct to higher level
  207. if(!ICommRecvCaps(pTG, (LPBC)&pTG->ProtInst.RecvCaps))
  208. {
  209. // ICommFailureCode already set
  210. MyDebugPrint(pTG, LOG_ALL, "ATTENTION: GotRecvCaps pTG->ProtInst.fAbort = TRUE\n");
  211. pTG->ProtInst.fAbort = TRUE;
  212. }
  213. // This need to be moved into whatnext.NodeA so that we can set
  214. // param to FALSE (no sleep) and do the stall thing
  215. AwaitSendParamsAndDoNegot(pTG, TRUE);
  216. }
  217. void GotPollReq(PThrdGlbl pTG)
  218. {
  219. BG_CHK(pTG->ProtInst.fRecvdDTC);
  220. if(!pTG->ProtInst.llSendParams.fECM)
  221. {
  222. // if we can't do ECM on send, ignore the received NSFs
  223. // zap the ECM bits of the received DTC
  224. pTG->ProtInst.RemoteDTC.ECM = 0;
  225. pTG->ProtInst.RemoteDTC.SmallFrame = 0;
  226. }
  227. GotRecvFrames(pTG, ifrNSC, &pTG->ProtInst.RecvdNS,
  228. (pTG->ProtInst.fRecvdDTC ? &pTG->ProtInst.RemoteDTC : NULL),
  229. (pTG->ProtInst.fRecvdID ? pTG->ProtInst.bRemoteID : NULL),
  230. (pTG->ProtInst.fRecvdSUB ? pTG->ProtInst.bRecipSubAddr : NULL),
  231. RECV_POLLREQ, (NPBC)&pTG->ProtInst.RecvPollReq, sizeof(pTG->ProtInst.RecvPollReq),
  232. &pTG->ProtInst.llRecvCaps);
  233. pTG->ProtInst.fRecvPollReqGot = TRUE;
  234. pTG->ProtInst.fllRecvCapsGot = TRUE;
  235. // send off BC struct to higher level
  236. if(!ICommRecvPollReq(pTG, (LPBC)&pTG->ProtInst.RecvPollReq))
  237. {
  238. // ICommFailureCode already set
  239. MyDebugPrint(pTG, LOG_ALL, "ATTENTION: GetPollReq pTG->ProtInst.fAbort = TRUE\n");
  240. pTG->ProtInst.fAbort = TRUE;
  241. }
  242. //
  243. // This need to be moved into whatnext.NodeA so that we can set
  244. // param to FALSE (no sleep) and do the stall thing
  245. AwaitSendParamsAndDoNegot(pTG, TRUE);
  246. }
  247. void GotRecvParams(PThrdGlbl pTG)
  248. {
  249. GotRecvFrames(pTG, ifrNSS, &pTG->ProtInst.RecvdNS,
  250. (pTG->ProtInst.fRecvdDCS ? (&pTG->ProtInst.RemoteDCS) : NULL),
  251. (pTG->ProtInst.fRecvdID ? pTG->ProtInst.bRemoteID : NULL),
  252. (pTG->ProtInst.fRecvdSUB ? pTG->ProtInst.bRecipSubAddr : NULL),
  253. RECV_PARAMS, (NPBC)&pTG->ProtInst.RecvParams, sizeof(pTG->ProtInst.RecvParams),
  254. &pTG->ProtInst.llRecvParams);
  255. // If DCS has fECM set then we must've said we could do ECM
  256. BG_CHK(pTG->ProtInst.llRecvParams.fECM ? pTG->ProtInst.llSendCaps.fECM : 1);
  257. pTG->ProtInst.fRecvParamsGot = TRUE;
  258. pTG->ProtInst.fllRecvParamsGot = TRUE;
  259. if(!ICommRecvParams(pTG, (LPBC)&pTG->ProtInst.RecvParams)) {
  260. MyDebugPrint(pTG, LOG_ALL, "ATTENTION: GotRecvParams pTG->ProtInst.fAbort = TRUE\n");
  261. pTG->ProtInst.fAbort = TRUE;
  262. }
  263. ICommSetRecvMode(pTG, ProtReceivingECM(pTG));
  264. }