OPAL
Version 3.10.4
|
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: 26283 $ 00027 * $Author: rjongbloed $ 00028 * $Date: 2011-08-08 02:41:14 -0500 (Mon, 08 Aug 2011) $ 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() = 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 // 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 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 // Include concrete classes here so the factories are initialised 00716 #if OPAL_SIP && OPAL_PTLIB_EXPAT 00717 PFACTORY_LOAD(SIP_Presentity); 00718 #endif 00719 00720 00721 #endif // OPAL_IM_PRES_ENT_H 00722