sipep.h

Go to the documentation of this file.
00001 /*
00002  * sipep.h
00003  *
00004  * Session Initiation Protocol endpoint.
00005  *
00006  * Open Phone Abstraction Library (OPAL)
00007  * Formally known as the Open H323 project.
00008  *
00009  * Copyright (c) 2001 Equivalence Pty. Ltd.
00010  *
00011  * The contents of this file are subject to the Mozilla Public License
00012  * Version 1.0 (the "License"); you may not use this file except in
00013  * compliance with the License. You may obtain a copy of the License at
00014  * http://www.mozilla.org/MPL/
00015  *
00016  * Software distributed under the License is distributed on an "AS IS"
00017  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00018  * the License for the specific language governing rights and limitations
00019  * under the License.
00020  *
00021  * The Original Code is Open Phone Abstraction Library.
00022  *
00023  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00024  *
00025  * Contributor(s): ______________________________________.
00026  *
00027  * $Revision: 24764 $
00028  * $Author: rjongbloed $
00029  * $Date: 2010-09-30 01:52:18 -0500 (Thu, 30 Sep 2010) $
00030  */
00031 
00032 #ifndef OPAL_SIP_SIPEP_H
00033 #define OPAL_SIP_SIPEP_H
00034 
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038 
00039 #ifndef _PTLIB_H
00040 #include <ptlib.h>
00041 #endif
00042 
00043 #include <opal/buildopts.h>
00044 
00045 #if OPAL_SIP
00046 
00047 #include <ptclib/threadpool.h>
00048 #include <opal/rtpep.h>
00049 #include <sip/sipcon.h>
00050 #include <sip/sippdu.h>
00051 #include <sip/handlers.h> 
00052 
00053 #if OPAL_HAS_SIPIM
00054 #include <im/sipim.h>
00055 #endif
00056 
00057 class SIPRegisterHandler;
00058 
00059 
00060 //
00061 //  provide flag so applications know if presence is available
00062 //
00063 #define OPAL_HAS_SIP_PRESENCE   1
00064 
00066 
00070 class SIPAuthInfo : public PObject
00071 {
00072   public:
00073     SIPAuthInfo()
00074     { }
00075 
00076     SIPAuthInfo(const PString & u, const PString & p)
00077     { username = u; password = p; }
00078     PString username;
00079     PString password;
00080 };
00081 
00083 
00086 class SIPEndPoint : public OpalRTPEndPoint
00087 {
00088   PCLASSINFO(SIPEndPoint, OpalRTPEndPoint);
00089 
00090   public:
00095     SIPEndPoint(
00096       OpalManager & manager
00097     );
00098 
00101     ~SIPEndPoint();
00103 
00110     virtual void ShutDown();
00111 
00115     virtual PString GetDefaultTransport() const;
00116 
00121     virtual PBoolean NewIncomingConnection(
00122       OpalTransport * transport  
00123     );
00124 
00154     virtual PSafePtr<OpalConnection> MakeConnection(
00155       OpalCall & call,                         
00156       const PString & party,                   
00157       void * userData,                         
00158       unsigned int options,                    
00159       OpalConnection::StringOptions * stringOptions  
00160     );
00161 
00180     virtual void OnReleased(
00181       OpalConnection & connection   
00182     );
00183 
00188     virtual PBoolean GarbageCollection();
00190 
00196     virtual SIPConnection * CreateConnection(
00197       OpalCall & call,                         
00198       const PString & token,                   
00199       void * userData,                         
00200       const SIPURL & destination,              
00201       OpalTransport * transport,               
00202       SIP_PDU * invite,                        
00203       unsigned int options = 0,                
00204       OpalConnection::StringOptions * stringOptions = NULL 
00205 
00206     );
00207     
00210     virtual PBoolean SetupTransfer(
00211       const PString & token,        
00212       const PString & callIdentity, 
00213       const PString & remoteParty,  
00214       void * userData = NULL        
00215     );
00216     
00220     virtual PBoolean ForwardConnection(
00221       SIPConnection & connection,     
00222       const PString & forwardParty    
00223     );
00224 
00235     bool ClearDialogContext(
00236       const PString & descriptor  
00237     );
00238     bool ClearDialogContext(
00239       SIPDialogContext & context  
00240     );
00242   
00245 
00249     OpalTransport * CreateTransport(
00250       const SIPURL & remoteURL,
00251       const PString & localInterface = PString::Empty()
00252     );
00253 
00254     virtual void HandlePDU(
00255       OpalTransport & transport
00256     );
00257 
00260     virtual PBoolean OnReceivedPDU(
00261       OpalTransport & transport,
00262       SIP_PDU * pdu
00263     );
00264 
00267     virtual bool OnReceivedConnectionlessPDU(
00268       OpalTransport & transport, 
00269       SIP_PDU * pdu
00270     );
00271 
00274     virtual void OnReceivedResponse(
00275       SIPTransaction & transaction,
00276       SIP_PDU & response
00277     );
00278 
00281     virtual PBoolean OnReceivedINVITE(
00282       OpalTransport & transport,
00283       SIP_PDU * pdu
00284     );
00285 
00288     virtual PBoolean OnReceivedNOTIFY(
00289       OpalTransport & transport,
00290       SIP_PDU & response
00291     );
00292 
00295     virtual PBoolean OnReceivedREGISTER(
00296       OpalTransport & transport, 
00297       SIP_PDU & pdu
00298     );
00299 
00302     virtual PBoolean OnReceivedSUBSCRIBE(
00303       OpalTransport & transport, 
00304       SIP_PDU & pdu
00305     );
00306 
00309     virtual bool OnReceivedMESSAGE(
00310       OpalTransport & transport,
00311       SIP_PDU & response
00312     );
00313 
00316     virtual bool OnReceivedOPTIONS(
00317       OpalTransport & transport,
00318       SIP_PDU & response
00319     );
00320     
00323     virtual void OnTransactionFailed(
00324       SIPTransaction & transaction
00325     );
00326     
00334     virtual void OnRTPStatistics(
00335       const SIPConnection & connection,  
00336       const RTP_Session & session         
00337     ) const;
00339  
00340 
00348     PSafePtr<SIPConnection> GetSIPConnectionWithLock(
00349       const PString & token,     
00350       PSafetyMode mode = PSafeReadWrite,  
00351       SIP_PDU::StatusCodes * errorCode = NULL 
00352     );
00353 
00354     virtual PBoolean IsAcceptedAddress(const SIPURL & toAddr);
00355 
00356 
00391     bool Register(
00392       const SIPRegister::Params & params, 
00393       PString & aor,                      
00394       bool asynchronous = true            
00395     );
00396 
00398     bool P_DEPRECATED Register(
00399       const PString & host,
00400       const PString & user = PString::Empty(),
00401       const PString & autName = PString::Empty(),
00402       const PString & password = PString::Empty(),
00403       const PString & authRealm = PString::Empty(),
00404       unsigned expire = 0,
00405       const PTimeInterval & minRetryTime = PMaxTimeInterval, 
00406       const PTimeInterval & maxRetryTime = PMaxTimeInterval
00407     );
00408 
00423     PBoolean IsRegistered(
00424       const PString & aor,          
00425       bool includeOffline = false   
00426     );
00427 
00437     bool Unregister(
00438       const PString & aor    
00439     );
00440 
00444     bool UnregisterAll();
00445 
00448     unsigned GetRegistrationsCount() const { return activeSIPHandlers.GetCount(SIP_PDU::Method_REGISTER); }
00449 
00452     PStringList GetRegistrations(
00453       bool includeOffline = false   
00454     ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_REGISTER); }
00455 
00457     struct RegistrationStatus {
00458       SIPRegisterHandler * m_handler;           
00459       PString              m_addressofRecord;   
00460       bool                 m_wasRegistering;    
00461       bool                 m_reRegistering;     
00462       SIP_PDU::StatusCodes m_reason;            
00463       OpalProductInfo      m_productInfo;       
00464       void               * m_userData;          
00465     };
00466 
00469     virtual void OnRegistrationStatus(
00470       const RegistrationStatus & status   
00471     );
00472 
00473     // For backward compatibility
00474     virtual void OnRegistrationStatus(
00475       const PString & aor,
00476       PBoolean wasRegistering,
00477       PBoolean reRegistering,
00478       SIP_PDU::StatusCodes reason
00479     );
00480 
00484     virtual void OnRegistrationFailed(
00485       const PString & aor,
00486       SIP_PDU::StatusCodes reason,
00487       PBoolean wasRegistering
00488     );
00489 
00493     virtual void OnRegistered(
00494       const PString & aor,
00495       PBoolean wasRegistering
00496     );
00497 
00498 
00538     bool Subscribe(
00539       const SIPSubscribe::Params & params, 
00540       PString & token,                     
00541       bool tokenIsAOR = true               
00542     );
00543 
00544     // For backward compatibility
00545     bool Subscribe(
00546       SIPSubscribe::PredefinedPackages eventPackage, 
00547       unsigned expire,                               
00548       const PString & aor                            
00549     );
00550 
00557     bool IsSubscribed(
00558       const PString & aor,           
00559       bool includeOffline = false    
00560     );
00561     bool IsSubscribed(
00562       const PString & eventPackage,  
00563       const PString & aor,           
00564       bool includeOffline = false    
00565     );
00566 
00576     bool Unsubscribe(
00577       const PString & aor          
00578     );
00579     bool Unsubscribe(
00580       SIPSubscribe::PredefinedPackages eventPackage,  
00581       const PString & aor                             
00582     );
00583     bool Unsubscribe(
00584       const PString & eventPackage,  
00585       const PString & aor            
00586     );
00587 
00591     bool UnsubcribeAll(
00592       SIPSubscribe::PredefinedPackages eventPackage  
00593     );
00594     bool UnsubcribeAll(
00595       const PString & eventPackage  
00596     );
00597 
00600     unsigned GetSubscriptionCount(
00601       const SIPSubscribe::EventPackage & eventPackage  
00602     ) { return activeSIPHandlers.GetCount(SIP_PDU::Method_SUBSCRIBE, eventPackage); }
00603 
00606     PStringList GetSubscriptions(
00607       const SIPSubscribe::EventPackage & eventPackage, 
00608       bool includeOffline = false   
00609     ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_REGISTER, eventPackage); }
00610 
00612     typedef SIPSubscribe::SubscriptionStatus SubscriptionStatus;
00613 
00616     virtual void OnSubscriptionStatus(
00617       const SubscriptionStatus & status   
00618     );
00619 
00623     virtual void OnSubscriptionStatus(
00624       const PString & eventPackage, 
00625       const SIPURL & uri,           
00626       bool wasSubscribing,          
00627       bool reSubscribing,           
00628       SIP_PDU::StatusCodes reason   
00629     );
00630 
00631     virtual void OnSubscriptionStatus(
00632       SIPSubscribeHandler & handler, 
00633       const SIPURL & uri,            
00634       bool wasSubscribing,           
00635       bool reSubscribing,            
00636       SIP_PDU::StatusCodes reason    
00637     );
00638 
00641     virtual bool CanNotify(
00642       const PString & eventPackage 
00643     );
00644 
00647     bool Notify(
00648       const SIPURL & targetAddress, 
00649       const PString & eventPackage, 
00650       const PObject & body          
00651     );
00652 
00653 
00656     virtual void OnDialogInfoReceived(
00657       const SIPDialogNotification & info  
00658     );
00659 
00660     void SendNotifyDialogInfo(
00661       const SIPDialogNotification & info  
00662     );
00663 
00664 
00667     virtual PBoolean Message(
00668       const PURL & to, 
00669       const PString & type,
00670       const PString & body,
00671       PURL & from, 
00672       PString & conversationId
00673     );
00674     virtual PBoolean Message(
00675       OpalIM & message
00676     );
00677 
00682     virtual void OnMessageFailed(
00683       const SIPURL & messageUrl,
00684       SIP_PDU::StatusCodes reason
00685     );
00686 
00687 
00690     virtual bool SendOPTIONS(
00691       const SIPOptions::Params & params
00692     );
00693 
00697     virtual void OnOptionsCompleted(
00698       const SIPOptions::Params & params,    
00699       const SIP_PDU & response              
00700     );
00701 
00702 
00706     bool Publish(
00707       const SIPSubscribe::Params & params,
00708       const PString & body,
00709       PString & aor
00710     );
00711     bool Publish(
00712       const PString & to,   
00713       const PString & body, 
00714       unsigned expire = 300 
00715     );
00716 
00719     PStringList GetPublications(
00720       const SIPSubscribe::EventPackage & eventPackage, 
00721       bool includeOffline = false   
00722     ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_PUBLISH, eventPackage); }
00723 
00724 
00728     bool PublishPresence(
00729       const SIPPresenceInfo & info,  
00730       unsigned expire = 300          
00731     );
00732     
00735     virtual void OnPresenceInfoReceived (
00736       const SIPPresenceInfo & info  
00737     );
00738     virtual void OnPresenceInfoReceived (
00739       const PString & identity,
00740       const PString & basic,
00741       const PString & note
00742     );
00743 
00744 
00747     PBoolean Ping(
00748       const PURL & to
00749     );
00750 
00753     SIPConnection::PRACKMode GetDefaultPRACKMode() const { return m_defaultPrackMode; }
00754 
00757     void SetDefaultPRACKMode(SIPConnection::PRACKMode mode) { m_defaultPrackMode = mode; }
00758 
00759     void SetMIMEForm(PBoolean v) { mimeForm = v; }
00760     PBoolean GetMIMEForm() const { return mimeForm; }
00761 
00762     void SetMaxRetries(unsigned r) { maxRetries = r; }
00763     unsigned GetMaxRetries() const { return maxRetries; }
00764 
00765     void SetRetryTimeouts(
00766       const PTimeInterval & t1,
00767       const PTimeInterval & t2
00768     ) { retryTimeoutMin = t1; retryTimeoutMax = t2; }
00769     const PTimeInterval & GetRetryTimeoutMin() const { return retryTimeoutMin; }
00770     const PTimeInterval & GetRetryTimeoutMax() const { return retryTimeoutMax; }
00771 
00772     void SetNonInviteTimeout(
00773       const PTimeInterval & t
00774     ) { nonInviteTimeout = t; }
00775     const PTimeInterval & GetNonInviteTimeout() const { return nonInviteTimeout; }
00776 
00777     void SetPduCleanUpTimeout(
00778       const PTimeInterval & t
00779     ) { pduCleanUpTimeout = t; }
00780     const PTimeInterval & GetPduCleanUpTimeout() const { return pduCleanUpTimeout; }
00781 
00782     void SetInviteTimeout(
00783       const PTimeInterval & t
00784     ) { inviteTimeout = t; }
00785     const PTimeInterval & GetInviteTimeout() const { return inviteTimeout; }
00786 
00787     void SetProgressTimeout(
00788       const PTimeInterval & t
00789     ) { m_progressTimeout = t; }
00790     const PTimeInterval & GetProgressTimeout() const { return m_progressTimeout; }
00791 
00792     void SetAckTimeout(
00793       const PTimeInterval & t
00794     ) { ackTimeout = t; }
00795     const PTimeInterval & GetAckTimeout() const { return ackTimeout; }
00796 
00797     void SetRegistrarTimeToLive(
00798       const PTimeInterval & t
00799     ) { registrarTimeToLive = t; }
00800     const PTimeInterval & GetRegistrarTimeToLive() const { return registrarTimeToLive; }
00801     
00802     void SetNotifierTimeToLive(
00803       const PTimeInterval & t
00804     ) { notifierTimeToLive = t; }
00805     const PTimeInterval & GetNotifierTimeToLive() const { return notifierTimeToLive; }
00806     
00807     void SetNATBindingTimeout(
00808       const PTimeInterval & t
00809     ) { natBindingTimeout = t; natBindingTimer.RunContinuous (natBindingTimeout); }
00810     const PTimeInterval & GetNATBindingTimeout() const { return natBindingTimeout; }
00811 
00812     void AddTransaction(
00813       SIPTransaction * transaction
00814     ) { transactions.SetAt(transaction->GetTransactionID(), transaction); }
00815 
00816     PSafePtr<SIPTransaction> GetTransaction(const PString & transactionID, PSafetyMode mode = PSafeReadWrite)
00817     { return transactions.FindWithLock(transactionID, mode); }
00818     
00821     unsigned GetNextCSeq() { return ++lastSentCSeq; }
00822 
00825     bool GetAuthentication(const PString & authRealm, PString & user, PString & password); 
00826     
00829     virtual SIPURL GetRegisteredProxy(const SIPURL & remoteURL);
00830 
00836     virtual SIPURL GetRegisteredPartyName(const SIPURL & remoteURL, const OpalTransport & transport);
00837 
00838 
00841     virtual SIPURL GetDefaultRegisteredPartyName(const OpalTransport & transport);
00842     
00843 
00855     SIPURL GetContactURL(const OpalTransport &transport, const SIPURL & localURI);
00856 
00857 
00867     virtual SIPURL GetLocalURL(
00868        const OpalTransport & transport,             
00869        const PString & userName = PString::Empty()  
00870     );
00871     
00872     
00875     const SIPURL & GetProxy() const { return proxy; }
00876 
00877     
00880     void SetProxy(const SIPURL & url);
00881     
00882     
00885     void SetProxy(
00886       const PString & hostname,
00887       const PString & username,
00888       const PString & password
00889     );
00890 
00891     
00894     int GetDefaultAppearanceCode() const { return m_defaultAppearanceCode; }
00895 
00898     void SetDefaultAppearanceCode(int code) { m_defaultAppearanceCode = code; }
00899 
00906     virtual PString GetUserAgent() const;
00907         
00910     void SetUserAgent(const PString & str) { userAgentString = str; }
00911 
00912 
00915     virtual unsigned GetAllowedMethods() const;
00916 
00917 
00920     enum NATBindingRefreshMethod{
00921       None,
00922       Options,
00923       EmptyRequest,
00924       NumMethods
00925     };
00926 
00927 
00930     void SetNATBindingRefreshMethod(const NATBindingRefreshMethod m) { natMethod = m; }
00931 
00932     virtual SIPRegisterHandler * CreateRegisterHandler(const SIPRegister::Params & params);
00933 
00934     virtual void OnStartTransaction(SIPConnection & conn, SIPTransaction & transaction);
00935 
00936 #if OPAL_HAS_SIPIM
00937     virtual OpalSIPIMManager & GetSIPIMManager() { return m_sipIMManager; }
00938 #endif
00939 
00940     void UpdateHandlerIndexes(SIPHandler * handler) { activeSIPHandlers.Update(handler); }
00941 
00942   protected:
00943     PDECLARE_NOTIFIER(PThread, SIPEndPoint, TransportThreadMain);
00944     PDECLARE_NOTIFIER(PTimer, SIPEndPoint, NATBindingRefresh);
00945 
00946     SIPURL        proxy;
00947     PString       userAgentString;
00948 
00949     SIPConnection::PRACKMode m_defaultPrackMode;
00950 
00951     bool          mimeForm;
00952     unsigned      maxRetries;
00953     PTimeInterval retryTimeoutMin;   // T1
00954     PTimeInterval retryTimeoutMax;   // T2
00955     PTimeInterval nonInviteTimeout;  // T3
00956     PTimeInterval pduCleanUpTimeout; // T4
00957     PTimeInterval inviteTimeout;
00958     PTimeInterval m_progressTimeout;
00959     PTimeInterval ackTimeout;
00960     PTimeInterval registrarTimeToLive;
00961     PTimeInterval notifierTimeToLive;
00962     PTimeInterval natBindingTimeout;
00963 
00964     bool              m_shuttingDown;
00965     SIPHandlersList   activeSIPHandlers;
00966     PStringToString   m_receivedConnectionTokens;
00967 
00968     PSafeDictionary<PString, SIPTransaction> transactions;
00969 
00970     PTimer                  natBindingTimer;
00971     NATBindingRefreshMethod natMethod;
00972     PAtomicInteger          lastSentCSeq;
00973     int                     m_defaultAppearanceCode;
00974 
00975     std::map<PString, PSyncPoint> m_registrationComplete;
00976 
00977   public:
00978     class WorkThreadPool;
00979     class SIP_Work
00980     {
00981       public:
00982         SIP_Work(SIPEndPoint & ep, SIP_PDU * pdu, const PString & token);
00983         virtual ~SIP_Work();
00984 
00985         virtual void Process();
00986 
00987         SIPEndPoint & m_endpoint;
00988         SIP_PDU     * m_pdu;
00989         PString       m_token;
00990     };
00991 
00992     class WorkThreadPool : public PThreadPool<SIP_Work>
00993     {
00994       public:
00995         virtual WorkerThreadBase * CreateWorkerThread();
00996     } m_connectionThreadPool, m_handlerThreadPool;
00997 
00998   protected:
00999     typedef std::queue<SIP_Work *> SIP_WorkQueue;
01000 
01001     class SIP_Work_Thread : public WorkThreadPool::WorkerThread
01002     {
01003       public:
01004         SIP_Work_Thread(WorkThreadPool & pool_);
01005 
01006         void AddWork(SIP_Work * work);
01007         void RemoveWork(SIP_Work * work);
01008         unsigned GetWorkSize() const;
01009 
01010         void Main();
01011         void Shutdown();
01012 
01013       protected:
01014         PSyncPoint m_sync;
01015         SIP_WorkQueue m_pduQueue;
01016     };
01017 
01018     enum {
01019       HighPriority = 80,
01020       LowPriority  = 30,
01021     };
01022     class InterfaceMonitor : public PInterfaceMonitorClient
01023     {
01024         PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
01025       public:
01026         InterfaceMonitor(SIPEndPoint & manager, PINDEX priority);
01027         
01028         virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
01029         virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
01030 
01031       protected:
01032         SIPEndPoint & m_endpoint;
01033     };
01034     InterfaceMonitor m_highPriorityMonitor;
01035     InterfaceMonitor m_lowPriorityMonitor;
01036 
01037     friend void InterfaceMonitor::OnAddInterface(const PIPSocket::InterfaceEntry & entry);
01038     friend void InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
01039 
01040 #if OPAL_HAS_SIPIM
01041     OpalSIPIMManager m_sipIMManager;
01042 #endif
01043 
01044     bool m_disableTrying;
01045 
01046     P_REMOVE_VIRTUAL_VOID(OnReceivedIntervalTooBrief(SIPTransaction &, SIP_PDU &));
01047     P_REMOVE_VIRTUAL_VOID(OnReceivedAuthenticationRequired(SIPTransaction &, SIP_PDU &));
01048     P_REMOVE_VIRTUAL_VOID(OnReceivedOK(SIPTransaction &, SIP_PDU &));
01049 
01050   public:
01051     struct ConnectionlessMessageInfo {
01052       ConnectionlessMessageInfo(OpalTransport & transport, SIP_PDU & pdu)
01053         : m_pdu(pdu), m_transport(transport), m_status(true)
01054       { }
01055 
01056       SIP_PDU & m_pdu;
01057       OpalTransport & m_transport;
01058       bool m_status;
01059     };
01060 
01061     typedef PNotifierTemplate<ConnectionlessMessageInfo &> ConnectionlessMessageNotifier;
01062     #define PDECLARE_ConnectionlessMessageNotifier(cls, fn) PDECLARE_NOTIFIER2(SIPEndPoint, cls, fn, SIPEndPoint::ConnectionlessMessageInfo &)
01063     #define PCREATE_ConnectionlessMessageNotifier(fn) PCREATE_NOTIFIER2(fn, SIPEndPoint::ConnectionlessMessageInfo &)
01064 
01065     void SetConnectionlessMessageNotifier(
01066       const ConnectionlessMessageNotifier & notifier
01067     )
01068     { m_onConnectionlessMessage = notifier; }
01069 
01070   protected:
01071     ConnectionlessMessageNotifier m_onConnectionlessMessage;
01072 };
01073 
01074 
01075 #endif // OPAL_SIP
01076 
01077 #endif // OPAL_SIP_SIPEP_H
01078 
01079 
01080 // End of File ///////////////////////////////////////////////////////////////

Generated on Sun Nov 21 20:20:51 2010 for OPAL by  doxygen 1.4.7