"<xon>", // AT_XON
"<Unknown response>" // AT_OTHER
};
-const char* ClassModem::callTypes[5] = {
+const char* ClassModem::callTypes[6] = {
"unknown",
"data",
"fax",
"voice",
- "error"
+ "error",
+ "done"
};
-const char* ClassModem::answerTypes[5] = {
+const char* ClassModem::answerTypes[6] = {
"any",
- "fax",
"data",
+ "fax",
"voice",
- "dial"
+ "dial",
+ "external"
};
ClassModem::ClassModem(ModemServer& s, const ModemConfig& c)
do {
r = atResponse(rbuf, conf.answerResponseTimeout);
again:
- if (r == AT_TIMEOUT || r == AT_DLEEOT)
+ if (r == AT_TIMEOUT || r == AT_DLEEOT || r == AT_NOCARRIER)
break;
const AnswerMsg* am = findAnswer(rbuf);
if (am != NULL) {
CALLTYPE_ERROR = 4, // error deducing type of incoming call
CALLTYPE_DONE = 5 // subprocess completed call handling
};
- static const char* callTypes[5];
+ static const char* callTypes[6];
enum { // ClassModem::SpeakerVolume
OFF = 0, // nothing
ANSTYPE_DATA = 1, // data call
ANSTYPE_FAX = 2, // fax call
ANSTYPE_VOICE = 3, // voice call
- ANSTYPE_EXTERN = 3, // any kind of call, but answered externally
- ANSTYPE_DIAL = 4 // dial out to receive (pseudo poll)
+ ANSTYPE_DIAL = 4, // dial out to receive (pseudo poll)
+ ANSTYPE_EXTERN = 5 // any kind of call, but answered externally
};
- static const char* answerTypes[5];
+ static const char* answerTypes[6];
enum { // ClassModem::ATResponse
AT_NOTHING = 0, // for passing as a parameter
* exec getty below.
*/
void
-Getty::setupArgv(const char* args, const fxStr& name, const fxStr& number)
+Getty::setupArgv(const char* args, const CallID& callid)
{
argbuf = args;
- nambuf = name;
- numbuf = number;
- bool insertName = false, insertNumber = false;
u_int l;
/*
* Substitute escape sequences.
argbuf.insert(speed, l);
l += speed.length(); // avoid loops
break;
- case 'a':
- argbuf.remove(l-1,3);
- insertName = true;
- break;
- case 'u':
- argbuf.remove(l-1,3);
- insertNumber = true;
- break;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ {
+ u_int id = argbuf[l+1] - 0x31;
+ argbuf.remove(l,2);
+ if (id < callid.size()) {
+ argbuf.insert(callid.id(id), l);
+ l += callid.length(id);
+ }
+ }
+ break;
case '%': // %% = %
argbuf.remove(l,1);
break;
argv[nargs++] = &argbuf[token];
}
}
- if (nargs < GETTY_MAXARGS-1 && insertName && nambuf.length())
- argv[nargs++] = &nambuf[0];
- if (nargs < GETTY_MAXARGS-1 && insertNumber && numbuf.length())
- argv[nargs++] = &numbuf[0];
argv[nargs] = NULL;
}
* System V, BSD, etc. are derived from this.
*/
#include "Str.h"
+#include "CallID.h"
const int GETTY_MAXARGS = 64; // max args passed to getty
public:
virtual ~Getty();
// setup arguments for getty process
- void setupArgv(const char* args, const fxStr&, const fxStr&);
+ void setupArgv(const char* args, const CallID& callid);
// run getty process
virtual void run(int fd, bool parentIsInit);
virtual bool wait(int& status, bool block = false);
callResolved = answerCall(atype, ctype, emsg, callid, dialnumber);
}
}
+ if (emsg.length())
+ traceProtocol((const char*) emsg);
/*
* Call resolved. If we were able to recognize the call
* type and setup a session, then reset the answer rotary
if (ctype == ClassModem::CALLTYPE_DONE) // NB: call completed
return (true);
if (ctype != ClassModem::CALLTYPE_ERROR)
- modemAnswerCall(ctype, emsg, dialnumber);
+ modemAnswerCallCmd(ctype);
} else
emsg = "External getty use is not permitted";
} else
emsg = fxStr::format("%s: could not create", what);
return (ClassModem::CALLTYPE_ERROR);
}
- getty->setupArgv(args,
- callid.size() > CallID::NUMBER ? callid.id(CallID::NUMBER) : "",
- callid.size() > CallID::NAME ? callid.id(CallID::NAME) : "");
+
+ getty->setupArgv(args, callid);
+
/*
* The getty process should not inherit the lock file.
* Remove it here before the fork so that our state is
DRingOff string \- distinctive ring ``off'' cadence indicator
DRingOn string \- distinctive ring ``on'' cadence indicator
DynamicConfig string \- script for dynamic receive configuration
+EGettyArgs string \- arguments passed to external getty program
FAXNumber string \- facsimile modem phone number
FaxRcvdCmd string \s-1bin/faxrcvd\s+1 notification script for received facsimile
GettyArgs string \- arguments passed to getty program
options to cause the current call to be rejected instaead of answered.
Note that this file must be marked as executable by the faxgetty process.
.TP
+.B EGettyArgs
+A string that indicates whether or not the server should use an
+an external getty application to deduce and possibly handle an incoming call.
+If the string value is not null, then it is interpreted
+as a set of arguments to pass to the getty program.
+Before supplying the arguments, the string is first scanned
+for ``%''-escape sequences: any appearance of ``%l'' is replaced
+with the tty name and any appearance of ``%s'' is replaced with
+the serial port speed (in decimal).
+Any appearance of escaped numbers 1 through 9 (``%1'' through ``%9'') are replaced
+by the match to the corresponding
+.BR CallIDPattern ,
+if present.
+The ``%'' character can be specified with ``%%''.
+If the
+.B EGettyArgs
+parameter is not specified in the configuration file or if
+the string value is null, then ``extern'' connections will be rejected.
+Note that in addition to the specified command line arguments, the
+external getty
+program is invoked with its standard input, output, and error
+descriptors directed to the controlling tty device.
+
+When the external getty application completes, its exit status is evaluated
+and is interpreted to indicate what, if anything, should be done with the call.
+An exit status of ``0'' indicates an unknown call type and that the call should
+be handled as if the external getty program had not been used. An exit status
+of ``1'' indicates a data connection and that the
+.IR getty (${MANNUM1_8})
+program should be used to handle the call (see
+.BR GettyArgs )
+after being answered with
+.B ModemAnswerDataBeginCmd .
+An exit status of ``2'' indicates a fax connection that should be handled after
+being answered with
+.BR ModemAnswerFaxBeginCmd .
+An exit status of ``3'' indicates a voice call and that the
+.I vgetty
+program should be used to handle the call (see
+.BR VGettyArgs )
+after being answered with
+BR ModemAnswerVoiceBeginCmd .
+An exit status of ``4'' is considered to be an error condition. The session
+will be terminated. An exit status of ``5'' is used to indicate that the
+external getty program handled the call entirely, is not an error condition, and
+that the session is to be considered terminated.
+.TP
.B FAXNumber
The phone number associated with the facsimile modem.
This string is used to generate the
for ``%''-escape sequences: any appearance of ``%l'' is replaced
with the tty name and any appearance of ``%s'' is replaced with
the serial port speed (in decimal).
+Any appearance of escaped numbers 1 through 9 (``%1'' through ``%9'') are replaced
+by the match to the corresponding
+.BR CallIDPattern ,
+if present.
The ``%'' character can be specified with ``%%''.
If the
.B GettyArgs
for ``%''-escape sequences: any appearance of ``%l'' is replaced
with the tty name and any appearance of ``%s'' is replaced with
the serial port speed (in decimal).
+Any appearance of escaped numbers 1 through 9 (``%1'' through ``%9'') are replaced
+by the match to the corresponding
+.BR CallIDPattern ,
+if present.
The ``%'' character can be specified with ``%%''.
If the
.B VGettyArgs