# handlers.h

Go to the documentation of this file.

    00001 /*
    00002  * handlers.h
    00003  *
    00004  * Session Initiation Protocol endpoint.
    00005  *
    00006  * Open Phone Abstraction Library (OPAL)
    00007  *
    00008  * Copyright (c) 2000 Equivalence Pty. Ltd.
    00009  *
    00010  * The contents of this file are subject to the Mozilla Public License
    00011  * Version 1.0 (the "License"); you may not use this file except in
    00012  * compliance with the License. You may obtain a copy of the License at
    00013  * http://www.mozilla.org/MPL/
    00014  *
    00015  * Software distributed under the License is distributed on an "AS IS"
    00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
    00017  * the License for the specific language governing rights and limitations
    00018  * under the License.
    00019  *
    00020  * The Original Code is Open Phone Abstraction Library.
    00021  *
    00022  * The Initial Developer of the Original Code is Damien Sandras.
    00023  *
    00024  * Contributor(s): ______________________________________.
    00025  *
    00026  * $Revision: 28428 $
    00027  * $Author: rjongbloed $
    00028  * $Date: 2012-10-01 03:38:50 -0500 (Mon, 01 Oct 2012) $
    00029  */
    00030
    00031 #ifndef OPAL_SIP_HANDLERS_H
    00032 #define OPAL_SIP_HANDLERS_H
    00033
    00034 #ifdef P_USE_PRAGMA
    00035 #pragma interface
    00036 #endif
    00037
    00038 #ifndef _PTLIB_H
    00039 #include <ptlib.h>
    00040 #endif
    00041
    00042 #include <opal/buildopts.h>
    00043
    00044 #if OPAL_SIP
    00045
    00046 #include <opal/pres_ent.h>
    00047 #include <opal/connection.h>
    00048 #include <sip/sippdu.h>
    00049
    00050
    00051 /* Class to handle SIP REGISTER, SUBSCRIBE, MESSAGE, and renew
    00052  * the 'bindings' before they expire.
    00053  */
    00054 class SIPHandler : public PSafeObject
    00055 {
    00056   PCLASSINFO(SIPHandler, PSafeObject);
    00057
    00058 protected:
    00059   SIPHandler(
    00060     SIP_PDU::Methods method,
    00061     SIPEndPoint & ep,
    00062     const SIPParameters & params
    00063   );
    00064
    00065 public:
    00066   ~SIPHandler();
    00067
    00068   virtual Comparison Compare(const PObject & other) const;
    00069
    00070   virtual bool ShutDown();
    00071
    00072   enum State {
    00073     Subscribed,       // The registration is active
    00074     Subscribing,      // The registration is in process
    00075     Unavailable,      // The registration is offline and still being attempted
    00076     Refreshing,       // The registration is being refreshed
    00077     Restoring,        // The registration is trying to be restored after being offline
    00078     Unsubscribing,    // The unregistration is in process
    00079     Unsubscribed,     // The registrating is inactive
    00080     NumStates
    00081   };
    00082
    00083   void SetState (SIPHandler::State s);
    00084
    00085   inline SIPHandler::State GetState ()
    00086   { return m_state; }
    00087
    00088   virtual OpalTransport * GetTransport();
    00089
    00090   virtual SIPAuthentication * GetAuthentication()
    00091   { return m_authentication; }
    00092
    00093   virtual const SIPURL & GetAddressOfRecord()
    00094     { return m_addressOfRecord; }
    00095
    00096   virtual PBoolean OnReceivedNOTIFY(SIP_PDU & response);
    00097
    00098   virtual void SetExpire(int e);
    00099
    00100   virtual int GetExpire()
    00101     { return m_currentExpireTime; }
    00102
    00103   virtual const PString & GetCallID() const
    00104     { return m_callID; }
    00105
    00106   virtual void SetBody(const PString & /*body*/) { }
    00107
    00108   virtual bool IsDuplicateCSeq(unsigned ) { return false; }
    00109
    00110   virtual SIPTransaction * CreateTransaction(OpalTransport & t) = 0;
    00111
    00112   SIP_PDU::Methods GetMethod() const { return m_method; }
    00113   virtual SIPSubscribe::EventPackage GetEventPackage() const { return SIPEventPackage(); }
    00114
    00115   virtual void OnReceivedResponse(SIPTransaction & transaction, SIP_PDU & response);
    00116   virtual void OnReceivedIntervalTooBrief(SIPTransaction & transaction, SIP_PDU & response);
    00117   virtual void OnReceivedTemporarilyUnavailable(SIPTransaction & transaction, SIP_PDU & response);
    00118   virtual void OnReceivedAuthenticationRequired(SIPTransaction & transaction, SIP_PDU & response);
    00119   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
    00120   virtual void OnTransactionFailed(SIPTransaction & transaction);
    00121
    00122   virtual void OnFailed(const SIP_PDU & response);
    00123   virtual void OnFailed(SIP_PDU::StatusCodes);
    00124
    00125   bool ActivateState(SIPHandler::State state);
    00126   virtual bool SendNotify(const PObject * /*body*/) { return false; }
    00127
    00128   SIPEndPoint & GetEndPoint() const { return endpoint; }
    00129
    00130   const OpalProductInfo & GetProductInfo() const { return m_productInfo; }
    00131
    00132   const PString & GetUsername() const     { return m_username; }
    00133   const PString & GetPassword() const     { return m_password; }
    00134   const PString & GetRealm() const        { return m_realm; }
    00135   const SIPURL & GetRemoteAddress() const { return m_remoteAddress; }
    00136   const SIPURL & GetProxy() const         { return m_proxy; }
    00137
    00138   SIPMIMEInfo m_mime;
    00139
    00140 protected:
    00141   virtual PBoolean SendRequest(SIPHandler::State state);
    00142   void RetryLater(unsigned after);
    00143   PDECLARE_NOTIFIER(PTimer, SIPHandler, OnExpireTimeout);
    00144   static PBoolean WriteSIPHandler(OpalTransport & transport, void * info);
    00145   virtual bool WriteSIPHandler(OpalTransport & transport, bool forked);
    00146
    00147   SIPEndPoint               & endpoint;
    00148
    00149   SIPAuthentication         * m_authentication;
    00150   unsigned                    m_authenticateErrors;
    00151   PString                     m_username;
    00152   PString                     m_password;
    00153   PString                     m_realm;
    00154
    00155   PSafeList<SIPTransaction>   m_transactions;
    00156   OpalTransport             * m_transport;
    00157
    00158   SIP_PDU::Methods            m_method;
    00159   SIPURL                      m_addressOfRecord;
    00160   SIPURL                      m_remoteAddress;
    00161   PString                     m_callID;
    00162   unsigned                    m_lastCseq;
    00163   int                         m_currentExpireTime;
    00164   int                         m_originalExpireTime;
    00165   int                         m_offlineExpireTime;
    00166   State                       m_state;
    00167   queue<State>                m_stateQueue;
    00168   bool                        m_receivedResponse;
    00169   PTimer                      m_expireTimer;
    00170   SIPURL                      m_proxy;
    00171   OpalProductInfo             m_productInfo;
    00172
    00173   // Keep a copy of the keys used for easy removal on destruction
    00174   typedef std::map<PString, PSafePtr<SIPHandler> > IndexMap;
    00175   std::pair<IndexMap::iterator, bool> m_byCallID;
    00176   std::pair<IndexMap::iterator, bool> m_byAorAndPackage;
    00177   std::pair<IndexMap::iterator, bool> m_byAuthIdAndRealm;
    00178   std::pair<IndexMap::iterator, bool> m_byAorUserAndRealm;
    00179
    00180   friend class SIPHandlersList;
    00181 };
    00182
    00183 #if PTRACING
    00184 ostream & operator<<(ostream & strm, SIPHandler::State state);
    00185 #endif
    00186
    00187
    00188 class SIPRegisterHandler : public SIPHandler
    00189 {
    00190   PCLASSINFO(SIPRegisterHandler, SIPHandler);
    00191
    00192 public:
    00193   SIPRegisterHandler(
    00194     SIPEndPoint & ep,
    00195     const SIPRegister::Params & params
    00196   );
    00197
    00198   virtual SIPTransaction * CreateTransaction(OpalTransport &);
    00199   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
    00200
    00201   virtual void OnFailed(SIP_PDU::StatusCodes r);
    00202
    00203   void UpdateParameters(const SIPRegister::Params & params);
    00204
    00205   const SIPRegister::Params & GetParams() const { return m_parameters; }
    00206
    00207   const SIPURLList & GetContacts() const { return m_contactAddresses; }
    00208   const SIPURLList & GetServiceRoute() const { return m_serviceRoute; }
    00209
    00210 protected:
    00211   virtual PBoolean SendRequest(SIPHandler::State state);
    00212   void SendStatus(SIP_PDU::StatusCodes code, State state);
    00213
    00214   SIPRegister::Params  m_parameters;
    00215   unsigned             m_sequenceNumber;
    00216   SIPURLList           m_contactAddresses;
    00217   SIPURLList           m_serviceRoute;
    00218   OpalTransportAddress m_externalAddress;
    00219 };
    00220
    00221
    00222 class SIPSubscribeHandler : public SIPHandler
    00223 {
    00224   PCLASSINFO(SIPSubscribeHandler, SIPHandler);
    00225 public:
    00226   SIPSubscribeHandler(SIPEndPoint & ep, const SIPSubscribe::Params & params);
    00227   ~SIPSubscribeHandler();
    00228
    00229   virtual SIPTransaction * CreateTransaction (OpalTransport &);
    00230   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
    00231   virtual PBoolean OnReceivedNOTIFY(SIP_PDU & response);
    00232   virtual void OnFailed(const SIP_PDU & response);
    00233   virtual SIPEventPackage GetEventPackage() const
    00234     { return m_parameters.m_eventPackage; }
    00235
    00236   void UpdateParameters(const SIPSubscribe::Params & params);
    00237
    00238   virtual bool IsDuplicateCSeq(unsigned sequenceNumber) { return m_dialog.IsDuplicateCSeq(sequenceNumber); }
    00239
    00240   const SIPSubscribe::Params & GetParams() const { return m_parameters; }
    00241
    00242 protected:
    00243   virtual PBoolean SendRequest(SIPHandler::State state);
    00244   virtual bool WriteSIPHandler(OpalTransport & transport, bool forked);
    00245   void SendStatus(SIP_PDU::StatusCodes code, State state);
    00246   bool DispatchNOTIFY(SIP_PDU & request, SIP_PDU & response);
    00247
    00248   SIPSubscribe::Params     m_parameters;
    00249   SIPDialogContext         m_dialog;
    00250   bool                     m_unconfirmed;
    00251   SIPEventPackageHandler * m_packageHandler;
    00252
    00253   SIP_PDU                  * m_previousResponse;
    00254 };
    00255
    00256
    00257 class SIPNotifyHandler : public SIPHandler
    00258 {
    00259   PCLASSINFO(SIPNotifyHandler, SIPHandler);
    00260 public:
    00261   SIPNotifyHandler(
    00262     SIPEndPoint & ep,
    00263     const PString & targetAddress,
    00264     const SIPEventPackage & eventPackage,
    00265     const SIPDialogContext & dialog
    00266   );
    00267   ~SIPNotifyHandler();
    00268
    00269   virtual SIPTransaction * CreateTransaction(OpalTransport &);
    00270   virtual SIPEventPackage GetEventPackage() const
    00271     { return m_eventPackage; }
    00272
    00273   virtual void SetBody(const PString & body) { m_body = body; }
    00274
    00275   virtual bool IsDuplicateCSeq(unsigned sequenceNumber) { return m_dialog.IsDuplicateCSeq(sequenceNumber); }
    00276   virtual bool SendNotify(const PObject * body);
    00277
    00278   enum Reasons {
    00279     Deactivated,
    00280     Probation,
    00281     Rejected,
    00282     Timeout,
    00283     GiveUp,
    00284     NoResource
    00285   };
    00286
    00287 protected:
    00288   virtual PBoolean SendRequest(SIPHandler::State state);
    00289   virtual bool WriteSIPHandler(OpalTransport & transport, bool forked);
    00290
    00291   SIPEventPackage          m_eventPackage;
    00292   SIPDialogContext         m_dialog;
    00293   Reasons                  m_reason;
    00294   SIPEventPackageHandler * m_packageHandler;
    00295   PString                  m_body;
    00296 };
    00297
    00298
    00299 class SIPPublishHandler : public SIPHandler
    00300 {
    00301   PCLASSINFO(SIPPublishHandler, SIPHandler);
    00302
    00303 public:
    00304   SIPPublishHandler(SIPEndPoint & ep,
    00305                     const SIPSubscribe::Params & params,
    00306                     const PString & body);
    00307
    00308   virtual void SetBody(const PString & body) { m_body = body; }
    00309
    00310   virtual SIPTransaction * CreateTransaction(OpalTransport &);
    00311   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
    00312   virtual SIPEventPackage GetEventPackage() const { return m_parameters.m_eventPackage; }
    00313
    00314 protected:
    00315   SIPSubscribe::Params m_parameters;
    00316   PString              m_body;
    00317   PString              m_sipETag;
    00318 };
    00319
    00320
    00321 class SIPMessageHandler : public SIPHandler
    00322 {
    00323   PCLASSINFO(SIPMessageHandler, SIPHandler);
    00324 public:
    00325   SIPMessageHandler(SIPEndPoint & ep, const SIPMessage::Params & params);
    00326
    00327   virtual SIPTransaction * CreateTransaction (OpalTransport &);
    00328   virtual void OnFailed(SIP_PDU::StatusCodes);
    00329   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
    00330
    00331   void UpdateParameters(const SIPMessage::Params & params);
    00332
    00333 protected:
    00334   SIPMessage::Params m_parameters;
    00335 };
    00336
    00337
    00338 class SIPOptionsHandler : public SIPHandler
    00339 {
    00340   PCLASSINFO(SIPOptionsHandler, SIPHandler);
    00341 public:
    00342   SIPOptionsHandler(SIPEndPoint & ep, const SIPOptions::Params & params);
    00343
    00344   virtual SIPTransaction * CreateTransaction (OpalTransport &);
    00345   virtual void OnFailed(SIP_PDU::StatusCodes);
    00346   virtual void OnFailed(const SIP_PDU & response);
    00347   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
    00348
    00349 protected:
    00350   SIPOptions::Params m_parameters;
    00351 };
    00352
    00353
    00354 class SIPPingHandler : public SIPHandler
    00355 {
    00356   PCLASSINFO(SIPPingHandler, SIPHandler);
    00357 public:
    00358   SIPPingHandler(SIPEndPoint & ep, const PURL & to);
    00359   virtual SIPTransaction * CreateTransaction (OpalTransport &);
    00360 };
    00361
    00362
    00366 class SIPHandlersList
    00367 {
    00368   public:
    00371     void Append(SIPHandler * handler);
    00372
    00377     void Remove(SIPHandler * handler);
    00378
    00381     void Update(SIPHandler * handler);
    00382
    00385     bool DeleteObjectsToBeRemoved()
    00386       { return m_handlersList.DeleteObjectsToBeRemoved(); }
    00387
    00391     PSafePtr<SIPHandler> GetFirstHandler(PSafetyMode mode = PSafeReference) const
    00392       { return PSafePtr<SIPHandler>(m_handlersList, mode); }
    00393
    00397     unsigned GetCount(SIP_PDU::Methods meth, const PString & eventPackage = PString::Empty()) const;
    00398
    00402     PStringList GetAddresses(bool includeOffline, SIP_PDU::Methods meth, const PString & eventPackage = PString::Empty()) const;
    00403
    00407     PSafePtr<SIPHandler> FindSIPHandlerByCallID(const PString & callID, PSafetyMode m);
    00408
    00412     PSafePtr<SIPHandler> FindSIPHandlerByAuthRealm(const PString & authRealm, PSafetyMode m);
    00413
    00417     PSafePtr<SIPHandler> FindSIPHandlerByAuthRealm(const PString & authRealm, const PString & userName, PSafetyMode m);
    00418
    00426     PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, PSafetyMode m);
    00427     PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, const PString & eventPackage, PSafetyMode m);
    00428
    00434     PSafePtr <SIPHandler> FindSIPHandlerByDomain(const PString & name, SIP_PDU::Methods meth, PSafetyMode m);
    00435
    00436   protected:
    00437     void RemoveIndexes(SIPHandler * handler);
    00438
    00439     PMutex m_extraMutex;
    00440     PSafeList<SIPHandler> m_handlersList;
    00441
    00442     typedef SIPHandler::IndexMap IndexMap;
    00443     PSafePtr<SIPHandler> FindBy(IndexMap & by, const PString & key, PSafetyMode m);
    00444
    00445     IndexMap m_byCallID;
    00446     IndexMap m_byAorAndPackage;
    00447     IndexMap m_byAuthIdAndRealm;
    00448     IndexMap m_byAorUserAndRealm;
    00449 };
    00450
    00451
    00454 class SIPPresenceInfo : public OpalPresenceInfo
    00455 {
    00456 public:
    00457   SIPPresenceInfo(
    00458     State state = Unchanged
    00459   );
    00460
    00461   // basic presence defined by RFC 3863
    00462   PString m_tupleId;
    00463   PString m_contact;
    00464
    00465   // presence extensions defined by RFC 4480
    00466   PStringArray m_activities;  // list of activities, seperated by newline
    00467
    00468   // presence agent
    00469   PString m_presenceAgent;
    00470
    00471   PString AsXML() const;
    00472
    00473 #if P_EXPAT
    00474   static bool ParseXML(
    00475     const PString & body,
    00476     list<SIPPresenceInfo> & info,
    00477     PString & error
    00478   );
    00479 #endif
    00480
    00481   void PrintOn(ostream & strm) const;
    00482   friend ostream & operator<<(ostream & strm, const SIPPresenceInfo & info) { info.PrintOn(strm); return strm; }
    00483
    00484   static State FromSIPActivityString(const PString & str);
    00485
    00486   static bool AsSIPActivityString(State state, PString & str);
    00487   bool AsSIPActivityString(PString & str) const;
    00488
    00489   PString m_personId;
    00490 };
    00491
    00492
    00495 struct SIPDialogNotification : public PObject
    00496 {
    00497   PCLASSINFO(SIPDialogNotification, PObject);
    00498
    00499   enum States {
    00500     Terminated,
    00501     Trying,
    00502     Proceeding,
    00503     Early,
    00504     Confirmed,
    00505
    00506     FirstState = Terminated,
    00507     LastState = Confirmed
    00508   };
    00509   friend States operator++(States & state) { return (state = (States)(state+1)); }
    00510   friend States operator--(States & state) { return (state = (States)(state-1)); }
    00511   static PString GetStateName(States state);
    00512   PString GetStateName() const { return GetStateName(m_state); }
    00513
    00514   enum Events {
    00515     NoEvent = -1,
    00516     Cancelled,
    00517     Rejected,
    00518     Replaced,
    00519     LocalBye,
    00520     RemoteBye,
    00521     Error,
    00522     Timeout,
    00523
    00524     FirstEvent = Cancelled,
    00525     LastEvent = Timeout
    00526   };
    00527   friend Events operator++(Events & evt) { return (evt = (Events)(evt+1)); }
    00528   friend Events operator--(Events & evt) { return (evt = (Events)(evt-1)); }
    00529   static PString GetEventName(Events state);
    00530   PString GetEventName() const { return GetEventName(m_eventType); }
    00531
    00532   enum Rendering {
    00533     RenderingUnknown = -1,
    00534     NotRenderingMedia,
    00535     RenderingMedia
    00536   };
    00537
    00538   PString  m_entity;
    00539   PString  m_dialogId;
    00540   PString  m_callId;
    00541   bool     m_initiator;
    00542   States   m_state;
    00543   Events   m_eventType;
    00544   unsigned m_eventCode;
    00545   struct Participant {
    00546     Participant() : m_appearance(-1), m_byeless(false), m_rendering(RenderingUnknown) { }
    00547     PString   m_URI;
    00548     PString   m_dialogTag;
    00549     PString   m_identity;
    00550     PString   m_display;
    00551     int       m_appearance;
    00552     bool      m_byeless;
    00553     Rendering m_rendering;
    00554   } m_local, m_remote;
    00555
    00556   SIPDialogNotification(const PString & entity = PString::Empty());
    00557
    00558   void PrintOn(ostream & strm) const;
    00559 };
    00560
    00561
    00562 #endif // OPAL_SIP
    00563
    00564 #endif // OPAL_SIP_HANDLERS_H