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_OPAL_CONNECTION_H
00036 #define OPAL_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 #include <im/t140.h>
00052
00053 class OpalEndPoint;
00054 class OpalCall;
00055 class OpalSilenceDetector;
00056 class OpalEchoCanceler;
00057 class OpalRFC2833Proto;
00058 class OpalRFC2833Info;
00059
00271 class OpalProductInfo
00272 {
00273 public:
00274 OpalProductInfo();
00275
00276 static OpalProductInfo & Default();
00277
00278 PCaselessString AsString() const;
00279
00280 PString vendor;
00281 PString name;
00282 PString version;
00283 PString comments;
00284 BYTE t35CountryCode;
00285 BYTE t35Extension;
00286 WORD manufacturerCode;
00287 };
00288
00289
00307 class OpalConnection : public PSafeObject
00308 {
00309 PCLASSINFO(OpalConnection, PSafeObject);
00310 public:
00315 enum CallEndReason {
00316 EndedByLocalUser,
00317 EndedByNoAccept,
00318 EndedByAnswerDenied,
00319 EndedByRemoteUser,
00320 EndedByRefusal,
00321 EndedByNoAnswer,
00322 EndedByCallerAbort,
00323 EndedByTransportFail,
00324 EndedByConnectFail,
00325 EndedByGatekeeper,
00326 EndedByNoUser,
00327 EndedByNoBandwidth,
00328 EndedByCapabilityExchange,
00329 EndedByCallForwarded,
00330 EndedBySecurityDenial,
00331 EndedByLocalBusy,
00332 EndedByLocalCongestion,
00333 EndedByRemoteBusy,
00334 EndedByRemoteCongestion,
00335 EndedByUnreachable,
00336 EndedByNoEndPoint,
00337 EndedByHostOffline,
00338 EndedByTemporaryFailure,
00339 EndedByQ931Cause,
00340 EndedByDurationLimit,
00341 EndedByInvalidConferenceID,
00342 EndedByNoDialTone,
00343 EndedByNoRingBackTone,
00344 EndedByOutOfService,
00345 EndedByAcceptingCallWaiting,
00346 NumCallEndReasons,
00347
00348 EndedWithQ931Code = 0x100
00349 };
00350
00351 #if PTRACING
00352 friend ostream & operator<<(ostream & o, CallEndReason reason);
00353 #endif
00354
00355 enum AnswerCallResponse {
00356 AnswerCallNow,
00357 AnswerCallDenied,
00358 AnswerCallPending,
00359 AnswerCallDeferred,
00360 AnswerCallAlertWithMedia,
00361 AnswerCallDeferredWithMedia,
00362 AnswerCallProgress,
00363 AnswerCallNowAndReleaseCurrent,
00364 NumAnswerCallResponses
00365 };
00366 #if PTRACING
00367 friend ostream & operator<<(ostream & o, AnswerCallResponse s);
00368 #endif
00369
00372 enum Options {
00373 FastStartOptionDisable = 0x0001,
00374 FastStartOptionEnable = 0x0002,
00375 FastStartOptionMask = 0x0003,
00376
00377 H245TunnelingOptionDisable = 0x0004,
00378 H245TunnelingOptionEnable = 0x0008,
00379 H245TunnelingOptionMask = 0x000c,
00380
00381 H245inSetupOptionDisable = 0x0010,
00382 H245inSetupOptionEnable = 0x0020,
00383 H245inSetupOptionMask = 0x0030,
00384
00385 DetectInBandDTMFOptionDisable = 0x0040,
00386 DetectInBandDTMFOptionEnable = 0x0080,
00387 DetectInBandDTMFOptionMask = 0x00c0,
00388
00389 RTPAggregationDisable = 0x0100,
00390 RTPAggregationEnable = 0x0200,
00391 RTPAggregationMask = 0x0300,
00392
00393 SendDTMFAsDefault = 0x0000,
00394 SendDTMFAsString = 0x0400,
00395 SendDTMFAsTone = 0x0800,
00396 SendDTMFAsRFC2833 = 0x0c00,
00397 SendDTMFMask = 0x0c00
00398 };
00399
00400 class StringOptions : public PStringToString
00401 {
00402 };
00403
00408 OpalConnection(
00409 OpalCall & call,
00410 OpalEndPoint & endpoint,
00411 const PString & token,
00412 unsigned options = 0,
00413 OpalConnection::StringOptions * stringOptions = NULL
00414 );
00415
00418 ~OpalConnection();
00420
00427 void PrintOn(
00428 ostream & strm
00429 ) const;
00431
00448 virtual bool IsNetworkConnection() const = 0;
00449
00453 enum Phases {
00454 UninitialisedPhase,
00455 SetUpPhase,
00456 ProceedingPhase,
00457 AlertingPhase,
00458 ConnectedPhase,
00459 EstablishedPhase,
00460 ReleasingPhase,
00461 ReleasedPhase,
00462 NumPhases
00463 };
00464
00469 inline Phases GetPhase() const { return phase; }
00470
00479 CallEndReason GetCallEndReason() const { return callEndReason; }
00480
00485 virtual void SetCallEndReason(
00486 CallEndReason reason
00487 );
00488
00496 void ClearCall(
00497 CallEndReason reason = EndedByLocalUser
00498 );
00499
00502 virtual void ClearCallSynchronous(
00503 PSyncPoint * sync,
00504 CallEndReason reason = EndedByLocalUser
00505 );
00506
00510 unsigned GetQ931Cause() const { return q931Cause; }
00511
00515 void SetQ931Cause(unsigned v) { q931Cause = v; }
00516
00523 virtual bool TransferConnection(
00524 const PString & remoteParty
00525 );
00526
00529 virtual bool HoldConnection();
00530
00534 virtual bool RetrieveConnection();
00535
00538 virtual PBoolean IsConnectionOnHold();
00539
00544 virtual void OnHold(
00545 bool fromRemote,
00546 bool onHold
00547 );
00549
00577 virtual PBoolean OnIncomingConnection(unsigned int options, OpalConnection::StringOptions * stringOptions);
00578 virtual PBoolean OnIncomingConnection(unsigned int options);
00579 virtual PBoolean OnIncomingConnection();
00580
00587 virtual PBoolean SetUpConnection() = 0;
00588
00592 virtual PBoolean OnSetUpConnection();
00593
00594
00609 virtual void OnProceeding();
00610
00621 virtual void OnAlerting();
00622
00633 virtual PBoolean SetAlerting(
00634 const PString & calleeName,
00635 PBoolean withMedia
00636 ) = 0;
00637
00654 virtual AnswerCallResponse OnAnswerCall(
00655 const PString & callerName
00656 );
00657
00668 virtual void AnsweringCall(
00669 AnswerCallResponse response
00670 );
00671
00686 virtual void OnConnected();
00687
00698 virtual PBoolean SetConnected();
00699
00711 virtual void OnEstablished();
00712
00721 virtual void Release(
00722 CallEndReason reason = EndedByLocalUser
00723 );
00724
00742 virtual void OnReleased();
00744
00755 virtual PString GetDestinationAddress();
00756
00766 virtual PBoolean ForwardCall(
00767 const PString & forwardParty
00768 );
00769
00772 PSafePtr<OpalConnection> GetOtherPartyConnection() const;
00773
00776 template <class cls> PSafePtr<cls> GetOtherPartyConnectionAs() const { return PSafePtrCast<OpalConnection, cls>(GetOtherPartyConnection()); }
00778
00787 virtual OpalMediaFormatList GetMediaFormats() const;
00788
00793 virtual OpalMediaFormatList GetLocalMediaFormats();
00794
00803 virtual void AdjustMediaFormats(
00804 OpalMediaFormatList & mediaFormats
00805 ) const;
00806
00809 virtual OpalMediaStreamPtr OpenMediaStream(
00810 const OpalMediaFormat & mediaFormat,
00811 unsigned sessionID,
00812 bool isSource
00813 );
00814
00819 virtual bool CloseMediaStream(
00820 unsigned sessionId,
00821 bool source
00822 );
00823
00828 virtual bool CloseMediaStream(
00829 OpalMediaStream & stream
00830 );
00831
00839 bool RemoveMediaStream(
00840 OpalMediaStream & strm
00841 );
00842
00845 virtual void StartMediaStreams();
00846
00849 virtual void CloseMediaStreams();
00850
00853 virtual void PauseMediaStreams(PBoolean paused);
00854
00867 virtual OpalMediaStream * CreateMediaStream(
00868 const OpalMediaFormat & mediaFormat,
00869 unsigned sessionID,
00870 PBoolean isSource
00871 );
00872
00876 OpalMediaStreamPtr GetMediaStream(
00877 const PString & streamID,
00878 bool source
00879 ) const;
00880
00886 OpalMediaStreamPtr GetMediaStream(
00887 unsigned sessionId,
00888 bool source
00889 ) const;
00890
00896 OpalMediaStreamPtr GetMediaStream(
00897 const OpalMediaType & mediaType,
00898 bool source
00899 ) const;
00900
00912 virtual PBoolean OnOpenMediaStream(
00913 OpalMediaStream & stream
00914 );
00915
00920 virtual void OnClosedMediaStream(
00921 const OpalMediaStream & stream
00922 );
00923
00928 virtual void OnPatchMediaStream(
00929 PBoolean isSource,
00930 OpalMediaPatch & patch
00931 );
00932
00937 virtual void AttachRFC2833HandlerToPatch(PBoolean isSource, OpalMediaPatch & patch);
00938
00944 virtual PBoolean IsMediaBypassPossible(
00945 unsigned sessionID
00946 ) const;
00947
00948 #if OPAL_VIDEO
00949
00954 virtual void AddVideoMediaFormats(
00955 OpalMediaFormatList & mediaFormats
00956 ) const;
00957
00960 virtual PBoolean CreateVideoInputDevice(
00961 const OpalMediaFormat & mediaFormat,
00962 PVideoInputDevice * & device,
00963 PBoolean & autoDelete
00964 );
00965
00969 virtual PBoolean CreateVideoOutputDevice(
00970 const OpalMediaFormat & mediaFormat,
00971 PBoolean preview,
00972 PVideoOutputDevice * & device,
00973 PBoolean & autoDelete
00974 );
00975 #endif
00976
00979 virtual PBoolean SetAudioVolume(
00980 PBoolean source,
00981 unsigned percentage
00982 );
00983
00987 virtual unsigned GetAudioSignalLevel(
00988 PBoolean source
00989 );
00991
00996 unsigned GetBandwidthAvailable() const { return bandwidthAvailable; }
00997
01002 virtual PBoolean SetBandwidthAvailable(
01003 unsigned newBandwidth,
01004 PBoolean force = PFalse
01005 );
01006
01011 virtual unsigned GetBandwidthUsed() const;
01012
01021 virtual PBoolean SetBandwidthUsed(
01022 unsigned releasedBandwidth,
01023 unsigned requiredBandwidth
01024 );
01026
01029 enum SendUserInputModes {
01030 SendUserInputAsQ931,
01031 SendUserInputAsString,
01032 SendUserInputAsTone,
01033 SendUserInputAsInlineRFC2833,
01034 SendUserInputAsSeparateRFC2833,
01035 SendUserInputAsProtocolDefault,
01036 NumSendUserInputModes
01037 };
01038 #if PTRACING
01039 friend ostream & operator<<(ostream & o, SendUserInputModes m);
01040 #endif
01041
01044 virtual void SetSendUserInputMode(SendUserInputModes mode);
01045
01048 virtual SendUserInputModes GetSendUserInputMode() const { return sendUserInputMode; }
01049
01055 virtual SendUserInputModes GetRealSendUserInputMode() const { return GetSendUserInputMode(); }
01056
01063 virtual PBoolean SendUserInputString(
01064 const PString & value
01065 );
01066
01083 virtual PBoolean SendUserInputTone(
01084 char tone,
01085 unsigned duration = 0
01086 );
01087
01094 virtual void OnUserInputString(
01095 const PString & value
01096 );
01097
01104 virtual void OnUserInputTone(
01105 char tone,
01106 unsigned duration
01107 );
01108
01112 void SendUserInputHookFlash(
01113 unsigned duration = 500
01114 ) { SendUserInputTone('!', duration); }
01115
01118 virtual PString GetUserInput(
01119 unsigned timeout = 30
01120 );
01121
01126 virtual void SetUserInput(
01127 const PString & input
01128 );
01129
01132 virtual PString ReadUserInput(
01133 const char * terminators = "#\r\n",
01134 unsigned lastDigitTimeout = 4,
01135 unsigned firstDigitTimeout = 30
01136 );
01137
01144 virtual PBoolean PromptUserInput(
01145 PBoolean play
01146 );
01148
01153 virtual bool GarbageCollection();
01155
01160 OpalEndPoint & GetEndPoint() const { return endpoint; }
01161
01164 OpalCall & GetCall() const { return ownerCall; }
01165
01168 const PString & GetToken() const { return callToken; }
01169
01172 PBoolean IsOriginating() const { return originating; }
01173
01176 PTime GetSetupUpTime() const { return setupTime; }
01177
01180 PTime GetAlertingTime() const { return alertingTime; }
01181
01184 PTime GetConnectionStartTime() const { return connectedTime; }
01185
01188 PTime GetConnectionEndTime() const { return callEndTime; }
01189
01192 const OpalProductInfo & GetProductInfo() const { return productInfo; }
01193
01196 void SetProductInfo(
01197 const OpalProductInfo & info
01198 ) { productInfo = info; }
01199
01202 virtual PString GetPrefixName() const;
01203
01206 const PString & GetLocalPartyName() const { return localPartyName; }
01207
01210 virtual void SetLocalPartyName(const PString & name);
01211
01214 virtual PString GetLocalPartyURL() const;
01215
01218 const PString & GetDisplayName() const { return displayName; }
01219
01222 void SetDisplayName(const PString & name) { displayName = name; }
01223
01226 const PString & GetRemotePartyName() const { return remotePartyName; }
01227
01230 void SetRemotePartyName(const PString & name) { remotePartyName = name; }
01231
01240 const PString & GetRemotePartyNumber() const { return remotePartyNumber; }
01241
01247 const PString & GetRemotePartyAddress() const { return remotePartyAddress; }
01248
01251 void SetRemotePartyAddress(const PString & addr) { remotePartyAddress = addr; }
01252
01259 virtual PString GetRemotePartyURL() const;
01260
01261
01262 const PString GetRemotePartyCallbackURL() const { return GetRemotePartyURL(); }
01263
01267 PCaselessString GetRemoteApplication() const { return remoteProductInfo.AsString(); }
01268
01271 const OpalProductInfo & GetRemoteProductInfo() const { return remoteProductInfo; }
01272
01273
01280 const PString & GetCalledPartyName() const { return m_calledPartyName; }
01281
01288 const PString & GetCalledPartyNumber() const { return m_calledPartyNumber; }
01289
01297 virtual PString GetCalledPartyURL();
01298
01299
01300
01301
01302
01303
01304 void CopyPartyNames(const OpalConnection & other);
01305
01306
01320 virtual PString GetAlertingType() const;
01321
01335 virtual bool SetAlertingType(const PString & info);
01336
01337
01341 unsigned GetMinAudioJitterDelay() const { return minAudioJitterDelay; }
01342
01346 unsigned GetMaxAudioJitterDelay() const { return maxAudioJitterDelay; }
01347
01350 void SetAudioJitterDelay(
01351 unsigned minDelay,
01352 unsigned maxDelay
01353 );
01354
01357 OpalSilenceDetector * GetSilenceDetector() const { return silenceDetector; }
01358
01361 OpalEchoCanceler * GetEchoCanceler() const { return echoCanceler; }
01362
01366 virtual PString GetIdentifier() const;
01367
01376 virtual PINDEX GetMaxRtpPayloadSize() const;
01377
01378 virtual OpalTransport & GetTransport() const
01379 { return *(OpalTransport *)NULL; }
01380
01381 PDICTIONARY(MediaAddressesDict, POrdinalKey, OpalTransportAddress);
01382 MediaAddressesDict & GetMediaTransportAddresses()
01383 { return mediaTransportAddresses; }
01384
01385 #if OPAL_STATISTICS
01386
01388 unsigned GetVideoUpdateRequestsSent() const { return m_VideoUpdateRequestsSent; }
01389 #endif
01390
01391
01393 const StringOptions & GetStringOptions() const { return m_connStringOptions; }
01394
01396 void SetStringOptions(
01397 const StringOptions & options,
01398 bool overwrite
01399 );
01400
01401 virtual void ApplyStringOptions(OpalConnection::StringOptions & stringOptions);
01402 virtual void OnApplyStringOptions();
01403
01404 virtual void PreviewPeerMediaFormats(const OpalMediaFormatList & fmts);
01405
01406 virtual void EnableRecording();
01407 virtual void DisableRecording();
01408
01409 virtual void OnMediaPatchStart(
01410 unsigned sessionId,
01411 bool isSource
01412 );
01413 virtual void OnMediaPatchStop(
01414 unsigned sessionId,
01415 bool isSource
01416 );
01417
01421 PDECLARE_NOTIFIER(OpalMediaCommand, OpalConnection, OnMediaCommand);
01422
01429 virtual OpalMediaType::AutoStartMode GetAutoStart(
01430 const OpalMediaType & mediaType
01431 ) const;
01432
01433 #if OPAL_HAS_IM
01434 struct IMInfo : public PObject {
01435 unsigned sessionId;
01436 OpalMediaFormat mediaFormat;
01437 T140String body;
01438 };
01439
01440 virtual bool SendIM(const OpalMediaFormat & format, const T140String & body);
01441 virtual bool SendIM(const OpalMediaFormat & format, const RTP_DataFrame & body);
01442 virtual void OnReceiveIM(const IMInfo & im);
01443
01444 void AddIMListener(
01445 const PNotifier & listener
01446 );
01447 #endif
01448
01449 protected:
01450 void OnConnectedInternal();
01451
01452 #if OPAL_PTLIB_DTMF
01453 PDECLARE_NOTIFIER(RTP_DataFrame, OpalConnection, OnUserInputInBandDTMF);
01454 #endif
01455 PDECLARE_NOTIFIER(PThread, OpalConnection, OnReleaseThreadMain);
01456 PDECLARE_NOTIFIER(RTP_DataFrame, OpalConnection, OnRecordAudio);
01457
01458
01459 OpalCall & ownerCall;
01460 OpalEndPoint & endpoint;
01461
01462 private:
01463 PMutex phaseMutex;
01464 Phases phase;
01465
01466 protected:
01467 PString callToken;
01468 PBoolean originating;
01469 PTime setupTime;
01470 PTime alertingTime;
01471 PTime connectedTime;
01472 PTime callEndTime;
01473 OpalProductInfo productInfo;
01474 PString localPartyName;
01475 PString displayName;
01476 PString remotePartyName;
01477 OpalProductInfo remoteProductInfo;
01478 PString remotePartyNumber;
01479 PString remotePartyAddress;
01480 CallEndReason callEndReason;
01481 bool synchronousOnRelease;
01482 PString m_calledPartyNumber;
01483 PString m_calledPartyName;
01484
01485 SendUserInputModes sendUserInputMode;
01486 PString userInputString;
01487 PSyncPoint userInputAvailable;
01488 PBoolean detectInBandDTMF;
01489 unsigned dtmfScaleMultiplier;
01490 unsigned dtmfScaleDivisor;
01491 unsigned q931Cause;
01492
01493 OpalSilenceDetector * silenceDetector;
01494 OpalEchoCanceler * echoCanceler;
01495
01496 MediaAddressesDict mediaTransportAddresses;
01497 PSafeList<OpalMediaStream> mediaStreams;
01498
01499 unsigned minAudioJitterDelay;
01500 unsigned maxAudioJitterDelay;
01501 unsigned bandwidthAvailable;
01502
01503
01504
01505 #if OPAL_PTLIB_DTMF
01506 PDTMFDecoder dtmfDecoder;
01507 #endif
01508
01512 void SetPhase(Phases phaseToSet);
01513
01514 #if PTRACING
01515 friend ostream & operator<<(ostream & o, Phases p);
01516 #endif
01517
01518 StringOptions m_connStringOptions;
01519 PString recordAudioFilename;
01520 PNotifier recordNotifier;
01521
01522 #if OPAL_STATISTICS
01523 unsigned m_VideoUpdateRequestsSent;
01524 #endif
01525
01526 struct AutoStartInfo {
01527 unsigned preferredSessionId;
01528 OpalMediaType::AutoStartMode autoStart;
01529 };
01530
01531 class AutoStartMap : public std::map<OpalMediaType, AutoStartInfo>
01532 {
01533 public:
01534 AutoStartMap();
01535 void Initialise(const OpalConnection::StringOptions & stringOptions);
01536 OpalMediaType::AutoStartMode GetAutoStart(const OpalMediaType & mediaType) const;
01537 void SetAutoStart(const OpalMediaType & mediaType, OpalMediaType::AutoStartMode autoStart);
01538
01539 protected:
01540 bool m_initialised;
01541 PMutex m_mutex;
01542
01543 };
01544 AutoStartMap m_autoStartInfo;
01545
01546 #if OPAL_HAS_IM
01547 mutable PList<PNotifier> m_imListeners;
01548 #endif
01549
01550 };
01551
01552 #endif // OPAL_OPAL_CONNECTION_H
01553
01554
01555