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.
689 lines
21 KiB
689 lines
21 KiB
|
|
/***************************************************************************
|
|
Name : DIS.C
|
|
Comment : Collection if DIS/DCS/DTC and CSI/TSI/CIG mangling routines.
|
|
They manipulate the DIS struct whose members correspond to the bits
|
|
of the T30 DIS/DCS/DTC frames.
|
|
|
|
Copyright (c) 1993 Microsoft Corp.
|
|
|
|
Revision Log
|
|
Date Name Description
|
|
-------- ----- ---------------------------------------------------------
|
|
***************************************************************************/
|
|
#define USE_DEBUG_CONTEXT DEBUG_CONTEXT_T30_MAIN
|
|
|
|
#include "prep.h"
|
|
|
|
|
|
#include "protocol.h"
|
|
|
|
///RSL
|
|
#include "glbproto.h"
|
|
|
|
USHORT SetupDISorDCSorDTC
|
|
(
|
|
PThrdGlbl pTG,
|
|
NPDIS npdis,
|
|
NPBCFAX npbcFax,
|
|
NPLLPARAMS npll
|
|
)
|
|
{
|
|
// return length of DIS
|
|
|
|
USHORT uLen;
|
|
|
|
DEBUG_FUNCTION_NAME(_T("SetupDISorDCSorDTC"));
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"baud=0x%02x min=0x%02x res=0x%02x code=0x%02x"
|
|
" wide=0x%02x len=0x%02x",
|
|
npll->Baud, npll->MinScan,
|
|
(WORD)npbcFax->AwRes, npbcFax->Encoding,
|
|
npbcFax->PageWidth, npbcFax->PageLength);
|
|
|
|
_fmemset(npdis, 0, sizeof(DIS));
|
|
|
|
// npdis->G1stuff = 0;
|
|
// npdis->G2stuff = 0;
|
|
npdis->G3Rx = 1; // always ON for DIS & DCS. Indicates T.4 recv Cap/Mode
|
|
npdis->G3Tx = (BYTE) (npbcFax->fPublicPoll);
|
|
// This must be 0 for a DCS frame. The Omnifax G77 and GT choke on it!
|
|
|
|
npdis->Baud = npll->Baud;
|
|
|
|
npdis->MR_2D = ((npbcFax->Encoding & MR_DATA) != 0);
|
|
|
|
npdis->MMR = ((npbcFax->Encoding & MMR_DATA) != 0);
|
|
// npdis->MR_2D = 0;
|
|
// npdis->MMR = 0;
|
|
|
|
npdis->PageWidth = (BYTE) (npbcFax->PageWidth);
|
|
npdis->PageLength = (BYTE) (npbcFax->PageLength);
|
|
npdis->MinScanCode = npll->MinScan;
|
|
|
|
// npdis->Uncompressed = npdis->ELM = 0;
|
|
|
|
// we do not support ECM
|
|
npdis->ECM = 0;
|
|
npdis->SmallFrame = 0;
|
|
|
|
|
|
if (npbcFax->PageWidth > WIDTH_MAX)
|
|
{
|
|
npdis->WidthInvalid = TRUE;
|
|
npdis->Width2 = (npbcFax->PageWidth>>WIDTH_SHIFT);
|
|
}
|
|
|
|
// doesn't hold for SendParams (why??)
|
|
npdis->Res_300 = 0; // RSL ((npbcFax->AwRes & AWRES_300_300) != 0);
|
|
npdis->Res8x15 = ((npbcFax->AwRes & AWRES_mm080_154) != 0);
|
|
|
|
|
|
if (! pTG->SrcHiRes)
|
|
{
|
|
npdis->ResFine_200 = 0;
|
|
}
|
|
else
|
|
{
|
|
npdis->ResFine_200 = ((npbcFax->AwRes & (AWRES_mm080_077|AWRES_200_200)) != 0);
|
|
}
|
|
|
|
npdis->Res16x15_400 = ((npbcFax->AwRes & (AWRES_mm160_154|AWRES_400_400)) != 0);
|
|
npdis->ResInchBased = ((npbcFax->AwRes & (AWRES_200_200|AWRES_400_400)) != 0);
|
|
npdis->ResMetricBased = ((npbcFax->AwRes & AWRES_mm160_154) ||
|
|
((npbcFax->AwRes & AWRES_mm080_077) && npdis->ResInchBased));
|
|
|
|
npdis->MinScanSuperHalf = ((npll->MinScan & MINSCAN_SUPER_HALF) != 0);
|
|
|
|
npdis->Extend24 = npdis->Extend32 = npdis->Extend40 = 0;
|
|
uLen = 3;
|
|
|
|
DebugPrintEx(DEBUG_MSG,"DIS len = %d", uLen);
|
|
return uLen;
|
|
}
|
|
|
|
|
|
void ParseDISorDCSorDTC
|
|
(
|
|
PThrdGlbl pTG,
|
|
NPDIS npDIS,
|
|
NPBCFAX npbcFax,
|
|
NPLLPARAMS npll,
|
|
BOOL fParams
|
|
)
|
|
{
|
|
///////////////////////////////////////////////////////////////
|
|
// Prepare to get trash (upto 2 bytes) at end of every frame //
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
LPB npb, npbLim;
|
|
|
|
DEBUG_FUNCTION_NAME(_T("ParseDISorDCSorDTC"));
|
|
// first make sure DIS is clean. We may have picked up some trailing CRCs
|
|
// trailing-trash removed by reading the Extend bits
|
|
|
|
npb = npbLim = (LPB)npDIS;
|
|
npbLim += sizeof(DIS);
|
|
for(npb+=2; npb<npbLim && (*npb & 0x80); npb++);
|
|
// exits when npb points past end of structure or
|
|
// points to the first byte with the high bit NOT set
|
|
// i.e. the last VALID byte
|
|
|
|
for(npb++; npb<npbLim; npb++)
|
|
*npb = 0;
|
|
// starting with the byte AFTER the last valid byte, until end
|
|
// of the structure, zap all bytes to zero
|
|
|
|
// parse high level params into NPI
|
|
|
|
memset(npbcFax, 0, sizeof(BCFAX));
|
|
|
|
npbcFax->AwRes = 0;
|
|
npbcFax->Encoding = 0;
|
|
|
|
// Resolution
|
|
if(npDIS->Res8x15)
|
|
npbcFax->AwRes |= AWRES_mm080_154;
|
|
|
|
if(npDIS->Res_300)
|
|
npbcFax->AwRes |= AWRES_300_300;
|
|
|
|
if(npDIS->ResInchBased)
|
|
{
|
|
if(npDIS->ResFine_200)
|
|
npbcFax->AwRes |= AWRES_200_200;
|
|
|
|
if(npDIS->Res16x15_400)
|
|
npbcFax->AwRes |= AWRES_400_400;
|
|
}
|
|
if(npDIS->ResMetricBased || !npDIS->ResInchBased)
|
|
{
|
|
if(npDIS->ResFine_200)
|
|
npbcFax->AwRes |= AWRES_mm080_077;
|
|
|
|
if(npDIS->Res16x15_400)
|
|
npbcFax->AwRes |= AWRES_mm160_154;
|
|
}
|
|
|
|
// Encoding (MMR only if ECM also supported)
|
|
if(npDIS->MR_2D)
|
|
npbcFax->Encoding |= MR_DATA;
|
|
|
|
if(npDIS->MMR && npDIS->ECM)
|
|
npbcFax->Encoding |= MMR_DATA;
|
|
|
|
if(!fParams)
|
|
{
|
|
// setting up capabilities -- add the "always present" caps
|
|
npbcFax->AwRes |= AWRES_mm080_038;
|
|
npbcFax->Encoding |= MH_DATA;
|
|
}
|
|
else
|
|
{
|
|
// setting up params -- set the defaults if none otehr specified
|
|
if(!npbcFax->AwRes)
|
|
npbcFax->AwRes = AWRES_mm080_038;
|
|
|
|
if(!npbcFax->Encoding)
|
|
npbcFax->Encoding = MH_DATA;
|
|
|
|
// if both MR & MMR are set (this happens with Ricoh's fax simulator!)
|
|
// then set just MMR. MH doesnt have an explicit bit, so we set MH
|
|
// here only if nothing else is set. So the only multiple-setting case
|
|
// (for encodings) that we can encounter is (MR|MMR). BUG#6950
|
|
if(npbcFax->Encoding == (MR_DATA|MMR_DATA))
|
|
npbcFax->Encoding = MMR_DATA;
|
|
}
|
|
|
|
// PageWidth and Length
|
|
npbcFax->PageWidth = npDIS->PageWidth;
|
|
|
|
// IFAX Bug#8152: Hack for interpreting invalid value (1,1) as
|
|
// A3, because some fax machines do that. This is
|
|
// as per Note 7 of Table 2/T.30 of ITU-T.30 (1992, page 40).
|
|
#define WIDTH_ILLEGAL_A3 0x3
|
|
if (!fParams && npbcFax->PageWidth==WIDTH_ILLEGAL_A3)
|
|
{
|
|
npbcFax->PageWidth=WIDTH_A3;
|
|
}
|
|
npbcFax->PageLength = npDIS->PageLength;
|
|
|
|
// has G3 file available for polling
|
|
npbcFax->fPublicPoll = npDIS->G3Tx;
|
|
|
|
|
|
// Now low level params LLPARAMS
|
|
// Baudrate and MinScan. That's it!
|
|
|
|
npll->Baud = npDIS->Baud;
|
|
npll->MinScan = npDIS->MinScanCode;
|
|
if(npDIS->MinScanSuperHalf)
|
|
npll->MinScan |= MINSCAN_SUPER_HALF;
|
|
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"baud=0x%02x min=0x%02x res=0x%02x code=0x%02x"
|
|
" wide=0x%02x len=0x%02x",
|
|
npll->Baud, npll->MinScan,
|
|
(WORD)npbcFax->AwRes, npbcFax->Encoding,
|
|
npbcFax->PageWidth, npbcFax->PageLength);
|
|
}
|
|
|
|
|
|
/* Converts the code for a speed to the speed in BPS */
|
|
|
|
UWORD CodeToBPS[16] =
|
|
{
|
|
/* V27_2400 0 */ 2400,
|
|
/* V29_9600 1 */ 9600,
|
|
/* V27_4800 2 */ 4800,
|
|
/* V29_7200 3 */ 7200,
|
|
/* V33_14400 4 */ 14400,
|
|
0,
|
|
/* V33_12000 6 */ 12000,
|
|
0,
|
|
/* V17_14400 8 */ 14400,
|
|
/* V17_9600 9 */ 9600,
|
|
/* V17_12000 10 */ 12000,
|
|
/* V17_7200 11 */ 7200,
|
|
0,
|
|
0,
|
|
0,
|
|
0
|
|
};
|
|
|
|
|
|
#define msBAD 255
|
|
|
|
/* Converts a DCS min-scan field code into millisecs */
|
|
BYTE msPerLine[8] = { 20, 5, 10, msBAD, 40, msBAD, msBAD, 0 };
|
|
|
|
|
|
USHORT MinScanToBytesPerLine(PThrdGlbl pTG, BYTE MinScan, BYTE Baud)
|
|
{
|
|
USHORT uStuff;
|
|
BYTE ms;
|
|
|
|
uStuff = CodeToBPS[Baud];
|
|
ms = msPerLine[MinScan];
|
|
uStuff /= 100; // StuffBytes = (BPS * ms)/8000
|
|
uStuff *= ms; // take care not to use longs
|
|
uStuff /= 80; // or overflow WORD or lose precision
|
|
uStuff += 1; // Rough fix for truncation problems
|
|
|
|
return uStuff;
|
|
}
|
|
|
|
#define ms40 4
|
|
#define ms20 0
|
|
#define ms10 2
|
|
#define ms5 1
|
|
#define ms0 7
|
|
|
|
/* first index is a DIS min-scan capability. 2nd is 0 for normal
|
|
* 1 for fine (1/2) and 2 for super-fine (if 1/2 yet again).
|
|
* Output is the Code to stick in the DCS.
|
|
*/
|
|
|
|
BYTE MinScanTab[8][3] =
|
|
{
|
|
ms20, ms20, ms10,
|
|
ms5, ms5, ms5,
|
|
ms10, ms10, ms5,
|
|
ms20, ms10, ms5,
|
|
ms40, ms40, ms20,
|
|
ms40, ms20, ms10,
|
|
ms10, ms5, ms5,
|
|
ms0, ms0, ms0
|
|
};
|
|
|
|
|
|
#define V_ILLEGAL 255
|
|
|
|
#define V27_2400 0
|
|
#define V27_4800 2
|
|
#define V29_9600 1
|
|
#define V29_7200 3
|
|
#define V33_14400 4
|
|
#define V33_12000 6
|
|
#define V17_14400 8
|
|
#define V17_12000 10
|
|
#define V17_9600 9
|
|
#define V17_7200 11
|
|
|
|
#define V27_SLOW 0
|
|
#define V27_ONLY 2
|
|
#define V29_ONLY 1
|
|
#define V33_ONLY 4
|
|
#define V17_ONLY 8
|
|
#define V27_V29 3
|
|
#define V27_V29_V33 7
|
|
#define V27_V29_V33_V17 11
|
|
#define V_ALL 15
|
|
|
|
/* Converts a capability into the best speed it offers.
|
|
* index will usually be the & of both DIS's Baud rate fields
|
|
* (both having first been "adjusted", i.e. 11 changed to 15)
|
|
* Output is the Code to stick in the DCS.
|
|
*/
|
|
|
|
BYTE BaudNegTab[16] =
|
|
{
|
|
/* V27_SLOW 0 --> 0 */ V27_2400,
|
|
/* V29_ONLY 1 --> 1 */ V29_9600,
|
|
/* V27_ONLY 2 --> 2 */ V27_4800,
|
|
/* V27_V29 3 --> 1 */ V29_9600,
|
|
V_ILLEGAL,
|
|
V_ILLEGAL,
|
|
V_ILLEGAL,
|
|
/* V27_V29_V33 7 --> 4 */ V33_14400,
|
|
V_ILLEGAL,
|
|
V_ILLEGAL,
|
|
V_ILLEGAL,
|
|
/* V27_V29_V33_V17 11 --> 8 */ V17_14400,
|
|
V_ILLEGAL,
|
|
V_ILLEGAL,
|
|
V_ILLEGAL,
|
|
/* V_ALL 15 --> 8 */ V17_14400
|
|
};
|
|
|
|
/***************************************************************************
|
|
Name : NegotiateLowLevelParams
|
|
Purpose : Takes a received DIS and optionally MS NSF,
|
|
our HW caps and
|
|
|
|
picks highest common baud rate, ECM is picked if both have it
|
|
ECM frame size is 256 unless remote DIS has that bit set to 1
|
|
or we want small frames (compiled-in option).
|
|
|
|
The MinScan time is set to the max.
|
|
(i.e. highest/slowest) of both.
|
|
|
|
Fill results in Negot section of npProt
|
|
|
|
CalledFrom: NegotiateLowLevelParams is called by the sender when a DIS
|
|
and/or NSF is received.
|
|
***************************************************************************/
|
|
|
|
|
|
void NegotiateLowLevelParams
|
|
(
|
|
PThrdGlbl pTG,
|
|
NPLLPARAMS npllRecv,
|
|
NPLLPARAMS npllSend,
|
|
DWORD AwRes,
|
|
USHORT uEnc,
|
|
NPLLPARAMS npllNegot
|
|
)
|
|
{
|
|
USHORT Baud, Baud1, Baud2;
|
|
USHORT MinScanCode, col;
|
|
|
|
DEBUG_FUNCTION_NAME(_T("NegotiateLowLevelParams"));
|
|
////// negotiate Baudrate, ECM, ECM frame size, and MinScan. That's it!
|
|
|
|
Baud1 = npllRecv->Baud;
|
|
Baud2 = npllSend->Baud;
|
|
if(Baud1 == 11)
|
|
Baud1=15;
|
|
|
|
if(Baud2 == 11)
|
|
Baud2=15;
|
|
|
|
Baud = Baud1 & Baud2;
|
|
npllNegot->Baud = BaudNegTab[Baud];
|
|
if (npllNegot->Baud == V_ILLEGAL)
|
|
{
|
|
// this is a case in which the remote side sent us an invalid param
|
|
// as the input supported baud rate and modulation.
|
|
// since we haven't sent out the DCS yet, we'll try to go with V.29 9600
|
|
// and send this DCS, if the remote side does not support this
|
|
// let it disconnect, anyways it violated the protocol.
|
|
npllNegot->Baud = V29_9600;
|
|
DebugPrintEx(DEBUG_ERR,"Remote side violates protocol (%d), default to V.29 9600",npllRecv->Baud);
|
|
}
|
|
// there is always some common baud rate (i.e. at least 2400 mandatory)
|
|
|
|
|
|
/* Minimum Scan line times. Only Receiver's pref matters.
|
|
* Use teh table above to convert from Receiver's DIS to the
|
|
* required DCS. Col 1 is used if vertical res. is normal (100dpi)
|
|
* Col2 if VR is 200 or 300dpi, (OR if VR is 400dpi, but Bit 46
|
|
* is not set), and Col3 is used if VR is 400dpi *and* Bit 46
|
|
* (MinScanSuperHalf) is set
|
|
*/
|
|
|
|
{
|
|
MinScanCode = (npllRecv->MinScan & 0x07); // low 3 bits
|
|
|
|
if(AwRes & (AWRES_mm080_154|AWRES_mm160_154|AWRES_400_400))
|
|
{
|
|
if(npllRecv->MinScan & MINSCAN_SUPER_HALF)
|
|
col = 2;
|
|
else
|
|
col = 1;
|
|
}
|
|
// T30 says scan time for 300dpi & 200dpi is the same
|
|
else if(AwRes & (AWRES_300_300|AWRES_mm080_077|AWRES_200_200))
|
|
col = 1;
|
|
else
|
|
col = 0;
|
|
|
|
npllNegot->MinScan = MinScanTab[MinScanCode][col];
|
|
}
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"baud=0x%02x min=0x%02x",
|
|
npllNegot->Baud, npllNegot->MinScan);
|
|
}
|
|
|
|
|
|
USHORT GetReversedFIFs
|
|
(
|
|
IN PThrdGlbl pTG,
|
|
IN LPCSTR lpstrSource,
|
|
OUT LPSTR lpstrDest,
|
|
IN UINT cch
|
|
)
|
|
{
|
|
/** Both args always 20 bytes long. Throws away leading & trailing
|
|
blanks, then copies what's left *reversed* into lpstr[].
|
|
Terminates with 0.
|
|
**/
|
|
|
|
int i, j, k;
|
|
|
|
DEBUG_FUNCTION_NAME(_T("GetReversedFIFs"));
|
|
|
|
if (strlen(lpstrSource)>=cch)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Output buffer is too short to create reverse FIF");
|
|
return 0;
|
|
}
|
|
|
|
if (strlen(lpstrSource)>IDFIFSIZE)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Source buffer is too long to create reverse FIF");
|
|
return 0;
|
|
}
|
|
|
|
for(k=0; k<IDFIFSIZE && lpstrSource[k]==' '; k++); // k==first nonblank or 20
|
|
|
|
for(j=IDFIFSIZE-1; j>=k && lpstrSource[j]==' '; j--); // j==last nonblank or -1
|
|
|
|
i = 0;
|
|
|
|
for( ; i<IDFIFSIZE && j>=k; i++, j--)
|
|
lpstrDest[i] = lpstrSource[j];
|
|
|
|
lpstrDest[i] = 0;
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"Got<%s> produced<%s>",
|
|
(LPSTR)lpstrSource, (LPSTR)lpstrDest);
|
|
|
|
return (USHORT)i;
|
|
}
|
|
|
|
void CreateStupidReversedFIFs(PThrdGlbl pTG, LPSTR lpstr1, LPSTR lpstr2)
|
|
{
|
|
/** Both args always 20 bytes long. Copies LPSTR *reversed* into
|
|
the end of lpstr1[], then pads rest with blank.
|
|
Terminates with a 0
|
|
**/
|
|
|
|
int i, j;
|
|
|
|
for(i=0, j=IDFIFSIZE-1; lpstr2[i] && j>=0; i++, j--)
|
|
lpstr1[j] = lpstr2[i];
|
|
|
|
if(j>=0)
|
|
_fmemset(lpstr1, ' ', j+1);
|
|
|
|
lpstr1[IDFIFSIZE] = 0;
|
|
|
|
}
|
|
|
|
|
|
/* Converts a the code for a speed to the code fro the next
|
|
* best (lower) speed. order is
|
|
(V17: 144-120-96-72-V27_2400) (V33: 144 120 V29: 96 72 V27: 48 24)
|
|
*/
|
|
// NOTE: FRANCE defines the fallback sequence to go from V17_7200 to V27_4800
|
|
|
|
|
|
|
|
|
|
BYTE DropBaudTab[16] =
|
|
{
|
|
/* V27_2400 --> X 0 --> X */ V_ILLEGAL,
|
|
/* V29_9600 --> V29_7200 1 --> 3 */ V29_7200,
|
|
/* V27_4800 --> V27_2400 2 --> 0 */ V27_2400,
|
|
/* V29_7200 --> V27_4800 3 --> 2 */ V27_4800,
|
|
/* V33_14400 -> V33_12000 4 --> 6 */ V33_12000,
|
|
V_ILLEGAL,
|
|
/* V33_12000 -> V29_9600 6 --> 1 */ V29_9600,
|
|
V_ILLEGAL,
|
|
/* V17_14400 -> V17_12000 8 -> 10 */ V17_12000,
|
|
/* V17_9600 --> V17_7200 9 -> 11 */ V17_7200,
|
|
/* V17_12000 -> V17_9600 10 -> 9 */ V17_9600,
|
|
/* V17_7200 --> V29_9600 11 -> 1
|
|
or V29_7200 11 -> 3
|
|
USE THIS---> or V27_4800 11 -> 2
|
|
or V27_2400 11 -> 0 */ V27_4800,
|
|
V_ILLEGAL,
|
|
V_ILLEGAL,
|
|
V_ILLEGAL,
|
|
V_ILLEGAL
|
|
};
|
|
|
|
BOOL DropSendSpeed(PThrdGlbl pTG)
|
|
{
|
|
USHORT uSpeed;
|
|
UWORD uBps;
|
|
|
|
DEBUG_FUNCTION_NAME(_T("DropSendSpeed"));
|
|
if ((pTG->ProtInst.llNegot.Baud==V_ILLEGAL) || (pTG->ProtInst.llNegot.Baud>15))
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"Illegal input speed to DropSendSpeed %d",
|
|
pTG->ProtInst.llNegot.Baud);
|
|
return FALSE;
|
|
}
|
|
|
|
uSpeed = DropBaudTab[pTG->ProtInst.llNegot.Baud];
|
|
uBps = CodeToBPS[uSpeed];
|
|
// enforce LowestSendSpeed
|
|
if ( (uSpeed == V_ILLEGAL) ||
|
|
( (pTG->ProtInst.LowestSendSpeed <= 14400) &&
|
|
(uBps < pTG->ProtInst.LowestSendSpeed)
|
|
)
|
|
)
|
|
{
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"Can't drop (0x%02x)",
|
|
pTG->ProtInst.llNegot.Baud);
|
|
return FALSE;
|
|
// speed remains same as before if lowest speed
|
|
// return FALSE to hangup
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx(DEBUG_MSG,"Now at 0x%02x", uSpeed);
|
|
pTG->ProtInst.llNegot.Baud = (BYTE) uSpeed;
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
void EnforceMaxSpeed(PThrdGlbl pTG)
|
|
{
|
|
DEBUG_FUNCTION_NAME(_T("EnforceMaxSpeed"));
|
|
|
|
// enforce HighestSendSpeed setting
|
|
if( pTG->ProtInst.HighestSendSpeed && pTG->ProtInst.HighestSendSpeed >= 2400 &&
|
|
pTG->ProtInst.HighestSendSpeed >= pTG->ProtInst.LowestSendSpeed)
|
|
{
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"MaxSend=%d. Baud=%x BPS=%d, dropping",
|
|
pTG->ProtInst.HighestSendSpeed,
|
|
pTG->ProtInst.llNegot.Baud,
|
|
CodeToBPS[pTG->ProtInst.llNegot.Baud]);
|
|
|
|
while(CodeToBPS[pTG->ProtInst.llNegot.Baud] > pTG->ProtInst.HighestSendSpeed)
|
|
{
|
|
if(!DropSendSpeed(pTG))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"MaxSend=%d. Baud=%x BPS=%d",
|
|
pTG->ProtInst.HighestSendSpeed,
|
|
pTG->ProtInst.llNegot.Baud,
|
|
CodeToBPS[pTG->ProtInst.llNegot.Baud]);
|
|
}
|
|
}
|
|
|
|
USHORT CopyFrame(PThrdGlbl pTG, LPBYTE lpbDst, LPFR lpfr, USHORT uSize)
|
|
{
|
|
///////////////////////////////////////////////////////////////
|
|
// Prepare to get trash (upto 2 bytes) at end of every frame //
|
|
///////////////////////////////////////////////////////////////
|
|
USHORT uDstLen;
|
|
|
|
uDstLen = min(uSize, lpfr->cb);
|
|
_fmemset(lpbDst, 0, uSize);
|
|
_fmemcpy(lpbDst, lpfr->fif, uDstLen);
|
|
return uDstLen;
|
|
}
|
|
|
|
void CopyRevIDFrame
|
|
(
|
|
IN PThrdGlbl pTG,
|
|
OUT LPBYTE lpbDst,
|
|
IN LPFR lpfr,
|
|
IN UINT cb
|
|
)
|
|
{
|
|
///////////////////////////////////////////////////////////////
|
|
// Prepare to get trash (upto 2 bytes) at end of every frame //
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
USHORT uDstLen;
|
|
char szTemp[IDFIFSIZE+2];
|
|
|
|
DEBUG_FUNCTION_NAME(_T("CopyRevIDFrame"));
|
|
|
|
uDstLen = min(IDFIFSIZE, lpfr->cb);
|
|
_fmemset(szTemp, ' ', IDFIFSIZE); // fill spaces (reqd by GetReverse)
|
|
_fmemcpy(szTemp, lpfr->fif, uDstLen);
|
|
szTemp[IDFIFSIZE] = 0; // zero-terminate
|
|
|
|
GetReversedFIFs(pTG, szTemp, lpbDst, cb);
|
|
|
|
if(uDstLen!=IDFIFSIZE)
|
|
DebugPrintEx(DEBUG_ERR, "Bad ID frame" );
|
|
}
|
|
|
|
// This function check whether the parameters in recvdDCS are valids by checking the
|
|
// DCS we got given the DIS we send to transmitter
|
|
BOOL AreDCSParametersOKforDIS(LPDIS sendDIS, LPDIS recvdDCS)
|
|
{
|
|
// FYI: The DCS is save in pTG->ProtInst->RemoteDCS
|
|
// While we save our DIS in pTG->ProtInst->LocalDIS
|
|
// This will solve bug #4677: "Fax: T.30: service does not receive simple 1 page fax, using ECM"
|
|
if (sendDIS->ECM != recvdDCS->ECM)
|
|
{
|
|
return FALSE;
|
|
}
|
|
switch(sendDIS->PageWidth)
|
|
{
|
|
case 0: // This means: ONLY 1728 dots
|
|
if (recvdDCS->PageWidth != 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
case 1: // This means: 1728 or 2048
|
|
if ((recvdDCS->PageWidth != 0) && (recvdDCS->PageWidth != 1))
|
|
{
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
|
|
case 2: // This means: 1728 or 2048 or 2432
|
|
case 3: // This is wrong but we interpret it like 2: All the standard widths
|
|
break;
|
|
|
|
default:// There is no other option (PageWidth is two only bits)
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|