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: 28081 $
00027  * $Author: rjongbloed $
00028  * $Date: 2012-07-22 07:24:14 -0500 (Sun, 22 Jul 2012) $
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 #include <ptclib/vcard.h>
00042 
00043 #include <im/im.h>
00044 
00045 #include <list>
00046 #include <queue>
00047 
00048 class OpalManager;
00049 class OpalPresentityCommand;
00050 
00051 
00053 
00056 class OpalPresenceInfo : public PObject
00057 {
00058   public:
00060     enum State {
00061       InternalError = -3,    // something bad happened
00062       Forbidden     = -2,    // access to presence information was specifically forbidden
00063       NoPresence    = -1,    // remove presence status - not the same as Unavailable or Away
00064 
00065       // basic states (from RFC 3863)
00066       Unchanged,
00067       Available,
00068       Unavailable,
00069 
00070       // extended states (from RFC 4480)
00071       // if this is changed, also change the tables in sippres.cxx and handlers.cxx - look for RFC 4480
00072       ExtendedBase    = 100,
00073       UnknownExtended = ExtendedBase,
00074       Appointment,
00075       Away,
00076       Breakfast,
00077       Busy,
00078       Dinner,
00079       Holiday,
00080       InTransit,
00081       LookingForWork,
00082       Lunch,
00083       Meal,
00084       Meeting,
00085       OnThePhone,
00086       Other,
00087       Performance,
00088       PermanentAbsence,
00089       Playing,
00090       Presentation,
00091       Shopping,
00092       Sleeping,
00093       Spectator,
00094       Steering,
00095       Travel,
00096       TV,
00097       Vacation,
00098       Working,
00099       Worship
00100     };
00101 
00102     State   m_state;    
00103     PString m_note;     
00104     PURL    m_entity;   
00105     PURL    m_target;   
00106     PTime   m_when;     
00107 
00108     OpalPresenceInfo(State state = Unchanged) : m_state(state) { }
00109 
00110     static PString AsString(State state);
00111     static State FromString(const PString & str);
00112     PString AsString() const;
00113 
00114     Comparison Compare(const PObject & other) const;
00115 };
00116 
00117 ostream & operator<<(ostream & strm, OpalPresenceInfo::State state);
00118 
00120 
00121 class OpalSetLocalPresenceCommand;
00122 class OpalSubscribeToPresenceCommand;
00123 class OpalAuthorisationRequestCommand;
00124 class OpalSendMessageToCommand;
00125 
00135 class OpalPresentity : public PSafeObject
00136 {
00137     PCLASSINFO(OpalPresentity, PSafeObject);
00138 
00141   protected:
00143     OpalPresentity();
00144     OpalPresentity(const OpalPresentity & other);
00145 
00146   public:
00147     ~OpalPresentity();
00148 
00151     static OpalPresentity * Create(
00152       OpalManager & manager, 
00153       const PURL & url,      
00154       const PString & scheme = PString::Empty() 
00155     );
00157 
00169     virtual bool Open();
00170 
00173     virtual bool IsOpen() const { return m_open; }
00174 
00177     virtual bool Close();
00179 
00182 
00183     PStringOptions & GetAttributes() { return m_attributes; }
00184 
00186     virtual PStringArray GetAttributeNames() const = 0;
00187 
00189     virtual PStringArray GetAttributeTypes() const = 0;
00190 
00191     static const PCaselessString & AuthNameKey();         
00192     static const PCaselessString & AuthPasswordKey();     
00193     static const PCaselessString & TimeToLiveKey();       
00194 
00199     const PURL & GetAOR() const { return m_aor; }
00201 
00212     virtual bool SubscribeToPresence(
00213       const PURL & presentity,      
00214       bool subscribe = true,        
00215       const PString & note = PString::Empty() 
00216     );
00217 
00226     virtual bool UnsubscribeFromPresence(
00227       const PURL & presentity    
00228     );
00229 
00231     enum Authorisation {
00232       AuthorisationPermitted,
00233       AuthorisationDenied,
00234       AuthorisationDeniedPolitely,
00235       AuthorisationConfirming,
00236       AuthorisationRemove,
00237       NumAuthorisations
00238     };
00239 
00250     virtual bool SetPresenceAuthorisation(
00251       const PURL & presentity,        
00252       Authorisation authorisation     
00253     );
00254 
00262     virtual bool SetLocalPresence(
00263       OpalPresenceInfo::State state,            
00264       const PString & note = PString::Empty()   
00265     );
00266 
00269     virtual bool GetLocalPresence(
00270       OpalPresenceInfo::State & state, 
00271       PString & note
00272     );
00273 
00274 
00279     template <class cls>
00280     __inline cls * CreateCommand()
00281     {
00282       return dynamic_cast<cls *>(InternalCreateCommand(typeid(cls).name()));
00283     }
00284 
00296     virtual bool SendCommand(
00297       OpalPresentityCommand * cmd   
00298     );
00300 
00303     struct AuthorisationRequest
00304     {
00305       PURL    m_presentity; 
00306       PString m_note;       
00307     };
00308 
00316     virtual void OnAuthorisationRequest(
00317       const AuthorisationRequest & request  
00318     );
00319 
00320     typedef PNotifierTemplate<const AuthorisationRequest &> AuthorisationRequestNotifier;
00321 #define PDECLARE_AuthorisationRequestNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, const OpalPresentity::AuthorisationRequest &)
00322     #define PCREATE_AuthorisationRequestNotifier(fn) PCREATE_NOTIFIER2(fn, const OpalPresentity::AuthorisationRequest &)
00323 
00325     void SetAuthorisationRequestNotifier(
00326       const AuthorisationRequestNotifier & notifier   
00327     );
00328 
00337     virtual void OnPresenceChange(
00338       const OpalPresenceInfo & info 
00339     );
00340 
00341     typedef PNotifierTemplate<const OpalPresenceInfo &> PresenceChangeNotifier;
00342     #define PDECLARE_PresenceChangeNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, const OpalPresenceInfo &)
00343     #define PCREATE_PresenceChangeNotifier(fn) PCREATE_NOTIFIER2(fn, const OpalPresenceInfo &)
00344 
00346     void SetPresenceChangeNotifier(
00347       const PresenceChangeNotifier & notifier   
00348     );
00350 
00357     struct BuddyInfo {
00358       BuddyInfo(
00359         const PURL & presentity = PString::Empty(),
00360         const PString & displayName = PString::Empty()
00361       ) : m_presentity(presentity)
00362         , m_displayName(displayName)
00363       { }
00364 
00365       PURL    m_presentity;   
00366       PString m_displayName;  
00367 
00368       // RFC4482 contact fields, note most of these are duplicated
00369       // in the vCard structure
00370       PvCard  m_vCard;        
00374       PURL    m_icon;         
00378       PURL    m_map;          
00380       PURL    m_sound;        
00384       PURL    m_homePage;     
00385 
00386       // Extra field for protocol dependent "get out of gaol" card
00387       PString m_contentType;  
00388       PString m_rawXML;       
00389     };
00390 
00391     typedef std::list<BuddyInfo> BuddyList;
00392 
00393     enum BuddyStatus {
00394       BuddyStatus_GenericFailure             = -1,
00395       BuddyStatus_OK                         = 0,
00396       BuddyStatus_SpecifiedBuddyNotFound,
00397       BuddyStatus_ListFeatureNotImplemented,
00398       BuddyStatus_ListTemporarilyUnavailable,
00399       BuddyStatus_ListMayBeIncomplete,
00400       BuddyStatus_BadBuddySpecification,
00401       BuddyStatus_ListSubscribeFailed,
00402       BuddyStatus_AccountNotLoggedIn
00403     };
00404 
00407     virtual BuddyStatus GetBuddyListEx(
00408       BuddyList & buddies   
00409     );
00410     virtual bool GetBuddyList(
00411       BuddyList & buddies   
00412     )
00413     { return GetBuddyListEx(buddies) == BuddyStatus_OK; }
00414 
00417     virtual BuddyStatus SetBuddyListEx(
00418       const BuddyList & buddies   
00419     );
00420     virtual bool SetBuddyList(
00421       const BuddyList & buddies   
00422     )
00423     { return SetBuddyListEx(buddies) == BuddyStatus_OK; }
00424 
00425 
00428     virtual BuddyStatus DeleteBuddyListEx();
00429     virtual bool DeleteBuddyList() { return DeleteBuddyListEx() == BuddyStatus_OK; }
00430 
00435     virtual BuddyStatus GetBuddyEx(
00436       BuddyInfo & buddy
00437     );
00438     virtual bool GetBuddy(
00439       BuddyInfo & buddy
00440     )
00441     { return GetBuddyEx(buddy) == BuddyStatus_OK; }
00442 
00445     virtual BuddyStatus SetBuddyEx(
00446       const BuddyInfo & buddy
00447     );
00448     virtual bool SetBuddy(
00449       const BuddyInfo & buddy
00450     )
00451     { return SetBuddyEx(buddy) == BuddyStatus_OK; }
00452 
00455     virtual BuddyStatus DeleteBuddyEx(
00456       const PURL & presentity
00457     );
00458     virtual bool DeleteBuddy(
00459       const PURL & presentity
00460     )
00461     { return DeleteBuddyEx(presentity) == BuddyStatus_OK; }
00462 
00468     virtual BuddyStatus SubscribeBuddyListEx(
00469       PINDEX & successfulCount,
00470       bool subscribe = true
00471     );
00472     virtual bool SubscribeBuddyList(
00473       bool subscribe = true
00474     )
00475     { PINDEX successfulCount; return SubscribeBuddyListEx(successfulCount, subscribe) == BuddyStatus_OK; }
00476 
00482     virtual BuddyStatus UnsubscribeBuddyListEx();
00483     virtual bool UnsubscribeBuddyList()
00484     { return UnsubscribeBuddyListEx() == BuddyStatus_OK; }
00486   
00487   
00490     virtual bool SendMessageTo(
00491       const OpalIM & message
00492     );
00493 
00498     virtual void OnReceivedMessage(
00499       const OpalIM & message 
00500     );
00501 
00502     typedef PNotifierTemplate<const OpalIM &> ReceivedMessageNotifier;
00503     #define PDECLARE_ReceivedMessageNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, const OpalIM &)
00504     #define PCREATE_ReceivedMessageNotifier(fn) PCREATE_NOTIFIER2(fn, const OpalIM &)
00505 
00507     void SetReceivedMessageNotifier(
00508       const ReceivedMessageNotifier & notifier   
00509     );
00511 
00516     virtual void SetAOR(
00517       const PURL & aor
00518     );
00519 
00520     void Internal_SendMessageToCommand(const OpalSendMessageToCommand & cmd);
00521 
00522   protected:
00523     OpalPresentityCommand * InternalCreateCommand(const char * cmdName);
00524 
00525     OpalManager        * m_manager;
00526     PGloballyUniqueID    m_guid;
00527     PURL                 m_aor;
00528     PStringOptions       m_attributes;
00529 
00530     AuthorisationRequestNotifier m_onAuthorisationRequestNotifier;
00531     PresenceChangeNotifier       m_onPresenceChangeNotifier;
00532     ReceivedMessageNotifier      m_onReceivedMessageNotifier;
00533 
00534     PAtomicBoolean m_open;
00535     PMutex m_notificationMutex;
00536     bool m_temporarilyUnavailable;
00537     OpalPresenceInfo::State m_localState;      
00538     PString m_localStateNote;                  
00539 };
00540 
00541 
00543 
00547 class OpalPresentityWithCommandThread : public OpalPresentity
00548 {
00549     PCLASSINFO(OpalPresentityWithCommandThread, OpalPresentity);
00550 
00553   protected:
00555     OpalPresentityWithCommandThread();
00556     OpalPresentityWithCommandThread(const OpalPresentityWithCommandThread & other);
00557 
00558   public:
00562     ~OpalPresentityWithCommandThread();
00564 
00578     virtual bool SendCommand(
00579       OpalPresentityCommand * cmd   
00580     );
00582 
00595     void StartThread(
00596       bool startQueue = true
00597     );
00598 
00604     void StopThread();
00605 
00608     void StartQueue(
00609       bool startQueue = true
00610     );
00611     
00613 
00614   protected:
00615     void ThreadMain();
00616 
00617     typedef std::queue<OpalPresentityCommand *> CommandQueue;
00618     CommandQueue   m_commandQueue;
00619     PMutex         m_commandQueueMutex;
00620     PAtomicInteger m_commandSequence;
00621     PSyncPoint     m_commandQueueSync;
00622 
00623     bool      m_threadRunning;
00624     bool      m_queueRunning;
00625     PThread * m_thread;
00626 };
00627 
00629 
00632 class OpalPresentityCommand {
00633   public:
00634     OpalPresentityCommand(bool responseNeeded = false) 
00635       : m_responseNeeded(responseNeeded)
00636     { }
00637     virtual ~OpalPresentityCommand() { }
00638 
00642     virtual void Process(
00643       OpalPresentity & presentity
00644     ) = 0;
00645 
00646     typedef PAtomicInteger::IntegerType CmdSeqType;
00647     CmdSeqType m_sequence;
00648     bool       m_responseNeeded;
00649     PURL       m_presentity;
00650 };
00651 
00654 #define OPAL_DEFINE_COMMAND(command, entity, func) \
00655   class entity##_##command : public command \
00656   { \
00657     public: virtual void Process(OpalPresentity & presentity) { dynamic_cast<entity &>(presentity).func(*this); } \
00658   }; \
00659   static PFactory<OpalPresentityCommand>::Worker<entity##_##command> \
00660   s_##entity##_##command(PDefaultPFactoryKey(entity::Class())+typeid(command).name())
00661 
00662 
00665 class OpalSubscribeToPresenceCommand : public OpalPresentityCommand {
00666   public:
00667     OpalSubscribeToPresenceCommand(bool subscribe = true) : m_subscribe(subscribe) { }
00668 
00669     bool    m_subscribe;  
00670     PString m_note;       
00671 };
00672 
00673 
00680 class OpalAuthorisationRequestCommand : public OpalPresentityCommand {
00681   public:
00682     OpalAuthorisationRequestCommand() : m_authorisation(OpalPresentity::AuthorisationPermitted) { }
00683 
00684     OpalPresentity::Authorisation m_authorisation;  
00685     PString m_note;                                 
00686 };
00687 
00688 
00694 class OpalSetLocalPresenceCommand : public OpalPresentityCommand, public OpalPresenceInfo {
00695   public:
00696     OpalSetLocalPresenceCommand(State state = NoPresence) : OpalPresenceInfo(state) { }
00697 };
00698 
00699 
00702 class OpalSendMessageToCommand : public OpalPresentityCommand
00703 {
00704   public:
00705     OpalSendMessageToCommand() { }
00706 
00707     OpalIM m_message;
00708 };
00709 
00711 
00712 // Include concrete classes here so the factories are initialised
00713 #if OPAL_SIP && OPAL_PTLIB_EXPAT
00714 PFACTORY_LOAD(SIP_Presentity);
00715 #endif
00716 
00717 
00718 #endif  // OPAL_IM_PRES_ENT_H
00719 

Generated on 14 Aug 2013 for OPAL by  doxygen 1.4.7