1 /*
2  * t38proto.h
3  *
4  * T.38 protocol handler
5  *
6  * Open Phone Abstraction Library
7  *
8  * Copyright (c) 2001 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Open H323 Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Contributor(s): ______________________________________.
25  *
26  * $Revision: 28445 $
27  * $Author: rjongbloed $
28  * $Date: 2012-10-02 20:11:02 -0500 (Tue, 02 Oct 2012) $
29  */
30 
31 #ifndef OPAL_T38_T38PROTO_H
32 #define OPAL_T38_T38PROTO_H
33 
34 #ifdef P_USE_PRAGMA
35 #pragma interface
36 #endif
37 
38 #include <opal/buildopts.h>
39 
40 
41 #if OPAL_FAX
42 
43 #include <ptlib/pipechan.h>
44 
45 #include <opal/mediafmt.h>
46 #include <opal/mediastrm.h>
47 #include <opal/localep.h>
48 
49 
50 class OpalTransport;
51 class T38_IFPPacket;
52 class PASN_OctetString;
53 class OpalFaxConnection;
54 
55 
56 #define OPAL_OPT_STATION_ID  "Station-Id"      ///< String option for fax station ID string
57 #define OPAL_OPT_HEADER_INFO "Header-Info"     ///< String option for transmitted fax page header
58 #define OPAL_NO_G111_FAX     "No-G711-Fax"     ///< Suppress G.711 fall back
59 #define OPAL_SWITCH_ON_CED   "Switch-On-CED"   ///< Try switch to T.38 on receipt of CED tone
60 #define OPAL_T38_SWITCH_TIME "T38-Switch-Time" ///< Seconds for fail safe switch to T.38 mode
61 
62 #define OPAL_FAX_TIFF_FILE "TIFF-File"
63 
64 
65 ///////////////////////////////////////////////////////////////////////////////
66 
67 class OpalFaxConnection;
68 
69 /** Fax Endpoint.
70     This class represents connection that can take a standard group 3 fax
71     TIFF file and produce either T.38 packets or actual tones represented
72     by a stream of PCM. For T.38 it is expected the second connection in the
73     call supports T.38 e.g. SIP or H.323. If PCM is being used then the second
74     connection may be anything that supports PCM, such as SIP or H.323 using
75     G.711 codec or OpalLineEndpoint which could the send the TIFF file to a
76     physical fax machine.
77 
78     Relies on the presence of the spandsp plug in to do the hard work.
79  */
80 class OpalFaxEndPoint : public OpalLocalEndPoint
81 {
82   PCLASSINFO(OpalFaxEndPoint, OpalLocalEndPoint);
83   public:
84   /**@name Construction */
85   //@{
86     /**Create a new endpoint.
87      */
88     OpalFaxEndPoint(
89       OpalManager & manager,        ///<  Manager of all endpoints.
90       const char * g711Prefix = "fax", ///<  Prefix for URL style address strings
91       const char * t38Prefix = "t38"  ///<  Prefix for URL style address strings
92     );
93 
94     /**Destroy endpoint.
95      */
96     ~OpalFaxEndPoint();
97   //@}
98 
99   /**@name Overrides from OpalEndPoint */
100   //@{
101     virtual PSafePtr<OpalConnection> MakeConnection(
102       OpalCall & call,          ///<  Owner of connection
103       const PString & party,    ///<  Remote party to call
104       void * userData = NULL,          ///<  Arbitrary data to pass to connection
105       unsigned int options = 0,     ///<  options to pass to conneciton
106       OpalConnection::StringOptions * stringOptions = NULL  ///< Options to pass to connection
107     );
108 
109     /**Get the data formats this endpoint is capable of operating.
110        This provides a list of media data format names that may be used by an
111        OpalMediaStream may be created by a connection from this endpoint.
112 
113        Note that a specific connection may not actually support all of the
114        media formats returned here, but should return no more.
115       */
116     virtual OpalMediaFormatList GetMediaFormats() const;
117   //@}
118 
119   /**@name Fax specific operations */
120   //@{
121     /**Determine if the fax plug in is available, that is fax system can be used.
122       */
123     virtual bool IsAvailable() const;
124 
125     /**Create a connection for the fax endpoint.
126       */
127     virtual OpalFaxConnection * CreateConnection(
128       OpalCall & call,          ///< Owner of connection
129       void * userData,          ///<  Arbitrary data to pass to connection
130       OpalConnection::StringOptions * stringOptions, ///< Options to pass to connection
131       const PString & filename, ///< filename to send/receive
132       bool receiving,           ///< Flag for receiving/sending fax
133       bool disableT38           ///< Flag to disable use of T.38
134     );
135 
136     /**Fax transmission/receipt completed.
137        Default behaviour releases the connection.
138       */
139     virtual void OnFaxCompleted(
140       OpalFaxConnection & connection, ///< Connection that completed.
141       bool failed   ///< Fax ended with failure
142     );
143   //@}
144 
145   /**@name Member variable access */
146     /**Get the default directory for received faxes.
147       */
GetDefaultDirectory()148     const PString & GetDefaultDirectory() const { return m_defaultDirectory; }
149 
150     /**Set the default directory for received faxes.
151       */
SetDefaultDirectory(const PString & dir)152     void SetDefaultDirectory(
153       const PString & dir    /// New directory for fax reception
154     ) { m_defaultDirectory = dir; }
155 
GetT38Prefix()156     const PString & GetT38Prefix() const { return m_t38Prefix; }
157   //@}
158 
159   protected:
160     PString    m_t38Prefix;
161     PDirectory m_defaultDirectory;
162 };
163 
164 
165 ///////////////////////////////////////////////////////////////////////////////
166 
167 /** Fax Connection.
168     There are six modes of operation:
169         Mode            receiving     disableT38    filename
170         TIFF -> T.38      false         false       "something.tif"
171         T.38 -> TIFF      true          false       "something.tif"
172         TIFF -> G.711     false         true        "something.tif"
173         G.711 ->TIFF      true          true        "something.tif"
174         T.38  -> G.711    false       don't care    PString::Empty()
175         G.711 -> T.38     true        don't care    PString::Empty()
176 
177     If T.38 is involved then there is generally two stages to the setup, as
178     indicated by the m_switchedToT38 flag. When false then we are in audio
179     mode looking for CNG/CED tones. When true, then we are switching, or have
180     switched, to T.38 operation. If the switch fails, then the m_disableT38
181     is set and we proceed in fall back mode.
182  */
183 class OpalFaxConnection : public OpalLocalConnection
184 {
185   PCLASSINFO(OpalFaxConnection, OpalLocalConnection);
186   public:
187   /**@name Construction */
188   //@{
189     /**Create a new endpoint.
190      */
191     OpalFaxConnection(
192       OpalCall & call,                 ///< Owner calll for connection
193       OpalFaxEndPoint & endpoint,      ///< Owner endpoint for connection
194       const PString & filename,        ///< TIFF file name to send/receive
195       bool receiving,                  ///< True if receiving a fax
196       bool disableT38,                 ///< True if want to force G.711
197       OpalConnection::StringOptions * stringOptions = NULL  ///< Options to pass to connection
198     );
199 
200     /**Destroy endpoint.
201      */
202     ~OpalFaxConnection();
203   //@}
204 
205   /**@name Overrides from OpalLocalConnection */
206   //@{
207     virtual PString GetPrefixName() const;
208 
209     virtual OpalMediaFormatList GetMediaFormats() const;
210     virtual void AdjustMediaFormats(bool local, const OpalConnection * otherConnection, OpalMediaFormatList & mediaFormats) const;
211     virtual void OnEstablished();
212     virtual void OnReleased();
213     virtual OpalMediaStream * CreateMediaStream(const OpalMediaFormat & mediaFormat, unsigned sessionID, PBoolean isSource);
214     virtual void OnStartMediaPatch(OpalMediaPatch & patch);
215     virtual void OnStopMediaPatch(OpalMediaPatch & patch);
216     virtual PBoolean SendUserInputTone(char tone, unsigned duration);
217     virtual void OnUserInputTone(char tone, unsigned duration);
218     virtual bool SwitchFaxMediaStreams(bool toT38);
219     virtual void OnSwitchedFaxMediaStreams(bool toT38, bool success);
220     virtual bool OnSwitchingFaxMediaStreams(bool toT38);
221   //@}
222 
223   /**@name New operations */
224   //@{
225     /**Fax transmission/receipt completed.
226        Default behaviour calls equivalent function on OpalFaxEndPoint.
227       */
228     virtual void OnFaxCompleted(
229       bool failed   ///< Fax ended with failure
230     );
231 
232 #if OPAL_STATISTICS
233     /**Get fax transmission/receipt statistics.
234       */
235     virtual void GetStatistics(
236       OpalMediaStatistics & statistics  ///< Statistics for call
237     ) const;
238 #endif
239 
240     /**Get the file to send/receive
241       */
GetFileName()242     const PString & GetFileName() const { return m_filename; }
243 
244     /**Get receive fax flag.
245       */
IsReceive()246     bool IsReceive() const { return m_receiving; }
247   //@}
248 
249   protected:
250     PDECLARE_NOTIFIER(PTimer,  OpalFaxConnection, OnSwitchTimeout);
251     PDECLARE_NOTIFIER(PThread, OpalFaxConnection, OpenFaxStreams);
252     void SetFaxMediaFormatOptions(OpalMediaFormat & mediaFormat) const;
253 
254 
255     OpalFaxEndPoint & m_endpoint;
256     PString           m_filename;
257     bool              m_receiving;
258     bool              m_disableT38;
259     OpalMediaFormat   m_tiffFileFormat;
260 #if OPAL_STATISTICS
261     void InternalGetStatistics(OpalMediaStatistics & statistics, bool terminate) const;
262     OpalMediaStatistics m_finalStatistics;
263 #endif
264 
265     enum {
266       e_AwaitingSwitchToT38,
267       e_SwitchingToT38,
268       e_CompletedSwitch
269     } m_state;
270 
271     PTimer m_switchTimer;
272 
273   friend class OpalFaxMediaStream;
274 };
275 
276 
277 typedef OpalFaxConnection OpalT38Connection; // For backward compatibility
278 
279 
280 #endif // OPAL_FAX
281 
282 #endif // OPAL_T38_T38PROTO_H
283