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/call.h>
00042 #include <opal/connection.h>
00043 #include <opal/guid.h>
00044 #include <codec/silencedetect.h>
00045 #include <codec/echocancel.h>
00046 #include <ptclib/pstun.h>
00047 #include <ptclib/url.h>
00048
00049 #if OPAL_VIDEO
00050 #include <ptlib/videoio.h>
00051 #endif
00052
00053 class OpalEndPoint;
00054 class OpalMediaPatch;
00055
00056
00073 class OpalManager : public PObject
00074 {
00075 PCLASSINFO(OpalManager, PObject);
00076 public:
00081 OpalManager();
00082
00087 ~OpalManager();
00089
00099 void AttachEndPoint(
00100 OpalEndPoint * endpoint,
00101 const PString & prefix = PString::Empty()
00102 );
00103
00107 void DetachEndPoint(
00108 const PString & prefix
00109 );
00110 void DetachEndPoint(
00111 OpalEndPoint * endpoint
00112 );
00113
00116 OpalEndPoint * FindEndPoint(
00117 const PString & prefix
00118 );
00119
00122 PList<OpalEndPoint> GetEndPoints() const;
00123
00129 void ShutDownEndpoints();
00131
00150 virtual PSafePtr<OpalCall> SetUpCall(
00151 const PString & partyA,
00152 const PString & partyB,
00153 void * userData = NULL,
00154 unsigned options = 0,
00155 OpalConnection::StringOptions * stringOptions = NULL
00156 );
00157 virtual PBoolean SetUpCall(
00158 const PString & partyA,
00159 const PString & partyB,
00160 PString & token,
00161 void * userData = NULL,
00162 unsigned options = 0,
00163 OpalConnection::StringOptions * stringOptions = NULL
00164 );
00165
00174 virtual void OnEstablishedCall(
00175 OpalCall & call
00176 );
00177
00183 virtual PBoolean HasCall(
00184 const PString & token
00185 ) { return activeCalls.FindWithLock(token, PSafeReference) != NULL; }
00186
00189 PINDEX GetCallCount() const { return activeCalls.GetSize(); }
00190
00191
00198 virtual PBoolean IsCallEstablished(
00199 const PString & token
00200 );
00201
00210 PSafePtr<OpalCall> FindCallWithLock(
00211 const PString & token,
00212 PSafetyMode mode = PSafeReadWrite
00213 ) { return activeCalls.FindWithLock(token, mode); }
00214
00222 virtual PBoolean ClearCall(
00223 const PString & token,
00224 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00225 PSyncPoint * sync = NULL
00226 );
00227
00235 virtual PBoolean ClearCallSynchronous(
00236 const PString & token,
00237 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser
00238 );
00239
00245 virtual void ClearAllCalls(
00246 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00247 PBoolean wait = PTrue
00248 );
00249
00263 virtual void OnClearedCall(
00264 OpalCall & call
00265 );
00266
00275 virtual OpalCall * CreateCall(
00276 void * userData
00277 );
00278 OpalCall * InternalCreateCall();
00279
00288 virtual void DestroyCall(
00289 OpalCall * call
00290 );
00291
00296 virtual PString GetNextToken(char prefix);
00298
00335 virtual PSafePtr<OpalConnection> MakeConnection(
00336 OpalCall & call,
00337 const PString & party,
00338 void * userData = NULL,
00339 unsigned int options = 0,
00340 OpalConnection::StringOptions * stringOptions = NULL
00341 );
00342
00369 virtual PBoolean OnIncomingConnection(
00370 OpalConnection & connection,
00371 unsigned options,
00372 OpalConnection::StringOptions * stringOptions
00373 );
00374
00381 virtual bool OnRouteConnection(
00382 PStringSet & routesTried,
00383 const PString & a_party,
00384 const PString & b_party,
00385 OpalCall & call,
00386 unsigned options,
00387 OpalConnection::StringOptions * stringOptions
00388 );
00389
00405 virtual void OnProceeding(
00406 OpalConnection & connection
00407 );
00408
00425 virtual void OnAlerting(
00426 OpalConnection & connection
00427 );
00428
00445 virtual OpalConnection::AnswerCallResponse OnAnswerCall(
00446 OpalConnection & connection,
00447 const PString & caller
00448 );
00449
00461 virtual void OnConnected(
00462 OpalConnection & connection
00463 );
00464
00478 virtual void OnEstablished(
00479 OpalConnection & connection
00480 );
00481
00497 virtual void OnReleased(
00498 OpalConnection & connection
00499 );
00500
00507 virtual void OnHold(
00508 OpalConnection & connection,
00509 bool fromRemote,
00510 bool onHold
00511 );
00512 virtual void OnHold(OpalConnection & connection);
00513
00518 virtual PBoolean OnForwarded(
00519 OpalConnection & connection,
00520 const PString & remoteParty
00521 );
00523
00533 virtual OpalMediaFormatList GetCommonMediaFormats(
00534 bool transportable,
00535 bool pcmAudio
00536 ) const;
00537
00547 virtual void AdjustMediaFormats(
00548 const OpalConnection & connection,
00549 OpalMediaFormatList & mediaFormats
00550 ) const;
00551
00554 virtual PBoolean IsMediaBypassPossible(
00555 const OpalConnection & source,
00556 const OpalConnection & destination,
00557 unsigned sessionID
00558 ) const;
00559
00575 virtual PBoolean OnOpenMediaStream(
00576 OpalConnection & connection,
00577 OpalMediaStream & stream
00578 );
00579
00587 virtual void OnRTPStatistics(
00588 const OpalConnection & connection,
00589 const RTP_Session & session
00590 );
00591
00596 virtual void OnClosedMediaStream(
00597 const OpalMediaStream & stream
00598 );
00599
00600 #if OPAL_VIDEO
00601
00603 virtual PBoolean CreateVideoInputDevice(
00604 const OpalConnection & connection,
00605 const OpalMediaFormat & mediaFormat,
00606 PVideoInputDevice * & device,
00607 PBoolean & autoDelete
00608 );
00609
00613 virtual PBoolean CreateVideoOutputDevice(
00614 const OpalConnection & connection,
00615 const OpalMediaFormat & mediaFormat,
00616 PBoolean preview,
00617 PVideoOutputDevice * & device,
00618 PBoolean & autoDelete
00619 );
00620 #endif
00621
00629 virtual OpalMediaPatch * CreateMediaPatch(
00630 OpalMediaStream & source,
00631 PBoolean requiresPatchThread = PTrue
00632 );
00633
00638 virtual void DestroyMediaPatch(
00639 OpalMediaPatch * patch
00640 );
00641
00649 virtual PBoolean OnStartMediaPatch(
00650 const OpalMediaPatch & patch
00651 );
00653
00661 virtual void OnUserInputString(
00662 OpalConnection & connection,
00663 const PString & value
00664 );
00665
00672 virtual void OnUserInputTone(
00673 OpalConnection & connection,
00674 char tone,
00675 int duration
00676 );
00677
00680 virtual PString ReadUserInput(
00681 OpalConnection & connection,
00682 const char * terminators = "#\r\n",
00683 unsigned lastDigitTimeout = 4,
00684 unsigned firstDigitTimeout = 30
00685 );
00687
00690 enum MessageWaitingType {
00691 NoMessageWaiting,
00692 VoiceMessageWaiting,
00693 FaxMessageWaiting,
00694 PagerMessageWaiting,
00695 MultimediaMessageWaiting,
00696 TextMessageWaiting,
00697 NumMessageWaitingTypes
00698 };
00699
00702 virtual void OnMWIReceived(
00703 const PString & party,
00704 MessageWaitingType type,
00705 const PString & extraInfo
00706 );
00707
00708
00709 class RouteEntry : public PObject
00710 {
00711 PCLASSINFO(RouteEntry, PObject);
00712 public:
00713 RouteEntry(const PString & pat, const PString & dest);
00714 void PrintOn(ostream & strm) const;
00715 PString pattern;
00716 PString destination;
00717 PRegularExpression regex;
00718 };
00719 PARRAY(RouteTable, RouteEntry);
00720
00831 virtual PBoolean AddRouteEntry(
00832 const PString & spec
00833 );
00834
00841 PBoolean SetRouteTable(
00842 const PStringArray & specs
00843 );
00844
00849 void SetRouteTable(
00850 const RouteTable & table
00851 );
00852
00855 const RouteTable & GetRouteTable() const { return routeTable; }
00856
00864 virtual PString ApplyRouteTable(
00865 const PString & source,
00866 const PString & destination,
00867 PINDEX & entry
00868 );
00870
00875 const OpalProductInfo & GetProductInfo() const { return productInfo; }
00876
00879 void SetProductInfo(
00880 const OpalProductInfo & info,
00881 bool updateAll = true
00882 );
00883
00886 const PString & GetDefaultUserName() const { return defaultUserName; }
00887
00890 void SetDefaultUserName(
00891 const PString & name,
00892 bool updateAll = true
00893 );
00894
00897 const PString & GetDefaultDisplayName() const { return defaultDisplayName; }
00898
00901 void SetDefaultDisplayName(
00902 const PString & name,
00903 bool updateAll = true
00904 );
00905
00906 #if OPAL_VIDEO
00907
00908
00909
00910
00911
00912
00913
00916 bool CanAutoStartReceiveVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Receive) != 0; }
00917
00920 void SetAutoStartReceiveVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(CanAutoStartTransmitVideo() ? can ? OpalMediaType::ReceiveTransmit : OpalMediaType::Transmit : can ? OpalMediaType::Receive : OpalMediaType::OfferInactive); }
00921
00924 bool CanAutoStartTransmitVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Transmit) != 0; }
00925
00928 void SetAutoStartTransmitVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(CanAutoStartReceiveVideo() ? can ? OpalMediaType::ReceiveTransmit : OpalMediaType::Receive : can ? OpalMediaType::Transmit : OpalMediaType::OfferInactive); }
00929
00930 #endif
00931
00938 virtual PBoolean IsLocalAddress(
00939 const PIPSocket::Address & remoteAddress
00940 ) const;
00941
00959 virtual PBoolean IsRTPNATEnabled(
00960 OpalConnection & connection,
00961 const PIPSocket::Address & localAddr,
00962 const PIPSocket::Address & peerAddr,
00963 const PIPSocket::Address & signalAddr,
00964 PBoolean incoming
00965 );
00966
00973 virtual PBoolean TranslateIPAddress(
00974 PIPSocket::Address & localAddress,
00975 const PIPSocket::Address & remoteAddress
00976 );
00977
00980 const PString & GetTranslationHost() const { return translationHost; }
00981
00984 bool SetTranslationHost(
00985 const PString & host
00986 );
00987
00990 const PIPSocket::Address & GetTranslationAddress() const { return translationAddress; }
00991
00994 void SetTranslationAddress(
00995 const PIPSocket::Address & address
00996 );
00997
01003 virtual PNatMethod * GetNatMethod(
01004 const PIPSocket::Address & remoteAddress = PIPSocket::GetDefaultIpAny()
01005 ) const;
01006
01011 PSTUNClient::NatTypes SetSTUNServer(
01012 const PString & server
01013 );
01014
01017 const PString & GetSTUNServer() const { return stunServer; }
01018
01021 PSTUNClient * GetSTUNClient() const { return stun; }
01022
01025 WORD GetTCPPortBase() const { return tcpPorts.base; }
01026
01029 WORD GetTCPPortMax() const { return tcpPorts.max; }
01030
01033 void SetTCPPorts(unsigned tcpBase, unsigned tcpMax);
01034
01037 WORD GetNextTCPPort();
01038
01041 WORD GetUDPPortBase() const { return udpPorts.base; }
01042
01045 WORD GetUDPPortMax() const { return udpPorts.max; }
01046
01049 void SetUDPPorts(unsigned udpBase, unsigned udpMax);
01050
01053 WORD GetNextUDPPort();
01054
01057 WORD GetRtpIpPortBase() const { return rtpIpPorts.base; }
01058
01061 WORD GetRtpIpPortMax() const { return rtpIpPorts.max; }
01062
01065 void SetRtpIpPorts(unsigned udpBase, unsigned udpMax);
01066
01069 WORD GetRtpIpPortPair();
01070
01073 BYTE GetRtpIpTypeofService() const { return rtpIpTypeofService; }
01074
01077 void SetRtpIpTypeofService(unsigned tos) { rtpIpTypeofService = (BYTE)tos; }
01078
01083 PINDEX GetMaxRtpPayloadSize() const { return rtpPayloadSizeMax; }
01084
01089 void SetMaxRtpPayloadSize(
01090 PINDEX size,
01091 bool mtu = false
01092 ) { rtpPayloadSizeMax = size - (mtu ? (20+16+12) : 0); }
01093
01097 PINDEX GetMaxRtpPacketSize() const { return rtpPacketSizeMax; }
01098
01102 void SetMaxRtpPacketSize(
01103 PINDEX size
01104 ) { rtpPacketSizeMax = size; }
01105
01109 unsigned GetMinAudioJitterDelay() const { return minAudioJitterDelay; }
01110
01114 unsigned GetMaxAudioJitterDelay() const { return maxAudioJitterDelay; }
01115
01125 void SetAudioJitterDelay(
01126 unsigned minDelay,
01127 unsigned maxDelay
01128 );
01129
01132 const PStringArray & GetMediaFormatOrder() const { return mediaFormatOrder; }
01133
01136 void SetMediaFormatOrder(
01137 const PStringArray & order
01138 );
01139
01142 const PStringArray & GetMediaFormatMask() const { return mediaFormatMask; }
01143
01146 void SetMediaFormatMask(
01147 const PStringArray & mask
01148 );
01149
01152 virtual void SetSilenceDetectParams(
01153 const OpalSilenceDetector::Params & params
01154 ) { silenceDetectParams = params; }
01155
01158 const OpalSilenceDetector::Params & GetSilenceDetectParams() const { return silenceDetectParams; }
01159
01162 virtual void SetEchoCancelParams(
01163 const OpalEchoCanceler::Params & params
01164 ) { echoCancelParams = params; }
01165
01168 const OpalEchoCanceler::Params & GetEchoCancelParams() const { return echoCancelParams; }
01169
01170 #if OPAL_VIDEO
01171
01179 virtual PBoolean SetVideoInputDevice(
01180 const PVideoDevice::OpenArgs & deviceArgs
01181 );
01182
01186 const PVideoDevice::OpenArgs & GetVideoInputDevice() const { return videoInputDevice; }
01187
01195 virtual PBoolean SetVideoPreviewDevice(
01196 const PVideoDevice::OpenArgs & deviceArgs
01197 );
01198
01202 const PVideoDevice::OpenArgs & GetVideoPreviewDevice() const { return videoPreviewDevice; }
01203
01211 virtual PBoolean SetVideoOutputDevice(
01212 const PVideoDevice::OpenArgs & deviceArgs
01213 );
01214
01218 const PVideoDevice::OpenArgs & GetVideoOutputDevice() const { return videoOutputDevice; }
01219
01220 #endif
01221
01222 PBoolean DetectInBandDTMFDisabled() const
01223 { return disableDetectInBandDTMF; }
01224
01227 void DisableDetectInBandDTMF(
01228 PBoolean mode
01229 ) { disableDetectInBandDTMF = mode; }
01230
01233 const PTimeInterval & GetNoMediaTimeout() const { return noMediaTimeout; }
01234
01237 PBoolean SetNoMediaTimeout(
01238 const PTimeInterval & newInterval
01239 );
01240
01243 const PString & GetDefaultILSServer() const { return ilsServer; }
01244
01247 void SetDefaultILSServer(
01248 const PString & server
01249 ) { ilsServer = server; }
01251
01252
01253 void GarbageCollection();
01254
01260 virtual void OnNewConnection(
01261 OpalConnection & connection
01262 );
01263
01272 virtual PBoolean StartRecording(
01273 const PString & callToken,
01274 const PFilePath & filename,
01275 const OpalRecordManager::Options & options = false
01276 );
01277
01280 virtual bool IsRecording(
01281 const PString & callToken
01282 );
01283
01288 virtual bool StopRecording(
01289 const PString & callToken
01290 );
01291
01292 #ifdef OPAL_ZRTP
01293 virtual bool GetZRTPEnabled() const;
01294 #endif
01295
01296 virtual void OnApplyStringOptions(
01297 OpalConnection & conn,
01298 OpalConnection::StringOptions & stringOptions
01299 );
01300
01303 virtual PBoolean Message(
01304 const PString & to,
01305 const PString & body
01306 );
01307 virtual PBoolean Message(
01308 const PURL & to,
01309 const PString & type,
01310 const PString & body,
01311 PURL & from,
01312 PString & conversationId
01313 );
01314
01317 virtual void OnMessageReceived(
01318 const PURL & from,
01319 const PString & fromName,
01320 const PURL & to,
01321 const PString & type,
01322 const PString & body,
01323 const PString & conversationId
01324 );
01325
01326 protected:
01327
01328 OpalProductInfo productInfo;
01329
01330 PString defaultUserName;
01331 PString defaultDisplayName;
01332
01333 BYTE rtpIpTypeofService;
01334 PINDEX rtpPayloadSizeMax;
01335 PINDEX rtpPacketSizeMax;
01336 unsigned minAudioJitterDelay;
01337 unsigned maxAudioJitterDelay;
01338 PStringArray mediaFormatOrder;
01339 PStringArray mediaFormatMask;
01340 PBoolean disableDetectInBandDTMF;
01341 PTimeInterval noMediaTimeout;
01342 PString ilsServer;
01343
01344 OpalSilenceDetector::Params silenceDetectParams;
01345 OpalEchoCanceler::Params echoCancelParams;
01346
01347 #if OPAL_VIDEO
01348 PVideoDevice::OpenArgs videoInputDevice;
01349 PVideoDevice::OpenArgs videoPreviewDevice;
01350 PVideoDevice::OpenArgs videoOutputDevice;
01351 #endif
01352
01353 struct PortInfo {
01354 void Set(
01355 unsigned base,
01356 unsigned max,
01357 unsigned range,
01358 unsigned dflt
01359 );
01360 WORD GetNext(
01361 unsigned increment
01362 );
01363
01364 PMutex mutex;
01365 WORD base;
01366 WORD max;
01367 WORD current;
01368 } tcpPorts, udpPorts, rtpIpPorts;
01369
01370 class InterfaceMonitor : public PInterfaceMonitorClient
01371 {
01372 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
01373
01374 enum {
01375 OpalManagerInterfaceMonitorClientPriority = 100,
01376 };
01377 public:
01378 InterfaceMonitor(OpalManager & manager);
01379
01380 protected:
01381 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
01382 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
01383
01384 OpalManager & m_manager;
01385 };
01386
01387 PString translationHost;
01388 PIPSocket::Address translationAddress;
01389 PString stunServer;
01390 PSTUNClient * stun;
01391 InterfaceMonitor * interfaceMonitor;
01392
01393 RouteTable routeTable;
01394 PMutex routeTableMutex;
01395
01396
01397 PReadWriteMutex endpointsMutex;
01398 PList<OpalEndPoint> endpointList;
01399 std::map<PString, OpalEndPoint *> endpointMap;
01400
01401 PAtomicInteger lastCallTokenID;
01402
01403 class CallDict : public PSafeDictionary<PString, OpalCall>
01404 {
01405 public:
01406 CallDict(OpalManager & mgr) : manager(mgr) { }
01407 virtual void DeleteObject(PObject * object) const;
01408 OpalManager & manager;
01409 } activeCalls;
01410
01411 PAtomicInteger m_clearingAllCallsCount;
01412 PMutex m_clearingAllCallsMutex;
01413 PSyncPoint m_allCallsCleared;
01414 void InternalClearAllCalls(OpalConnection::CallEndReason reason, bool wait, bool first);
01415
01416 PThread * garbageCollector;
01417 PSyncPoint garbageCollectExit;
01418 PDECLARE_NOTIFIER(PThread, OpalManager, GarbageMain);
01419
01420 #ifdef OPAL_ZRTP
01421 bool zrtpEnabled;
01422 #endif
01423
01424 friend OpalCall::OpalCall(OpalManager & mgr);
01425 friend void OpalCall::OnReleased(OpalConnection & connection);
01426
01427 private:
01428 P_REMOVE_VIRTUAL(OpalCall *,CreateCall(), 0);
01429 P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &, unsigned), false);
01430 P_REMOVE_VIRTUAL(PBoolean, OnIncomingConnection(OpalConnection &), false);
01431 };
01432
01433
01434 PString OpalGetVersion();
01435 unsigned OpalGetMajorVersion();
01436 unsigned OpalGetMinorVersion();
01437 unsigned OpalGetBuildNumber();
01438
01439
01440 #endif // OPAL_OPAL_MANAGER_H
01441
01442
01443