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 OpalMediaStatistics::Fax m_statistics;
00178 };
00179
00181
00184 class OpalT38MediaStream : public OpalFaxMediaStream
00185 {
00186 PCLASSINFO(OpalT38MediaStream, OpalFaxMediaStream);
00187 public:
00188 OpalT38MediaStream(
00189 OpalFaxConnection & conn,
00190 const OpalMediaFormat & mediaFormat,
00191 unsigned sessionID,
00192 bool isSource,
00193 const PString & token,
00194 const PString & filename,
00195 bool receive,
00196 const PString & stationId
00197 );
00198
00199 PString GetSpanDSPCommandLine(OpalFaxCallInfo &);
00200
00201 virtual PBoolean ReadPacket(RTP_DataFrame & packet);
00202 virtual PBoolean WritePacket(RTP_DataFrame & packet);
00203
00204 RTP_DataFrameList queuedFrames;
00205 };
00206
00208
00209 class OpalFaxConnection;
00210
00219 class OpalFaxEndPoint : public OpalEndPoint
00220 {
00221 PCLASSINFO(OpalFaxEndPoint, OpalEndPoint);
00222 public:
00227 OpalFaxEndPoint(
00228 OpalManager & manager,
00229 const char * g711Prefix = "fax",
00230 const char * t38Prefix = "t38"
00231 );
00232
00235 ~OpalFaxEndPoint();
00237
00238 virtual PBoolean MakeConnection(
00239 OpalCall & call,
00240 const PString & party,
00241 void * userData = NULL,
00242 unsigned int options = 0,
00243 OpalConnection::StringOptions * stringOptions = NULL
00244 );
00245
00248 virtual OpalFaxConnection * CreateConnection(
00249 OpalCall & call,
00250 void * userData,
00251 OpalConnection::StringOptions * stringOptions,
00252 const PString & filename,
00253 bool receive,
00254 bool t38
00255 );
00256
00266 virtual OpalMediaFormatList GetMediaFormats() const;
00267
00271 virtual void AcceptIncomingConnection(
00272 const PString & connectionToken
00273 );
00274
00278 virtual void OnFaxCompleted(
00279 OpalFaxConnection & connection,
00280 bool failed
00281 );
00283
00287 const PFilePath & GetSpanDSP() const { return m_spanDSP; }
00288
00291 void SetSpanDSP(
00292 const PString & path
00293 ) { m_spanDSP = path; }
00294
00297 const PString & GetDefaultDirectory() const { return m_defaultDirectory; }
00298
00301 void SetDefaultDirectory(
00302 const PString & dir
00303 ) { m_defaultDirectory = dir; }
00304
00305 const PString & GetT38Prefix() const { return m_t38Prefix; }
00307
00308 protected:
00309 PString m_t38Prefix;
00310 PFilePath m_spanDSP;
00311 PDirectory m_defaultDirectory;
00312 };
00313
00314
00316
00319 class OpalFaxConnection : public OpalConnection
00320 {
00321 PCLASSINFO(OpalFaxConnection, OpalConnection);
00322 public:
00327 OpalFaxConnection(
00328 OpalCall & call,
00329 OpalFaxEndPoint & endpoint,
00330 const PString & filename,
00331 bool receive,
00332 const PString & _token,
00333 OpalConnection::StringOptions * stringOptions = NULL
00334 );
00335
00338 ~OpalFaxConnection();
00340
00351 virtual bool IsNetworkConnection() const { return false; }
00352
00359 virtual PBoolean SetUpConnection();
00360
00371 virtual PBoolean SetAlerting(
00372 const PString & calleeName,
00373 PBoolean withMedia
00374 );
00375
00383 virtual OpalMediaFormatList GetMediaFormats() const;
00384
00385 virtual void ApplyStringOptions(OpalConnection::StringOptions & stringOptions);
00386 virtual OpalMediaStream * CreateMediaStream(const OpalMediaFormat & mediaFormat, unsigned sessionID, PBoolean isSource);
00387 virtual void AdjustMediaFormats(OpalMediaFormatList & mediaFormats) const;
00388
00393 virtual void AcceptIncoming();
00394
00398 virtual void OnFaxCompleted(
00399 bool failed
00400 );
00401
00404 bool IsReceive() const { return m_receive; }
00406
00407 protected:
00408 OpalFaxEndPoint & m_endpoint;
00409 PString m_filename;
00410 bool m_receive;
00411 PString m_stationId;
00412 };
00413
00415
00418 class OpalT38Connection : public OpalFaxConnection
00419 {
00420 PCLASSINFO(OpalT38Connection, OpalFaxConnection);
00421 public:
00426 OpalT38Connection(
00427 OpalCall & call,
00428 OpalFaxEndPoint & endpoint,
00429 const PString & filename,
00430 bool receive,
00431 const PString & token,
00432 OpalConnection::StringOptions * stringOptions = NULL
00433 );
00434
00435 virtual PString GetPrefixName() const { return m_endpoint.GetT38Prefix(); }
00436 virtual void ApplyStringOptions(OpalConnection::StringOptions & stringOptions);
00437 virtual void OnEstablished();
00438 virtual OpalMediaStream * CreateMediaStream(const OpalMediaFormat & mediaFormat, unsigned sessionID, PBoolean isSource);
00439 virtual void OnMediaPatchStop(unsigned sessionId, bool isSource);
00440 virtual OpalMediaFormatList GetMediaFormats() const;
00441
00442
00443 enum Mode {
00444 Mode_Wait,
00445 Mode_Timeout,
00446 Mode_UserInput,
00447 Mode_InBand
00448 };
00449
00450 virtual PBoolean SendUserInputTone(
00451 char tone,
00452 unsigned duration
00453 );
00454
00455 protected:
00456 PDECLARE_NOTIFIER(PTimer, OpalT38Connection, OnSendCNGCED);
00457 PDECLARE_NOTIFIER(PTimer, OpalT38Connection, OnFaxChangeTimeout);
00458 PDECLARE_NOTIFIER(PThread, OpalT38Connection, OpenFaxStreams);
00459 void RequestFaxMode(bool fax);
00460
00461 Mode m_syncMode;
00462
00463 bool m_faxMode;
00464 PTimer m_faxTimer;
00465 };
00466
00467
00468 #endif // OPAL_FAX
00469
00470 #endif // OPAL_T38_T38PROTO_H