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
00032
00033
00034
00035 #ifndef __OPAL_CONNECTION_H
00036 #define __OPAL_CONNECTION_H
00037
00038 #ifdef P_USE_PRAGMA
00039 #pragma interface
00040 #endif
00041
00042 #include <opal/buildopts.h>
00043
00044 #include <opal/mediafmt.h>
00045 #include <opal/mediastrm.h>
00046 #include <opal/guid.h>
00047 #include <opal/transports.h>
00048 #include <ptclib/dtmf.h>
00049 #include <ptlib/safecoll.h>
00050 #include <rtp/rtp.h>
00051
00052 class OpalEndPoint;
00053 class OpalCall;
00054 class OpalSilenceDetector;
00055 class OpalEchoCanceler;
00056 class OpalRFC2833Proto;
00057 class OpalRFC2833Info;
00058 class OpalT120Protocol;
00059 class OpalT38Protocol;
00060 class OpalH224Handler;
00061 class OpalH281Handler;
00062
00063
00066 class OpalProductInfo
00067 {
00068 public:
00069 OpalProductInfo();
00070
00071 static OpalProductInfo & Default();
00072
00073 PCaselessString AsString() const;
00074
00075 PString vendor;
00076 PString name;
00077 PString version;
00078 BYTE t35CountryCode;
00079 BYTE t35Extension;
00080 WORD manufacturerCode;
00081 };
00082
00083
00101 class OpalConnection : public PSafeObject
00102 {
00103 PCLASSINFO(OpalConnection, PSafeObject);
00104 public:
00109 enum CallEndReason {
00110 EndedByLocalUser,
00111 EndedByNoAccept,
00112 EndedByAnswerDenied,
00113 EndedByRemoteUser,
00114 EndedByRefusal,
00115 EndedByNoAnswer,
00116 EndedByCallerAbort,
00117 EndedByTransportFail,
00118 EndedByConnectFail,
00119 EndedByGatekeeper,
00120 EndedByNoUser,
00121 EndedByNoBandwidth,
00122 EndedByCapabilityExchange,
00123 EndedByCallForwarded,
00124 EndedBySecurityDenial,
00125 EndedByLocalBusy,
00126 EndedByLocalCongestion,
00127 EndedByRemoteBusy,
00128 EndedByRemoteCongestion,
00129 EndedByUnreachable,
00130 EndedByNoEndPoint,
00131 EndedByHostOffline,
00132 EndedByTemporaryFailure,
00133 EndedByQ931Cause,
00134 EndedByDurationLimit,
00135 EndedByInvalidConferenceID,
00136 EndedByNoDialTone,
00137 EndedByNoRingBackTone,
00138 EndedByOutOfService,
00139 EndedByAcceptingCallWaiting,
00140 NumCallEndReasons,
00141
00142 EndedWithQ931Code = 0x100
00143 };
00144
00145 #if PTRACING
00146 friend ostream & operator<<(ostream & o, CallEndReason reason);
00147 #endif
00148
00149 enum AnswerCallResponse {
00150 AnswerCallNow,
00151 AnswerCallDenied,
00152 AnswerCallPending,
00153 AnswerCallDeferred,
00154 AnswerCallAlertWithMedia,
00155 AnswerCallDeferredWithMedia,
00156 AnswerCallProgress,
00157 AnswerCallNowAndReleaseCurrent,
00158 NumAnswerCallResponses
00159 };
00160 #if PTRACING
00161 friend ostream & operator<<(ostream & o, AnswerCallResponse s);
00162 #endif
00163
00166 enum Options {
00167 FastStartOptionDisable = 0x0001,
00168 FastStartOptionEnable = 0x0002,
00169 FastStartOptionMask = 0x0003,
00170
00171 H245TunnelingOptionDisable = 0x0004,
00172 H245TunnelingOptionEnable = 0x0008,
00173 H245TunnelingOptionMask = 0x000c,
00174
00175 H245inSetupOptionDisable = 0x0010,
00176 H245inSetupOptionEnable = 0x0020,
00177 H245inSetupOptionMask = 0x0030,
00178
00179 DetectInBandDTMFOptionDisable = 0x0040,
00180 DetectInBandDTMFOptionEnable = 0x0080,
00181 DetectInBandDTMFOptionMask = 0x00c0,
00182
00183 RTPAggregationDisable = 0x0100,
00184 RTPAggregationEnable = 0x0200,
00185 RTPAggregationMask = 0x0300,
00186
00187 SendDTMFAsDefault = 0x0000,
00188 SendDTMFAsString = 0x0400,
00189 SendDTMFAsTone = 0x0800,
00190 SendDTMFAsRFC2833 = 0x0c00,
00191 SendDTMFMask = 0x0c00
00192 };
00193
00194 class StringOptions : public PStringToString
00195 {
00196 };
00197
00202 OpalConnection(
00203 OpalCall & call,
00204 OpalEndPoint & endpoint,
00205 const PString & token,
00206 unsigned options = 0,
00207 OpalConnection::StringOptions * stringOptions = NULL
00208 );
00209
00212 ~OpalConnection();
00214
00221 void PrintOn(
00222 ostream & strm
00223 ) const;
00225
00228 enum Phases {
00229 UninitialisedPhase,
00230 SetUpPhase,
00231 AlertingPhase,
00232 ConnectedPhase,
00233 EstablishedPhase,
00234 ReleasingPhase,
00235 ReleasedPhase,
00236 NumPhases
00237 };
00238
00243 inline Phases GetPhase() const { return phase; }
00244
00253 CallEndReason GetCallEndReason() const { return callEndReason; }
00254
00259 virtual void SetCallEndReason(
00260 CallEndReason reason
00261 );
00262
00270 void ClearCall(
00271 CallEndReason reason = EndedByLocalUser
00272 );
00273
00276 virtual void ClearCallSynchronous(
00277 PSyncPoint * sync,
00278 CallEndReason reason = EndedByLocalUser
00279 );
00280
00284 unsigned GetQ931Cause() const { return q931Cause; }
00285
00289 void SetQ931Cause(unsigned v) { q931Cause = v; }
00290
00294 virtual void TransferConnection(
00295 const PString & remoteParty,
00296 const PString & callIdentity = PString::Empty()
00298 );
00299
00302 virtual void HoldConnection();
00303
00307 virtual void RetrieveConnection();
00308
00311 virtual PBoolean IsConnectionOnHold();
00313
00341 virtual PBoolean OnIncomingConnection(unsigned int options, OpalConnection::StringOptions * stringOptions);
00342 virtual PBoolean OnIncomingConnection(unsigned int options);
00343 virtual PBoolean OnIncomingConnection();
00344
00351 virtual PBoolean SetUpConnection() = 0;
00352
00356 virtual PBoolean OnSetUpConnection();
00357
00358
00374 virtual void OnAlerting();
00375
00386 virtual PBoolean SetAlerting(
00387 const PString & calleeName,
00388 PBoolean withMedia
00389 ) = 0;
00390
00407 virtual AnswerCallResponse OnAnswerCall(
00408 const PString & callerName
00409 );
00410
00421 virtual void AnsweringCall(
00422 AnswerCallResponse response
00423 );
00424
00435 virtual void OnConnected();
00436
00441 virtual PBoolean SetConnected() = 0;
00442
00454 virtual void OnEstablished();
00455
00464 virtual void Release(
00465 CallEndReason reason = EndedByLocalUser
00466 );
00467
00485 virtual void OnReleased();
00487
00497 virtual PString GetDestinationAddress();
00498
00508 virtual PBoolean ForwardCall(
00509 const PString & forwardParty
00510 );
00512
00521 virtual OpalMediaFormatList GetMediaFormats() const = 0;
00522
00527 virtual OpalMediaFormatList GetLocalMediaFormats();
00528
00537 virtual void AdjustMediaFormats(
00538 OpalMediaFormatList & mediaFormats
00539 ) const;
00540
00543 virtual OpalMediaStreamPtr OpenMediaStream(
00544 const OpalMediaFormat & mediaFormat,
00545 unsigned sessionID,
00546 bool isSource
00547 );
00548
00553 virtual bool CloseMediaStream(
00554 unsigned sessionId,
00555 bool source
00556 );
00557
00562 virtual bool CloseMediaStream(
00563 OpalMediaStream & stream
00564 );
00565
00573 bool RemoveMediaStream(
00574 OpalMediaStream & strm
00575 );
00576
00579 virtual void StartMediaStreams();
00580
00583 virtual void CloseMediaStreams();
00584
00587 virtual void PauseMediaStreams(PBoolean paused);
00588
00601 virtual OpalMediaStream * CreateMediaStream(
00602 const OpalMediaFormat & mediaFormat,
00603 unsigned sessionID,
00604 PBoolean isSource
00605 );
00606
00612 OpalMediaStreamPtr GetMediaStream(
00613 unsigned sessionId,
00614 bool source
00615 ) const;
00616
00628 virtual PBoolean OnOpenMediaStream(
00629 OpalMediaStream & stream
00630 );
00631
00636 virtual void OnClosedMediaStream(
00637 const OpalMediaStream & stream
00638 );
00639
00644 virtual void OnPatchMediaStream(
00645 PBoolean isSource,
00646 OpalMediaPatch & patch
00647 );
00648
00653 virtual void AttachRFC2833HandlerToPatch(PBoolean isSource, OpalMediaPatch & patch);
00654
00660 virtual PBoolean IsMediaBypassPossible(
00661 unsigned sessionID
00662 ) const;
00663
00666 struct MediaInformation {
00667 MediaInformation() {
00668 rfc2833 = RTP_DataFrame::IllegalPayloadType;
00669 #if OPAL_T38FAX
00670 ciscoNSE = RTP_DataFrame::IllegalPayloadType;
00671 #endif
00672 }
00673
00674 OpalTransportAddress data;
00675 OpalTransportAddress control;
00676 RTP_DataFrame::PayloadTypes rfc2833;
00677 #if OPAL_T38FAX
00678 RTP_DataFrame::PayloadTypes ciscoNSE;
00679 #endif
00680 };
00681
00690 virtual PBoolean GetMediaInformation(
00691 unsigned sessionID,
00692 MediaInformation & info
00693 ) const;
00694
00695 #if OPAL_VIDEO
00696
00701 virtual void AddVideoMediaFormats(
00702 OpalMediaFormatList & mediaFormats
00703 ) const;
00704
00707 virtual PBoolean CreateVideoInputDevice(
00708 const OpalMediaFormat & mediaFormat,
00709 PVideoInputDevice * & device,
00710 PBoolean & autoDelete
00711 );
00712
00716 virtual PBoolean CreateVideoOutputDevice(
00717 const OpalMediaFormat & mediaFormat,
00718 PBoolean preview,
00719 PVideoOutputDevice * & device,
00720 PBoolean & autoDelete
00721 );
00722 #endif
00723
00726 virtual PBoolean SetAudioVolume(
00727 PBoolean source,
00728 unsigned percentage
00729 );
00730
00734 virtual unsigned GetAudioSignalLevel(
00735 PBoolean source
00736 );
00738
00744 virtual RTP_Session * GetSession(
00745 unsigned sessionID
00746 ) const;
00747
00762 virtual RTP_Session * UseSession(
00763 unsigned sessionID
00764 );
00765 virtual RTP_Session * UseSession(
00766 const OpalTransport & transport,
00767 unsigned sessionID,
00768 RTP_QOS * rtpqos = NULL
00769 );
00770
00775 virtual void ReleaseSession(
00776 unsigned sessionID,
00777 PBoolean clearAll = PFalse
00778 );
00779
00784 virtual RTP_Session * CreateSession(
00785 const OpalTransport & transport,
00786 unsigned sessionID,
00787 RTP_QOS * rtpqos
00788 );
00789
00798 virtual PINDEX GetMaxRtpPayloadSize() const;
00800
00805 unsigned GetBandwidthAvailable() const { return bandwidthAvailable; }
00806
00811 virtual PBoolean SetBandwidthAvailable(
00812 unsigned newBandwidth,
00813 PBoolean force = PFalse
00814 );
00815
00820 virtual unsigned GetBandwidthUsed() const;
00821
00830 virtual PBoolean SetBandwidthUsed(
00831 unsigned releasedBandwidth,
00832 unsigned requiredBandwidth
00833 );
00835
00838 enum SendUserInputModes {
00839 SendUserInputAsQ931,
00840 SendUserInputAsString,
00841 SendUserInputAsTone,
00842 SendUserInputAsInlineRFC2833,
00843 SendUserInputAsSeparateRFC2833,
00844 SendUserInputAsProtocolDefault,
00845 NumSendUserInputModes
00846 };
00847 #if PTRACING
00848 friend ostream & operator<<(ostream & o, SendUserInputModes m);
00849 #endif
00850
00853 virtual void SetSendUserInputMode(SendUserInputModes mode);
00854
00857 virtual SendUserInputModes GetSendUserInputMode() const { return sendUserInputMode; }
00858
00864 virtual SendUserInputModes GetRealSendUserInputMode() const { return GetSendUserInputMode(); }
00865
00872 virtual PBoolean SendUserInputString(
00873 const PString & value
00874 );
00875
00892 virtual PBoolean SendUserInputTone(
00893 char tone,
00894 unsigned duration = 0
00895 );
00896
00903 virtual void OnUserInputString(
00904 const PString & value
00905 );
00906
00913 virtual void OnUserInputTone(
00914 char tone,
00915 unsigned duration
00916 );
00917
00921 void SendUserInputHookFlash(
00922 unsigned duration = 500
00923 ) { SendUserInputTone('!', duration); }
00924
00927 virtual PString GetUserInput(
00928 unsigned timeout = 30
00929 );
00930
00935 virtual void SetUserInput(
00936 const PString & input
00937 );
00938
00941 virtual PString ReadUserInput(
00942 const char * terminators = "#\r\n",
00943 unsigned lastDigitTimeout = 4,
00944 unsigned firstDigitTimeout = 30
00945 );
00946
00953 virtual PBoolean PromptUserInput(
00954 PBoolean play
00955 );
00957
00960 #if OPAL_T120DATA
00961
00973 virtual OpalT120Protocol * CreateT120ProtocolHandler();
00974 #endif
00975
00976 #if OPAL_T38FAX
00977
00989 virtual OpalT38Protocol * CreateT38ProtocolHandler();
00990 #endif
00991
00992 #if OPAL_H224
00993
01005 virtual OpalH224Handler *CreateH224ProtocolHandler(unsigned sessionID);
01006
01016 virtual OpalH281Handler *CreateH281ProtocolHandler(OpalH224Handler & h224Handler);
01017
01021 OpalH224Handler * GetH224Handler() const { return h224Handler; }
01022 #endif
01023
01028 virtual bool GarbageCollection();
01030
01035 OpalEndPoint & GetEndPoint() const { return endpoint; }
01036
01039 OpalCall & GetCall() const { return ownerCall; }
01040
01043 const PString & GetToken() const { return callToken; }
01044
01047 PBoolean IsOriginating() const { return originating; }
01048
01051 PTime GetSetupUpTime() const { return setupTime; }
01052
01055 PTime GetAlertingTime() const { return alertingTime; }
01056
01059 PTime GetConnectionStartTime() const { return connectedTime; }
01060
01063 PTime GetConnectionEndTime() const { return callEndTime; }
01064
01067 const OpalProductInfo & GetProductInfo() const { return productInfo; }
01068
01071 void SetProductInfo(
01072 const OpalProductInfo & info
01073 ) { productInfo = info; }
01074
01077 const PString & GetLocalPartyName() const { return localPartyName; }
01078
01081 virtual void SetLocalPartyName(const PString & name);
01082
01085 virtual PString GetLocalPartyURL() const;
01086
01089 const PString & GetDisplayName() const { return displayName; }
01090
01093 void SetDisplayName(const PString & name) { displayName = name; }
01094
01097 const PString & GetRemotePartyName() const { return remotePartyName; }
01098
01102 PCaselessString GetRemoteApplication() const { return remoteProductInfo.AsString(); }
01103
01106 const OpalProductInfo & GetRemoteProductInfo() const { return remoteProductInfo; }
01107
01112 const PString & GetRemotePartyNumber() const { return remotePartyNumber; }
01113
01116 const PString & GetRemotePartyAddress() const { return remotePartyAddress; }
01117
01122 virtual const PString GetRemotePartyCallbackURL() const { return remotePartyAddress; }
01123
01124
01128 virtual const PString & GetCalledDestinationNumber() const { return calledDestinationNumber; }
01129
01133 virtual const PString & GetCalledDestinationName() const { return calledDestinationName; }
01134
01138 virtual const PString & GetCalledDestinationURL() const { return calledDestinationURL; }
01139
01143 unsigned GetMinAudioJitterDelay() const { return minAudioJitterDelay; }
01144
01148 unsigned GetMaxAudioJitterDelay() const { return maxAudioJitterDelay; }
01149
01152 void SetAudioJitterDelay(
01153 unsigned minDelay,
01154 unsigned maxDelay
01155 );
01156
01159 OpalSilenceDetector * GetSilenceDetector() const { return silenceDetector; }
01160
01163 OpalEchoCanceler * GetEchoCanceler() const { return echoCanceler; }
01164
01167 virtual const OpalGloballyUniqueID & GetIdentifier() const
01168 { return callIdentifier; }
01169
01170 virtual OpalTransport & GetTransport() const
01171 { return *(OpalTransport *)NULL; }
01172
01173 PDICTIONARY(MediaAddressesDict, POrdinalKey, OpalTransportAddress);
01174 MediaAddressesDict & GetMediaTransportAddresses()
01175 { return mediaTransportAddresses; }
01176
01177 #ifdef OPAL_STATISTICS
01178
01180 unsigned GetVideoUpdateRequestsSent() const { return m_VideoUpdateRequestsSent; }
01181 #endif
01182
01183
01184 const RTP_DataFrame::PayloadMapType & GetRTPPayloadMap() const
01185 { return rtpPayloadMap; }
01186
01189 PBoolean RemoteIsNAT() const
01190 { return remoteIsNAT; }
01191
01209 virtual PBoolean IsRTPNATEnabled(
01210 const PIPSocket::Address & localAddr,
01211 const PIPSocket::Address & peerAddr,
01212 const PIPSocket::Address & signalAddr,
01213 PBoolean incoming
01214 );
01215
01216 virtual void SetSecurityMode(const PString & v)
01217 { securityMode = v; }
01218
01219 virtual PString GetSecurityMode() const
01220 { return securityMode; }
01221
01222 virtual void * GetSecurityData();
01223 virtual void SetSecurityData(void *data);
01224
01225 StringOptions * GetStringOptions() const
01226 { return stringOptions; }
01227
01228 void SetStringOptions(StringOptions * options);
01229
01241 virtual PBoolean OnOpenIncomingMediaChannels();
01242
01243 virtual void ApplyStringOptions();
01244
01245 virtual void PreviewPeerMediaFormats(const OpalMediaFormatList & fmts);
01246
01247 virtual void EnableRecording();
01248 virtual void DisableRecording();
01249
01250 virtual void OnMediaPatchStart(
01251 unsigned sessionId,
01252 bool isSource
01253 );
01254 virtual void OnMediaPatchStop(
01255 unsigned sessionId,
01256 bool isSource
01257 );
01258
01262 PDECLARE_NOTIFIER(OpalMediaCommand, OpalConnection, OnMediaCommand);
01263
01264 protected:
01265 PDECLARE_NOTIFIER(OpalRFC2833Info, OpalConnection, OnUserInputInlineRFC2833);
01266 PDECLARE_NOTIFIER(OpalRFC2833Info, OpalConnection, OnUserInputInlineCiscoNSE);
01267 #if P_DTMF
01268 PDECLARE_NOTIFIER(RTP_DataFrame, OpalConnection, OnUserInputInBandDTMF);
01269 #endif
01270 PDECLARE_NOTIFIER(PThread, OpalConnection, OnReleaseThreadMain);
01271 PDECLARE_NOTIFIER(RTP_DataFrame, OpalConnection, OnRecordAudio);
01272
01273
01274 OpalCall & ownerCall;
01275 OpalEndPoint & endpoint;
01276
01277 PMutex phaseMutex;
01278 Phases phase;
01279
01280 PString callToken;
01281 OpalGloballyUniqueID callIdentifier;
01282 PBoolean originating;
01283 PTime setupTime;
01284 PTime alertingTime;
01285 PTime connectedTime;
01286 PTime callEndTime;
01287 OpalProductInfo productInfo;
01288 PString localPartyName;
01289 PString displayName;
01290 PString remotePartyName;
01291 OpalProductInfo remoteProductInfo;
01292 PString remotePartyNumber;
01293 PString remotePartyAddress;
01294 CallEndReason callEndReason;
01295 PString calledDestinationNumber;
01296 PString calledDestinationName;
01297 PString calledDestinationURL;
01298 PBoolean remoteIsNAT;
01299
01300 SendUserInputModes sendUserInputMode;
01301 PString userInputString;
01302 PSyncPoint userInputAvailable;
01303 PBoolean detectInBandDTMF;
01304 unsigned q931Cause;
01305
01306 OpalSilenceDetector * silenceDetector;
01307 OpalEchoCanceler * echoCanceler;
01308 OpalRFC2833Proto * rfc2833Handler;
01309 #if OPAL_T120DATA
01310 OpalT120Protocol * t120handler;
01311 #endif
01312 #if OPAL_T38FAX
01313 OpalT38Protocol * t38handler;
01314 OpalRFC2833Proto * ciscoNSEHandler;
01315 #endif
01316 #if OPAL_H224
01317 OpalH224Handler * h224Handler;
01318 #endif
01319
01320 OpalMediaFormatList localMediaFormats;
01321 MediaAddressesDict mediaTransportAddresses;
01322 PSafeList<OpalMediaStream> mediaStreams;
01323 RTP_SessionManager rtpSessions;
01324
01325 unsigned minAudioJitterDelay;
01326 unsigned maxAudioJitterDelay;
01327 unsigned bandwidthAvailable;
01328
01329 RTP_DataFrame::PayloadMapType rtpPayloadMap;
01330
01331
01332
01333 #if P_DTMF
01334 PDTMFDecoder dtmfDecoder;
01335 #endif
01336
01337 PString securityMode;
01338 void * securityData;
01339
01343 void SetPhase(Phases phaseToSet);
01344
01345 #if PTRACING
01346 friend ostream & operator<<(ostream & o, Phases p);
01347 #endif
01348
01349 PBoolean useRTPAggregation;
01350
01351 StringOptions * stringOptions;
01352 PString recordAudioFilename;
01353
01354 #ifdef OPAL_STATISTICS
01355 unsigned m_VideoUpdateRequestsSent;
01356 #endif
01357 };
01358
01359 class RTP_UDP;
01360
01361 class OpalSecurityMode : public PObject
01362 {
01363 PCLASSINFO(OpalSecurityMode, PObject);
01364 public:
01365 virtual RTP_UDP * CreateRTPSession(
01366 #if OPAL_RTP_AGGREGATE
01367 PHandleAggregator * _aggregator,
01368 #endif
01369 unsigned id,
01370 PBoolean remoteIsNAT,
01371 OpalConnection & connection
01372 ) = 0;
01373 virtual PBoolean Open() = 0;
01374 };
01375
01376
01377 #endif // __OPAL_CONNECTION_H
01378
01379
01380