OPAL  Version 3.10.4
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: 26833 $
00027  * $Author: rjongbloed $
00028  * $Date: 2011-12-22 23:24:13 -0600 (Thu, 22 Dec 2011) $
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 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         * authentication;
00150   PString                     m_username;
00151   PString                     m_password;
00152   PString                     m_realm;
00153 
00154   PSafeList<SIPTransaction>   m_transactions;
00155   OpalTransport             * m_transport;
00156 
00157   SIP_PDU::Methods            m_method;
00158   SIPURL                      m_addressOfRecord;
00159   SIPURL                      m_remoteAddress;
00160   PString                     m_callID;
00161   unsigned                    m_lastCseq;
00162   int                         m_currentExpireTime;
00163   int                         m_originalExpireTime;
00164   int                         m_offlineExpireTime;
00165   State                       m_state;
00166   queue<State>                m_stateQueue;
00167   bool                        m_receivedResponse;
00168   PTimer                      m_expireTimer; 
00169   SIPURL                      m_proxy;
00170   OpalProductInfo             m_productInfo;
00171 
00172   // Keep a copy of the keys used for easy removal on destruction
00173   typedef std::map<PString, PSafePtr<SIPHandler> > IndexMap;
00174   std::pair<IndexMap::iterator, bool> m_byCallID;
00175   std::pair<IndexMap::iterator, bool> m_byAorAndPackage;
00176   std::pair<IndexMap::iterator, bool> m_byAuthIdAndRealm;
00177   std::pair<IndexMap::iterator, bool> m_byAorUserAndRealm;
00178 
00179   friend class SIPHandlersList;
00180 };
00181 
00182 #if PTRACING
00183 ostream & operator<<(ostream & strm, SIPHandler::State state);
00184 #endif
00185 
00186 
00187 class SIPRegisterHandler : public SIPHandler
00188 {
00189   PCLASSINFO(SIPRegisterHandler, SIPHandler);
00190 
00191 public:
00192   SIPRegisterHandler(
00193     SIPEndPoint & ep,
00194     const SIPRegister::Params & params
00195   );
00196 
00197   virtual SIPTransaction * CreateTransaction(OpalTransport &);
00198   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
00199 
00200   virtual void OnFailed(SIP_PDU::StatusCodes r);
00201 
00202   void UpdateParameters(const SIPRegister::Params & params);
00203 
00204   const SIPRegister::Params & GetParams() const { return m_parameters; }
00205 
00206   const SIPURLList & GetContacts() const { return m_contactAddresses; }
00207   const SIPURLList & GetServiceRoute() const { return m_serviceRoute; }
00208 
00209 protected:
00210   virtual PBoolean SendRequest(SIPHandler::State state);
00211   void SendStatus(SIP_PDU::StatusCodes code, State state);
00212 
00213   SIPRegister::Params  m_parameters;
00214   unsigned             m_sequenceNumber;
00215   SIPURLList           m_contactAddresses;
00216   SIPURLList           m_serviceRoute;
00217   OpalTransportAddress m_externalAddress;
00218 };
00219 
00220 
00221 class SIPSubscribeHandler : public SIPHandler
00222 {
00223   PCLASSINFO(SIPSubscribeHandler, SIPHandler);
00224 public:
00225   SIPSubscribeHandler(SIPEndPoint & ep, const SIPSubscribe::Params & params);
00226   ~SIPSubscribeHandler();
00227 
00228   virtual SIPTransaction * CreateTransaction (OpalTransport &);
00229   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
00230   virtual PBoolean OnReceivedNOTIFY(SIP_PDU & response);
00231   virtual void OnFailed(const SIP_PDU & response);
00232   virtual SIPEventPackage GetEventPackage() const
00233     { return m_parameters.m_eventPackage; }
00234 
00235   void UpdateParameters(const SIPSubscribe::Params & params);
00236 
00237   virtual bool IsDuplicateCSeq(unsigned sequenceNumber) { return m_dialog.IsDuplicateCSeq(sequenceNumber); }
00238 
00239   const SIPSubscribe::Params & GetParams() const { return m_parameters; }
00240 
00241 protected:
00242   virtual PBoolean SendRequest(SIPHandler::State state);
00243   virtual bool WriteSIPHandler(OpalTransport & transport, bool forked);
00244   void SendStatus(SIP_PDU::StatusCodes code, State state);
00245   bool DispatchNOTIFY(SIP_PDU & request, SIP_PDU & response);
00246 
00247   SIPSubscribe::Params     m_parameters;
00248   SIPDialogContext         m_dialog;
00249   bool                     m_unconfirmed;
00250   SIPEventPackageHandler * m_packageHandler;
00251 
00252   SIP_PDU                  * m_previousResponse;
00253 };
00254 
00255 
00256 class SIPNotifyHandler : public SIPHandler
00257 {
00258   PCLASSINFO(SIPNotifyHandler, SIPHandler);
00259 public:
00260   SIPNotifyHandler(
00261     SIPEndPoint & ep,
00262     const PString & targetAddress,
00263     const SIPEventPackage & eventPackage,
00264     const SIPDialogContext & dialog
00265   );
00266   ~SIPNotifyHandler();
00267 
00268   virtual SIPTransaction * CreateTransaction(OpalTransport &);
00269   virtual SIPEventPackage GetEventPackage() const
00270     { return m_eventPackage; }
00271 
00272   virtual void SetBody(const PString & body) { m_body = body; }
00273 
00274   virtual bool IsDuplicateCSeq(unsigned sequenceNumber) { return m_dialog.IsDuplicateCSeq(sequenceNumber); }
00275   virtual bool SendNotify(const PObject * body);
00276 
00277   enum Reasons {
00278     Deactivated,
00279     Probation,
00280     Rejected,
00281     Timeout,
00282     GiveUp,
00283     NoResource
00284   };
00285 
00286 protected:
00287   virtual PBoolean SendRequest(SIPHandler::State state);
00288   virtual bool WriteSIPHandler(OpalTransport & transport, bool forked);
00289 
00290   SIPEventPackage          m_eventPackage;
00291   SIPDialogContext         m_dialog;
00292   Reasons                  m_reason;
00293   SIPEventPackageHandler * m_packageHandler;
00294   PString                  m_body;
00295 };
00296 
00297 
00298 class SIPPublishHandler : public SIPHandler
00299 {
00300   PCLASSINFO(SIPPublishHandler, SIPHandler);
00301 
00302 public:
00303   SIPPublishHandler(SIPEndPoint & ep, 
00304                     const SIPSubscribe::Params & params,
00305                     const PString & body);
00306 
00307   virtual void SetBody(const PString & body) { m_body = body; }
00308 
00309   virtual SIPTransaction * CreateTransaction(OpalTransport &);
00310   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
00311   virtual SIPEventPackage GetEventPackage() const { return m_parameters.m_eventPackage; }
00312 
00313 protected:
00314   SIPSubscribe::Params m_parameters;
00315   PString              m_body;
00316   PString              m_sipETag;
00317 };
00318 
00319 
00320 class SIPMessageHandler : public SIPHandler
00321 {
00322   PCLASSINFO(SIPMessageHandler, SIPHandler);
00323 public:
00324   SIPMessageHandler(SIPEndPoint & ep, const SIPMessage::Params & params);
00325 
00326   virtual SIPTransaction * CreateTransaction (OpalTransport &);
00327   virtual void OnFailed(SIP_PDU::StatusCodes);
00328   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
00329 
00330   void UpdateParameters(const SIPMessage::Params & params);
00331 
00332 protected:
00333   SIPMessage::Params m_parameters;
00334 };
00335 
00336 
00337 class SIPOptionsHandler : public SIPHandler
00338 {
00339   PCLASSINFO(SIPOptionsHandler, SIPHandler);
00340 public:
00341   SIPOptionsHandler(SIPEndPoint & ep, const SIPOptions::Params & params);
00342 
00343   virtual SIPTransaction * CreateTransaction (OpalTransport &);
00344   virtual void OnFailed(SIP_PDU::StatusCodes);
00345   virtual void OnFailed(const SIP_PDU & response);
00346   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
00347 
00348 protected:
00349   SIPOptions::Params m_parameters;
00350 };
00351 
00352 
00353 class SIPPingHandler : public SIPHandler
00354 {
00355   PCLASSINFO(SIPPingHandler, SIPHandler);
00356 public:
00357   SIPPingHandler(SIPEndPoint & ep, const PURL & to);
00358   virtual SIPTransaction * CreateTransaction (OpalTransport &);
00359 };
00360 
00361 
00365 class SIPHandlersList
00366 {
00367   public:
00370     void Append(SIPHandler * handler);
00371 
00376     void Remove(SIPHandler * handler);
00377 
00380     void Update(SIPHandler * handler);
00381 
00384     bool DeleteObjectsToBeRemoved()
00385       { return m_handlersList.DeleteObjectsToBeRemoved(); }
00386 
00390     PSafePtr<SIPHandler> GetFirstHandler(PSafetyMode mode = PSafeReference) const
00391       { return PSafePtr<SIPHandler>(m_handlersList, mode); }
00392 
00396     unsigned GetCount(SIP_PDU::Methods meth, const PString & eventPackage = PString::Empty()) const;
00397 
00401     PStringList GetAddresses(bool includeOffline, SIP_PDU::Methods meth, const PString & eventPackage = PString::Empty()) const;
00402 
00406     PSafePtr<SIPHandler> FindSIPHandlerByCallID(const PString & callID, PSafetyMode m);
00407 
00411     PSafePtr<SIPHandler> FindSIPHandlerByAuthRealm(const PString & authRealm, PSafetyMode m);
00412 
00416     PSafePtr<SIPHandler> FindSIPHandlerByAuthRealm(const PString & authRealm, const PString & userName, PSafetyMode m);
00417 
00425     PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, PSafetyMode m);
00426     PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, const PString & eventPackage, PSafetyMode m);
00427 
00433     PSafePtr <SIPHandler> FindSIPHandlerByDomain(const PString & name, SIP_PDU::Methods meth, PSafetyMode m);
00434 
00435   protected:
00436     void RemoveIndexes(SIPHandler * handler);
00437 
00438     PMutex m_extraMutex;
00439     PSafeList<SIPHandler> m_handlersList;
00440 
00441     typedef SIPHandler::IndexMap IndexMap;
00442     PSafePtr<SIPHandler> FindBy(IndexMap & by, const PString & key, PSafetyMode m);
00443 
00444     IndexMap m_byCallID;
00445     IndexMap m_byAorAndPackage;
00446     IndexMap m_byAuthIdAndRealm;
00447     IndexMap m_byAorUserAndRealm;
00448 };
00449 
00450 
00453 class SIPPresenceInfo : public OpalPresenceInfo
00454 {
00455 public:
00456   SIPPresenceInfo(
00457     State state = Unchanged
00458   );
00459 
00460   // basic presence defined by RFC 3863
00461   PString m_tupleId;
00462   PString m_contact;
00463 
00464   // presence extensions defined by RFC 4480
00465   PStringArray m_activities;  // list of activities, seperated by newline
00466 
00467   // presence agent
00468   PString m_presenceAgent;
00469 
00470   PString AsXML() const;
00471 
00472 #if P_EXPAT
00473   static bool ParseXML(
00474     const PString & body,
00475     list<SIPPresenceInfo> & info,
00476     PString & error
00477   );
00478 #endif
00479 
00480   void PrintOn(ostream & strm) const;
00481   friend ostream & operator<<(ostream & strm, const SIPPresenceInfo & info) { info.PrintOn(strm); return strm; }
00482 
00483   static State FromSIPActivityString(const PString & str);
00484 
00485   static bool AsSIPActivityString(State state, PString & str);
00486   bool AsSIPActivityString(PString & str) const;
00487 
00488   PString m_personId;
00489 };
00490 
00491 
00494 struct SIPDialogNotification : public PObject
00495 {
00496   PCLASSINFO(SIPDialogNotification, PObject);
00497 
00498   enum States {
00499     Terminated,
00500     Trying,
00501     Proceeding,
00502     Early,
00503     Confirmed,
00504 
00505     FirstState = Terminated,
00506     LastState = Confirmed
00507   };
00508   friend States operator++(States & state) { return (state = (States)(state+1)); }
00509   friend States operator--(States & state) { return (state = (States)(state-1)); }
00510   static PString GetStateName(States state);
00511   PString GetStateName() const { return GetStateName(m_state); }
00512 
00513   enum Events {
00514     NoEvent = -1,
00515     Cancelled,
00516     Rejected,
00517     Replaced,
00518     LocalBye,
00519     RemoteBye,
00520     Error,
00521     Timeout,
00522 
00523     FirstEvent = Cancelled,
00524     LastEvent = Timeout
00525   };
00526   friend Events operator++(Events & evt) { return (evt = (Events)(evt+1)); }
00527   friend Events operator--(Events & evt) { return (evt = (Events)(evt-1)); }
00528   static PString GetEventName(Events state);
00529   PString GetEventName() const { return GetEventName(m_eventType); }
00530 
00531   enum Rendering {
00532     RenderingUnknown = -1,
00533     NotRenderingMedia,
00534     RenderingMedia
00535   };
00536 
00537   PString  m_entity;
00538   PString  m_dialogId;
00539   PString  m_callId;
00540   bool     m_initiator;
00541   States   m_state;
00542   Events   m_eventType;
00543   unsigned m_eventCode;
00544   struct Participant {
00545     Participant() : m_appearance(-1), m_byeless(false), m_rendering(RenderingUnknown) { }
00546     PString   m_URI;
00547     PString   m_dialogTag;
00548     PString   m_identity;
00549     PString   m_display;
00550     int       m_appearance;
00551     bool      m_byeless;
00552     Rendering m_rendering;
00553   } m_local, m_remote;
00554 
00555   SIPDialogNotification(const PString & entity = PString::Empty());
00556 
00557   void PrintOn(ostream & strm) const;
00558 };
00559 
00560 
00561 #endif // OPAL_SIP
00562 
00563 #endif // OPAL_SIP_HANDLERS_H