OPAL  Version 3.10.4
handlers.h
Go to the documentation of this file.
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: 26833 $
27  * $Author: rjongbloed $
28  * $Date: 2011-12-22 23:24:13 -0600 (Thu, 22 Dec 2011) $
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
81  };
82 
83  void SetState (SIPHandler::State s);
84 
86  { return m_state; }
87 
88  virtual OpalTransport * GetTransport();
89 
91  { return authentication; }
92 
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 
100  virtual int GetExpire()
101  { return m_currentExpireTime; }
102 
103  virtual const PString & GetCallID() const
104  { return m_callID; }
105 
106  virtual void SetBody(const PString & /*body*/) { }
107 
108  virtual bool IsDuplicateCSeq(unsigned ) { return false; }
109 
111 
112  SIP_PDU::Methods GetMethod() const { return m_method; }
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);
126  virtual bool SendNotify(const PObject * /*body*/) { return false; }
127 
128  SIPEndPoint & GetEndPoint() const { return endpoint; }
129 
130  const OpalProductInfo & GetProductInfo() const { return m_productInfo; }
131 
132  const PString & GetUsername() const { return m_username; }
133  const PString & GetPassword() const { return m_password; }
134  const PString & GetRealm() const { return m_realm; }
135  const SIPURL & GetRemoteAddress() const { return m_remoteAddress; }
136  const SIPURL & GetProxy() const { return m_proxy; }
137 
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 
148 
150  PString m_username;
151  PString m_password;
152  PString m_realm;
153 
154  PSafeList<SIPTransaction> m_transactions;
156 
160  PString m_callID;
161  unsigned m_lastCseq;
166  queue<State> m_stateQueue;
168  PTimer m_expireTimer;
171 
172  // Keep a copy of the keys used for easy removal on destruction
173  typedef std::map<PString, PSafePtr<SIPHandler> > IndexMap;
174  std::pair<IndexMap::iterator, bool> m_byCallID;
175  std::pair<IndexMap::iterator, bool> m_byAorAndPackage;
176  std::pair<IndexMap::iterator, bool> m_byAuthIdAndRealm;
177  std::pair<IndexMap::iterator, bool> m_byAorUserAndRealm;
178 
179  friend class SIPHandlersList;
180 };
181 
182 #if PTRACING
183 ostream & operator<<(ostream & strm, SIPHandler::State state);
184 #endif
185 
186 
188 {
189  PCLASSINFO(SIPRegisterHandler, SIPHandler);
190 
191 public:
193  SIPEndPoint & ep,
194  const SIPRegister::Params & params
195  );
196 
198  virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
199 
200  virtual void OnFailed(SIP_PDU::StatusCodes r);
201 
202  void UpdateParameters(const SIPRegister::Params & params);
203 
204  const SIPRegister::Params & GetParams() const { return m_parameters; }
205 
206  const SIPURLList & GetContacts() const { return m_contactAddresses; }
207  const SIPURLList & GetServiceRoute() const { return m_serviceRoute; }
208 
209 protected:
210  virtual PBoolean SendRequest(SIPHandler::State state);
211  void SendStatus(SIP_PDU::StatusCodes code, State state);
212 
218 };
219 
220 
222 {
223  PCLASSINFO(SIPSubscribeHandler, SIPHandler);
224 public:
227 
229  virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
230  virtual PBoolean OnReceivedNOTIFY(SIP_PDU & response);
231  virtual void OnFailed(const SIP_PDU & response);
233  { return m_parameters.m_eventPackage; }
234 
235  void UpdateParameters(const SIPSubscribe::Params & params);
236 
237  virtual bool IsDuplicateCSeq(unsigned sequenceNumber) { return m_dialog.IsDuplicateCSeq(sequenceNumber); }
238 
239  const SIPSubscribe::Params & GetParams() const { return m_parameters; }
240 
241 protected:
242  virtual PBoolean SendRequest(SIPHandler::State state);
243  virtual bool WriteSIPHandler(OpalTransport & transport, bool forked);
244  void SendStatus(SIP_PDU::StatusCodes code, State state);
245  bool DispatchNOTIFY(SIP_PDU & request, SIP_PDU & response);
246 
251 
253 };
254 
255 
257 {
258  PCLASSINFO(SIPNotifyHandler, SIPHandler);
259 public:
261  SIPEndPoint & ep,
262  const PString & targetAddress,
263  const SIPEventPackage & eventPackage,
264  const SIPDialogContext & dialog
265  );
267 
270  { return m_eventPackage; }
271 
272  virtual void SetBody(const PString & body) { m_body = body; }
273 
274  virtual bool IsDuplicateCSeq(unsigned sequenceNumber) { return m_dialog.IsDuplicateCSeq(sequenceNumber); }
275  virtual bool SendNotify(const PObject * body);
276 
277  enum Reasons {
284  };
285 
286 protected:
287  virtual PBoolean SendRequest(SIPHandler::State state);
288  virtual bool WriteSIPHandler(OpalTransport & transport, bool forked);
289 
294  PString m_body;
295 };
296 
297 
299 {
300  PCLASSINFO(SIPPublishHandler, SIPHandler);
301 
302 public:
304  const SIPSubscribe::Params & params,
305  const PString & body);
306 
307  virtual void SetBody(const PString & body) { m_body = body; }
308 
310  virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
312 
313 protected:
315  PString m_body;
316  PString m_sipETag;
317 };
318 
319 
321 {
322  PCLASSINFO(SIPMessageHandler, SIPHandler);
323 public:
324  SIPMessageHandler(SIPEndPoint & ep, const SIPMessage::Params & params);
325 
327  virtual void OnFailed(SIP_PDU::StatusCodes);
328  virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
329 
330  void UpdateParameters(const SIPMessage::Params & params);
331 
332 protected:
334 };
335 
336 
338 {
339  PCLASSINFO(SIPOptionsHandler, SIPHandler);
340 public:
341  SIPOptionsHandler(SIPEndPoint & ep, const SIPOptions::Params & params);
342 
344  virtual void OnFailed(SIP_PDU::StatusCodes);
345  virtual void OnFailed(const SIP_PDU & response);
346  virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response);
347 
348 protected:
350 };
351 
352 
354 {
355  PCLASSINFO(SIPPingHandler, SIPHandler);
356 public:
357  SIPPingHandler(SIPEndPoint & ep, const PURL & to);
359 };
360 
361 
366 {
367  public:
370  void Append(SIPHandler * handler);
371 
376  void Remove(SIPHandler * handler);
377 
380  void Update(SIPHandler * handler);
381 
385  { return m_handlersList.DeleteObjectsToBeRemoved(); }
386 
390  PSafePtr<SIPHandler> GetFirstHandler(PSafetyMode mode = PSafeReference) const
391  { return PSafePtr<SIPHandler>(m_handlersList, mode); }
392 
396  unsigned GetCount(SIP_PDU::Methods meth, const PString & eventPackage = PString::Empty()) const;
397 
401  PStringList GetAddresses(bool includeOffline, SIP_PDU::Methods meth, const PString & eventPackage = PString::Empty()) const;
402 
406  PSafePtr<SIPHandler> FindSIPHandlerByCallID(const PString & callID, PSafetyMode m);
407 
411  PSafePtr<SIPHandler> FindSIPHandlerByAuthRealm(const PString & authRealm, PSafetyMode m);
412 
416  PSafePtr<SIPHandler> FindSIPHandlerByAuthRealm(const PString & authRealm, const PString & userName, PSafetyMode m);
417 
425  PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, PSafetyMode m);
426  PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, const PString & eventPackage, PSafetyMode m);
427 
433  PSafePtr <SIPHandler> FindSIPHandlerByDomain(const PString & name, SIP_PDU::Methods meth, PSafetyMode m);
434 
435  protected:
436  void RemoveIndexes(SIPHandler * handler);
437 
438  PMutex m_extraMutex;
439  PSafeList<SIPHandler> m_handlersList;
440 
442  PSafePtr<SIPHandler> FindBy(IndexMap & by, const PString & key, PSafetyMode m);
443 
448 };
449 
450 
454 {
455 public:
457  State state = Unchanged
458  );
459 
460  // basic presence defined by RFC 3863
461  PString m_tupleId;
462  PString m_contact;
463 
464  // presence extensions defined by RFC 4480
465  PStringArray m_activities; // list of activities, seperated by newline
466 
467  // presence agent
469 
470  PString AsXML() const;
471 
472 #if P_EXPAT
473  static bool ParseXML(
474  const PString & body,
475  list<SIPPresenceInfo> & info,
476  PString & error
477  );
478 #endif
479 
480  void PrintOn(ostream & strm) const;
481  friend ostream & operator<<(ostream & strm, const SIPPresenceInfo & info) { info.PrintOn(strm); return strm; }
482 
483  static State FromSIPActivityString(const PString & str);
484 
485  static bool AsSIPActivityString(State state, PString & str);
486  bool AsSIPActivityString(PString & str) const;
487 
488  PString m_personId;
489 };
490 
491 
494 struct SIPDialogNotification : public PObject
495 {
497 
498  enum States {
504 
507  };
508  friend States operator++(States & state) { return (state = (States)(state+1)); }
509  friend States operator--(States & state) { return (state = (States)(state-1)); }
510  static PString GetStateName(States state);
511  PString GetStateName() const { return GetStateName(m_state); }
512 
513  enum Events {
514  NoEvent = -1,
522 
525  };
526  friend Events operator++(Events & evt) { return (evt = (Events)(evt+1)); }
527  friend Events operator--(Events & evt) { return (evt = (Events)(evt-1)); }
528  static PString GetEventName(Events state);
529  PString GetEventName() const { return GetEventName(m_eventType); }
530 
531  enum Rendering {
535  };
536 
537  PString m_entity;
538  PString m_dialogId;
539  PString m_callId;
543  unsigned m_eventCode;
544  struct Participant {
546  PString m_URI;
547  PString m_dialogTag;
548  PString m_identity;
549  PString m_display;
551  bool m_byeless;
553  } m_local, m_remote;
554 
555  SIPDialogNotification(const PString & entity = PString::Empty());
556 
557  void PrintOn(ostream & strm) const;
558 };
559 
560 
561 #endif // OPAL_SIP
562 
563 #endif // OPAL_SIP_HANDLERS_H