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 #ifndef OPAL_OPAL_MANAGER_H
00033 #define OPAL_OPAL_MANAGER_H
00034
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038
00039 #include <opal/buildopts.h>
00040
00041 #include <opal/pres_ent.h>
00042 #include <opal/call.h>
00043 #include <opal/connection.h>
00044 #include <opal/guid.h>
00045 #include <codec/silencedetect.h>
00046 #include <codec/echocancel.h>
00047 #include <ptclib/pstun.h>
00048 #include <ptclib/url.h>
00049
00050 #if OPAL_VIDEO
00051 #include <ptlib/videoio.h>
00052 #endif
00053
00054 class OpalEndPoint;
00055 class OpalMediaPatch;
00056
00057
00074 class OpalManager : public PObject
00075 {
00076 PCLASSINFO(OpalManager, PObject);
00077 public:
00082 OpalManager();
00083
00088 ~OpalManager();
00090
00100 void AttachEndPoint(
00101 OpalEndPoint * endpoint,
00102 const PString & prefix = PString::Empty()
00103 );
00104
00108 void DetachEndPoint(
00109 const PString & prefix
00110 );
00111 void DetachEndPoint(
00112 OpalEndPoint * endpoint
00113 );
00114
00117 OpalEndPoint * FindEndPoint(
00118 const PString & prefix
00119 );
00120
00123 PList<OpalEndPoint> GetEndPoints() const;
00124
00130 void ShutDownEndpoints();
00132
00151 virtual PSafePtr<OpalCall> SetUpCall(
00152 const PString & partyA,
00153 const PString & partyB,
00154 void * userData = NULL,
00155 unsigned options = 0,
00156 OpalConnection::StringOptions * stringOptions = NULL
00157 );
00158 virtual PBoolean SetUpCall(
00159 const PString & partyA,
00160 const PString & partyB,
00161 PString & token,
00162 void * userData = NULL,
00163 unsigned options = 0,
00164 OpalConnection::StringOptions * stringOptions = NULL
00165 );
00166
00175 virtual void OnEstablishedCall(
00176 OpalCall & call
00177 );
00178
00184 virtual PBoolean HasCall(
00185 const PString & token
00186 ) { return activeCalls.FindWithLock(token, PSafeReference) != NULL; }
00187
00190 PINDEX GetCallCount() const { return activeCalls.GetSize(); }
00191
00192
00199 virtual PBoolean IsCallEstablished(
00200 const PString & token
00201 );
00202
00211 PSafePtr<OpalCall> FindCallWithLock(
00212 const PString & token,
00213 PSafetyMode mode = PSafeReadWrite
00214 ) { return activeCalls.FindWithLock(token, mode); }
00215
00223 virtual PBoolean ClearCall(
00224 const PString & token,
00225 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00226 PSyncPoint * sync = NULL
00227 );
00228
00236 virtual PBoolean ClearCallSynchronous(
00237 const PString & token,
00238 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser
00239 );
00240
00246 virtual void ClearAllCalls(
00247 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00248 PBoolean wait = PTrue
00249 );
00250
00264 virtual void OnClearedCall(
00265 OpalCall & call
00266 );
00267
00276 virtual OpalCall * CreateCall(
00277 void * userData
00278 );
00279 OpalCall * InternalCreateCall();
00280
00289 virtual void DestroyCall(
00290 OpalCall * call
00291 );
00292
00297 virtual PString GetNextToken(char prefix);
00299
00305 virtual PSafePtr<OpalPresentity> AddPresentity(
00306 const PString & presentity
00307 );
00308
00311 virtual PSafePtr<OpalPresentity> GetPresentity(
00312 const PString & presentity,
00313 PSafetyMode mode = PSafeReference
00314 );
00315
00318 virtual PStringList GetPresentities() const;
00319
00322 virtual bool RemovePresentity(
00323 const PString & presentity
00324 );
00325
00328 virtual PBoolean Message(
00329 const PString & to,
00330 const PString & body
00331 );
00332 virtual PBoolean Message(
00333 const PURL & to,
00334 const PString & type,
00335 const PString & body,
00336 PURL & from,
00337 PString & conversationId
00338 );
00339
00342 virtual void OnMessageReceived(
00343 const PURL & from,
00344 const PString & fromName,
00345 const PURL & to,
00346 const PString & type,
00347 const PString & body,
00348 const PString & conversationId
00349 );
00350
00351 #if OPAL_HAS_IM
00352
00354 virtual bool TransmitExternalIM(
00355 OpalConnection & conn,
00356 const OpalMediaFormat & format,
00357 RTP_IMFrame & frame
00358 );
00359 #endif
00360
00361
00398 virtual PSafePtr<OpalConnection> MakeConnection(
00399 OpalCall & call,
00400 const PString & party,
00401 void * userData = NULL,
00402 unsigned int options = 0,
00403 OpalConnection::StringOptions * stringOptions = NULL
00404 );
00405
00411 virtual void OnNewConnection(
00412 OpalConnection & connection
00413 );
00414
00441 virtual PBoolean OnIncomingConnection(
00442 OpalConnection & connection,
00443 unsigned options,
00444 OpalConnection::StringOptions * stringOptions
00445 );
00446
00453 virtual bool OnRouteConnection(
00454 PStringSet & routesTried,
00455 const PString & a_party,
00456 const PString & b_party,
00457 OpalCall & call,
00458 unsigned options,
00459 OpalConnection::StringOptions * stringOptions
00460 );
00461
00477 virtual void OnProceeding(
00478 OpalConnection & connection
00479 );
00480
00497 virtual void OnAlerting(
00498 OpalConnection & connection
00499 );
00500
00517 virtual OpalConnection::AnswerCallResponse OnAnswerCall(
00518 OpalConnection & connection,
00519 const PString & caller
00520 );
00521
00533 virtual void OnConnected(
00534 OpalConnection & connection
00535 );
00536
00550 virtual void OnEstablished(
00551 OpalConnection & connection
00552 );
00553
00569 virtual void OnReleased(
00570 OpalConnection & connection
00571 );
00572
00579 virtual void OnHold(
00580 OpalConnection & connection,
00581 bool fromRemote,
00582 bool onHold
00583 );
00584 virtual void OnHold(OpalConnection & connection);
00585
00590 virtual PBoolean OnForwarded(
00591 OpalConnection & connection,
00592 const PString & remoteParty
00593 );
00595
00605 virtual OpalMediaFormatList GetCommonMediaFormats(
00606 bool transportable,
00607 bool pcmAudio
00608 ) const;
00609
00619 virtual void AdjustMediaFormats(
00620 bool local,
00621 const OpalConnection & connection,
00622 OpalMediaFormatList & mediaFormats
00623 ) const;
00624
00627 virtual PBoolean IsMediaBypassPossible(
00628 const OpalConnection & source,
00629 const OpalConnection & destination,
00630 unsigned sessionID
00631 ) const;
00632
00648 virtual PBoolean OnOpenMediaStream(
00649 OpalConnection & connection,
00650 OpalMediaStream & stream
00651 );
00652
00661 virtual RTP_UDP * CreateRTPSession (const RTP_Session::Params & params);
00662
00670 virtual void OnRTPStatistics(
00671 const OpalConnection & connection,
00672 const RTP_Session & session
00673 );
00674
00691 virtual bool OnLocalRTP(
00692 OpalConnection & connection1,
00693 OpalConnection & connection2,
00694 unsigned sessionID,
00695 bool opened
00696 ) const;
00697
00723 bool SetMediaBypass(
00724 const PString & token1,
00725 const PString & token2,
00726 bool bypass,
00727 unsigned sessionID = 0,
00728 bool network = true
00729 );
00730 static bool SetMediaBypass(
00731 OpalConnection & connection1,
00732 OpalConnection & connection2,
00733 bool bypass,
00734 unsigned sessionID = 0
00735 );
00736
00741 virtual void OnClosedMediaStream(
00742 const OpalMediaStream & stream
00743 );
00744
00745 #if OPAL_VIDEO
00746
00748 virtual PBoolean CreateVideoInputDevice(
00749 const OpalConnection & connection,
00750 const OpalMediaFormat & mediaFormat,
00751 PVideoInputDevice * & device,
00752 PBoolean & autoDelete
00753 );
00754
00758 virtual PBoolean CreateVideoOutputDevice(
00759 const OpalConnection & connection,
00760 const OpalMediaFormat & mediaFormat,
00761 PBoolean preview,
00762 PVideoOutputDevice * & device,
00763 PBoolean & autoDelete
00764 );
00765 #endif
00766
00774 virtual OpalMediaPatch * CreateMediaPatch(
00775 OpalMediaStream & source,
00776 PBoolean requiresPatchThread = PTrue
00777 );
00778
00783 virtual void DestroyMediaPatch(
00784 OpalMediaPatch * patch
00785 );
00786
00793 virtual void OnStartMediaPatch(
00794 OpalConnection & connection,
00795 OpalMediaPatch & patch
00796 );
00797
00800 virtual void OnStopMediaPatch(
00801 OpalConnection & connection,
00802 OpalMediaPatch & patch
00803 );
00805
00813 virtual void OnUserInputString(
00814 OpalConnection & connection,
00815 const PString & value
00816 );
00817
00824 virtual void OnUserInputTone(
00825 OpalConnection & connection,
00826 char tone,
00827 int duration
00828 );
00829
00832 virtual PString ReadUserInput(
00833 OpalConnection & connection,
00834 const char * terminators = "#\r\n",
00835 unsigned lastDigitTimeout = 4,
00836 unsigned firstDigitTimeout = 30
00837 );
00839
00842 enum MessageWaitingType {
00843 NoMessageWaiting,
00844 VoiceMessageWaiting,
00845 FaxMessageWaiting,
00846 PagerMessageWaiting,
00847 MultimediaMessageWaiting,
00848 TextMessageWaiting,
00849 NumMessageWaitingTypes
00850 };
00851
00854 virtual void OnMWIReceived(
00855 const PString & party,
00856 MessageWaitingType type,
00857 const PString & extraInfo
00858 );
00859
00860
00861 class RouteEntry : public PObject
00862 {
00863 PCLASSINFO(RouteEntry, PObject);
00864 public:
00865 RouteEntry(const PString & pat, const PString & dest);
00866 void PrintOn(ostream & strm) const;
00867 PString pattern;
00868 PString destination;
00869 PRegularExpression regex;
00870 };
00871 PARRAY(RouteTable, RouteEntry);
00872
00983 virtual PBoolean AddRouteEntry(
00984 const PString & spec
00985 );
00986
00993 PBoolean SetRouteTable(
00994 const PStringArray & specs
00995 );
00996
01001 void SetRouteTable(
01002 const RouteTable & table
01003 );
01004
01007 const RouteTable & GetRouteTable() const { return m_routeTable; }
01008
01016 virtual PString ApplyRouteTable(
01017 const PString & source,
01018 const PString & destination,
01019 PINDEX & entry
01020 );
01022
01023 #if OPAL_HAS_MIXER
01024
01034 virtual PBoolean StartRecording(
01035 const PString & callToken,
01036 const PFilePath & filename,
01037 const OpalRecordManager::Options & options = false
01038 );
01039
01042 virtual bool IsRecording(
01043 const PString & callToken
01044 );
01045
01050 virtual bool StopRecording(
01051 const PString & callToken
01052 );
01053
01055 #endif
01056
01061 const OpalProductInfo & GetProductInfo() const { return productInfo; }
01062
01065 void SetProductInfo(
01066 const OpalProductInfo & info,
01067 bool updateAll = true
01068 );
01069
01072 const PString & GetDefaultUserName() const { return defaultUserName; }
01073
01076 void SetDefaultUserName(
01077 const PString & name,
01078 bool updateAll = true
01079 );
01080
01083 const PString & GetDefaultDisplayName() const { return defaultDisplayName; }
01084
01087 void SetDefaultDisplayName(
01088 const PString & name,
01089 bool updateAll = true
01090 );
01091
01092 #if OPAL_VIDEO
01093
01094
01095
01096
01097
01098
01099
01102 bool CanAutoStartReceiveVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Receive) != 0; }
01103
01106 void SetAutoStartReceiveVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(OpalMediaType::Receive, can); }
01107
01110 bool CanAutoStartTransmitVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Transmit) != 0; }
01111
01114 void SetAutoStartTransmitVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(OpalMediaType::Transmit, can); }
01115
01116 #endif
01117
01124 virtual PBoolean IsLocalAddress(
01125 const PIPSocket::Address & remoteAddress
01126 ) const;
01127
01145 virtual PBoolean IsRTPNATEnabled(
01146 OpalConnection & connection,
01147 const PIPSocket::Address & localAddr,
01148 const PIPSocket::Address & peerAddr,
01149 const PIPSocket::Address & signalAddr,
01150 PBoolean incoming
01151 );
01152
01159 virtual PBoolean TranslateIPAddress(
01160 PIPSocket::Address & localAddress,
01161 const PIPSocket::Address & remoteAddress
01162 );
01163
01166 const PString & GetTranslationHost() const { return translationHost; }
01167
01170 bool SetTranslationHost(
01171 const PString & host
01172 );
01173
01176 const PIPSocket::Address & GetTranslationAddress() const { return translationAddress; }
01177
01180 void SetTranslationAddress(
01181 const PIPSocket::Address & address
01182 );
01183
01189 virtual PNatMethod * GetNatMethod(
01190 const PIPSocket::Address & remoteAddress = PIPSocket::GetDefaultIpAny()
01191 ) const;
01192
01197 PSTUNClient::NatTypes SetSTUNServer(
01198 const PString & server
01199 );
01200
01203 const PString & GetSTUNServer() const { return stunServer; }
01204
01207 PSTUNClient * GetSTUNClient() const { return stun; }
01208
01211 WORD GetTCPPortBase() const { return tcpPorts.base; }
01212
01215 WORD GetTCPPortMax() const { return tcpPorts.max; }
01216
01219 void SetTCPPorts(unsigned tcpBase, unsigned tcpMax);
01220
01223 WORD GetNextTCPPort();
01224
01227 WORD GetUDPPortBase() const { return udpPorts.base; }
01228
01231 WORD GetUDPPortMax() const { return udpPorts.max; }
01232
01235 void SetUDPPorts(unsigned udpBase, unsigned udpMax);
01236
01239 WORD GetNextUDPPort();
01240
01243 WORD GetRtpIpPortBase() const { return rtpIpPorts.base; }
01244
01247 WORD GetRtpIpPortMax() const { return rtpIpPorts.max; }
01248
01251 void SetRtpIpPorts(unsigned udpBase, unsigned udpMax);
01252
01255 WORD GetRtpIpPortPair();
01256
01259 BYTE GetRtpIpTypeofService() const { return rtpIpTypeofService; }
01260
01263 void SetRtpIpTypeofService(unsigned tos) { rtpIpTypeofService = (BYTE)tos; }
01264
01269 PINDEX GetMaxRtpPayloadSize() const { return rtpPayloadSizeMax; }
01270
01275 void SetMaxRtpPayloadSize(
01276 PINDEX size,
01277 bool mtu = false
01278 ) { rtpPayloadSizeMax = size - (mtu ? (20+16+12) : 0); }
01279
01283 PINDEX GetMaxRtpPacketSize() const { return rtpPacketSizeMax; }
01284
01288 void SetMaxRtpPacketSize(
01289 PINDEX size
01290 ) { rtpPacketSizeMax = size; }
01291
01295 unsigned GetMinAudioJitterDelay() const { return minAudioJitterDelay; }
01296
01300 unsigned GetMaxAudioJitterDelay() const { return maxAudioJitterDelay; }
01301
01311 void SetAudioJitterDelay(
01312 unsigned minDelay,
01313 unsigned maxDelay
01314 );
01315
01318 const PStringArray & GetMediaFormatOrder() const { return mediaFormatOrder; }
01319
01322 void SetMediaFormatOrder(
01323 const PStringArray & order
01324 );
01325
01331 const PStringArray & GetMediaFormatMask() const { return mediaFormatMask; }
01332
01338 void SetMediaFormatMask(
01339 const PStringArray & mask
01340 );
01341
01344 virtual void SetSilenceDetectParams(
01345 const OpalSilenceDetector::Params & params
01346 ) { silenceDetectParams = params; }
01347
01350 const OpalSilenceDetector::Params & GetSilenceDetectParams() const { return silenceDetectParams; }
01351
01352 #if OPAL_AEC
01353
01355 virtual void SetEchoCancelParams(
01356 const OpalEchoCanceler::Params & params
01357 ) { echoCancelParams = params; }
01358
01361 const OpalEchoCanceler::Params & GetEchoCancelParams() const { return echoCancelParams; }
01362 #endif
01363
01364 #if OPAL_VIDEO
01365
01373 virtual PBoolean SetVideoInputDevice(
01374 const PVideoDevice::OpenArgs & deviceArgs
01375 );
01376
01380 const PVideoDevice::OpenArgs & GetVideoInputDevice() const { return videoInputDevice; }
01381
01389 virtual PBoolean SetVideoPreviewDevice(
01390 const PVideoDevice::OpenArgs & deviceArgs
01391 );
01392
01396 const PVideoDevice::OpenArgs & GetVideoPreviewDevice() const { return videoPreviewDevice; }
01397
01405 virtual PBoolean SetVideoOutputDevice(
01406 const PVideoDevice::OpenArgs & deviceArgs
01407 );
01408
01412 const PVideoDevice::OpenArgs & GetVideoOutputDevice() const { return videoOutputDevice; }
01413
01414 #endif
01415
01416 PBoolean DetectInBandDTMFDisabled() const
01417 { return disableDetectInBandDTMF; }
01418
01421 void DisableDetectInBandDTMF(
01422 PBoolean mode
01423 ) { disableDetectInBandDTMF = mode; }
01424
01427 const PTimeInterval & GetNoMediaTimeout() const { return noMediaTimeout; }
01428
01431 PBoolean SetNoMediaTimeout(
01432 const PTimeInterval & newInterval
01433 );
01434
01437 const PString & GetDefaultILSServer() const { return ilsServer; }
01438
01441 void SetDefaultILSServer(
01442 const PString & server
01443 ) { ilsServer = server; }
01445
01446
01447 void GarbageCollection();
01448
01449 #ifdef OPAL_ZRTP
01450 virtual bool GetZRTPEnabled() const;
01451 #endif
01452
01453 virtual void OnApplyStringOptions(
01454 OpalConnection & conn,
01455 OpalConnection::StringOptions & stringOptions
01456 );
01457
01458 protected:
01459
01460 OpalProductInfo productInfo;
01461
01462 PString defaultUserName;
01463 PString defaultDisplayName;
01464
01465 BYTE rtpIpTypeofService;
01466 PINDEX rtpPayloadSizeMax;
01467 PINDEX rtpPacketSizeMax;
01468 unsigned minAudioJitterDelay;
01469 unsigned maxAudioJitterDelay;
01470 PStringArray mediaFormatOrder;
01471 PStringArray mediaFormatMask;
01472 PBoolean disableDetectInBandDTMF;
01473 PTimeInterval noMediaTimeout;
01474 PString ilsServer;
01475
01476 OpalSilenceDetector::Params silenceDetectParams;
01477 #if OPAL_AEC
01478 OpalEchoCanceler::Params echoCancelParams;
01479 #endif
01480
01481 #if OPAL_VIDEO
01482 PVideoDevice::OpenArgs videoInputDevice;
01483 PVideoDevice::OpenArgs videoPreviewDevice;
01484 PVideoDevice::OpenArgs videoOutputDevice;
01485 #endif
01486
01487 struct PortInfo {
01488 void Set(
01489 unsigned base,
01490 unsigned max,
01491 unsigned range,
01492 unsigned dflt
01493 );
01494 WORD GetNext(
01495 unsigned increment
01496 );
01497
01498 PMutex mutex;
01499 WORD base;
01500 WORD max;
01501 WORD current;
01502 } tcpPorts, udpPorts, rtpIpPorts;
01503
01504 class InterfaceMonitor : public PInterfaceMonitorClient
01505 {
01506 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
01507
01508 enum {
01509 OpalManagerInterfaceMonitorClientPriority = 100,
01510 };
01511 public:
01512 InterfaceMonitor(OpalManager & manager);
01513
01514 protected:
01515 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
01516 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
01517
01518 OpalManager & m_manager;
01519 };
01520
01521 PString translationHost;
01522 PIPSocket::Address translationAddress;
01523 PString stunServer;
01524 PSTUNClient * stun;
01525 InterfaceMonitor * interfaceMonitor;
01526
01527 RouteTable m_routeTable;
01528 PMutex m_routeMutex;
01529
01530
01531 PReadWriteMutex endpointsMutex;
01532 PList<OpalEndPoint> endpointList;
01533 std::map<PString, OpalEndPoint *> endpointMap;
01534
01535 PAtomicInteger lastCallTokenID;
01536
01537 class CallDict : public PSafeDictionary<PString, OpalCall>
01538 {
01539 public:
01540 CallDict(OpalManager & mgr) : manager(mgr) { }
01541 virtual void DeleteObject(PObject * object) const;
01542 OpalManager & manager;
01543 } activeCalls;
01544
01545 PSafeDictionary<PString, OpalPresentity> m_presentities;
01546
01547 PAtomicInteger m_clearingAllCallsCount;
01548 PMutex m_clearingAllCallsMutex;
01549 PSyncPoint m_allCallsCleared;
01550 void InternalClearAllCalls(OpalConnection::CallEndReason reason, bool wait, bool first);
01551
01552 PThread * garbageCollector;
01553 PSyncPoint garbageCollectExit;
01554 PDECLARE_NOTIFIER(PThread, OpalManager, GarbageMain);
01555
01556 #ifdef OPAL_ZRTP
01557 bool zrtpEnabled;
01558 #endif
01559
01560 friend OpalCall::OpalCall(OpalManager & mgr);
01561 friend void OpalCall::InternalOnClear();
01562
01563 private:
01564 P_REMOVE_VIRTUAL(OpalCall *,CreateCall(), 0);
01565 P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &, unsigned), false);
01566 P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &), false);
01567 P_REMOVE_VIRTUAL(PBoolean, OnStartMediaPatch(const OpalMediaPatch &), false);
01568 P_REMOVE_VIRTUAL_VOID(AdjustMediaFormats(const OpalConnection &, OpalMediaFormatList &) const);
01569 };
01570
01571
01572 PString OpalGetVersion();
01573 unsigned OpalGetMajorVersion();
01574 unsigned OpalGetMinorVersion();
01575 unsigned OpalGetBuildNumber();
01576
01577
01578 #endif // OPAL_OPAL_MANAGER_H
01579
01580
01581