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_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 
00061 
00065 class SIPAuthInfo : public PObject
00066 {
00067   public:
00068     SIPAuthInfo()
00069     { }
00070 
00071     SIPAuthInfo(const PString & u, const PString & p)
00072     { username = u; password = p; }
00073     PString username;
00074     PString password;
00075 };
00076 
00078 
00081 class SIPEndPoint : public OpalRTPEndPoint
00082 {
00083   PCLASSINFO(SIPEndPoint, OpalRTPEndPoint);
00084 
00085   public:
00090     SIPEndPoint(
00091       OpalManager & manager
00092     );
00093 
00096     ~SIPEndPoint();
00098 
00105     virtual void ShutDown();
00106 
00110     virtual PString GetDefaultTransport() const;
00111 
00116     virtual PBoolean NewIncomingConnection(
00117       OpalTransport * transport  
00118     );
00119 
00149     virtual PBoolean MakeConnection(
00150       OpalCall & call,                         
00151       const PString & party,                   
00152       void * userData,                         
00153       unsigned int options,                    
00154       OpalConnection::StringOptions * stringOptions  
00155     );
00156 
00175     virtual void OnReleased(
00176       OpalConnection & connection   
00177     );
00178 
00183     virtual PBoolean GarbageCollection();
00185 
00191     virtual SIPConnection * CreateConnection(
00192       OpalCall & call,                         
00193       const PString & token,                   
00194       void * userData,                         
00195       const SIPURL & destination,              
00196       OpalTransport * transport,               
00197       SIP_PDU * invite,                        
00198       unsigned int options = 0,                
00199       OpalConnection::StringOptions * stringOptions = NULL 
00200 
00201     );
00202     
00205     virtual PBoolean SetupTransfer(
00206       const PString & token,        
00207       const PString & callIdentity, 
00208       const PString & remoteParty,  
00209       void * userData = NULL        
00210     );
00211     
00215     virtual PBoolean ForwardConnection(
00216       SIPConnection & connection,     
00217       const PString & forwardParty    
00218     );
00219 
00221   
00224 
00228     OpalTransport * CreateTransport(
00229       const SIPURL & remoteURL,
00230       const PString & localInterface = PString::Empty()
00231     );
00232 
00233     virtual void HandlePDU(
00234       OpalTransport & transport
00235     );
00236 
00239     virtual PBoolean OnReceivedPDU(
00240       OpalTransport & transport,
00241       SIP_PDU * pdu
00242     );
00243 
00246     virtual bool OnReceivedConnectionlessPDU(
00247       OpalTransport & transport, 
00248       SIP_PDU * pdu
00249     );
00250 
00253     virtual void OnReceivedResponse(
00254       SIPTransaction & transaction,
00255       SIP_PDU & response
00256     );
00257 
00260     virtual PBoolean OnReceivedINVITE(
00261       OpalTransport & transport,
00262       SIP_PDU * pdu
00263     );
00264 
00267     virtual PBoolean OnReceivedNOTIFY(
00268       OpalTransport & transport,
00269       SIP_PDU & response
00270     );
00271 
00274     virtual PBoolean OnReceivedREGISTER(
00275       OpalTransport & transport, 
00276       SIP_PDU & pdu
00277     );
00278 
00281     virtual PBoolean OnReceivedSUBSCRIBE(
00282       OpalTransport & transport, 
00283       SIP_PDU & pdu
00284     );
00285 
00288     virtual bool OnReceivedMESSAGE(
00289       OpalTransport & transport,
00290       SIP_PDU & response
00291     );
00292 
00295     virtual bool OnReceivedOPTIONS(
00296       OpalTransport & transport,
00297       SIP_PDU & response
00298     );
00299     
00302     virtual void OnTransactionFailed(
00303       SIPTransaction & transaction
00304     );
00305     
00313     virtual void OnRTPStatistics(
00314       const SIPConnection & connection,  
00315       const RTP_Session & session         
00316     ) const;
00318  
00319 
00327     PSafePtr<SIPConnection> GetSIPConnectionWithLock(
00328       const PString & token,     
00329       PSafetyMode mode = PSafeReadWrite,
00330       SIP_PDU::StatusCodes * errorCode = NULL
00331     );
00332 
00333     virtual PBoolean IsAcceptedAddress(const SIPURL & toAddr);
00334 
00335 
00338     virtual void OnMessageReceived (const SIPURL & from, const PString & body);
00339     virtual void OnMessageReceived (const SIPURL & from, const SIP_PDU & pdu);
00340 
00354     bool Register(
00355       const SIPRegister::Params & params, 
00356       PString & aor                       
00357     );
00358 
00360     bool Register(
00361       const PString & host,
00362       const PString & user = PString::Empty(),
00363       const PString & autName = PString::Empty(),
00364       const PString & password = PString::Empty(),
00365       const PString & authRealm = PString::Empty(),
00366       unsigned expire = 0,
00367       const PTimeInterval & minRetryTime = PMaxTimeInterval, 
00368       const PTimeInterval & maxRetryTime = PMaxTimeInterval
00369     );
00370 
00375     bool Unregister(const PString & aor);
00376 
00380     bool UnregisterAll();
00381 
00388     PBoolean IsRegistered(
00389       const PString & aor,          
00390       bool includeOffline = false   
00391     );
00392 
00395     unsigned GetRegistrationsCount() const { return activeSIPHandlers.GetCount(SIP_PDU::Method_REGISTER); }
00396 
00399     PStringList GetRegistrations(
00400       bool includeOffline = false   
00401     ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_REGISTER); }
00402 
00404     struct RegistrationStatus {
00405       PString              m_addressofRecord;   
00406       bool                 m_wasRegistering;    
00407       bool                 m_reRegistering;     
00408       SIP_PDU::StatusCodes m_reason;            
00409       OpalProductInfo      m_productInfo;       
00410       void               * m_userData;          
00411     };
00412 
00415     virtual void OnRegistrationStatus(
00416       const RegistrationStatus & status   
00417     );
00418 
00419     
00420     virtual void OnRegistrationStatus(
00421       const PString & aor,
00422       PBoolean wasRegistering,
00423       PBoolean reRegistering,
00424       SIP_PDU::StatusCodes reason
00425     );
00426 
00430     virtual void OnRegistrationFailed(
00431       const PString & aor,
00432       SIP_PDU::StatusCodes reason,
00433       PBoolean wasRegistering
00434     );
00435 
00439     virtual void OnRegistered(
00440       const PString & aor,
00441       PBoolean wasRegistering
00442     );
00443 
00444 
00448     bool Subscribe(
00449       SIPSubscribe::PredefinedPackages eventPackage, 
00450       unsigned expire,                               
00451       const PString & aor                            
00452     );
00453     bool Subscribe(
00454       const SIPSubscribe::Params & params, 
00455       PString & aor                        
00456     );
00457 
00460     bool Unsubscribe(
00461       SIPSubscribe::PredefinedPackages eventPackage,  
00462       const PString & aor                             
00463     );
00464     bool Unsubscribe(
00465       const PString & eventPackage,  
00466       const PString & aor            
00467     );
00468 
00472     bool UnsubcribeAll(
00473       SIPSubscribe::PredefinedPackages eventPackage  
00474     );
00475     bool UnsubcribeAll(
00476       const PString & eventPackage  
00477     );
00478 
00485     PBoolean IsSubscribed(
00486       const PString & eventPackage,  
00487       const PString & aor,           
00488       bool includeOffline = false    
00489     );
00490 
00493     unsigned GetSubscriptionCount(
00494       const SIPSubscribe::EventPackage & eventPackage  
00495     ) { return activeSIPHandlers.GetCount(SIP_PDU::Method_SUBSCRIBE, eventPackage); }
00496 
00499     PStringList GetSubscriptions(
00500       const SIPSubscribe::EventPackage & eventPackage, 
00501       bool includeOffline = false   
00502     ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_REGISTER, eventPackage); }
00503 
00506     virtual void OnSubscriptionStatus(
00507       const PString & eventPackage, 
00508       const SIPURL & uri,           
00509       bool wasSubscribing,          
00510       bool reSubscribing,           
00511       SIP_PDU::StatusCodes reason   
00512     );
00513 
00516     virtual bool CanNotify(
00517       const PString & eventPackage 
00518     );
00519 
00522     bool Notify(
00523       const SIPURL & targetAddress, 
00524       const PString & eventPackage, 
00525       const PObject & body          
00526     );
00527 
00528 
00531     virtual void OnDialogInfoReceived(
00532       const SIPDialogNotification & info  
00533     );
00534 
00535     void SendNotifyDialogInfo(
00536       const SIPDialogNotification & info  
00537     );
00538 
00539 
00542     PBoolean Message(
00543       const PString & to, 
00544       const PString & body
00545     );
00546     PBoolean Message(
00547       const PString & to, 
00548       const PString & body,
00549       const PString & remoteContact, 
00550       const PString & callID
00551     );
00552     
00557     virtual void OnMessageFailed(
00558       const SIPURL & messageUrl,
00559       SIP_PDU::StatusCodes reason
00560     );
00561 
00562 
00566     bool Publish(
00567       const SIPSubscribe::Params & params,
00568       const PString & body,
00569       PString & aor
00570     );
00571     bool Publish(
00572       const PString & to,   
00573       const PString & body, 
00574       unsigned expire = 300 
00575     );
00576 
00579     PStringList GetPublications(
00580       const SIPSubscribe::EventPackage & eventPackage, 
00581       bool includeOffline = false   
00582     ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_PUBLISH, eventPackage); }
00583 
00584 
00588     bool PublishPresence(
00589       const SIPPresenceInfo & info,  
00590       unsigned expire = 300          
00591     );
00592     
00595     virtual void OnPresenceInfoReceived (
00596       const SIPPresenceInfo & info  
00597     );
00598     virtual void OnPresenceInfoReceived (
00599       const PString & identity,
00600       const PString & basic,
00601       const PString & note
00602     );
00603 
00604 
00607     PBoolean Ping(
00608       const PString & to
00609     );
00610 
00611 
00612     void SetMIMEForm(PBoolean v) { mimeForm = v; }
00613     PBoolean GetMIMEForm() const { return mimeForm; }
00614 
00615     void SetMaxRetries(unsigned r) { maxRetries = r; }
00616     unsigned GetMaxRetries() const { return maxRetries; }
00617 
00618     void SetRetryTimeouts(
00619       const PTimeInterval & t1,
00620       const PTimeInterval & t2
00621     ) { retryTimeoutMin = t1; retryTimeoutMax = t2; }
00622     const PTimeInterval & GetRetryTimeoutMin() const { return retryTimeoutMin; }
00623     const PTimeInterval & GetRetryTimeoutMax() const { return retryTimeoutMax; }
00624 
00625     void SetNonInviteTimeout(
00626       const PTimeInterval & t
00627     ) { nonInviteTimeout = t; }
00628     const PTimeInterval & GetNonInviteTimeout() const { return nonInviteTimeout; }
00629 
00630     void SetPduCleanUpTimeout(
00631       const PTimeInterval & t
00632     ) { pduCleanUpTimeout = t; }
00633     const PTimeInterval & GetPduCleanUpTimeout() const { return pduCleanUpTimeout; }
00634 
00635     void SetInviteTimeout(
00636       const PTimeInterval & t
00637     ) { inviteTimeout = t; }
00638     const PTimeInterval & GetInviteTimeout() const { return inviteTimeout; }
00639 
00640     void SetAckTimeout(
00641       const PTimeInterval & t
00642     ) { ackTimeout = t; }
00643     const PTimeInterval & GetAckTimeout() const { return ackTimeout; }
00644 
00645     void SetRegistrarTimeToLive(
00646       const PTimeInterval & t
00647     ) { registrarTimeToLive = t; }
00648     const PTimeInterval & GetRegistrarTimeToLive() const { return registrarTimeToLive; }
00649     
00650     void SetNotifierTimeToLive(
00651       const PTimeInterval & t
00652     ) { notifierTimeToLive = t; }
00653     const PTimeInterval & GetNotifierTimeToLive() const { return notifierTimeToLive; }
00654     
00655     void SetNATBindingTimeout(
00656       const PTimeInterval & t
00657     ) { natBindingTimeout = t; natBindingTimer.RunContinuous (natBindingTimeout); }
00658     const PTimeInterval & GetNATBindingTimeout() const { return natBindingTimeout; }
00659 
00660     void AddTransaction(
00661       SIPTransaction * transaction
00662     ) { transactions.SetAt(transaction->GetTransactionID(), transaction); }
00663 
00664     PSafePtr<SIPTransaction> GetTransaction(const PString & transactionID, PSafetyMode mode = PSafeReadWrite)
00665     { return transactions.FindWithLock(transactionID, mode); }
00666     
00669     unsigned GetNextCSeq() { return ++lastSentCSeq; }
00670 
00673     PBoolean GetAuthentication(const PString & authRealm, PString & realm, PString & user, PString & password); 
00674     
00680     virtual SIPURL GetRegisteredPartyName(const SIPURL & remoteURL, const OpalTransport & transport);
00681 
00682 
00685     virtual SIPURL GetDefaultRegisteredPartyName(const OpalTransport & transport);
00686     
00687 
00699     SIPURL GetContactURL(const OpalTransport &transport, const SIPURL & localURI);
00700 
00701 
00711     virtual SIPURL GetLocalURL(
00712        const OpalTransport & transport,             
00713        const PString & userName = PString::Empty()  
00714     );
00715     
00716     
00719     const SIPURL & GetProxy() const { return proxy; }
00720 
00721     
00724     void SetProxy(const SIPURL & url);
00725     
00726     
00729     void SetProxy(
00730       const PString & hostname,
00731       const PString & username,
00732       const PString & password
00733     );
00734 
00735     
00738     int GetDefaultAppearanceCode() const { return m_defaultAppearanceCode; }
00739 
00742     void SetDefaultAppearanceCode(int code) { m_defaultAppearanceCode = code; }
00743 
00750     virtual PString GetUserAgent() const;
00751         
00754     void SetUserAgent(const PString & str) { userAgentString = str; }
00755 
00756 
00759     virtual unsigned GetAllowedMethods() const;
00760 
00761 
00764     enum NATBindingRefreshMethod{
00765       None,
00766       Options,
00767       EmptyRequest,
00768       NumMethods
00769     };
00770 
00771 
00774     void SetNATBindingRefreshMethod(const NATBindingRefreshMethod m) { natMethod = m; }
00775 
00776     virtual SIPRegisterHandler * CreateRegisterHandler(const SIPRegister::Params & params);
00777 
00778     virtual void OnStartTransaction(SIPConnection & conn, SIPTransaction & transaction);
00779 
00780 #if OPAL_HAS_SIPIM
00781     virtual OpalSIPIMManager & GetSIPIMManager() { return m_sipIMManager; }
00782 #endif
00783 
00784   protected:
00785     void TransportReadLoop(OpalTransport * transport);
00786     PDECLARE_NOTIFIER(PThread, SIPEndPoint, TransportThreadMain);
00787     PDECLARE_NOTIFIER(PTimer, SIPEndPoint, NATBindingRefresh);
00788 
00789     SIPURL        proxy;
00790     PString       userAgentString;
00791 
00792     bool          mimeForm;
00793     unsigned      maxRetries;
00794     PTimeInterval retryTimeoutMin;   
00795     PTimeInterval retryTimeoutMax;   
00796     PTimeInterval nonInviteTimeout;  
00797     PTimeInterval pduCleanUpTimeout; 
00798     PTimeInterval inviteTimeout;
00799     PTimeInterval ackTimeout;
00800     PTimeInterval registrarTimeToLive;
00801     PTimeInterval notifierTimeToLive;
00802     PTimeInterval natBindingTimeout;
00803 
00804     bool              m_shuttingDown;
00805     SIPHandlersList   activeSIPHandlers;
00806     PStringToString   m_receivedConnectionTokens;
00807 
00808     PSafeDictionary<PString, SIPTransaction> transactions;
00809 
00810     PTimer                  natBindingTimer;
00811     NATBindingRefreshMethod natMethod;
00812     PAtomicInteger          lastSentCSeq;
00813     int                     m_defaultAppearanceCode;
00814 
00815     struct SIP_PDU_Work
00816     {
00817       public:
00818         SIP_PDU_Work(SIPEndPoint & ep, const PString & token, SIP_PDU * pdu);
00819         ~SIP_PDU_Work();
00820 
00821         void OnReceivedPDU();
00822 
00823         SIPEndPoint & m_endpoint;
00824         PString       m_token;
00825         SIP_PDU     * m_pdu;
00826     };
00827 
00828     class PDUThreadPool : public PThreadPool<SIP_PDU_Work>
00829     {
00830       public:
00831         virtual WorkerThreadBase * CreateWorkerThread();
00832     } m_connectionThreadPool, m_handlerThreadPool;
00833 
00834     typedef std::queue<SIP_PDU_Work *> SIP_PDUWorkQueue;
00835 
00836     class SIP_PDU_Thread : public PDUThreadPool::WorkerThread
00837     {
00838       public:
00839         SIP_PDU_Thread(PDUThreadPool & pool_);
00840 
00841         void AddWork(SIP_PDU_Work * work);
00842         void RemoveWork(SIP_PDU_Work * work);
00843         unsigned GetWorkSize() const;
00844 
00845         void Main();
00846         void Shutdown();
00847 
00848       protected:
00849         PSyncPoint m_sync;
00850         SIP_PDUWorkQueue m_pduQueue;
00851     };
00852 
00853     enum {
00854       HighPriority = 80,
00855       LowPriority  = 30,
00856     };
00857     class InterfaceMonitor : public PInterfaceMonitorClient
00858     {
00859         PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
00860       public:
00861         InterfaceMonitor(SIPEndPoint & manager, PINDEX priority);
00862         
00863         virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
00864         virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
00865 
00866       protected:
00867         SIPEndPoint & m_endpoint;
00868     };
00869     InterfaceMonitor m_highPriorityMonitor;
00870     InterfaceMonitor m_lowPriorityMonitor;
00871 
00872     friend void InterfaceMonitor::OnAddInterface(const PIPSocket::InterfaceEntry & entry);
00873     friend void InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
00874 
00875 #if OPAL_HAS_SIPIM
00876     OpalSIPIMManager m_sipIMManager;
00877 #endif
00878 
00879     bool m_disableTrying;
00880 
00881     P_REMOVE_VIRTUAL_VOID(OnReceivedIntervalTooBrief(SIPTransaction &, SIP_PDU &));
00882     P_REMOVE_VIRTUAL_VOID(OnReceivedAuthenticationRequired(SIPTransaction &, SIP_PDU &));
00883     P_REMOVE_VIRTUAL_VOID(OnReceivedOK(SIPTransaction &, SIP_PDU &));
00884 };
00885 
00886 
00887 #endif // OPAL_SIP
00888 
00889 #endif // OPAL_SIP_SIPEP_H
00890 
00891 
00892