1 /* $Id$ */
2 /*
3 * Copyright (c) 1990-1996 Sam Leffler
4 * Copyright (c) 1991-1996 Silicon Graphics, Inc.
5 * HylaFAX is a trademark of Silicon Graphics
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
14 *
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 *
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 * OF THIS SOFTWARE.
25 */
26
27 /*
28 * EIA/TIA-578 (Class 1) Modem Driver.
29 */
30 #include "Sys.h"
31 #include "Class1.h"
32 #include "ModemConfig.h"
33 #include "HDLCFrame.h"
34 #include "t.30.h"
35 #include "tiffio.h"
36
37 #include <stdlib.h>
38 #include <ctype.h>
39
40 const char* Class1Modem::modulationNames[6] = {
41 "v.21, chan 2",
42 "v.27ter fallback mode",
43 "v.27ter",
44 "v.29",
45 "v.17",
46 "v.33",
47 };
48 /*
49 * Modem capabilities are queried at startup and a
50 * table based on this is created for each modem.
51 * This information is used to negotiate T.30 session
52 * parameters (e.g. signalling rate).
53 *
54 * NB: v.17 w/ long training is the same as v.33, at
55 * least at 12000 and 14400.
56 */
57 const Class1Cap Class1Modem::basicCaps[15] = {
58 { 3, 0, 0, V21, false }, // v.21
59 { 24, BR_2400, DCSSIGRATE_2400V27, V27FB, false }, // v.27 ter
60 { 48, BR_4800, DCSSIGRATE_4800V27, V27, false }, // v.27 ter
61 { 72, BR_7200, DCSSIGRATE_7200V29, V29, false }, // v.29
62 { 73, BR_7200, DCSSIGRATE_7200V17, V17, false }, // v.17
63 { 74, BR_7200, DCSSIGRATE_7200V17, V17, false }, // v.17 w/st
64 { 96, BR_9600, DCSSIGRATE_9600V29, V29, false }, // v.29
65 { 97, BR_9600, DCSSIGRATE_9600V17, V17, false }, // v.17
66 { 98, BR_9600, DCSSIGRATE_9600V17, V17, false }, // v.17 w/st
67 { 121, BR_12000, DCSSIGRATE_12000V33, V33, false }, // v.33
68 { 121, BR_12000, DCSSIGRATE_12000V17, V17, false }, // v.17
69 { 122, BR_12000, DCSSIGRATE_12000V17, V17, false }, // v.17 w/st
70 { 145, BR_14400, DCSSIGRATE_14400V33, V33, false }, // v.33
71 { 145, BR_14400, DCSSIGRATE_14400V17, V17, false }, // v.17
72 { 146, BR_14400, DCSSIGRATE_14400V17, V17, false }, // v.17 w/st
73 };
74 #define NCAPS (sizeof (basicCaps) / sizeof (basicCaps[0]))
75
76 const char* Class1Modem::tmCmdFmt = "AT+FTM=%u";
77 const char* Class1Modem::rmCmdFmt = "AT+FRM=%u";
78
Class1Modem(FaxServer & s,const ModemConfig & c)79 Class1Modem::Class1Modem(FaxServer& s, const ModemConfig& c)
80 : FaxModem(s,c)
81 , thCmd("AT+FTH=3")
82 , rhCmd("AT+FRH=3")
83 {
84 messageReceived = false;
85 memcpy(xmitCaps, basicCaps, sizeof (basicCaps));
86 memcpy(recvCaps, basicCaps, sizeof (basicCaps));
87
88 /*
89 * Because the sending routines deliver data to the transmit functions
90 * in segments, these must be globally available to spool outgoing data
91 * until a complete ECM block can be assembled.
92 *
93 * Besides the contents of ecmBlock, ecmStuffedBlock must be able to
94 * hold all sync flag bytes, stuffed bits, and RCP frames.
95 */
96 u_int fs = 256;
97 if (conf.class1ECMFrameSize == 64) fs = 64;
98 ecmFrame = (u_char*) malloc(fs + 4);
99 fxAssert(ecmFrame != NULL, "ECM procedure error (frame).");
100 ecmBlock = (u_char*) malloc((fs + 4) * 256);
101 fxAssert(ecmBlock != NULL, "ECM procedure error (block).");
102 ecmStuffedBlock = (u_char*) malloc(fs == 256 ? 83000 : 33000);
103 fxAssert(ecmStuffedBlock != NULL, "ECM procedure error (stuffed block).");
104 gotCTRL = false;
105 repeatPhaseB = false;
106 silenceHeard = false;
107 imagefd = 0;
108 }
109
~Class1Modem()110 Class1Modem::~Class1Modem()
111 {
112 free(ecmFrame);
113 free(ecmBlock);
114 free(ecmStuffedBlock);
115 }
116
117 bool
atCmd(const fxStr & cmd,ATResponse r,long ms)118 Class1Modem::atCmd(const fxStr& cmd, ATResponse r, long ms)
119 {
120 silenceHeard = false;
121 return (ClassModem::atCmd(cmd, r, ms));
122 }
123
124 /*
125 * Check if the modem is a Class 1 modem and,
126 * if so, configure it for use.
127 */
128 bool
setupModem(bool isSend)129 Class1Modem::setupModem(bool isSend)
130 {
131 if (!selectBaudRate(conf.maxRate, conf.flowControl, conf.flowControl))
132 return (false);
133 // Query service support information
134 fxStr s;
135 if (doQuery(conf.classQueryCmd, s, 5000) && FaxModem::parseRange(s, modemServices))
136 traceBits(modemServices & SERVICE_ALL, serviceNames);
137 if ((modemServices & serviceType) == 0)
138 return (false);
139 atCmd(classCmd);
140
141 /*
142 * Query manufacturer, model, and firmware revision.
143 * We use the manufacturer especially as a key to
144 * working around firmware bugs (yech!).
145 */
146 if (setupManufacturer(modemMfr)) {
147 modemCapability("Mfr " | modemMfr);
148 modemMfr.raisecase();
149 }
150 (void) setupModel(modemModel);
151 (void) setupRevision(modemRevision);
152 if (modemModel != "")
153 modemCapability("Model " | modemModel);
154 if (modemRevision != "")
155 modemCapability("Revision " | modemRevision);
156
157 /*
158 * Get modem capabilities and calculate best signalling
159 * rate, data formatting capabilities, etc. for use in
160 * T.30 negotiations.
161 */
162 if (!class1Query(conf.class1TMQueryCmd, xmitCaps)) {
163 serverTrace("Error parsing \"+FTM\" query response: \"%s\"", rbuf);
164 return (false);
165 }
166 modemParams.br = 0;
167 u_int i;
168 for (i = 1; i < NCAPS; i++)
169 if (xmitCaps[i].ok)
170 modemParams.br |= BIT(xmitCaps[i].br);
171 nonV34br = modemParams.br;
172 if (conf.class1EnableV34Cmd != "" && conf.class1ECMSupport) {
173 // This is cosmetic, mostly, to state the modem supports V.34.
174 // We could query the modem but that would require another
175 // config option, so we just trust the enable command.
176 primaryV34Rate = 0;
177 u_short pos = conf.class1EnableV34Cmd.findR(conf.class1EnableV34Cmd.length(), "+F34=", 5) + 4;
178 if (pos == 4) // Unknown class1EnableV34Cmd
179 modemCapability("Unable to determinate V.34 speed from class1EnableV34Cmd, V.34 faxing will be disabled!");
180 else
181 primaryV34Rate = atoi(conf.class1EnableV34Cmd.extract(pos, conf.class1EnableV34Cmd.next(pos, ',') - pos));
182 modemParams.br |= BIT(primaryV34Rate) - 1;
183 }
184 modemParams.wd = conf.class1PageWidthSupport;
185 modemParams.ln = conf.class1PageLengthSupport;
186 modemParams.df = BIT(DF_1DMH) | (conf.class1MRSupport ? BIT(DF_2DMR) : 0);
187 modemParams.bf = BF_DISABLE;
188 modemParams.st = ST_ALL;
189 modemParams.jp = 0;
190 pokeConfig(isSend);
191 traceModemParams();
192 /*
193 * Receive capabilities are maintained separately from
194 * transmit capabilities because we need to know more
195 * than the signalling rate to formulate the DIS.
196 */
197 if (!class1Query(conf.class1RMQueryCmd, recvCaps)) {
198 serverTrace("Error parsing \"+FRM\" query response: \"%s\"", rbuf);
199 return (false);
200 }
201 u_int mods = 0;
202 for (i = 1; i < NCAPS; i++)
203 if (recvCaps[i].ok)
204 mods |= BIT(recvCaps[i].mod);
205 switch (mods) {
206 case BIT(V27FB):
207 discap = DISSIGRATE_V27FB;
208 break;
209 case BIT(V27FB)|BIT(V27):
210 discap = DISSIGRATE_V27;
211 break;
212 case BIT(V29):
213 discap = DISSIGRATE_V29;
214 break;
215 case BIT(V27FB)|BIT(V27)|BIT(V29):
216 discap = DISSIGRATE_V2729;
217 break;
218 case BIT(V27FB)|BIT(V27)|BIT(V29)|BIT(V33):
219 discap = DISSIGRATE_V33;
220 break;
221 case BIT(V27FB)|BIT(V27)|BIT(V29)|BIT(V17):
222 case BIT(V27FB)|BIT(V27)|BIT(V29)|BIT(V33)|BIT(V17):
223 discap = DISSIGRATE_V17;
224 break;
225 }
226 /*
227 * T.30 specifies that HDLC frame data are in MSB bit
228 * order except for CIG/TSI data which have LSB bit order.
229 * We compose and interpret frame data in MSB bit order
230 * and pass the frames through frameRev immediately before
231 * transmitting and upon receiving to handle modem characteristics.
232 *
233 * Class1Modem::encodeTSI and Class1Modem::decodeTSI (below)
234 * assume this work and process CIG/TSI data accordingly.
235 */
236 frameRev = TIFFGetBitRevTable(conf.frameFillOrder == FILLORDER_LSB2MSB);
237
238 setupClass1Parameters();
239 return (true);
240 }
241
242 /*
243 * These are potentially dynamic modem settings that can be altered on-the-fly.
244 */
245 void
pokeConfig(bool isSend)246 Class1Modem::pokeConfig(bool isSend)
247 {
248 modemParams.vr = conf.class1Resolutions; // bitmapped by configuration
249 if (conf.class1ECMSupport) {
250 modemParams.ec = BIT(EC_DISABLE) | BIT(EC_ENABLE64) | BIT(EC_ENABLE256);
251 modemParams.df |= (conf.class1MMRSupport ? BIT(DF_2DMMR) : 0);
252 switch (conf.class1JBIGSupport) {
253 case FaxModem::JBIG_FULL:
254 jbigSupported = true;
255 break;
256 case FaxModem::JBIG_SEND:
257 jbigSupported = isSend;
258 break;
259 case FaxModem::JBIG_RECV:
260 jbigSupported = !isSend;
261 break;
262 default:
263 jbigSupported = false;
264 break;
265 }
266 if (jbigSupported) modemParams.df |= BIT(DF_JBIG);
267 if (conf.class1GreyJPEGSupport || conf.class1ColorJPEGSupport)
268 modemParams.jp |= BIT(JP_GREY);
269 if (conf.class1ColorJPEGSupport)
270 modemParams.jp |= BIT(JP_COLOR);
271 } else
272 modemParams.ec = BIT(EC_DISABLE);
273 }
274
275 /*
276 * Send the modem the Class 1 configuration commands.
277 */
278 bool
setupClass1Parameters()279 Class1Modem::setupClass1Parameters()
280 {
281 if (modemServices & serviceType) {
282 setupFlowControl(flowControl);
283 atCmd(conf.setupAACmd);
284 }
285 return (true);
286 }
287
288 void
hangup()289 Class1Modem::hangup()
290 {
291 if (useV34) {
292 // terminate V.34 channel
293 u_char buf[2];
294 buf[0] = DLE; buf[1] = EOT; // <DLE><EOT>
295 putModemData(buf, 2);
296 // T.31-A1 samples indicate an OK response, but anything is acceptable
297 (void) atResponse(rbuf, 60000);
298 }
299 atCmd(conf.onHookCmd, AT_OK, 5000);
300 }
301
302 /*
303 * Setup receive-specific parameters.
304 */
305 bool
setupReceive()306 Class1Modem::setupReceive()
307 {
308 return (true); // nothing to do
309 }
310
311 /*
312 * Send the modem any commands needed to force use of
313 * the specified flow control scheme.
314 */
315 bool
setupFlowControl(FlowControl fc)316 Class1Modem::setupFlowControl(FlowControl fc)
317 {
318 switch (fc) {
319 case FLOW_NONE: return atCmd(conf.class1NFLOCmd);
320 case FLOW_XONXOFF: return atCmd(conf.class1SFLOCmd);
321 case FLOW_RTSCTS: return atCmd(conf.class1HFLOCmd);
322 }
323 return (true);
324 }
325
326 /*
327 * Place the modem into the appropriate state
328 * for sending facsimile.
329 */
330 bool
faxService(bool enableV34,bool enableV17)331 Class1Modem::faxService(bool enableV34, bool enableV17)
332 {
333 if (!atCmd(classCmd)) return (false);
334 if (conf.class1EnableV34Cmd != "" && enableV34)
335 atCmd(conf.class1EnableV34Cmd);
336 useV34 = false; // only when V.8 handshaking is used
337 gotEOT = false;
338 return (setupFlowControl(flowControl));
339 }
340
341 /*
342 * The modem is initialized. Now set it to ready for answer.
343 */
344 bool
ready(long ms)345 Class1Modem::ready(long ms)
346 {
347 gotEOT = false;
348 useV34 = false; // only when V.8 handshaking is used
349 if (conf.class1EnableV34Cmd != "" && conf.class1ECMSupport)
350 if (!atCmd(conf.class1EnableV34Cmd))
351 return (false);
352 if (conf.class1AdaptRecvCmd != "")
353 if (!atCmd(conf.class1AdaptRecvCmd))
354 return (false);
355 return (FaxModem::ready(ms));
356 }
357
358
359 /*
360 * Set the local subscriber identification.
361 */
362 void
setLID(const fxStr & number)363 Class1Modem::setLID(const fxStr& number)
364 {
365 encodeTSI(lid, number);
366 }
367
368 bool
supportsPolling() const369 Class1Modem::supportsPolling() const
370 {
371 return (true);
372 }
373
374 /*
375 * Construct a binary TSI/CIG string for transmission. Note
376 * that we do not enforce the specification that restricts
377 * the alphabet to that of Table 3/T.30 (numeric digits,
378 * hyphen, period, and space), but instead permit any
379 * printable ASCII string of at most 20 characters to be
380 * used. Note also that the bit reversal is done with the
381 * understanding that the encoded string is processed again
382 * using frameRev (see above) when forming the transmitted
383 * HDLC frame.
384 */
385 void
encodeTSI(fxStr & binary,const fxStr & ascii)386 Class1Modem::encodeTSI(fxStr& binary, const fxStr& ascii)
387 {
388 u_int i, j;
389 u_char buf[20];
390 u_int n = fxmin(ascii.length(),(u_int) 20);
391 for (i = 0, j = 0; i < n; i++) {
392 char c = ascii[i];
393 if (isprint(c) || c == ' ')
394 buf[j++] = frameRev[c];
395 }
396 /*
397 * Now ``reverse copy'' the string.
398 */
399 binary.resize(20);
400 for (i = 0; j > 0; i++, j--)
401 binary[i] = buf[j-1];
402 for (; i < 20; i++)
403 binary[i] = frameRev[' ']; // blank pad remainder
404 }
405
406 /*
407 * Encode an NSF string for transmission.
408 */
409 void
encodeNSF(fxStr & binary,const fxStr & ascii)410 Class1Modem::encodeNSF(fxStr& binary, const fxStr& ascii)
411 {
412 u_int i, j;
413 u_int n = ascii.length();
414 binary.resize(n);
415 for (i = 0, j = 0; i < n; i++) {
416 char c = ascii[i];
417 if (isprint(c) || c == ' ')
418 binary[j++] = frameRev[c];
419 }
420 }
421
422 /*
423 * Do the inverse of encodeTSI; i.e. convert a binary
424 * string of encoded digits into the equivalent ascii.
425 * Note that as above (and per the spec) bytes are
426 * presumed to be transmitted in LSB2MSB bit order and
427 * then reversed on receipt according to the host bit
428 * order.
429 */
430 const fxStr&
decodeTSI(fxStr & ascii,const HDLCFrame & binary)431 Class1Modem::decodeTSI(fxStr& ascii, const HDLCFrame& binary)
432 {
433 int n = binary.getFrameDataLength();
434 if (n > 20) // spec says no more than 20 digits
435 n = 20;
436 else n--; // trim FCF
437 ascii.resize(n);
438 u_int d = 0;
439 bool seenDigit = false;
440 for (const u_char* cp = binary.getFrameData() + n-1; n > 0; cp--, n--) {
441 /*
442 * Accept any printable ascii.
443 */
444 u_char c = frameRev[*cp];
445 if (isprint(c) || c == ' ') {
446 if (c != ' ')
447 seenDigit = true;
448 if (seenDigit)
449 ascii[d++] = c;
450 }
451 }
452 ascii.resize(d);
453 return ascii;
454 }
455
456 /*
457 * Construct a binary PWD/SUB/SEP string for transmission.
458 */
459 void
encodePWD(fxStr & binary,const fxStr & ascii)460 Class1Modem::encodePWD(fxStr& binary, const fxStr& ascii)
461 {
462 encodeTSI(binary, ascii);
463 }
464
465 /*
466 * Do the inverse of encodePWD; i.e. convert a binary
467 * string of encoded digits into the equivalent ascii.
468 */
469 const fxStr&
decodePWD(fxStr & ascii,const HDLCFrame & binary)470 Class1Modem::decodePWD(fxStr& ascii, const HDLCFrame& binary)
471 {
472 return decodeTSI(ascii, binary);
473 }
474
475 bool
switchingPause(Status & eresult,u_int times)476 Class1Modem::switchingPause(Status& eresult, u_int times)
477 {
478 /*
479 * If class1SwitchingCmd is of the AT+FRS=n form we honor
480 * the caller's indicattion for a multiplication of the
481 * configured silence detection. This is primarily used
482 * to avoid sending CRP as a receiver during a sender's TCF,
483 * but it could also be used in places where we find a
484 * longer wait often necessary.
485 */
486 fxStr scmd = fxStr(conf.class1SwitchingCmd);
487 if (times != 1) {
488 fxStr ncmd = fxStr(scmd);
489 ncmd.raiseatcmd();
490 if (ncmd.length() > 7 && ncmd.head(7) == "AT+FRS=") {
491 int dur = atoi(ncmd.tail(ncmd.length()-7)) * times;
492 scmd = scmd.head(7) | fxStr(dur, "%d");
493 }
494 }
495 if (!silenceHeard && !atCmd(scmd, AT_OK)) {
496 eresult = Status(100, "Failure to receive silence (synchronization failure).");
497 protoTrace(eresult.string());
498 if (wasTimeout()) abortReceive();
499 return (false);
500 }
501 /*
502 * We necessarily use class1SwitchingCmd rather frequently...
503 * sometimes this is programmed to be immediately before our signalling,
504 * and sometimes this is programmed to be immediately after the remote
505 * signalling. That doesn't therefore give us very good control on
506 * ensuring that class1SwitchingCmd is not issued in duplicate in some
507 * kinds of program flow.
508 *
509 * Ideally we'd be able to standardize on issuing class1SwitchingCmd
510 * only in one case or another (but not both), but that's not particularly
511 * an easy ideal to realize given the number of exceptions to that rule
512 * that would neccesarily be required.
513 *
514 * So for now we just set this flag here, and we unset it in atCmd, and
515 * if the flag is set when we come back here, then we can avoid duplication.
516 */
517 silenceHeard = true;
518 return (true);
519 }
520
521 /*
522 * Pass data to modem, filtering DLE's and
523 * optionally including the end-of-data
524 * marker <DLE><ETX>.
525 *
526 * If the data transfer is aborted by the user
527 * then we must take care to send <DLE><ETX>
528 * in order to exit gracefully.
529 */
530 bool
sendClass1Data(const u_char * data,u_int cc,const u_char * bitrev,bool eod,long ms)531 Class1Modem::sendClass1Data(const u_char* data, u_int cc,
532 const u_char* bitrev, bool eod, long ms)
533 {
534 bool ok = putModemDLEData(data, cc, bitrev, ms, conf.doPhaseCDebug);
535 if (eod || abortRequested()) {
536 u_char buf[2];
537 buf[0] = DLE;
538 buf[1] = ETX;
539 ok = putModemData(buf, 2);
540 return (ok && !abortRequested());
541 } else
542 return (ok);
543 }
544
545 /*
546 * Receive timed out, abort the operation
547 * and resynchronize before returning.
548 */
549 void
abortReceive()550 Class1Modem::abortReceive()
551 {
552 if (useV34) return; // nothing to do in V.34
553 bool b = wasTimeout();
554 char c = CAN; // anything other than DC1/DC3
555 putModem(&c, 1, 1);
556 /*
557 * If the modem handles abort properly, then just
558 * wait for an OK result. Otherwise, wait a short
559 * period of time, flush any input, and then send
560 * "AT" and wait for the return "OK".
561 */
562 if (conf.class1RecvAbortOK == 0) { // modem doesn't send OK response
563 pause(200);
564 flushModemInput();
565 (void) atCmd("AT", AT_OK, 100);
566 } else
567 while (!waitFor(AT_OK, conf.class1RecvAbortOK) && lastResponse == AT_OTHER && !wasTimeout());
568 setTimeout(b); // XXX putModem clobbers timeout state
569 }
570
571 /*
572 * Request a primary rate renegotiation.
573 */
574 bool
renegotiatePrimary(bool constrain)575 Class1Modem::renegotiatePrimary(bool constrain)
576 {
577 u_char buf[4];
578 u_short size = 0;
579 buf[size++] = DLE;
580 if (constrain) {
581 // don't neotiate a faster rate
582 if (primaryV34Rate == 1) buf[size++] = 0x70; // 2400 bit/s
583 else if (primaryV34Rate == 2 || primaryV34Rate == 3) {
584 /*
585 * V.34 bitspeed 2400 is only possible with symbolrate 2400, and
586 * as we have no way of determining the symbolrate, we cannot
587 * wisely instruct the modem to use 2400 bps unless the modem
588 * negotiates it independently.
589 */
590 buf[size++] = 0x71; // 4800 bit/s
591 } else buf[size++] = primaryV34Rate + 0x6D; // drop 4800 bit/s
592 buf[size++] = DLE;
593 }
594 buf[size++] = 0x6C; // <DLE><pph>
595 if (!putModemData(buf, size)) return (false);
596 if (constrain)
597 protoTrace("Request primary rate renegotiation (limit %u bit/s).",
598 primaryV34Rate == 1 ? 2400 : primaryV34Rate > 3 ? (primaryV34Rate-2)*2400 : 4800);
599 else
600 protoTrace("Request primary rate renegotiation.");
601 return (true);
602 }
603
604 /*
605 * Wait for a <DLE><ctrl> response per T.31-A1 B.8.4.
606 */
607 bool
waitForDCEChannel(bool awaitctrl)608 Class1Modem::waitForDCEChannel(bool awaitctrl)
609 {
610 time_t start = Sys::now();
611 int c;
612 fxStr garbage;
613 bool gotresponse = false;
614 gotRTNC = false;
615 ctrlFrameRcvd = fxStr::null;
616 do {
617 c = getModemChar(60000);
618 if (c == DLE) {
619 /*
620 * With V.34-faxing we expect <DLE><command>
621 * Refer to T.31-A1 Table B.1. Except for EOT
622 * these are merely indicators and do not require
623 * action.
624 */
625 c = getModemChar(60000);
626 switch (c) {
627 case EOT:
628 protoTrace("EOT received (end of transmission)");
629 gotEOT = true;
630 recvdDCN = true;
631 return (false);
632 case 0x69:
633 protoTrace("Control channel retrain");
634 // wait for the control channel to reappear
635 // should we reset the timeout setting?
636 gotresponse = waitForDCEChannel(true);
637 gotRTNC = true;
638 return ((awaitctrl ? gotresponse : false));
639 case 0x6B:
640 protoTrace("Primary channel selected");
641 gotCTRL = false;
642 continue;
643 case 0x6D:
644 protoTrace("Control channel selected");
645 gotCTRL = true;
646 continue;
647 case 0x6E: // 1200 bit/s
648 case 0x6F: // 2400 bit/s
649 // control rate indication
650 if (controlV34Rate != (c - 0x6D)) {
651 controlV34Rate = (c - 0x6D);
652 protoTrace("Control channel rate now %u bit/s", controlV34Rate*1200);
653 }
654 if (awaitctrl) gotresponse = true;
655 continue;
656 case 0x70: // 2400 bit/s
657 case 0x71: // 4800 bit/s
658 case 0x72: // 7200 bit/s
659 case 0x73: // 9600 bit/s
660 case 0x74: // 12000 bit/s
661 case 0x75: // 14400 bit/s
662 case 0x76: // 16800 bit/s
663 case 0x77: // 19200 bit/s
664 case 0x78: // 21600 bit/s
665 case 0x79: // 24000 bit/s
666 case 0x7A: // 26400 bit/s
667 case 0x7B: // 28800 bit/s
668 case 0x7C: // 31200 bit/s
669 case 0x7D: // 33600 bit/s
670 // primary rate indication
671 if (primaryV34Rate != (c - 0x6F)) {
672 primaryV34Rate = (c - 0x6F);
673 protoTrace("Primary channel rate now %u bit/s", primaryV34Rate*2400);
674 }
675 if (!awaitctrl) gotresponse = true;
676 continue;
677 default:
678 // unexpected <DLE><command>, deem as garbage
679 garbage.append(DLE);
680 garbage.append(c);
681 break;
682 }
683 } else garbage.append(c);
684 if (gotCTRL && garbage.length() > 2 && (garbage[0] & 0xFF) == 0xFF &&
685 (garbage[garbage.length()-2] & 0xFF) == 0x10 &&
686 (garbage[garbage.length()-1] & 0xFF) == 0x03) {
687 // We got a control frame and won't get the channel change...
688 for (u_int i = 0; i < garbage.length()-2; i++) {
689 if ((garbage[i] & 0xFF) == DLE && ++i < garbage.length()) {
690 /*
691 * We've got a frame and must apply T.31-A1 Table B.1.
692 */
693 if ((garbage[i] & 0xFF) == 0x07) { // end of HDLC frame w/FCS error
694 // what to do? send CRP? discard frame?
695 continue;
696 }
697 switch (garbage[i] & 0xFF) {
698 case DLE: // <DLE><DLE> => <DLE>
699 ctrlFrameRcvd.append(DLE);
700 break;
701 case SUB: // <DLE><SUB> => <DLE><DLE>
702 ctrlFrameRcvd.append(DLE);
703 ctrlFrameRcvd.append(DLE);
704 break;
705 case 0x51: // <DLE><0x51> => <DC1>
706 ctrlFrameRcvd.append(DC1);
707 break;
708 case 0x53: // <DLE><0x53> => <DC3>
709 ctrlFrameRcvd.append(0x13);
710 break;
711 }
712 } else
713 ctrlFrameRcvd.append(garbage[i] & 0xFF);
714 }
715 return (false);
716 }
717 fxStr rcpsignal;
718 rcpsignal.append(0xFF); rcpsignal.append(0x03); rcpsignal.append(0x86); rcpsignal.append(0x69);
719 rcpsignal.append(0xCB); rcpsignal.append(0x10); rcpsignal.append(0x03);
720 if (!gotCTRL && garbage == rcpsignal) {
721 // We anticipate getting "extra" RCP frames since we
722 // only look for one but usually we will see three.
723 garbage.cut(0, 7);
724 }
725 } while (!gotresponse && Sys::now()-start < 60);
726 if (getHDLCTracing() && garbage.length()) {
727 fxStr buf;
728 u_int j = 0;
729 for (u_int i = 0; i < garbage.length(); i++) {
730 if (j > 0)
731 buf.append(' ');
732 buf.append(fxStr(garbage[i] & 0xFF, "%2.2X"));
733 j++;
734 if (j > 19) {
735 protoTrace("--> [%u:%.*s]",
736 j, buf.length(), (const char*) buf);
737 buf = "";
738 j = 0;
739 }
740 }
741 if (j)
742 protoTrace("--> [%u:%.*s]",
743 j, buf.length(), (const char*) buf);
744 }
745 return (gotresponse);
746 }
747
748 /*
749 * Receive an HDLC frame. The frame itself must
750 * be received within 3 seconds (per the spec).
751 * If a carrier is received, but the complete frame
752 * is not received before the timeout, the receive
753 * is aborted.
754 */
755 bool
recvRawFrame(HDLCFrame & frame)756 Class1Modem::recvRawFrame(HDLCFrame& frame)
757 {
758 /*
759 * The spec says that a frame that takes between
760 * 2.55 and 3.45 seconds to be received may be
761 * discarded; we also add some time for DCE
762 * to detect and strip flags.
763 * We need to be generous here ... given that
764 * some frames can be long and some devices
765 * can add lots of flags to the signalling.
766 * The previous value of 5 seconds appears
767 * to have been too conservative; if the modem
768 * has said CONNECT, then it should be
769 * responsible enough to carry-through with
770 * things. A timeout here is only needed to
771 * reign in modems that don't carry through.
772 */
773 startTimeout(10000);
774 /*
775 * Strip HDLC frame flags. This is not needed,
776 * (according to the standard DCE does the job),
777 * be we leave this legacy code unchanged
778 * for sure - D.B.
779 */
780 int c;
781 fxStr garbage;
782
783 for (;;) {
784 c = getModemChar(0);
785 if (c == 0xff || c == EOF)
786 break;
787 if (useV34 && c == DLE) {
788 c = getModemChar(0);
789 switch (c) {
790 case EOT:
791 protoTrace("EOT received (end of transmission)");
792 gotEOT = true;
793 recvdDCN = true;
794 return (false);
795 case 0x69:
796 protoTrace("Control channel retrain");
797 // wait for the control channel to reappear
798 // should we reset the timeout setting?
799 waitForDCEChannel(true);
800 gotRTNC = true;
801 return (false);
802 default:
803 // unexpected <DLE><command>, deem as garbage
804 garbage.append(DLE);
805 break;
806 }
807 }
808 garbage.append(c);
809 if ( garbage.length() >= 2 && garbage.tail(2) == "\r\n") {
810 /*
811 * CR+LF received before address field.
812 * We expect result code (though it's possible
813 * that CR+LF is a part of garbage frame)
814 */
815 garbage = garbage.head(garbage.length() - 2);
816 break;
817 }
818 }
819
820 if (getHDLCTracing() && garbage.length()) {
821 fxStr buf;
822 u_int j = 0;
823 for (u_int i = 0; i < garbage.length(); i++) {
824 if (j > 0)
825 buf.append(' ');
826 buf.append(fxStr(garbage[i] & 0xFF, "%2.2X"));
827 j++;
828 if (j > 19) {
829 protoTrace("--> [%u:%.*s]",
830 j, buf.length(), (const char*) buf);
831 buf = "";
832 j = 0;
833 }
834 }
835 if (j)
836 protoTrace("--> [%u:%.*s]",
837 j, buf.length(), (const char*) buf);
838 }
839
840 if (c == 0xff) { // address field received
841 do {
842 if (c == DLE) {
843 c = getModemChar(0);
844 if (c == ETX || c == EOF)
845 break;
846 if (useV34) {
847 /*
848 * T.31-A1 Table B.1
849 * These indicate transparancy, shielding, or delimiting.
850 */
851 if (c == 0x07) { // end of HDLC frame w/FCS error
852 break;
853 }
854 switch (c) {
855 case EOT:
856 protoTrace("EOT received (end of transmission)");
857 gotEOT = true;
858 recvdDCN = true;
859 return (false);
860 case DLE: // <DLE><DLE> => <DLE>
861 break;
862 case SUB: // <DLE><SUB> => <DLE><DLE>
863 frame.put(frameRev[DLE]);
864 break;
865 case 0x51: // <DLE><0x51> => <DC1>
866 c = DC1;
867 break;
868 case 0x53: // <DLE><0x53> => <DC3>
869 c = 0x13;
870 break;
871 }
872 } else {
873 /*
874 * Some modems may not double-up the in-data DLEs like they should.
875 */
876 if (conf.class1ModemHasDLEBug) frame.put(frameRev[DLE]);
877 else if (c != DLE) {
878 protoTrace("Odd. Modem reported meaningless <DLE><0x%X>. Possible DLE bug indication.", c);
879 }
880 }
881 }
882 frame.put(frameRev[c]);
883 } while ((c = getModemChar(0)) != EOF);
884 }
885 stopTimeout("receiving HDLC frame data");
886 if (frame.getLength() > 0)
887 traceHDLCFrame("-->", frame);
888 if (wasTimeout()) {
889 abortReceive();
890 return (false);
891 }
892 /*
893 * Now collect the "OK", "ERROR", or "FCERROR"
894 * response telling whether or not the FCS was
895 * legitimate.
896 */
897 if (!useV34 && !waitFor(AT_OK)) {
898 if (lastResponse == AT_ERROR)
899 protoTrace("FCS error");
900 return (false);
901 }
902 if (useV34 && c == 0x07) {
903 protoTrace("FCS error");
904 return (false);
905 }
906 if (frame.getFrameDataLength() < 1) {
907 protoTrace("HDLC frame too short (%u bytes)", frame.getLength());
908 return (false);
909 }
910 if ((frame[1]&0xf7) != 0xc0) {
911 protoTrace("HDLC frame with bad control field %#x", frame[1]);
912 return (false);
913 }
914 if (conf.class1ValidateV21Frames && !frame.checkCRC()) {
915 protoTrace("FCS error (calculated)");
916 return (false);
917 }
918 frameRcvd = "";
919 for (u_int i = 0; i < frame.getLength(); i++) frameRcvd.append(frame[i]);
920 frame.setOK(true);
921 return (true);
922 }
923
924 bool
syncECMFrame()925 Class1Modem::syncECMFrame()
926 {
927 /*
928 * We explicitly look for the first sync flag so as to
929 * not get confused by any initial garbage or training.
930 */
931 int bit = 0;
932 u_short ones = 0;
933
934 // look for the first sync flag
935
936 time_t start = Sys::now();
937 startTimeout(60000); // despite indications by T.4 A.3.1
938 do {
939 if ((unsigned) Sys::now()-start >= 60) {
940 protoTrace("Timeout awaiting synchronization sequence");
941 setTimeout(true);
942 return (false);
943 }
944 bit = getModemBit(0);
945 } while (bit != 0 && !didBlockEnd());
946 do {
947 if ((unsigned) Sys::now()-start >= 60) {
948 protoTrace("Timeout awaiting synchronization sequence");
949 setTimeout(true);
950 return (false);
951 }
952 if (bit == 0 || ones > 0xFF) ones = 0;
953 bit = getModemBit(0);
954 if (bit == 1) ones++;
955 } while (!(ones == 6 && bit == 0 && bit != EOF) && !didBlockEnd());
956 stopTimeout("awaiting synchronization sequence");
957 if (wasTimeout()) {
958 return (false);
959 }
960 return (true);
961 }
962
963 /*
964 * Receive an HDLC frame with ECM. We must always be cautious
965 * of "stuffed" zero-bits after five sequential one-bits between
966 * flag sequences. We assume this is called only after a
967 * successfuly received complete flag sequence.
968 *
969 * Things are significantly more simple with V.34-fax ECM since
970 * there is no synchronization or RCP frames. In this case we
971 * simply have to handle byte transparancy and shielding, looking
972 * for byte-aligned frame delimiters.
973 */
974 bool
recvECMFrame(HDLCFrame & frame)975 Class1Modem::recvECMFrame(HDLCFrame& frame)
976 {
977 if (useV34) {
978 int c;
979 for (;;) {
980 c = getModemChar(60000);
981 if (wasTimeout()) {
982 return (false);
983 }
984 if (c == DLE) {
985 c = getModemChar(60000);
986 if (wasTimeout()) {
987 return (false);
988 }
989 switch (c) {
990 case DLE:
991 break;
992 case SUB:
993 frame.put(frameRev[DLE]);
994 break;
995 case 0x51:
996 c = 0x11;
997 break;
998 case 0x53:
999 c = 0x13;
1000 break;
1001 case ETX:
1002 if (frame.getLength() > 0)
1003 traceHDLCFrame("-->", frame, true);
1004 if (frame.getLength() < 5) { // RCP frame size
1005 protoTrace("HDLC frame too short (%u bytes)", frame.getLength());
1006 return (false);
1007 }
1008 if (frame[0] != 0xff) {
1009 protoTrace("HDLC frame with bad address field %#x", frame[0]);
1010 return (false);
1011 }
1012 if ((frame[1]&0xf7) != 0xc0) {
1013 protoTrace("HDLC frame with bad control field %#x", frame[1]);
1014 return (false);
1015 }
1016 return (true);
1017 case 0x07:
1018 protoTrace("FCS error");
1019 return (false);
1020 case 0x04:
1021 protoTrace("EOT received (end of transmission)");
1022 gotEOT = true;
1023 recvdDCN = true;
1024 return (false);
1025 case 0x6D:
1026 protoTrace("Control channel selected");
1027 gotCTRL = true;
1028 return (false);
1029 default:
1030 protoTrace("got <DLE><%X>", c);
1031 break;
1032 }
1033 }
1034 frame.put(frameRev[c]);
1035 }
1036 }
1037
1038 int bit = getModemBit(60000);
1039 u_short ones = 0;
1040
1041 // look for the last sync flag (possibly the previous one)
1042
1043 // some senders use this as the time to do framing so we must wait longer than T.4 A.3.1 implies
1044 time_t start = Sys::now();
1045 while (bit != 1 && bit != EOF && !didBlockEnd()) { // flag begins with zero, address begins with one
1046 do {
1047 if ((unsigned) Sys::now()-start >= 300) { // 5 minutes of synchronization is too much
1048 protoTrace("Timeout waiting for the last synchronization flag");
1049 return false;
1050 }
1051 if (bit == 0 || ones > 6) ones = 0;
1052 bit = getModemBit(60000);
1053 if (bit == 1) ones++;
1054 } while (!(ones == 6 && bit == 0 && bit != EOF) && !didBlockEnd());
1055 ones = 0;
1056 bit = getModemBit(60000);
1057 }
1058
1059 // receive the frame, strip stuffed zero-bits, and look for end flag
1060
1061 ones = 1;
1062 u_short bitpos = 7;
1063 u_int byte = (bit << bitpos);
1064 bool rcpframe = false;
1065 start = Sys::now();
1066 do {
1067 if ((unsigned) Sys::now()-start >= 3) {
1068 protoTrace("Timeout receiving HDLC frame");
1069 return (false);
1070 }
1071 bit = getModemBit(60000);
1072 if (bit == 1) {
1073 ones++;
1074 }
1075 if (!(ones == 5 && bit == 0 && bit != EOF)) { // not transparent stuffed zero-bits
1076 bitpos--;
1077 byte |= (bit << bitpos);
1078 if (bitpos == 0) { // fully populated byte
1079 frame.put(byte);
1080 bitpos = 8;
1081 byte = 0;
1082 }
1083 }
1084 if (bit == 0) ones = 0;
1085 // don't wait for the terminating flag on an RCP frame
1086 if (frame[0] == 0xff && frame[1] == 0xc0 && frame[2] == 0x61 && frame.getLength() == 5 && frame.checkCRC()) {
1087 protoTrace("RECV received RCP frame");
1088 rcpframe = true;
1089 } else if (didBlockEnd()) {
1090 // sometimes RCP frames are truncated by or are missing due to premature DLE+ETX characters, sadly
1091 protoTrace("RECV assumed RCP frame with block end");
1092 // force-feed a valid RCP frame with FCS
1093 frame.reset();
1094 frame.put(0xff); frame.put(0xc0); frame.put(0x61); frame.put(0x96); frame.put(0xd3);
1095 rcpframe = true;
1096 }
1097 } while (ones != 6 && bit != EOF && !rcpframe && frame.getLength() < frameSize+6);
1098 if (ones == 6) bit = getModemBit(60000); // trailing bit on flag
1099 if (!rcpframe && frame.getLength() < frameSize+6) {
1100 /*
1101 * The HDLC frame was terminated early by a flag. T.30 A.3.5 states that
1102 * frame size cannot change during one page, and T.4 A.3.6.2 seems to provide
1103 * for padding in order to get that last frame on a block to always line up
1104 * on a byte and frame boundary. However, the NOTE 2 there seemse to give
1105 * leniency to that requirement, and in fact many senders will send short
1106 * frames on the last frame of a block. So we run a couple of additional
1107 * checks here (in addition to FCS checking) to limit the remote chance
1108 * of FCS actually checking out on corrupt data (although that may be very
1109 * remote indeed). We don't do these "trailing flag" tests on normal-sized
1110 * frames because we deliberately don't look for a trailing flag when we
1111 * get enough data.
1112 */
1113 if (bit) { // should have been zero
1114 protoTrace("Bad HDLC terminating flag received.");
1115 return (false);
1116 }
1117 if (byte != 0x7e) { // trailing byte should be flag
1118 protoTrace("HDLC frame not byte-oriented. Trailing byte: %#x", byte);
1119 return (false);
1120 }
1121 }
1122 traceHDLCFrame("-->", frame, true);
1123 if (bit == EOF) {
1124 protoTrace("EOF received.");
1125 return (false);
1126 }
1127 if (frame.getLength() < 5) { // RCP frame size
1128 protoTrace("HDLC frame too short (%u bytes)", frame.getLength());
1129 return (false);
1130 }
1131 if (frame[0] != 0xff) {
1132 protoTrace("HDLC frame with bad address field %#x", frame[0]);
1133 return (false);
1134 }
1135 if ((frame[1]&0xf7) != 0xc0) {
1136 protoTrace("HDLC frame with bad control field %#x", frame[1]);
1137 return (false);
1138 }
1139 return (true);
1140 }
1141
1142 bool
endECMBlock()1143 Class1Modem::endECMBlock()
1144 {
1145 if (didBlockEnd()) return (true); // some erroniously re-use bytes
1146
1147 int c = getLastByte(); // some erroniously re-use bits
1148 time_t start = Sys::now();
1149 setTimeout(false);
1150 do {
1151 if ((unsigned) Sys::now()-start >= 60) { // 60 seconds of garbage after RCP is too much
1152 protoTrace("Timeout waiting for DLE+ETX");
1153 setTimeout(true);
1154 return false;
1155 }
1156 if (c == DLE) {
1157 c = getModemChar(30*1000);
1158 if (c == ETX || c == EOF)
1159 break;
1160 }
1161 } while ((c = getModemChar(30*1000)) != EOF);
1162 if (c == EOF) return (false);
1163 else return (true);
1164 }
1165
1166 #include "StackBuffer.h"
1167
1168 /*
1169 * Log an HLDC frame along with a time stamp (secs.10ms).
1170 */
1171 void
traceHDLCFrame(const char * direction,const HDLCFrame & frame,bool isecm)1172 Class1Modem::traceHDLCFrame(const char* direction, const HDLCFrame& frame, bool isecm)
1173 {
1174 if (!isecm) {
1175 if (!getHDLCTracing()) return;
1176 } else {
1177 if (!getECMTracing()) return;
1178 }
1179 const char* hexdigits = "0123456789ABCDEF";
1180 fxStackBuffer buf;
1181 for (u_int i = 0; i < frame.getLength(); i++) {
1182 u_char b = frame[i];
1183 if (i > 0)
1184 buf.put(' ');
1185 buf.put(hexdigits[b>>4]);
1186 buf.put(hexdigits[b&0xf]);
1187 }
1188 protoTrace("%s HDLC<%u:%.*s>", direction,
1189 frame.getLength(), buf.getLength(), (const char*) buf);
1190 }
1191
1192 /*
1193 * Send a raw HDLC frame and wait for the modem response.
1194 * The modem is expected to be an HDLC frame sending mode
1195 * (i.e. +FTH=3 or similar has already be sent to the modem).
1196 * The T.30 max frame length is enforced with a 3 second
1197 * timeout on the send.
1198 */
1199 bool
sendRawFrame(HDLCFrame & frame)1200 Class1Modem::sendRawFrame(HDLCFrame& frame)
1201 {
1202 traceHDLCFrame("<--", frame);
1203 if (frame.getLength() < 3) {
1204 protoTrace("HDLC frame too short (%u bytes)", frame.getLength());
1205 return (false);
1206 }
1207 if (frame[0] != 0xff) {
1208 protoTrace("HDLC frame with bad address field %#x", frame[0]);
1209 return (false);
1210 }
1211 if ((frame[1]&0xf7) != 0xc0) {
1212 protoTrace("HDLC frame with bad control field %#x", frame[1]);
1213 return (false);
1214 }
1215 signalSent = "";
1216 for (u_int i = 0; i < frame.getLength(); i++) signalSent.append(frame[i]);
1217 /*
1218 * sendFrame() is always called with a timeout set.
1219 * Let's keep it that way
1220 */
1221 return (sendClass1Data(frame, frame.getLength(), frameRev, true, 0) &&
1222 (useV34 ? true : waitFor(frame.moreFrames() ? AT_CONNECT : AT_OK, 0)));
1223 }
1224
1225 /*
1226 * Send a single byte frame.
1227 */
1228 bool
sendFrame(u_char fcf,bool lastFrame)1229 Class1Modem::sendFrame(u_char fcf, bool lastFrame)
1230 {
1231 HDLCFrame frame(conf.class1FrameOverhead);
1232 frame.put(0xff);
1233 frame.put(lastFrame ? 0xc8 : 0xc0);
1234 frame.put(fcf);
1235 return (sendRawFrame(frame));
1236 }
1237
1238 /*
1239 * Send a frame with DCS/DIS.
1240 */
1241 bool
sendFrame(u_char fcf,FaxParams & dcs_caps,bool lastFrame)1242 Class1Modem::sendFrame(u_char fcf, FaxParams& dcs_caps, bool lastFrame)
1243 {
1244 HDLCFrame frame(conf.class1FrameOverhead);
1245 frame.put(0xff);
1246 frame.put(lastFrame ? 0xc8 : 0xc0);
1247 frame.put(fcf);
1248
1249 int curByte = 0;
1250 //add dcs bytes an any optional bytes
1251 frame.put(dcs_caps.getByte(curByte));
1252 while (dcs_caps.hasNextByte(curByte)) {
1253 curByte += 1;
1254 frame.put(dcs_caps.getByte(curByte));
1255 }
1256
1257 return (sendRawFrame(frame));
1258 }
1259
1260 /*
1261 * Send a frame with TSI/CSI/PWD/SUB/SEP/PPR.
1262 */
1263 bool
sendFrame(u_char fcf,const fxStr & tsi,bool lastFrame)1264 Class1Modem::sendFrame(u_char fcf, const fxStr& tsi, bool lastFrame)
1265 {
1266 HDLCFrame frame(conf.class1FrameOverhead);
1267 frame.put(0xff);
1268 frame.put(lastFrame ? 0xc8 : 0xc0);
1269 frame.put(fcf);
1270 frame.put((const u_char*)(const char*)tsi, tsi.length());
1271 return (sendRawFrame(frame));
1272 }
1273
1274 /*
1275 * Send a frame with NSF.
1276 */
1277 bool
sendFrame(u_char fcf,const u_char * code,const fxStr & nsf,bool lastFrame)1278 Class1Modem::sendFrame(u_char fcf, const u_char* code, const fxStr& nsf, bool lastFrame)
1279 {
1280 HDLCFrame frame(conf.class1FrameOverhead);
1281 frame.put(0xff);
1282 frame.put(lastFrame ? 0xc8 : 0xc0);
1283 frame.put(fcf);
1284 frame.put(code, 3); // should be in LSBMSB already
1285 frame.put((const u_char*)(const char*)nsf, nsf.length());
1286 return (sendRawFrame(frame));
1287 }
1288
1289 bool
transmitFrame(fxStr & signal)1290 Class1Modem::transmitFrame(fxStr& signal)
1291 {
1292 HDLCFrame frame(conf.class1FrameOverhead);
1293 for (u_int i = 0; i < signal.length(); i++) frame.put(signal[i]);
1294 startTimeout(7550);
1295 bool frameSent = useV34 ? true : atCmd(thCmd, AT_NOTHING, 0);
1296 if (frameSent) frameSent = useV34 ? true : atResponse(rbuf, 0) == AT_CONNECT;
1297 if (frameSent) frameSent = sendRawFrame(frame);
1298 else if (lastResponse == AT_ERROR) gotEOT = true; // on hook
1299 stopTimeout("sending HDLC frame");
1300 return (frameSent);
1301 }
1302
1303 bool
transmitFrame(u_char fcf,bool lastFrame)1304 Class1Modem::transmitFrame(u_char fcf, bool lastFrame)
1305 {
1306 startTimeout(7550);
1307 bool frameSent = useV34 ? true : atCmd(thCmd, AT_NOTHING, 0);
1308 if (frameSent) frameSent = useV34 ? true : atResponse(rbuf, 0) == AT_CONNECT;
1309 if (frameSent) frameSent = sendFrame(fcf, lastFrame);
1310 else if (lastResponse == AT_ERROR) gotEOT = true; // on hook
1311 stopTimeout("sending HDLC frame");
1312 return (frameSent);
1313 }
1314
1315 bool
transmitFrame(u_char fcf,FaxParams & dcs_caps,bool lastFrame)1316 Class1Modem::transmitFrame(u_char fcf, FaxParams& dcs_caps, bool lastFrame)
1317 {
1318 /*
1319 * The T.30 spec says no frame can take more than 3 seconds
1320 * (+/- 15%) to transmit. But the DCE can take as much as 5
1321 * seconds to respond CONNECT or result OK, per T.31.
1322 */
1323 startTimeout(7550);
1324 bool frameSent = useV34 ? true : atCmd(thCmd, AT_NOTHING, 0);
1325 if (frameSent) frameSent = useV34 ? true : atResponse(rbuf, 0) == AT_CONNECT;
1326 if (frameSent) frameSent = sendFrame(fcf, dcs_caps, lastFrame);
1327 else if (lastResponse == AT_ERROR) gotEOT = true; // on hook
1328 stopTimeout("sending HDLC frame");
1329 return (frameSent);
1330 }
1331
1332 bool
transmitFrame(u_char fcf,const fxStr & tsi,bool lastFrame)1333 Class1Modem::transmitFrame(u_char fcf, const fxStr& tsi, bool lastFrame)
1334 {
1335 startTimeout(7550);
1336 bool frameSent = useV34 ? true : atCmd(thCmd, AT_NOTHING, 0);
1337 if (frameSent) frameSent = useV34 ? true : atResponse(rbuf, 0) == AT_CONNECT;
1338 if (frameSent) frameSent = sendFrame(fcf, tsi, lastFrame);
1339 else if (lastResponse == AT_ERROR) gotEOT = true; // on hook
1340 stopTimeout("sending HDLC frame");
1341 return (frameSent);
1342 }
1343
1344 bool
transmitFrame(u_char fcf,const u_char * code,const fxStr & nsf,bool lastFrame)1345 Class1Modem::transmitFrame(u_char fcf, const u_char* code, const fxStr& nsf, bool lastFrame)
1346 {
1347 startTimeout(7550);
1348 bool frameSent = useV34 ? true : atCmd(thCmd, AT_NOTHING, 0);
1349 if (frameSent) frameSent = useV34 ? true : atResponse(rbuf, 0) == AT_CONNECT;
1350 if (frameSent) frameSent = sendFrame(fcf, code, nsf, lastFrame);
1351 else if (lastResponse == AT_ERROR) gotEOT = true; // on hook
1352 stopTimeout("sending HDLC frame");
1353 return (frameSent);
1354 }
1355
1356 /*
1357 * Send data using the specified signalling rate.
1358 */
1359 bool
transmitData(int br,u_char * data,u_int cc,const u_char * bitrev,bool eod)1360 Class1Modem::transmitData(int br, u_char* data, u_int cc,
1361 const u_char* bitrev, bool eod)
1362 {
1363 if (flowControl == FLOW_XONXOFF)
1364 setXONXOFF(FLOW_XONXOFF, FLOW_NONE, ACT_FLUSH);
1365 fxStr tmCmd(br, tmCmdFmt);
1366 bool ok = atCmd(tmCmd, AT_CONNECT);
1367 if (ok) {
1368
1369 // T.31 8.3.3 requires the DCE to report CONNECT at the beginning
1370 // of transmission of the training pattern rather than at the end.
1371 // We pause here to allow the remote's +FRM to result in CONNECT.
1372 // This delay will vary depending on the modem's adherence to T.31.
1373 pause(conf.class1TMConnectDelay);
1374
1375 ok = sendClass1Data(data, cc, bitrev, eod, getDataTimeout());
1376 if (ok && eod) {
1377 ok = false;
1378 u_short attempts = 0;
1379 lastResponse = AT_NOTHING;
1380 while (!ok && lastResponse != AT_NOCARRIER && attempts++ < 3) {
1381 ok = waitFor(AT_OK, 60*1000); // wait up to 60 seconds for "OK"
1382 }
1383 }
1384 } else if (lastResponse == AT_ERROR) gotEOT = true; // on hook
1385 if (flowControl == FLOW_XONXOFF)
1386 setXONXOFF(FLOW_NONE, FLOW_NONE, ACT_DRAIN);
1387 return (ok);
1388 }
1389
1390 /*
1391 * Receive an HDLC frame. The timeout is against
1392 * the receipt of the HDLC flags; the frame itself must
1393 * be received within 3 seconds (per the spec).
1394 * If a carrier is received, but the complete frame
1395 * is not received before the timeout, the receive
1396 * is aborted.
1397 *
1398 * If the frame is received in error, then in instances
1399 * where the other end is likely to be able to receive
1400 * it, we can transmit CRP to get the other end to
1401 * retransmit the frame.
1402 */
1403 bool
recvFrame(HDLCFrame & frame,u_char dir,long ms,bool readPending,bool docrp,bool usehooksensitivity)1404 Class1Modem::recvFrame(HDLCFrame& frame, u_char dir, long ms, bool readPending, bool docrp, bool usehooksensitivity)
1405 {
1406 bool gotframe;
1407 u_short crpcnt = 0, rhcnt = 0;
1408 u_int onhooks = 0;
1409 gotCONNECT = true;
1410 time_t start = Sys::now();
1411 if (useV34) {
1412 do {
1413 if (crpcnt) traceFCF(dir == FCF_SNDR ? "SEND send" : "RECV send", FCF_CRP);
1414 frame.reset();
1415 gotframe = recvRawFrame(frame);
1416 } while (!gotframe && !gotRTNC && !gotEOT && docrp && crpcnt++ < 3 && !wasTimeout() && transmitFrame(dir|FCF_CRP));
1417 return (gotframe);
1418 }
1419 startTimeout(ms);
1420 if (!readPending) {
1421 /*
1422 * Hopefully the modem is smart enough to *not* do +FCERROR after +FRH=3,
1423 * as it is only a stumbling-block for us and cannot be beneficial. But,
1424 * in case it adheres blindly to the spec, we'll repeat ourselves here
1425 * until we timeout or we do get the V.21 carrier. We do slow the looping
1426 * with a pause to prevent unwanted massive amounts of tracing. The pause
1427 * needs to be short enough, though, that the modem will still pick up
1428 * any V.21 signalling if it misses that much of the startup.
1429 */
1430 do {
1431 readPending = atCmd(rhCmd, AT_NOTHING, 0) && waitFor(AT_CONNECT, 0);
1432 if (lastResponse == AT_FCERROR) pause(200);
1433 if (lastResponse == AT_ERROR && !wasTimeout() && ++onhooks <= conf.class1HookSensitivity) {
1434 if (!usehooksensitivity) {
1435 /*
1436 * Class1HookSensitivity is used by the calling function, not us.
1437 */
1438 break;
1439 } else {
1440 stopTimeout("");
1441 startTimeout(ms);
1442 }
1443 }
1444 } while (((u_int) Sys::now()-start < howmany(conf.t1Timer, 1000)) && !wasTimeout() &&
1445 (lastResponse == AT_FCERROR || (lastResponse == AT_ERROR && onhooks <= conf.class1HookSensitivity)));
1446 }
1447 if (readPending) {
1448 stopTimeout("waiting for HDLC flags");
1449 if (wasTimeout()){
1450 abortReceive();
1451 return (false);
1452 }
1453 Status eresult;
1454 do {
1455 if (crpcnt || rhcnt) {
1456 if (rhcnt) crpcnt = 0;
1457 if (crpcnt) {
1458 rhcnt = 0;
1459 traceFCF(dir == FCF_SNDR ? "SEND send" : "RECV send", FCF_CRP);
1460 }
1461 do {
1462 lastResponse = AT_NOTHING;
1463 startTimeout(ms);
1464 if (!(atCmd(rhCmd, AT_NOTHING, 0) && waitFor(AT_CONNECT,0))) {
1465 stopTimeout("waiting for v.21 carrier");
1466 if (wasTimeout()) {
1467 abortReceive();
1468 setTimeout(false);
1469 }
1470 if (lastResponse != AT_NOCARRIER || rhcnt++ > 30) return (false);
1471 }
1472 stopTimeout("waiting for v.21 carrier");
1473 /*
1474 * The meaning of a direct NO CARRIER response/result to the AT+FRH=3
1475 * command can be interpreted two ways due to wording in ITU T.31.
1476 * The more traditional interpretation is that it is out-of-spec: that
1477 * a NO CARRIER response should only come after a CONNECT message.
1478 * However, T.31 gives sample sessions that illustrate precisely this
1479 * kind of out-of-spec sequence:
1480 *
1481 * <-- AT+FRH=3
1482 * --> NO CARRIER
1483 *
1484 * And the interpretation is clear to indicate that in this case the
1485 * modem detected a carrier, but it apparently was not V.21 HDLC, and
1486 * the NO CARRIER response indicates that the indeterminate carrier
1487 * has dropped. This functionality is more cumbersome than it is
1488 * helpful (its value is not much different than that of an AT+FRS=1
1489 * command), and what it really means is that we just need to re-issue
1490 * the AT+FRH=3 command until we get something useful as this scenario
1491 * will most likely occur on incidence of Phase C premature carrier loss.
1492 */
1493 } while (lastResponse == AT_NOCARRIER);
1494 }
1495 frame.reset();
1496 gotframe = recvRawFrame(frame);
1497 /*
1498 * Some modems aren't very particular about reporting CONNECT after AT+FRH=3.
1499 * So, for such modems CONNECT may come with V.17 modulated audio or any noise
1500 * whatsoever. Those modems tend to report NO CARRIER after CONNECT, perhaps
1501 * after <DLE><ETX> or some other garbage possibly. NO CARRIER is an invalid
1502 * modem response at that point, anyway. So it is a good indicator for us.
1503 * So we simply repeat AT+FRH=3 in that case.
1504 */
1505 } while ( ((u_int) Sys::now()-start < howmany(conf.t1Timer, 1000) )
1506 && !gotframe && !wasTimeout()
1507 && ( (conf.class1HasRHConnectBug && !frame.getLength() && lastResponse == AT_NOCARRIER && rhcnt++ < 30)
1508 || (docrp && crpcnt++ < 3 && switchingPause(eresult, 3) && transmitFrame(dir|FCF_CRP) )
1509 )); /* triple switchingPause to avoid sending CRP during TCF */
1510 return (gotframe);
1511 } else {
1512 gotCONNECT = false;
1513 if (lastResponse == AT_ERROR) gotEOT = true; // on hook
1514 }
1515 stopTimeout("waiting for v.21 carrier");
1516 if (wasTimeout()) {
1517 abortReceive();
1518 setTimeout(false);
1519 }
1520 return (false);
1521 }
1522
1523 /*
1524 * Receive TCF data using the specified signalling rate.
1525 */
1526 bool
recvTCF(int br,HDLCFrame & buf,const u_char * bitrev,long ms)1527 Class1Modem::recvTCF(int br, HDLCFrame& buf, const u_char* bitrev, long ms)
1528 {
1529 buf.reset();
1530 if (flowControl == FLOW_XONXOFF)
1531 setXONXOFF(FLOW_NONE, FLOW_XONXOFF, ACT_DRAIN);
1532 /*
1533 * Loop waiting for carrier or timeout.
1534 */
1535 bool readPending, gotCarrier;
1536 fxStr rmCmd(br, rmCmdFmt);
1537 startTimeout(ms);
1538 u_short attempts = 0;
1539 do {
1540 readPending = atCmd(rmCmd, AT_NOTHING, 0);
1541 gotCarrier = readPending && waitFor(AT_CONNECT, 0);
1542 } while (readPending && !gotCarrier && lastResponse == AT_FCERROR && ++attempts < conf.class1RMPersistence);
1543 /*
1544 * If carrier was recognized, collect the data.
1545 */
1546 bool gotData = false;
1547 if (gotCarrier) {
1548 int c = getModemChar(0); // NB: timeout is to first byte
1549 stopTimeout("receiving TCF");
1550 if (c != EOF) {
1551 buf.reset();
1552 /*
1553 * Use a timer to receive the 1.5
1554 * second TCF--perhaps if it is too long it
1555 * won't permit us to send the nak in time?
1556 *
1557 * The initial timer needs to be longer than 1.5 seconds
1558 * to support senders that may not start the zeros
1559 * until a second or two after CONNECT. This is
1560 * also why we restart our timeout after the zeros
1561 * start.
1562 */
1563 bool zerosstarted = false;
1564 startTimeout(ms);
1565 do {
1566 if (c == 0x00 && !zerosstarted) {
1567 zerosstarted = true;
1568 startTimeout(ms);
1569 }
1570 if (c == DLE) {
1571 c = getModemChar(0);
1572 if (c == ETX) {
1573 gotData = true;
1574 break;
1575 }
1576 if (c == EOF) {
1577 break;
1578 }
1579 }
1580 buf.put(bitrev[c]);
1581 if (buf.getLength() > 10000) {
1582 setTimeout(true);
1583 break;
1584 }
1585 } while ((c = getModemChar(0)) != EOF);
1586 }
1587 }
1588 stopTimeout("receiving TCF");
1589 /*
1590 * If the +FRM is still pending, abort it.
1591 */
1592 if (readPending && wasTimeout())
1593 abortReceive();
1594 if (flowControl == FLOW_XONXOFF)
1595 setXONXOFF(FLOW_NONE, FLOW_NONE, ACT_DRAIN);
1596 return (gotData);
1597 }
1598
1599 /*
1600 * Modem manipulation support.
1601 */
1602
1603 /*
1604 * Reset a Class 1 modem.
1605 */
1606 bool
reset(long ms)1607 Class1Modem::reset(long ms)
1608 {
1609 return (FaxModem::reset(ms) && setupClass1Parameters());
1610 }
1611
1612 ATResponse
atResponse(char * buf,long ms)1613 Class1Modem::atResponse(char* buf, long ms)
1614 {
1615 if (FaxModem::atResponse(buf, ms) == AT_OTHER && strneq(buf, "+FCERROR", 8))
1616 lastResponse = AT_FCERROR;
1617 if (lastResponse == AT_OTHER && strneq(buf, "+FRH:3", 6))
1618 lastResponse = AT_FRH3;
1619 if (lastResponse == AT_OTHER && strneq(buf, "+F34:", 5)) {
1620 /*
1621 * V.8 handshaking was successful. The rest of the
1622 * session is governed by T.31 Amendment 1 Annex B.
1623 * (This should only happen after ATA or ATD.)
1624 *
1625 * The +F34: response is interpreted according to T.31-A1 B.6.2.
1626 */
1627 buf += 5; // skip "+F34:" prefix
1628 primaryV34Rate = 0;
1629 while (!isdigit(buf[0])) buf++; // move to digits
1630 do {
1631 primaryV34Rate = primaryV34Rate*10 + (buf[0] - '0');
1632 } while (isdigit((++buf)[0]));
1633 controlV34Rate = 0;
1634 while (!isdigit(buf[0])) buf++; // move to digits
1635 do {
1636 controlV34Rate = controlV34Rate*10 + (buf[0] - '0');
1637 } while (isdigit((++buf)[0]));
1638 useV34 = true;
1639 protoTrace("V.8 handshaking succeeded, V.34-Fax (SuperG3) capability enabled.");
1640 protoTrace("Primary channel rate: %u bit/s, Control channel rate: %u bit/s.", primaryV34Rate*2400, controlV34Rate*1200);
1641 modemParams.br |= BIT(primaryV34Rate) - 1;
1642 }
1643 return (lastResponse);
1644 }
1645
1646 /*
1647 * Wait (carefully) for some response from the modem.
1648 */
1649 bool
waitFor(ATResponse wanted,long ms)1650 Class1Modem::waitFor(ATResponse wanted, long ms)
1651 {
1652 for (;;) {
1653 ATResponse response = atResponse(rbuf, ms);
1654 if (response == wanted)
1655 return (true);
1656 switch (response) {
1657 case AT_TIMEOUT:
1658 case AT_EMPTYLINE:
1659 case AT_ERROR:
1660 case AT_NOCARRIER:
1661 case AT_NODIALTONE:
1662 case AT_NOANSWER:
1663 case AT_OFFHOOK:
1664 case AT_RING:
1665 modemTrace("MODEM %s", ATresponses[response]);
1666 /* fall thru... */
1667 case AT_OTHER:
1668 case AT_FCERROR:
1669 case AT_FRH3:
1670 case AT_OK:
1671 return (false);
1672 }
1673 }
1674 }
1675
1676 /*
1677 * Send queryCmd and get a range response.
1678 */
1679 bool
class1Query(const fxStr & queryCmd,Class1Cap caps[])1680 Class1Modem::class1Query(const fxStr& queryCmd, Class1Cap caps[])
1681 {
1682 char response[1024];
1683 if (queryCmd[0] == '!') {
1684 return (parseQuery(queryCmd.tail(queryCmd.length()-1), caps));
1685 }
1686 if (atCmd(queryCmd, AT_NOTHING) && atResponse(response) == AT_OTHER) {
1687 sync(5000);
1688 return (parseQuery(response, caps));
1689 }
1690 return (false);
1691 }
1692
1693 /*
1694 * Map the DCS signalling rate to the appropriate
1695 * Class 1 capability entry.
1696 */
1697 const Class1Cap*
findSRCapability(u_short sr,const Class1Cap caps[])1698 Class1Modem::findSRCapability(u_short sr, const Class1Cap caps[])
1699 {
1700 for (u_int i = NCAPS-1; i > 0; i--) {
1701 const Class1Cap* cap = &caps[i];
1702 if (cap->sr == sr) {
1703 if (cap->mod == V17 && HasShortTraining(cap-1))
1704 cap--;
1705 return (cap);
1706 }
1707 }
1708 // XXX should not happen...
1709 protoTrace("MODEM: unknown signalling rate %#x, using 9600 v.29", sr);
1710 return findSRCapability(DCSSIGRATE_9600V29, caps);
1711 }
1712
1713 /*
1714 * Map the Class 2 bit rate to the best
1715 * signalling rate capability of the modem.
1716 */
1717 const Class1Cap*
findBRCapability(u_short br,const Class1Cap caps[])1718 Class1Modem::findBRCapability(u_short br, const Class1Cap caps[])
1719 {
1720 for (u_int i = NCAPS-1; i > 0; i--) {
1721 const Class1Cap* cap = &caps[i];
1722 if (cap->br == br && cap->ok) {
1723 if (cap->mod == V17 && HasShortTraining(cap-1))
1724 cap--;
1725 return (cap);
1726 }
1727 }
1728 protoTrace("MODEM: unsupported baud rate %#x", br);
1729 return NULL;
1730 }
1731
1732 /*
1733 * Build upon the result from Class2Params.
1734 */
1735 FaxParams
modemDIS() const1736 Class1Modem::modemDIS() const
1737 {
1738 FaxParams dis_caps = FaxModem::modemDIS();
1739
1740 // signalling rates
1741 for (u_short i = 0; i < 4; i++) dis_caps.setBit(11+i, (discap & (0x08>>i)));
1742 if (useV34) dis_caps.setBit(FaxParams::BITNUM_V8_CAPABLE, true);
1743
1744 // preferred ECM frame size
1745 if (conf.class1ECMFrameSize == 64) dis_caps.setBit(FaxParams::BITNUM_FRAMESIZE_DIS, true);
1746
1747 // we set both units preferences to allow the sender to choose
1748 dis_caps.setBit(FaxParams::BITNUM_METRIC_RES, true);
1749 dis_caps.setBit(FaxParams::BITNUM_INCH_RES, true);
1750
1751 // we indicate both letter and legal page size support
1752 dis_caps.setBit(FaxParams::BITNUM_LETTER_SIZE, true);
1753 dis_caps.setBit(FaxParams::BITNUM_LEGAL_SIZE, true);
1754
1755 // selective polling, subaddressing, password
1756 dis_caps.setBit(FaxParams::BITNUM_SEP, true);
1757 dis_caps.setBit(FaxParams::BITNUM_SUB, true);
1758 dis_caps.setBit(FaxParams::BITNUM_PWD, true);
1759
1760 if (conf.class1ECMSupport) {
1761 // JBIG
1762 if (jbigSupported) {
1763 dis_caps.setBit(FaxParams::BITNUM_JBIG_BASIC, true);
1764 dis_caps.setBit(FaxParams::BITNUM_JBIG_L0, true); // JBIG library can handle L0 = 1-Yd
1765 }
1766 /* - disabled for now
1767 // JBIG grey/color requires JPEG grey/color
1768 if (conf.class1GreyJBIGSupport || conf.class1ColorJBIGSupport) {
1769 dis_caps.setBit(FaxParams::BITNUM_JPEG, true);
1770 dis_caps.setBit(FaxParams::BITNUM_JBIG, true);
1771 }
1772 if (conf.class1ColorJBIGSupport)
1773 dis_caps.setBit(FaxParams::BITNUM_FULLCOLOR, true);
1774 */
1775 // JPEG
1776 if (conf.class1GreyJPEGSupport || conf.class1ColorJPEGSupport)
1777 dis_caps.setBit(FaxParams::BITNUM_JPEG, true);
1778 if (conf.class1ColorJPEGSupport)
1779 dis_caps.setBit(FaxParams::BITNUM_FULLCOLOR, true);
1780 }
1781 return dis_caps;
1782 }
1783
1784 const char COMMA = ',';
1785 const char SPACE = ' ';
1786
1787 /*
1788 * Parse a Class 1 parameter string.
1789 */
1790 bool
parseQuery(const char * cp,Class1Cap caps[])1791 Class1Modem::parseQuery(const char* cp, Class1Cap caps[])
1792 {
1793 bool bracket = false, first = true;
1794
1795 while (cp[0]) {
1796 if (cp[0] == SPACE) { // ignore white space
1797 cp++;
1798 continue;
1799 }
1800
1801 /* by a.pogoda@web.de, jan 21st 2002
1802 * workaround for modems sending (<item>,<item>,...), i.e.
1803 * enclosed in brackets rather than just <item>,<item>,...
1804 * e.g. elsa microlink 56k internet II and maybo others
1805 */
1806 if (cp[0]=='(' && first && !bracket) {
1807 /* check whether the first non-space char is an
1808 * opening bracket and skip it if true
1809 */
1810 bracket = true;
1811 cp++;
1812 continue;
1813 }
1814 else if (cp[0]==')' && !first && bracket) {
1815 /* if an opening bracket was scanned before and
1816 * the current char is a closing one, skip it
1817 */
1818 bracket = false;
1819 cp++;
1820 continue;
1821 }
1822 else if (!isdigit(cp[0]))
1823 return (false);
1824
1825 /* state that we already scanned past the first char */
1826 first = false;
1827 int v = 0;
1828 do {
1829 v = v*10 + (cp[0] - '0');
1830 } while (isdigit((++cp)[0]));
1831 int r = v;
1832 if (cp[0] == '-') { // <low>-<high>
1833 cp++;
1834 if (!isdigit(cp[0])) {
1835 return (false);
1836 }
1837 r = 0;
1838 do {
1839 r = r*10 + (cp[0] - '0');
1840 } while (isdigit((++cp)[0]));
1841 }
1842 for (u_int i = 0; i < NCAPS; i++)
1843 if (caps[i].value >= v && caps[i].value <= r) {
1844 caps[i].ok = true;
1845 break;
1846 }
1847 if (cp[0] == COMMA) // <item>,<item>...
1848 cp++;
1849 }
1850 return (true);
1851 }
1852
1853