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 PBoolean 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
00226
00229
00233 OpalTransport * CreateTransport(
00234 const SIPURL & remoteURL,
00235 const PString & localInterface = PString::Empty()
00236 );
00237
00238 virtual void HandlePDU(
00239 OpalTransport & transport
00240 );
00241
00244 virtual PBoolean OnReceivedPDU(
00245 OpalTransport & transport,
00246 SIP_PDU * pdu
00247 );
00248
00251 virtual bool OnReceivedConnectionlessPDU(
00252 OpalTransport & transport,
00253 SIP_PDU * pdu
00254 );
00255
00258 virtual void OnReceivedResponse(
00259 SIPTransaction & transaction,
00260 SIP_PDU & response
00261 );
00262
00265 virtual PBoolean OnReceivedINVITE(
00266 OpalTransport & transport,
00267 SIP_PDU * pdu
00268 );
00269
00272 virtual void OnReceivedIntervalTooBrief(
00273 SIPTransaction & transaction,
00274 SIP_PDU & response)
00275 ;
00276
00279 virtual void OnReceivedAuthenticationRequired(
00280 SIPTransaction & transaction,
00281 SIP_PDU & response
00282 );
00283
00287 virtual void OnReceivedOK(
00288 SIPTransaction & transaction,
00289 SIP_PDU & response
00290 );
00291
00294 virtual PBoolean OnReceivedNOTIFY(
00295 OpalTransport & transport,
00296 SIP_PDU & response
00297 );
00298
00301 virtual PBoolean OnReceivedREGISTER(
00302 OpalTransport & transport,
00303 SIP_PDU & pdu
00304 );
00305
00308 virtual PBoolean OnReceivedSUBSCRIBE(
00309 OpalTransport & transport,
00310 SIP_PDU & pdu
00311 );
00312
00315 virtual bool OnReceivedMESSAGE(
00316 OpalTransport & transport,
00317 SIP_PDU & response
00318 );
00319
00322 virtual bool OnReceivedOPTIONS(
00323 OpalTransport & transport,
00324 SIP_PDU & response
00325 );
00326
00329 virtual void OnTransactionFailed(
00330 SIPTransaction & transaction
00331 );
00332
00340 virtual void OnRTPStatistics(
00341 const SIPConnection & connection,
00342 const RTP_Session & session
00343 ) const;
00345
00346
00354 PSafePtr<SIPConnection> GetSIPConnectionWithLock(
00355 const PString & token,
00356 PSafetyMode mode = PSafeReadWrite,
00357 SIP_PDU::StatusCodes * errorCode = NULL
00358 );
00359
00360 virtual PBoolean IsAcceptedAddress(const SIPURL & toAddr);
00361
00362
00365 virtual void OnMessageReceived (const SIPURL & from, const PString & body);
00366 virtual void OnMessageReceived (const SIPURL & from, const SIP_PDU & pdu);
00367
00381 bool Register(
00382 const SIPRegister::Params & params,
00383 PString & aor
00384 );
00385
00387 bool Register(
00388 const PString & host,
00389 const PString & user = PString::Empty(),
00390 const PString & autName = PString::Empty(),
00391 const PString & password = PString::Empty(),
00392 const PString & authRealm = PString::Empty(),
00393 unsigned expire = 0,
00394 const PTimeInterval & minRetryTime = PMaxTimeInterval,
00395 const PTimeInterval & maxRetryTime = PMaxTimeInterval
00396 );
00397
00402 bool Unregister(const PString & aor);
00403
00406 bool UnregisterAll();
00407
00414 PBoolean IsRegistered(
00415 const PString & aor,
00416 bool includeOffline = false
00417 );
00418
00421 unsigned GetRegistrationsCount() const { return activeSIPHandlers.GetCount(SIP_PDU::Method_REGISTER); }
00422
00425 PStringList GetRegistrations(
00426 bool includeOffline = false
00427 ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_REGISTER); }
00428
00430 struct RegistrationStatus {
00431 PString m_addressofRecord;
00432 bool m_wasRegistering;
00433 bool m_reRegistering;
00434 SIP_PDU::StatusCodes m_reason;
00435 OpalProductInfo m_productInfo;
00436 };
00437
00440 virtual void OnRegistrationStatus(
00441 const RegistrationStatus & status
00442 );
00443
00444
00445 virtual void OnRegistrationStatus(
00446 const PString & aor,
00447 PBoolean wasRegistering,
00448 PBoolean reRegistering,
00449 SIP_PDU::StatusCodes reason
00450 );
00451
00455 virtual void OnRegistrationFailed(
00456 const PString & aor,
00457 SIP_PDU::StatusCodes reason,
00458 PBoolean wasRegistering
00459 );
00460
00464 virtual void OnRegistered(
00465 const PString & aor,
00466 PBoolean wasRegistering
00467 );
00468
00469
00473 bool Subscribe(
00474 SIPSubscribe::PredefinedPackages eventPackage,
00475 unsigned expire,
00476 const PString & aor
00477 );
00478 bool Subscribe(
00479 const SIPSubscribe::Params & params,
00480 PString & aor
00481 );
00482
00483
00484 bool Unsubscribe(
00485 SIPSubscribe::PredefinedPackages eventPackage,
00486 const PString & aor
00487 );
00488 bool Unsubscribe(
00489 const PString & eventPackage,
00490 const PString & aor
00491 );
00492
00495 bool UnsubcribeAll(
00496 SIPSubscribe::PredefinedPackages eventPackage
00497 );
00498 bool UnsubcribeAll(
00499 const PString & eventPackage
00500 );
00501
00508 PBoolean IsSubscribed(
00509 const PString & eventPackage,
00510 const PString & aor,
00511 bool includeOffline = false
00512 );
00513
00516 unsigned GetSubscriptionCount(
00517 const SIPSubscribe::EventPackage & eventPackage
00518 ) { return activeSIPHandlers.GetCount(SIP_PDU::Method_SUBSCRIBE, eventPackage); }
00519
00522 PStringList GetSubscriptions(
00523 const SIPSubscribe::EventPackage & eventPackage,
00524 bool includeOffline = false
00525 ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_REGISTER, eventPackage); }
00526
00529 virtual void OnSubscriptionStatus(
00530 const PString & eventPackage,
00531 const SIPURL & uri,
00532 bool wasSubscribing,
00533 bool reSubscribing,
00534 SIP_PDU::StatusCodes reason
00535 );
00536
00539 virtual bool CanNotify(
00540 const PString & eventPackage
00541 );
00542
00545 bool Notify(
00546 const SIPURL & targetAddress,
00547 const PString & eventPackage,
00548 const PObject & body
00549 );
00550
00551
00554 virtual void OnDialogInfoReceived(
00555 const SIPDialogNotification & info
00556 );
00557
00558 void SendNotifyDialogInfo(
00559 const SIPDialogNotification & info
00560 );
00561
00562
00565 PBoolean Message(
00566 const PString & to,
00567 const PString & body
00568 );
00569 PBoolean Message(
00570 const PString & to,
00571 const PString & body,
00572 const PString & remoteContact,
00573 const PString & callID
00574 );
00575
00580 virtual void OnMessageFailed(
00581 const SIPURL & messageUrl,
00582 SIP_PDU::StatusCodes reason
00583 );
00584
00585
00589 bool Publish(
00590 const SIPSubscribe::Params & params,
00591 const PString & body,
00592 PString & aor
00593 );
00594 bool Publish(
00595 const PString & to,
00596 const PString & body,
00597 unsigned expire = 300
00598 );
00599
00602 PStringList GetPublications(
00603 const SIPSubscribe::EventPackage & eventPackage,
00604 bool includeOffline = false
00605 ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_PUBLISH, eventPackage); }
00606
00607
00611 bool PublishPresence(
00612 const SIPPresenceInfo & info,
00613 unsigned expire = 300
00614 );
00615
00618 virtual void OnPresenceInfoReceived (
00619 const SIPPresenceInfo & info
00620 );
00621 virtual void OnPresenceInfoReceived (
00622 const PString & identity,
00623 const PString & basic,
00624 const PString & note
00625 );
00626
00627
00630 PBoolean Ping(
00631 const PString & to
00632 );
00633
00634
00635 void SetMIMEForm(PBoolean v) { mimeForm = v; }
00636 PBoolean GetMIMEForm() const { return mimeForm; }
00637
00638 void SetMaxRetries(unsigned r) { maxRetries = r; }
00639 unsigned GetMaxRetries() const { return maxRetries; }
00640
00641 void SetRetryTimeouts(
00642 const PTimeInterval & t1,
00643 const PTimeInterval & t2
00644 ) { retryTimeoutMin = t1; retryTimeoutMax = t2; }
00645 const PTimeInterval & GetRetryTimeoutMin() const { return retryTimeoutMin; }
00646 const PTimeInterval & GetRetryTimeoutMax() const { return retryTimeoutMax; }
00647
00648 void SetNonInviteTimeout(
00649 const PTimeInterval & t
00650 ) { nonInviteTimeout = t; }
00651 const PTimeInterval & GetNonInviteTimeout() const { return nonInviteTimeout; }
00652
00653 void SetPduCleanUpTimeout(
00654 const PTimeInterval & t
00655 ) { pduCleanUpTimeout = t; }
00656 const PTimeInterval & GetPduCleanUpTimeout() const { return pduCleanUpTimeout; }
00657
00658 void SetInviteTimeout(
00659 const PTimeInterval & t
00660 ) { inviteTimeout = t; }
00661 const PTimeInterval & GetInviteTimeout() const { return inviteTimeout; }
00662
00663 void SetAckTimeout(
00664 const PTimeInterval & t
00665 ) { ackTimeout = t; }
00666 const PTimeInterval & GetAckTimeout() const { return ackTimeout; }
00667
00668 void SetRegistrarTimeToLive(
00669 const PTimeInterval & t
00670 ) { registrarTimeToLive = t; }
00671 const PTimeInterval & GetRegistrarTimeToLive() const { return registrarTimeToLive; }
00672
00673 void SetNotifierTimeToLive(
00674 const PTimeInterval & t
00675 ) { notifierTimeToLive = t; }
00676 const PTimeInterval & GetNotifierTimeToLive() const { return notifierTimeToLive; }
00677
00678 void SetNATBindingTimeout(
00679 const PTimeInterval & t
00680 ) { natBindingTimeout = t; natBindingTimer.RunContinuous (natBindingTimeout); }
00681 const PTimeInterval & GetNATBindingTimeout() const { return natBindingTimeout; }
00682
00683 void AddTransaction(
00684 SIPTransaction * transaction
00685 ) { transactions.SetAt(transaction->GetTransactionID(), transaction); }
00686
00687 PSafePtr<SIPTransaction> GetTransaction(const PString & transactionID, PSafetyMode mode = PSafeReadWrite)
00688 { return transactions.FindWithLock(transactionID, mode); }
00689
00692 unsigned GetNextCSeq() { return ++lastSentCSeq; }
00693
00696 PBoolean GetAuthentication(const PString & authRealm, PString & realm, PString & user, PString & password);
00697
00703 virtual SIPURL GetRegisteredPartyName(const SIPURL & remoteURL, const OpalTransport & transport);
00704
00705
00708 virtual SIPURL GetDefaultRegisteredPartyName(const OpalTransport & transport);
00709
00710
00722 SIPURL GetContactURL(const OpalTransport &transport, const SIPURL & localURI);
00723
00724
00734 virtual SIPURL GetLocalURL(
00735 const OpalTransport & transport,
00736 const PString & userName = PString::Empty()
00737 );
00738
00739
00742 const SIPURL & GetProxy() const { return proxy; }
00743
00744
00747 void SetProxy(const SIPURL & url);
00748
00749
00752 void SetProxy(
00753 const PString & hostname,
00754 const PString & username,
00755 const PString & password
00756 );
00757
00758
00761 int GetDefaultAppearanceCode() const { return m_defaultAppearanceCode; }
00762
00765 void SetDefaultAppearanceCode(int code) { m_defaultAppearanceCode = code; }
00766
00773 virtual PString GetUserAgent() const;
00774
00777 void SetUserAgent(const PString & str) { userAgentString = str; }
00778
00779
00782 virtual unsigned GetAllowedMethods() const;
00783
00784
00787 enum NATBindingRefreshMethod{
00788 None,
00789 Options,
00790 EmptyRequest,
00791 NumMethods
00792 };
00793
00794
00797 void SetNATBindingRefreshMethod(const NATBindingRefreshMethod m) { natMethod = m; }
00798
00799 virtual SIPRegisterHandler * CreateRegisterHandler(const SIPRegister::Params & params);
00800
00801 virtual void OnStartTransaction(SIPConnection & conn, SIPTransaction & transaction);
00802
00803 #if OPAL_HAS_SIPIM
00804 virtual OpalSIPIMManager & GetSIPIMManager() { return m_sipIMManager; }
00805 #endif
00806
00807 protected:
00808 PDECLARE_NOTIFIER(PThread, SIPEndPoint, TransportThreadMain);
00809 PDECLARE_NOTIFIER(PTimer, SIPEndPoint, NATBindingRefresh);
00810
00811 SIPURL proxy;
00812 PString userAgentString;
00813
00814 bool mimeForm;
00815 unsigned maxRetries;
00816 PTimeInterval retryTimeoutMin;
00817 PTimeInterval retryTimeoutMax;
00818 PTimeInterval nonInviteTimeout;
00819 PTimeInterval pduCleanUpTimeout;
00820 PTimeInterval inviteTimeout;
00821 PTimeInterval ackTimeout;
00822 PTimeInterval registrarTimeToLive;
00823 PTimeInterval notifierTimeToLive;
00824 PTimeInterval natBindingTimeout;
00825
00826 bool m_shuttingDown;
00827 SIPHandlersList activeSIPHandlers;
00828 PStringToString m_receivedConnectionTokens;
00829
00830 PSafeDictionary<PString, SIPTransaction> transactions;
00831
00832 PTimer natBindingTimer;
00833 NATBindingRefreshMethod natMethod;
00834 PAtomicInteger lastSentCSeq;
00835 int m_defaultAppearanceCode;
00836
00837 struct SIP_PDU_Work
00838 {
00839 public:
00840 SIP_PDU_Work(SIPEndPoint & ep, const PString & token, SIP_PDU * pdu);
00841 ~SIP_PDU_Work();
00842
00843 void OnReceivedPDU();
00844
00845 SIPEndPoint & m_endpoint;
00846 PString m_token;
00847 SIP_PDU * m_pdu;
00848 };
00849
00850 class PDUThreadPool : public PThreadPool<SIP_PDU_Work>
00851 {
00852 public:
00853 virtual WorkerThreadBase * CreateWorkerThread();
00854 } threadPool;
00855
00856 typedef std::queue<SIP_PDU_Work *> SIP_PDUWorkQueue;
00857
00858 class SIP_PDU_Thread : public PDUThreadPool::WorkerThread
00859 {
00860 public:
00861 SIP_PDU_Thread(PDUThreadPool & pool_);
00862
00863 void AddWork(SIP_PDU_Work * work);
00864 void RemoveWork(SIP_PDU_Work * work);
00865 unsigned GetWorkSize() const;
00866
00867 void Main();
00868 void Shutdown();
00869
00870 protected:
00871 PSyncPoint m_sync;
00872 SIP_PDUWorkQueue m_pduQueue;
00873 };
00874
00875 virtual void AddWork(SIP_PDU_Work * work);
00876
00877 enum {
00878 HighPriority = 80,
00879 LowPriority = 30,
00880 };
00881 class InterfaceMonitor : public PInterfaceMonitorClient
00882 {
00883 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
00884 public:
00885 InterfaceMonitor(SIPEndPoint & manager, PINDEX priority);
00886
00887 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
00888 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
00889
00890 protected:
00891 SIPEndPoint & m_endpoint;
00892 };
00893 InterfaceMonitor m_highPriorityMonitor;
00894 InterfaceMonitor m_lowPriorityMonitor;
00895
00896 friend void InterfaceMonitor::OnAddInterface(const PIPSocket::InterfaceEntry & entry);
00897 friend void InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
00898
00899 #if OPAL_HAS_SIPIM
00900 OpalSIPIMManager m_sipIMManager;
00901 #endif
00902 };
00903
00904
00905 #endif // OPAL_SIP
00906
00907 #endif // OPAL_SIP_SIPEP_H
00908
00909
00910