#ifndef __msn_notificationserver_h__ #define __msn_notificationserver_h__ /* * notificationserver.h * libmsn * * Created by Mark Rowe on Mon Mar 22 2004. * Refactored by Tiago Salem Herrmann on 08/2007. * Copyright (c) 2004 Mark Rowe. All rights reserved. * Copyright (c) 2007 Tiago Salem Herrmann. All rights reserved * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include "libmsn_export.h" #ifdef _WIN32 typedef unsigned uint; #endif namespace MSN { class SwitchboardServerConnection; /** Contains information about synchronising the contact list with the server. */ class LIBMSN_EXPORT ListSyncInfo { public: /** Constants specifying the status of the list synchronisation. */ enum SyncProgress { LST_AB = 1, /**< Address book has been received. */ LST_AL = 2, /**< Allow list has been received. */ LST_BL = 4, /**< Block list has been received. */ LST_RL = 8, /**< Reverse list has been received. */ LST_PL = 16, /**< Pending list has been received. */ COMPLETE_BLP = 32 /**< @c BLP has been received. */ }; /** Treat unknown users as if appearing on this list when they attempt * to initiate a switchboard session. */ enum PrivacySetting { ALLOW = 'A', /**< Any user can see our status, except those in Block List. */ BLOCK = 'B' /**< Nobody can see our status, except those in Allow List. */ }; /** Action to take when a new user appears on our reverse list. */ enum NewReverseListEntryAction { PROMPT = 'A', DONT_PROMPT = 'N' }; /** A list of people who's statuses we are wish to be notified about. */ std::map contactList; std::string myDisplayName; std::map groups; /** The progress of the sync operation. */ unsigned int progress; unsigned int usersRemaining, groupsRemaining; /** Last change on Address Book and lists timestamp */ std::string lastChange; /** Specifies the default list for non-buddies to be treated as * appearing in when attempting to invite you into a switchboard setting. * * This corresponds to the @c BLP command in the MSN protocol. */ char privacySetting; /** Specifies whether the user should be prompted when a new buddy * appears on their reverse list. * * This corresponds to the @c GTC command in the MSN protocol. */ char reverseListPrompting; ListSyncInfo(std::string lastChange_) : progress(0), lastChange(lastChange_), privacySetting(ListSyncInfo::ALLOW), reverseListPrompting(ListSyncInfo::PROMPT) {}; }; // Intermediate steps in connection: class LIBMSN_EXPORT connectinfo { public: Passport username; std::string password; std::string cookie; connectinfo(const Passport & username_, const std::string & password_) : username(username_), password(password_), cookie("") {}; }; /** Represents a connection to a MSN notification server. * * The MSN notification server is responsible for dealing with the contact * list, online status, and dispatching message requests or invitations to * or from switchboard servers. */ class LIBMSN_EXPORT NotificationServerConnection : public Connection { private: typedef void (NotificationServerConnection::*NotificationServerCallback)(std::vector & args, int trid, void *); std::string token; class AuthData : public ::MSN::AuthData { public: std::string password; AuthData(const Passport & passport_, const std::string & password_) : ::MSN::AuthData(passport_), password(password_) {} ; }; NotificationServerConnection::AuthData auth; int synctrid; public: MSNObject msnobj; /** Create a NotificationServerConnection with the specified @a username and * @a password. */ NotificationServerConnection(Passport username, std::string password, Callbacks & cb); virtual ~NotificationServerConnection(); virtual void dispatchCommand(std::vector & args); /** Return a list of SwitchboardServerConnection's that have been started * from this NotificationServerConnection. */ const std::vector & switchboardConnections(); /* Add a SwitchboardServerConnection to the list of connections that have * been started from this connection. */ void addSwitchboardConnection(SwitchboardServerConnection *); /* Add the @p Soap object to the list of connections that have * been started from this connection. */ void addSoapConnection(Soap *); /* Remove a SwitchboardServerConnection from the list of connections that have * been started from this connection. */ void removeSwitchboardConnection(SwitchboardServerConnection *); /* Remove the @p Soap object from the list of connections that have * been started from this connection. */ void removeSoapConnection(Soap *); /** Return a connection that is associated with @a fd. * * If @a fd is equal to @p sock, @c this is returned. Otherwise * connectionWithSocket is sent to each SwitchboardServerConnection * or Soap connections until a match is found. * * @return The matching connection, if found. Otherwise, @c NULL. */ Connection *connectionWithSocket(void *sock); /** Return a SwitchboardServerConnection that has exactly one user whose * username is @a username. * * @return The matching SwitchboardServerConnection, or @c NULL. */ SwitchboardServerConnection *switchboardWithOnlyUser(Passport username); /** @name Action Methods * * These methods all perform actions on the notification server. */ /** @{ */ /** Set our capabilities. This is the sum of MSNClientInformationFields enum fields */ void setCapabilities(uint m_clientId); void disconnectNS(); /** Set our online state to @a state and our capabilites to @a clientID. */ void setState(BuddyStatus state, uint clientID); /** Set Black List policy */ void setBLP(char setting); /** It must be called to complete the connection. Add all your contacts * to allContacts, (both Forward, allow and block lists). The integer value * of allContacts is the sum of all lists this contact is present. For example: * If the contact is both on your allow and forward list, the number must be * 3 (2+1). */ void completeConnection(std::map & allContacts, void *data); /** Set our friendly name to @a friendlyName. * * @param friendlyName Maximum allowed length is 387 characters after URL-encoding. */ void setFriendlyName(std::string friendlyName, bool updateServer = false) throw (std::runtime_error); /** Points to our display picture. It must be a png file, size: 96x96. * @param filename Path to the PNG file to be sent as avatar of this contact */ bool change_DisplayPicture(std::string filename); /** Sets our personal info. Current media, personal message... */ void setPersonalStatus(personalInfo pInfo); /** Add buddy named @a buddyName to the list named @a list. */ void addToList(MSN::ContactList list, Passport buddyName); /** Remove buddy named @a buddyName from the list named @a list. */ void removeFromList(MSN::ContactList list, Passport buddyName); /** Add contact @a buddyName to address book with @a displayName * Automatically adds to allow list too. */ void addToAddressBook(Passport buddyName, std::string displayName); /** Delete contact @a passport with @a contactId from address book. */ void delFromAddressBook(std::string contactId, std::string passport); /** Enable a contact on address book. You will use it when you have disabled * a contact before. This contact is still on your Address Book, but it is not * a messenger contact. This function will turn this contact into a messenger * contact again. */ void enableContactOnAddressBook(std::string contactId, std::string passport); /** Do not delete the contact, just disable it. */ void disableContactOnAddressBook(std::string contactId, std::string passport); /** Block a contact. This user won't be able to see your status anymore. */ void blockContact(Passport buddyName); /** Unblock a contact. This user will be able to see your status again. */ void unblockContact(Passport buddyName); /** Add a contact @a contactId to the group @a groupId . */ void addToGroup(std::string groupId, std::string contactId); /** Remove a contact from a group. */ void removeFromGroup(std::string groupId, std::string contactId); /** Add a new group. */ void addGroup(std::string groupName); /** Remove a group. */ void removeGroup(std::string groupId); /** Rename a group. */ void renameGroup(std::string groupId, std::string newGroupName); /** Request the server side buddy list. * * @param lastChange if @a version is specified the server will respond with * the changes necessary to update the list to the latest * version. Otherwise the entire list will be sent. */ void synchronizeContactList(std::string lastChange="0"); /** Send a 'keep-alive' ping to the server. */ void sendPing(); /** Request a switchboard connection. */ void requestSwitchboardConnection(const void *tag); /** Retrieve the Offline Instant Message identified by id */ void get_oim(std::string id, bool markAsRead); /** Erase the Offline Instant Message identified by id */ void delete_oim(std::string id); /** Send an Offline Instant Message */ void send_oim(Soap::OIM oim); void getInboxUrl(); /* when we have to send more than 1 ADL command, we need to keep this here to track */ std::list adl_packets; /* Our current Display Name */ std::string myDisplayName; /* Our passport */ std::string myPassport; /* Sum of capabilities of the user */ uint m_clientId; char bplSetting; /* Our IP number reported by notification server */ std::string server_reported_ip; /* Our TCP source port reported by notification server */ std::string server_reported_port; std::string login_time; std::string MSPAuth; std::string sid; std::string kv; /* 1 if our email is verified, 0 if not */ std::string server_email_verified; /* Says if we are direct connected based on server's report */ bool direct_connection; virtual void connect(const std::string & hostname, unsigned int port); virtual void connect(const std::string & hostname, unsigned int port, const Passport & username, const std::string & password); virtual void disconnect(); virtual void addCallback(NotificationServerCallback cb, int trid, void *data); virtual void removeCallback(int trid); virtual void socketConnectionCompleted(); enum NotificationServerState { NS_DISCONNECTED, NS_CONNECTING, NS_CONNECTED, NS_SYNCHRONISING, NS_ONLINE }; connectinfo *info; NotificationServerState connectionState() const { return this->_connectionState; }; Callbacks & externalCallbacks; virtual NotificationServerConnection *myNotificationServer() { return this; }; void gotTickets(Soap & soapConnection, std::vector sitesToAuthList); void gotLists(Soap &soapConnection); void gotAddressBook(Soap &soapConnection); void gotOIM(Soap & soapConnection, bool success, std::string id, std::string message); void gotOIMLockkey(Soap & soapConnection, std::string lockkey); void gotOIMSendConfirmation(Soap & soapConnection, int id, bool sent); void gotOIMDeleteConfirmation(Soap & soapConnection, std::string id, bool deleted); void gotSoapMailData(Soap & soapConnection, std::string maildata); void gotChangeDisplayNameConfirmation(Soap & soapConnection, std::string displayName, bool changed); void gotDelContactFromGroupConfirmation(Soap & soapConnection, bool deleted, std::string newVersion, std::string groupId, std::string contactId); void gotAddContactToGroupConfirmation(Soap & soapConnection, bool added, std::string newVersion, std::string groupId, std::string contactId); void gotAddGroupConfirmation(Soap & soapConnection, bool added, std::string newVersion, std::string groupName, std::string groupId); void gotDelGroupConfirmation(Soap & soapConnection, bool removed, std::string newVersion, std::string groupId); void gotRenameGroupConfirmation(Soap & soapConnection, bool renamed, std::string newVersion, std::string newGroupName, std::string groupId); void gotAddContactToAddressBookConfirmation(Soap & soapConnection, bool added, std::string newVersion, std::string passport, std::string displayName, std::string guid); void gotDelContactFromAddressBookConfirmation(Soap & soapConnection, bool removed, std::string newVersion, std::string contactId, std::string passport); void gotEnableContactOnAddressBookConfirmation(Soap & soapConnection, bool enabled, std::string newVersion, std::string contactId, std::string passport); void gotDisableContactOnAddressBookConfirmation(Soap & soapConnection, bool disabled, std::string newVersion, std::string contactId, std::string passport); void gotAddContactToListConfirmation(Soap & soapConnection, bool added, std::string newVersion, std::string passport, MSN::ContactList list); void gotDelContactFromListConfirmation(Soap & soapConnection, bool deleted, std::string newVersion, std::string passport, MSN::ContactList list); protected: virtual void handleIncomingData(); NotificationServerState _connectionState; void setConnectionState(NotificationServerState s) { this->_connectionState = s; }; void assertConnectionStateIs(NotificationServerState s) { assert(this->_connectionState == s); }; void assertConnectionStateIsNot(NotificationServerState s) { assert(this->_connectionState != s); }; void assertConnectionStateIsAtLeast(NotificationServerState s) { assert(this->_connectionState >= s); }; private: std::vector _switchboardConnections; std::vector _SoapConnections; std::map > callbacks; ListSyncInfo *listInfo; std::vector sitesToAuthList; std::vector SentQueuedOIMs; std::vector DeletedQueuedOIMs; std::string lockkey; bool generatingLockkey; bool removingOIM; void sendQueuedOIMs(); // mdi value got by tweener std::string mdi; virtual void disconnectForTransfer(); static std::map &)> commandHandlers; static std::map &, std::string, std::string)> messageHandlers; void registerHandlers(); void handle_OUT(std::vector & args); void handle_RML(std::vector & args); void handle_BLP(std::vector & args); void handle_CHG(std::vector & args); void handle_CHL(std::vector & args); void handle_ILN(std::vector & args); void handle_NLN(std::vector & args); void handle_FLN(std::vector & args); void handle_MSG(std::vector & args); void handle_RNG(std::vector & args); void handle_PRP(std::vector & args); void handle_UBX(std::vector & args); void handle_GCF(std::vector & args); void handle_ADL(std::vector & args); void handle_UBN(std::vector & args); void handle_FQY(std::vector & args); void callback_NegotiateCVR(std::vector & args, int trid, void *data); void callback_TransferToSwitchboard(std::vector & args, int trid, void *data); void callback_RequestUSR(std::vector & args, int trid, void *data); void callback_PassportAuthentication(std::vector & args, int trid, void * data); void callback_AuthenticationComplete(std::vector & args, int trid, void * data); void callback_initialBPL(std::vector & args, int trid, void *data); void callback_URL(std::vector & args, int trid, void *data); void message_initial_email_notification(std::vector & args, std::string mime, std::string body); void message_email_notification(std::vector & args, std::string mime, std::string body); void message_msmsgsprofile(std::vector & args, std::string mime, std::string body); void message_initialmdatanotification(std::vector & args, std::string mime, std::string body); void message_oimnotification(std::vector & args, std::string mime, std::string body); void gotMailData(std::string maildata); }; } #endif