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