OPAL  Version 3.14.3
t38proto.h
Go to the documentation of this file.
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: 31967 $
27  * $Author: rjongbloed $
28  * $Date: 2014-05-26 17:40:17 +1000 (Mon, 26 May 2014) $
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_config.h>
39 
40 #if OPAL_T38_CAPABILITY
41 
42 #include <opal/mediafmt.h>
43 #include <opal/mediastrm.h>
44 #include <opal/mediasession.h>
45 #include <ep/localep.h>
46 
47 
48 class OpalTransport;
49 class OpalFaxConnection;
50 
51 #if OPAL_PTLIB_ASN
52 class T38_IFPPacket;
53 class PASN_OctetString;
54 #endif
55 
56 #define OPAL_OPT_STATION_ID "Station-Id"
57 #define OPAL_OPT_HEADER_INFO "Header-Info"
58 #define OPAL_NO_G111_FAX "No-G711-Fax"
59 #define OPAL_SWITCH_ON_CED "Switch-On-CED"
60 #define OPAL_T38_SWITCH_TIME "T38-Switch-Time"
61 
62 #define OPAL_FAX_TIFF_FILE "TIFF-File"
63 
64 #define OPAL_T38FaxRateManagement "T38FaxRateManagement"
65 #define OPAL_T38localTCF "localTCF"
66 #define OPAL_T38transferredTCF "transferredTCF"
67 #define OPAL_T38FaxVersion "T38FaxVersion"
68 #define OPAL_T38MaxBitRate "T38MaxBitRate"
69 #define OPAL_T38FaxMaxBuffer "T38FaxMaxBuffer"
70 #define OPAL_T38FaxMaxDatagram "T38FaxMaxDatagram"
71 #define OPAL_T38FaxUdpEC "T38FaxUdpEC"
72 #define OPAL_T38UDPFEC "t38UDPFEC"
73 #define OPAL_T38UDPRedundancy "t38UDPRedundancy"
74 #define OPAL_T38FaxFillBitRemoval "T38FaxFillBitRemoval"
75 #define OPAL_T38FaxTranscodingMMR "T38FaxTranscodingMMR"
76 #define OPAL_T38FaxTranscodingJBIG "T38FaxTranscodingJBIG"
77 #define OPAL_T38UseECM "Use-ECM"
78 #define OPAL_FaxStationIdentifier "Station-Identifier"
79 #define OPAL_FaxHeaderInfo "Header-Info"
80 #define OPAL_UDPTLRawMode "UDPTL-Raw-Mode"
81 
82 
83 #if OPAL_FAX
84 
86 
87 class OpalFaxConnection;
88 
100 class OpalFaxEndPoint : public OpalLocalEndPoint
101 {
102  PCLASSINFO(OpalFaxEndPoint, OpalLocalEndPoint);
103  public:
108  OpalFaxEndPoint(
109  OpalManager & manager,
110  const char * g711Prefix = "fax",
111  const char * t38Prefix = "t38"
112  );
113 
116  ~OpalFaxEndPoint();
118 
121  virtual PSafePtr<OpalConnection> MakeConnection(
122  OpalCall & call,
123  const PString & party,
124  void * userData = NULL,
125  unsigned int options = 0,
126  OpalConnection::StringOptions * stringOptions = NULL
127  );
128 
136  virtual OpalMediaFormatList GetMediaFormats() const;
138 
143  virtual bool IsAvailable() const;
144 
147  virtual OpalFaxConnection * CreateConnection(
148  OpalCall & call,
149  void * userData,
150  OpalConnection::StringOptions * stringOptions,
151  const PString & filename,
152  bool receiving,
153  bool disableT38
154  );
155 
159  virtual void OnFaxCompleted(
160  OpalFaxConnection & connection,
161  bool failed
162  );
164 
168  const PString & GetDefaultDirectory() const { return m_defaultDirectory; }
169 
172  void SetDefaultDirectory(
173  const PString & dir
174  ) { m_defaultDirectory = dir; }
175 
176  const PString & GetT38Prefix() const { return m_t38Prefix; }
178 
179  protected:
180  PString m_t38Prefix;
181  PDirectory m_defaultDirectory;
182 };
183 
184 
186 
203 class OpalFaxConnection : public OpalLocalConnection
204 {
205  PCLASSINFO(OpalFaxConnection, OpalLocalConnection);
206  public:
211  OpalFaxConnection(
212  OpalCall & call,
213  OpalFaxEndPoint & endpoint,
214  const PString & filename,
215  bool receiving,
216  bool disableT38,
217  OpalConnection::StringOptions * stringOptions = NULL
218  );
219 
222  ~OpalFaxConnection();
224 
227  virtual PString GetPrefixName() const;
228 
229  virtual OpalMediaFormatList GetMediaFormats() const;
230  virtual void AdjustMediaFormats(bool local, const OpalConnection * otherConnection, OpalMediaFormatList & mediaFormats) const;
231  virtual void OnEstablished();
232  virtual void OnReleased();
233  virtual OpalMediaStream * CreateMediaStream(const OpalMediaFormat & mediaFormat, unsigned sessionID, PBoolean isSource);
234  virtual void OnClosedMediaStream(const OpalMediaStream & stream);
235  virtual PBoolean SendUserInputTone(char tone, unsigned duration);
236  virtual void OnUserInputTone(char tone, unsigned duration);
237  virtual bool SwitchFaxMediaStreams(bool toT38);
238  virtual void OnSwitchedFaxMediaStreams(bool toT38, bool success);
239  virtual bool OnSwitchingFaxMediaStreams(bool toT38);
240  virtual void OnApplyStringOptions();
242 
248  virtual void OnFaxCompleted(
249  bool failed
250  );
251 
254  virtual void GetStatistics(
255  OpalMediaStatistics & statistics
256  ) const;
257 
260  const PString & GetFileName() const { return m_filename; }
261 
264  bool IsReceive() const { return m_receiving; }
266 
267  protected:
268  PDECLARE_NOTIFIER(PTimer, OpalFaxConnection, OnSwitchTimeout);
269  void InternalOpenFaxStreams();
270  void InternalOnFaxCompleted();
271 
272  void SetFaxMediaFormatOptions(OpalMediaFormat & mediaFormat) const;
273 
274  OpalFaxEndPoint & m_endpoint;
275  PString m_filename;
276  bool m_receiving;
277  bool m_disableT38;
278  unsigned m_switchTime;
279  OpalMediaFormat m_tiffFileFormat;
280 
281  PTimer m_switchTimer;
282 
283  OpalMediaStatistics m_finalStatistics;
284  PAtomicBoolean m_completed;
285 };
286 
287 
288 typedef OpalFaxConnection OpalT38Connection; // For backward compatibility
289 
290 class T38_UDPTLPacket;
291 
292 class OpalFaxSession : public OpalMediaSession
293 {
294  public:
295  static const PCaselessString & UDPTL();
296 
297  OpalFaxSession(const Init & init);
298  ~OpalFaxSession();
299 
300  virtual const PCaselessString & GetSessionType() const { return UDPTL(); }
301  virtual bool Open(const PString & localInterface, const OpalTransportAddress & remoteAddress, bool isMediaAddress);
302  virtual bool IsOpen() const;
303  virtual bool Close();
304  virtual OpalTransportAddress GetLocalAddress(bool isMediaAddress = true) const;
305  virtual OpalTransportAddress GetRemoteAddress(bool isMediaAddress = true) const;
306  virtual bool SetRemoteAddress(const OpalTransportAddress & remoteAddress, bool isMediaAddress = true);
307 
308  virtual void AttachTransport(Transport & transport);
309  virtual Transport DetachTransport();
310 
312  const OpalMediaFormat & mediaFormat,
313  unsigned sessionID,
314  bool isSource
315  );
316 
317  bool WriteData(RTP_DataFrame & frame);
318  bool ReadData(RTP_DataFrame & frame);
319 
320  void ApplyMediaOptions(const OpalMediaFormat & mediaFormat);
321 
322  virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
323 
324  protected:
325  void SetFrameFromIFP(RTP_DataFrame & frame, const PASN_OctetString & ifp, unsigned sequenceNumber);
326  void DecrementSentPacketRedundancy(bool stripRedundancy);
327  bool WriteUDPTL();
328 
329  Transport m_savedTransport;
330  PIPSocket * m_dataSocket;
331  bool m_shuttingDown;
332 
333  bool m_rawUDPTL; // Put UDPTL directly in RTP payload
334  PINDEX m_datagramSize;
335 
336  int m_consecutiveBadPackets;
337  bool m_awaitingGoodPacket;
338  T38_UDPTLPacket * m_receivedPacket;
339  unsigned m_expectedSequenceNumber;
340  int m_secondaryPacket;
341 
342  std::map<int, int> m_redundancy;
343  PTimeInterval m_redundancyInterval;
344  PTimeInterval m_keepAliveInterval;
345  bool m_optimiseOnRetransmit;
346  std::vector<int> m_sentPacketRedundancy;
347  T38_UDPTLPacket * m_sentPacket;
348  PMutex m_writeMutex;
349  PTimer m_timerWriteDataIdle;
350  PDECLARE_NOTIFIER(PTimer, OpalFaxSession, OnWriteDataIdle);
351 
352  PUInt64 m_txBytes;
353  unsigned m_txPackets;
354  PUInt64 m_rxBytes;
355  unsigned m_rxPackets;
356  unsigned m_missingPackets;
357 };
358 
359 class OpalFaxMediaStream : public OpalMediaStream
360 {
361  PCLASSINFO(OpalFaxMediaStream, OpalMediaStream);
362 
363  public:
364  OpalFaxMediaStream(OpalConnection & conn,
365  const OpalMediaFormat & mediaFormat,
366  unsigned sessionID,
367  bool isSource,
368  OpalFaxSession & session);
369 
370  virtual PBoolean Open();
371  virtual PBoolean ReadPacket(RTP_DataFrame & packet);
372  virtual PBoolean WritePacket(RTP_DataFrame & packet);
373  virtual PBoolean IsSynchronous() const;
374  virtual bool InternalUpdateMediaFormat(const OpalMediaFormat & mediaFormat);
375  virtual void GetStatistics(OpalMediaStatistics & statistics, bool fromPatch) const;
376 
377  protected:
378  virtual void InternalClose();
379 
380  OpalFaxSession & m_session;
381 };
382 
383 #endif // OPAL_FAX
384 #endif // OPAL_T38_CAPABILITY
385 
386 #endif // OPAL_T38_T38PROTO_H