OPAL  Version 3.18.8
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 
27 #ifndef OPAL_IM_PRES_ENT_H
28 #define OPAL_IM_PRES_ENT_H
29 
30 #include <ptlib.h>
31 #include <opal_config.h>
32 
33 #if OPAL_HAS_PRESENCE
34 
35 #include <ptlib/pfactory.h>
36 #include <ptlib/safecoll.h>
37 #include <ptclib/url.h>
38 #include <ptclib/guid.h>
39 
40 #ifdef P_VCARD
41  #include <ptclib/vcard.h>
42 #endif
43 
44 #include <im/im.h>
45 
46 #include <list>
47 #include <queue>
48 
49 class OpalManager;
50 class OpalPresentityCommand;
51 
52 
54 
68 class OpalPresenceInfo : public PObject
69 {
70  PCLASSINFO_WITH_CLONE(OpalPresenceInfo, PObject);
71  public:
75  P_DECLARE_STREAMABLE_ENUM_EX(State,StateCount,
76  UnknownUser,-4,
77  InternalError,
78  Forbidden,
79  NoPresence,
80  Unchanged,
81  Available,
82  Unavailable
83  );
84 
85  State m_state;
86  PStringSet m_activities;
87  PString m_note;
88  PTime m_when;
89 
90  PURL m_entity;
91  PURL m_target;
92  PString m_service;
93  PString m_contact;
94  PStringSet m_capabilities;
95 
96  PString m_infoType;
97  PString m_infoData;
98 
99  OpalPresenceInfo(State state = Unchanged);
100  OpalPresenceInfo(const PString & str);
101 
102  static PString AsString(State state);
103  static State FromString(const PString & str);
104  PString AsString() const;
105 
106  Comparison Compare(const PObject & other) const;
107 };
108 
109 ostream & operator<<(ostream & strm, OpalPresenceInfo::State state);
110 
112 
113 class OpalSetLocalPresenceCommand;
114 class OpalSubscribeToPresenceCommand;
115 class OpalAuthorisationRequestCommand;
116 class OpalSendMessageToCommand;
117 
127 class OpalPresentity : public PSafeObject
128 {
129  PCLASSINFO(OpalPresentity, PSafeObject);
130 
133  protected:
135  OpalPresentity();
136  OpalPresentity(const OpalPresentity & other);
137 
138  public:
139  ~OpalPresentity();
140 
143  static OpalPresentity * Create(
144  OpalManager & manager,
145  const PURL & url,
146  const PString & scheme = PString::Empty()
147  );
149 
161  virtual bool Open();
162 
165  virtual bool IsOpen() const { return m_open; }
166 
169  virtual bool Close();
171 
174  PStringOptions & GetAttributes() { return m_attributes; }
176 
178  virtual PStringArray GetAttributeNames() const = 0;
179 
181  virtual PStringArray GetAttributeTypes() const = 0;
182 
183  static const PCaselessString & AuthNameKey();
184  static const PCaselessString & AuthPasswordKey();
185  static const PCaselessString & TimeToLiveKey();
186 
191  const PURL & GetAOR() const { return m_aor; }
193 
204  virtual bool SubscribeToPresence(
205  const PURL & presentity,
206  bool subscribe = true,
207  const PString & note = PString::Empty()
208  );
209 
218  virtual bool UnsubscribeFromPresence(
219  const PURL & presentity
220  );
221 
223  enum Authorisation {
224  AuthorisationPermitted,
225  AuthorisationDenied,
226  AuthorisationDeniedPolitely,
227  AuthorisationConfirming,
228  AuthorisationRemove,
229  NumAuthorisations
230  };
231 
242  virtual bool SetPresenceAuthorisation(
243  const PURL & presentity,
244  Authorisation authorisation
245  );
246 
254  bool SetLocalPresence(
255  const OpalPresenceInfo & info
256  );
257 
258  // For backward compatibility
259  bool SetLocalPresence(
260  OpalPresenceInfo::State state,
261  const PString & note = PString::Empty()
262  );
263 
266  bool GetLocalPresence(
267  OpalPresenceInfo & info
268  );
269 
270  // For backward compatibility
271  bool GetLocalPresence(
272  OpalPresenceInfo::State & state,
273  PString & note
274  );
275 
276 
281  template <class cls> __inline cls * CreateCommand();
282 
294  virtual bool SendCommand(
295  OpalPresentityCommand * cmd
296  );
298 
301  struct AuthorisationRequest
302  {
303  PURL m_presentity;
304  PString m_note;
305  };
306 
314  virtual void OnAuthorisationRequest(
315  const AuthorisationRequest & request
316  );
317 
318  typedef PNotifierTemplate<AuthorisationRequest> AuthorisationRequestNotifier;
319  #define PDECLARE_AuthorisationRequestNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, OpalPresentity::AuthorisationRequest)
320  #define PDECLARE_ASYNC_AuthorisationRequestNotifier(cls, fn) PDECLARE_ASYNC_NOTIFIER2(OpalPresentity, cls, fn, OpalPresentity::AuthorisationRequest)
321  #define PCREATE_AuthorisationRequestNotifier(fn) PCREATE_NOTIFIER2(fn, OpalPresentity::AuthorisationRequest)
322 
324  void SetAuthorisationRequestNotifier(
325  const AuthorisationRequestNotifier & notifier
326  );
327 
336  virtual void OnPresenceChange(
337  const OpalPresenceInfo & info
338  );
339 
340  typedef PNotifierTemplate< PAutoPtr<OpalPresenceInfo> > PresenceChangeNotifier;
341  #define PDECLARE_PresenceChangeNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, PAutoPtr<OpalPresenceInfo>)
342  #define PDECLARE_ASYNC_PresenceChangeNotifier(cls, fn) PDECLARE_ASYNC_NOTIFIER2(OpalPresentity, cls, fn, PAutoPtr<OpalPresenceInfo>)
343  #define PCREATE_PresenceChangeNotifier(fn) PCREATE_NOTIFIER2(fn, PAutoPtr<OpalPresenceInfo>)
344 
346  void SetPresenceChangeNotifier(
347  const PresenceChangeNotifier & notifier
348  );
350 
357  struct BuddyInfo {
358  BuddyInfo(
359  const PURL & presentity = PString::Empty(),
360  const PString & displayName = PString::Empty()
361  ) : m_presentity(presentity)
362  , m_displayName(displayName)
363  { }
364 
365  PURL m_presentity;
366  PString m_displayName;
367 
368  // RFC4482 contact fields, note most of these are duplicated
369  // in the vCard structure
370 #ifdef P_VCARD
371  PvCard m_vCard;
375 #endif
376  PURL m_icon;
380  PURL m_map;
382  PURL m_sound;
386  PURL m_homePage;
387 
388  // Extra field for protocol dependent "get out of gaol" card
389  PString m_contentType;
390  PString m_rawXML;
391  };
392 
393  typedef std::list<BuddyInfo> BuddyList;
394 
395  enum BuddyStatus {
396  BuddyStatus_GenericFailure = -1,
397  BuddyStatus_OK = 0,
398  BuddyStatus_SpecifiedBuddyNotFound,
399  BuddyStatus_ListFeatureNotImplemented,
400  BuddyStatus_ListTemporarilyUnavailable,
401  BuddyStatus_ListMayBeIncomplete,
402  BuddyStatus_BadBuddySpecification,
403  BuddyStatus_ListSubscribeFailed,
404  BuddyStatus_AccountNotLoggedIn
405  };
406 
409  virtual BuddyStatus GetBuddyListEx(
410  BuddyList & buddies
411  );
412  virtual bool GetBuddyList(
413  BuddyList & buddies
414  )
415  { return GetBuddyListEx(buddies) == BuddyStatus_OK; }
416 
419  virtual BuddyStatus SetBuddyListEx(
420  const BuddyList & buddies
421  );
422  virtual bool SetBuddyList(
423  const BuddyList & buddies
424  )
425  { return SetBuddyListEx(buddies) == BuddyStatus_OK; }
426 
427 
430  virtual BuddyStatus DeleteBuddyListEx();
431  virtual bool DeleteBuddyList() { return DeleteBuddyListEx() == BuddyStatus_OK; }
432 
437  virtual BuddyStatus GetBuddyEx(
438  BuddyInfo & buddy
439  );
440  virtual bool GetBuddy(
441  BuddyInfo & buddy
442  )
443  { return GetBuddyEx(buddy) == BuddyStatus_OK; }
444 
447  virtual BuddyStatus SetBuddyEx(
448  const BuddyInfo & buddy
449  );
450  virtual bool SetBuddy(
451  const BuddyInfo & buddy
452  )
453  { return SetBuddyEx(buddy) == BuddyStatus_OK; }
454 
457  virtual BuddyStatus DeleteBuddyEx(
458  const PURL & presentity
459  );
460  virtual bool DeleteBuddy(
461  const PURL & presentity
462  )
463  { return DeleteBuddyEx(presentity) == BuddyStatus_OK; }
464 
470  virtual BuddyStatus SubscribeBuddyListEx(
471  PINDEX & successfulCount,
472  bool subscribe = true
473  );
474  virtual bool SubscribeBuddyList(
475  bool subscribe = true
476  )
477  { PINDEX successfulCount; return SubscribeBuddyListEx(successfulCount, subscribe) == BuddyStatus_OK; }
478 
484  virtual BuddyStatus UnsubscribeBuddyListEx();
485  virtual bool UnsubscribeBuddyList()
486  { return UnsubscribeBuddyListEx() == BuddyStatus_OK; }
488 
489 
490 #if OPAL_HAS_IM
491 
493  virtual bool SendMessageTo(
494  const OpalIM & message
495  );
496 
503  virtual void OnReceivedMessage(
504  const OpalIM & message
505  );
506 
507  typedef PNotifierTemplate<OpalIM> ReceivedMessageNotifier;
508  #define PDECLARE_ReceivedMessageNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, OpalIM)
509  #define PDECLARE_ASYNC_ReceivedMessageNotifier(cls, fn) PDECLARE_ASYNC_NOTIFIER2(OpalPresentity, cls, fn, OpalIM)
510  #define PCREATE_ReceivedMessageNotifier(fn) PCREATE_NOTIFIER2(fn, OpalIM)
511 
513  void SetReceivedMessageNotifier(
514  const ReceivedMessageNotifier & notifier
515  );
516 
517  void Internal_SendMessageToCommand(const OpalSendMessageToCommand & cmd);
519 #endif // OPAL_HAS_IM
520 
525  virtual void SetAOR(
526  const PURL & aor
527  );
528 
529  OpalManager & GetManager() const { return *m_manager; }
530 
531  protected:
532  OpalManager * m_manager;
533  PGloballyUniqueID m_guid;
534  PURL m_aor;
535  PStringOptions m_attributes;
536 
537  AuthorisationRequestNotifier m_onAuthorisationRequestNotifier;
538  PresenceChangeNotifier m_onPresenceChangeNotifier;
539 #if OPAL_HAS_IM
540  ReceivedMessageNotifier m_onReceivedMessageNotifier;
541 #endif // OPAL_HAS_IM
542 
543  atomic<bool> m_open;
544  PDECLARE_MUTEX(m_notificationMutex);
545  bool m_temporarilyUnavailable;
546  OpalPresenceInfo m_localInfo;
547 };
548 
549 
551 
555 class OpalPresentityWithCommandThread : public OpalPresentity
556 {
557  PCLASSINFO(OpalPresentityWithCommandThread, OpalPresentity);
558 
561  protected:
563  OpalPresentityWithCommandThread();
564  OpalPresentityWithCommandThread(const OpalPresentityWithCommandThread & other);
565 
566  public:
570  ~OpalPresentityWithCommandThread();
572 
577  virtual bool Close();
578 
590  virtual bool SendCommand(
591  OpalPresentityCommand * cmd
592  );
594 
595  protected:
596  struct WorkItem
597  {
598  OpalPresentity & m_owner;
599  OpalPresentityCommand * m_command;
600  WorkItem(OpalPresentityWithCommandThread & owner, OpalPresentityCommand * command);
601  ~WorkItem();
602  void Work();
603  };
604 
605  PQueuedThreadPool<WorkItem> m_threadPool;
606 };
607 
609 
612 class OpalPresentityCommand {
613  public:
614  OpalPresentityCommand(bool responseNeeded = false)
615  : m_responseNeeded(responseNeeded)
616  { }
617  virtual ~OpalPresentityCommand() { }
618 
622  virtual void Process(
623  OpalPresentity & presentity
624  ) = 0;
625 
626  static OpalPresentityCommand * Create(OpalPresentity & presentity, const char * cmdName);
627  static PDefaultPFactoryKey MakeKey(const char * className, const char * cmdName);
628 
629  typedef uint32_t CmdSeqType;
630  CmdSeqType m_sequence;
631  bool m_responseNeeded;
632  PURL m_presentity;
633 };
634 
637 #define OPAL_PRESENTITY_COMMAND(command, entity, func) \
638  class entity##_##command : public command \
639  { \
640  public: virtual void Process(OpalPresentity & presentity) { dynamic_cast<entity &>(presentity).func(*this); } \
641  }; \
642  PFACTORY_CREATE(PFactory<OpalPresentityCommand>, entity##_##command, OpalPresentityCommand::MakeKey(typeid(entity).name(), typeid(command).name()))
643 
644 
647 class OpalSubscribeToPresenceCommand : public OpalPresentityCommand {
648  public:
649  OpalSubscribeToPresenceCommand(bool subscribe = true) : m_subscribe(subscribe) { }
650 
651  bool m_subscribe;
652  PString m_note;
653 };
654 
655 
662 class OpalAuthorisationRequestCommand : public OpalPresentityCommand {
663  public:
664  OpalAuthorisationRequestCommand() : m_authorisation(OpalPresentity::AuthorisationPermitted) { }
665 
666  OpalPresentity::Authorisation m_authorisation;
667  PString m_note;
668 };
669 
670 
676 class OpalSetLocalPresenceCommand : public OpalPresentityCommand, public OpalPresenceInfo {
677  public:
678  OpalSetLocalPresenceCommand(State state = NoPresence) : OpalPresenceInfo(state) { }
679 };
680 
681 
682 #if OPAL_HAS_IM
683 
685 class OpalSendMessageToCommand : public OpalPresentityCommand
686 {
687  public:
688  OpalSendMessageToCommand() { }
689 
690  OpalIM m_message;
691 };
692 #endif // OPAL_HAS_IM
693 
694 
696 
697 // Include concrete classes here so the factories are initialised
698 #if OPAL_SIP_PRESENCE
699  PFACTORY_LOAD(SIP_Presentity);
700 #endif
701 
702 template <class cls> __inline cls * OpalPresentity::CreateCommand()
703 {
704  return dynamic_cast<cls *>(OpalPresentityCommand::Create(*this, typeid(cls).name()));
705 }
706 
707 
708 #endif // OPAL_HAS_PRESENCE
709 
710 
711 #endif // OPAL_IM_PRES_ENT_H
Definition: manager.h:150
PFACTORY_LOAD(OpalPluginCodecManager)
Definition: im.h:75
ostream & operator<<(ostream &strm, OpalSilenceDetector::Mode mode)