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.
 
 
 
 
 
 

498 lines
16 KiB

/***************************************************************************
Name : NEGOT.C
Comment : Capability handling and negotiation
Revision Log
Date Name Description
-------- ----- ---------------------------------------------------------
***************************************************************************/
#include "prep.h"
#include "protocol.h"
#include "glbproto.h"
BOOL glLoRes=0; // Simulate LoRes from Remote when TX
#define faxTlog(m) DEBUGMSG(ZONE_NEGOT, m);
# define INST_ENCODING pTG->Inst.awfi.Encoding
# define INST_VSECURITY pTG->Inst.awfi.vSecurity
# define INST_RESOLUTION pTG->Inst.awfi.AwRes
# define INST_PAGEWIDTH pTG->Inst.awfi.PageWidth
# define INST_PAGELENGTH pTG->Inst.awfi.PageLength
//////// Move these hardcoded values to an INI file ////////
#define CAPS_WIDTH WIDTH_A4
#define ENCODE_CAPS (MH_DATA | MR_DATA ) // RSL | MMR_DATA)
// Current suppored linearized verson +++ (change to vMSG_IFAX100 when we
// have enabled Linearized published images).
#define vMSG_WIN95 vMSG_IFAX100 // vMSG_SNOW
//# define CAPS_RES 0
//#if 0
#ifdef DPI_400
# define CAPS_RES (AWRES_mm080_038 | AWRES_mm080_077 | AWRES_200_200 | AWRES_300_300 | AWRES_mm080_154 | AWRES_160_154 | AWRES_400_400)
#else
# define CAPS_RES (AWRES_mm080_038 | AWRES_mm080_077 | AWRES_200_200 | AWRES_300_300)
#endif
//#endif
/********* These are the Ricoh thresholds--they're too simplistic *****
USHORT MaxBadLines[4][4] =
{
{110, 220, 330, 440 }, // CheckLevel=1 10%
{ 82, 165, 248, 330 }, // CheckLevel=2 7.5%
{ 55, 110, 165, 220 }, // CheckLevel=3 5%
{ 27, 55, 83, 110 } // CheckLevel=4 2.5%
};
USHORT MaxConsecBad[4][4] =
{
{ 6, 12, 18, 24 }, // CheckLevel=1
{ 5, 10, 15, 20 }, // CheckLevel=2
{ 4, 8, 12, 16 }, // CheckLevel=3
{ 3, 6, 9, 12 } // CheckLevel=4
};
*****************/
////////////////////////////////////////////////////////////////
// Don't delete this -- these were my thresholds _before_ I talked to Ricoh
////////
// higher thresholds, tapering off, because
// at higher resolutions we want cleaner copy.
// USHORT MaxBadLines[4] = { 33, 66, 84, 99 }; // 3.5, 3, 2.5, 2.25 %bad
// USHORT MaxConsecBad[4] = { 5, 9, 12, 15 }; // 2/3rd of a 10pt char is 9,18,27,36 lines
////////////////////////////////////////////////////////////////
USHORT MaxBadLines[4][4] =
{
{ 77, 132, 165, 198 }, // CheckLevel=1 7, 6, 5, 4.5% bad
{ 58, 99, 124, 149 }, // CheckLevel=2 5.25, 4.5, 3.75, 3.375% bad
{ 39, 66, 83, 99 }, // CheckLevel=3 3.5, 3, 2.5, 2.25% bad
{ 19, 33, 41, 50 } // CheckLevel=4 1.75, 1.5, 1.25, 1.125% bad
};
USHORT MaxConsecBad[4][4] =
{
{ 7, 13, 18, 23 }, // CheckLevel=1
{ 6, 11, 15, 19 }, // CheckLevel=2
{ 5, 9, 12, 15 }, // CheckLevel=3
{ 4, 7, 9, 11 } // CheckLevel=4
};
// lBad = DWORD with max. consecutive badlines in low word
// and total number of bad lines in high word.
// res==resolution (using ENCODE_ values)
// i = vertical res index into table above (0=100, 1=200, 2=300 3=400)
/** Widths in pixels must be exactly correct for MH decoding to work.
the width above are for NORMAL, FINE, 200dpi and SUPER resolutions.
At 400dpi or SUPER_SUPER exactly twice as amny pixels must be supplied
and at 300dpi exactly 1.5 times.
A4 B4 A3
200 1728/216 2048/256 2432/304
300 2592/324 3072/384 3648/456
400 3456/432 4096/512 4864/608
**/
// first index is 200/300/400dpi horiz res (inch or mm based)
// second index is width A4/B4/A3
USHORT ResWidthToBytes[3][3] =
{
{ 216, 256, 304 },
{ 324, 384, 456 },
{ 432, 512, 608 }
};
BYTE BestEncoding[8] =
{
0, // none (error)
1, // MH only
2, // MR only
2, // MR & MH
4, // MMR only
4, // MMR & MH
4, // MMR & MR
4 // MMR & MR & MH
};
BOOL NegotiateCaps(PThrdGlbl pTG)
{
USHORT Res;
if (glLoRes) {
pTG->Inst.RemoteRecvCaps.Fax.AwRes = 0;
}
memset(&pTG->Inst.SendParams, 0, sizeof(pTG->Inst.SendParams));
pTG->Inst.SendParams.bctype = SEND_PARAMS;
// They should be set. This code here is correct--arulm
// +++ Following three are not set in pcfax11
pTG->Inst.SendParams.wBCSize = sizeof(BC);
pTG->Inst.SendParams.wBCVer = VER_AWFXPROT100;
pTG->Inst.SendParams.wTotalSize = sizeof(BC);
// +++ Initialize ID from our own SendCaps...
{
char rgchID[MAXFHBIDLEN+2];
GetTextId(&pTG->Inst.SendCaps, rgchID, MAXFHBIDLEN+1);
PutTextId((LPBC)&pTG->Inst.SendParams, sizeof(pTG->Inst.SendParams),
rgchID, _fstrlen(rgchID), TEXTCODE_ASCII);
}
// RSL BUGBUG this should be set from fax UI
////////////////////////////////////////////
pTG->Inst.awfi.Encoding = ENCODE_CAPS; // MR_DATA | MH_DATA;
if (! pTG->SrcHiRes) {
pTG->Inst.awfi.AwRes = 0;
}
else {
pTG->Inst.awfi.AwRes = CAPS_RES; // AWRES_200_200;
}
////////////// Width, Length, Res & Enc /////////////////////////////
/////// Encoding ///////
BG_CHK(pTG->Inst.RemoteRecvCaps.Fax.Encoding && pTG->Inst.RemoteRecvCaps.Fax.Encoding < 8);
// this next BG_CHK seems bogus...?
// BG_CHK(pTG->Inst.ProtParams.fDisableECM ? (!(pTG->Inst.RemoteRecvCaps.Fax.Encoding & MMR_DATA)) : 1);
BG_CHK(INST_ENCODING && INST_ENCODING < 8);
BG_CHK(BestEncoding[INST_ENCODING] == INST_ENCODING); // check just 1 bit set
#define SEND_RECODE_TO INST_ENCODING
// If pTG->Inst.fDisableG3ECM, we will refuse to send MMR
if (pTG->Inst.fDisableG3ECM && (pTG->Inst.RemoteRecvCaps.Fax.Encoding & MMR_DATA))
{
(MyDebugPrint(pTG, LOG_ERR, "<WARNING> - fDisableG3ECM => NOT using MMR\r\n"));
pTG->Inst.RemoteRecvCaps.Fax.Encoding &= ~MMR_DATA;
}
if(!(pTG->Inst.SendParams.Fax.Encoding =
BestEncoding[(INST_ENCODING | SEND_RECODE_TO) &
pTG->Inst.RemoteRecvCaps.Fax.Encoding]))
{
// No matching Encoding not supported
(MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: SendEnc %d CanRecodeTo %d RecvCapsEnc %d. No match\r\n",
INST_ENCODING, SEND_RECODE_TO, pTG->Inst.RemoteRecvCaps.Fax.Encoding));
SetFailureCode(pTG, T30FAILS_NEGOT_ENCODING);
goto error;
}
// check just 1 bit set
BG_CHK(BestEncoding[pTG->Inst.SendParams.Fax.Encoding] ==
pTG->Inst.SendParams.Fax.Encoding);
BG_CHK(pTG->Inst.SendParams.Fax.Encoding == INST_ENCODING);
/////// Width ///////
pTG->Inst.RemoteRecvCaps.Fax.PageWidth &= 0x0F; // castrate all A5/A6 widths
if(INST_PAGEWIDTH > 0x0F)
{
// A5 or A6. Can quit or send as A4
// INST_PAGEWIDTH = WIDTH_A4;
(MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: A5/A6 images not supported\r\n"));
SetFailureCode(pTG, T30FAILS_NEGOT_A5A6);
goto error;
}
if(pTG->Inst.RemoteRecvCaps.Fax.PageWidth < INST_PAGEWIDTH)
{
// or do some scaling
(MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: Image too wide\r\n"));
SetFailureCode(pTG, T30FAILS_NEGOT_WIDTH);
goto error;
}
else
pTG->Inst.SendParams.Fax.PageWidth = INST_PAGEWIDTH;
/////// Length ///////
if(pTG->Inst.RemoteRecvCaps.Fax.PageLength < INST_PAGELENGTH)
{
(MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: Image too long\r\n"));
SetFailureCode(pTG, T30FAILS_NEGOT_LENGTH);
goto error;
}
else
pTG->Inst.SendParams.Fax.PageLength = INST_PAGELENGTH;
/////// Res ///////
// pick best resolution
pTG->Inst.HorizScaling = 0;
pTG->Inst.VertScaling = 0;
// test scaling to NORMAL
// pTG->Inst.RemoteRecvCaps.Fax.AwRes = AWRES_mm080_038;
Res = (USHORT) (INST_RESOLUTION & pTG->Inst.RemoteRecvCaps.Fax.AwRes);
if(Res) // send native
pTG->Inst.SendParams.Fax.AwRes = Res;
else
{
BG_CHK(INST_RESOLUTION != AWRES_mm080_038);
BG_CHK(pTG->Inst.RemoteRecvCaps.Fax.AwRes & AWRES_mm080_038);
switch(INST_RESOLUTION)
{
case AWRES_mm160_154:
if(AWRES_400_400 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
{
pTG->Inst.SendParams.Fax.AwRes = AWRES_400_400;
}
else
{
(MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 16x15.4 image and no horiz scaling\r\n"));
SetFailureCode(pTG, T30FAILS_NEGOT_RES);
goto error;
}
break;
case AWRES_mm080_154:
#ifdef VS
if(pTG->Inst.SendParams.Fax.Encoding == MMR_DATA)
#endif //VS
{
(MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 8x15.4 image and no vert scaling\r\n"));
SetFailureCode(pTG, T30FAILS_NEGOT_RES);
goto error;
}
#ifdef VS
if(AWRES_mm080_077 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
{
pTG->Inst.SendParams.Fax.AwRes = AWRES_mm080_077;
pTG->Inst.VertScaling = 2;
}
else if(AWRES_200_200 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
{
pTG->Inst.SendParams.Fax.AwRes = AWRES_200_200;
pTG->Inst.VertScaling = 2;
}
else
{
pTG->Inst.SendParams.Fax.AwRes = AWRES_mm080_038;
pTG->Inst.VertScaling = 4;
}
#endif //VS
break;
case AWRES_mm080_077:
if(AWRES_200_200 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
{
pTG->Inst.SendParams.Fax.AwRes = AWRES_200_200;
}
#ifdef VS
else if(pTG->Inst.SendParams.Fax.Encoding == MMR_DATA)
#else //VS
else
#endif //VS
{
(MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 8x7.7 image and no vert scaling\r\n"));
SetFailureCode(pTG, T30FAILS_NEGOT_RES);
goto error;
}
#ifdef VS
else
{
pTG->Inst.SendParams.Fax.AwRes = AWRES_mm080_038;
pTG->Inst.VertScaling = 2;
}
#endif //VS
break;
case AWRES_400_400:
if(AWRES_mm160_154 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
{
pTG->Inst.SendParams.Fax.AwRes = AWRES_mm160_154;
}
else
{
(MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 400dpi image and no horiz scaling\r\n"));
SetFailureCode(pTG, T30FAILS_NEGOT_RES);
goto error;
}
break;
case AWRES_300_300:
{
(MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 300dpi image and no non-integer scaling\r\n"));
SetFailureCode(pTG, T30FAILS_NEGOT_RES);
goto error;
}
break;
case AWRES_200_200:
if(AWRES_mm080_077 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
{
pTG->Inst.SendParams.Fax.AwRes = AWRES_mm080_077;
}
#ifdef VS
else if(pTG->Inst.SendParams.Fax.Encoding == MMR_DATA)
#else //VS
else
#endif //VS
{
(MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 200dpi image and no vert scaling\r\n"));
SetFailureCode(pTG, T30FAILS_NEGOT_RES);
goto error;
}
#ifdef VS
else
{
pTG->Inst.SendParams.Fax.AwRes = AWRES_mm080_038;
pTG->Inst.VertScaling = 2;
}
#endif //VS
break;
default:
BG_CHK(FALSE);
}
}
#ifdef VS
if(pTG->Inst.VertScaling)
{
BG_CHK(pTG->Inst.SendParams.Fax.Encoding != MMR_DATA);
//RSL InitVertScale(pTG->Inst.VertScaling);
}
#endif //VS
(MyDebugPrint(pTG, LOG_ALL, "Negotiation Succeeded: Res=%d PageWidth=%d Len=%d Enc=%d HSc=%d VSc=%d HSc3=%d VSc3=%d\r\n",
pTG->Inst.SendParams.Fax.AwRes, pTG->Inst.SendParams.Fax.PageWidth, pTG->Inst.SendParams.Fax.PageLength,
pTG->Inst.SendParams.Fax.Encoding, pTG->Inst.HorizScaling, pTG->Inst.VertScaling,
pTG->Inst.HorizScaling300dpi, pTG->Inst.VertScaling300dpi));
return TRUE;
error:
return FALSE;
}
void InitCapsBC(PThrdGlbl pTG, LPBC lpbc, USHORT uSize, BCTYPE bctype)
{
memset(lpbc, 0, uSize);
lpbc->bctype = bctype;
// They should be set. This code here is correct--arulm
// +++ Following three lines are not in pcfax11
lpbc->wBCSize = sizeof(BC);
lpbc->wBCVer = VER_AWFXPROT100;
lpbc->wTotalSize = sizeof(BC);
lpbc->Std.GroupNum = GROUPNUM_STD;
lpbc->Std.GroupLength = sizeof(BCSTD);
lpbc->Std.vMsgProtocol = vMSG_WIN95;
lpbc->Std.fBinaryData = TRUE;
// lpbc->Std.fInwardRouting = FALSE;
// NOSECURITY is defined for France build etc.
lpbc->Std.vSecurity = 0;
lpbc->Std.OperatingSys = OS_WIN16;
// lpbc->Std.vShortFlags = 0;
// lpbc->Std.vInteractive = 0;
// lpbc->Std.DataSpeed = 0;
// lpbc->Std.DataLink = 0;
// lpbc->Fax.fPublicPoll = 0;
if (! pTG->SrcHiRes) {
lpbc->Fax.AwRes = 0;
}
else {
lpbc->Fax.AwRes = CAPS_RES;
}
lpbc->Fax.Encoding = ENCODE_CAPS;
if (0) // RSL (pTG->Inst.fDisableMRRecv)
{
ERRMSG(( SZMOD "<<WARNING>> Disabling MR Receive capability\r\n"));
lpbc->Fax.Encoding &= ~MR_DATA;
}
lpbc->Fax.PageWidth = CAPS_WIDTH; // can be upto A3
lpbc->Fax.PageLength = LENGTH_UNLIMITED;
lpbc->Image.GroupNum = GROUPNUM_IMAGE;
lpbc->Image.GroupLength = sizeof(BCIMAGE);
lpbc->Image.vRamboVer = vRAMBO_VER1;
}