# 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