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 <opal/audiorecord.h>
00045 #include <codec/silencedetect.h>
00046 #include <codec/echocancel.h>
00047 #include <ptclib/pstun.h>
00048
00049 #if OPAL_VIDEO
00050 #include <ptlib/videoio.h>
00051 #endif
00052
00053 class OpalEndPoint;
00054 class OpalMediaPatch;
00055
00072 class OpalManager : public PObject
00073 {
00074 PCLASSINFO(OpalManager, PObject);
00075 public:
00080 OpalManager();
00081
00086 ~OpalManager();
00088
00098 void AttachEndPoint(
00099 OpalEndPoint * endpoint,
00100 const PString & prefix = PString::Empty()
00101 );
00102
00106 void DetachEndPoint(
00107 const PString & prefix
00108 );
00109 void DetachEndPoint(
00110 OpalEndPoint * endpoint
00111 );
00112
00115 OpalEndPoint * FindEndPoint(
00116 const PString & prefix
00117 );
00118
00121 PList<OpalEndPoint> GetEndPoints() const;
00122
00128 void ShutDownEndpoints();
00130
00149 virtual PBoolean SetUpCall(
00150 const PString & partyA,
00151 const PString & partyB,
00152 PString & token,
00153 void * userData = NULL,
00154 unsigned options = 0,
00155 OpalConnection::StringOptions * stringOptions = NULL
00156 );
00157
00166 virtual void OnEstablishedCall(
00167 OpalCall & call
00168 );
00169
00175 virtual PBoolean HasCall(
00176 const PString & token
00177 ) { return activeCalls.FindWithLock(token, PSafeReference) != NULL; }
00178
00181 PINDEX GetCallCount() const { return activeCalls.GetSize(); }
00182
00183
00190 virtual PBoolean IsCallEstablished(
00191 const PString & token
00192 );
00193
00202 PSafePtr<OpalCall> FindCallWithLock(
00203 const PString & token,
00204 PSafetyMode mode = PSafeReadWrite
00205 ) { return activeCalls.FindWithLock(token, mode); }
00206
00214 virtual PBoolean ClearCall(
00215 const PString & token,
00216 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00217 PSyncPoint * sync = NULL
00218 );
00219
00227 virtual PBoolean ClearCallSynchronous(
00228 const PString & token,
00229 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser
00230 );
00231
00237 virtual void ClearAllCalls(
00238 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00239 PBoolean wait = PTrue
00240 );
00241
00255 virtual void OnClearedCall(
00256 OpalCall & call
00257 );
00258
00267 virtual OpalCall * CreateCall(
00268 void * userData
00269 );
00270 virtual OpalCall * CreateCall();
00271 OpalCall * InternalCreateCall();
00272
00281 virtual void DestroyCall(
00282 OpalCall * call
00283 );
00284
00288 PString GetNextCallToken();
00290
00327 virtual PBoolean MakeConnection(
00328 OpalCall & call,
00329 const PString & party,
00330 void * userData = NULL,
00331 unsigned int options = 0,
00332 OpalConnection::StringOptions * stringOptions = NULL
00333 );
00334
00361 virtual PBoolean OnIncomingConnection(
00362 OpalConnection & connection,
00363 unsigned options,
00364 OpalConnection::StringOptions * stringOptions
00365 );
00366 virtual PBoolean OnIncomingConnection(
00367 OpalConnection & connection,
00368 unsigned options
00369 );
00370 virtual PBoolean OnIncomingConnection(
00371 OpalConnection & connection
00372 );
00373
00380 virtual bool OnRouteConnection(
00381 PStringSet & routesTried,
00382 const PString & a_party,
00383 const PString & b_party,
00384 OpalCall & call,
00385 unsigned options,
00386 OpalConnection::StringOptions * stringOptions
00387 );
00388
00404 virtual void OnProceeding(
00405 OpalConnection & connection
00406 );
00407
00424 virtual void OnAlerting(
00425 OpalConnection & connection
00426 );
00427
00428 virtual OpalConnection::AnswerCallResponse
00429 OnAnswerCall(OpalConnection & connection,
00430 const PString & caller
00431 );
00432
00444 virtual void OnConnected(
00445 OpalConnection & connection
00446 );
00447
00461 virtual void OnEstablished(
00462 OpalConnection & connection
00463 );
00464
00480 virtual void OnReleased(
00481 OpalConnection & connection
00482 );
00483
00490 virtual void OnHold(
00491 OpalConnection & connection,
00492 bool fromRemote,
00493 bool onHold
00494 );
00495 virtual void OnHold(OpalConnection & connection);
00496
00501 virtual PBoolean OnForwarded(
00502 OpalConnection & connection,
00503 const PString & remoteParty
00504 );
00506
00518 virtual void AdjustMediaFormats(
00519 const OpalConnection & connection,
00520 OpalMediaFormatList & mediaFormats
00521 ) const;
00522
00525 virtual PBoolean IsMediaBypassPossible(
00526 const OpalConnection & source,
00527 const OpalConnection & destination,
00528 unsigned sessionID
00529 ) const;
00530
00546 virtual PBoolean OnOpenMediaStream(
00547 OpalConnection & connection,
00548 OpalMediaStream & stream
00549 );
00550
00558 virtual void OnRTPStatistics(
00559 const OpalConnection & connection,
00560 const RTP_Session & session
00561 );
00562
00567 virtual void OnClosedMediaStream(
00568 const OpalMediaStream & stream
00569 );
00570
00571 #if OPAL_VIDEO
00572
00577 virtual void AddVideoMediaFormats(
00578 OpalMediaFormatList & mediaFormats,
00579 const OpalConnection * connection = NULL
00580 ) const;
00581
00584 virtual PBoolean CreateVideoInputDevice(
00585 const OpalConnection & connection,
00586 const OpalMediaFormat & mediaFormat,
00587 PVideoInputDevice * & device,
00588 PBoolean & autoDelete
00589 );
00590
00594 virtual PBoolean CreateVideoOutputDevice(
00595 const OpalConnection & connection,
00596 const OpalMediaFormat & mediaFormat,
00597 PBoolean preview,
00598 PVideoOutputDevice * & device,
00599 PBoolean & autoDelete
00600 );
00601 #endif
00602
00610 virtual OpalMediaPatch * CreateMediaPatch(
00611 OpalMediaStream & source,
00612 PBoolean requiresPatchThread = PTrue
00613 );
00614
00619 virtual void DestroyMediaPatch(
00620 OpalMediaPatch * patch
00621 );
00622
00630 virtual PBoolean OnStartMediaPatch(
00631 const OpalMediaPatch & patch
00632 );
00634
00642 virtual void OnUserInputString(
00643 OpalConnection & connection,
00644 const PString & value
00645 );
00646
00653 virtual void OnUserInputTone(
00654 OpalConnection & connection,
00655 char tone,
00656 int duration
00657 );
00658
00661 virtual PString ReadUserInput(
00662 OpalConnection & connection,
00663 const char * terminators = "#\r\n",
00664 unsigned lastDigitTimeout = 4,
00665 unsigned firstDigitTimeout = 30
00666 );
00668
00671 enum MessageWaitingType {
00672 NoMessageWaiting,
00673 VoiceMessageWaiting,
00674 FaxMessageWaiting,
00675 PagerMessageWaiting,
00676 MultimediaMessageWaiting,
00677 TextMessageWaiting,
00678 NumMessageWaitingTypes
00679 };
00680
00683 virtual void OnMWIReceived(
00684 const PString & party,
00685 MessageWaitingType type,
00686 const PString & extraInfo
00687 );
00688
00689
00690 class RouteEntry : public PObject
00691 {
00692 PCLASSINFO(RouteEntry, PObject);
00693 public:
00694 RouteEntry(const PString & pat, const PString & dest);
00695 void PrintOn(ostream & strm) const;
00696 PString pattern;
00697 PString destination;
00698 PRegularExpression regex;
00699 };
00700 PARRAY(RouteTable, RouteEntry);
00701
00812 virtual PBoolean AddRouteEntry(
00813 const PString & spec
00814 );
00815
00822 PBoolean SetRouteTable(
00823 const PStringArray & specs
00824 );
00825
00830 void SetRouteTable(
00831 const RouteTable & table
00832 );
00833
00836 const RouteTable & GetRouteTable() const { return routeTable; }
00837
00845 virtual PString ApplyRouteTable(
00846 const PString & source,
00847 const PString & destination,
00848 PINDEX & entry
00849 );
00851
00856 const OpalProductInfo & GetProductInfo() const { return productInfo; }
00857
00860 void SetProductInfo(
00861 const OpalProductInfo & info,
00862 bool updateAll = true
00863 );
00864
00867 const PString & GetDefaultUserName() const { return defaultUserName; }
00868
00871 void SetDefaultUserName(
00872 const PString & name,
00873 bool updateAll = true
00874 );
00875
00878 const PString & GetDefaultDisplayName() const { return defaultDisplayName; }
00879
00882 void SetDefaultDisplayName(
00883 const PString & name,
00884 bool updateAll = true
00885 );
00886
00887 #if OPAL_VIDEO
00888
00889
00890
00891
00892
00893
00894
00897 bool CanAutoStartReceiveVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Receive) != 0; }
00898
00901 void SetAutoStartReceiveVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(CanAutoStartTransmitVideo() ? can ? OpalMediaType::ReceiveTransmit : OpalMediaType::Transmit : can ? OpalMediaType::Receive : OpalMediaType::OfferInactive); }
00902
00905 bool CanAutoStartTransmitVideo() const { return (OpalMediaType::Video().GetAutoStart()&OpalMediaType::Transmit) != 0; }
00906
00909 void SetAutoStartTransmitVideo(bool can) { OpalMediaType::Video().GetDefinition()->SetAutoStart(CanAutoStartReceiveVideo() ? can ? OpalMediaType::ReceiveTransmit : OpalMediaType::Receive : can ? OpalMediaType::Transmit : OpalMediaType::OfferInactive); }
00910
00911 #endif
00912
00919 virtual PBoolean IsLocalAddress(
00920 const PIPSocket::Address & remoteAddress
00921 ) const;
00922
00940 virtual PBoolean IsRTPNATEnabled(
00941 OpalConnection & connection,
00942 const PIPSocket::Address & localAddr,
00943 const PIPSocket::Address & peerAddr,
00944 const PIPSocket::Address & signalAddr,
00945 PBoolean incoming
00946 );
00947
00954 virtual PBoolean TranslateIPAddress(
00955 PIPSocket::Address & localAddress,
00956 const PIPSocket::Address & remoteAddress
00957 );
00958
00961 const PString & GetTranslationHost() const { return translationHost; }
00962
00965 bool SetTranslationHost(
00966 const PString & host
00967 );
00968
00971 const PIPSocket::Address & GetTranslationAddress() const { return translationAddress; }
00972
00975 void SetTranslationAddress(
00976 const PIPSocket::Address & address
00977 );
00978
00984 virtual PNatMethod * GetNatMethod(
00985 const PIPSocket::Address & remoteAddress = PIPSocket::GetDefaultIpAny()
00986 ) const;
00987
00992 PSTUNClient::NatTypes SetSTUNServer(
00993 const PString & server
00994 );
00995
00998 const PString & GetSTUNServer() const { return stunServer; }
00999
01002 PSTUNClient * GetSTUNClient() const { return stun; }
01003
01006 WORD GetTCPPortBase() const { return tcpPorts.base; }
01007
01010 WORD GetTCPPortMax() const { return tcpPorts.max; }
01011
01014 void SetTCPPorts(unsigned tcpBase, unsigned tcpMax);
01015
01018 WORD GetNextTCPPort();
01019
01022 WORD GetUDPPortBase() const { return udpPorts.base; }
01023
01026 WORD GetUDPPortMax() const { return udpPorts.max; }
01027
01030 void SetUDPPorts(unsigned udpBase, unsigned udpMax);
01031
01034 WORD GetNextUDPPort();
01035
01038 WORD GetRtpIpPortBase() const { return rtpIpPorts.base; }
01039
01042 WORD GetRtpIpPortMax() const { return rtpIpPorts.max; }
01043
01046 void SetRtpIpPorts(unsigned udpBase, unsigned udpMax);
01047
01050 WORD GetRtpIpPortPair();
01051
01054 BYTE GetRtpIpTypeofService() const { return rtpIpTypeofService; }
01055
01058 void SetRtpIpTypeofService(unsigned tos) { rtpIpTypeofService = (BYTE)tos; }
01059
01064 PINDEX GetMaxRtpPayloadSize() const { return rtpPayloadSizeMax; }
01065
01070 void SetMaxRtpPayloadSize(
01071 PINDEX size,
01072 bool mtu = false
01073 ) { rtpPayloadSizeMax = size - (mtu ? (20+16+12) : 0); }
01074
01078 unsigned GetMinAudioJitterDelay() const { return minAudioJitterDelay; }
01079
01083 unsigned GetMaxAudioJitterDelay() const { return maxAudioJitterDelay; }
01084
01094 void SetAudioJitterDelay(
01095 unsigned minDelay,
01096 unsigned maxDelay
01097 );
01098
01101 const PStringArray & GetMediaFormatOrder() const { return mediaFormatOrder; }
01102
01105 void SetMediaFormatOrder(
01106 const PStringArray & order
01107 );
01108
01111 const PStringArray & GetMediaFormatMask() const { return mediaFormatMask; }
01112
01115 void SetMediaFormatMask(
01116 const PStringArray & mask
01117 );
01118
01121 virtual void SetSilenceDetectParams(
01122 const OpalSilenceDetector::Params & params
01123 ) { silenceDetectParams = params; }
01124
01127 const OpalSilenceDetector::Params & GetSilenceDetectParams() const { return silenceDetectParams; }
01128
01131 virtual void SetEchoCancelParams(
01132 const OpalEchoCanceler::Params & params
01133 ) { echoCancelParams = params; }
01134
01137 const OpalEchoCanceler::Params & GetEchoCancelParams() const { return echoCancelParams; }
01138
01139 #if OPAL_VIDEO
01140
01148 virtual PBoolean SetVideoInputDevice(
01149 const PVideoDevice::OpenArgs & deviceArgs
01150 );
01151
01155 const PVideoDevice::OpenArgs & GetVideoInputDevice() const { return videoInputDevice; }
01156
01164 virtual PBoolean SetVideoPreviewDevice(
01165 const PVideoDevice::OpenArgs & deviceArgs
01166 );
01167
01171 const PVideoDevice::OpenArgs & GetVideoPreviewDevice() const { return videoPreviewDevice; }
01172
01180 virtual PBoolean SetVideoOutputDevice(
01181 const PVideoDevice::OpenArgs & deviceArgs
01182 );
01183
01187 const PVideoDevice::OpenArgs & GetVideoOutputDevice() const { return videoOutputDevice; }
01188
01189 #endif
01190
01191 PBoolean DetectInBandDTMFDisabled() const
01192 { return disableDetectInBandDTMF; }
01193
01196 void DisableDetectInBandDTMF(
01197 PBoolean mode
01198 ) { disableDetectInBandDTMF = mode; }
01199
01202 const PTimeInterval & GetNoMediaTimeout() const { return noMediaTimeout; }
01203
01206 PBoolean SetNoMediaTimeout(
01207 const PTimeInterval & newInterval
01208 );
01209
01212 const PString & GetDefaultILSServer() const { return ilsServer; }
01213
01216 void SetDefaultILSServer(
01217 const PString & server
01218 ) { ilsServer = server; }
01220
01221
01222 void GarbageCollection();
01223
01229 virtual void OnNewConnection(
01230 OpalConnection & connection
01231 );
01232
01233 OpalRecordManager & GetRecordManager() const
01234 { return *m_recordManager; }
01235
01244 virtual PBoolean StartRecording(
01245 const PString & callToken,
01246 const PFilePath & filename,
01247 bool mono = false
01248 );
01249
01252 virtual bool IsRecording(
01253 const PString & callToken
01254 );
01255
01260 virtual bool StopRecording(
01261 const PString & callToken
01262 );
01263
01264 #ifdef OPAL_ZRTP
01265 virtual bool GetZRTPEnabled() const;
01266 #endif
01267
01268 virtual void AddIMMediaFormats(
01269 OpalMediaFormatList & mediaFormats,
01270 const OpalConnection * connection = NULL
01271 ) const;
01272
01273 virtual void OnApplyStringOptions(
01274 OpalConnection & conn,
01275 OpalConnection::StringOptions & stringOptions
01276 );
01277
01278 protected:
01279
01280 OpalProductInfo productInfo;
01281
01282 PString defaultUserName;
01283 PString defaultDisplayName;
01284
01285 BYTE rtpIpTypeofService;
01286 PINDEX rtpPayloadSizeMax;
01287 unsigned minAudioJitterDelay;
01288 unsigned maxAudioJitterDelay;
01289 PStringArray mediaFormatOrder;
01290 PStringArray mediaFormatMask;
01291 PBoolean disableDetectInBandDTMF;
01292 PTimeInterval noMediaTimeout;
01293 PString ilsServer;
01294
01295 OpalSilenceDetector::Params silenceDetectParams;
01296 OpalEchoCanceler::Params echoCancelParams;
01297
01298 #if OPAL_VIDEO
01299 PVideoDevice::OpenArgs videoInputDevice;
01300 PVideoDevice::OpenArgs videoPreviewDevice;
01301 PVideoDevice::OpenArgs videoOutputDevice;
01302 #endif
01303
01304 struct PortInfo {
01305 void Set(
01306 unsigned base,
01307 unsigned max,
01308 unsigned range,
01309 unsigned dflt
01310 );
01311 WORD GetNext(
01312 unsigned increment
01313 );
01314
01315 PMutex mutex;
01316 WORD base;
01317 WORD max;
01318 WORD current;
01319 } tcpPorts, udpPorts, rtpIpPorts;
01320
01321 class InterfaceMonitor : public PInterfaceMonitorClient
01322 {
01323 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
01324
01325 enum {
01326 OpalManagerInterfaceMonitorClientPriority = 100,
01327 };
01328 public:
01329 InterfaceMonitor(OpalManager & manager);
01330
01331 protected:
01332 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
01333 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
01334
01335 OpalManager & m_manager;
01336 };
01337
01338 PString translationHost;
01339 PIPSocket::Address translationAddress;
01340 PString stunServer;
01341 PSTUNClient * stun;
01342 InterfaceMonitor * interfaceMonitor;
01343
01344 RouteTable routeTable;
01345 PMutex routeTableMutex;
01346
01347
01348 PReadWriteMutex endpointsMutex;
01349 PList<OpalEndPoint> endpointList;
01350 std::map<PString, OpalEndPoint *> endpointMap;
01351
01352 PAtomicInteger lastCallTokenID;
01353
01354 class CallDict : public PSafeDictionary<PString, OpalCall>
01355 {
01356 public:
01357 CallDict(OpalManager & mgr) : manager(mgr) { }
01358 virtual void DeleteObject(PObject * object) const;
01359 OpalManager & manager;
01360 } activeCalls;
01361
01362 PAtomicInteger m_clearingAllCallsCount;
01363 PMutex m_clearingAllCallsMutex;
01364 PSyncPoint m_allCallsCleared;
01365 void InternalClearAllCalls(OpalConnection::CallEndReason reason, bool wait, bool first);
01366
01367 PThread * garbageCollector;
01368 PSyncPoint garbageCollectExit;
01369 PDECLARE_NOTIFIER(PThread, OpalManager, GarbageMain);
01370
01371 #ifdef OPAL_ZRTP
01372 bool zrtpEnabled;
01373 #endif
01374
01375 OpalRecordManager * m_recordManager;
01376
01377 friend OpalCall::OpalCall(OpalManager & mgr);
01378 friend void OpalCall::OnReleased(OpalConnection & connection);
01379 };
01380
01381
01382 PString OpalGetVersion();
01383 unsigned OpalGetMajorVersion();
01384 unsigned OpalGetMinorVersion();
01385 unsigned OpalGetBuildNumber();
01386
01387
01388 #endif // OPAL_OPAL_MANAGER_H
01389
01390
01391