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_T38PROTO_H
00032 #define __OPAL_T38PROTO_H
00033
00034 #ifdef P_USE_PRAGMA
00035 #pragma interface
00036 #endif
00037
00038 #if OPAL_T38FAX
00039
00040 #include <ptlib/pipechan.h>
00041
00042 #include <opal/mediafmt.h>
00043 #include <opal/mediastrm.h>
00044 #include <opal/endpoint.h>
00045
00046 class OpalTransport;
00047 class T38_IFPPacket;
00048 class PASN_OctetString;
00049
00050 namespace PWLibStupidLinkerHacks {
00051 extern int t38Loader;
00052 };
00053
00055
00058 class OpalT38Protocol : public PObject
00059 {
00060 PCLASSINFO(OpalT38Protocol, PObject);
00061 public:
00066 OpalT38Protocol();
00067
00070 ~OpalT38Protocol();
00072
00077 virtual void Close();
00078
00083 virtual PBoolean Originate();
00084
00087 virtual PBoolean WritePacket(
00088 const T38_IFPPacket & pdu
00089 );
00090
00093 virtual PBoolean WriteIndicator(
00094 unsigned indicator
00095 );
00096
00099 virtual PBoolean WriteMultipleData(
00100 unsigned mode,
00101 PINDEX count,
00102 unsigned * type,
00103 const PBYTEArray * data
00104 );
00105
00108 virtual PBoolean WriteData(
00109 unsigned mode,
00110 unsigned type,
00111 const PBYTEArray & data
00112 );
00113
00116 virtual PBoolean Answer();
00117
00122 virtual PBoolean HandlePacket(
00123 const T38_IFPPacket & pdu
00124 );
00125
00130 virtual PBoolean HandlePacketLost(
00131 unsigned nLost
00132 );
00133
00137 virtual PBoolean OnIndicator(
00138 unsigned indicator
00139 );
00140
00144 virtual PBoolean OnCNG();
00145
00149 virtual PBoolean OnCED();
00150
00154 virtual PBoolean OnPreamble();
00155
00159 virtual PBoolean OnTraining(
00160 unsigned indicator
00161 );
00162
00167 virtual PBoolean OnData(
00168 unsigned mode,
00169 unsigned type,
00170 const PBYTEArray & data
00171 );
00173
00174 OpalTransport * GetTransport() const { return transport; }
00175 void SetTransport(
00176 OpalTransport * transport,
00177 PBoolean autoDelete = PTrue
00178 );
00179
00180 protected:
00181 PBoolean HandleRawIFP(
00182 const PASN_OctetString & pdu
00183 );
00184
00185 OpalTransport * transport;
00186 PBoolean autoDeleteTransport;
00187
00188 PBoolean corrigendumASN;
00189 unsigned indicatorRedundancy;
00190 unsigned lowSpeedRedundancy;
00191 unsigned highSpeedRedundancy;
00192
00193 int lastSentSequenceNumber;
00194 PList<PBYTEArray> redundantIFPs;
00195 };
00196
00197
00199
00200 #if OPAL_AUDIO
00201
00207 class OpalFaxAudioFormat : public OpalMediaFormat
00208 {
00209 friend class OpalPluginCodecManager;
00210 PCLASSINFO(OpalFaxAudioFormat, OpalMediaFormat);
00211 public:
00212 OpalFaxAudioFormat(
00213 const char * fullName,
00214 RTP_DataFrame::PayloadTypes rtpPayloadType,
00215 const char * encodingName,
00216 PINDEX frameSize,
00217 unsigned frameTime,
00218 unsigned rxFrames,
00219 unsigned txFrames,
00220 unsigned maxFrames = 256,
00221 unsigned clockRate = 8000,
00222 time_t timeStamp = 0
00223 );
00224 };
00225
00226 #endif
00227
00229
00235 class T38PseudoRTP : public RTP_UDP
00236 {
00237 PCLASSINFO(T38PseudoRTP, RTP_UDP);
00238
00239 public:
00244 T38PseudoRTP(
00245 #if OPAL_RTP_AGGREGATE
00246 PHandleAggregator * aggregator,
00247 #endif
00248 unsigned id,
00249 PBoolean remoteIsNAT
00250 );
00251
00253 ~T38PseudoRTP();
00254
00255 PBoolean ReadData(RTP_DataFrame & frame, PBoolean loop);
00256 PBoolean WriteData(RTP_DataFrame & frame);
00257 RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00258 RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & , PINDEX & );
00259
00260 RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
00261 RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
00262
00263 PBoolean SetRemoteSocketInfo(PIPSocket::Address address, WORD port, PBoolean isDataPort);
00264
00265 protected:
00266 int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timeout);
00267 PBoolean OnTimeout(RTP_DataFrame & frame);
00268 PBoolean corrigendumASN;
00269 int consecutiveBadPackets;
00270
00271 PBYTEArray lastIFP;
00272
00273 #if 0
00274 PList<PBYTEArray> redundantIFPs;
00275 #endif
00276
00278 };
00279
00281
00282 class OpalFaxCallInfo {
00283 public:
00284 OpalFaxCallInfo();
00285 PUDPSocket socket;
00286 PPipeChannel spanDSP;
00287 unsigned refCount;
00288 PIPSocket::Address spanDSPAddr;
00289 WORD spanDSPPort;
00290 };
00291
00293
00296 class OpalFaxMediaStream : public OpalMediaStream
00297 {
00298 PCLASSINFO(OpalFaxMediaStream, OpalMediaStream);
00299 public:
00304 OpalFaxMediaStream(
00305 OpalConnection & conn,
00306 const OpalMediaFormat & mediaFormat,
00307 unsigned sessionID,
00308 PBoolean isSource ,
00309 const PString & token,
00310 const PString & filename,
00311 PBoolean receive
00312 );
00314
00321 virtual PBoolean Open();
00322
00327 virtual PBoolean Close();
00328
00334 virtual PBoolean Start();
00335
00339 virtual PBoolean ReadPacket(
00340 RTP_DataFrame & packet
00341 );
00342
00346 virtual PBoolean WritePacket(
00347 RTP_DataFrame & packet
00348 );
00349
00353 virtual PBoolean IsSynchronous() const;
00354
00355 virtual PString GetSpanDSPCommandLine(OpalFaxCallInfo &);
00356
00358
00359 protected:
00360 PMutex infoMutex;
00361 PString sessionToken;
00362 OpalFaxCallInfo * faxCallInfo;
00363 PFilePath filename;
00364 PBoolean receive;
00365 BYTE writeBuffer[320];
00366 PINDEX writeBufferLen;
00367 };
00368
00370
00373 class OpalT38MediaStream : public OpalFaxMediaStream
00374 {
00375 PCLASSINFO(OpalT38MediaStream, OpalFaxMediaStream);
00376 public:
00377 OpalT38MediaStream(
00378 OpalConnection & conn,
00379 const OpalMediaFormat & mediaFormat,
00380 unsigned sessionID,
00381 PBoolean isSource ,
00382 const PString & token,
00383 const PString & filename,
00384 PBoolean receive
00385 );
00386
00387 PString GetSpanDSPCommandLine(OpalFaxCallInfo &);
00388
00389 PBoolean ReadPacket(RTP_DataFrame & packet);
00390 PBoolean WritePacket(RTP_DataFrame & packet);
00391 };
00392
00394
00395 class OpalFaxConnection;
00396
00399 class OpalFaxEndPoint : public OpalEndPoint
00400 {
00401 PCLASSINFO(OpalFaxEndPoint, OpalEndPoint);
00402 public:
00407 OpalFaxEndPoint(
00408 OpalManager & manager,
00409 const char * prefix = "fax"
00410 );
00411
00414 ~OpalFaxEndPoint();
00416
00417 virtual PBoolean MakeConnection(
00418 OpalCall & call,
00419 const PString & party,
00420 void * userData = NULL,
00421 unsigned int options = 0,
00422 OpalConnection::StringOptions * stringOptions = NULL
00423 );
00424
00427 virtual OpalFaxConnection * CreateConnection(
00428 OpalCall & call,
00429 const PString & filename,
00430 PBoolean receive,
00431 void * userData = NULL,
00432 OpalConnection::StringOptions * stringOptions = NULL
00433 );
00434
00444 virtual OpalMediaFormatList GetMediaFormats() const;
00445
00446 virtual PString MakeToken();
00447
00451 virtual void AcceptIncomingConnection(
00452 const PString & connectionToken
00453 );
00454
00459 virtual void OnPatchMediaStream(
00460 const OpalFaxConnection & connection,
00461 PBoolean isSource,
00462 OpalMediaPatch & patch
00463 );
00465 };
00466
00468
00471 class OpalFaxConnection : public OpalConnection
00472 {
00473 PCLASSINFO(OpalFaxConnection, OpalConnection);
00474 public:
00479 OpalFaxConnection(
00480 OpalCall & call,
00481 OpalFaxEndPoint & endpoint,
00482 const PString & filename,
00483 PBoolean receive,
00484 const PString & _token,
00485 OpalConnection::StringOptions * stringOptions = NULL
00486 );
00487
00490 ~OpalFaxConnection();
00492
00501 virtual PBoolean SetUpConnection();
00502
00513 virtual PBoolean SetAlerting(
00514 const PString & calleeName,
00515 PBoolean withMedia
00516 );
00517
00522 virtual PBoolean SetConnected();
00523
00531 virtual OpalMediaFormatList GetMediaFormats() const;
00532
00533 OpalMediaStream * CreateMediaStream(const OpalMediaFormat & mediaFormat, unsigned sessionID, PBoolean isSource);
00534
00542 virtual void OnPatchMediaStream(
00543 PBoolean isSource,
00544 OpalMediaPatch & patch
00545 );
00546
00551 virtual void AcceptIncoming();
00552
00554
00555 void AdjustMediaFormats(OpalMediaFormatList & mediaFormats) const;
00556
00557 protected:
00558 OpalFaxEndPoint & endpoint;
00559 PString filename;
00560 PBoolean receive;
00561 PBoolean forceFaxAudio;
00562 };
00563
00565
00566 class OpalT38Connection;
00567
00570 class OpalT38EndPoint : public OpalFaxEndPoint
00571 {
00572 PCLASSINFO(OpalT38EndPoint, OpalFaxEndPoint);
00573 public:
00578 OpalT38EndPoint(
00579 OpalManager & manager,
00580 const char * prefix = "t38"
00581 );
00582 OpalMediaFormatList GetMediaFormats() const;
00583 PString MakeToken();
00584 virtual OpalFaxConnection * CreateConnection(OpalCall & call, const PString & filename, PBoolean receive, void * , OpalConnection::StringOptions * stringOptions);
00585 };
00586
00588
00591 class OpalT38Connection : public OpalFaxConnection
00592 {
00593 PCLASSINFO(OpalT38Connection, OpalFaxConnection);
00594 public:
00599 OpalT38Connection(
00600 OpalCall & call,
00601 OpalT38EndPoint & endpoint,
00602 const PString & filename,
00603 PBoolean receive,
00604 const PString & _token,
00605 OpalConnection::StringOptions * stringOptions = NULL
00606 );
00607 void AdjustMediaFormats(OpalMediaFormatList & mediaFormats) const;
00608 OpalMediaStream * CreateMediaStream(const OpalMediaFormat & mediaFormat, unsigned sessionID, PBoolean isSource);
00609 OpalMediaFormatList GetMediaFormats() const;
00610 };
00611
00613
00614 #define OPAL_T38 "T.38"
00615 #define OPAL_PCM16_FAX "PCM-16-Fax"
00616
00617 extern const OpalFaxAudioFormat & GetOpalPCM16Fax();
00618 extern const OpalMediaFormat & GetOpalT38();
00619
00620 #define OpalPCM16Fax GetOpalPCM16Fax()
00621 #define OpalT38 GetOpalT38()
00622
00623
00624 #endif // OPAL_T38FAX
00625
00626 #endif // __OPAL_T38PROTO_H