# pres_ent.h

Go to the documentation of this file.

    00001 /*
    00002  * prese_ent.h
    00003  *
    00004  * Presence Entity classes for Opal
    00005  *
    00006  * Open Phone Abstraction Library (OPAL)
    00007  *
    00008  * Copyright (c) 2009 Post Increment
    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 Post Increment
    00023  *
    00024  * Contributor(s): ______________________________________.
    00025  *
    00026  * $Revision: 29768 $
    00027  * $Author: rjongbloed $
    00028  * $Date: 2013-05-23 02:27:37 -0500 (Thu, 23 May 2013) $
    00029  */
    00030
    00031 #ifndef OPAL_IM_PRES_ENT_H
    00032 #define OPAL_IM_PRES_ENT_H
    00033
    00034 #include <ptlib.h>
    00035 #include <opal/buildopts.h>
    00036
    00037 #if OPAL_HAS_PRESENCE
    00038
    00039 #include <ptlib/pfactory.h>
    00040 #include <ptlib/safecoll.h>
    00041 #include <ptclib/url.h>
    00042 #include <ptclib/guid.h>
    00043
    00044 #ifdef P_VCARD
    00045   #include <ptclib/vcard.h>
    00046 #endif
    00047
    00048 #include <im/im.h>
    00049
    00050 #include <list>
    00051 #include <queue>
    00052
    00053 class OpalManager;
    00054 class OpalPresentityCommand;
    00055
    00056
    00058
    00072 class OpalPresenceInfo : public PObject
    00073 {
    00074     PCLASSINFO_WITH_CLONE(OpalPresenceInfo, PObject);
    00075   public:
    00079     P_DECLARE_STREAMABLE_ENUM_EX(State,StateCount,
    00080       UnknownUser,-4,
    00081       InternalError,
    00082       Forbidden,
    00083       NoPresence,
    00084       Unchanged,
    00085       Available,
    00086       Unavailable
    00087     );
    00088
    00089     State      m_state;
    00090     PStringSet m_activities;
    00091     PString    m_note;
    00092     PTime      m_when;
    00093
    00094     PURL       m_entity;
    00095     PURL       m_target;
    00096     PString    m_service;
    00097     PString    m_contact;
    00098     PStringSet m_capabilities;
    00099
    00100     PString    m_infoType;
    00101     PString    m_infoData;
    00102
    00103     OpalPresenceInfo(State state = Unchanged);
    00104
    00105     static PString AsString(State state);
    00106     static State FromString(const PString & str);
    00107     PString AsString() const;
    00108
    00109     Comparison Compare(const PObject & other) const;
    00110 };
    00111
    00112 ostream & operator<<(ostream & strm, OpalPresenceInfo::State state);
    00113
    00115
    00116 class OpalSetLocalPresenceCommand;
    00117 class OpalSubscribeToPresenceCommand;
    00118 class OpalAuthorisationRequestCommand;
    00119 class OpalSendMessageToCommand;
    00120
    00130 class OpalPresentity : public PSafeObject
    00131 {
    00132     PCLASSINFO(OpalPresentity, PSafeObject);
    00133
    00136   protected:
    00138     OpalPresentity();
    00139     OpalPresentity(const OpalPresentity & other);
    00140
    00141   public:
    00142     ~OpalPresentity();
    00143
    00146     static OpalPresentity * Create(
    00147       OpalManager & manager,
    00148       const PURL & url,
    00149       const PString & scheme = PString::Empty()
    00150     );
    00152
    00164     virtual bool Open();
    00165
    00168     virtual bool IsOpen() const { return m_open; }
    00169
    00172     virtual bool Close();
    00174
    00177
    00178     PStringOptions & GetAttributes() { return m_attributes; }
    00179
    00181     virtual PStringArray GetAttributeNames() const = 0;
    00182
    00184     virtual PStringArray GetAttributeTypes() const = 0;
    00185
    00186     static const PCaselessString & AuthNameKey();
    00187     static const PCaselessString & AuthPasswordKey();
    00188     static const PCaselessString & TimeToLiveKey();
    00189
    00194     const PURL & GetAOR() const { return m_aor; }
    00196
    00207     virtual bool SubscribeToPresence(
    00208       const PURL & presentity,
    00209       bool subscribe = true,
    00210       const PString & note = PString::Empty()
    00211     );
    00212
    00221     virtual bool UnsubscribeFromPresence(
    00222       const PURL & presentity
    00223     );
    00224
    00226     enum Authorisation {
    00227       AuthorisationPermitted,
    00228       AuthorisationDenied,
    00229       AuthorisationDeniedPolitely,
    00230       AuthorisationConfirming,
    00231       AuthorisationRemove,
    00232       NumAuthorisations
    00233     };
    00234
    00245     virtual bool SetPresenceAuthorisation(
    00246       const PURL & presentity,
    00247       Authorisation authorisation
    00248     );
    00249
    00257     bool SetLocalPresence(
    00258       const OpalPresenceInfo & info
    00259     );
    00260
    00261     // For backward compatibility
    00262     bool SetLocalPresence(
    00263       OpalPresenceInfo::State state,
    00264       const PString & note = PString::Empty()
    00265     );
    00266
    00269     bool GetLocalPresence(
    00270       OpalPresenceInfo & info
    00271     );
    00272
    00273     // For backward compatibility
    00274     bool GetLocalPresence(
    00275       OpalPresenceInfo::State & state,
    00276       PString & note
    00277     );
    00278
    00279
    00284     template <class cls>
    00285     __inline cls * CreateCommand()
    00286     {
    00287       return dynamic_cast<cls *>(InternalCreateCommand(typeid(cls).name()));
    00288     }
    00289
    00301     virtual bool SendCommand(
    00302       OpalPresentityCommand * cmd
    00303     );
    00305
    00308     struct AuthorisationRequest
    00309     {
    00310       PURL    m_presentity;
    00311       PString m_note;
    00312     };
    00313
    00321     virtual void OnAuthorisationRequest(
    00322       const AuthorisationRequest & request
    00323     );
    00324
    00325     typedef PNotifierTemplate<AuthorisationRequest> AuthorisationRequestNotifier;
    00326     #define PDECLARE_AuthorisationRequestNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, OpalPresentity::AuthorisationRequest)
    00327     #define PDECLARE_ASYNC_AuthorisationRequestNotifier(cls, fn) PDECLARE_ASYNC_NOTIFIER2(OpalPresentity, cls, fn, OpalPresentity::AuthorisationRequest)
    00328     #define PCREATE_AuthorisationRequestNotifier(fn) PCREATE_NOTIFIER2(fn, OpalPresentity::AuthorisationRequest)
    00329
    00331     void SetAuthorisationRequestNotifier(
    00332       const AuthorisationRequestNotifier & notifier
    00333     );
    00334
    00343     virtual void OnPresenceChange(
    00344       const OpalPresenceInfo & info
    00345     );
    00346
    00347     typedef PNotifierTemplate< std::auto_ptr<OpalPresenceInfo> > PresenceChangeNotifier;
    00348     #define PDECLARE_PresenceChangeNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, std::auto_ptr<OpalPresenceInfo>)
    00349     #define PDECLARE_ASYNC_PresenceChangeNotifier(cls, fn) PDECLARE_ASYNC_NOTIFIER2(OpalPresentity, cls, fn, std::auto_ptr<OpalPresenceInfo>)
    00350     #define PCREATE_PresenceChangeNotifier(fn) PCREATE_NOTIFIER2(fn, std::auto_ptr<OpalPresenceInfo>)
    00351
    00353     void SetPresenceChangeNotifier(
    00354       const PresenceChangeNotifier & notifier
    00355     );
    00357
    00364     struct BuddyInfo {
    00365       BuddyInfo(
    00366         const PURL & presentity = PString::Empty(),
    00367         const PString & displayName = PString::Empty()
    00368       ) : m_presentity(presentity)
    00369         , m_displayName(displayName)
    00370       { }
    00371
    00372       PURL    m_presentity;
    00373       PString m_displayName;
    00374
    00375       // RFC4482 contact fields, note most of these are duplicated
    00376       // in the vCard structure
    00377 #ifdef P_VCARD
    00378       PvCard  m_vCard;
    00382 #endif
    00383       PURL    m_icon;
    00387       PURL    m_map;
    00389       PURL    m_sound;
    00393       PURL    m_homePage;
    00394
    00395       // Extra field for protocol dependent "get out of gaol" card
    00396       PString m_contentType;
    00397       PString m_rawXML;
    00398     };
    00399
    00400     typedef std::list<BuddyInfo> BuddyList;
    00401
    00402     enum BuddyStatus {
    00403       BuddyStatus_GenericFailure             = -1,
    00404       BuddyStatus_OK                         = 0,
    00405       BuddyStatus_SpecifiedBuddyNotFound,
    00406       BuddyStatus_ListFeatureNotImplemented,
    00407       BuddyStatus_ListTemporarilyUnavailable,
    00408       BuddyStatus_ListMayBeIncomplete,
    00409       BuddyStatus_BadBuddySpecification,
    00410       BuddyStatus_ListSubscribeFailed,
    00411       BuddyStatus_AccountNotLoggedIn
    00412     };
    00413
    00416     virtual BuddyStatus GetBuddyListEx(
    00417       BuddyList & buddies
    00418     );
    00419     virtual bool GetBuddyList(
    00420       BuddyList & buddies
    00421     )
    00422     { return GetBuddyListEx(buddies) == BuddyStatus_OK; }
    00423
    00426     virtual BuddyStatus SetBuddyListEx(
    00427       const BuddyList & buddies
    00428     );
    00429     virtual bool SetBuddyList(
    00430       const BuddyList & buddies
    00431     )
    00432     { return SetBuddyListEx(buddies) == BuddyStatus_OK; }
    00433
    00434
    00437     virtual BuddyStatus DeleteBuddyListEx();
    00438     virtual bool DeleteBuddyList() { return DeleteBuddyListEx() == BuddyStatus_OK; }
    00439
    00444     virtual BuddyStatus GetBuddyEx(
    00445       BuddyInfo & buddy
    00446     );
    00447     virtual bool GetBuddy(
    00448       BuddyInfo & buddy
    00449     )
    00450     { return GetBuddyEx(buddy) == BuddyStatus_OK; }
    00451
    00454     virtual BuddyStatus SetBuddyEx(
    00455       const BuddyInfo & buddy
    00456     );
    00457     virtual bool SetBuddy(
    00458       const BuddyInfo & buddy
    00459     )
    00460     { return SetBuddyEx(buddy) == BuddyStatus_OK; }
    00461
    00464     virtual BuddyStatus DeleteBuddyEx(
    00465       const PURL & presentity
    00466     );
    00467     virtual bool DeleteBuddy(
    00468       const PURL & presentity
    00469     )
    00470     { return DeleteBuddyEx(presentity) == BuddyStatus_OK; }
    00471
    00477     virtual BuddyStatus SubscribeBuddyListEx(
    00478       PINDEX & successfulCount,
    00479       bool subscribe = true
    00480     );
    00481     virtual bool SubscribeBuddyList(
    00482       bool subscribe = true
    00483     )
    00484     { PINDEX successfulCount; return SubscribeBuddyListEx(successfulCount, subscribe) == BuddyStatus_OK; }
    00485
    00491     virtual BuddyStatus UnsubscribeBuddyListEx();
    00492     virtual bool UnsubscribeBuddyList()
    00493     { return UnsubscribeBuddyListEx() == BuddyStatus_OK; }
    00495
    00496
    00497 #if OPAL_HAS_IM
    00498
    00500     virtual bool SendMessageTo(
    00501       const OpalIM & message
    00502     );
    00503
    00510     virtual void OnReceivedMessage(
    00511       const OpalIM & message
    00512     );
    00513
    00514     typedef PNotifierTemplate<OpalIM> ReceivedMessageNotifier;
    00515     #define PDECLARE_ReceivedMessageNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, OpalIM)
    00516     #define PDECLARE_ASYNC_ReceivedMessageNotifier(cls, fn) PDECLARE_ASYNC_NOTIFIER2(OpalPresentity, cls, fn, OpalIM)
    00517     #define PCREATE_ReceivedMessageNotifier(fn) PCREATE_NOTIFIER2(fn, OpalIM)
    00518
    00520     void SetReceivedMessageNotifier(
    00521       const ReceivedMessageNotifier & notifier
    00522     );
    00523
    00524     void Internal_SendMessageToCommand(const OpalSendMessageToCommand & cmd);
    00526 #endif // OPAL_HAS_IM
    00527
    00532     virtual void SetAOR(
    00533       const PURL & aor
    00534     );
    00535
    00536     OpalManager & GetManager() const { return *m_manager; }
    00537
    00538   protected:
    00539     OpalPresentityCommand * InternalCreateCommand(const char * cmdName);
    00540
    00541     OpalManager        * m_manager;
    00542     PGloballyUniqueID    m_guid;
    00543     PURL                 m_aor;
    00544     PStringOptions       m_attributes;
    00545
    00546     AuthorisationRequestNotifier m_onAuthorisationRequestNotifier;
    00547     PresenceChangeNotifier       m_onPresenceChangeNotifier;
    00548 #if OPAL_HAS_IM
    00549     ReceivedMessageNotifier      m_onReceivedMessageNotifier;
    00550 #endif // OPAL_HAS_IM
    00551
    00552     PAtomicBoolean m_open;
    00553     PMutex m_notificationMutex;
    00554     bool m_temporarilyUnavailable;
    00555     OpalPresenceInfo m_localInfo;
    00556 };
    00557
    00558
    00560
    00564 class OpalPresentityWithCommandThread : public OpalPresentity
    00565 {
    00566     PCLASSINFO(OpalPresentityWithCommandThread, OpalPresentity);
    00567
    00570   protected:
    00572     OpalPresentityWithCommandThread();
    00573     OpalPresentityWithCommandThread(const OpalPresentityWithCommandThread & other);
    00574
    00575   public:
    00579     ~OpalPresentityWithCommandThread();
    00581
    00595     virtual bool SendCommand(
    00596       OpalPresentityCommand * cmd
    00597     );
    00599
    00612     void StartThread(
    00613       bool startQueue = true
    00614     );
    00615
    00621     void StopThread();
    00622
    00625     void StartQueue(
    00626       bool startQueue = true
    00627     );
    00628
    00630
    00631   protected:
    00632     void ThreadMain();
    00633
    00634     typedef std::queue<OpalPresentityCommand *> CommandQueue;
    00635     CommandQueue   m_commandQueue;
    00636     PMutex         m_commandQueueMutex;
    00637     PAtomicInteger m_commandSequence;
    00638     PSyncPoint     m_commandQueueSync;
    00639
    00640     bool      m_threadRunning;
    00641     bool      m_queueRunning;
    00642     PThread * m_thread;
    00643 };
    00644
    00646
    00649 class OpalPresentityCommand {
    00650   public:
    00651     OpalPresentityCommand(bool responseNeeded = false)
    00652       : m_responseNeeded(responseNeeded)
    00653     { }
    00654     virtual ~OpalPresentityCommand() { }
    00655
    00659     virtual void Process(
    00660       OpalPresentity & presentity
    00661     ) = 0;
    00662
    00663     typedef PAtomicInteger::IntegerType CmdSeqType;
    00664     CmdSeqType m_sequence;
    00665     bool       m_responseNeeded;
    00666     PURL       m_presentity;
    00667 };
    00668
    00671 #define OPAL_DEFINE_COMMAND(command, entity, func) \
    00672   class entity##_##command : public command \
    00673   { \
    00674     public: virtual void Process(OpalPresentity & presentity) { dynamic_cast<entity &>(presentity).func(*this); } \
    00675   }; \
    00676   static PFactory<OpalPresentityCommand>::Worker<entity##_##command> \
    00677   s_##entity##_##command(PDefaultPFactoryKey(entity::Class())+typeid(command).name())
    00678
    00679
    00682 class OpalSubscribeToPresenceCommand : public OpalPresentityCommand {
    00683   public:
    00684     OpalSubscribeToPresenceCommand(bool subscribe = true) : m_subscribe(subscribe) { }
    00685
    00686     bool    m_subscribe;
    00687     PString m_note;
    00688 };
    00689
    00690
    00697 class OpalAuthorisationRequestCommand : public OpalPresentityCommand {
    00698   public:
    00699     OpalAuthorisationRequestCommand() : m_authorisation(OpalPresentity::AuthorisationPermitted) { }
    00700
    00701     OpalPresentity::Authorisation m_authorisation;
    00702     PString m_note;
    00703 };
    00704
    00705
    00711 class OpalSetLocalPresenceCommand : public OpalPresentityCommand, public OpalPresenceInfo {
    00712   public:
    00713     OpalSetLocalPresenceCommand(State state = NoPresence) : OpalPresenceInfo(state) { }
    00714 };
    00715
    00716
    00717 #if OPAL_HAS_IM
    00718
    00720 class OpalSendMessageToCommand : public OpalPresentityCommand
    00721 {
    00722   public:
    00723     OpalSendMessageToCommand() { }
    00724
    00725     OpalIM m_message;
    00726 };
    00727 #endif // OPAL_HAS_IM
    00728
    00729
    00731
    00732 // Include concrete classes here so the factories are initialised
    00733 #if OPAL_SIP_PRESENCE
    00734   PFACTORY_LOAD(SIP_Presentity);
    00735 #endif
    00736
    00737
    00738 #endif // OPAL_HAS_PRESENCE
    00739
    00740
    00741 #endif  // OPAL_IM_PRES_ENT_H