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 #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,
00062 Forbidden = -2,
00063 NoPresence = -1,
00064
00065
00066 Unchanged,
00067 Available,
00068 Unavailable,
00069
00070
00071
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() = 0;
00170
00173 virtual bool IsOpen() const = 0;
00174
00177 virtual bool Close() = 0;
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
00369
00370 PvCard m_vCard;
00374 PURL m_icon;
00378 PURL m_map;
00380 PURL m_sound;
00384 PURL m_homePage;
00385
00386
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 virtual PString GetID() const;
00523
00524 protected:
00525 OpalPresentityCommand * InternalCreateCommand(const char * cmdName);
00526
00527 OpalManager * m_manager;
00528 PGloballyUniqueID m_guid;
00529 PURL m_aor;
00530 PStringOptions m_attributes;
00531
00532 AuthorisationRequestNotifier m_onAuthorisationRequestNotifier;
00533 PresenceChangeNotifier m_onPresenceChangeNotifier;
00534 ReceivedMessageNotifier m_onReceivedMessageNotifier;
00535
00536 PMutex m_notificationMutex;
00537 PAtomicInteger::IntegerType m_idNumber;
00538
00539 bool m_temporarilyUnavailable;
00540 OpalPresenceInfo::State m_localState;
00541 PString m_localStateNote;
00542 };
00543
00544
00546
00550 class OpalPresentityWithCommandThread : public OpalPresentity
00551 {
00552 PCLASSINFO(OpalPresentityWithCommandThread, OpalPresentity);
00553
00556 protected:
00558 OpalPresentityWithCommandThread();
00559 OpalPresentityWithCommandThread(const OpalPresentityWithCommandThread & other);
00560
00561 public:
00565 ~OpalPresentityWithCommandThread();
00567
00581 virtual bool SendCommand(
00582 OpalPresentityCommand * cmd
00583 );
00585
00598 void StartThread(
00599 bool startQueue = true
00600 );
00601
00607 void StopThread();
00608
00611 void StartQueue(
00612 bool startQueue = true
00613 );
00614
00616
00617 protected:
00618 void ThreadMain();
00619
00620 typedef std::queue<OpalPresentityCommand *> CommandQueue;
00621 CommandQueue m_commandQueue;
00622 PMutex m_commandQueueMutex;
00623 PAtomicInteger m_commandSequence;
00624 PSyncPoint m_commandQueueSync;
00625
00626 bool m_threadRunning;
00627 bool m_queueRunning;
00628 PThread * m_thread;
00629 };
00630
00632
00635 class OpalPresentityCommand {
00636 public:
00637 OpalPresentityCommand(bool responseNeeded = false)
00638 : m_responseNeeded(responseNeeded)
00639 { }
00640 virtual ~OpalPresentityCommand() { }
00641
00645 virtual void Process(
00646 OpalPresentity & presentity
00647 ) = 0;
00648
00649 typedef PAtomicInteger::IntegerType CmdSeqType;
00650 CmdSeqType m_sequence;
00651 bool m_responseNeeded;
00652 PURL m_presentity;
00653 };
00654
00657 #define OPAL_DEFINE_COMMAND(command, entity, func) \
00658 class entity##_##command : public command \
00659 { \
00660 public: virtual void Process(OpalPresentity & presentity) { dynamic_cast<entity &>(presentity).func(*this); } \
00661 }; \
00662 static PFactory<OpalPresentityCommand>::Worker<entity##_##command> \
00663 s_##entity##_##command(PDefaultPFactoryKey(entity::Class())+typeid(command).name())
00664
00665
00668 class OpalSubscribeToPresenceCommand : public OpalPresentityCommand {
00669 public:
00670 OpalSubscribeToPresenceCommand(bool subscribe = true) : m_subscribe(subscribe) { }
00671
00672 bool m_subscribe;
00673 PString m_note;
00674 };
00675
00676
00683 class OpalAuthorisationRequestCommand : public OpalPresentityCommand {
00684 public:
00685 OpalAuthorisationRequestCommand() : m_authorisation(OpalPresentity::AuthorisationPermitted) { }
00686
00687 OpalPresentity::Authorisation m_authorisation;
00688 PString m_note;
00689 };
00690
00691
00697 class OpalSetLocalPresenceCommand : public OpalPresentityCommand, public OpalPresenceInfo {
00698 public:
00699 OpalSetLocalPresenceCommand(State state = NoPresence) : OpalPresenceInfo(state) { }
00700 };
00701
00702
00705 class OpalSendMessageToCommand : public OpalPresentityCommand
00706 {
00707 public:
00708 OpalSendMessageToCommand() { }
00709
00710 OpalIM m_message;
00711 };
00712
00714
00715
00716 #if OPAL_SIP && OPAL_PTLIB_EXPAT
00717 PFACTORY_LOAD(SIP_Presentity);
00718 #endif
00719
00720
00721 #endif // OPAL_IM_PRES_ENT_H
00722