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 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
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
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;
00954 PTimeInterval retryTimeoutMax;
00955 PTimeInterval nonInviteTimeout;
00956 PTimeInterval pduCleanUpTimeout;
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