|
|
/***************************************************************************
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)); }
|