ClassModem.h
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:13k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: ClassModem.h,v 1.15 2008/07/16 16:17:39 faxguy Exp $ */
  2. /*
  3.  * Copyright (c) 1994-1996 Sam Leffler
  4.  * Copyright (c) 1994-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. #ifndef _ClassModem_
  27. #define _ClassModem_
  28. /*
  29.  * Class-X-style Modem Driver Interface.
  30.  */
  31. #include <stdarg.h>
  32. #include "Str.h"
  33. #include "CallID.h"
  34. class ModemServer;
  35. class ModemConfig;
  36. class FaxRequest;
  37. class Class2Params;
  38. // NB: these would be enums in the ClassModem class
  39. //     if there were a portable way to refer to them!
  40. typedef u_int CallStatus; // return status from dialing op
  41. typedef u_int CallType; // type detected for incoming call
  42. typedef u_int AnswerType; // type of call to answer for
  43. typedef u_int SpeakerVolume;
  44. typedef u_int ATResponse; // response code from AT command
  45. typedef u_int BaudRate; // serial line communication rate
  46. typedef u_int ECMType; // ECM service specification to follow
  47. typedef u_int FlowControl; // serial line flow control scheme
  48. typedef u_int SetAction; // how to act when setting line
  49. typedef struct {
  50.     const char* msg; // string to match
  51.     u_short len; // string length
  52.     ATResponse expect; // next AT response to expect
  53.     CallStatus status; // resultant call status
  54.     CallType type; // resultant call type
  55. } AnswerMsg;
  56. /*
  57.  * AT command escape codes.  Command strings specified in the
  58.  * modem configuration file are parsed and embedded commands
  59.  * are converted to one of the escape codes below.
  60.  */ 
  61. #define ord(e) ((int)(e))
  62. #define ESC_SETBR (0x80|0x01) // set baud rate
  63. #define ESC_SETFLOW (0x80|0x02) // set flow control
  64. #define ESC_DELAY (0x80|0x04) // delay period of time
  65. #define ESC_WAITFOR (0x80|0x08) // wait for modem response
  66. #define ESC_FLUSH (0x80|0x10) // flush input queue
  67. #define ESC_PLAY (0x80|0x20) // play (voice) file
  68. #ifdef OFF
  69. #undef OFF // workaround for SCO
  70. #endif
  71. #ifdef ERROR
  72. #undef ERROR // workaround for Mac OS X
  73. #endif
  74. /*
  75.  * This is an abstract class that defines the interface to
  76.  * the set of modem drivers.  Real drivers are derived from
  77.  * this and fill in the pure virtual methods to, for example,
  78.  * send specific commands to the modem.  The Class2Params
  79.  * structure defines the session parameters used/supported
  80.  * by this interface.  Class2Params is derived from the
  81.  * set of parameters supported by the Class 2 interface spec.
  82.  */
  83. class ClassModem {
  84. public:
  85.     enum { // ClassModem::CallStatus
  86. OK    = 0, // phone answered & carrier received
  87. BUSY    = 1, // destination phone busy
  88. NOCARRIER  = 2, // no carrier from remote
  89. NOANSWER   = 3, // no answer from remote
  90. NODIALTONE = 4, // no local dialtone (phone not plugged in?)
  91. ERROR    = 5, // error in dial command
  92. FAILURE    = 6, // other problem (e.g. modem turned off)
  93. NOFCON    = 7, // carrier established, but phase a failure
  94. DATACONN   = 8, // data carrier established
  95. RING    = 9 // glare - ring detected after dial
  96.     };
  97.     enum { // ClassModem::CallType
  98. CALLTYPE_UNKNOWN = 0, // unknown variety
  99. CALLTYPE_DATA = 1, // data connection
  100. CALLTYPE_FAX = 2, // fax connection
  101. CALLTYPE_VOICE = 3, // voice connection
  102. CALLTYPE_ERROR = 4, // error deducing type of incoming call
  103. CALLTYPE_DONE = 5 // subprocess completed call handling
  104.     };
  105.     static const char* callTypes[6];
  106.     enum { // ClassModem::SpeakerVolume
  107. OFF = 0, // nothing
  108. QUIET = 1, // somewhere near a dull chirp
  109. LOW = 2, // normally acceptable
  110. MEDIUM = 3, // heard above a stereo
  111. HIGH = 4 // ear splitting
  112.     };
  113.     enum { // ClassModem::BaudRate
  114. BR0 = 0, // force hangup/drop DTR
  115. BR300 = 1, // 300 bits/sec
  116. BR1200 = 2, // 1200 bits/sec
  117. BR2400 = 3, // 2400 bits/sec
  118. BR4800 = 4, // 4800 bits/sec
  119. BR9600 = 5, // 9600 bits/sec
  120. BR19200 = 6, // 19200 bits/sec
  121. BR38400 = 7, // 38400 bits/sec
  122. BR57600 = 8, // 57600 bits/sec
  123. BR76800 = 9, // 76800 bits/sec
  124. BR115200= 10 // 115200 bits/sec
  125.     };
  126.     enum { // ClassModem::ECMType
  127. ECMTYPE_UNSET   = 0, // use default for service type
  128. ECMTYPE_CLASS2  = 1, // use Class 2 type ECM
  129. ECMTYPE_CLASS20 = 2 // use Class 2.0 type ECM
  130.     };
  131.     enum { // ClassModem::FlowControl
  132. FLOW_NONE = 0, // no flow control
  133. FLOW_XONXOFF = 1, // XON/XOFF software flow control
  134. FLOW_RTSCTS = 2 // RTS/CTS hardware flow control
  135.     };
  136.     enum { // ClassModem::SetAction
  137. ACT_NOW = 0, // set terminal parameters now
  138. ACT_DRAIN = 1, // set parameters after draining output queue
  139. ACT_FLUSH = 2 // set parameters after flush both queues
  140.     };
  141.     enum { // ClassModem::AnswerType
  142. ANSTYPE_ANY = 0, // any kind of call
  143. ANSTYPE_DATA = 1, // data call
  144. ANSTYPE_FAX = 2, // fax call
  145. ANSTYPE_VOICE = 3, // voice call
  146. ANSTYPE_DIAL = 4, // dial out to receive (pseudo poll)
  147. ANSTYPE_EXTERN = 5 // any kind of call, but answered externally
  148.     };
  149.     static const char* answerTypes[6];
  150.     enum { // ClassModem::ATResponse
  151. AT_NOTHING = 0, // for passing as a parameter
  152. AT_OK = 1, // "OK" response
  153. AT_CONNECT = 2, // "CONNECT" response
  154. AT_NOANSWER = 3, // "NO ANSWER" response
  155. AT_NOCARRIER = 4, // "NO CARRIER" response
  156. AT_NODIALTONE = 5, // "NO DIALTONE" response
  157. AT_BUSY = 6, // "BUSY" response
  158. AT_OFFHOOK = 7, // "PHONE OFF-HOOK" response
  159. AT_RING = 8, // "RING" response
  160. AT_ERROR = 9, // "ERROR" response
  161. AT_FHNG = 10, // "FHNG" response
  162. AT_EMPTYLINE = 11, // empty line (0 characters received)
  163. AT_TIMEOUT = 12, // timeout waiting for response
  164. AT_DLEETX = 13, // dle/etx characters
  165. AT_DLEEOT = 14, // dle+eot characters (end of transmission)
  166. AT_XON = 15, // xon character
  167. AT_DTMF = 16, // DTMF detection
  168. AT_VCON = 17, // voice connection
  169. AT_OTHER = 18 // unknown response (not one of above)
  170.     };
  171. private:
  172.     ModemServer& server; // server for getting to device
  173.     long dataTimeout; // baud rate-dependent data timeout
  174.     BaudRate rate; // selected DTE-DCE communication rate
  175.     FlowControl iFlow; // input flow control scheme
  176.     FlowControl oFlow; // output flow control scheme
  177.     fxStr dialedNumber; // number dialed
  178. protected:
  179. // NB: these are defined protected for convenience (XXX)
  180.     const ModemConfig& conf; // configuration parameters
  181.     FlowControl flowControl; // current DTE-DCE flow control scheme
  182.     u_int modemServices; // services modem supports
  183.     fxStr modemMfr; // manufacturer identification
  184.     fxStr modemModel; // model identification
  185.     fxStr modemRevision; // product revision identification
  186.     char rbuf[1024]; // last input line
  187.     ATResponse lastResponse; // last atResponse code
  188.     fxStr mfrQueryCmd; // manufacturer identification command
  189.     fxStr modelQueryCmd; // model identification command
  190.     fxStr revQueryCmd; // product revision identification command
  191.     static const char* serviceNames[9];  // class 2 services
  192.     static const char* callStatus[10];  // printable call status
  193.     static const char* ATresponses[19];
  194.     ClassModem(ModemServer&, const ModemConfig&);
  195. // setup and configuration
  196.     static void setupDefault(fxStr&, const fxStr&, const char*);
  197.     virtual bool selectBaudRate(BaudRate max, FlowControl i, FlowControl o);
  198.     virtual bool setupManufacturer(fxStr& mfr);
  199.     virtual bool setupModel(fxStr& model);
  200.     virtual bool setupRevision(fxStr& rev);
  201.     bool doQuery(const fxStr& queryCmd, fxStr& result, long ms = 30*1000);
  202. // dial/answer interactions with derived classes
  203.     virtual const AnswerMsg* findAnswer(const char* s);
  204.     virtual CallType answerResponse(fxStr, fxStr& emsg);
  205.     virtual CallStatus dialResponse(fxStr& emsg) = 0;
  206.     virtual bool isNoise(const char*);
  207. // miscellaneous
  208.     void modemSupports(const char* fmt, ...);
  209.     void modemCapability(const char* fmt, ...);
  210.     void traceBits(u_int bits, const char* bitNames[]);
  211.     void traceBitMask(u_int bits, const char* bitNames[]);
  212.     CallType  findCallType(int vec[]);
  213. public:
  214.     virtual ~ClassModem();
  215.     virtual bool setupModem(bool isSend = true) = 0;
  216.     virtual bool isFaxModem() const = 0; // XXX safe to cast
  217.     virtual bool sync(long ms = 0); // synchronize (wait for "OK")
  218.     virtual bool reset(long ms = 5*1000); // reset modem state
  219.     virtual bool ready(long ms = 5*1000); // ready modem state
  220.     virtual void hangup(); // hangup the phone
  221. // configuration controls
  222.     virtual void setSpeakerVolume(SpeakerVolume);
  223. // configuration query
  224.     const fxStr& getModel() const;
  225.     const fxStr& getManufacturer() const;
  226.     const fxStr& getRevision() const;
  227.     fxStr getCapabilities() const;
  228.     u_int getModemServices() const;
  229.     bool doCallIDDisplay(int i) const;
  230.     bool doCallIDRecord(int i) const;
  231.     const fxStr& getCallIDLabel(int i) const;
  232.     const fxStr& getCallIDType(int i) const;
  233. // data transfer timeout controls
  234.     void setDataTimeout(long secs, u_int br);
  235.     long getDataTimeout() const;
  236. // miscellaneous
  237.     void pause(u_int ms);
  238.     void modemTrace(const char* fmt, ...);
  239.     void protoTrace(const char* fmt, ...);
  240.     void serverTrace(const char* fmt, ...);
  241. // modem i/o support
  242.     void trimModemLine(char buf[], int& cc);
  243.     int getModemLine(char buf[], u_int bufSize, long ms = 0);
  244. // support to write to modem w/ timeout
  245.     void beginTimedTransfer();
  246.     void endTimedTransfer();
  247.     bool wasTimeout();
  248.     void setTimeout(bool);
  249.     void flushModemInput();
  250.     bool putModem(void* data, int n, long ms = 0);
  251.     bool putModemData(void* data, int n, long ms = -1);
  252.     bool putModemDLEData(const u_char* data, u_int,
  253.     const u_char* brev, long ms, bool doquery = false);
  254.     bool putModemLine(const char* cp, long ms = 0);
  255.     int getModemBit(long ms = 0);
  256.     int getModemChar(long ms = 0, bool doquery = false);
  257.     int getModemDataChar();
  258.     int getLastByte();
  259.     bool didBlockEnd();
  260.     void resetBlock();
  261.     void startTimeout(long ms);
  262.     void stopTimeout(const char* whichdir);
  263.     bool poke();
  264. // host-modem protocol parsing support
  265.     virtual ATResponse atResponse(char* buf, long ms = 30*1000);
  266.     bool waitFor(ATResponse wanted, long ms = 30*1000);
  267.     bool atCmd(const fxStr& cmd, ATResponse = AT_OK, long ms = 30*1000);
  268.     bool atQuery(const char* what, fxStr& v, long ms = 30*1000);
  269.     bool atQuery(const char* what, u_int& v, long ms = 30*1000);
  270.     bool parseRange(const char*, u_int&);
  271.     bool vparseRange(const char*, int masked, int nargs ...);
  272. // modem line control
  273.     bool sendBreak(bool pause);
  274.     bool setBaudRate(BaudRate rate);
  275.     bool setBaudRate(BaudRate rate, FlowControl i, FlowControl o);
  276.     bool setXONXOFF(FlowControl i, FlowControl o, SetAction);
  277.     bool setDTR(bool on);
  278.     bool setInputBuffering(bool on);
  279.     bool modemStopOutput();
  280.     FlowControl getInputFlow();
  281.     FlowControl getOutputFlow();
  282. // server-related stuff
  283.     bool abortRequested();
  284.     /*
  285.      * Send support:
  286.      *
  287.      * if (dial(number, origin, emsg) == OK) {
  288.      *   ...do stuff...
  289.      * }
  290.      * hangup();
  291.      */
  292.     virtual bool dataService();
  293.     virtual CallStatus dial(const char* number, const char* origin, fxStr& emsg);
  294.     /*
  295.      * Receive support:
  296.      *
  297.      * if (waitForRings(nrings, ctype, cid)) { // wait before answering phone
  298.      *    case (answerCall(type, emsg)) {
  299.      *    CALLTYPE_FAX:
  300.      *         ...do fax kinds of things...
  301.      *      break;
  302.      *   CALLTYPE_DATA:
  303.      *         ...do data kinds of things...
  304.      *      break;
  305.      *   CALLTYPE_VOICE:
  306.      *         ...do voice kinds of things...
  307.      *      break;
  308.      *    }
  309.      * }
  310.      *
  311.      * with recvAbort available to abort a receive
  312.      * at any time in this procedure.
  313.      */
  314.     virtual bool waitForRings(u_short rings, CallType&, CallID&);
  315.     virtual CallType answerCall(AnswerType, fxStr& emsg, const char* dialnumber = NULL);
  316.     virtual void answerCallCmd(CallType);
  317. };
  318. inline long ClassModem::getDataTimeout() const { return dataTimeout; }
  319. inline const fxStr& ClassModem::getModel() const { return modemModel; }
  320. inline const fxStr& ClassModem::getManufacturer() const { return modemMfr; }
  321. inline const fxStr& ClassModem::getRevision() const { return modemRevision; }
  322. inline u_int ClassModem::getModemServices() const       { return modemServices; }
  323. inline FlowControl ClassModem::getInputFlow() { return iFlow; }
  324. inline FlowControl ClassModem::getOutputFlow() { return oFlow; }
  325. #endif /* _ClassModem_ */