1 /*
2  * handlers.h
3  *
4  * Session Initiation Protocol endpoint.
5  *
6  * Open Phone Abstraction Library (OPAL)
7  *
8  * Copyright (c) 2000 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Open Phone Abstraction Library.
21  *
22  * The Initial Developer of the Original Code is Damien Sandras.
23  *
24  * Contributor(s): ______________________________________.
25  *
26  * $Revision: 28428 $
27  * $Author: rjongbloed $
28  * $Date: 2012-10-01 03:38:50 -0500 (Mon, 01 Oct 2012) $
29  */
30 
31 #ifndef OPAL_SIP_HANDLERS_H
32 #define OPAL_SIP_HANDLERS_H
33 
34 #ifdef P_USE_PRAGMA
35 #pragma interface
36 #endif
37 
38 #ifndef _PTLIB_H
39 #include <ptlib.h>
40 #endif
41 
42 #include <opal/buildopts.h>
43 
44 #if OPAL_SIP
45 
46 #include <opal/pres_ent.h>
47 #include <opal/connection.h>
48 #include <sip/sippdu.h>
49 
50 
51 /* Class to handle SIP REGISTER, SUBSCRIBE, MESSAGE, and renew
52  * the 'bindings' before they expire.
53  */
54 class SIPHandler : public PSafeObject
55 {
56   PCLASSINFO(SIPHandler, PSafeObject);
57 
58 protected:
59   SIPHandler(
60     SIP_PDU::Methods method,
61     SIPEndPoint & ep,
62     const SIPParameters & params
63   );
64 
65 public:
66   ~SIPHandler();
67 
68   virtual Comparison Compare(const PObject & other) const;
69 
70   virtual bool ShutDown();
71 
72   enum State {
73     Subscribed,       // The registration is active
74     Subscribing,      // The registration is in process
75     Unavailable,      // The registration is offline and still being attempted
76     Refreshing,       // The registration is being refreshed
77     Restoring,        // The registration is trying to be restored after being offline
78     Unsubscribing,    // The unregistration is in process
79     Unsubscribed,     // The registrating is inactive
80     NumStates
81   };
82 
83   void SetState (SIPHandler::State s);
84 
GetState()85   inline SIPHandler::State GetState ()
86   { return m_state; }
87 
88   virtual OpalTransport * GetTransport();
89 
GetAuthentication()90   virtual SIPAuthentication * GetAuthentication()
91   { return m_authentication; }
92 
GetAddressOfRecord()93   virtual const SIPURL & GetAddressOfRecord()
94     { return m_addressOfRecord; }
95 
96   virtual PBoolean OnReceivedNOTIFY(SIP_PDU & response);
97 
98   virtual void SetExpire(int e);
99 
GetExpire()100   virtual int GetExpire()
101     { return m_currentExpireTime; }
102 
GetCallID()103   virtual const PString & GetCallID() const
104     { return m_callID; }
105 
SetBody(const PString &)106   virtual void SetBody(const PString & /*body*/) { }
107 
IsDuplicateCSeq(unsigned)108   virtual bool IsDuplicateCSeq(unsigned ) { return false; }
109 
110   virtual SIPTransaction * CreateTransaction(OpalTransport & t) = 0;
111 
GetMethod()112   SIP_PDU::Methods GetMethod() const { return m_method; }
GetEventPackage()113   virtual SIPSubscribe::EventPackage GetEventPackage() const { return SIPEventPackage(); }
114 
115   virtual void OnReceivedResponse(SIPTransaction & transaction, SIP_PDU & response);
116   virtual void OnReceivedIntervalTooBrief(SIPTransaction & transaction, SIP_PDU & response);
117   virtual void OnReceivedTemporarilyUnavailable(SIPTransaction & transaction, SIP_PDU & response);
118   virtual void OnReceivedAuthenticationRequired(SIPTransaction & transaction, SIP_PDU & response);
119   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
120   virtual void OnTransactionFailed(SIPTransaction & transaction);
121 
122   virtual void OnFailed(const SIP_PDU & response);
123   virtual void OnFailed(SIP_PDU::StatusCodes);
124 
125   bool ActivateState(SIPHandler::State state);
SendNotify(const PObject *)126   virtual bool SendNotify(const PObject * /*body*/) { return false; }
127 
GetEndPoint()128   SIPEndPoint & GetEndPoint() const { return endpoint; }
129 
GetProductInfo()130   const OpalProductInfo & GetProductInfo() const { return m_productInfo; }
131 
GetUsername()132   const PString & GetUsername() const     { return m_username; }
GetPassword()133   const PString & GetPassword() const     { return m_password; }
GetRealm()134   const PString & GetRealm() const        { return m_realm; }
GetRemoteAddress()135   const SIPURL & GetRemoteAddress() const { return m_remoteAddress; }
GetProxy()136   const SIPURL & GetProxy() const         { return m_proxy; }
137 
138   SIPMIMEInfo m_mime;
139 
140 protected:
141   virtual PBoolean SendRequest(SIPHandler::State state);
142   void RetryLater(unsigned after);
143   PDECLARE_NOTIFIER(PTimer, SIPHandler, OnExpireTimeout);
144   static PBoolean WriteSIPHandler(OpalTransport & transport, void * info);
145   virtual bool WriteSIPHandler(OpalTransport & transport, bool forked);
146 
147   SIPEndPoint               & endpoint;
148 
149   SIPAuthentication         * m_authentication;
150   unsigned                    m_authenticateErrors;
151   PString                     m_username;
152   PString                     m_password;
153   PString                     m_realm;
154 
155   PSafeList<SIPTransaction>   m_transactions;
156   OpalTransport             * m_transport;
157 
158   SIP_PDU::Methods            m_method;
159   SIPURL                      m_addressOfRecord;
160   SIPURL                      m_remoteAddress;
161   PString                     m_callID;
162   unsigned                    m_lastCseq;
163   int                         m_currentExpireTime;
164   int                         m_originalExpireTime;
165   int                         m_offlineExpireTime;
166   State                       m_state;
167   queue<State>                m_stateQueue;
168   bool                        m_receivedResponse;
169   PTimer                      m_expireTimer;
170   SIPURL                      m_proxy;
171   OpalProductInfo             m_productInfo;
172 
173   // Keep a copy of the keys used for easy removal on destruction
174   typedef std::map<PString, PSafePtr<SIPHandler> > IndexMap;
175   std::pair<IndexMap::iterator, bool> m_byCallID;
176   std::pair<IndexMap::iterator, bool> m_byAorAndPackage;
177   std::pair<IndexMap::iterator, bool> m_byAuthIdAndRealm;
178   std::pair<IndexMap::iterator, bool> m_byAorUserAndRealm;
179 
180   friend class SIPHandlersList;
181 };
182 
183 #if PTRACING
184 ostream & operator<<(ostream & strm, SIPHandler::State state);
185 #endif
186 
187 
188 class SIPRegisterHandler : public SIPHandler
189 {
190   PCLASSINFO(SIPRegisterHandler, SIPHandler);
191 
192 public:
193   SIPRegisterHandler(
194     SIPEndPoint & ep,
195     const SIPRegister::Params & params
196   );
197 
198   virtual SIPTransaction * CreateTransaction(OpalTransport &);
199   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
200 
201   virtual void OnFailed(SIP_PDU::StatusCodes r);
202 
203   void UpdateParameters(const SIPRegister::Params & params);
204 
GetParams()205   const SIPRegister::Params & GetParams() const { return m_parameters; }
206 
GetContacts()207   const SIPURLList & GetContacts() const { return m_contactAddresses; }
GetServiceRoute()208   const SIPURLList & GetServiceRoute() const { return m_serviceRoute; }
209 
210 protected:
211   virtual PBoolean SendRequest(SIPHandler::State state);
212   void SendStatus(SIP_PDU::StatusCodes code, State state);
213 
214   SIPRegister::Params  m_parameters;
215   unsigned             m_sequenceNumber;
216   SIPURLList           m_contactAddresses;
217   SIPURLList           m_serviceRoute;
218   OpalTransportAddress m_externalAddress;
219 };
220 
221 
222 class SIPSubscribeHandler : public SIPHandler
223 {
224   PCLASSINFO(SIPSubscribeHandler, SIPHandler);
225 public:
226   SIPSubscribeHandler(SIPEndPoint & ep, const SIPSubscribe::Params & params);
227   ~SIPSubscribeHandler();
228 
229   virtual SIPTransaction * CreateTransaction (OpalTransport &);
230   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
231   virtual PBoolean OnReceivedNOTIFY(SIP_PDU & response);
232   virtual void OnFailed(const SIP_PDU & response);
GetEventPackage()233   virtual SIPEventPackage GetEventPackage() const
234     { return m_parameters.m_eventPackage; }
235 
236   void UpdateParameters(const SIPSubscribe::Params & params);
237 
IsDuplicateCSeq(unsigned sequenceNumber)238   virtual bool IsDuplicateCSeq(unsigned sequenceNumber) { return m_dialog.IsDuplicateCSeq(sequenceNumber); }
239 
GetParams()240   const SIPSubscribe::Params & GetParams() const { return m_parameters; }
241 
242 protected:
243   virtual PBoolean SendRequest(SIPHandler::State state);
244   virtual bool WriteSIPHandler(OpalTransport & transport, bool forked);
245   void SendStatus(SIP_PDU::StatusCodes code, State state);
246   bool DispatchNOTIFY(SIP_PDU & request, SIP_PDU & response);
247 
248   SIPSubscribe::Params     m_parameters;
249   SIPDialogContext         m_dialog;
250   bool                     m_unconfirmed;
251   SIPEventPackageHandler * m_packageHandler;
252 
253   SIP_PDU                  * m_previousResponse;
254 };
255 
256 
257 class SIPNotifyHandler : public SIPHandler
258 {
259   PCLASSINFO(SIPNotifyHandler, SIPHandler);
260 public:
261   SIPNotifyHandler(
262     SIPEndPoint & ep,
263     const PString & targetAddress,
264     const SIPEventPackage & eventPackage,
265     const SIPDialogContext & dialog
266   );
267   ~SIPNotifyHandler();
268 
269   virtual SIPTransaction * CreateTransaction(OpalTransport &);
GetEventPackage()270   virtual SIPEventPackage GetEventPackage() const
271     { return m_eventPackage; }
272 
SetBody(const PString & body)273   virtual void SetBody(const PString & body) { m_body = body; }
274 
IsDuplicateCSeq(unsigned sequenceNumber)275   virtual bool IsDuplicateCSeq(unsigned sequenceNumber) { return m_dialog.IsDuplicateCSeq(sequenceNumber); }
276   virtual bool SendNotify(const PObject * body);
277 
278   enum Reasons {
279     Deactivated,
280     Probation,
281     Rejected,
282     Timeout,
283     GiveUp,
284     NoResource
285   };
286 
287 protected:
288   virtual PBoolean SendRequest(SIPHandler::State state);
289   virtual bool WriteSIPHandler(OpalTransport & transport, bool forked);
290 
291   SIPEventPackage          m_eventPackage;
292   SIPDialogContext         m_dialog;
293   Reasons                  m_reason;
294   SIPEventPackageHandler * m_packageHandler;
295   PString                  m_body;
296 };
297 
298 
299 class SIPPublishHandler : public SIPHandler
300 {
301   PCLASSINFO(SIPPublishHandler, SIPHandler);
302 
303 public:
304   SIPPublishHandler(SIPEndPoint & ep,
305                     const SIPSubscribe::Params & params,
306                     const PString & body);
307 
SetBody(const PString & body)308   virtual void SetBody(const PString & body) { m_body = body; }
309 
310   virtual SIPTransaction * CreateTransaction(OpalTransport &);
311   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
GetEventPackage()312   virtual SIPEventPackage GetEventPackage() const { return m_parameters.m_eventPackage; }
313 
314 protected:
315   SIPSubscribe::Params m_parameters;
316   PString              m_body;
317   PString              m_sipETag;
318 };
319 
320 
321 class SIPMessageHandler : public SIPHandler
322 {
323   PCLASSINFO(SIPMessageHandler, SIPHandler);
324 public:
325   SIPMessageHandler(SIPEndPoint & ep, const SIPMessage::Params & params);
326 
327   virtual SIPTransaction * CreateTransaction (OpalTransport &);
328   virtual void OnFailed(SIP_PDU::StatusCodes);
329   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
330 
331   void UpdateParameters(const SIPMessage::Params & params);
332 
333 protected:
334   SIPMessage::Params m_parameters;
335 };
336 
337 
338 class SIPOptionsHandler : public SIPHandler
339 {
340   PCLASSINFO(SIPOptionsHandler, SIPHandler);
341 public:
342   SIPOptionsHandler(SIPEndPoint & ep, const SIPOptions::Params & params);
343 
344   virtual SIPTransaction * CreateTransaction (OpalTransport &);
345   virtual void OnFailed(SIP_PDU::StatusCodes);
346   virtual void OnFailed(const SIP_PDU & response);
347   virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
348 
349 protected:
350   SIPOptions::Params m_parameters;
351 };
352 
353 
354 class SIPPingHandler : public SIPHandler
355 {
356   PCLASSINFO(SIPPingHandler, SIPHandler);
357 public:
358   SIPPingHandler(SIPEndPoint & ep, const PURL & to);
359   virtual SIPTransaction * CreateTransaction (OpalTransport &);
360 };
361 
362 
363 /** This dictionary is used both to contain the active and successful
364  * registrations, and subscriptions.
365  */
366 class SIPHandlersList
367 {
368   public:
369     /** Append a new handler to the list
370       */
371     void Append(SIPHandler * handler);
372 
373     /** Remove a handler from the list.
374         Handler is not immediately deleted but marked for deletion later by
375         DeleteObjectsToBeRemoved() when all references are done with the handler.
376       */
377     void Remove(SIPHandler * handler);
378 
379     /** Update indexes for handler in the list
380       */
381     void Update(SIPHandler * handler);
382 
383     /** Clean up lists of handler.
384       */
DeleteObjectsToBeRemoved()385     bool DeleteObjectsToBeRemoved()
386       { return m_handlersList.DeleteObjectsToBeRemoved(); }
387 
388     /** Get the first handler in the list. Further enumeration may be done by
389         the ++operator on the safe pointer.
390      */
391     PSafePtr<SIPHandler> GetFirstHandler(PSafetyMode mode = PSafeReference) const
392       { return PSafePtr<SIPHandler>(m_handlersList, mode); }
393 
394     /**
395      * Return the number of registered accounts
396      */
397     unsigned GetCount(SIP_PDU::Methods meth, const PString & eventPackage = PString::Empty()) const;
398 
399     /**
400      * Return a list of the active address of records for each handler.
401      */
402     PStringList GetAddresses(bool includeOffline, SIP_PDU::Methods meth, const PString & eventPackage = PString::Empty()) const;
403 
404     /**
405      * Find the SIPHandler object with the specified callID
406      */
407     PSafePtr<SIPHandler> FindSIPHandlerByCallID(const PString & callID, PSafetyMode m);
408 
409     /**
410      * Find the SIPHandler object with the specified authRealm
411      */
412     PSafePtr<SIPHandler> FindSIPHandlerByAuthRealm(const PString & authRealm, PSafetyMode m);
413 
414     /**
415      * Find the SIPHandler object with the specified authRealm & user
416      */
417     PSafePtr<SIPHandler> FindSIPHandlerByAuthRealm(const PString & authRealm, const PString & userName, PSafetyMode m);
418 
419     /**
420      * Find the SIPHandler object with the specified URL. The url is
421      * the registration address, for example, 6001@sip.seconix.com
422      * when registering 6001 to sip.seconix.com with realm seconix.com
423      * or 6001@seconix.com when registering 6001@seconix.com to
424      * sip.seconix.com
425      */
426     PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, PSafetyMode m);
427     PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, const PString & eventPackage, PSafetyMode m);
428 
429     /**
430      * Find the SIPHandler object with the specified registration host.
431      * For example, in the above case, the name parameter
432      * could be "sip.seconix.com" or "seconix.com".
433      */
434     PSafePtr <SIPHandler> FindSIPHandlerByDomain(const PString & name, SIP_PDU::Methods meth, PSafetyMode m);
435 
436   protected:
437     void RemoveIndexes(SIPHandler * handler);
438 
439     PMutex m_extraMutex;
440     PSafeList<SIPHandler> m_handlersList;
441 
442     typedef SIPHandler::IndexMap IndexMap;
443     PSafePtr<SIPHandler> FindBy(IndexMap & by, const PString & key, PSafetyMode m);
444 
445     IndexMap m_byCallID;
446     IndexMap m_byAorAndPackage;
447     IndexMap m_byAuthIdAndRealm;
448     IndexMap m_byAorUserAndRealm;
449 };
450 
451 
452 /** Information for SIP "presence" event package notification messages.
453   */
454 class SIPPresenceInfo : public OpalPresenceInfo
455 {
456 public:
457   SIPPresenceInfo(
458     State state = Unchanged
459   );
460 
461   // basic presence defined by RFC 3863
462   PString m_tupleId;
463   PString m_contact;
464 
465   // presence extensions defined by RFC 4480
466   PStringArray m_activities;  // list of activities, seperated by newline
467 
468   // presence agent
469   PString m_presenceAgent;
470 
471   PString AsXML() const;
472 
473 #if P_EXPAT
474   static bool ParseXML(
475     const PString & body,
476     list<SIPPresenceInfo> & info,
477     PString & error
478   );
479 #endif
480 
481   void PrintOn(ostream & strm) const;
482   friend ostream & operator<<(ostream & strm, const SIPPresenceInfo & info) { info.PrintOn(strm); return strm; }
483 
484   static State FromSIPActivityString(const PString & str);
485 
486   static bool AsSIPActivityString(State state, PString & str);
487   bool AsSIPActivityString(PString & str) const;
488 
489   PString m_personId;
490 };
491 
492 
493 /** Information for SIP "dialog" event package notification messages.
494   */
495 struct SIPDialogNotification : public PObject
496 {
497   PCLASSINFO(SIPDialogNotification, PObject);
498 
499   enum States {
500     Terminated,
501     Trying,
502     Proceeding,
503     Early,
504     Confirmed,
505 
506     FirstState = Terminated,
507     LastState = Confirmed
508   };
509   friend States operator++(States & state) { return (state = (States)(state+1)); }
510   friend States operator--(States & state) { return (state = (States)(state-1)); }
511   static PString GetStateName(States state);
GetStateNameSIPDialogNotification512   PString GetStateName() const { return GetStateName(m_state); }
513 
514   enum Events {
515     NoEvent = -1,
516     Cancelled,
517     Rejected,
518     Replaced,
519     LocalBye,
520     RemoteBye,
521     Error,
522     Timeout,
523 
524     FirstEvent = Cancelled,
525     LastEvent = Timeout
526   };
527   friend Events operator++(Events & evt) { return (evt = (Events)(evt+1)); }
528   friend Events operator--(Events & evt) { return (evt = (Events)(evt-1)); }
529   static PString GetEventName(Events state);
GetEventNameSIPDialogNotification530   PString GetEventName() const { return GetEventName(m_eventType); }
531 
532   enum Rendering {
533     RenderingUnknown = -1,
534     NotRenderingMedia,
535     RenderingMedia
536   };
537 
538   PString  m_entity;
539   PString  m_dialogId;
540   PString  m_callId;
541   bool     m_initiator;
542   States   m_state;
543   Events   m_eventType;
544   unsigned m_eventCode;
545   struct Participant {
ParticipantSIPDialogNotification::Participant546     Participant() : m_appearance(-1), m_byeless(false), m_rendering(RenderingUnknown) { }
547     PString   m_URI;
548     PString   m_dialogTag;
549     PString   m_identity;
550     PString   m_display;
551     int       m_appearance;
552     bool      m_byeless;
553     Rendering m_rendering;
554   } m_local, m_remote;
555 
556   SIPDialogNotification(const PString & entity = PString::Empty());
557 
558   void PrintOn(ostream & strm) const;
559 };
560 
561 
562 #endif // OPAL_SIP
563 
564 #endif // OPAL_SIP_HANDLERS_H
565