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
00060
00061
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 );
00395
00397 bool P_DEPRECATED Register(
00398 const PString & host,
00399 const PString & user = PString::Empty(),
00400 const PString & autName = PString::Empty(),
00401 const PString & password = PString::Empty(),
00402 const PString & authRealm = PString::Empty(),
00403 unsigned expire = 0,
00404 const PTimeInterval & minRetryTime = PMaxTimeInterval,
00405 const PTimeInterval & maxRetryTime = PMaxTimeInterval
00406 );
00407
00422 PBoolean IsRegistered(
00423 const PString & aor,
00424 bool includeOffline = false
00425 );
00426
00436 bool Unregister(
00437 const PString & aor
00438 );
00439
00443 bool UnregisterAll();
00444
00447 unsigned GetRegistrationsCount() const { return activeSIPHandlers.GetCount(SIP_PDU::Method_REGISTER); }
00448
00451 PStringList GetRegistrations(
00452 bool includeOffline = false
00453 ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_REGISTER); }
00454
00456 struct RegistrationStatus {
00457 SIPRegisterHandler * m_handler;
00458 PString m_addressofRecord;
00459 bool m_wasRegistering;
00460 bool m_reRegistering;
00461 SIP_PDU::StatusCodes m_reason;
00462 OpalProductInfo m_productInfo;
00463 void * m_userData;
00464 };
00465
00468 virtual void OnRegistrationStatus(
00469 const RegistrationStatus & status
00470 );
00471
00472
00473 virtual void OnRegistrationStatus(
00474 const PString & aor,
00475 PBoolean wasRegistering,
00476 PBoolean reRegistering,
00477 SIP_PDU::StatusCodes reason
00478 );
00479
00483 virtual void OnRegistrationFailed(
00484 const PString & aor,
00485 SIP_PDU::StatusCodes reason,
00486 PBoolean wasRegistering
00487 );
00488
00492 virtual void OnRegistered(
00493 const PString & aor,
00494 PBoolean wasRegistering
00495 );
00496
00497
00537 bool Subscribe(
00538 const SIPSubscribe::Params & params,
00539 PString & token,
00540 bool tokenIsAOR = true
00541 );
00542
00543
00544 bool Subscribe(
00545 SIPSubscribe::PredefinedPackages eventPackage,
00546 unsigned expire,
00547 const PString & aor
00548 );
00549
00556 bool IsSubscribed(
00557 const PString & aor,
00558 bool includeOffline = false
00559 );
00560 bool IsSubscribed(
00561 const PString & eventPackage,
00562 const PString & aor,
00563 bool includeOffline = false
00564 );
00565
00575 bool Unsubscribe(
00576 const PString & aor
00577 );
00578 bool Unsubscribe(
00579 SIPSubscribe::PredefinedPackages eventPackage,
00580 const PString & aor
00581 );
00582 bool Unsubscribe(
00583 const PString & eventPackage,
00584 const PString & aor
00585 );
00586
00590 bool UnsubcribeAll(
00591 SIPSubscribe::PredefinedPackages eventPackage
00592 );
00593 bool UnsubcribeAll(
00594 const PString & eventPackage
00595 );
00596
00599 unsigned GetSubscriptionCount(
00600 const SIPSubscribe::EventPackage & eventPackage
00601 ) { return activeSIPHandlers.GetCount(SIP_PDU::Method_SUBSCRIBE, eventPackage); }
00602
00605 PStringList GetSubscriptions(
00606 const SIPSubscribe::EventPackage & eventPackage,
00607 bool includeOffline = false
00608 ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_REGISTER, eventPackage); }
00609
00611 typedef SIPSubscribe::SubscriptionStatus SubscriptionStatus;
00612
00615 virtual void OnSubscriptionStatus(
00616 const SubscriptionStatus & status
00617 );
00618
00622 virtual void OnSubscriptionStatus(
00623 const PString & eventPackage,
00624 const SIPURL & uri,
00625 bool wasSubscribing,
00626 bool reSubscribing,
00627 SIP_PDU::StatusCodes reason
00628 );
00629
00630 virtual void OnSubscriptionStatus(
00631 SIPSubscribeHandler & handler,
00632 const SIPURL & uri,
00633 bool wasSubscribing,
00634 bool reSubscribing,
00635 SIP_PDU::StatusCodes reason
00636 );
00637
00640 virtual bool CanNotify(
00641 const PString & eventPackage
00642 );
00643
00646 bool Notify(
00647 const SIPURL & targetAddress,
00648 const PString & eventPackage,
00649 const PObject & body
00650 );
00651
00652
00655 virtual void OnDialogInfoReceived(
00656 const SIPDialogNotification & info
00657 );
00658
00659 void SendNotifyDialogInfo(
00660 const SIPDialogNotification & info
00661 );
00662
00665 virtual bool Message(
00666 const PURL & to,
00667 const PString & type,
00668 const PString & body,
00669 PURL & from,
00670 PString & conversationId
00671 );
00672
00677 virtual void OnMessageFailed(
00678 const SIPURL & messageUrl,
00679 SIP_PDU::StatusCodes reason
00680 );
00681
00682
00686 bool Publish(
00687 const SIPSubscribe::Params & params,
00688 const PString & body,
00689 PString & aor
00690 );
00691 bool Publish(
00692 const PString & to,
00693 const PString & body,
00694 unsigned expire = 300
00695 );
00696
00699 PStringList GetPublications(
00700 const SIPSubscribe::EventPackage & eventPackage,
00701 bool includeOffline = false
00702 ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_PUBLISH, eventPackage); }
00703
00704
00708 bool PublishPresence(
00709 const SIPPresenceInfo & info,
00710 unsigned expire = 300
00711 );
00712
00715 virtual void OnPresenceInfoReceived (
00716 const SIPPresenceInfo & info
00717 );
00718 virtual void OnPresenceInfoReceived (
00719 const PString & identity,
00720 const PString & basic,
00721 const PString & note
00722 );
00723
00724
00727 PBoolean Ping(
00728 const PURL & to
00729 );
00730
00731
00732 void SetMIMEForm(PBoolean v) { mimeForm = v; }
00733 PBoolean GetMIMEForm() const { return mimeForm; }
00734
00735 void SetMaxRetries(unsigned r) { maxRetries = r; }
00736 unsigned GetMaxRetries() const { return maxRetries; }
00737
00738 void SetRetryTimeouts(
00739 const PTimeInterval & t1,
00740 const PTimeInterval & t2
00741 ) { retryTimeoutMin = t1; retryTimeoutMax = t2; }
00742 const PTimeInterval & GetRetryTimeoutMin() const { return retryTimeoutMin; }
00743 const PTimeInterval & GetRetryTimeoutMax() const { return retryTimeoutMax; }
00744
00745 void SetNonInviteTimeout(
00746 const PTimeInterval & t
00747 ) { nonInviteTimeout = t; }
00748 const PTimeInterval & GetNonInviteTimeout() const { return nonInviteTimeout; }
00749
00750 void SetPduCleanUpTimeout(
00751 const PTimeInterval & t
00752 ) { pduCleanUpTimeout = t; }
00753 const PTimeInterval & GetPduCleanUpTimeout() const { return pduCleanUpTimeout; }
00754
00755 void SetInviteTimeout(
00756 const PTimeInterval & t
00757 ) { inviteTimeout = t; }
00758 const PTimeInterval & GetInviteTimeout() const { return inviteTimeout; }
00759
00760 void SetProgressTimeout(
00761 const PTimeInterval & t
00762 ) { m_progressTimeout = t; }
00763 const PTimeInterval & GetProgressTimeout() const { return m_progressTimeout; }
00764
00765 void SetAckTimeout(
00766 const PTimeInterval & t
00767 ) { ackTimeout = t; }
00768 const PTimeInterval & GetAckTimeout() const { return ackTimeout; }
00769
00770 void SetRegistrarTimeToLive(
00771 const PTimeInterval & t
00772 ) { registrarTimeToLive = t; }
00773 const PTimeInterval & GetRegistrarTimeToLive() const { return registrarTimeToLive; }
00774
00775 void SetNotifierTimeToLive(
00776 const PTimeInterval & t
00777 ) { notifierTimeToLive = t; }
00778 const PTimeInterval & GetNotifierTimeToLive() const { return notifierTimeToLive; }
00779
00780 void SetNATBindingTimeout(
00781 const PTimeInterval & t
00782 ) { natBindingTimeout = t; natBindingTimer.RunContinuous (natBindingTimeout); }
00783 const PTimeInterval & GetNATBindingTimeout() const { return natBindingTimeout; }
00784
00785 void AddTransaction(
00786 SIPTransaction * transaction
00787 ) { transactions.SetAt(transaction->GetTransactionID(), transaction); }
00788
00789 PSafePtr<SIPTransaction> GetTransaction(const PString & transactionID, PSafetyMode mode = PSafeReadWrite)
00790 { return transactions.FindWithLock(transactionID, mode); }
00791
00794 unsigned GetNextCSeq() { return ++lastSentCSeq; }
00795
00798 bool GetAuthentication(const PString & authRealm, PString & user, PString & password);
00799
00802 virtual SIPURL GetRegisteredProxy(const SIPURL & remoteURL);
00803
00809 virtual SIPURL GetRegisteredPartyName(const SIPURL & remoteURL, const OpalTransport & transport);
00810
00811
00814 virtual SIPURL GetDefaultRegisteredPartyName(const OpalTransport & transport);
00815
00816
00828 SIPURL GetContactURL(const OpalTransport &transport, const SIPURL & localURI);
00829
00830
00840 virtual SIPURL GetLocalURL(
00841 const OpalTransport & transport,
00842 const PString & userName = PString::Empty()
00843 );
00844
00845
00848 const SIPURL & GetProxy() const { return proxy; }
00849
00850
00853 void SetProxy(const SIPURL & url);
00854
00855
00858 void SetProxy(
00859 const PString & hostname,
00860 const PString & username,
00861 const PString & password
00862 );
00863
00864
00867 int GetDefaultAppearanceCode() const { return m_defaultAppearanceCode; }
00868
00871 void SetDefaultAppearanceCode(int code) { m_defaultAppearanceCode = code; }
00872
00879 virtual PString GetUserAgent() const;
00880
00883 void SetUserAgent(const PString & str) { userAgentString = str; }
00884
00885
00888 virtual unsigned GetAllowedMethods() const;
00889
00890
00893 enum NATBindingRefreshMethod{
00894 None,
00895 Options,
00896 EmptyRequest,
00897 NumMethods
00898 };
00899
00900
00903 void SetNATBindingRefreshMethod(const NATBindingRefreshMethod m) { natMethod = m; }
00904
00905 virtual SIPRegisterHandler * CreateRegisterHandler(const SIPRegister::Params & params);
00906
00907 virtual void OnStartTransaction(SIPConnection & conn, SIPTransaction & transaction);
00908
00909 #if OPAL_HAS_SIPIM
00910 virtual OpalSIPIMManager & GetSIPIMManager() { return m_sipIMManager; }
00911 #endif
00912
00913 void UpdateHandlerIndexes(SIPHandler * handler) { activeSIPHandlers.Update(handler); }
00914
00915 protected:
00916 PDECLARE_NOTIFIER(PThread, SIPEndPoint, TransportThreadMain);
00917 PDECLARE_NOTIFIER(PTimer, SIPEndPoint, NATBindingRefresh);
00918
00919 SIPURL proxy;
00920 PString userAgentString;
00921
00922 bool mimeForm;
00923 unsigned maxRetries;
00924 PTimeInterval retryTimeoutMin;
00925 PTimeInterval retryTimeoutMax;
00926 PTimeInterval nonInviteTimeout;
00927 PTimeInterval pduCleanUpTimeout;
00928 PTimeInterval inviteTimeout;
00929 PTimeInterval m_progressTimeout;
00930 PTimeInterval ackTimeout;
00931 PTimeInterval registrarTimeToLive;
00932 PTimeInterval notifierTimeToLive;
00933 PTimeInterval natBindingTimeout;
00934
00935 bool m_shuttingDown;
00936 SIPHandlersList activeSIPHandlers;
00937 PStringToString m_receivedConnectionTokens;
00938
00939 PSafeDictionary<PString, SIPTransaction> transactions;
00940
00941 PTimer natBindingTimer;
00942 NATBindingRefreshMethod natMethod;
00943 PAtomicInteger lastSentCSeq;
00944 int m_defaultAppearanceCode;
00945
00946 public:
00947 class WorkThreadPool;
00948 class SIP_Work
00949 {
00950 public:
00951 SIP_Work(SIPEndPoint & ep, SIP_PDU * pdu, const PString & token);
00952 virtual ~SIP_Work();
00953
00954 virtual void Process();
00955
00956 SIPEndPoint & m_endpoint;
00957 SIP_PDU * m_pdu;
00958 PString m_token;
00959 };
00960
00961 class WorkThreadPool : public PThreadPool<SIP_Work>
00962 {
00963 public:
00964 virtual WorkerThreadBase * CreateWorkerThread();
00965 } m_connectionThreadPool, m_handlerThreadPool;
00966
00967 protected:
00968 typedef std::queue<SIP_Work *> SIP_WorkQueue;
00969
00970 class SIP_Work_Thread : public WorkThreadPool::WorkerThread
00971 {
00972 public:
00973 SIP_Work_Thread(WorkThreadPool & pool_);
00974
00975 void AddWork(SIP_Work * work);
00976 void RemoveWork(SIP_Work * work);
00977 unsigned GetWorkSize() const;
00978
00979 void Main();
00980 void Shutdown();
00981
00982 protected:
00983 PSyncPoint m_sync;
00984 SIP_WorkQueue m_pduQueue;
00985 };
00986
00987 enum {
00988 HighPriority = 80,
00989 LowPriority = 30,
00990 };
00991 class InterfaceMonitor : public PInterfaceMonitorClient
00992 {
00993 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
00994 public:
00995 InterfaceMonitor(SIPEndPoint & manager, PINDEX priority);
00996
00997 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
00998 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
00999
01000 protected:
01001 SIPEndPoint & m_endpoint;
01002 };
01003 InterfaceMonitor m_highPriorityMonitor;
01004 InterfaceMonitor m_lowPriorityMonitor;
01005
01006 friend void InterfaceMonitor::OnAddInterface(const PIPSocket::InterfaceEntry & entry);
01007 friend void InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
01008
01009 #if OPAL_HAS_SIPIM
01010 OpalSIPIMManager m_sipIMManager;
01011 #endif
01012
01013 bool m_disableTrying;
01014
01015 P_REMOVE_VIRTUAL_VOID(OnReceivedIntervalTooBrief(SIPTransaction &, SIP_PDU &));
01016 P_REMOVE_VIRTUAL_VOID(OnReceivedAuthenticationRequired(SIPTransaction &, SIP_PDU &));
01017 P_REMOVE_VIRTUAL_VOID(OnReceivedOK(SIPTransaction &, SIP_PDU &));
01018
01019 public:
01020 struct ConnectionlessMessageInfo {
01021 ConnectionlessMessageInfo(OpalTransport & transport, SIP_PDU & pdu)
01022 : m_pdu(pdu), m_transport(transport), m_status(true)
01023 { }
01024
01025 SIP_PDU & m_pdu;
01026 OpalTransport & m_transport;
01027 bool m_status;
01028 };
01029
01030 typedef PNotifierTemplate<ConnectionlessMessageInfo &> ConnectionlessMessageNotifier;
01031 #define PDECLARE_ConnectionlessMessageNotifier(cls, fn) PDECLARE_NOTIFIER2(SIPEndPoint, cls, fn, SIPEndPoint::ConnectionlessMessageInfo &)
01032 #define PCREATE_ConnectionlessMessageNotifier(fn) PCREATE_NOTIFIER2(fn, SIPEndPoint::ConnectionlessMessageInfo &)
01033
01034 void SetConnectionlessMessageNotifier(
01035 const ConnectionlessMessageNotifier & notifier
01036 )
01037 { m_onConnectionlessMessage = notifier; }
01038
01039 protected:
01040 ConnectionlessMessageNotifier m_onConnectionlessMessage;
01041 };
01042
01043
01044 #endif // OPAL_SIP
01045
01046 #endif // OPAL_SIP_SIPEP_H
01047
01048
01049