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: 22858 $
00027  * $Author: csoutheren $
00028  * $Date: 2009-06-12 22:50:19 +1000 (Fri, 12 Jun 2009) $
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 #include <ptlib/pfactory.h>
00038 #include <ptlib/safecoll.h>
00039 #include <ptclib/url.h>
00040 #include <ptclib/guid.h>
00041 
00042 #include <im/im.h>
00043 
00044 #include <list>
00045 #include <queue>
00046 
00047 class OpalManager;
00048 class OpalPresentityCommand;
00049 
00050 
00052 
00055 class OpalPresenceInfo
00056 {
00057   public:
00059     enum State {
00060       InternalError = -3,    // something bad happened
00061       Forbidden     = -2,    // access to presence information was specifically forbidden
00062       NoPresence    = -1,    // remove presence status - not the same as Unavailable or Away
00063 
00064       // basic states (from RFC 3863)
00065       Unchanged,
00066       Available,
00067       Unavailable,
00068 
00069       // extended states (from RFC 4480)
00070       // if this is changed, also change the tables in sippres.cxx and handlers.cxx - look for RFC 4480
00071       ExtendedBase    = 100,
00072       UnknownExtended = ExtendedBase,
00073       Appointment,
00074       Away,
00075       Breakfast,
00076       Busy,
00077       Dinner,
00078       Holiday,
00079       InTransit,
00080       LookingForWork,
00081       Lunch,
00082       Meal,
00083       Meeting,
00084       OnThePhone,
00085       Other,
00086       Performance,
00087       PermanentAbsence,
00088       Playing,
00089       Presentation,
00090       Shopping,
00091       Sleeping,
00092       Spectator,
00093       Steering,
00094       Travel,
00095       TV,
00096       Vacation,
00097       Working,
00098       Worship
00099     };
00100 
00101     State   m_state;    
00102     PString m_note;     
00103     PURL    m_entity;   
00104     PURL    m_target;   
00105 
00106     OpalPresenceInfo(State state = Unchanged) : m_state(state) { }
00107 
00108     static PString AsString(State state);
00109     static State FromString(const PString & str);
00110     PString AsString() const;
00111 };
00112 
00113 ostream & operator<<(ostream & strm, OpalPresenceInfo::State state);
00114 
00116 
00117 class OpalSetLocalPresenceCommand;
00118 class OpalSubscribeToPresenceCommand;
00119 class OpalAuthorisationRequestCommand;
00120 class OpalSendMessageToCommand;
00121 
00131 class OpalPresentity : public PSafeObject
00132 {
00133     PCLASSINFO(OpalPresentity, PSafeObject);
00134 
00137   protected:
00139     OpalPresentity();
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() = 0;
00165 
00168     virtual bool IsOpen() const = 0;
00169 
00172     virtual bool Close() = 0;
00174 
00179     class Attributes :  public PStringToString
00180     {
00181       public:
00183         virtual bool Has(const PString &   key   ) const { return Contains(key  ); }
00184         virtual bool Has(const PString & (*key)()) const { return Contains(key()); }
00185 
00187         virtual PString Get(const PString &   key   , const PString & deflt = PString::Empty()) const { return (*this)(key  , deflt); }
00188                 PString Get(const PString & (*key)(), const PString & deflt = PString::Empty()) const { return (*this)(key(), deflt); }
00189 
00191         virtual void Set(const PString &   key   , const PString & value) { SetAt(key  , value); }
00192                 void Set(const PString & (*key)(), const PString & value) { SetAt(key(), value); }
00193     };
00194 
00196     Attributes & GetAttributes() { return m_attributes; }
00197 
00198     static const PString & AuthNameKey();         
00199     static const PString & AuthPasswordKey();     
00200     static const PString & FullNameKey();         
00201     static const PString & SchemeKey();           
00202     static const PString & TimeToLiveKey();       
00203 
00208     const PURL & GetAOR() const { return m_aor; }
00210 
00221     virtual bool SubscribeToPresence(
00222       const PURL & presentity,      
00223       bool subscribe = true,        
00224       const PString & note = PString::Empty() 
00225     );
00226 
00235     virtual bool UnsubscribeFromPresence(
00236       const PURL & presentity    
00237     );
00238 
00240     enum Authorisation {
00241       AuthorisationPermitted,
00242       AuthorisationDenied,
00243       AuthorisationDeniedPolitely,
00244       AuthorisationConfirming,
00245       AuthorisationRemove,
00246       NumAuthorisations
00247     };
00248 
00259     virtual bool SetPresenceAuthorisation(
00260       const PURL & presentity,        
00261       Authorisation authorisation     
00262     );
00263 
00271     virtual bool SetLocalPresence(
00272       OpalPresenceInfo::State state,            
00273       const PString & note = PString::Empty()   
00274     );
00275 
00280     template <class cls>
00281     __inline cls * CreateCommand()
00282     {
00283       return dynamic_cast<cls *>(InternalCreateCommand(typeid(cls).name()));
00284     }
00285 
00297     virtual bool SendCommand(
00298       OpalPresentityCommand * cmd   
00299     );
00301 
00304     struct AuthorisationRequest
00305     {
00306       PURL    m_presentity; 
00307       PString m_note;       
00308     };
00309 
00317     virtual void OnAuthorisationRequest(
00318       const AuthorisationRequest & request  
00319     );
00320 
00321     typedef PNotifierTemplate<const AuthorisationRequest &> AuthorisationRequestNotifier;
00322 #define PDECLARE_AuthorisationRequestNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, const OpalPresentity::AuthorisationRequest &)
00323     #define PCREATE_AuthorisationRequestNotifier(fn) PCREATE_NOTIFIER2(fn, const OpalPresentity::AuthorisationRequest &)
00324 
00326     void SetAuthorisationRequestNotifier(
00327       const AuthorisationRequestNotifier & notifier   
00328     );
00329 
00338     virtual void OnPresenceChange(
00339       const OpalPresenceInfo & info 
00340     );
00341 
00342     typedef PNotifierTemplate<const OpalPresenceInfo &> PresenceChangeNotifier;
00343     #define PDECLARE_PresenceChangeNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, const OpalPresenceInfo &)
00344     #define PCREATE_PresenceChangeNotifier(fn) PCREATE_NOTIFIER2(fn, const OpalPresenceInfo &)
00345 
00347     void SetPresenceChangeNotifier(
00348       const PresenceChangeNotifier & notifier   
00349     );
00351 
00358     struct BuddyInfo {
00359       BuddyInfo(
00360         const PURL & presentity = PString::Empty(),
00361         const PString & displayName = PString::Empty()
00362       ) : m_presentity(presentity)
00363         , m_displayName(displayName)
00364       { }
00365 
00366       PURL    m_presentity;   
00367       PString m_displayName;  
00368 
00369       PString m_contentType;  
00370       PString m_rawXML;       
00371     };
00372 
00373     typedef std::list<BuddyInfo> BuddyList;
00374 
00375     enum BuddyStatus {
00376       BuddyStatus_GenericFailure             = -1,
00377       BuddyStatus_OK                         = 0,
00378       BuddyStatus_SpecifiedBuddyNotFound,
00379       BuddyStatus_ListFeatureNotImplemented,
00380       BuddyStatus_ListTemporarilyUnavailable,
00381       BuddyStatus_ListMayBeIncomplete,
00382       BuddyStatus_BadBuddySpecification,
00383       BuddyStatus_ListSubscribeFailed,
00384       BuddyStatus_AccountNotLoggedIn
00385     };
00386 
00389     virtual BuddyStatus GetBuddyListEx(
00390       BuddyList & buddies   
00391     );
00392     virtual bool GetBuddyList(
00393       BuddyList & buddies   
00394     )
00395     { return GetBuddyListEx(buddies) == BuddyStatus_OK; }
00396 
00399     virtual BuddyStatus SetBuddyListEx(
00400       const BuddyList & buddies   
00401     );
00402     virtual bool SetBuddyList(
00403       const BuddyList & buddies   
00404     )
00405     { return SetBuddyListEx(buddies) == BuddyStatus_OK; }
00406 
00407 
00410     virtual BuddyStatus DeleteBuddyListEx();
00411     virtual bool DeleteBuddyList() { return DeleteBuddyListEx() == BuddyStatus_OK; }
00412 
00417     virtual BuddyStatus GetBuddyEx(
00418       BuddyInfo & buddy
00419     );
00420     virtual bool GetBuddy(
00421       BuddyInfo & buddy
00422     )
00423     { return GetBuddyEx(buddy) == BuddyStatus_OK; }
00424 
00427     virtual BuddyStatus SetBuddyEx(
00428       const BuddyInfo & buddy
00429     );
00430     virtual bool SetBuddy(
00431       const BuddyInfo & buddy
00432     )
00433     { return SetBuddyEx(buddy) == BuddyStatus_OK; }
00434 
00437     virtual BuddyStatus DeleteBuddyEx(
00438       const PURL & presentity
00439     );
00440     virtual bool DeleteBuddy(
00441       const PURL & presentity
00442     )
00443     { return DeleteBuddyEx(presentity) == BuddyStatus_OK; }
00444 
00450     virtual BuddyStatus SubscribeBuddyListEx(
00451       PINDEX & successfulCount,
00452       bool subscribe = true
00453     );
00454     virtual bool SubscribeBuddyList(
00455       bool subscribe = true
00456     )
00457     { PINDEX successfulCount; return SubscribeBuddyListEx(successfulCount, subscribe) == BuddyStatus_OK; }
00458 
00464     virtual BuddyStatus UnsubscribeBuddyListEx();
00465     virtual bool UnsubscribeBuddyList()
00466     { return UnsubscribeBuddyListEx() == BuddyStatus_OK; }
00467 
00468     virtual PString GetID() const;
00470   
00471   
00472     virtual bool SendMessageTo(
00473       const OpalIM & message
00474     );
00475 
00480     virtual void OnReceivedMessage(
00481       const OpalIM & message 
00482     );
00483 
00484     typedef PNotifierTemplate<const OpalIM &> ReceivedMessageNotifier;
00485     #define PDECLARE_ReceivedMessageNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, const OpalIM &)
00486     #define PCREATE_ReceivedMessageNotifier(fn) PCREATE_NOTIFIER2(fn, const OpalIM &)
00487 
00489     void SetReceivedMessageNotifier(
00490       const ReceivedMessageNotifier & notifier   
00491     );
00492 
00493     void Internal_SendLocalPresence   (const OpalSetLocalPresenceCommand & cmd);
00494     void Internal_SubscribeToPresence (const OpalSubscribeToPresenceCommand & cmd);
00495     void Internal_AuthorisationRequest(const OpalAuthorisationRequestCommand & cmd);
00496     void Internal_SendMessageToCommand(const OpalSendMessageToCommand & cmd);
00497 
00498   protected:
00499     OpalPresentityCommand * InternalCreateCommand(const char * cmdName);
00500 
00501     OpalManager        * m_manager;
00502     PGloballyUniqueID    m_guid;
00503     PURL                 m_aor;
00504     Attributes           m_attributes;
00505 
00506     AuthorisationRequestNotifier m_onAuthorisationRequestNotifier;
00507     PresenceChangeNotifier       m_onPresenceChangeNotifier;
00508     ReceivedMessageNotifier      m_onReceivedMessageNotifier;
00509 
00510     PMutex m_notificationMutex;
00511     PAtomicInteger::IntegerType m_idNumber;
00512 
00513     bool m_temporarilyUnavailable;
00514 };
00515 
00516 
00518 
00522 class OpalPresentityWithCommandThread : public OpalPresentity
00523 {
00524     PCLASSINFO(OpalPresentityWithCommandThread, OpalPresentity);
00525 
00528   protected:
00530     OpalPresentityWithCommandThread();
00531 
00532   public:
00536     ~OpalPresentityWithCommandThread();
00538 
00552     virtual bool SendCommand(
00553       OpalPresentityCommand * cmd   
00554     );
00556 
00569     void StartThread(
00570       bool startQueue = true
00571     );
00572 
00578     void StopThread();
00579 
00582     void StartQueue(
00583       bool startQueue = true
00584     );
00585     
00587 
00588   protected:
00589     void ThreadMain();
00590 
00591     typedef std::queue<OpalPresentityCommand *> CommandQueue;
00592     CommandQueue   m_commandQueue;
00593     PMutex         m_commandQueueMutex;
00594     PAtomicInteger m_commandSequence;
00595     PSyncPoint     m_commandQueueSync;
00596 
00597     bool      m_threadRunning;
00598     bool      m_queueRunning;
00599     PThread * m_thread;
00600 };
00601 
00603 
00606 class OpalPresentityCommand {
00607   public:
00608     OpalPresentityCommand(bool responseNeeded = false) 
00609       : m_responseNeeded(responseNeeded)
00610     { }
00611     virtual ~OpalPresentityCommand() { }
00612 
00616     virtual void Process(
00617       OpalPresentity & presentity
00618     ) = 0;
00619 
00620     typedef PAtomicInteger::IntegerType CmdSeqType;
00621     CmdSeqType m_sequence;
00622     bool       m_responseNeeded;
00623     PURL       m_presentity;
00624 };
00625 
00628 #define OPAL_DEFINE_COMMAND(command, entity, func) \
00629   class entity##_##command : public command \
00630   { \
00631     public: virtual void Process(OpalPresentity & presentity) { dynamic_cast<entity &>(presentity).func(*this); } \
00632   }; \
00633   static PFactory<OpalPresentityCommand>::Worker<entity##_##command> \
00634   s_entity##_##command(PDefaultPFactoryKey(entity::Class())+typeid(command).name())
00635 
00636 
00639 class OpalSubscribeToPresenceCommand : public OpalPresentityCommand {
00640   public:
00641     OpalSubscribeToPresenceCommand(bool subscribe = true) : m_subscribe(subscribe) { }
00642 
00643     bool    m_subscribe;  
00644     PString m_note;       
00645 };
00646 
00647 
00654 class OpalAuthorisationRequestCommand : public OpalPresentityCommand {
00655   public:
00656     OpalAuthorisationRequestCommand() : m_authorisation(OpalPresentity::AuthorisationPermitted) { }
00657 
00658     OpalPresentity::Authorisation m_authorisation;  
00659     PString m_note;                                 
00660 };
00661 
00662 
00668 class OpalSetLocalPresenceCommand : public OpalPresentityCommand, public OpalPresenceInfo {
00669   public:
00670     OpalSetLocalPresenceCommand(State state = NoPresence) : OpalPresenceInfo(state) { }
00671 };
00672 
00673 
00676 class OpalSendMessageToCommand : public OpalPresentityCommand
00677 {
00678   public:
00679     OpalSendMessageToCommand() { }
00680 
00681     OpalIM m_message;
00682 };
00683 
00685 
00686 // Include concrete classes here so the factories are initialised
00687 #if OPAL_SIP && OPAL_PTLIB_EXPAT
00688 PFACTORY_LOAD(SIPLocal_Presentity);
00689 PFACTORY_LOAD(SIPXCAP_Presentity);
00690 PFACTORY_LOAD(SIPOMA_Presentity);
00691 #endif
00692 
00693 
00694 #endif  // OPAL_IM_PRES_ENT_H
00695 

Generated on Sun Nov 21 20:20:51 2010 for OPAL by  doxygen 1.4.7