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

  1. /***************************************************************************
  2. Name : NEGOT.C
  3. Comment : Capability handling and negotiation
  4. Revision Log
  5. Date Name Description
  6. -------- ----- ---------------------------------------------------------
  7. ***************************************************************************/
  8. #include "prep.h"
  9. #include "protocol.h"
  10. #include "glbproto.h"
  11. BOOL glLoRes=0; // Simulate LoRes from Remote when TX
  12. #define faxTlog(m) DEBUGMSG(ZONE_NEGOT, m);
  13. # define INST_ENCODING pTG->Inst.awfi.Encoding
  14. # define INST_VSECURITY pTG->Inst.awfi.vSecurity
  15. # define INST_RESOLUTION pTG->Inst.awfi.AwRes
  16. # define INST_PAGEWIDTH pTG->Inst.awfi.PageWidth
  17. # define INST_PAGELENGTH pTG->Inst.awfi.PageLength
  18. //////// Move these hardcoded values to an INI file ////////
  19. #define CAPS_WIDTH WIDTH_A4
  20. #define ENCODE_CAPS (MH_DATA | MR_DATA ) // RSL | MMR_DATA)
  21. // Current suppored linearized verson +++ (change to vMSG_IFAX100 when we
  22. // have enabled Linearized published images).
  23. #define vMSG_WIN95 vMSG_IFAX100 // vMSG_SNOW
  24. //# define CAPS_RES 0
  25. //#if 0
  26. #ifdef DPI_400
  27. # define CAPS_RES (AWRES_mm080_038 | AWRES_mm080_077 | AWRES_200_200 | AWRES_300_300 | AWRES_mm080_154 | AWRES_160_154 | AWRES_400_400)
  28. #else
  29. # define CAPS_RES (AWRES_mm080_038 | AWRES_mm080_077 | AWRES_200_200 | AWRES_300_300)
  30. #endif
  31. //#endif
  32. /********* These are the Ricoh thresholds--they're too simplistic *****
  33. USHORT MaxBadLines[4][4] =
  34. {
  35. {110, 220, 330, 440 }, // CheckLevel=1 10%
  36. { 82, 165, 248, 330 }, // CheckLevel=2 7.5%
  37. { 55, 110, 165, 220 }, // CheckLevel=3 5%
  38. { 27, 55, 83, 110 } // CheckLevel=4 2.5%
  39. };
  40. USHORT MaxConsecBad[4][4] =
  41. {
  42. { 6, 12, 18, 24 }, // CheckLevel=1
  43. { 5, 10, 15, 20 }, // CheckLevel=2
  44. { 4, 8, 12, 16 }, // CheckLevel=3
  45. { 3, 6, 9, 12 } // CheckLevel=4
  46. };
  47. *****************/
  48. ////////////////////////////////////////////////////////////////
  49. // Don't delete this -- these were my thresholds _before_ I talked to Ricoh
  50. ////////
  51. // higher thresholds, tapering off, because
  52. // at higher resolutions we want cleaner copy.
  53. // USHORT MaxBadLines[4] = { 33, 66, 84, 99 }; // 3.5, 3, 2.5, 2.25 %bad
  54. // USHORT MaxConsecBad[4] = { 5, 9, 12, 15 }; // 2/3rd of a 10pt char is 9,18,27,36 lines
  55. ////////////////////////////////////////////////////////////////
  56. USHORT MaxBadLines[4][4] =
  57. {
  58. { 77, 132, 165, 198 }, // CheckLevel=1 7, 6, 5, 4.5% bad
  59. { 58, 99, 124, 149 }, // CheckLevel=2 5.25, 4.5, 3.75, 3.375% bad
  60. { 39, 66, 83, 99 }, // CheckLevel=3 3.5, 3, 2.5, 2.25% bad
  61. { 19, 33, 41, 50 } // CheckLevel=4 1.75, 1.5, 1.25, 1.125% bad
  62. };
  63. USHORT MaxConsecBad[4][4] =
  64. {
  65. { 7, 13, 18, 23 }, // CheckLevel=1
  66. { 6, 11, 15, 19 }, // CheckLevel=2
  67. { 5, 9, 12, 15 }, // CheckLevel=3
  68. { 4, 7, 9, 11 } // CheckLevel=4
  69. };
  70. // lBad = DWORD with max. consecutive badlines in low word
  71. // and total number of bad lines in high word.
  72. // res==resolution (using ENCODE_ values)
  73. // i = vertical res index into table above (0=100, 1=200, 2=300 3=400)
  74. /** Widths in pixels must be exactly correct for MH decoding to work.
  75. the width above are for NORMAL, FINE, 200dpi and SUPER resolutions.
  76. At 400dpi or SUPER_SUPER exactly twice as amny pixels must be supplied
  77. and at 300dpi exactly 1.5 times.
  78. A4 B4 A3
  79. 200 1728/216 2048/256 2432/304
  80. 300 2592/324 3072/384 3648/456
  81. 400 3456/432 4096/512 4864/608
  82. **/
  83. // first index is 200/300/400dpi horiz res (inch or mm based)
  84. // second index is width A4/B4/A3
  85. USHORT ResWidthToBytes[3][3] =
  86. {
  87. { 216, 256, 304 },
  88. { 324, 384, 456 },
  89. { 432, 512, 608 }
  90. };
  91. BYTE BestEncoding[8] =
  92. {
  93. 0, // none (error)
  94. 1, // MH only
  95. 2, // MR only
  96. 2, // MR & MH
  97. 4, // MMR only
  98. 4, // MMR & MH
  99. 4, // MMR & MR
  100. 4 // MMR & MR & MH
  101. };
  102. BOOL NegotiateCaps(PThrdGlbl pTG)
  103. {
  104. USHORT Res;
  105. if (glLoRes) {
  106. pTG->Inst.RemoteRecvCaps.Fax.AwRes = 0;
  107. }
  108. memset(&pTG->Inst.SendParams, 0, sizeof(pTG->Inst.SendParams));
  109. pTG->Inst.SendParams.bctype = SEND_PARAMS;
  110. // They should be set. This code here is correct--arulm
  111. // +++ Following three are not set in pcfax11
  112. pTG->Inst.SendParams.wBCSize = sizeof(BC);
  113. pTG->Inst.SendParams.wBCVer = VER_AWFXPROT100;
  114. pTG->Inst.SendParams.wTotalSize = sizeof(BC);
  115. // +++ Initialize ID from our own SendCaps...
  116. {
  117. char rgchID[MAXFHBIDLEN+2];
  118. GetTextId(&pTG->Inst.SendCaps, rgchID, MAXFHBIDLEN+1);
  119. PutTextId((LPBC)&pTG->Inst.SendParams, sizeof(pTG->Inst.SendParams),
  120. rgchID, _fstrlen(rgchID), TEXTCODE_ASCII);
  121. }
  122. // RSL BUGBUG this should be set from fax UI
  123. ////////////////////////////////////////////
  124. pTG->Inst.awfi.Encoding = ENCODE_CAPS; // MR_DATA | MH_DATA;
  125. if (! pTG->SrcHiRes) {
  126. pTG->Inst.awfi.AwRes = 0;
  127. }
  128. else {
  129. pTG->Inst.awfi.AwRes = CAPS_RES; // AWRES_200_200;
  130. }
  131. ////////////// Width, Length, Res & Enc /////////////////////////////
  132. /////// Encoding ///////
  133. BG_CHK(pTG->Inst.RemoteRecvCaps.Fax.Encoding && pTG->Inst.RemoteRecvCaps.Fax.Encoding < 8);
  134. // this next BG_CHK seems bogus...?
  135. // BG_CHK(pTG->Inst.ProtParams.fDisableECM ? (!(pTG->Inst.RemoteRecvCaps.Fax.Encoding & MMR_DATA)) : 1);
  136. BG_CHK(INST_ENCODING && INST_ENCODING < 8);
  137. BG_CHK(BestEncoding[INST_ENCODING] == INST_ENCODING); // check just 1 bit set
  138. #define SEND_RECODE_TO INST_ENCODING
  139. // If pTG->Inst.fDisableG3ECM, we will refuse to send MMR
  140. if (pTG->Inst.fDisableG3ECM && (pTG->Inst.RemoteRecvCaps.Fax.Encoding & MMR_DATA))
  141. {
  142. (MyDebugPrint(pTG, LOG_ERR, "<WARNING> - fDisableG3ECM => NOT using MMR\r\n"));
  143. pTG->Inst.RemoteRecvCaps.Fax.Encoding &= ~MMR_DATA;
  144. }
  145. if(!(pTG->Inst.SendParams.Fax.Encoding =
  146. BestEncoding[(INST_ENCODING | SEND_RECODE_TO) &
  147. pTG->Inst.RemoteRecvCaps.Fax.Encoding]))
  148. {
  149. // No matching Encoding not supported
  150. (MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: SendEnc %d CanRecodeTo %d RecvCapsEnc %d. No match\r\n",
  151. INST_ENCODING, SEND_RECODE_TO, pTG->Inst.RemoteRecvCaps.Fax.Encoding));
  152. SetFailureCode(pTG, T30FAILS_NEGOT_ENCODING);
  153. goto error;
  154. }
  155. // check just 1 bit set
  156. BG_CHK(BestEncoding[pTG->Inst.SendParams.Fax.Encoding] ==
  157. pTG->Inst.SendParams.Fax.Encoding);
  158. BG_CHK(pTG->Inst.SendParams.Fax.Encoding == INST_ENCODING);
  159. /////// Width ///////
  160. pTG->Inst.RemoteRecvCaps.Fax.PageWidth &= 0x0F; // castrate all A5/A6 widths
  161. if(INST_PAGEWIDTH > 0x0F)
  162. {
  163. // A5 or A6. Can quit or send as A4
  164. // INST_PAGEWIDTH = WIDTH_A4;
  165. (MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: A5/A6 images not supported\r\n"));
  166. SetFailureCode(pTG, T30FAILS_NEGOT_A5A6);
  167. goto error;
  168. }
  169. if(pTG->Inst.RemoteRecvCaps.Fax.PageWidth < INST_PAGEWIDTH)
  170. {
  171. // or do some scaling
  172. (MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: Image too wide\r\n"));
  173. SetFailureCode(pTG, T30FAILS_NEGOT_WIDTH);
  174. goto error;
  175. }
  176. else
  177. pTG->Inst.SendParams.Fax.PageWidth = INST_PAGEWIDTH;
  178. /////// Length ///////
  179. if(pTG->Inst.RemoteRecvCaps.Fax.PageLength < INST_PAGELENGTH)
  180. {
  181. (MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: Image too long\r\n"));
  182. SetFailureCode(pTG, T30FAILS_NEGOT_LENGTH);
  183. goto error;
  184. }
  185. else
  186. pTG->Inst.SendParams.Fax.PageLength = INST_PAGELENGTH;
  187. /////// Res ///////
  188. // pick best resolution
  189. pTG->Inst.HorizScaling = 0;
  190. pTG->Inst.VertScaling = 0;
  191. // test scaling to NORMAL
  192. // pTG->Inst.RemoteRecvCaps.Fax.AwRes = AWRES_mm080_038;
  193. Res = (USHORT) (INST_RESOLUTION & pTG->Inst.RemoteRecvCaps.Fax.AwRes);
  194. if(Res) // send native
  195. pTG->Inst.SendParams.Fax.AwRes = Res;
  196. else
  197. {
  198. BG_CHK(INST_RESOLUTION != AWRES_mm080_038);
  199. BG_CHK(pTG->Inst.RemoteRecvCaps.Fax.AwRes & AWRES_mm080_038);
  200. switch(INST_RESOLUTION)
  201. {
  202. case AWRES_mm160_154:
  203. if(AWRES_400_400 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
  204. {
  205. pTG->Inst.SendParams.Fax.AwRes = AWRES_400_400;
  206. }
  207. else
  208. {
  209. (MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 16x15.4 image and no horiz scaling\r\n"));
  210. SetFailureCode(pTG, T30FAILS_NEGOT_RES);
  211. goto error;
  212. }
  213. break;
  214. case AWRES_mm080_154:
  215. #ifdef VS
  216. if(pTG->Inst.SendParams.Fax.Encoding == MMR_DATA)
  217. #endif //VS
  218. {
  219. (MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 8x15.4 image and no vert scaling\r\n"));
  220. SetFailureCode(pTG, T30FAILS_NEGOT_RES);
  221. goto error;
  222. }
  223. #ifdef VS
  224. if(AWRES_mm080_077 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
  225. {
  226. pTG->Inst.SendParams.Fax.AwRes = AWRES_mm080_077;
  227. pTG->Inst.VertScaling = 2;
  228. }
  229. else if(AWRES_200_200 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
  230. {
  231. pTG->Inst.SendParams.Fax.AwRes = AWRES_200_200;
  232. pTG->Inst.VertScaling = 2;
  233. }
  234. else
  235. {
  236. pTG->Inst.SendParams.Fax.AwRes = AWRES_mm080_038;
  237. pTG->Inst.VertScaling = 4;
  238. }
  239. #endif //VS
  240. break;
  241. case AWRES_mm080_077:
  242. if(AWRES_200_200 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
  243. {
  244. pTG->Inst.SendParams.Fax.AwRes = AWRES_200_200;
  245. }
  246. #ifdef VS
  247. else if(pTG->Inst.SendParams.Fax.Encoding == MMR_DATA)
  248. #else //VS
  249. else
  250. #endif //VS
  251. {
  252. (MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 8x7.7 image and no vert scaling\r\n"));
  253. SetFailureCode(pTG, T30FAILS_NEGOT_RES);
  254. goto error;
  255. }
  256. #ifdef VS
  257. else
  258. {
  259. pTG->Inst.SendParams.Fax.AwRes = AWRES_mm080_038;
  260. pTG->Inst.VertScaling = 2;
  261. }
  262. #endif //VS
  263. break;
  264. case AWRES_400_400:
  265. if(AWRES_mm160_154 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
  266. {
  267. pTG->Inst.SendParams.Fax.AwRes = AWRES_mm160_154;
  268. }
  269. else
  270. {
  271. (MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 400dpi image and no horiz scaling\r\n"));
  272. SetFailureCode(pTG, T30FAILS_NEGOT_RES);
  273. goto error;
  274. }
  275. break;
  276. case AWRES_300_300:
  277. {
  278. (MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 300dpi image and no non-integer scaling\r\n"));
  279. SetFailureCode(pTG, T30FAILS_NEGOT_RES);
  280. goto error;
  281. }
  282. break;
  283. case AWRES_200_200:
  284. if(AWRES_mm080_077 & pTG->Inst.RemoteRecvCaps.Fax.AwRes)
  285. {
  286. pTG->Inst.SendParams.Fax.AwRes = AWRES_mm080_077;
  287. }
  288. #ifdef VS
  289. else if(pTG->Inst.SendParams.Fax.Encoding == MMR_DATA)
  290. #else //VS
  291. else
  292. #endif //VS
  293. {
  294. (MyDebugPrint(pTG, LOG_ERR, "Negotiation failed: 200dpi image and no vert scaling\r\n"));
  295. SetFailureCode(pTG, T30FAILS_NEGOT_RES);
  296. goto error;
  297. }
  298. #ifdef VS
  299. else
  300. {
  301. pTG->Inst.SendParams.Fax.AwRes = AWRES_mm080_038;
  302. pTG->Inst.VertScaling = 2;
  303. }
  304. #endif //VS
  305. break;
  306. default:
  307. BG_CHK(FALSE);
  308. }
  309. }
  310. #ifdef VS
  311. if(pTG->Inst.VertScaling)
  312. {
  313. BG_CHK(pTG->Inst.SendParams.Fax.Encoding != MMR_DATA);
  314. //RSL InitVertScale(pTG->Inst.VertScaling);
  315. }
  316. #endif //VS
  317. (MyDebugPrint(pTG, LOG_ALL, "Negotiation Succeeded: Res=%d PageWidth=%d Len=%d Enc=%d HSc=%d VSc=%d HSc3=%d VSc3=%d\r\n",
  318. pTG->Inst.SendParams.Fax.AwRes, pTG->Inst.SendParams.Fax.PageWidth, pTG->Inst.SendParams.Fax.PageLength,
  319. pTG->Inst.SendParams.Fax.Encoding, pTG->Inst.HorizScaling, pTG->Inst.VertScaling,
  320. pTG->Inst.HorizScaling300dpi, pTG->Inst.VertScaling300dpi));
  321. return TRUE;
  322. error:
  323. return FALSE;
  324. }
  325. void InitCapsBC(PThrdGlbl pTG, LPBC lpbc, USHORT uSize, BCTYPE bctype)
  326. {
  327. memset(lpbc, 0, uSize);
  328. lpbc->bctype = bctype;
  329. // They should be set. This code here is correct--arulm
  330. // +++ Following three lines are not in pcfax11
  331. lpbc->wBCSize = sizeof(BC);
  332. lpbc->wBCVer = VER_AWFXPROT100;
  333. lpbc->wTotalSize = sizeof(BC);
  334. lpbc->Std.GroupNum = GROUPNUM_STD;
  335. lpbc->Std.GroupLength = sizeof(BCSTD);
  336. lpbc->Std.vMsgProtocol = vMSG_WIN95;
  337. lpbc->Std.fBinaryData = TRUE;
  338. // lpbc->Std.fInwardRouting = FALSE;
  339. // NOSECURITY is defined for France build etc.
  340. lpbc->Std.vSecurity = 0;
  341. lpbc->Std.OperatingSys = OS_WIN16;
  342. // lpbc->Std.vShortFlags = 0;
  343. // lpbc->Std.vInteractive = 0;
  344. // lpbc->Std.DataSpeed = 0;
  345. // lpbc->Std.DataLink = 0;
  346. // lpbc->Fax.fPublicPoll = 0;
  347. if (! pTG->SrcHiRes) {
  348. lpbc->Fax.AwRes = 0;
  349. }
  350. else {
  351. lpbc->Fax.AwRes = CAPS_RES;
  352. }
  353. lpbc->Fax.Encoding = ENCODE_CAPS;
  354. if (0) // RSL (pTG->Inst.fDisableMRRecv)
  355. {
  356. ERRMSG(( SZMOD "<<WARNING>> Disabling MR Receive capability\r\n"));
  357. lpbc->Fax.Encoding &= ~MR_DATA;
  358. }
  359. lpbc->Fax.PageWidth = CAPS_WIDTH; // can be upto A3
  360. lpbc->Fax.PageLength = LENGTH_UNLIMITED;
  361. lpbc->Image.GroupNum = GROUPNUM_IMAGE;
  362. lpbc->Image.GroupLength = sizeof(BCIMAGE);
  363. lpbc->Image.vRamboVer = vRAMBO_VER1;
  364. }