OPAL Version 3.10.2
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: 26283 $
00027  * $Author: rjongbloed $
00028  * $Date: 2011-08-08 02:41:14 -0500 (Mon, 08 Aug 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 expire; }
00102 
00103   virtual PString GetCallID()
00104     { return 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                     callID;
00161   int                         expire;
00162   int                         originalExpire;
00163   int                         offlineExpire;
00164   unsigned                    authenticationAttempts;
00165   State                       m_state;
00166   queue<State>                m_stateQueue;
00167   bool                        m_receivedResponse;
00168   PTimer                      expireTimer; 
00169   PTimeInterval               retryTimeoutMin; 
00170   PTimeInterval               retryTimeoutMax; 
00171   SIPURL                      m_proxy;
00172   OpalProductInfo             m_productInfo;
00173 
00174   // Keep a copy of the keys used for easy removal on destruction
00175   typedef std::map<PString, PSafePtr<SIPHandler> > IndexMap;
00176   std::pair<IndexMap::iterator, bool> m_byCallID;
00177   std::pair<IndexMap::iterator, bool> m_byAorAndPackage;
00178   std::pair<IndexMap::iterator, bool> m_byAuthIdAndRealm;
00179   std::pair<IndexMap::iterator, bool> m_byAorUserAndRealm;
00180 
00181   friend class SIPHandlersList;
00182 };
00183 
00184 #if PTRACING
00185 ostream & operator<<(ostream & strm, SIPHandler::State state);
00186 #endif
00187 
00188 
00189 class SIPRegisterHandler : public SIPHandler
00190 {
00191   PCLASSINFO(SIPRegisterHandler, SIPHandler);
00192 
00193 public:
00194   SIPRegisterHandler(
00195     SIPEndPoint & ep,
00196     const SIPRegister::Params & params
00197   );
00198 
00199   virtual SIPTransaction * CreateTransaction(OpalTransport &);
00200   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
00201 
00202   virtual void OnFailed(SIP_PDU::StatusCodes r);
00203 
00204   void UpdateParameters(const SIPRegister::Params & params);
00205 
00206   const SIPRegister::Params & GetParams() const { return m_parameters; }
00207 
00208   const SIPURLList & GetContacts() const { return m_contactAddresses; }
00209   const SIPURLList & GetServiceRoute() const { return m_serviceRoute; }
00210 
00211 protected:
00212   virtual PBoolean SendRequest(SIPHandler::State state);
00213   void SendStatus(SIP_PDU::StatusCodes code, State state);
00214 
00215   SIPRegister::Params m_parameters;
00216   unsigned            m_sequenceNumber;
00217   SIPURLList          m_contactAddresses;
00218   SIPURLList          m_serviceRoute;
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, const PString & userName, PSafetyMode m);
00413 
00421     PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, PSafetyMode m);
00422     PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, const PString & eventPackage, PSafetyMode m);
00423 
00429     PSafePtr <SIPHandler> FindSIPHandlerByDomain(const PString & name, SIP_PDU::Methods meth, PSafetyMode m);
00430 
00431   protected:
00432     void RemoveIndexes(SIPHandler * handler);
00433 
00434     PMutex m_extraMutex;
00435     PSafeList<SIPHandler> m_handlersList;
00436 
00437     typedef SIPHandler::IndexMap IndexMap;
00438     PSafePtr<SIPHandler> FindBy(IndexMap & by, const PString & key, PSafetyMode m);
00439 
00440     IndexMap m_byCallID;
00441     IndexMap m_byAorAndPackage;
00442     IndexMap m_byAuthIdAndRealm;
00443     IndexMap m_byAorUserAndRealm;
00444 };
00445 
00446 
00449 class SIPPresenceInfo : public OpalPresenceInfo
00450 {
00451 public:
00452   SIPPresenceInfo(
00453     State state = Unchanged
00454   );
00455 
00456   // basic presence defined by RFC 3863
00457   PString m_tupleId;
00458   PString m_contact;
00459 
00460   // presence extensions defined by RFC 4480
00461   PStringArray m_activities;  // list of activities, seperated by newline
00462 
00463   // presence agent
00464   PString m_presenceAgent;
00465 
00466   PString AsXML() const;
00467 
00468 #if P_EXPAT
00469   static bool ParseXML(
00470     const PString & body,
00471     list<SIPPresenceInfo> & info,
00472     PString & error
00473   );
00474 #endif
00475 
00476   void PrintOn(ostream & strm) const;
00477   friend ostream & operator<<(ostream & strm, const SIPPresenceInfo & info) { info.PrintOn(strm); return strm; }
00478 
00479   static State FromSIPActivityString(const PString & str);
00480 
00481   static bool AsSIPActivityString(State state, PString & str);
00482   bool AsSIPActivityString(PString & str) const;
00483 
00484   PString m_personId;
00485 };
00486 
00487 
00490 struct SIPDialogNotification : public PObject
00491 {
00492   PCLASSINFO(SIPDialogNotification, PObject);
00493 
00494   enum States {
00495     Terminated,
00496     Trying,
00497     Proceeding,
00498     Early,
00499     Confirmed,
00500 
00501     FirstState = Terminated,
00502     LastState = Confirmed
00503   };
00504   friend States operator++(States & state) { return (state = (States)(state+1)); }
00505   friend States operator--(States & state) { return (state = (States)(state-1)); }
00506   static PString GetStateName(States state);
00507   PString GetStateName() const { return GetStateName(m_state); }
00508 
00509   enum Events {
00510     NoEvent = -1,
00511     Cancelled,
00512     Rejected,
00513     Replaced,
00514     LocalBye,
00515     RemoteBye,
00516     Error,
00517     Timeout,
00518 
00519     FirstEvent = Cancelled,
00520     LastEvent = Timeout
00521   };
00522   friend Events operator++(Events & evt) { return (evt = (Events)(evt+1)); }
00523   friend Events operator--(Events & evt) { return (evt = (Events)(evt-1)); }
00524   static PString GetEventName(Events state);
00525   PString GetEventName() const { return GetEventName(m_eventType); }
00526 
00527   enum Rendering {
00528     RenderingUnknown = -1,
00529     NotRenderingMedia,
00530     RenderingMedia
00531   };
00532 
00533   PString  m_entity;
00534   PString  m_dialogId;
00535   PString  m_callId;
00536   bool     m_initiator;
00537   States   m_state;
00538   Events   m_eventType;
00539   unsigned m_eventCode;
00540   struct Participant {
00541     Participant() : m_appearance(-1), m_byeless(false), m_rendering(RenderingUnknown) { }
00542     PString   m_URI;
00543     PString   m_dialogTag;
00544     PString   m_identity;
00545     PString   m_display;
00546     int       m_appearance;
00547     bool      m_byeless;
00548     Rendering m_rendering;
00549   } m_local, m_remote;
00550 
00551   SIPDialogNotification(const PString & entity = PString::Empty());
00552 
00553   void PrintOn(ostream & strm) const;
00554 };
00555 
00556 
00557 #endif // OPAL_SIP
00558 
00559 #endif // OPAL_SIP_HANDLERS_H