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
00042 #include <im/im.h>
00043
00044 #include <list>
00045 #include <queue>
00046
00047 class OpalManager;
00048 class OpalPresentityCommand;
00049
00050
00052
00055 class OpalPresenceInfo
00056 {
00057 public:
00059 enum State {
00060 InternalError = -3,
00061 Forbidden = -2,
00062 NoPresence = -1,
00063
00064
00065 Unchanged,
00066 Available,
00067 Unavailable,
00068
00069
00070
00071 ExtendedBase = 100,
00072 UnknownExtended = ExtendedBase,
00073 Appointment,
00074 Away,
00075 Breakfast,
00076 Busy,
00077 Dinner,
00078 Holiday,
00079 InTransit,
00080 LookingForWork,
00081 Lunch,
00082 Meal,
00083 Meeting,
00084 OnThePhone,
00085 Other,
00086 Performance,
00087 PermanentAbsence,
00088 Playing,
00089 Presentation,
00090 Shopping,
00091 Sleeping,
00092 Spectator,
00093 Steering,
00094 Travel,
00095 TV,
00096 Vacation,
00097 Working,
00098 Worship
00099 };
00100
00101 State m_state;
00102 PString m_note;
00103 PURL m_entity;
00104 PURL m_target;
00105
00106 OpalPresenceInfo(State state = Unchanged) : m_state(state) { }
00107
00108 static PString AsString(State state);
00109 static State FromString(const PString & str);
00110 PString AsString() const;
00111 };
00112
00113 ostream & operator<<(ostream & strm, OpalPresenceInfo::State state);
00114
00116
00117 class OpalSetLocalPresenceCommand;
00118 class OpalSubscribeToPresenceCommand;
00119 class OpalAuthorisationRequestCommand;
00120 class OpalSendMessageToCommand;
00121
00131 class OpalPresentity : public PSafeObject
00132 {
00133 PCLASSINFO(OpalPresentity, PSafeObject);
00134
00137 protected:
00139 OpalPresentity();
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() = 0;
00165
00168 virtual bool IsOpen() const = 0;
00169
00172 virtual bool Close() = 0;
00174
00179 class Attributes : public PStringToString
00180 {
00181 public:
00183 virtual bool Has(const PString & key ) const { return Contains(key ); }
00184 virtual bool Has(const PString & (*key)()) const { return Contains(key()); }
00185
00187 virtual PString Get(const PString & key , const PString & deflt = PString::Empty()) const { return (*this)(key , deflt); }
00188 PString Get(const PString & (*key)(), const PString & deflt = PString::Empty()) const { return (*this)(key(), deflt); }
00189
00191 virtual void Set(const PString & key , const PString & value) { SetAt(key , value); }
00192 void Set(const PString & (*key)(), const PString & value) { SetAt(key(), value); }
00193 };
00194
00196 Attributes & GetAttributes() { return m_attributes; }
00197
00198 static const PString & AuthNameKey();
00199 static const PString & AuthPasswordKey();
00200 static const PString & FullNameKey();
00201 static const PString & SchemeKey();
00202 static const PString & TimeToLiveKey();
00203
00208 const PURL & GetAOR() const { return m_aor; }
00210
00221 virtual bool SubscribeToPresence(
00222 const PURL & presentity,
00223 bool subscribe = true,
00224 const PString & note = PString::Empty()
00225 );
00226
00235 virtual bool UnsubscribeFromPresence(
00236 const PURL & presentity
00237 );
00238
00240 enum Authorisation {
00241 AuthorisationPermitted,
00242 AuthorisationDenied,
00243 AuthorisationDeniedPolitely,
00244 AuthorisationConfirming,
00245 AuthorisationRemove,
00246 NumAuthorisations
00247 };
00248
00259 virtual bool SetPresenceAuthorisation(
00260 const PURL & presentity,
00261 Authorisation authorisation
00262 );
00263
00271 virtual bool SetLocalPresence(
00272 OpalPresenceInfo::State state,
00273 const PString & note = PString::Empty()
00274 );
00275
00280 template <class cls>
00281 __inline cls * CreateCommand()
00282 {
00283 return dynamic_cast<cls *>(InternalCreateCommand(typeid(cls).name()));
00284 }
00285
00297 virtual bool SendCommand(
00298 OpalPresentityCommand * cmd
00299 );
00301
00304 struct AuthorisationRequest
00305 {
00306 PURL m_presentity;
00307 PString m_note;
00308 };
00309
00317 virtual void OnAuthorisationRequest(
00318 const AuthorisationRequest & request
00319 );
00320
00321 typedef PNotifierTemplate<const AuthorisationRequest &> AuthorisationRequestNotifier;
00322 #define PDECLARE_AuthorisationRequestNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, const OpalPresentity::AuthorisationRequest &)
00323 #define PCREATE_AuthorisationRequestNotifier(fn) PCREATE_NOTIFIER2(fn, const OpalPresentity::AuthorisationRequest &)
00324
00326 void SetAuthorisationRequestNotifier(
00327 const AuthorisationRequestNotifier & notifier
00328 );
00329
00338 virtual void OnPresenceChange(
00339 const OpalPresenceInfo & info
00340 );
00341
00342 typedef PNotifierTemplate<const OpalPresenceInfo &> PresenceChangeNotifier;
00343 #define PDECLARE_PresenceChangeNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, const OpalPresenceInfo &)
00344 #define PCREATE_PresenceChangeNotifier(fn) PCREATE_NOTIFIER2(fn, const OpalPresenceInfo &)
00345
00347 void SetPresenceChangeNotifier(
00348 const PresenceChangeNotifier & notifier
00349 );
00351
00358 struct BuddyInfo {
00359 BuddyInfo(
00360 const PURL & presentity = PString::Empty(),
00361 const PString & displayName = PString::Empty()
00362 ) : m_presentity(presentity)
00363 , m_displayName(displayName)
00364 { }
00365
00366 PURL m_presentity;
00367 PString m_displayName;
00368
00369 PString m_contentType;
00370 PString m_rawXML;
00371 };
00372
00373 typedef std::list<BuddyInfo> BuddyList;
00374
00375 enum BuddyStatus {
00376 BuddyStatus_GenericFailure = -1,
00377 BuddyStatus_OK = 0,
00378 BuddyStatus_SpecifiedBuddyNotFound,
00379 BuddyStatus_ListFeatureNotImplemented,
00380 BuddyStatus_ListTemporarilyUnavailable,
00381 BuddyStatus_ListMayBeIncomplete,
00382 BuddyStatus_BadBuddySpecification,
00383 BuddyStatus_ListSubscribeFailed,
00384 BuddyStatus_AccountNotLoggedIn
00385 };
00386
00389 virtual BuddyStatus GetBuddyListEx(
00390 BuddyList & buddies
00391 );
00392 virtual bool GetBuddyList(
00393 BuddyList & buddies
00394 )
00395 { return GetBuddyListEx(buddies) == BuddyStatus_OK; }
00396
00399 virtual BuddyStatus SetBuddyListEx(
00400 const BuddyList & buddies
00401 );
00402 virtual bool SetBuddyList(
00403 const BuddyList & buddies
00404 )
00405 { return SetBuddyListEx(buddies) == BuddyStatus_OK; }
00406
00407
00410 virtual BuddyStatus DeleteBuddyListEx();
00411 virtual bool DeleteBuddyList() { return DeleteBuddyListEx() == BuddyStatus_OK; }
00412
00417 virtual BuddyStatus GetBuddyEx(
00418 BuddyInfo & buddy
00419 );
00420 virtual bool GetBuddy(
00421 BuddyInfo & buddy
00422 )
00423 { return GetBuddyEx(buddy) == BuddyStatus_OK; }
00424
00427 virtual BuddyStatus SetBuddyEx(
00428 const BuddyInfo & buddy
00429 );
00430 virtual bool SetBuddy(
00431 const BuddyInfo & buddy
00432 )
00433 { return SetBuddyEx(buddy) == BuddyStatus_OK; }
00434
00437 virtual BuddyStatus DeleteBuddyEx(
00438 const PURL & presentity
00439 );
00440 virtual bool DeleteBuddy(
00441 const PURL & presentity
00442 )
00443 { return DeleteBuddyEx(presentity) == BuddyStatus_OK; }
00444
00450 virtual BuddyStatus SubscribeBuddyListEx(
00451 PINDEX & successfulCount,
00452 bool subscribe = true
00453 );
00454 virtual bool SubscribeBuddyList(
00455 bool subscribe = true
00456 )
00457 { PINDEX successfulCount; return SubscribeBuddyListEx(successfulCount, subscribe) == BuddyStatus_OK; }
00458
00464 virtual BuddyStatus UnsubscribeBuddyListEx();
00465 virtual bool UnsubscribeBuddyList()
00466 { return UnsubscribeBuddyListEx() == BuddyStatus_OK; }
00467
00468 virtual PString GetID() const;
00470
00471
00472 virtual bool SendMessageTo(
00473 const OpalIM & message
00474 );
00475
00480 virtual void OnReceivedMessage(
00481 const OpalIM & message
00482 );
00483
00484 typedef PNotifierTemplate<const OpalIM &> ReceivedMessageNotifier;
00485 #define PDECLARE_ReceivedMessageNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalPresentity, cls, fn, const OpalIM &)
00486 #define PCREATE_ReceivedMessageNotifier(fn) PCREATE_NOTIFIER2(fn, const OpalIM &)
00487
00489 void SetReceivedMessageNotifier(
00490 const ReceivedMessageNotifier & notifier
00491 );
00492
00493 void Internal_SendLocalPresence (const OpalSetLocalPresenceCommand & cmd);
00494 void Internal_SubscribeToPresence (const OpalSubscribeToPresenceCommand & cmd);
00495 void Internal_AuthorisationRequest(const OpalAuthorisationRequestCommand & cmd);
00496 void Internal_SendMessageToCommand(const OpalSendMessageToCommand & cmd);
00497
00498 protected:
00499 OpalPresentityCommand * InternalCreateCommand(const char * cmdName);
00500
00501 OpalManager * m_manager;
00502 PGloballyUniqueID m_guid;
00503 PURL m_aor;
00504 Attributes m_attributes;
00505
00506 AuthorisationRequestNotifier m_onAuthorisationRequestNotifier;
00507 PresenceChangeNotifier m_onPresenceChangeNotifier;
00508 ReceivedMessageNotifier m_onReceivedMessageNotifier;
00509
00510 PMutex m_notificationMutex;
00511 PAtomicInteger::IntegerType m_idNumber;
00512
00513 bool m_temporarilyUnavailable;
00514 };
00515
00516
00518
00522 class OpalPresentityWithCommandThread : public OpalPresentity
00523 {
00524 PCLASSINFO(OpalPresentityWithCommandThread, OpalPresentity);
00525
00528 protected:
00530 OpalPresentityWithCommandThread();
00531
00532 public:
00536 ~OpalPresentityWithCommandThread();
00538
00552 virtual bool SendCommand(
00553 OpalPresentityCommand * cmd
00554 );
00556
00569 void StartThread(
00570 bool startQueue = true
00571 );
00572
00578 void StopThread();
00579
00582 void StartQueue(
00583 bool startQueue = true
00584 );
00585
00587
00588 protected:
00589 void ThreadMain();
00590
00591 typedef std::queue<OpalPresentityCommand *> CommandQueue;
00592 CommandQueue m_commandQueue;
00593 PMutex m_commandQueueMutex;
00594 PAtomicInteger m_commandSequence;
00595 PSyncPoint m_commandQueueSync;
00596
00597 bool m_threadRunning;
00598 bool m_queueRunning;
00599 PThread * m_thread;
00600 };
00601
00603
00606 class OpalPresentityCommand {
00607 public:
00608 OpalPresentityCommand(bool responseNeeded = false)
00609 : m_responseNeeded(responseNeeded)
00610 { }
00611 virtual ~OpalPresentityCommand() { }
00612
00616 virtual void Process(
00617 OpalPresentity & presentity
00618 ) = 0;
00619
00620 typedef PAtomicInteger::IntegerType CmdSeqType;
00621 CmdSeqType m_sequence;
00622 bool m_responseNeeded;
00623 PURL m_presentity;
00624 };
00625
00628 #define OPAL_DEFINE_COMMAND(command, entity, func) \
00629 class entity##_##command : public command \
00630 { \
00631 public: virtual void Process(OpalPresentity & presentity) { dynamic_cast<entity &>(presentity).func(*this); } \
00632 }; \
00633 static PFactory<OpalPresentityCommand>::Worker<entity##_##command> \
00634 s_entity##_##command(PDefaultPFactoryKey(entity::Class())+typeid(command).name())
00635
00636
00639 class OpalSubscribeToPresenceCommand : public OpalPresentityCommand {
00640 public:
00641 OpalSubscribeToPresenceCommand(bool subscribe = true) : m_subscribe(subscribe) { }
00642
00643 bool m_subscribe;
00644 PString m_note;
00645 };
00646
00647
00654 class OpalAuthorisationRequestCommand : public OpalPresentityCommand {
00655 public:
00656 OpalAuthorisationRequestCommand() : m_authorisation(OpalPresentity::AuthorisationPermitted) { }
00657
00658 OpalPresentity::Authorisation m_authorisation;
00659 PString m_note;
00660 };
00661
00662
00668 class OpalSetLocalPresenceCommand : public OpalPresentityCommand, public OpalPresenceInfo {
00669 public:
00670 OpalSetLocalPresenceCommand(State state = NoPresence) : OpalPresenceInfo(state) { }
00671 };
00672
00673
00676 class OpalSendMessageToCommand : public OpalPresentityCommand
00677 {
00678 public:
00679 OpalSendMessageToCommand() { }
00680
00681 OpalIM m_message;
00682 };
00683
00685
00686
00687 #if OPAL_SIP && OPAL_PTLIB_EXPAT
00688 PFACTORY_LOAD(SIPLocal_Presentity);
00689 PFACTORY_LOAD(SIPXCAP_Presentity);
00690 PFACTORY_LOAD(SIPOMA_Presentity);
00691 #endif
00692
00693
00694 #endif // OPAL_IM_PRES_ENT_H
00695