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

/***************************************************************************
Name : RECVFR.C
Comment :
Functions: (see Prototypes just below)
Copyright (c) 1993 Microsoft Corp.
Revision Log
Date Name Description
-------- ----- ---------------------------------------------------------
***************************************************************************/
#include "prep.h"
#include "efaxcb.h"
#include "protocol.h"
///RSL
#include "glbproto.h"
#define faxTlog(m) DEBUGMSG(ZONE_RECVFR, m)
#define FILEID FILEID_RECVFR
USHORT FindMSNSx(PThrdGlbl pTG, NPRFS npRecvd)
{
USHORT i;
for(i=0; i<npRecvd->uNumFrames; i++)
{
BG_CHK(i < MAXFRAMES);
if(IsAtWorkNSx(npRecvd->rglpfr[i]->fif, npRecvd->rglpfr[i]->cb))
{
faxTlog((SZMOD "Found MS NSx!!\r\n"));
return i+1;
}
}
return 0;
}
void GotRecvFrames(PThrdGlbl pTG, IFR ifr, NPRFS npRecvd, NPDIS npdis, LPBYTE lpbRecvdID,
LPBYTE lpbRecipSubAddr, BCTYPE bctype, NPBC npbc, USHORT wBCSize,
NPLLPARAMS npll)
{
USHORT uRet1=0, uRet2=0;
InitBC(npbc, wBCSize, bctype);
// RSL remove NSF processing.
uRet1 = 0;
if(npRecvd->uNumFrames) // recvd some NSXs
{
// scope out NSXs
if(uRet1) // RSL = FindMSNSx(pTG, npRecvd))
{
// found MS NSXs
BG_CHK((ifr!=ifrNSF) ? (pTG->ProtInst.llSendCaps.fECM && uRet1==1) : TRUE);
// if we got MS NSCs or NSSs then we must be able to do ECM
// and we can't get can't get other peoples NSSs/NSCs at same time
// setup BC first
npbc->bctype = bctype;
// all short ptrs into DGROUP get correctly cast to LPs we hope...
if(uRet2 = NSX_TO_BC(pTG, ifr, npRecvd->rglpfr, npRecvd->uNumFrames, npbc, wBCSize))
{
(MyDebugPrint(pTG, LOG_ERR, "<<ERROR>> got error %d parsing NSX\r\n", uRet2));
// forget we got an NSX
// zero out BC again
InitBC( npbc, wBCSize, bctype);
uRet1 = 0;
}
#ifndef NOCHALL
else
{
if(ifr==ifrNSF)
{
USHORT uChallLen;
// Poll challenge string is the first POLL_CHALLENGE_LEN
// bytes (following the B5 00 76 signature) of the first
// MS NSF _received_ or the whole thing if it is shorter
// than that
BG_CHK(npRecvd->rglpfr[uRet1-1]->cb > 3);
uChallLen = min(npRecvd->rglpfr[uRet1-1]->cb-3, POLL_CHALLENGE_LEN);
AppendToBCLen( npbc, wBCSize, npRecvd->rglpfr[uRet1-1]->fif+3,
uChallLen, wChallenge, wChallengeLen);
}
else if(ifr==ifrNSC)
{
// for NSC append _our_ challenge string, i.e.
// first POLL_CHALLENGE_LEN bytes (following the B5 00 76
// signature) of the first MS NSF that _we_sent_out
// or the whole thing if it is shorter than that
AppendToBCLen(npbc, wBCSize, pTG->bSavedChallenge,
pTG->uSavedChallengeLen, wChallenge, wChallengeLen);
}
// for NSS wChallenge==NULL
}
#endif //!NOCHALL
}
#ifdef OEMNSF
else if(wOEMFlags && lpfnOEMNSxToBC)
{
#pragma message("WARNING: OEMNsxToBC: The code here for removing and restoring the FCS bytes hasn't been tested!!!")
USHORT uRet3;
USHORT iFrame;
// OEM NSX DLL exists --> do something for(iFrame=0; iFrame<wNumFrame; iFrame++)
for(iFrame=0; iFrame < npRecvd->uNumFrames; iFrame++)
npRecvd->rglpfr[iFrame]->cb -= 2; // Subtract 2 to lop off the FCS
if(!(uRet3 = lpfnOEMNSxToBC(ifr, npRecvd->rglpfr, npRecvd->uNumFrames, npbc, wBCSize, npll)))
{
//It might be a modem that doesn't pass us the FCS, try again
for(iFrame=0; iFrame < npRecvd->uNumFrames; iFrame++)
npRecvd->rglpfr[iFrame]->cb += 2; // Put last two bytes back on
// zero out BC again
InitBC(pTG, npbc, wBCSize, bctype);
if(!(uRet3 = lpfnOEMNSxToBC(ifr, npRecvd->rglpfr, npRecvd->uNumFrames, npbc, wBCSize, npll)))
{
(MyDebugPrint(pTG, LOG_ERR, "<<ERROR>> got error parsing OEM NSF\r\n"));
// zero out BC again
InitBC(pTG, npbc, wBCSize, bctype);
}
}
else
{
faxTlog((SZMOD "Using OEM Protocol\r\n"));
fUsingOEMProt = TRUE;
if(uRet3 & OEMNSF_IGNORE_DIS)
npdis = NULL;
if(uRet3 & OEMNSF_IGNORE_CSI)
lpbRecvdID = NULL;
}
}
#endif
}
if(npdis)
{
// extract DIS caps into BC and LL
ParseDISorDCSorDTC(pTG, npdis, &(npbc->Fax), npll, (ifr==ifrNSS ? TRUE : FALSE));
}
// If an ID is recvd in NSF/NSS/NSC the CSI/TSI/CIG should NOT overwrite it
if(lpbRecvdID && !HasTextId(npbc))
{
PutTextId(npbc, wBCSize, lpbRecvdID, (int)_fstrlen(lpbRecvdID), TEXTCODE_ASCII);
//PutNumId(npbc, wBCSize, lpbRecvdID, (int) _fstrlen(lpbRecvdID), TEXTCODE_ASCII);
}
// If a subaddress is recvd in NSF/NSS/NSC the SUB frame should NOT overwrite it
if(lpbRecipSubAddr && !HasRecipSubAddr( npbc))
{
PutRecipSubAddr( npbc, wBCSize, lpbRecipSubAddr, (int)_fstrlen(lpbRecipSubAddr));
}
if(uRet1 > 0)
{
npll->fECM = TRUE; // ignore ECM bit in DIS, if MS NSF present
}
}
BOOL AwaitSendParamsAndDoNegot(PThrdGlbl pTG, BOOL fSleep)
{
// This does actual negotiation & gets SENDPARAMS. It could potentially
// return SEND_POLLREQ instead.
if(!ProtGetBC(pTG, SEND_PARAMS, fSleep))
{
if(fSleep)
{
// ICommFailureCode already set
MyDebugPrint(pTG, LOG_ALL, "ATTENTION: AwaitSendParamsAndDoNegot pTG->ProtInst.fAbort = TRUE\n");
pTG->ProtInst.fAbort = TRUE;
}
return FALSE;
}
// negotiate low-level params here. (a) because this is where
// high-level params are negotiated (b) because it's inefficient to
// do it on each DCS (c) because RTN breaks otherwise--see bug#731
// llRecvCaps and llSendParams are set only at startup
// SendParams are set in ProtGetBC just above
// llNegot is the return value. So this can be called
// only at the end of this function
// negot lowlevel params if we are sending and not polling
if(!pTG->ProtInst.fAbort && pTG->ProtInst.fSendParamsInited)
{
NegotiateLowLevelParams(pTG, &pTG->ProtInst.llRecvCaps, &pTG->ProtInst.llSendParams,
pTG->ProtInst.SendParams.Fax.AwRes,
pTG->ProtInst.SendParams.Fax.Encoding,
&pTG->ProtInst.llNegot);
pTG->ProtInst.fllNegotiated = TRUE;
// This chnages llNegot->Baud according to the MaxSpeed settings
EnforceMaxSpeed(pTG);
}
return TRUE;
}
void GotRecvCaps(PThrdGlbl pTG)
{
BG_CHK(pTG->ProtInst.fRecvdDIS);
if(!pTG->ProtInst.llSendParams.fECM)
{
// if we can't do ECM on send, ignore the received NSFs
// zap the ECM bits of the received DTC
pTG->ProtInst.RemoteDIS.ECM = 0;
pTG->ProtInst.RemoteDIS.SmallFrame = 0;
}
GotRecvFrames(pTG, ifrNSF, &pTG->ProtInst.RecvdNS,
(pTG->ProtInst.fRecvdDIS ? &pTG->ProtInst.RemoteDIS : NULL),
(pTG->ProtInst.fRecvdID ? pTG->ProtInst.bRemoteID : NULL),
(pTG->ProtInst.fRecvdSUB ? pTG->ProtInst.bRecipSubAddr : NULL),
RECV_CAPS, (NPBC)&pTG->ProtInst.RecvCaps, sizeof(pTG->ProtInst.RecvCaps),
&pTG->ProtInst.llRecvCaps);
pTG->ProtInst.fRecvCapsGot = TRUE;
pTG->ProtInst.fllRecvCapsGot = TRUE;
#ifdef FILET30
// Send up raw caps.
ICommRawCaps(
pTG,
(LPBYTE) (pTG->ProtInst.fRecvdID ? pTG->ProtInst.bRemoteID: NULL),
(LPBYTE) (pTG->ProtInst.fRecvdDIS ? (LPBYTE) (&(pTG->ProtInst.RemoteDIS)):NULL),
(USHORT) (pTG->ProtInst.fRecvdDIS ? pTG->ProtInst.uRemoteDISlen:0),
(LPFR FAR *) (pTG->ProtInst.RecvdNS.uNumFrames ? pTG->ProtInst.RecvdNS.rglpfr:NULL),
(USHORT) (pTG->ProtInst.RecvdNS.uNumFrames)
);
#endif
// send off BC struct to higher level
if(!ICommRecvCaps(pTG, (LPBC)&pTG->ProtInst.RecvCaps))
{
// ICommFailureCode already set
MyDebugPrint(pTG, LOG_ALL, "ATTENTION: GotRecvCaps pTG->ProtInst.fAbort = TRUE\n");
pTG->ProtInst.fAbort = TRUE;
}
// This need to be moved into whatnext.NodeA so that we can set
// param to FALSE (no sleep) and do the stall thing
AwaitSendParamsAndDoNegot(pTG, TRUE);
}
void GotPollReq(PThrdGlbl pTG)
{
BG_CHK(pTG->ProtInst.fRecvdDTC);
if(!pTG->ProtInst.llSendParams.fECM)
{
// if we can't do ECM on send, ignore the received NSFs
// zap the ECM bits of the received DTC
pTG->ProtInst.RemoteDTC.ECM = 0;
pTG->ProtInst.RemoteDTC.SmallFrame = 0;
}
GotRecvFrames(pTG, ifrNSC, &pTG->ProtInst.RecvdNS,
(pTG->ProtInst.fRecvdDTC ? &pTG->ProtInst.RemoteDTC : NULL),
(pTG->ProtInst.fRecvdID ? pTG->ProtInst.bRemoteID : NULL),
(pTG->ProtInst.fRecvdSUB ? pTG->ProtInst.bRecipSubAddr : NULL),
RECV_POLLREQ, (NPBC)&pTG->ProtInst.RecvPollReq, sizeof(pTG->ProtInst.RecvPollReq),
&pTG->ProtInst.llRecvCaps);
pTG->ProtInst.fRecvPollReqGot = TRUE;
pTG->ProtInst.fllRecvCapsGot = TRUE;
// send off BC struct to higher level
if(!ICommRecvPollReq(pTG, (LPBC)&pTG->ProtInst.RecvPollReq))
{
// ICommFailureCode already set
MyDebugPrint(pTG, LOG_ALL, "ATTENTION: GetPollReq pTG->ProtInst.fAbort = TRUE\n");
pTG->ProtInst.fAbort = TRUE;
}
//
// This need to be moved into whatnext.NodeA so that we can set
// param to FALSE (no sleep) and do the stall thing
AwaitSendParamsAndDoNegot(pTG, TRUE);
}
void GotRecvParams(PThrdGlbl pTG)
{
GotRecvFrames(pTG, ifrNSS, &pTG->ProtInst.RecvdNS,
(pTG->ProtInst.fRecvdDCS ? (&pTG->ProtInst.RemoteDCS) : NULL),
(pTG->ProtInst.fRecvdID ? pTG->ProtInst.bRemoteID : NULL),
(pTG->ProtInst.fRecvdSUB ? pTG->ProtInst.bRecipSubAddr : NULL),
RECV_PARAMS, (NPBC)&pTG->ProtInst.RecvParams, sizeof(pTG->ProtInst.RecvParams),
&pTG->ProtInst.llRecvParams);
// If DCS has fECM set then we must've said we could do ECM
BG_CHK(pTG->ProtInst.llRecvParams.fECM ? pTG->ProtInst.llSendCaps.fECM : 1);
pTG->ProtInst.fRecvParamsGot = TRUE;
pTG->ProtInst.fllRecvParamsGot = TRUE;
if(!ICommRecvParams(pTG, (LPBC)&pTG->ProtInst.RecvParams)) {
MyDebugPrint(pTG, LOG_ALL, "ATTENTION: GotRecvParams pTG->ProtInst.fAbort = TRUE\n");
pTG->ProtInst.fAbort = TRUE;
}
ICommSetRecvMode(pTG, ProtReceivingECM(pTG));
}