00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef OPAL_T38_T38PROTO_H
00032 #define OPAL_T38_T38PROTO_H
00033
00034 #ifdef P_USE_PRAGMA
00035 #pragma interface
00036 #endif
00037
00038 #include <opal/buildopts.h>
00039
00040
00041 #if OPAL_FAX
00042
00043 #include <ptlib/pipechan.h>
00044
00045 #include <opal/mediafmt.h>
00046 #include <opal/mediastrm.h>
00047 #include <opal/endpoint.h>
00048
00049
00050 class OpalTransport;
00051 class T38_IFPPacket;
00052 class PASN_OctetString;
00053 class OpalFaxConnection;
00054
00055
00056 namespace PWLibStupidLinkerHacks {
00057 extern int t38Loader;
00058 };
00059
00061
00067 class OpalFaxAudioFormat : public OpalMediaFormat
00068 {
00069 friend class OpalPluginCodecManager;
00070 PCLASSINFO(OpalFaxAudioFormat, OpalMediaFormat);
00071 public:
00072 OpalFaxAudioFormat(
00073 const char * fullName,
00074 RTP_DataFrame::PayloadTypes rtpPayloadType,
00075 const char * encodingName,
00076 PINDEX frameSize,
00077 unsigned frameTime,
00078 unsigned rxFrames,
00079 unsigned txFrames,
00080 unsigned maxFrames = 256,
00081 unsigned clockRate = 8000,
00082 time_t timeStamp = 0
00083 );
00084 };
00085
00086
00088
00089 class OpalFaxCallInfo {
00090 public:
00091 OpalFaxCallInfo();
00092 PUDPSocket socket;
00093 PPipeChannel spanDSP;
00094 PThread * stdoutThread;
00095 unsigned refCount;
00096 PIPSocket::Address spanDSPAddr;
00097 WORD spanDSPPort;
00098 };
00099
00101
00104 class OpalFaxMediaStream : public OpalMediaStream
00105 {
00106 PCLASSINFO(OpalFaxMediaStream, OpalMediaStream);
00107 public:
00112 OpalFaxMediaStream(
00113 OpalFaxConnection & conn,
00114 const OpalMediaFormat & mediaFormat,
00115 unsigned sessionID,
00116 bool isSource,
00117 const PString & token,
00118 const PString & filename,
00119 bool receive,
00120 const PString & stationId
00121 );
00123
00130 virtual PBoolean Open();
00131
00136 virtual PBoolean Close();
00137
00141 virtual PBoolean ReadPacket(
00142 RTP_DataFrame & packet
00143 );
00144
00148 virtual PBoolean WritePacket(
00149 RTP_DataFrame & packet
00150 );
00151
00155 virtual PBoolean IsSynchronous() const;
00156
00157 #if OPAL_STATISTICS
00158 virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch = false) const;
00159 #endif
00160
00161
00162 virtual PString GetSpanDSPCommandLine(OpalFaxCallInfo &);
00163
00164 protected:
00165 PDECLARE_NOTIFIER(PThread, OpalFaxMediaStream, ReadStdOut);
00166
00167 OpalFaxConnection & m_connection;
00168 PMutex infoMutex;
00169 PString sessionToken;
00170 OpalFaxCallInfo * m_faxCallInfo;
00171 PFilePath m_filename;
00172 bool m_receive;
00173 BYTE writeBuffer[320];
00174 PINDEX writeBufferLen;
00175 PString m_stationId;
00176
00177 #if OPAL_STATISTICS
00178 OpalMediaStatistics::Fax m_statistics;
00179 #else
00180 int m_result;
00181 #endif
00182 };
00183
00185
00188 class OpalT38MediaStream : public OpalFaxMediaStream
00189 {
00190 PCLASSINFO(OpalT38MediaStream, OpalFaxMediaStream);
00191 public:
00192 OpalT38MediaStream(
00193 OpalFaxConnection & conn,
00194 const OpalMediaFormat & mediaFormat,
00195 unsigned sessionID,
00196 bool isSource,
00197 const PString & token,
00198 const PString & filename,
00199 bool receive,
00200 const PString & stationId
00201 );
00202
00203 PString GetSpanDSPCommandLine(OpalFaxCallInfo &);
00204
00205 virtual PBoolean ReadPacket(RTP_DataFrame & packet);
00206 virtual PBoolean WritePacket(RTP_DataFrame & packet);
00207
00208 RTP_DataFrameList queuedFrames;
00209 };
00210
00212
00213 class OpalFaxConnection;
00214
00223 class OpalFaxEndPoint : public OpalEndPoint
00224 {
00225 PCLASSINFO(OpalFaxEndPoint, OpalEndPoint);
00226 public:
00231 OpalFaxEndPoint(
00232 OpalManager & manager,
00233 const char * g711Prefix = "fax",
00234 const char * t38Prefix = "t38"
00235 );
00236
00239 ~OpalFaxEndPoint();
00241
00242 virtual PBoolean MakeConnection(
00243 OpalCall & call,
00244 const PString & party,
00245 void * userData = NULL,
00246 unsigned int options = 0,
00247 OpalConnection::StringOptions * stringOptions = NULL
00248 );
00249
00252 virtual OpalFaxConnection * CreateConnection(
00253 OpalCall & call,
00254 void * userData,
00255 OpalConnection::StringOptions * stringOptions,
00256 const PString & filename,
00257 bool receive,
00258 bool t38
00259 );
00260
00270 virtual OpalMediaFormatList GetMediaFormats() const;
00271
00275 virtual void AcceptIncomingConnection(
00276 const PString & connectionToken
00277 );
00278
00282 virtual void OnFaxCompleted(
00283 OpalFaxConnection & connection,
00284 bool failed
00285 );
00287
00291 const PFilePath & GetSpanDSP() const { return m_spanDSP; }
00292
00295 void SetSpanDSP(
00296 const PString & path
00297 ) { m_spanDSP = path; }
00298
00301 const PString & GetDefaultDirectory() const { return m_defaultDirectory; }
00302
00305 void SetDefaultDirectory(
00306 const PString & dir
00307 ) { m_defaultDirectory = dir; }
00308
00309 const PString & GetT38Prefix() const { return m_t38Prefix; }
00311
00312 protected:
00313 PString m_t38Prefix;
00314 PFilePath m_spanDSP;
00315 PDirectory m_defaultDirectory;
00316 };
00317
00318
00320
00323 class OpalFaxConnection : public OpalConnection
00324 {
00325 PCLASSINFO(OpalFaxConnection, OpalConnection);
00326 public:
00331 OpalFaxConnection(
00332 OpalCall & call,
00333 OpalFaxEndPoint & endpoint,
00334 const PString & filename,
00335 bool receive,
00336 const PString & _token,
00337 OpalConnection::StringOptions * stringOptions = NULL
00338 );
00339
00342 ~OpalFaxConnection();
00344
00355 virtual bool IsNetworkConnection() const { return false; }
00356
00363 virtual PBoolean SetUpConnection();
00364
00375 virtual PBoolean SetAlerting(
00376 const PString & calleeName,
00377 PBoolean withMedia
00378 );
00379
00387 virtual OpalMediaFormatList GetMediaFormats() const;
00388
00389 virtual void ApplyStringOptions(OpalConnection::StringOptions & stringOptions);
00390 virtual OpalMediaStream * CreateMediaStream(const OpalMediaFormat & mediaFormat, unsigned sessionID, PBoolean isSource);
00391 virtual void AdjustMediaFormats(OpalMediaFormatList & mediaFormats) const;
00392
00397 virtual void AcceptIncoming();
00398
00402 virtual void OnFaxCompleted(
00403 bool failed
00404 );
00405
00408 bool IsReceive() const { return m_receive; }
00410
00411 protected:
00412 OpalFaxEndPoint & m_endpoint;
00413 PString m_filename;
00414 bool m_receive;
00415 PString m_stationId;
00416 };
00417
00419
00422 class OpalT38Connection : public OpalFaxConnection
00423 {
00424 PCLASSINFO(OpalT38Connection, OpalFaxConnection);
00425 public:
00430 OpalT38Connection(
00431 OpalCall & call,
00432 OpalFaxEndPoint & endpoint,
00433 const PString & filename,
00434 bool receive,
00435 const PString & token,
00436 OpalConnection::StringOptions * stringOptions = NULL
00437 );
00438
00439 virtual PString GetPrefixName() const { return m_endpoint.GetT38Prefix(); }
00440 virtual void ApplyStringOptions(OpalConnection::StringOptions & stringOptions);
00441 virtual void OnEstablished();
00442 virtual OpalMediaStream * CreateMediaStream(const OpalMediaFormat & mediaFormat, unsigned sessionID, PBoolean isSource);
00443 virtual void OnMediaPatchStop(unsigned sessionId, bool isSource);
00444 virtual OpalMediaFormatList GetMediaFormats() const;
00445
00446
00447 enum Mode {
00448 Mode_Wait,
00449 Mode_Timeout,
00450 Mode_UserInput,
00451 Mode_InBand
00452 };
00453
00454 virtual PBoolean SendUserInputTone(
00455 char tone,
00456 unsigned duration
00457 );
00458
00459 protected:
00460 PDECLARE_NOTIFIER(PTimer, OpalT38Connection, OnSendCNGCED);
00461 PDECLARE_NOTIFIER(PTimer, OpalT38Connection, OnFaxChangeTimeout);
00462 PDECLARE_NOTIFIER(PThread, OpalT38Connection, OpenFaxStreams);
00463 void RequestFaxMode(bool fax);
00464
00465 Mode m_syncMode;
00466
00467 bool m_faxMode;
00468 PTimer m_faxTimer;
00469 };
00470
00471
00472 #endif // OPAL_FAX
00473
00474 #endif // OPAL_T38_T38PROTO_H