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_MANAGER_H
00033 #define __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 class OpalH224Handler;
00056 class OpalH281Handler;
00057
00058 typedef PFactory<OpalEndPoint> OpalEndpointFactory;
00059
00076 class OpalManager : public PObject
00077 {
00078 PCLASSINFO(OpalManager, PObject);
00079 public:
00084 OpalManager();
00085
00090 ~OpalManager();
00092
00102 void AttachEndPoint(
00103 OpalEndPoint * endpoint,
00104 const PString & prefix = PString::Empty(),
00105 bool autoDelete = true
00106 );
00107
00111 void DetachEndPoint(
00112 const PString & prefix
00113 );
00114 void DetachEndPoint(
00115 OpalEndPoint * endpoint
00116 );
00117
00120 OpalEndPoint * FindEndPoint(
00121 const PString & prefix
00122 );
00123
00126 PList<OpalEndPoint> GetEndPoints(
00127 bool unique = false
00128 ) const;
00129
00135 void ShutDownEndpoints();
00137
00159 virtual PBoolean SetUpCall(
00160 const PString & partyA,
00161 const PString & partyB,
00162 PString & token,
00163 void * userData = NULL,
00164 unsigned options = 0,
00165 OpalConnection::StringOptions * stringOptions = NULL
00166 );
00167
00176 virtual void OnEstablishedCall(
00177 OpalCall & call
00178 );
00179
00185 virtual PBoolean HasCall(
00186 const PString & token
00187 ) { return activeCalls.FindWithLock(token, PSafeReference) != NULL; }
00188
00195 virtual PBoolean IsCallEstablished(
00196 const PString & token
00197 );
00198
00207 PSafePtr<OpalCall> FindCallWithLock(
00208 const PString & token,
00209 PSafetyMode mode = PSafeReadWrite
00210 ) { return activeCalls.FindWithLock(token, mode); }
00211
00219 virtual PBoolean ClearCall(
00220 const PString & token,
00221 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00222 PSyncPoint * sync = NULL
00223 );
00224
00232 virtual PBoolean ClearCallSynchronous(
00233 const PString & token,
00234 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser
00235 );
00236
00242 virtual void ClearAllCalls(
00243 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser,
00244 PBoolean wait = PTrue
00245 );
00246
00260 virtual void OnClearedCall(
00261 OpalCall & call
00262 );
00263
00272 virtual OpalCall * CreateCall(
00273 void * userData
00274 );
00275 virtual OpalCall * CreateCall();
00276 OpalCall * InternalCreateCall();
00277
00286 virtual void DestroyCall(
00287 OpalCall * call
00288 );
00289
00293 PString GetNextCallToken();
00295
00332 virtual PBoolean MakeConnection(
00333 OpalCall & call,
00334 const PString & party,
00335 void * userData = NULL,
00336 unsigned int options = 0,
00337 OpalConnection::StringOptions * stringOptions = NULL
00338 );
00339
00366 virtual PBoolean OnIncomingConnection(
00367 OpalConnection & connection,
00368 unsigned options,
00369 OpalConnection::StringOptions * stringOptions
00370 );
00371 virtual PBoolean OnIncomingConnection(
00372 OpalConnection & connection,
00373 unsigned options
00374 );
00375 virtual PBoolean OnIncomingConnection(
00376 OpalConnection & connection
00377 );
00378
00385 virtual PString OnRouteConnection(
00386 OpalConnection & connection
00387 );
00388
00405 virtual void OnAlerting(
00406 OpalConnection & connection
00407 );
00408
00409 virtual OpalConnection::AnswerCallResponse
00410 OnAnswerCall(OpalConnection & connection,
00411 const PString & caller
00412 );
00413
00425 virtual void OnConnected(
00426 OpalConnection & connection
00427 );
00428
00442 virtual void OnEstablished(
00443 OpalConnection & connection
00444 );
00445
00461 virtual void OnReleased(
00462 OpalConnection & connection
00463 );
00464
00471 virtual void OnHold(
00472 OpalConnection & connection
00473 );
00474
00479 virtual PBoolean OnForwarded(
00480 OpalConnection & connection,
00481 const PString & remoteParty
00482 );
00484
00496 virtual void AdjustMediaFormats(
00497 const OpalConnection & connection,
00498 OpalMediaFormatList & mediaFormats
00499 ) const;
00500
00503 virtual PBoolean IsMediaBypassPossible(
00504 const OpalConnection & source,
00505 const OpalConnection & destination,
00506 unsigned sessionID
00507 ) const;
00508
00524 virtual PBoolean OnOpenMediaStream(
00525 OpalConnection & connection,
00526 OpalMediaStream & stream
00527 );
00528
00536 virtual void OnRTPStatistics(
00537 const OpalConnection & connection,
00538 const RTP_Session & session
00539 );
00540
00545 virtual void OnClosedMediaStream(
00546 const OpalMediaStream & stream
00547 );
00548
00549 #if OPAL_VIDEO
00550
00555 virtual void AddVideoMediaFormats(
00556 OpalMediaFormatList & mediaFormats,
00557 const OpalConnection * connection = NULL
00558 ) const;
00559
00562 virtual PBoolean CreateVideoInputDevice(
00563 const OpalConnection & connection,
00564 const OpalMediaFormat & mediaFormat,
00565 PVideoInputDevice * & device,
00566 PBoolean & autoDelete
00567 );
00568
00572 virtual PBoolean CreateVideoOutputDevice(
00573 const OpalConnection & connection,
00574 const OpalMediaFormat & mediaFormat,
00575 PBoolean preview,
00576 PVideoOutputDevice * & device,
00577 PBoolean & autoDelete
00578 );
00579 #endif
00580
00588 virtual OpalMediaPatch * CreateMediaPatch(
00589 OpalMediaStream & source,
00590 PBoolean requiresPatchThread = PTrue
00591 );
00592
00597 virtual void DestroyMediaPatch(
00598 OpalMediaPatch * patch
00599 );
00600
00608 virtual PBoolean OnStartMediaPatch(
00609 const OpalMediaPatch & patch
00610 );
00612
00620 virtual void OnUserInputString(
00621 OpalConnection & connection,
00622 const PString & value
00623 );
00624
00631 virtual void OnUserInputTone(
00632 OpalConnection & connection,
00633 char tone,
00634 int duration
00635 );
00636
00639 virtual PString ReadUserInput(
00640 OpalConnection & connection,
00641 const char * terminators = "#\r\n",
00642 unsigned lastDigitTimeout = 4,
00643 unsigned firstDigitTimeout = 30
00644 );
00646
00649 #if OPAL_T120DATA
00650
00660 virtual OpalT120Protocol * CreateT120ProtocolHandler(
00661 const OpalConnection & connection
00662 ) const;
00663 #endif
00664
00665 #if OPAL_T38FAX
00666
00676 virtual OpalT38Protocol * CreateT38ProtocolHandler(
00677 const OpalConnection & connection
00678 ) const;
00679
00680 #endif
00681
00682 #if OPAL_H224
00683
00692 virtual OpalH224Handler * CreateH224ProtocolHandler(
00693 OpalConnection & connection, unsigned sessionID
00694 ) const;
00695
00705 virtual OpalH281Handler * CreateH281ProtocolHandler(
00706 OpalH224Handler & h224Handler
00707 ) const;
00708 #endif
00709
00710 class RouteEntry : public PObject
00711 {
00712 PCLASSINFO(RouteEntry, PObject);
00713 public:
00714 RouteEntry(const PString & pat, const PString & dest);
00715 void PrintOn(ostream & strm) const;
00716 PString pattern;
00717 PString destination;
00718 PRegularExpression regex;
00719 };
00720 PARRAY(RouteTable, RouteEntry);
00721
00828 virtual PBoolean AddRouteEntry(
00829 const PString & spec
00830 );
00831
00838 PBoolean SetRouteTable(
00839 const PStringArray & specs
00840 );
00841
00846 void SetRouteTable(
00847 const RouteTable & table
00848 );
00849
00852 const RouteTable & GetRouteTable() const { return routeTable; }
00853
00861 virtual PString ApplyRouteTable(
00862 const PString & source,
00863 const PString & destination,
00864 PINDEX & entry
00865 );
00867
00872 const OpalProductInfo & GetProductInfo() const { return productInfo; }
00873
00876 void SetProductInfo(
00877 const OpalProductInfo & info
00878 ) { productInfo = info; }
00879
00882 const PString & GetDefaultUserName() const { return defaultUserName; }
00883
00886 void SetDefaultUserName(
00887 const PString & name
00888 ) { defaultUserName = name; }
00889
00892 const PString & GetDefaultDisplayName() const { return defaultDisplayName; }
00893
00896 void SetDefaultDisplayName(
00897 const PString & name
00898 ) { defaultDisplayName = name; }
00899
00900 #if OPAL_VIDEO
00901
00904 PBoolean CanAutoStartReceiveVideo() const { return autoStartReceiveVideo; }
00905
00908 void SetAutoStartReceiveVideo(PBoolean can) { autoStartReceiveVideo = can; }
00909
00912 PBoolean CanAutoStartTransmitVideo() const { return autoStartTransmitVideo; }
00913
00916 void SetAutoStartTransmitVideo(PBoolean can) { autoStartTransmitVideo = can; }
00917
00918 #endif
00919
00926 virtual PBoolean IsLocalAddress(
00927 const PIPSocket::Address & remoteAddress
00928 ) const;
00929
00947 virtual PBoolean IsRTPNATEnabled(
00948 OpalConnection & connection,
00949 const PIPSocket::Address & localAddr,
00950 const PIPSocket::Address & peerAddr,
00951 const PIPSocket::Address & signalAddr,
00952 PBoolean incoming
00953 );
00954
00961 virtual PBoolean TranslateIPAddress(
00962 PIPSocket::Address & localAddress,
00963 const PIPSocket::Address & remoteAddress
00964 );
00965
00968 const PString & GetTranslationHost() const { return translationHost; }
00969
00972 bool SetTranslationHost(
00973 const PString & host
00974 );
00975
00978 const PIPSocket::Address & GetTranslationAddress() const { return translationAddress; }
00979
00982 void SetTranslationAddress(
00983 const PIPSocket::Address & address
00984 );
00985
00991 PSTUNClient * GetSTUN(
00992 const PIPSocket::Address & address = 0
00993 ) const;
00994
00999 PSTUNClient::NatTypes SetSTUNServer(
01000 const PString & server
01001 );
01002
01005 const PString & GetSTUNServer() const { return stunServer; }
01006
01009 WORD GetTCPPortBase() const { return tcpPorts.base; }
01010
01013 WORD GetTCPPortMax() const { return tcpPorts.max; }
01014
01017 void SetTCPPorts(unsigned tcpBase, unsigned tcpMax);
01018
01021 WORD GetNextTCPPort();
01022
01025 WORD GetUDPPortBase() const { return udpPorts.base; }
01026
01029 WORD GetUDPPortMax() const { return udpPorts.max; }
01030
01033 void SetUDPPorts(unsigned udpBase, unsigned udpMax);
01034
01037 WORD GetNextUDPPort();
01038
01041 WORD GetRtpIpPortBase() const { return rtpIpPorts.base; }
01042
01045 WORD GetRtpIpPortMax() const { return rtpIpPorts.max; }
01046
01049 void SetRtpIpPorts(unsigned udpBase, unsigned udpMax);
01050
01053 WORD GetRtpIpPortPair();
01054
01057 BYTE GetRtpIpTypeofService() const { return rtpIpTypeofService; }
01058
01061 void SetRtpIpTypeofService(unsigned tos) { rtpIpTypeofService = (BYTE)tos; }
01062
01067 PINDEX GetMaxRtpPayloadSize() const { return rtpPayloadSizeMax; }
01068
01073 void SetMaxRtpPayloadSize(
01074 PINDEX size,
01075 bool mtu = false
01076 ) { rtpPayloadSizeMax = size - (mtu ? (20+16+12) : 0); }
01077
01081 unsigned GetMinAudioJitterDelay() const { return minAudioJitterDelay; }
01082
01086 unsigned GetMaxAudioJitterDelay() const { return maxAudioJitterDelay; }
01087
01090 void SetAudioJitterDelay(
01091 unsigned minDelay,
01092 unsigned maxDelay
01093 );
01094
01097 const PStringArray & GetMediaFormatOrder() const { return mediaFormatOrder; }
01098
01101 void SetMediaFormatOrder(const PStringArray & order) { mediaFormatOrder = order; }
01102
01105 const PStringArray & GetMediaFormatMask() const { return mediaFormatMask; }
01106
01109 void SetMediaFormatMask(const PStringArray & mask) { mediaFormatMask = mask; }
01110
01113 virtual void SetSilenceDetectParams(
01114 const OpalSilenceDetector::Params & params
01115 ) { silenceDetectParams = params; }
01116
01119 const OpalSilenceDetector::Params & GetSilenceDetectParams() const { return silenceDetectParams; }
01120
01123 virtual void SetEchoCancelParams(
01124 const OpalEchoCanceler::Params & params
01125 ) { echoCancelParams = params; }
01126
01129 const OpalEchoCanceler::Params & GetEchoCancelParams() const { return echoCancelParams; }
01130
01131 #if OPAL_VIDEO
01132
01140 virtual PBoolean SetVideoInputDevice(
01141 const PVideoDevice::OpenArgs & deviceArgs
01142 );
01143
01147 const PVideoDevice::OpenArgs & GetVideoInputDevice() const { return videoInputDevice; }
01148
01156 virtual PBoolean SetVideoPreviewDevice(
01157 const PVideoDevice::OpenArgs & deviceArgs
01158 );
01159
01163 const PVideoDevice::OpenArgs & GetVideoPreviewDevice() const { return videoPreviewDevice; }
01164
01172 virtual PBoolean SetVideoOutputDevice(
01173 const PVideoDevice::OpenArgs & deviceArgs
01174 );
01175
01179 const PVideoDevice::OpenArgs & GetVideoOutputDevice() const { return videoOutputDevice; }
01180
01181 #endif
01182
01183 PBoolean DetectInBandDTMFDisabled() const
01184 { return disableDetectInBandDTMF; }
01185
01188 void DisableDetectInBandDTMF(
01189 PBoolean mode
01190 ) { disableDetectInBandDTMF = mode; }
01191
01194 const PTimeInterval & GetNoMediaTimeout() const { return noMediaTimeout; }
01195
01198 PBoolean SetNoMediaTimeout(
01199 const PTimeInterval & newInterval
01200 );
01201
01204 const PString & GetDefaultILSServer() const { return ilsServer; }
01205
01208 void SetDefaultILSServer(
01209 const PString & server
01210 ) { ilsServer = server; }
01212
01213
01214 void GarbageCollection();
01215
01221 virtual void OnNewConnection(
01222 OpalConnection & connection
01223 );
01224
01225 virtual void SetDefaultSecurityMode(const PString & v)
01226 { defaultSecurityMode = v; }
01227
01228 virtual PString GetDefaultSecurityMode() const
01229 { return defaultSecurityMode; }
01230
01231 virtual PBoolean UseRTPAggregation() const;
01232
01233 OpalRecordManager & GetRecordManager()
01234 { return recordManager; }
01235
01236 virtual PBoolean StartRecording(const PString & callToken, const PFilePath & fn);
01237 virtual void StopRecording(const PString & callToken);
01238
01239 protected:
01240
01241 OpalProductInfo productInfo;
01242
01243 PString defaultUserName;
01244 PString defaultDisplayName;
01245
01246 #if OPAL_VIDEO
01247 PBoolean autoStartReceiveVideo;
01248 PBoolean autoStartTransmitVideo;
01249 #endif
01250
01251 BYTE rtpIpTypeofService;
01252 PINDEX rtpPayloadSizeMax;
01253 unsigned minAudioJitterDelay;
01254 unsigned maxAudioJitterDelay;
01255 PStringArray mediaFormatOrder;
01256 PStringArray mediaFormatMask;
01257 PBoolean disableDetectInBandDTMF;
01258 PTimeInterval noMediaTimeout;
01259 PString ilsServer;
01260
01261 OpalSilenceDetector::Params silenceDetectParams;
01262 OpalEchoCanceler::Params echoCancelParams;
01263
01264 #if OPAL_VIDEO
01265 PVideoDevice::OpenArgs videoInputDevice;
01266 PVideoDevice::OpenArgs videoPreviewDevice;
01267 PVideoDevice::OpenArgs videoOutputDevice;
01268 #endif
01269
01270 struct PortInfo {
01271 void Set(
01272 unsigned base,
01273 unsigned max,
01274 unsigned range,
01275 unsigned dflt
01276 );
01277 WORD GetNext(
01278 unsigned increment
01279 );
01280
01281 PMutex mutex;
01282 WORD base;
01283 WORD max;
01284 WORD current;
01285 } tcpPorts, udpPorts, rtpIpPorts;
01286
01287 class InterfaceMonitor : public PInterfaceMonitorClient
01288 {
01289 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
01290
01291 enum {
01292 OpalManagerInterfaceMonitorClientPriority = 100,
01293 };
01294 public:
01295 InterfaceMonitor(PSTUNClient * stun);
01296
01297 protected:
01298 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
01299 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
01300
01301 PSTUNClient * stun;
01302 };
01303
01304 PString translationHost;
01305 PIPSocket::Address translationAddress;
01306 PString stunServer;
01307 PSTUNClient * stun;
01308 InterfaceMonitor * interfaceMonitor;
01309
01310 RouteTable routeTable;
01311 PMutex routeTableMutex;
01312
01313
01314 PReadWriteMutex endpointsMutex;
01315
01316 PAtomicInteger lastCallTokenID;
01317
01318 class CallDict : public PSafeDictionary<PString, OpalCall>
01319 {
01320 public:
01321 CallDict(OpalManager & mgr) : manager(mgr) { }
01322 virtual void DeleteObject(PObject * object) const;
01323 OpalManager & manager;
01324 } activeCalls;
01325
01326 PBoolean clearingAllCalls;
01327 PSyncPoint allCallsCleared;
01328 PThread * garbageCollector;
01329 PSyncPoint garbageCollectExit;
01330 PDECLARE_NOTIFIER(PThread, OpalManager, GarbageMain);
01331
01332 PString defaultSecurityMode;
01333
01334 #if OPAL_RTP_AGGREGATE
01335 PBoolean useRTPAggregation;
01336 #endif
01337
01338 OpalRecordManager recordManager;
01339
01340 friend OpalCall::OpalCall(OpalManager & mgr);
01341 friend void OpalCall::OnReleased(OpalConnection & connection);
01342 };
01343
01344
01345 PString OpalGetVersion();
01346 unsigned OpalGetMajorVersion();
01347 unsigned OpalGetMinorVersion();
01348 unsigned OpalGetBuildNumber();
01349
01350
01351 #endif // __OPAL_MANAGER_H
01352
01353
01354