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();
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
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 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
00713 #if OPAL_SIP && OPAL_PTLIB_EXPAT
00714 PFACTORY_LOAD(SIP_Presentity);
00715 #endif
00716
00717
00718 #endif // OPAL_IM_PRES_ENT_H
00719