diff --git a/include/transport/NetworkPlugin.h b/include/transport/NetworkPlugin.h new file mode 100644 index 0000000000000000000000000000000000000000..1b1c6f08b03d45c3a240201d81cb91d46ca8ea83 --- /dev/null +++ b/include/transport/NetworkPlugin.h @@ -0,0 +1,294 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011, Jan Kaluza + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#pragma once + +#include +#undef TYPE_BOOL +#include "transport/protocol.pb.h" +// #include "conversation.h" +#include +#include + +namespace Transport { + +/// Represents Spectrum2 legacy network plugin. + +/// This class is base class for all C++ legacy network plugins. It provides a way to connect +/// Spectrum2 NetworkPluginServer and allows to use high-level API for legacy network plugins +/// development. +class NetworkPlugin { + public: + enum ExitCode { StorageBackendNeeded = -2 }; + + class PluginConfig { + public: + PluginConfig() : m_needPassword(true), m_needRegistration(false), m_supportMUC(false), m_rawXML(false), + m_disableJIDEscaping(false) {} + virtual ~PluginConfig() {} + + void setNeedRegistration(bool needRegistration = false) { m_needRegistration = needRegistration; } + void setNeedPassword(bool needPassword = true) { m_needPassword = needPassword; } + void setSupportMUC(bool supportMUC = true) { m_supportMUC = supportMUC; } + void setExtraFields(const std::vector &fields) { m_extraFields = fields; } + void setRawXML(bool rawXML = false) { m_rawXML = rawXML; } + void disableJIDEscaping() { m_disableJIDEscaping = true; } + + private: + bool m_needPassword; + bool m_needRegistration; + bool m_supportMUC; + bool m_rawXML; + bool m_disableJIDEscaping; + std::vector m_extraFields; + + friend class NetworkPlugin; + }; + + /// Creates new NetworkPlugin and connects the Spectrum2 NetworkPluginServer. + /// \param loop Event loop. + /// \param host Host where Spectrum2 NetworkPluginServer runs. + /// \param port Port. + NetworkPlugin(); + + /// Destructor. + virtual ~NetworkPlugin(); + + void sendConfig(const PluginConfig &cfg); + + void sendRawXML(std::string &xml); + + /// Call this function when legacy network buddy changed. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com") + /// \param alias Alias of legacy network buddy. If empty, then it's not changed on XMPP side. + /// \param groups Groups in which buddy currently is. If empty, then it's not changed on XMPP side. + /// \param status Status of this buddy. + /// \param statusMessage Status message of this buddy. + /// \param iconHash MD5 hash of buddy icon. Empty if none buddy icon. + /// \param blocked True if this buddy is blocked in privacy lists in legacy network. + void handleBuddyChanged(const std::string &user, const std::string &buddyName, const std::string &alias, + const std::vector &groups, pbnetwork::StatusType status, const std::string &statusMessage = "", const std::string &iconHash = "", + bool blocked = false + ); + + /// Call this method when buddy is removed from legacy network contact list. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com") + void handleBuddyRemoved(const std::string &user, const std::string &buddyName); + + /// Call this function when participant in room changed. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param nickname Nickname of participant. If participant renamed, this is old name of participant. (eg. "HanzZ") + /// \param room Room in which participant changed. (eg. #spectrum) + /// \param flags Participant flags. + /// \param status Current status of participant. Swift::StatusShow::None if participant left the room. + /// \param statusMessage Current status message of participant. + /// \param newname New name of participant if he changed the nickname. Otherwise empty. + void handleParticipantChanged(const std::string &user, const std::string &nickname, const std::string &room, int flags, + pbnetwork::StatusType = pbnetwork::STATUS_NONE, const std::string &statusMessage = "", const std::string &newname = ""); + + /// Call this function when user disconnected the legacy network because of some legacy network error. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param error Reserved for future use, currently keep it on 0. + /// \param message XMPP message which is sent to XMPP user. + void handleDisconnected(const std::string &user, int error = 0, const std::string &message = ""); + + /// Call this function when user connected the legacy network and is logged in. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + void handleConnected(const std::string &user); + + /// Call this function when new message is received from legacy network for user. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param legacyName Name of legacy network buddy or name of room. (eg. "user2@gmail.com") + /// \param message Plain text message. + /// \param nickname Nickname of buddy in room. Empty if it's normal chat message. + /// \param xhtml XHTML message. + void handleMessage(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &nickname = "", const std::string &xhtml = "", const std::string ×tamp = "", bool headline = false, bool pm = false); + + void handleMessageAck(const std::string &user, const std::string &legacyName, const std::string &id); + + /// Call this function when subject in room changed. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param legacyName Name of room. (eg. "#spectrum") + /// \param message Subject message. + /// \param nickname Nickname of user who changed subject. + void handleSubject(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &nickname = ""); + + /// Call this function XMPP user's nickname changed. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param room Room in which participant changed. (eg. #spectrum) + /// \param nickname New nickname. + void handleRoomNicknameChanged(const std::string &user, const std::string &room, const std::string &nickname); + + /// Call this function when requested VCard arrived. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param id VCard ID. + /// \param legacyName Name of legacy network buddy. (eg. "user2@gmail.com") + /// \param fullName Name of legacy network buddy. (eg. "Monty Python") + /// \param nickname Nickname. + /// \param photo Raw photo. + void handleVCard(const std::string &user, unsigned int id, const std::string &legacyName, const std::string &fullName, const std::string &nickname, const std::string &photo); + + /// Call this function when buddy started typing. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com") + void handleBuddyTyping(const std::string &user, const std::string &buddyName); + + /// Call this function when buddy typed, but is not typing anymore. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com") + void handleBuddyTyped(const std::string &user, const std::string &buddyName); + + /// Call this function when buddy has been typing, but paused for a while. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com") + void handleBuddyStoppedTyping(const std::string &user, const std::string &buddyName); + + /// Call this function when new authorization request arrived form legacy network + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com") + void handleAuthorization(const std::string &user, const std::string &buddyName); + + /// Call this function when attention request arrived from legacy network. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com") + /// \param message Message. + void handleAttention(const std::string &user, const std::string &buddyName, const std::string &message); + + void handleFTStart(const std::string &user, const std::string &buddyName, const std::string fileName, unsigned long size); + void handleFTFinish(const std::string &user, const std::string &buddyName, const std::string fileName, unsigned long size, unsigned long ftid); + + void handleFTData(unsigned long ftID, const std::string &data); + + void handleRoomList(const std::string &user, const std::list &rooms, const std::list &names); + + /// Called when XMPP user wants to connect legacy network. + /// You should connect him to legacy network and call handleConnected or handleDisconnected function later. + /// \param user XMPP JID of user for which this event occurs. + /// \param legacyName Legacy network name of this user used for login. + /// \param password Legacy network password of this user. + /** + \msc + NetworkPlugin,YourNetworkPlugin,LegacyNetwork; + NetworkPlugin->YourNetworkPlugin [label="handleLoginRequest(...)", URL="\ref NetworkPlugin::handleLoginRequest()"]; + YourNetworkPlugin->LegacyNetwork [label="connect the legacy network"]; + --- [label="If password was valid and user is connected and logged in"]; + YourNetworkPlugin<-LegacyNetwork [label="connected"]; + YourNetworkPlugin->NetworkPlugin [label="handleConnected()", URL="\ref NetworkPlugin::handleConnected()"]; + --- [label="else"]; + YourNetworkPlugin<-LegacyNetwork [label="disconnected"]; + YourNetworkPlugin->NetworkPlugin [label="handleDisconnected()", URL="\ref NetworkPlugin::handleDisconnected()"]; + \endmsc + */ + virtual void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) = 0; + + /// Called when XMPP user wants to disconnect legacy network. + /// You should disconnect him from legacy network. + /// \param user XMPP JID of user for which this event occurs. + /// \param legacyName Legacy network name of this user used for login. + virtual void handleLogoutRequest(const std::string &user, const std::string &legacyName) = 0; + + /// Called when XMPP user sends message to legacy network. + /// \param user XMPP JID of user for which this event occurs. + /// \param legacyName Legacy network name of buddy or room. + /// \param message Plain text message. + /// \param xhtml XHTML message. + virtual void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "", const std::string &id = "") = 0; + + /// Called when XMPP user requests VCard of buddy. + /// \param user XMPP JID of user for which this event occurs. + /// \param legacyName Legacy network name of buddy whose VCard is requested. + /// \param id ID which is associated with this request. You have to pass it to handleVCard function when you receive VCard. + /** + \msc + NetworkPlugin,YourNetworkPlugin,LegacyNetwork; + NetworkPlugin->YourNetworkPlugin [label="handleVCardRequest(...)", URL="\ref NetworkPlugin::handleVCardRequest()"]; + YourNetworkPlugin->LegacyNetwork [label="start VCard fetching"]; + YourNetworkPlugin<-LegacyNetwork [label="VCard fetched"]; + YourNetworkPlugin->NetworkPlugin [label="handleVCard()", URL="\ref NetworkPlugin::handleVCard()"]; + \endmsc + */ + virtual void handleVCardRequest(const std::string &/*user*/, const std::string &/*legacyName*/, unsigned int /*id*/) {} + + /// Called when XMPP user updates his own VCard. + /// You should update the VCard in legacy network too. + /// \param user XMPP JID of user for which this event occurs. + /// \param photo Raw photo data. + virtual void handleVCardUpdatedRequest(const std::string &/*user*/, const std::string &/*photo*/, const std::string &nickname) {} + + virtual void handleRoomSubjectChangedRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*message*/) {} + + virtual void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/) {} + virtual void handleLeaveRoomRequest(const std::string &/*user*/, const std::string &/*room*/) {} + virtual void handleStatusChangeRequest(const std::string &/*user*/, int status, const std::string &statusMessage) {} + virtual void handleBuddyUpdatedRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*alias*/, const std::vector &/*groups*/) {} + virtual void handleBuddyRemovedRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::vector &/*groups*/) {} + virtual void handleBuddyBlockToggled(const std::string &/*user*/, const std::string &/*buddyName*/, bool /*blocked*/) {} + + virtual void handleTypingRequest(const std::string &/*user*/, const std::string &/*buddyName*/) {} + virtual void handleTypedRequest(const std::string &/*user*/, const std::string &/*buddyName*/) {} + virtual void handleStoppedTypingRequest(const std::string &/*user*/, const std::string &/*buddyName*/) {} + virtual void handleAttentionRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*message*/) {} + + virtual void handleFTStartRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*fileName*/, unsigned long size, unsigned long ftID) {} + virtual void handleFTFinishRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*fileName*/, unsigned long size, unsigned long ftID) {} + virtual void handleFTPauseRequest(unsigned long ftID) {} + virtual void handleFTContinueRequest(unsigned long ftID) {} + + virtual void handleRawXML(const std::string &xml) {} + + virtual void handleMemoryUsage(double &res, double &shared) {res = 0; shared = 0;} + + virtual void handleExitRequest() { exit(1); } + void handleDataRead(std::string &data); + virtual void sendData(const std::string &string) {} + + void checkPing(); + + private: + void handleLoginPayload(const std::string &payload); + void handleLogoutPayload(const std::string &payload); + void handleStatusChangedPayload(const std::string &payload); + void handleConvMessagePayload(const std::string &payload); + void handleJoinRoomPayload(const std::string &payload); + void handleLeaveRoomPayload(const std::string &payload); + void handleVCardPayload(const std::string &payload); + void handleBuddyChangedPayload(const std::string &payload); + void handleBuddyRemovedPayload(const std::string &payload); + void handleChatStatePayload(const std::string &payload, int type); + void handleAttentionPayload(const std::string &payload); + void handleFTStartPayload(const std::string &payload); + void handleFTFinishPayload(const std::string &payload); + void handleFTPausePayload(const std::string &payload); + void handleFTContinuePayload(const std::string &payload); + void handleRoomSubjectChangedPayload(const std::string &payload); + + void send(const std::string &data); + void sendPong(); + void sendMemoryUsage(); + + std::string m_data; + bool m_pingReceived; + double m_init_res; + +}; + +}