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
00228 virtual PBoolean ClearCall(
00229 const PString & token,
00230 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00231 PSyncPoint * sync = NULL
00232 );
00233
00241 virtual PBoolean ClearCallSynchronous(
00242 const PString & token,
00243 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser
00244 );
00245
00251 virtual void ClearAllCalls(
00252 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00253 PBoolean wait = true
00254 );
00255
00269 virtual void OnClearedCall(
00270 OpalCall & call
00271 );
00272
00281 virtual OpalCall * CreateCall(
00282 void * userData
00283 );
00284 OpalCall * InternalCreateCall();
00285
00294 virtual void DestroyCall(
00295 OpalCall * call
00296 );
00297
00302 virtual PString GetNextToken(char prefix);
00304
00313 virtual PSafePtr<OpalPresentity> AddPresentity(
00314 const PString & presentity
00315 );
00316
00319 virtual PSafePtr<OpalPresentity> GetPresentity(
00320 const PString & presentity,
00321 PSafetyMode mode = PSafeReference
00322 );
00323
00326 virtual PStringList GetPresentities() const;
00327
00330 virtual bool RemovePresentity(
00331 const PString & presentity
00332 );
00334
00339 virtual PBoolean Message(
00340 const PString & to,
00341 const PString & body
00342 );
00343 virtual PBoolean Message(
00344 const PURL & to,
00345 const PString & type,
00346 const PString & body,
00347 PURL & from,
00348 PString & conversationId
00349 );
00350 virtual PBoolean Message(
00351 OpalIM & message
00352 );
00353
00356 virtual void OnMessageReceived(
00357 const OpalIM & message
00358 );
00359
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 );
00594
00640 virtual bool OnTransferNotify(
00641 OpalConnection & connection,
00642 const PStringToString & info
00643 );
00645
00646
00656 virtual OpalMediaFormatList GetCommonMediaFormats(
00657 bool transportable,
00658 bool pcmAudio
00659 ) const;
00660
00670 virtual void AdjustMediaFormats(
00671 bool local,
00672 const OpalConnection & connection,
00673 OpalMediaFormatList & mediaFormats
00674 ) const;
00675
00678 virtual PBoolean IsMediaBypassPossible(
00679 const OpalConnection & source,
00680 const OpalConnection & destination,
00681 unsigned sessionID
00682 ) const;
00683
00699 virtual PBoolean OnOpenMediaStream(
00700 OpalConnection & connection,
00701 OpalMediaStream & stream
00702 );
00703
00712 virtual RTP_UDP * CreateRTPSession (const RTP_Session::Params & params);
00713
00721 virtual void OnRTPStatistics(
00722 const OpalConnection & connection,
00723 const RTP_Session & session
00724 );
00725
00742 virtual bool OnLocalRTP(
00743 OpalConnection & connection1,
00744 OpalConnection & connection2,
00745 unsigned sessionID,
00746 bool opened
00747 ) const;
00748
00774 bool SetMediaPassThrough(
00775 const PString & token1,
00776 const PString & token2,
00777 bool bypass,
00778 unsigned sessionID = 0,
00779 bool network = true
00780 );
00781 static bool SetMediaPassThrough(
00782 OpalConnection & connection1,
00783 OpalConnection & connection2,
00784 bool bypass,
00785 unsigned sessionID = 0
00786 );
00787
00792 virtual void OnClosedMediaStream(
00793 const OpalMediaStream & stream
00794 );
00795
00796 #if OPAL_VIDEO
00797
00799 virtual PBoolean CreateVideoInputDevice(
00800 const OpalConnection & connection,
00801 const OpalMediaFormat & mediaFormat,
00802 PVideoInputDevice * & device,
00803 PBoolean & autoDelete
00804 );
00805
00809 virtual PBoolean CreateVideoOutputDevice(
00810 const OpalConnection & connection,
00811 const OpalMediaFormat & mediaFormat,
00812 PBoolean preview,
00813 PVideoOutputDevice * & device,
00814 PBoolean & autoDelete
00815 );
00816 #endif
00817
00825 virtual OpalMediaPatch * CreateMediaPatch(
00826 OpalMediaStream & source,
00827 PBoolean requiresPatchThread = true
00828 );
00829
00836 virtual void OnStartMediaPatch(
00837 OpalConnection & connection,
00838 OpalMediaPatch & patch
00839 );
00840
00843 virtual void OnStopMediaPatch(
00844 OpalConnection & connection,
00845 OpalMediaPatch & patch
00846 );
00848
00856 virtual void OnUserInputString(
00857 OpalConnection & connection,
00858 const PString & value
00859 );
00860
00867 virtual void OnUserInputTone(
00868 OpalConnection & connection,
00869 char tone,
00870 int duration
00871 );
00872
00875 virtual PString ReadUserInput(
00876 OpalConnection & connection,
00877 const char * terminators = "#\r\n",
00878 unsigned lastDigitTimeout = 4,
00879 unsigned firstDigitTimeout = 30
00880 );
00882
00885
00886 enum MessageWaitingType {
00887 NoMessageWaiting,
00888 VoiceMessageWaiting,
00889 FaxMessageWaiting,
00890 PagerMessageWaiting,
00891 MultimediaMessageWaiting,
00892 TextMessageWaiting,
00893 NumMessageWaitingTypes
00894 };
00895
00906 virtual void OnMWIReceived(
00907 const PString & party,
00908 MessageWaitingType type,
00909 const PString & extraInfo
00910 );
00911
00912
00913 class RouteEntry : public PObject
00914 {
00915 PCLASSINFO(RouteEntry, PObject);
00916 public:
00917 RouteEntry(const PString & pat, const PString & dest);
00918 void PrintOn(ostream & strm) const;
00919 PString pattern;
00920 PString destination;
00921 PRegularExpression regex;
00922 };
00923 PARRAY(RouteTable, RouteEntry);
00924
01035 virtual PBoolean AddRouteEntry(
01036 const PString & spec
01037 );
01038
01045 PBoolean SetRouteTable(
01046 const PStringArray & specs
01047 );
01048
01053 void SetRouteTable(
01054 const RouteTable & table
01055 );
01056
01059 const RouteTable & GetRouteTable() const { return m_routeTable; }
01060
01068 virtual PString ApplyRouteTable(
01069 const PString & source,
01070 const PString & destination,
01071 PINDEX & entry
01072 );
01074
01075 #if OPAL_HAS_MIXER
01076
01086 virtual PBoolean StartRecording(
01087 const PString & callToken,
01088 const PFilePath & filename,
01089 const OpalRecordManager::Options & options = false
01090 );
01091
01094 virtual bool IsRecording(
01095 const PString & callToken
01096 );
01097
01102 virtual bool StopRecording(
01103 const PString & callToken
01104 );
01105
01107 #endif
01108
01113 const OpalProductInfo & GetProductInfo() const { return productInfo; }
01114
01117 void SetProductInfo(
01118 const OpalProductInfo & info,
01119 bool updateAll = true
01120 );
01121
01124 const PString & GetDefaultUserName() const { return defaultUserName; }
01125
01128 void SetDefaultUserName(
01129 const PString & name,
01130 bool updateAll = true
01131 );
01132
01135 const PString & GetDefaultDisplayName() const { return defaultDisplayName; }
01136
01139 void SetDefaultDisplayName(
01140 const PString & name,
01141 bool updateAll = true
01142 );
01143
01144 #if OPAL_VIDEO
01145
01146
01147
01148
01149
01150
01151
01154 bool CanAutoStartReceiveVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Receive) != 0; }
01155
01158 void SetAutoStartReceiveVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(OpalMediaType::Receive, can); }
01159
01162 bool CanAutoStartTransmitVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Transmit) != 0; }
01163
01166 void SetAutoStartTransmitVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(OpalMediaType::Transmit, can); }
01167
01168 #endif
01169
01176 virtual PBoolean IsLocalAddress(
01177 const PIPSocket::Address & remoteAddress
01178 ) const;
01179
01197 virtual PBoolean IsRTPNATEnabled(
01198 OpalConnection & connection,
01199 const PIPSocket::Address & localAddr,
01200 const PIPSocket::Address & peerAddr,
01201 const PIPSocket::Address & signalAddr,
01202 PBoolean incoming
01203 );
01204
01211 virtual PBoolean TranslateIPAddress(
01212 PIPSocket::Address & localAddress,
01213 const PIPSocket::Address & remoteAddress
01214 );
01215
01218 const PString & GetTranslationHost() const { return translationHost; }
01219
01222 bool SetTranslationHost(
01223 const PString & host
01224 );
01225
01228 const PIPSocket::Address & GetTranslationAddress() const { return translationAddress; }
01229
01232 void SetTranslationAddress(
01233 const PIPSocket::Address & address
01234 );
01235
01241 virtual PNatMethod * GetNatMethod(
01242 const PIPSocket::Address & remoteAddress = PIPSocket::GetDefaultIpAny()
01243 ) const;
01244
01249 PSTUNClient::NatTypes SetSTUNServer(
01250 const PString & server
01251 );
01252
01255 const PString & GetSTUNServer() const { return stunServer; }
01256
01259 PSTUNClient * GetSTUNClient() const { return stun; }
01260
01263 WORD GetTCPPortBase() const { return tcpPorts.base; }
01264
01267 WORD GetTCPPortMax() const { return tcpPorts.max; }
01268
01271 void SetTCPPorts(unsigned tcpBase, unsigned tcpMax);
01272
01275 WORD GetNextTCPPort();
01276
01279 WORD GetUDPPortBase() const { return udpPorts.base; }
01280
01283 WORD GetUDPPortMax() const { return udpPorts.max; }
01284
01287 void SetUDPPorts(unsigned udpBase, unsigned udpMax);
01288
01291 WORD GetNextUDPPort();
01292
01295 WORD GetRtpIpPortBase() const { return rtpIpPorts.base; }
01296
01299 WORD GetRtpIpPortMax() const { return rtpIpPorts.max; }
01300
01303 void SetRtpIpPorts(unsigned udpBase, unsigned udpMax);
01304
01307 WORD GetRtpIpPortPair();
01308
01311 BYTE GetMediaTypeOfService() const { return m_defaultMediaTypeOfService; }
01312
01315 void SetMediaTypeOfService(unsigned tos) { m_defaultMediaTypeOfService = (BYTE)tos; }
01316
01317
01318 BYTE P_DEPRECATED GetRtpIpTypeofService() const { return m_defaultMediaTypeOfService; }
01319 void P_DEPRECATED SetRtpIpTypeofService(unsigned tos) { m_defaultMediaTypeOfService = (BYTE)tos; }
01320
01323 BYTE GetMediaTypeOfService(const OpalMediaType & type) const;
01324
01327 void SetMediaTypeOfService(const OpalMediaType & type, unsigned tos);
01328
01333 PINDEX GetMaxRtpPayloadSize() const { return rtpPayloadSizeMax; }
01334
01339 void SetMaxRtpPayloadSize(
01340 PINDEX size,
01341 bool mtu = false
01342 ) { rtpPayloadSizeMax = size - (mtu ? (20+16+12) : 0); }
01343
01347 PINDEX GetMaxRtpPacketSize() const { return rtpPacketSizeMax; }
01348
01352 void SetMaxRtpPacketSize(
01353 PINDEX size
01354 ) { rtpPacketSizeMax = size; }
01355
01359 unsigned GetMinAudioJitterDelay() const { return minAudioJitterDelay; }
01360
01364 unsigned GetMaxAudioJitterDelay() const { return maxAudioJitterDelay; }
01365
01375 void SetAudioJitterDelay(
01376 unsigned minDelay,
01377 unsigned maxDelay
01378 );
01379
01382 const PStringArray & GetMediaFormatOrder() const { return mediaFormatOrder; }
01383
01386 void SetMediaFormatOrder(
01387 const PStringArray & order
01388 );
01389
01395 const PStringArray & GetMediaFormatMask() const { return mediaFormatMask; }
01396
01402 void SetMediaFormatMask(
01403 const PStringArray & mask
01404 );
01405
01408 virtual void SetSilenceDetectParams(
01409 const OpalSilenceDetector::Params & params
01410 ) { silenceDetectParams = params; }
01411
01414 const OpalSilenceDetector::Params & GetSilenceDetectParams() const { return silenceDetectParams; }
01415
01416 #if OPAL_AEC
01417
01419 virtual void SetEchoCancelParams(
01420 const OpalEchoCanceler::Params & params
01421 ) { echoCancelParams = params; }
01422
01425 const OpalEchoCanceler::Params & GetEchoCancelParams() const { return echoCancelParams; }
01426 #endif
01427
01428 #if OPAL_VIDEO
01429
01437 virtual PBoolean SetVideoInputDevice(
01438 const PVideoDevice::OpenArgs & deviceArgs
01439 );
01440
01444 const PVideoDevice::OpenArgs & GetVideoInputDevice() const { return videoInputDevice; }
01445
01453 virtual PBoolean SetVideoPreviewDevice(
01454 const PVideoDevice::OpenArgs & deviceArgs
01455 );
01456
01460 const PVideoDevice::OpenArgs & GetVideoPreviewDevice() const { return videoPreviewDevice; }
01461
01469 virtual PBoolean SetVideoOutputDevice(
01470 const PVideoDevice::OpenArgs & deviceArgs
01471 );
01472
01476 const PVideoDevice::OpenArgs & GetVideoOutputDevice() const { return videoOutputDevice; }
01477
01478 #endif
01479
01480 PBoolean DetectInBandDTMFDisabled() const
01481 { return disableDetectInBandDTMF; }
01482
01485 void DisableDetectInBandDTMF(
01486 PBoolean mode
01487 ) { disableDetectInBandDTMF = mode; }
01488
01491 const PTimeInterval & GetNoMediaTimeout() const { return noMediaTimeout; }
01492
01495 PBoolean SetNoMediaTimeout(
01496 const PTimeInterval & newInterval
01497 );
01498
01501 const PString & GetDefaultILSServer() const { return ilsServer; }
01502
01505 void SetDefaultILSServer(
01506 const PString & server
01507 ) { ilsServer = server; }
01509
01510
01511 void GarbageCollection();
01512
01513 #ifdef OPAL_ZRTP
01514 virtual bool GetZRTPEnabled() const;
01515 #endif
01516
01517 virtual void OnApplyStringOptions(
01518 OpalConnection & conn,
01519 OpalConnection::StringOptions & stringOptions
01520 );
01521
01522 protected:
01523
01524 OpalProductInfo productInfo;
01525
01526 PString defaultUserName;
01527 PString defaultDisplayName;
01528
01529 BYTE m_defaultMediaTypeOfService;
01530 map<OpalMediaType, BYTE> m_mediaTypeOfService;
01531
01532 PINDEX rtpPayloadSizeMax;
01533 PINDEX rtpPacketSizeMax;
01534 unsigned minAudioJitterDelay;
01535 unsigned maxAudioJitterDelay;
01536 PStringArray mediaFormatOrder;
01537 PStringArray mediaFormatMask;
01538 PBoolean disableDetectInBandDTMF;
01539 PTimeInterval noMediaTimeout;
01540 PString ilsServer;
01541
01542 OpalSilenceDetector::Params silenceDetectParams;
01543 #if OPAL_AEC
01544 OpalEchoCanceler::Params echoCancelParams;
01545 #endif
01546
01547 #if OPAL_VIDEO
01548 PVideoDevice::OpenArgs videoInputDevice;
01549 PVideoDevice::OpenArgs videoPreviewDevice;
01550 PVideoDevice::OpenArgs videoOutputDevice;
01551 #endif
01552
01553 struct PortInfo {
01554 void Set(
01555 unsigned base,
01556 unsigned max,
01557 unsigned range,
01558 unsigned dflt
01559 );
01560 WORD GetNext(
01561 unsigned increment
01562 );
01563
01564 PMutex mutex;
01565 WORD base;
01566 WORD max;
01567 WORD current;
01568 } tcpPorts, udpPorts, rtpIpPorts;
01569
01570 class InterfaceMonitor : public PInterfaceMonitorClient
01571 {
01572 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
01573
01574 enum {
01575 OpalManagerInterfaceMonitorClientPriority = 100,
01576 };
01577 public:
01578 InterfaceMonitor(OpalManager & manager);
01579
01580 protected:
01581 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
01582 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
01583
01584 OpalManager & m_manager;
01585 };
01586
01587 PString translationHost;
01588 PIPSocket::Address translationAddress;
01589 PString stunServer;
01590 PSTUNClient * stun;
01591 InterfaceMonitor * interfaceMonitor;
01592
01593 RouteTable m_routeTable;
01594 PMutex m_routeMutex;
01595
01596
01597 PReadWriteMutex endpointsMutex;
01598 PList<OpalEndPoint> endpointList;
01599 std::map<PString, OpalEndPoint *> endpointMap;
01600
01601 PAtomicInteger lastCallTokenID;
01602
01603 class CallDict : public PSafeDictionary<PString, OpalCall>
01604 {
01605 public:
01606 CallDict(OpalManager & mgr) : manager(mgr) { }
01607 virtual void DeleteObject(PObject * object) const;
01608 OpalManager & manager;
01609 } activeCalls;
01610
01611 PSafeDictionary<PString, OpalPresentity> m_presentities;
01612
01613 PAtomicInteger m_clearingAllCallsCount;
01614 PMutex m_clearingAllCallsMutex;
01615 PSyncPoint m_allCallsCleared;
01616 void InternalClearAllCalls(OpalConnection::CallEndReason reason, bool wait, bool first);
01617
01618 PThread * garbageCollector;
01619 PSyncPoint garbageCollectExit;
01620 bool garbageCollectSkip;
01621 PDECLARE_NOTIFIER(PThread, OpalManager, GarbageMain);
01622
01623 #ifdef OPAL_ZRTP
01624 bool zrtpEnabled;
01625 #endif
01626
01627 friend OpalCall::OpalCall(OpalManager & mgr);
01628 friend void OpalCall::InternalOnClear();
01629
01630 private:
01631 P_REMOVE_VIRTUAL(OpalCall *,CreateCall(), 0);
01632 P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &, unsigned), false);
01633 P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &), false);
01634 P_REMOVE_VIRTUAL(PBoolean, OnStartMediaPatch(const OpalMediaPatch &), false);
01635 P_REMOVE_VIRTUAL_VOID(AdjustMediaFormats(const OpalConnection &, OpalMediaFormatList &) const);
01636 P_REMOVE_VIRTUAL_VOID(OnMessageReceived(const PURL&,const PString&,const PURL&,const PString&,const PString&,const PString&));
01637
01638
01639 #ifdef OPAL_HAS_IM
01640 public:
01641 OpalIMManager & GetIMManager() { return *m_imManager; }
01642
01643 protected:
01644 OpalIMManager * m_imManager;
01645 #endif
01646 };
01647
01648
01649 PString OpalGetVersion();
01650 unsigned OpalGetMajorVersion();
01651 unsigned OpalGetMinorVersion();
01652 unsigned OpalGetBuildNumber();
01653
01654
01655 #endif // OPAL_OPAL_MANAGER_H
01656
01657
01658