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 void OnReceivedIntervalTooBrief(
00289 SIPTransaction & transaction,
00290 SIP_PDU & response)
00291 ;
00292
00295 virtual void OnReceivedAuthenticationRequired(
00296 SIPTransaction & transaction,
00297 SIP_PDU & response
00298 );
00299
00303 virtual void OnReceivedOK(
00304 SIPTransaction & transaction,
00305 SIP_PDU & response
00306 );
00307
00310 virtual PBoolean OnReceivedNOTIFY(
00311 OpalTransport & transport,
00312 SIP_PDU & response
00313 );
00314
00317 virtual PBoolean OnReceivedREGISTER(
00318 OpalTransport & transport,
00319 SIP_PDU & pdu
00320 );
00321
00324 virtual PBoolean OnReceivedSUBSCRIBE(
00325 OpalTransport & transport,
00326 SIP_PDU & pdu
00327 );
00328
00331 virtual bool OnReceivedMESSAGE(
00332 OpalTransport & transport,
00333 SIP_PDU & response
00334 );
00335
00338 virtual bool OnReceivedOPTIONS(
00339 OpalTransport & transport,
00340 SIP_PDU & response
00341 );
00342
00345 virtual void OnTransactionFailed(
00346 SIPTransaction & transaction
00347 );
00348
00356 virtual void OnRTPStatistics(
00357 const SIPConnection & connection,
00358 const RTP_Session & session
00359 ) const;
00361
00362
00370 PSafePtr<SIPConnection> GetSIPConnectionWithLock(
00371 const PString & token,
00372 PSafetyMode mode = PSafeReadWrite,
00373 SIP_PDU::StatusCodes * errorCode = NULL
00374 );
00375
00376 virtual PBoolean IsAcceptedAddress(const SIPURL & toAddr);
00377
00378
00392 bool Register(
00393 const SIPRegister::Params & params,
00394 PString & aor
00395 );
00396
00398 bool 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
00412 bool Unregister(
00413 const PString & aor,
00414 unsigned msecs = 1000
00415 );
00416
00420 bool UnregisterAll();
00421
00428 PBoolean IsRegistered(
00429 const PString & aor,
00430 bool includeOffline = false
00431 );
00432
00435 unsigned GetRegistrationsCount() const { return activeSIPHandlers.GetCount(SIP_PDU::Method_REGISTER); }
00436
00439 PStringList GetRegistrations(
00440 bool includeOffline = false
00441 ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_REGISTER); }
00442
00444 struct RegistrationStatus {
00445 PString m_addressofRecord;
00446 bool m_wasRegistering;
00447 bool m_reRegistering;
00448 SIP_PDU::StatusCodes m_reason;
00449 OpalProductInfo m_productInfo;
00450 void * m_userData;
00451 };
00452
00455 virtual void OnRegistrationStatus(
00456 const RegistrationStatus & status
00457 );
00458
00459
00460 virtual void OnRegistrationStatus(
00461 const PString & aor,
00462 PBoolean wasRegistering,
00463 PBoolean reRegistering,
00464 SIP_PDU::StatusCodes reason
00465 );
00466
00470 virtual void OnRegistrationFailed(
00471 const PString & aor,
00472 SIP_PDU::StatusCodes reason,
00473 PBoolean wasRegistering
00474 );
00475
00479 virtual void OnRegistered(
00480 const PString & aor,
00481 PBoolean wasRegistering
00482 );
00483
00484
00488 bool Subscribe(
00489 SIPSubscribe::PredefinedPackages eventPackage,
00490 unsigned expire,
00491 const PString & aor
00492 );
00493 bool Subscribe(
00494 const SIPSubscribe::Params & params,
00495 PString & aor
00496 );
00497
00500 bool Unsubscribe(
00501 SIPSubscribe::PredefinedPackages eventPackage,
00502 const PString & aor
00503 );
00504 bool Unsubscribe(
00505 const PString & eventPackage,
00506 const PString & aor
00507 );
00508
00512 bool UnsubcribeAll(
00513 SIPSubscribe::PredefinedPackages eventPackage
00514 );
00515 bool UnsubcribeAll(
00516 const PString & eventPackage
00517 );
00518
00525 PBoolean IsSubscribed(
00526 const PString & eventPackage,
00527 const PString & aor,
00528 bool includeOffline = false
00529 );
00530
00533 unsigned GetSubscriptionCount(
00534 const SIPSubscribe::EventPackage & eventPackage
00535 ) { return activeSIPHandlers.GetCount(SIP_PDU::Method_SUBSCRIBE, eventPackage); }
00536
00539 PStringList GetSubscriptions(
00540 const SIPSubscribe::EventPackage & eventPackage,
00541 bool includeOffline = false
00542 ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_REGISTER, eventPackage); }
00543
00547 virtual void OnSubscriptionStatus(
00548 const PString & eventPackage,
00549 const SIPURL & uri,
00550 bool wasSubscribing,
00551 bool reSubscribing,
00552 SIP_PDU::StatusCodes reason
00553 );
00554
00555 virtual void OnSubscriptionStatus(
00556 SIPSubscribeHandler & handler,
00557 const SIPURL & uri,
00558 bool wasSubscribing,
00559 bool reSubscribing,
00560 SIP_PDU::StatusCodes reason
00561 );
00562
00565 virtual bool CanNotify(
00566 const PString & eventPackage
00567 );
00568
00571 bool Notify(
00572 const SIPURL & targetAddress,
00573 const PString & eventPackage,
00574 const PObject & body
00575 );
00576
00577
00580 virtual void OnDialogInfoReceived(
00581 const SIPDialogNotification & info
00582 );
00583
00584 void SendNotifyDialogInfo(
00585 const SIPDialogNotification & info
00586 );
00587
00590 virtual bool Message(
00591 const PURL & to,
00592 const PString & type,
00593 const PString & body,
00594 PURL & from,
00595 PString & conversationId
00596 );
00597
00602 virtual void OnMessageFailed(
00603 const SIPURL & messageUrl,
00604 SIP_PDU::StatusCodes reason
00605 );
00606
00607
00611 bool Publish(
00612 const SIPSubscribe::Params & params,
00613 const PString & body,
00614 PString & aor
00615 );
00616 bool Publish(
00617 const PString & to,
00618 const PString & body,
00619 unsigned expire = 300
00620 );
00621
00624 PStringList GetPublications(
00625 const SIPSubscribe::EventPackage & eventPackage,
00626 bool includeOffline = false
00627 ) const { return activeSIPHandlers.GetAddresses(includeOffline, SIP_PDU::Method_PUBLISH, eventPackage); }
00628
00629
00633 bool PublishPresence(
00634 const SIPPresenceInfo & info,
00635 unsigned expire = 300
00636 );
00637
00640 virtual void OnPresenceInfoReceived (
00641 const SIPPresenceInfo & info
00642 );
00643 virtual void OnPresenceInfoReceived (
00644 const PString & identity,
00645 const PString & basic,
00646 const PString & note
00647 );
00648
00649
00652 PBoolean Ping(
00653 const PString & to
00654 );
00655
00656
00657 void SetMIMEForm(PBoolean v) { mimeForm = v; }
00658 PBoolean GetMIMEForm() const { return mimeForm; }
00659
00660 void SetMaxRetries(unsigned r) { maxRetries = r; }
00661 unsigned GetMaxRetries() const { return maxRetries; }
00662
00663 void SetRetryTimeouts(
00664 const PTimeInterval & t1,
00665 const PTimeInterval & t2
00666 ) { retryTimeoutMin = t1; retryTimeoutMax = t2; }
00667 const PTimeInterval & GetRetryTimeoutMin() const { return retryTimeoutMin; }
00668 const PTimeInterval & GetRetryTimeoutMax() const { return retryTimeoutMax; }
00669
00670 void SetNonInviteTimeout(
00671 const PTimeInterval & t
00672 ) { nonInviteTimeout = t; }
00673 const PTimeInterval & GetNonInviteTimeout() const { return nonInviteTimeout; }
00674
00675 void SetPduCleanUpTimeout(
00676 const PTimeInterval & t
00677 ) { pduCleanUpTimeout = t; }
00678 const PTimeInterval & GetPduCleanUpTimeout() const { return pduCleanUpTimeout; }
00679
00680 void SetInviteTimeout(
00681 const PTimeInterval & t
00682 ) { inviteTimeout = t; }
00683 const PTimeInterval & GetInviteTimeout() const { return inviteTimeout; }
00684
00685 void SetAckTimeout(
00686 const PTimeInterval & t
00687 ) { ackTimeout = t; }
00688 const PTimeInterval & GetAckTimeout() const { return ackTimeout; }
00689
00690 void SetRegistrarTimeToLive(
00691 const PTimeInterval & t
00692 ) { registrarTimeToLive = t; }
00693 const PTimeInterval & GetRegistrarTimeToLive() const { return registrarTimeToLive; }
00694
00695 void SetNotifierTimeToLive(
00696 const PTimeInterval & t
00697 ) { notifierTimeToLive = t; }
00698 const PTimeInterval & GetNotifierTimeToLive() const { return notifierTimeToLive; }
00699
00700 void SetNATBindingTimeout(
00701 const PTimeInterval & t
00702 ) { natBindingTimeout = t; natBindingTimer.RunContinuous (natBindingTimeout); }
00703 const PTimeInterval & GetNATBindingTimeout() const { return natBindingTimeout; }
00704
00705 void AddTransaction(
00706 SIPTransaction * transaction
00707 ) { transactions.SetAt(transaction->GetTransactionID(), transaction); }
00708
00709 PSafePtr<SIPTransaction> GetTransaction(const PString & transactionID, PSafetyMode mode = PSafeReadWrite)
00710 { return transactions.FindWithLock(transactionID, mode); }
00711
00714 unsigned GetNextCSeq() { return ++lastSentCSeq; }
00715
00718 PBoolean GetAuthentication(const PString & authRealm, PString & realm, PString & user, PString & password);
00719
00725 virtual SIPURL GetRegisteredPartyName(const SIPURL & remoteURL, const OpalTransport & transport);
00726
00727
00730 virtual SIPURL GetDefaultRegisteredPartyName(const OpalTransport & transport);
00731
00732
00744 SIPURL GetContactURL(const OpalTransport &transport, const SIPURL & localURI);
00745
00746
00756 virtual SIPURL GetLocalURL(
00757 const OpalTransport & transport,
00758 const PString & userName = PString::Empty()
00759 );
00760
00761
00764 const SIPURL & GetProxy() const { return proxy; }
00765
00766
00769 void SetProxy(const SIPURL & url);
00770
00771
00774 void SetProxy(
00775 const PString & hostname,
00776 const PString & username,
00777 const PString & password
00778 );
00779
00780
00783 int GetDefaultAppearanceCode() const { return m_defaultAppearanceCode; }
00784
00787 void SetDefaultAppearanceCode(int code) { m_defaultAppearanceCode = code; }
00788
00795 virtual PString GetUserAgent() const;
00796
00799 void SetUserAgent(const PString & str) { userAgentString = str; }
00800
00801
00804 virtual unsigned GetAllowedMethods() const;
00805
00806
00809 enum NATBindingRefreshMethod{
00810 None,
00811 Options,
00812 EmptyRequest,
00813 NumMethods
00814 };
00815
00816
00819 void SetNATBindingRefreshMethod(const NATBindingRefreshMethod m) { natMethod = m; }
00820
00821 virtual SIPRegisterHandler * CreateRegisterHandler(const SIPRegister::Params & params);
00822
00823 virtual void OnStartTransaction(SIPConnection & conn, SIPTransaction & transaction);
00824
00825 #if OPAL_HAS_SIPIM
00826 virtual OpalSIPIMManager & GetSIPIMManager() { return m_sipIMManager; }
00827 #endif
00828
00829 protected:
00830 PDECLARE_NOTIFIER(PThread, SIPEndPoint, TransportThreadMain);
00831 PDECLARE_NOTIFIER(PTimer, SIPEndPoint, NATBindingRefresh);
00832
00833 SIPURL proxy;
00834 PString userAgentString;
00835
00836 bool mimeForm;
00837 unsigned maxRetries;
00838 PTimeInterval retryTimeoutMin;
00839 PTimeInterval retryTimeoutMax;
00840 PTimeInterval nonInviteTimeout;
00841 PTimeInterval pduCleanUpTimeout;
00842 PTimeInterval inviteTimeout;
00843 PTimeInterval ackTimeout;
00844 PTimeInterval registrarTimeToLive;
00845 PTimeInterval notifierTimeToLive;
00846 PTimeInterval natBindingTimeout;
00847
00848 bool m_shuttingDown;
00849 SIPHandlersList activeSIPHandlers;
00850 PStringToString m_receivedConnectionTokens;
00851
00852 PSafeDictionary<PString, SIPTransaction> transactions;
00853
00854 PTimer natBindingTimer;
00855 NATBindingRefreshMethod natMethod;
00856 PAtomicInteger lastSentCSeq;
00857 int m_defaultAppearanceCode;
00858
00859 public:
00860 class WorkThreadPool;
00861 class SIP_Work
00862 {
00863 public:
00864 SIP_Work(SIPEndPoint & ep, SIP_PDU * pdu, const PString & token);
00865 virtual ~SIP_Work();
00866
00867 virtual void Process();
00868
00869 SIPEndPoint & m_endpoint;
00870 SIP_PDU * m_pdu;
00871 PString m_token;
00872 };
00873
00874 class WorkThreadPool : public PThreadPool<SIP_Work>
00875 {
00876 public:
00877 virtual WorkerThreadBase * CreateWorkerThread();
00878 } m_connectionThreadPool, m_handlerThreadPool;
00879
00880 protected:
00881 typedef std::queue<SIP_Work *> SIP_WorkQueue;
00882
00883 class SIP_Work_Thread : public WorkThreadPool::WorkerThread
00884 {
00885 public:
00886 SIP_Work_Thread(WorkThreadPool & pool_);
00887
00888 void AddWork(SIP_Work * work);
00889 void RemoveWork(SIP_Work * work);
00890 unsigned GetWorkSize() const;
00891
00892 void Main();
00893 void Shutdown();
00894
00895 protected:
00896 PSyncPoint m_sync;
00897 SIP_WorkQueue m_pduQueue;
00898 };
00899
00900 enum {
00901 HighPriority = 80,
00902 LowPriority = 30,
00903 };
00904 class InterfaceMonitor : public PInterfaceMonitorClient
00905 {
00906 PCLASSINFO(InterfaceMonitor, PInterfaceMonitorClient);
00907 public:
00908 InterfaceMonitor(SIPEndPoint & manager, PINDEX priority);
00909
00910 virtual void OnAddInterface(const PIPSocket::InterfaceEntry & entry);
00911 virtual void OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
00912
00913 protected:
00914 SIPEndPoint & m_endpoint;
00915 };
00916 InterfaceMonitor m_highPriorityMonitor;
00917 InterfaceMonitor m_lowPriorityMonitor;
00918
00919 friend void InterfaceMonitor::OnAddInterface(const PIPSocket::InterfaceEntry & entry);
00920 friend void InterfaceMonitor::OnRemoveInterface(const PIPSocket::InterfaceEntry & entry);
00921
00922 #if OPAL_HAS_SIPIM
00923 OpalSIPIMManager m_sipIMManager;
00924 #endif
00925
00926 bool m_disableTrying;
00927 };
00928
00929
00930 #endif // OPAL_SIP
00931
00932 #endif // OPAL_SIP_SIPEP_H
00933
00934
00935