OPAL  Version 3.14.3
pres_ent.h
Go to the documentation of this file.
1 /*
2  * prese_ent.h
3  *
4  * Presence Entity classes for Opal
5  *
6  * Open Phone Abstraction Library (OPAL)
7  *
8  * Copyright (c) 2009 Post Increment
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 Post Increment
23  *
24  * Contributor(s): ______________________________________.
25  *
26  * $Revision: 32250 $
27  * $Author: rjongbloed $
28  * $Date: 2014-06-28 14:55:01 +1000 (Sat, 28 Jun 2014) $
29  */
30 
31 #ifndef OPAL_IM_PRES_ENT_H
32 #define OPAL_IM_PRES_ENT_H
33 
34 #include <ptlib.h>
35 #include <opal_config.h>
36 
37 #if OPAL_HAS_PRESENCE
38 
39 #include <ptlib/pfactory.h>
40 #include <ptlib/safecoll.h>
41 #include <ptclib/url.h>
42 #include <ptclib/guid.h>
43 
44 #ifdef P_VCARD
45  #include <ptclib/vcard.h>
46 #endif
47 
48 #include <im/im.h>
49 
50 #include <list>
51 #include <queue>
52 
53 class OpalManager;
54 class OpalPresentityCommand;
55 
56 
58 
72 class OpalPresenceInfo : public PObject
73 {
74  PCLASSINFO_WITH_CLONE(OpalPresenceInfo, PObject);
75  public:
79  P_DECLARE_STREAMABLE_ENUM_EX(State,StateCount,
80  UnknownUser,-4,
81  InternalError,
82  Forbidden,
83  NoPresence,
84  Unchanged,
85  Available,
86  Unavailable
87  );
88 
89  State m_state;
90  PStringSet m_activities;
91  PString m_note;
92  PTime m_when;
93 
94  PURL m_entity;
95  PURL m_target;
96  PString m_service;
97  PString m_contact;
98  PStringSet m_capabilities;
99 
100  PString m_infoType;
101  PString m_infoData;
102 
103  OpalPresenceInfo(State state = Unchanged);
104  OpalPresenceInfo(const PString & str);
105 
106  static PString AsString(State state);
107  static State FromString(const PString & str);
108  PString AsString() const;
109 
110  Comparison Compare(const PObject & other) const;
111 };
112 
113 ostream & operator<<(ostream & strm, OpalPresenceInfo::State state);
114 
116 
117 class OpalSetLocalPresenceCommand;
118 class OpalSubscribeToPresenceCommand;
119 class OpalAuthorisationRequestCommand;
120 class OpalSendMessageToCommand;
121 
131 class OpalPresentity : public PSafeObject
132 {
133  PCLASSINFO(OpalPresentity, PSafeObject);
134 
137  protected:
139  OpalPresentity();
140  OpalPresentity(const OpalPresentity & other);
141 
142  public:
143  ~OpalPresentity();
144 
147  static OpalPresentity * Create(
148  OpalManager & manager,
149  const PURL & url,
150  const PString & scheme = PString::Empty()
151  );
153 
165  virtual bool Open();
166 
169  virtual bool IsOpen() const { return m_open; }
170 
173  virtual bool Close();
175 
178 
179  PStringOptions & GetAttributes() { return m_attributes; }
180 
182  virtual PStringArray GetAttributeNames() const = 0;
183 
185  virtual PStringArray GetAttributeTypes() const = 0;
186 
187  static const PCaselessString & AuthNameKey();
188  static const PCaselessString & AuthPasswordKey();
189  static const PCaselessString & TimeToLiveKey();
190 
195  const PURL & GetAOR() const { return m_aor; }
197 
208  virtual bool SubscribeToPresence(
209  const PURL & presentity,
210  bool subscribe = true,
211  const PString & note = PString::Empty()
212  );
213 
222  virtual bool UnsubscribeFromPresence(
223  const PURL & presentity
224  );
225 
227  enum Authorisation {
228  AuthorisationPermitted,
229  AuthorisationDenied,
230  AuthorisationDeniedPolitely,
231  AuthorisationConfirming,
232  AuthorisationRemove,
233  NumAuthorisations
234  };
235 
246  virtual bool SetPresenceAuthorisation(
247  const PURL & presentity,
248  Authorisation authorisation
249  );
250 
258  bool SetLocalPresence(
259  const OpalPresenceInfo & info
260  );
261 
262  // For backward compatibility
263  bool SetLocalPresence(
264  OpalPresenceInfo::State state,
265  const PString & note = PString::Empty()
266  );
267 
270  bool GetLocalPresence(
271  OpalPresenceInfo & info
272  );
273 
274  // For backward compatibility
275  bool GetLocalPresence(
276  OpalPresenceInfo::State & state,
277  PString & note
278  );
279 
280 
285  template <class cls>
286  __inline cls * CreateCommand()
287  {
288  return dynamic_cast<cls *>(InternalCreateCommand(typeid(cls).name()));
289  }
290 
302  virtual bool SendCommand(
303  OpalPresentityCommand * cmd
304  );
306 
309  struct AuthorisationRequest
310  {
311  PURL m_presentity;
312  PString m_note;
313  };
314 
322  virtual void OnAuthorisationRequest(
323  const AuthorisationRequest & request
324  );
325 
326  typedef PNotifierTemplate<AuthorisationRequest> AuthorisationRequestNotifier;
327  #define PDECLARE_AuthorisationRequestNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, OpalPresentity::AuthorisationRequest)
328  #define PDECLARE_ASYNC_AuthorisationRequestNotifier(cls, fn) PDECLARE_ASYNC_NOTIFIER2(OpalPresentity, cls, fn, OpalPresentity::AuthorisationRequest)
329  #define PCREATE_AuthorisationRequestNotifier(fn) PCREATE_NOTIFIER2(fn, OpalPresentity::AuthorisationRequest)
330 
332  void SetAuthorisationRequestNotifier(
333  const AuthorisationRequestNotifier & notifier
334  );
335 
344  virtual void OnPresenceChange(
345  const OpalPresenceInfo & info
346  );
347 
348  typedef PNotifierTemplate< std::auto_ptr<OpalPresenceInfo> > PresenceChangeNotifier;
349  #define PDECLARE_PresenceChangeNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, std::auto_ptr<OpalPresenceInfo>)
350  #define PDECLARE_ASYNC_PresenceChangeNotifier(cls, fn) PDECLARE_ASYNC_NOTIFIER2(OpalPresentity, cls, fn, std::auto_ptr<OpalPresenceInfo>)
351  #define PCREATE_PresenceChangeNotifier(fn) PCREATE_NOTIFIER2(fn, std::auto_ptr<OpalPresenceInfo>)
352 
354  void SetPresenceChangeNotifier(
355  const PresenceChangeNotifier & notifier
356  );
358 
365  struct BuddyInfo {
366  BuddyInfo(
367  const PURL & presentity = PString::Empty(),
368  const PString & displayName = PString::Empty()
369  ) : m_presentity(presentity)
370  , m_displayName(displayName)
371  { }
372 
373  PURL m_presentity;
374  PString m_displayName;
375 
376  // RFC4482 contact fields, note most of these are duplicated
377  // in the vCard structure
378 #ifdef P_VCARD
379  PvCard m_vCard;
383 #endif
384  PURL m_icon;
388  PURL m_map;
390  PURL m_sound;
394  PURL m_homePage;
395 
396  // Extra field for protocol dependent "get out of gaol" card
397  PString m_contentType;
398  PString m_rawXML;
399  };
400 
401  typedef std::list<BuddyInfo> BuddyList;
402 
403  enum BuddyStatus {
404  BuddyStatus_GenericFailure = -1,
405  BuddyStatus_OK = 0,
406  BuddyStatus_SpecifiedBuddyNotFound,
407  BuddyStatus_ListFeatureNotImplemented,
408  BuddyStatus_ListTemporarilyUnavailable,
409  BuddyStatus_ListMayBeIncomplete,
410  BuddyStatus_BadBuddySpecification,
411  BuddyStatus_ListSubscribeFailed,
412  BuddyStatus_AccountNotLoggedIn
413  };
414 
417  virtual BuddyStatus GetBuddyListEx(
418  BuddyList & buddies
419  );
420  virtual bool GetBuddyList(
421  BuddyList & buddies
422  )
423  { return GetBuddyListEx(buddies) == BuddyStatus_OK; }
424 
427  virtual BuddyStatus SetBuddyListEx(
428  const BuddyList & buddies
429  );
430  virtual bool SetBuddyList(
431  const BuddyList & buddies
432  )
433  { return SetBuddyListEx(buddies) == BuddyStatus_OK; }
434 
435 
438  virtual BuddyStatus DeleteBuddyListEx();
439  virtual bool DeleteBuddyList() { return DeleteBuddyListEx() == BuddyStatus_OK; }
440 
445  virtual BuddyStatus GetBuddyEx(
446  BuddyInfo & buddy
447  );
448  virtual bool GetBuddy(
449  BuddyInfo & buddy
450  )
451  { return GetBuddyEx(buddy) == BuddyStatus_OK; }
452 
455  virtual BuddyStatus SetBuddyEx(
456  const BuddyInfo & buddy
457  );
458  virtual bool SetBuddy(
459  const BuddyInfo & buddy
460  )
461  { return SetBuddyEx(buddy) == BuddyStatus_OK; }
462 
465  virtual BuddyStatus DeleteBuddyEx(
466  const PURL & presentity
467  );
468  virtual bool DeleteBuddy(
469  const PURL & presentity
470  )
471  { return DeleteBuddyEx(presentity) == BuddyStatus_OK; }
472 
478  virtual BuddyStatus SubscribeBuddyListEx(
479  PINDEX & successfulCount,
480  bool subscribe = true
481  );
482  virtual bool SubscribeBuddyList(
483  bool subscribe = true
484  )
485  { PINDEX successfulCount; return SubscribeBuddyListEx(successfulCount, subscribe) == BuddyStatus_OK; }
486 
492  virtual BuddyStatus UnsubscribeBuddyListEx();
493  virtual bool UnsubscribeBuddyList()
494  { return UnsubscribeBuddyListEx() == BuddyStatus_OK; }
496 
497 
498 #if OPAL_HAS_IM
499 
501  virtual bool SendMessageTo(
502  const OpalIM & message
503  );
504 
511  virtual void OnReceivedMessage(
512  const OpalIM & message
513  );
514 
515  typedef PNotifierTemplate<OpalIM> ReceivedMessageNotifier;
516  #define PDECLARE_ReceivedMessageNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, OpalIM)
517  #define PDECLARE_ASYNC_ReceivedMessageNotifier(cls, fn) PDECLARE_ASYNC_NOTIFIER2(OpalPresentity, cls, fn, OpalIM)
518  #define PCREATE_ReceivedMessageNotifier(fn) PCREATE_NOTIFIER2(fn, OpalIM)
519 
521  void SetReceivedMessageNotifier(
522  const ReceivedMessageNotifier & notifier
523  );
524 
525  void Internal_SendMessageToCommand(const OpalSendMessageToCommand & cmd);
527 #endif // OPAL_HAS_IM
528 
533  virtual void SetAOR(
534  const PURL & aor
535  );
536 
537  OpalManager & GetManager() const { return *m_manager; }
538 
539  protected:
540  OpalPresentityCommand * InternalCreateCommand(const char * cmdName);
541 
542  OpalManager * m_manager;
543  PGloballyUniqueID m_guid;
544  PURL m_aor;
545  PStringOptions m_attributes;
546 
547  AuthorisationRequestNotifier m_onAuthorisationRequestNotifier;
548  PresenceChangeNotifier m_onPresenceChangeNotifier;
549 #if OPAL_HAS_IM
550  ReceivedMessageNotifier m_onReceivedMessageNotifier;
551 #endif // OPAL_HAS_IM
552 
553  PAtomicBoolean m_open;
554  PMutex m_notificationMutex;
555  bool m_temporarilyUnavailable;
556  OpalPresenceInfo m_localInfo;
557 };
558 
559 
561 
565 class OpalPresentityWithCommandThread : public OpalPresentity
566 {
567  PCLASSINFO(OpalPresentityWithCommandThread, OpalPresentity);
568 
571  protected:
573  OpalPresentityWithCommandThread();
574  OpalPresentityWithCommandThread(const OpalPresentityWithCommandThread & other);
575 
576  public:
580  ~OpalPresentityWithCommandThread();
582 
596  virtual bool SendCommand(
597  OpalPresentityCommand * cmd
598  );
600 
613  void StartThread(
614  bool startQueue = true
615  );
616 
622  void StopThread();
623 
626  void StartQueue(
627  bool startQueue = true
628  );
629 
631 
632  protected:
633  void ThreadMain();
634 
635  typedef std::queue<OpalPresentityCommand *> CommandQueue;
636  CommandQueue m_commandQueue;
637  PMutex m_commandQueueMutex;
638  PAtomicInteger m_commandSequence;
639  PSyncPoint m_commandQueueSync;
640 
641  bool m_threadRunning;
642  bool m_queueRunning;
643  PThread * m_thread;
644 };
645 
647 
650 class OpalPresentityCommand {
651  public:
652  OpalPresentityCommand(bool responseNeeded = false)
653  : m_responseNeeded(responseNeeded)
654  { }
655  virtual ~OpalPresentityCommand() { }
656 
660  virtual void Process(
661  OpalPresentity & presentity
662  ) = 0;
663 
664  typedef PAtomicInteger::IntegerType CmdSeqType;
665  CmdSeqType m_sequence;
666  bool m_responseNeeded;
667  PURL m_presentity;
668 };
669 
672 #define OPAL_DEFINE_COMMAND(command, entity, func) \
673  class entity##_##command : public command \
674  { \
675  public: virtual void Process(OpalPresentity & presentity) { dynamic_cast<entity &>(presentity).func(*this); } \
676  }; \
677  PFACTORY_CREATE(PFactory<OpalPresentityCommand>, entity##_##command, PDefaultPFactoryKey(entity::Class())+typeid(command).name())
678 
679 
682 class OpalSubscribeToPresenceCommand : public OpalPresentityCommand {
683  public:
684  OpalSubscribeToPresenceCommand(bool subscribe = true) : m_subscribe(subscribe) { }
685 
686  bool m_subscribe;
687  PString m_note;
688 };
689 
690 
697 class OpalAuthorisationRequestCommand : public OpalPresentityCommand {
698  public:
699  OpalAuthorisationRequestCommand() : m_authorisation(OpalPresentity::AuthorisationPermitted) { }
700 
701  OpalPresentity::Authorisation m_authorisation;
702  PString m_note;
703 };
704 
705 
711 class OpalSetLocalPresenceCommand : public OpalPresentityCommand, public OpalPresenceInfo {
712  public:
713  OpalSetLocalPresenceCommand(State state = NoPresence) : OpalPresenceInfo(state) { }
714 };
715 
716 
717 #if OPAL_HAS_IM
718 
720 class OpalSendMessageToCommand : public OpalPresentityCommand
721 {
722  public:
723  OpalSendMessageToCommand() { }
724 
725  OpalIM m_message;
726 };
727 #endif // OPAL_HAS_IM
728 
729 
731 
732 // Include concrete classes here so the factories are initialised
733 #if OPAL_SIP_PRESENCE
734  PFACTORY_LOAD(SIP_Presentity);
735 #endif
736 
737 
738 #endif // OPAL_HAS_PRESENCE
739 
740 
741 #endif // OPAL_IM_PRES_ENT_H