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