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 = true
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 virtual PBoolean Message(
00340 OpalIM & message
00341 );
00342
00345 virtual void OnMessageReceived(
00346 const OpalIM & message
00347 );
00349
00386 virtual PSafePtr<OpalConnection> MakeConnection(
00387 OpalCall & call,
00388 const PString & party,
00389 void * userData = NULL,
00390 unsigned int options = 0,
00391 OpalConnection::StringOptions * stringOptions = NULL
00392 );
00393
00399 virtual void OnNewConnection(
00400 OpalConnection & connection
00401 );
00402
00429 virtual PBoolean OnIncomingConnection(
00430 OpalConnection & connection,
00431 unsigned options,
00432 OpalConnection::StringOptions * stringOptions
00433 );
00434
00441 virtual bool OnRouteConnection(
00442 PStringSet & routesTried,
00443 const PString & a_party,
00444 const PString & b_party,
00445 OpalCall & call,
00446 unsigned options,
00447 OpalConnection::StringOptions * stringOptions
00448 );
00449
00465 virtual void OnProceeding(
00466 OpalConnection & connection
00467 );
00468
00485 virtual void OnAlerting(
00486 OpalConnection & connection
00487 );
00488
00505 virtual OpalConnection::AnswerCallResponse OnAnswerCall(
00506 OpalConnection & connection,
00507 const PString & caller
00508 );
00509
00521 virtual void OnConnected(
00522 OpalConnection & connection
00523 );
00524
00538 virtual void OnEstablished(
00539 OpalConnection & connection
00540 );
00541
00557 virtual void OnReleased(
00558 OpalConnection & connection
00559 );
00560
00567 virtual void OnHold(
00568 OpalConnection & connection,
00569 bool fromRemote,
00570 bool onHold
00571 );
00572 virtual void OnHold(OpalConnection & connection);
00573
00578 virtual PBoolean OnForwarded(
00579 OpalConnection & connection,
00580 const PString & remoteParty
00581 );
00582
00601 virtual bool OnTransferNotify(
00602 OpalConnection & connection,
00603 const PStringToString & info
00604 );
00606
00607
00617 virtual OpalMediaFormatList GetCommonMediaFormats(
00618 bool transportable,
00619 bool pcmAudio
00620 ) const;
00621
00631 virtual void AdjustMediaFormats(
00632 bool local,
00633 const OpalConnection & connection,
00634 OpalMediaFormatList & mediaFormats
00635 ) const;
00636
00639 virtual PBoolean IsMediaBypassPossible(
00640 const OpalConnection & source,
00641 const OpalConnection & destination,
00642 unsigned sessionID
00643 ) const;
00644
00660 virtual PBoolean OnOpenMediaStream(
00661 OpalConnection & connection,
00662 OpalMediaStream & stream
00663 );
00664
00673 virtual RTP_UDP * CreateRTPSession (const RTP_Session::Params & params);
00674
00682 virtual void OnRTPStatistics(
00683 const OpalConnection & connection,
00684 const RTP_Session & session
00685 );
00686
00703 virtual bool OnLocalRTP(
00704 OpalConnection & connection1,
00705 OpalConnection & connection2,
00706 unsigned sessionID,
00707 bool opened
00708 ) const;
00709
00735 bool SetMediaPassThrough(
00736 const PString & token1,
00737 const PString & token2,
00738 bool bypass,
00739 unsigned sessionID = 0,
00740 bool network = true
00741 );
00742 static bool SetMediaPassThrough(
00743 OpalConnection & connection1,
00744 OpalConnection & connection2,
00745 bool bypass,
00746 unsigned sessionID = 0
00747 );
00748
00753 virtual void OnClosedMediaStream(
00754 const OpalMediaStream & stream
00755 );
00756
00757 #if OPAL_VIDEO
00758
00760 virtual PBoolean CreateVideoInputDevice(
00761 const OpalConnection & connection,
00762 const OpalMediaFormat & mediaFormat,
00763 PVideoInputDevice * & device,
00764 PBoolean & autoDelete
00765 );
00766
00770 virtual PBoolean CreateVideoOutputDevice(
00771 const OpalConnection & connection,
00772 const OpalMediaFormat & mediaFormat,
00773 PBoolean preview,
00774 PVideoOutputDevice * & device,
00775 PBoolean & autoDelete
00776 );
00777 #endif
00778
00786 virtual OpalMediaPatch * CreateMediaPatch(
00787 OpalMediaStream & source,
00788 PBoolean requiresPatchThread = true
00789 );
00790
00795 virtual void DestroyMediaPatch(
00796 OpalMediaPatch * patch
00797 );
00798
00805 virtual void OnStartMediaPatch(
00806 OpalConnection & connection,
00807 OpalMediaPatch & patch
00808 );
00809
00812 virtual void OnStopMediaPatch(
00813 OpalConnection & connection,
00814 OpalMediaPatch & patch
00815 );
00817
00825 virtual void OnUserInputString(
00826 OpalConnection & connection,
00827 const PString & value
00828 );
00829
00836 virtual void OnUserInputTone(
00837 OpalConnection & connection,
00838 char tone,
00839 int duration
00840 );
00841
00844 virtual PString ReadUserInput(
00845 OpalConnection & connection,
00846 const char * terminators = "#\r\n",
00847 unsigned lastDigitTimeout = 4,
00848 unsigned firstDigitTimeout = 30
00849 );
00851
00854 enum MessageWaitingType {
00855 NoMessageWaiting,
00856 VoiceMessageWaiting,
00857 FaxMessageWaiting,
00858 PagerMessageWaiting,
00859 MultimediaMessageWaiting,
00860 TextMessageWaiting,
00861 NumMessageWaitingTypes
00862 };
00863
00866 virtual void OnMWIReceived(
00867 const PString & party,
00868 MessageWaitingType type,
00869 const PString & extraInfo
00870 );
00871
00872
00873 class RouteEntry : public PObject
00874 {
00875 PCLASSINFO(RouteEntry, PObject);
00876 public:
00877 RouteEntry(const PString & pat, const PString & dest);
00878 void PrintOn(ostream & strm) const;
00879 PString pattern;
00880 PString destination;
00881 PRegularExpression regex;
00882 };
00883 PARRAY(RouteTable, RouteEntry);
00884
00995 virtual PBoolean AddRouteEntry(
00996 const PString & spec
00997 );
00998
01005 PBoolean SetRouteTable(
01006 const PStringArray & specs
01007 );
01008
01013 void SetRouteTable(
01014 const RouteTable & table
01015 );
01016
01019 const RouteTable & GetRouteTable() const { return m_routeTable; }
01020
01028 virtual PString ApplyRouteTable(
01029 const PString & source,
01030 const PString & destination,
01031 PINDEX & entry
01032 );
01034
01035 #if OPAL_HAS_MIXER
01036
01046 virtual PBoolean StartRecording(
01047 const PString & callToken,
01048 const PFilePath & filename,
01049 const OpalRecordManager::Options & options = false
01050 );
01051
01054 virtual bool IsRecording(
01055 const PString & callToken
01056 );
01057
01062 virtual bool StopRecording(
01063 const PString & callToken
01064 );
01065
01067 #endif
01068
01073 const OpalProductInfo & GetProductInfo() const { return productInfo; }
01074
01077 void SetProductInfo(
01078 const OpalProductInfo & info,
01079 bool updateAll = true
01080 );
01081
01084 const PString & GetDefaultUserName() const { return defaultUserName; }
01085
01088 void SetDefaultUserName(
01089 const PString & name,
01090 bool updateAll = true
01091 );
01092
01095 const PString & GetDefaultDisplayName() const { return defaultDisplayName; }
01096
01099 void SetDefaultDisplayName(
01100 const PString & name,
01101 bool updateAll = true
01102 );
01103
01104 #if OPAL_VIDEO
01105
01106
01107
01108
01109
01110
01111
01114 bool CanAutoStartReceiveVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Receive) != 0; }
01115
01118 void SetAutoStartReceiveVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(OpalMediaType::Receive, can); }
01119
01122 bool CanAutoStartTransmitVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Transmit) != 0; }
01123
01126 void SetAutoStartTransmitVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(OpalMediaType::Transmit, can); }
01127
01128 #endif
01129
01136 virtual PBoolean IsLocalAddress(
01137 const PIPSocket::Address & remoteAddress
01138 ) const;
01139
01157 virtual PBoolean IsRTPNATEnabled(
01158 OpalConnection & connection,
01159 const PIPSocket::Address & localAddr,
01160 const PIPSocket::Address & peerAddr,
01161 const PIPSocket::Address & signalAddr,
01162 PBoolean incoming
01163 );
01164
01171 virtual PBoolean TranslateIPAddress(
01172 PIPSocket::Address & localAddress,
01173 const PIPSocket::Address & remoteAddress
01174 );
01175
01178 const PString & GetTranslationHost() const { return translationHost; }
01179
01182 bool SetTranslationHost(
01183 const PString & host
01184 );
01185
01188 const PIPSocket::Address & GetTranslationAddress() const { return translationAddress; }
01189
01192 void SetTranslationAddress(
01193 const PIPSocket::Address & address
01194 );
01195
01201 virtual PNatMethod * GetNatMethod(
01202 const PIPSocket::Address & remoteAddress = PIPSocket::GetDefaultIpAny()
01203 ) const;
01204
01209 PSTUNClient::NatTypes SetSTUNServer(
01210 const PString & server
01211 );
01212
01215 const PString & GetSTUNServer() const { return stunServer; }
01216
01219 PSTUNClient * GetSTUNClient() const { return stun; }
01220
01223 WORD GetTCPPortBase() const { return tcpPorts.base; }
01224
01227 WORD GetTCPPortMax() const { return tcpPorts.max; }
01228
01231 void SetTCPPorts(unsigned tcpBase, unsigned tcpMax);
01232
01235 WORD GetNextTCPPort();
01236
01239 WORD GetUDPPortBase() const { return udpPorts.base; }
01240
01243 WORD GetUDPPortMax() const { return udpPorts.max; }
01244
01247 void SetUDPPorts(unsigned udpBase, unsigned udpMax);
01248
01251 WORD GetNextUDPPort();
01252
01255 WORD GetRtpIpPortBase() const { return rtpIpPorts.base; }
01256
01259 WORD GetRtpIpPortMax() const { return rtpIpPorts.max; }
01260
01263 void SetRtpIpPorts(unsigned udpBase, unsigned udpMax);
01264
01267 WORD GetRtpIpPortPair();
01268
01271 BYTE GetMediaTypeOfService() const { return m_defaultMediaTypeOfService; }
01272
01275 void SetMediaTypeOfService(unsigned tos) { m_defaultMediaTypeOfService = (BYTE)tos; }
01276
01277
01278 BYTE P_DEPRECATED GetRtpIpTypeofService() const { return m_defaultMediaTypeOfService; }
01279 void P_DEPRECATED SetRtpIpTypeofService(unsigned tos) { m_defaultMediaTypeOfService = (BYTE)tos; }
01280
01283 BYTE GetMediaTypeOfService(const OpalMediaType & type) const;
01284
01287 void SetMediaTypeOfService(const OpalMediaType & type, unsigned tos);
01288
01293 PINDEX GetMaxRtpPayloadSize() const { return rtpPayloadSizeMax; }
01294
01299 void SetMaxRtpPayloadSize(
01300 PINDEX size,
01301 bool mtu = false
01302 ) { rtpPayloadSizeMax = size - (mtu ? (20+16+12) : 0); }
01303
01307 PINDEX GetMaxRtpPacketSize() const { return rtpPacketSizeMax; }
01308
01312 void SetMaxRtpPacketSize(
01313 PINDEX size
01314 ) { rtpPacketSizeMax = size; }
01315
01319 unsigned GetMinAudioJitterDelay() const { return minAudioJitterDelay; }
01320
01324 unsigned GetMaxAudioJitterDelay() const { return maxAudioJitterDelay; }
01325
01335 void SetAudioJitterDelay(
01336 unsigned minDelay,
01337 unsigned maxDelay
01338 );
01339
01342 const PStringArray & GetMediaFormatOrder() const { return mediaFormatOrder; }
01343
01346 void SetMediaFormatOrder(
01347 const PStringArray & order
01348 );
01349
01355 const PStringArray & GetMediaFormatMask() const { return mediaFormatMask; }
01356
01362 void SetMediaFormatMask(
01363 const PStringArray & mask
01364 );
01365
01368 virtual void SetSilenceDetectParams(
01369 const OpalSilenceDetector::Params & params
01370 ) { silenceDetectParams = params; }
01371
01374 const OpalSilenceDetector::Params & GetSilenceDetectParams() const { return silenceDetectParams; }
01375
01376 #if OPAL_AEC
01377
01379 virtual void SetEchoCancelParams(
01380 const OpalEchoCanceler::Params & params
01381 ) { echoCancelParams = params; }
01382
01385 const OpalEchoCanceler::Params & GetEchoCancelParams() const { return echoCancelParams; }
01386 #endif
01387
01388 #if OPAL_VIDEO
01389
01397 virtual PBoolean SetVideoInputDevice(
01398 const PVideoDevice::OpenArgs & deviceArgs
01399 );
01400
01404 const PVideoDevice::OpenArgs & GetVideoInputDevice() const { return videoInputDevice; }
01405
01413 virtual PBoolean SetVideoPreviewDevice(
01414 const PVideoDevice::OpenArgs & deviceArgs
01415 );
01416
01420 const PVideoDevice::OpenArgs & GetVideoPreviewDevice() const { return videoPreviewDevice; }
01421
01429 virtual PBoolean SetVideoOutputDevice(
01430 const PVideoDevice::OpenArgs & deviceArgs
01431 );
01432
01436 const PVideoDevice::OpenArgs & GetVideoOutputDevice() const { return videoOutputDevice; }
01437
01438 #endif
01439
01440 PBoolean DetectInBandDTMFDisabled() const
01441 { return disableDetectInBandDTMF; }
01442
01445 void DisableDetectInBandDTMF(
01446 PBoolean mode
01447 ) { disableDetectInBandDTMF = mode; }
01448
01451 const PTimeInterval & GetNoMediaTimeout() const { return noMediaTimeout; }
01452
01455 PBoolean SetNoMediaTimeout(
01456 const PTimeInterval & newInterval
01457 );
01458
01461 const PString & GetDefaultILSServer() const { return ilsServer; }
01462
01465 void SetDefaultILSServer(
01466 const PString & server
01467 ) { ilsServer = server; }
01469
01470
01471 void GarbageCollection();
01472
01473 #ifdef OPAL_ZRTP
01474 virtual bool GetZRTPEnabled() const;
01475 #endif
01476
01477 virtual void OnApplyStringOptions(
01478 OpalConnection & conn,
01479 OpalConnection::StringOptions & stringOptions
01480 );
01481
01482 protected:
01483
01484 OpalProductInfo productInfo;
01485
01486 PString defaultUserName;
01487 PString defaultDisplayName;
01488
01489 BYTE m_defaultMediaTypeOfService;
01490 map<OpalMediaType, BYTE> m_mediaTypeOfService;
01491
01492 PINDEX rtpPayloadSizeMax;
01493 PINDEX rtpPacketSizeMax;
01494 unsigned minAudioJitterDelay;
01495 unsigned maxAudioJitterDelay;
01496 PStringArray mediaFormatOrder;
01497 PStringArray mediaFormatMask;
01498 PBoolean disableDetectInBandDTMF;
01499 PTimeInterval noMediaTimeout;
01500 PString ilsServer;
01501
01502 OpalSilenceDetector::Params silenceDetectParams;
01503 #if OPAL_AEC
01504 OpalEchoCanceler::Params echoCancelParams;
01505 #endif
01506
01507 #if OPAL_VIDEO
01508 PVideoDevice::OpenArgs videoInputDevice;
01509 PVideoDevice::OpenArgs videoPreviewDevice;
01510 PVideoDevice::OpenArgs videoOutputDevice;
01511 #endif
01512
01513 struct PortInfo {
01514 void Set(
01515 unsigned base,
01516 unsigned max,
01517 unsigned range,
01518 unsigned dflt
01519 );
01520 WORD GetNext(
01521 unsigned increment
01522 );
01523
01524 PMutex mutex;
01525 WORD base;
01526 WORD max;
01527 WORD current;
01528 } tcpPorts, udpPorts, rtpIpPorts;
01529
01530 class InterfaceMonitor : public PInterfaceMonitorClient
01531 {
01532 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
01533
01534 enum {
01535 OpalManagerInterfaceMonitorClientPriority = 100,
01536 };
01537 public:
01538 InterfaceMonitor(OpalManager & manager);
01539
01540 protected:
01541 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
01542 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
01543
01544 OpalManager & m_manager;
01545 };
01546
01547 PString translationHost;
01548 PIPSocket::Address translationAddress;
01549 PString stunServer;
01550 PSTUNClient * stun;
01551 InterfaceMonitor * interfaceMonitor;
01552
01553 RouteTable m_routeTable;
01554 PMutex m_routeMutex;
01555
01556
01557 PReadWriteMutex endpointsMutex;
01558 PList<OpalEndPoint> endpointList;
01559 std::map<PString, OpalEndPoint *> endpointMap;
01560
01561 PAtomicInteger lastCallTokenID;
01562
01563 class CallDict : public PSafeDictionary<PString, OpalCall>
01564 {
01565 public:
01566 CallDict(OpalManager & mgr) : manager(mgr) { }
01567 virtual void DeleteObject(PObject * object) const;
01568 OpalManager & manager;
01569 } activeCalls;
01570
01571 PSafeDictionary<PString, OpalPresentity> m_presentities;
01572
01573 PAtomicInteger m_clearingAllCallsCount;
01574 PMutex m_clearingAllCallsMutex;
01575 PSyncPoint m_allCallsCleared;
01576 void InternalClearAllCalls(OpalConnection::CallEndReason reason, bool wait, bool first);
01577
01578 PThread * garbageCollector;
01579 PSyncPoint garbageCollectExit;
01580 PDECLARE_NOTIFIER(PThread, OpalManager, GarbageMain);
01581
01582 #ifdef OPAL_ZRTP
01583 bool zrtpEnabled;
01584 #endif
01585
01586 friend OpalCall::OpalCall(OpalManager & mgr);
01587 friend void OpalCall::InternalOnClear();
01588
01589 private:
01590 P_REMOVE_VIRTUAL(OpalCall *,CreateCall(), 0);
01591 P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &, unsigned), false);
01592 P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &), false);
01593 P_REMOVE_VIRTUAL(PBoolean, OnStartMediaPatch(const OpalMediaPatch &), false);
01594 P_REMOVE_VIRTUAL_VOID(AdjustMediaFormats(const OpalConnection &, OpalMediaFormatList &) const);
01595 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const PURL&,const PString&,const PURL&,const PString&,const PString&,const PString&));
01596 };
01597
01598
01599 PString OpalGetVersion();
01600 unsigned OpalGetMajorVersion();
01601 unsigned OpalGetMinorVersion();
01602 unsigned OpalGetBuildNumber();
01603
01604
01605 #endif // OPAL_OPAL_MANAGER_H
01606
01607
01608