00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00262 bool SetLocalPresence(
00263 OpalPresenceInfo::State state,
00264 const PString & note = PString::Empty()
00265 );
00266
00269 bool GetLocalPresence(
00270 OpalPresenceInfo & info
00271 );
00272
00273
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
00376
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
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
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