ClassModem.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:42k
- /* $Id: ClassModem.c++,v 1.35 2009/02/17 01:42:42 faxguy Exp $ */
- /*
- * Copyright (c) 1994-1996 Sam Leffler
- * Copyright (c) 1994-1996 Silicon Graphics, Inc.
- * HylaFAX is a trademark of Silicon Graphics
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
- #include <ctype.h>
- #include <stdlib.h>
- #include "ModemServer.h"
- #include "FaxTrace.h"
- #include "Sys.h"
- /*
- * Call status description strings.
- */
- const char* ClassModem::callStatus[10] = {
- "Call successful {E000}", // OK
- "Busy signal detected {E001}", // BUSY
- "No carrier detected {E002}", // NOCARRIER
- "No answer from remote {E003}", // NOANSWER
- "No local dialtone {E004}", // NODIALTONE
- "Invalid dialing command {E005}", // ERROR
- "Unknown problem {E006}", // FAILURE
- "Carrier established, but Phase A failure {E007}", // NOFCON
- "Data connection established (wanted fax) {E008}", // DATACONN
- "Glare - RING detected {E009}", // RING
- };
- /*
- * Service class descriptions. The first three
- * correspond to the EIA/TIA definitions. The
- * voice class is for ZyXEL modems.
- */
- const char* ClassModem::serviceNames[9] = {
- ""Data"", // SERVICE_DATA
- ""Class 1"", // SERVICE_CLASS1
- ""Class 2"", // SERVICE_CLASS2
- ""Class 2.0"", // SERVICE_CLASS20 (XXX 3)
- ""Class 1.0"", // SERVICE_CLASS10 (XXX 4)
- ""Class 2.1"", // SERVICE_CLASS21 (XXX 5)
- "", // 6
- "", // 7
- ""Voice"", // SERVICE_VOICE
- };
- const char* ClassModem::ATresponses[19] = {
- "Nothing", // AT_NOTHING
- "OK", // AT_OK
- "Connection established", // AT_CONNECT
- "No answer or ring back", // AT_NOANSWER
- "No carrier", // AT_NOCARRIER
- "No dial tone", // AT_NODIALTONE
- "Busy", // AT_BUSY
- "Phone off-hook", // AT_OFFHOOK
- "Ring", // AT_RING
- "Command error", // AT_ERROR
- "Hang up", // AT_FHNG
- "<Empty line>", // AT_EMPTYLINE
- "<Timeout>", // AT_TIMEOUT
- "<dle+etx>", // AT_DLEETX
- "End of transmission", // AT_DLEEOT
- "<xon>", // AT_XON
- "DTMF detection", // AT_DTMF
- "Voice connection", // AT_VCON
- "<Unknown response>" // AT_OTHER
- };
- const char* ClassModem::callTypes[6] = {
- "unknown",
- "data",
- "fax",
- "voice",
- "error",
- "done"
- };
- const char* ClassModem::answerTypes[6] = {
- "any",
- "data",
- "fax",
- "voice",
- "dial",
- "external"
- };
- ClassModem::ClassModem(ModemServer& s, const ModemConfig& c)
- : server(s)
- , conf(c)
- , mfrQueryCmd(c.mfrQueryCmd)
- , modelQueryCmd(c.modelQueryCmd)
- , revQueryCmd(c.revQueryCmd)
- {
- modemServices = 0;
- rate = BR0;
- flowControl = conf.flowControl;
- iFlow = FLOW_NONE;
- oFlow = FLOW_NONE;
- setupDefault(mfrQueryCmd, conf.mfrQueryCmd, "ATI3");
- setupDefault(modelQueryCmd, conf.modelQueryCmd, "ATI0");
- setupDefault(revQueryCmd, conf.revQueryCmd, ""); // No "standard" way? -- dbely
- }
- ClassModem::~ClassModem()
- {
- }
- /*
- * Default methods for modem driver interface.
- */
- bool
- ClassModem::dataService()
- {
- return atCmd(conf.class0Cmd);
- }
- CallStatus
- ClassModem::dial(const char* number, const char* origin, fxStr& emsg)
- {
- dialedNumber = fxStr(number);
- protoTrace("DIAL %s", number);
- fxStr dialcmd = conf.dialCmd;
- u_int destpos = dialcmd.find(0, "%s");
- u_int origpos = dialcmd.find(0, "%d");
- if (destpos == dialcmd.length() && origpos == dialcmd.length()) {
- // neither %d nor %s appear in the cmd, use dialcmd as-is
- } else if (origpos == dialcmd.length()) {
- // just %s appears in the cmd
- dialcmd = fxStr::format((const char*) dialcmd, number);
- } else if (destpos == dialcmd.length()) {
- // just %d appears in the cmd
- dialcmd[origpos+1] = 's'; // change %d to %s
- dialcmd = fxStr::format((const char*) dialcmd, origin);
- } else {
- // both %d and %s appear in the cmd
- dialcmd[origpos+1] = 's'; // change %d to %s
- if (origpos < destpos) {
- // %d appears before %s
- dialcmd = fxStr::format((const char*) dialcmd, origin, number);
- } else {
- // %s appears before %d
- dialcmd = fxStr::format((const char*) dialcmd, number, origin);
- }
- }
- emsg = "";
- CallStatus cs = (atCmd(dialcmd, AT_NOTHING) ? dialResponse(emsg) : FAILURE);
- if (cs != OK && emsg == "") {
- emsg = callStatus[cs];
- }
- return (cs);
- }
- /*
- * Status messages to ignore when dialing.
- */
- bool
- ClassModem::isNoise(const char* s)
- {
- static const char* noiseMsgs[] = {
- "CED", // RC32ACL-based modems send this before +FCON
- "DIALING",
- "RRING", // Telebit
- "RINGING", // ZyXEL
- "+FHR:", // Intel 144e
- "+A8", // Class 1.0 V.8 report
- "+F34:", // Class 1.0 V.34 report
- "+FDB:", // DCE debugging
- "MESSAGE-WAITING", // voice-mail waiting, Conexant
- "