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
00172 virtual PBoolean HasCall(
00173 const PString & token
00174 ) { return activeCalls.FindWithLock(token, PSafeReference) != NULL; }
00175
00178 PINDEX GetCallCount() const { return activeCalls.GetSize(); }
00179
00182 PArray<PString> GetAllCalls() const { return activeCalls.GetKeys(); }
00183
00192 PSafePtr<OpalCall> FindCallWithLock(
00193 const PString & token,
00194 PSafetyMode mode = PSafeReadWrite
00195 ) { return activeCalls.FindWithLock(token, mode); }
00196
00205 virtual void OnEstablishedCall(
00206 OpalCall & call
00207 );
00208
00215 virtual PBoolean IsCallEstablished(
00216 const PString & token
00217 );
00218
00226 virtual PBoolean ClearCall(
00227 const PString & token,
00228 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00229 PSyncPoint * sync = NULL
00230 );
00231
00239 virtual PBoolean ClearCallSynchronous(
00240 const PString & token,
00241 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser
00242 );
00243
00249 virtual void ClearAllCalls(
00250 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00251 PBoolean wait = true
00252 );
00253
00267 virtual void OnClearedCall(
00268 OpalCall & call
00269 );
00270
00279 virtual OpalCall * CreateCall(
00280 void * userData
00281 );
00282 OpalCall * InternalCreateCall();
00283
00292 virtual void DestroyCall(
00293 OpalCall * call
00294 );
00295
00300 virtual PString GetNextToken(char prefix);
00302
00311 virtual PSafePtr<OpalPresentity> AddPresentity(
00312 const PString & presentity
00313 );
00314
00317 virtual PSafePtr<OpalPresentity> GetPresentity(
00318 const PString & presentity,
00319 PSafetyMode mode = PSafeReference
00320 );
00321
00324 virtual PStringList GetPresentities() const;
00325
00328 virtual bool RemovePresentity(
00329 const PString & presentity
00330 );
00332
00337 virtual PBoolean Message(
00338 const PString & to,
00339 const PString & body
00340 );
00341 virtual PBoolean Message(
00342 const PURL & to,
00343 const PString & type,
00344 const PString & body,
00345 PURL & from,
00346 PString & conversationId
00347 );
00348 virtual PBoolean Message(
00349 OpalIM & message
00350 );
00351
00354 virtual void OnMessageReceived(
00355 const OpalIM & message
00356 );
00357
00359
00396 virtual PSafePtr<OpalConnection> MakeConnection(
00397 OpalCall & call,
00398 const PString & party,
00399 void * userData = NULL,
00400 unsigned int options = 0,
00401 OpalConnection::StringOptions * stringOptions = NULL
00402 );
00403
00409 virtual void OnNewConnection(
00410 OpalConnection & connection
00411 );
00412
00439 virtual PBoolean OnIncomingConnection(
00440 OpalConnection & connection,
00441 unsigned options,
00442 OpalConnection::StringOptions * stringOptions
00443 );
00444
00451 virtual bool OnRouteConnection(
00452 PStringSet & routesTried,
00453 const PString & a_party,
00454 const PString & b_party,
00455 OpalCall & call,
00456 unsigned options,
00457 OpalConnection::StringOptions * stringOptions
00458 );
00459
00475 virtual void OnProceeding(
00476 OpalConnection & connection
00477 );
00478
00495 virtual void OnAlerting(
00496 OpalConnection & connection
00497 );
00498
00515 virtual OpalConnection::AnswerCallResponse OnAnswerCall(
00516 OpalConnection & connection,
00517 const PString & caller
00518 );
00519
00531 virtual void OnConnected(
00532 OpalConnection & connection
00533 );
00534
00548 virtual void OnEstablished(
00549 OpalConnection & connection
00550 );
00551
00567 virtual void OnReleased(
00568 OpalConnection & connection
00569 );
00570
00577 virtual void OnHold(
00578 OpalConnection & connection,
00579 bool fromRemote,
00580 bool onHold
00581 );
00582 virtual void OnHold(OpalConnection & connection);
00583
00588 virtual PBoolean OnForwarded(
00589 OpalConnection & connection,
00590 const PString & remoteParty
00591 );
00592
00638 virtual bool OnTransferNotify(
00639 OpalConnection & connection,
00640 const PStringToString & info
00641 );
00643
00644
00654 virtual OpalMediaFormatList GetCommonMediaFormats(
00655 bool transportable,
00656 bool pcmAudio
00657 ) const;
00658
00668 virtual void AdjustMediaFormats(
00669 bool local,
00670 const OpalConnection & connection,
00671 OpalMediaFormatList & mediaFormats
00672 ) const;
00673
00676 virtual PBoolean IsMediaBypassPossible(
00677 const OpalConnection & source,
00678 const OpalConnection & destination,
00679 unsigned sessionID
00680 ) const;
00681
00697 virtual PBoolean OnOpenMediaStream(
00698 OpalConnection & connection,
00699 OpalMediaStream & stream
00700 );
00701
00710 virtual RTP_UDP * CreateRTPSession (const RTP_Session::Params & params);
00711
00719 virtual void OnRTPStatistics(
00720 const OpalConnection & connection,
00721 const RTP_Session & session
00722 );
00723
00740 virtual bool OnLocalRTP(
00741 OpalConnection & connection1,
00742 OpalConnection & connection2,
00743 unsigned sessionID,
00744 bool opened
00745 ) const;
00746
00772 bool SetMediaPassThrough(
00773 const PString & token1,
00774 const PString & token2,
00775 bool bypass,
00776 unsigned sessionID = 0,
00777 bool network = true
00778 );
00779 static bool SetMediaPassThrough(
00780 OpalConnection & connection1,
00781 OpalConnection & connection2,
00782 bool bypass,
00783 unsigned sessionID = 0
00784 );
00785
00790 virtual void OnClosedMediaStream(
00791 const OpalMediaStream & stream
00792 );
00793
00794 #if OPAL_VIDEO
00795
00797 virtual PBoolean CreateVideoInputDevice(
00798 const OpalConnection & connection,
00799 const OpalMediaFormat & mediaFormat,
00800 PVideoInputDevice * & device,
00801 PBoolean & autoDelete
00802 );
00803
00807 virtual PBoolean CreateVideoOutputDevice(
00808 const OpalConnection & connection,
00809 const OpalMediaFormat & mediaFormat,
00810 PBoolean preview,
00811 PVideoOutputDevice * & device,
00812 PBoolean & autoDelete
00813 );
00814 #endif
00815
00823 virtual OpalMediaPatch * CreateMediaPatch(
00824 OpalMediaStream & source,
00825 PBoolean requiresPatchThread = true
00826 );
00827
00834 virtual void OnStartMediaPatch(
00835 OpalConnection & connection,
00836 OpalMediaPatch & patch
00837 );
00838
00841 virtual void OnStopMediaPatch(
00842 OpalConnection & connection,
00843 OpalMediaPatch & patch
00844 );
00846
00854 virtual void OnUserInputString(
00855 OpalConnection & connection,
00856 const PString & value
00857 );
00858
00865 virtual void OnUserInputTone(
00866 OpalConnection & connection,
00867 char tone,
00868 int duration
00869 );
00870
00873 virtual PString ReadUserInput(
00874 OpalConnection & connection,
00875 const char * terminators = "#\r\n",
00876 unsigned lastDigitTimeout = 4,
00877 unsigned firstDigitTimeout = 30
00878 );
00880
00883
00884 enum MessageWaitingType {
00885 NoMessageWaiting,
00886 VoiceMessageWaiting,
00887 FaxMessageWaiting,
00888 PagerMessageWaiting,
00889 MultimediaMessageWaiting,
00890 TextMessageWaiting,
00891 NumMessageWaitingTypes
00892 };
00893
00904 virtual void OnMWIReceived(
00905 const PString & party,
00906 MessageWaitingType type,
00907 const PString & extraInfo
00908 );
00909
00910
00911 class RouteEntry : public PObject
00912 {
00913 PCLASSINFO(RouteEntry, PObject);
00914 public:
00915 RouteEntry(const PString & pat, const PString & dest);
00916 void PrintOn(ostream & strm) const;
00917 PString pattern;
00918 PString destination;
00919 PRegularExpression regex;
00920 };
00921 PARRAY(RouteTable, RouteEntry);
00922
01033 virtual PBoolean AddRouteEntry(
01034 const PString & spec
01035 );
01036
01043 PBoolean SetRouteTable(
01044 const PStringArray & specs
01045 );
01046
01051 void SetRouteTable(
01052 const RouteTable & table
01053 );
01054
01057 const RouteTable & GetRouteTable() const { return m_routeTable; }
01058
01066 virtual PString ApplyRouteTable(
01067 const PString & source,
01068 const PString & destination,
01069 PINDEX & entry
01070 );
01072
01073 #if OPAL_HAS_MIXER
01074
01084 virtual PBoolean StartRecording(
01085 const PString & callToken,
01086 const PFilePath & filename,
01087 const OpalRecordManager::Options & options = false
01088 );
01089
01092 virtual bool IsRecording(
01093 const PString & callToken
01094 );
01095
01100 virtual bool StopRecording(
01101 const PString & callToken
01102 );
01103
01105 #endif
01106
01111 const OpalProductInfo & GetProductInfo() const { return productInfo; }
01112
01115 void SetProductInfo(
01116 const OpalProductInfo & info,
01117 bool updateAll = true
01118 );
01119
01122 const PString & GetDefaultUserName() const { return defaultUserName; }
01123
01126 void SetDefaultUserName(
01127 const PString & name,
01128 bool updateAll = true
01129 );
01130
01133 const PString & GetDefaultDisplayName() const { return defaultDisplayName; }
01134
01137 void SetDefaultDisplayName(
01138 const PString & name,
01139 bool updateAll = true
01140 );
01141
01142 #if OPAL_VIDEO
01143
01144
01145
01146
01147
01148
01149
01152 bool CanAutoStartReceiveVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Receive) != 0; }
01153
01156 void SetAutoStartReceiveVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(OpalMediaType::Receive, can); }
01157
01160 bool CanAutoStartTransmitVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Transmit) != 0; }
01161
01164 void SetAutoStartTransmitVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(OpalMediaType::Transmit, can); }
01165
01166 #endif
01167
01174 virtual PBoolean IsLocalAddress(
01175 const PIPSocket::Address & remoteAddress
01176 ) const;
01177
01195 virtual PBoolean IsRTPNATEnabled(
01196 OpalConnection & connection,
01197 const PIPSocket::Address & localAddr,
01198 const PIPSocket::Address & peerAddr,
01199 const PIPSocket::Address & signalAddr,
01200 PBoolean incoming
01201 );
01202
01209 virtual PBoolean TranslateIPAddress(
01210 PIPSocket::Address & localAddress,
01211 const PIPSocket::Address & remoteAddress
01212 );
01213
01216 const PString & GetTranslationHost() const { return translationHost; }
01217
01220 bool SetTranslationHost(
01221 const PString & host
01222 );
01223
01226 const PIPSocket::Address & GetTranslationAddress() const { return translationAddress; }
01227
01230 void SetTranslationAddress(
01231 const PIPSocket::Address & address
01232 );
01233
01239 virtual PNatMethod * GetNatMethod(
01240 const PIPSocket::Address & remoteAddress = PIPSocket::GetDefaultIpAny()
01241 ) const;
01242
01247 PSTUNClient::NatTypes SetSTUNServer(
01248 const PString & server
01249 );
01250
01253 const PString & GetSTUNServer() const { return stunServer; }
01254
01257 PSTUNClient * GetSTUNClient() const { return stun; }
01258
01261 WORD GetTCPPortBase() const { return tcpPorts.base; }
01262
01265 WORD GetTCPPortMax() const { return tcpPorts.max; }
01266
01269 void SetTCPPorts(unsigned tcpBase, unsigned tcpMax);
01270
01273 WORD GetNextTCPPort();
01274
01277 WORD GetUDPPortBase() const { return udpPorts.base; }
01278
01281 WORD GetUDPPortMax() const { return udpPorts.max; }
01282
01285 void SetUDPPorts(unsigned udpBase, unsigned udpMax);
01286
01289 WORD GetNextUDPPort();
01290
01293 WORD GetRtpIpPortBase() const { return rtpIpPorts.base; }
01294
01297 WORD GetRtpIpPortMax() const { return rtpIpPorts.max; }
01298
01301 void SetRtpIpPorts(unsigned udpBase, unsigned udpMax);
01302
01305 WORD GetRtpIpPortPair();
01306
01309 BYTE GetMediaTypeOfService() const { return m_defaultMediaTypeOfService; }
01310
01313 void SetMediaTypeOfService(unsigned tos) { m_defaultMediaTypeOfService = (BYTE)tos; }
01314
01315
01316 BYTE P_DEPRECATED GetRtpIpTypeofService() const { return m_defaultMediaTypeOfService; }
01317 void P_DEPRECATED SetRtpIpTypeofService(unsigned tos) { m_defaultMediaTypeOfService = (BYTE)tos; }
01318
01321 BYTE GetMediaTypeOfService(const OpalMediaType & type) const;
01322
01325 void SetMediaTypeOfService(const OpalMediaType & type, unsigned tos);
01326
01331 PINDEX GetMaxRtpPayloadSize() const { return rtpPayloadSizeMax; }
01332
01337 void SetMaxRtpPayloadSize(
01338 PINDEX size,
01339 bool mtu = false
01340 ) { rtpPayloadSizeMax = size - (mtu ? (20+16+12) : 0); }
01341
01345 PINDEX GetMaxRtpPacketSize() const { return rtpPacketSizeMax; }
01346
01350 void SetMaxRtpPacketSize(
01351 PINDEX size
01352 ) { rtpPacketSizeMax = size; }
01353
01357 unsigned GetMinAudioJitterDelay() const { return minAudioJitterDelay; }
01358
01362 unsigned GetMaxAudioJitterDelay() const { return maxAudioJitterDelay; }
01363
01373 void SetAudioJitterDelay(
01374 unsigned minDelay,
01375 unsigned maxDelay
01376 );
01377
01380 const PStringArray & GetMediaFormatOrder() const { return mediaFormatOrder; }
01381
01384 void SetMediaFormatOrder(
01385 const PStringArray & order
01386 );
01387
01393 const PStringArray & GetMediaFormatMask() const { return mediaFormatMask; }
01394
01400 void SetMediaFormatMask(
01401 const PStringArray & mask
01402 );
01403
01406 virtual void SetSilenceDetectParams(
01407 const OpalSilenceDetector::Params & params
01408 ) { silenceDetectParams = params; }
01409
01412 const OpalSilenceDetector::Params & GetSilenceDetectParams() const { return silenceDetectParams; }
01413
01414 #if OPAL_AEC
01415
01417 virtual void SetEchoCancelParams(
01418 const OpalEchoCanceler::Params & params
01419 ) { echoCancelParams = params; }
01420
01423 const OpalEchoCanceler::Params & GetEchoCancelParams() const { return echoCancelParams; }
01424 #endif
01425
01426 #if OPAL_VIDEO
01427
01435 virtual PBoolean SetVideoInputDevice(
01436 const PVideoDevice::OpenArgs & deviceArgs
01437 );
01438
01442 const PVideoDevice::OpenArgs & GetVideoInputDevice() const { return videoInputDevice; }
01443
01451 virtual PBoolean SetVideoPreviewDevice(
01452 const PVideoDevice::OpenArgs & deviceArgs
01453 );
01454
01458 const PVideoDevice::OpenArgs & GetVideoPreviewDevice() const { return videoPreviewDevice; }
01459
01467 virtual PBoolean SetVideoOutputDevice(
01468 const PVideoDevice::OpenArgs & deviceArgs
01469 );
01470
01474 const PVideoDevice::OpenArgs & GetVideoOutputDevice() const { return videoOutputDevice; }
01475
01476 #endif
01477
01478 PBoolean DetectInBandDTMFDisabled() const
01479 { return disableDetectInBandDTMF; }
01480
01483 void DisableDetectInBandDTMF(
01484 PBoolean mode
01485 ) { disableDetectInBandDTMF = mode; }
01486
01489 const PTimeInterval & GetNoMediaTimeout() const { return noMediaTimeout; }
01490
01493 PBoolean SetNoMediaTimeout(
01494 const PTimeInterval & newInterval
01495 );
01496
01499 const PString & GetDefaultILSServer() const { return ilsServer; }
01500
01503 void SetDefaultILSServer(
01504 const PString & server
01505 ) { ilsServer = server; }
01507
01508
01509 void GarbageCollection();
01510
01511 #ifdef OPAL_ZRTP
01512 virtual bool GetZRTPEnabled() const;
01513 #endif
01514
01515 virtual void OnApplyStringOptions(
01516 OpalConnection & conn,
01517 OpalConnection::StringOptions & stringOptions
01518 );
01519
01520 protected:
01521
01522 OpalProductInfo productInfo;
01523
01524 PString defaultUserName;
01525 PString defaultDisplayName;
01526
01527 BYTE m_defaultMediaTypeOfService;
01528 map<OpalMediaType, BYTE> m_mediaTypeOfService;
01529
01530 PINDEX rtpPayloadSizeMax;
01531 PINDEX rtpPacketSizeMax;
01532 unsigned minAudioJitterDelay;
01533 unsigned maxAudioJitterDelay;
01534 PStringArray mediaFormatOrder;
01535 PStringArray mediaFormatMask;
01536 PBoolean disableDetectInBandDTMF;
01537 PTimeInterval noMediaTimeout;
01538 PString ilsServer;
01539
01540 OpalSilenceDetector::Params silenceDetectParams;
01541 #if OPAL_AEC
01542 OpalEchoCanceler::Params echoCancelParams;
01543 #endif
01544
01545 #if OPAL_VIDEO
01546 PVideoDevice::OpenArgs videoInputDevice;
01547 PVideoDevice::OpenArgs videoPreviewDevice;
01548 PVideoDevice::OpenArgs videoOutputDevice;
01549 #endif
01550
01551 struct PortInfo {
01552 void Set(
01553 unsigned base,
01554 unsigned max,
01555 unsigned range,
01556 unsigned dflt
01557 );
01558 WORD GetNext(
01559 unsigned increment
01560 );
01561
01562 PMutex mutex;
01563 WORD base;
01564 WORD max;
01565 WORD current;
01566 } tcpPorts, udpPorts, rtpIpPorts;
01567
01568 class InterfaceMonitor : public PInterfaceMonitorClient
01569 {
01570 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
01571
01572 enum {
01573 OpalManagerInterfaceMonitorClientPriority = 100,
01574 };
01575 public:
01576 InterfaceMonitor(OpalManager & manager);
01577
01578 protected:
01579 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
01580 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
01581
01582 OpalManager & m_manager;
01583 };
01584
01585 PString translationHost;
01586 PIPSocket::Address translationAddress;
01587 PString stunServer;
01588 PSTUNClient * stun;
01589 InterfaceMonitor * interfaceMonitor;
01590
01591 RouteTable m_routeTable;
01592 PMutex m_routeMutex;
01593
01594
01595 PReadWriteMutex endpointsMutex;
01596 PList<OpalEndPoint> endpointList;
01597 std::map<PString, OpalEndPoint *> endpointMap;
01598
01599 PAtomicInteger lastCallTokenID;
01600
01601 class CallDict : public PSafeDictionary<PString, OpalCall>
01602 {
01603 public:
01604 CallDict(OpalManager & mgr) : manager(mgr) { }
01605 virtual void DeleteObject(PObject * object) const;
01606 OpalManager & manager;
01607 } activeCalls;
01608
01609 PSafeDictionary<PString, OpalPresentity> m_presentities;
01610
01611 PAtomicInteger m_clearingAllCallsCount;
01612 PMutex m_clearingAllCallsMutex;
01613 PSyncPoint m_allCallsCleared;
01614 void InternalClearAllCalls(OpalConnection::CallEndReason reason, bool wait, bool first);
01615
01616 PThread * garbageCollector;
01617 PSyncPoint garbageCollectExit;
01618 bool garbageCollectSkip;
01619 PDECLARE_NOTIFIER(PThread, OpalManager, GarbageMain);
01620
01621 #ifdef OPAL_ZRTP
01622 bool zrtpEnabled;
01623 #endif
01624
01625 friend OpalCall::OpalCall(OpalManager & mgr);
01626 friend void OpalCall::InternalOnClear();
01627
01628 private:
01629 P_REMOVE_VIRTUAL(OpalCall *,CreateCall(), 0);
01630 P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &, unsigned), false);
01631 P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &), false);
01632 P_REMOVE_VIRTUAL(PBoolean, OnStartMediaPatch(const OpalMediaPatch &), false);
01633 P_REMOVE_VIRTUAL_VOID(AdjustMediaFormats(const OpalConnection &, OpalMediaFormatList &) const);
01634 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const PURL&,const PString&,const PURL&,const PString&,const PString&,const PString&));
01635
01636
01637 #ifdef OPAL_HAS_IM
01638 public:
01639 OpalIMManager & GetIMManager() { return *m_imManager; }
01640
01641 protected:
01642 OpalIMManager * m_imManager;
01643 #endif
01644 };
01645
01646
01647 PString OpalGetVersion();
01648 unsigned OpalGetMajorVersion();
01649 unsigned OpalGetMinorVersion();
01650 unsigned OpalGetBuildNumber();
01651
01652
01653 #endif // OPAL_OPAL_MANAGER_H
01654
01655
01656