/*************************************************************************** msnnotificationconnection.h - description ------------------- begin : Thu Jan 23 2003 copyright : (C) 2003 by Mike K. Bennett email : mkb137b@hotmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MSNNOTIFICATIONCONNECTION_H #define MSNNOTIFICATIONCONNECTION_H #include "../contact/msnstatus.h" #include "../notification/notificationmanager.h" #include "../network/soap/addressbookservice.h" #include "chatinformation.h" #include "msnconnection.h" #include <QDateTime> #include <QList> #include <QTimer> // Forward declarations class ChatInformation; class ChatMessage; class Contact; class ContactList; class KMessTest; class MimeMessage; class PassportLoginService; class QAbstractItemModel; class OfflineImService; class AddressBookService; class RoamingService; /** * @brief The primary connection to the MSN server. * * The notification connection is initialized when the * user signs in to the MSN Messenger service. * When this connection is dropped, the user is signed off as well. * The notification connection is used for the following actions: * - managing the contact list * - starting new chat sessions * - receive invitations for a chat session * - receive status updates about contacts, e.g.: * - online/offline changes * - new email * - personal status messages * - now playing information * - new offline-im messages * * Most protocol commands are echo'ed back to the client. * This allows a Model-View-Controller based protocol handling, * see MsnConnection::parseCommand() for details. * * When the connection to the notification server is established, * the the PassportLoginService class is used to retrieve an authentication token. * This token is provided to the <code>USR</code> command complete the login process. * * When a contact is updated, it's information in the * ContactList class is updated automatically. * Contacts are organized in multiple "lists". * This differs from the "groups" seen in the main window! * See the Contact class for information about "lists" and "groups". * * New chat invitations are handled by the <code>XFR</code> command. * The server response contains the login data for a chat session (or "chat room") * at a switchboard server. This information is used to start the chat session. * The information about new chats is forwarded to the ChatMaster first. * This class looks for existing chats with a contact, * or opens a new chat window instead when needed. * The actual chat session is handled by the MsnSwitchboardConnection class. * Once the chat session is created, the other contact * is invited to the session at the switchboard server. * * Some contact commands include an MsnObject argument. * This is the "ticket" to request a display picture later, * by "inviting" the contact to transfer the data belonging to the MsnObject. * Invitations for file and msnobject transfers are not handled by the notification connection however. * A chat session needs to be started first. The invitation for the msnobject or file transfer can be sent there. * * Note that each connection starts with a version exchange. * Clients inform the server about the versions of the protocol it supports. * The commands documented here may differ from other clients using a different protocol version. * Currently KMess uses <code>MSNP15</code> for all the notification connection. * New features are added to new protocol versions only. * Therefore, something as simple as a 'personal status message' required * an upgrade to a complete new protocol version. The <code>UBX</code> * command - which contains the personal status message - is only sent as of <code>MSNP11</code>. * * The <code>CHG</code> and <code>NLN</code> commands include a bitwise flag * with the supported client-to-client features. This includes the * MSNC version for the invitation system, the type of the client ('normal', 'mobile', 'web messenger') and features like 'winks', 'webcam', 'folder sharing'. * By advertising these values, a client promoses the feature is fully supported. * Changing the advertised MSNC version changes the type of P2P messages sent by another client. * Hence, changing the capabilities value could pose a major impact. * The list of known flags can be found in the ContactBase::MsnClientCapabilities enum. * * @author Mike K. Bennett * @author Valerio Pilo * @author Antonio Nastasi * @ingroup NetworkCore */ 00116 class MsnNotificationConnection : public MsnConnection { Q_OBJECT friend class KMessTest; public: // The constructor MsnNotificationConnection(); // The destructor ~MsnNotificationConnection(); // Request a change in the user's status void changeStatus( const Status newStatus ); // Close the connection with the server void closeConnection(); // Return the contact list model QAbstractItemModel* getContactListModel(); // Initialize the object bool initialize(); // Open a connection to the server bool openConnection(); // Load the contact list properties void readProperties(); // Save the contact list properties void saveProperties(); public slots: // Adds the given contact to the allow list. void allowContact(QString handle); // Copy contact to another group. void addContactToGroup(QString handle, QString groupId); // Add an existing contact to the friends list void addExistingContact( QString handle, const QStringList& groupsId = QStringList() ); // Add a new group void addGroup(QString name); // Add a new contact to the list void addNewContact( QString handle, const QStringList& groupsId = QStringList() ); // Block the given contact void blockContact(QString handle); // Change the current media of the user. void changeCurrentMedia( const QString &application, const QString &mediaType, bool enabled, const QString &formatString, const QStringList arguments ); // The msn object has required, requires a notification message void changedMsnObject(); // Change the friendly name of the user. void changeFriendlyName( QString newName ); // Change the personal message of the user. void changePersonalMessage( QString newMessage ); // Change the personal properties void changePersonalProperties( const QString& cid, int blp ); // Change a user property void changeProperty( QString type, QString value ); // Change a contact property void changeProperty( QString handle, QString type, QString value ); // Move the contact to another group. void moveContact(QString handle, QString fromGroupId, QString toGroupId); // Request a switchboard to connect to a contact void requestSwitchboard( QString handle, ChatInformation::ConnectionType type ); // Rename a group void renameGroup(QString id, QString newName); // Remove a contact from the contact list completely void removeContact(QString handle, bool block = true); // Remove a contact from a single group void removeContactFromGroup(QString handle, QString groupId); // Remove the current media advertising in the personal status. void removeCurrentMedia(); // Remove a group void removeGroup(QString id); // Unblock the given contact void unblockContact(QString handle); private slots: // The socket connected, so send the version command. void slotConnected(); // Create the Roaming service RoamingService *createRoamingService(); // Show warning notifications void slotWarning( const QString &warning, bool isImportant ); // Shows error notifications void slotError( QString error, MsnSocketBase::ErrorType type ); // Displays additional info about network errors void slotErrorEventActivated( NotificationManager::EventSettings settings, NotificationManager::Buttons button ); // Go online void goOnline(); private: // Private methods // Create and return one pointer to address book service AddressBookService *createAddressBookService(); // Create the Offline-IM service OfflineImService *createOfflineImService(); // Create the passport login handler PassportLoginService *createPassportLoginService(); // Create triple des encryption QByteArray createTripleDes ( const QByteArray &key, const QByteArray &secret, const QByteArray &iv ); // Received response to adl command void gotAdl( const QStringList& command, const QString &payload = "" ); // Received confirmation of the user's status change void gotChg( const QStringList& command ); // Received a challenge from the server void gotChl( const QStringList& command ); // Received a version update from the server void gotCvr( const QStringList& command ); // Received notice that a contact went offline void gotFln( const QStringList& command ); // Received notice that a contact is already online void gotIln( const QStringList& command ); // Received notice that a contact has changed status void gotNln( const QStringList& command ); // Received notice of disconnetion from the server void gotOut( const QStringList& command ); // Received a property change (friendly name, phone number, etc..) void gotPrp(const QStringList& command); void gotRml( const QStringList &command ); // Received a chat request from a contact void gotRng( const QStringList& command ); // Received details of a contact's personal message void gotUbx( const QStringList &command, const QByteArray &payload ); // Received the folder and command info for Hotmail's inbox or compose void gotUrl( const QStringList& command ); // Received user authentication information void gotUsr( const QStringList& command ); // Received version information void gotVer( const QStringList& command ); // Received server transfer information void gotXfr( const QStringList& command ); // Send the ADL command void putAdl( const QString &handle = "", int list = 0 ); // Send the RML command void putRml( const QString &handle, int list ); // Send the personal status and current media fields. void putUux(); // Send the version command void putVer(); // Parse a regular command void parseCommand( const QStringList& command ); // Parse an error command void parseError( const QStringList& command, const QByteArray &payloadData ); // Parse a message command void parseMimeMessage( const QStringList& command, const MimeMessage &message ); // Parse a payload command void parsePayloadMessage( const QStringList &command, const QByteArray &payload ); private slots: // Removes any expired switchboard requests, so new ones can be made void checkSwitchboardsTimeout(); // The passport login failed, username/password was incorrect void loginIncorrect(); // The passport login succeeded void loginSucceeded(); // Received the Mail-Data field over SOAP or at the notification connection. void receivedMailData( QDomElement mailData ); // An Offline-IM message was downloaded void receivedOfflineIm( const QString &messageId, const QString &from, const QString &to, const QDateTime &date, const QString &body, const QString &runId, int sequenceNum ); // The authentication process has timed out void slotAuthenticationFailed(); // Unlock notifications after the first seconds of connections void unlockNotifications(); // Contact added, notify it to contactlist void slotContactAdded( const QString &handle, const QString &contactId, const QStringList &groupsId ); // Contact added to group void slotContactAddedToGroup( const QString &contactId, const QString &groupId ); // Contact blocked void slotContactBlocked( const QString &handle ); // Contact deleted void slotContactDeleted( const QString &contactId ); // Contact removed from group void slotContactDeletedFromGroup( const QString &contactId, const QString &groupId ); // Called when address book services retrieved address book list void slotGotAddressBookList( const QList< QHash<QString,QVariant> > &contacts ); // Called when address book services retrieved membership lists void slotGotMembershipLists( const QString &serviceType, const QHash<QString,int> &contactsRole ); // Called when address book services parsed a group void slotGotGroup( const QString &id, const QString &name ); // Contact unblocked void slotContactUnblocked( const QString &handle ); private: // Private attributes // The address book service AddressBookService *addressBookService_; bool connected_; // Nonce received by the server on first SSO command QByteArray nonceBase64_; // The list of contacts' role QHash<QString,int> contactsRole_; 00310 struct MSNPMSNG { quint32 headerSize; quint32 cryptMode; quint32 cipherType; quint32 hashType; quint32 ivLength; quint32 hashLength; quint32 cipherLength; unsigned char ivBytes[8]; unsigned char hashBytes[20]; unsigned char cipherBytes[72]; }; 00324 struct OfflineImMessage { QString messageId; QString from; QDateTime date; QString body; QString runId; int sequenceNum; }; // A pointer to the list of contacts ContactList *contactList_; // A pointer to the shared current account singleton. CurrentAccount *currentAccount_; // Whether or not to enable presence notifications bool enableNotifications_; // Whether the goOnline() operation was completed bool goneOnline_; // Group where to initially place a newly added contact QString initialContactAddedGroup_; // Whether or not the object was initialized bool initialized_; // Whether or not the connection has just been established bool isInitiatingConnection_; // The last current media set. QString lastCurrentMedia_; // The last Personal Status Message set. QString lastPsm_; // Last status used int lastStatus_; // A timer to watch over the login process QTimer loginTimer_; // A timer used to unlock notifications after the last ILN is received. QTimer notificationUnlockTimer_; // A timer to login directly if the SOAP requests take too long. QTimer friendlyNameWaitTimer_; // The received offline messages. QList<OfflineImMessage*> offlineImMessages_; // The Offline-IM SOAP client OfflineImService *offlineImService_; // A list of switchboard requests which haven't yet been given servers QList<ChatInformation*> openRequests_; // The object than handles the passport login PassportLoginService *passportLoginService_; // The Roaming SOAP client RoamingService *roamingService_; // The pending offline-im messages QStringList pendingOfflineImMessages_; // Whether the initial status was already sent. See goOnline() bool initialStatusSent_; signals: // Signal a chat message, used for offline-im messages void offlineMessage( const ChatMessage &message ); // Signal that the connection has been made sucessfully void connected(); // Signal that a contact added you void contactAddedUser( const QString handle ); // Signal that a new email has been received void newEmail(QString sender, QString subject, bool inInbox, QString command, QString folder, QString url); // Signal that the connection should be established again after a disconnection void reconnect( QString handle ); // A new switchboard with a contact has been opened void startSwitchboard( const ChatInformation &chatInfo ); // Signal that a change has occurred in the AB (contact add/remove/delete, etc) void addressBookChanged( const QString &id, AddressBookService::AddressBookUpdate update ); }; #endif