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

Generated on 14 Aug 2013 for OPAL by  doxygen 1.4.7