1 #pragma once 2 3 #include <database/database.hpp> 4 #include <xmpp/xmpp_component.hpp> 5 #include <xmpp/jid.hpp> 6 7 #include <bridge/bridge.hpp> 8 9 #include <memory> 10 #include <string> 11 #include <map> 12 13 namespace db 14 { 15 class MucLogLine; 16 } 17 struct ListElement; 18 19 /** 20 * A callback called when the waited iq result is received (it is matched 21 * against the iq id) 22 */ 23 using iq_responder_callback_t = std::function<void(Bridge* bridge, const Stanza& stanza)>; 24 25 /** 26 * Interact with the Biboumi Bridge 27 */ 28 class BiboumiComponent: public XmppComponent 29 { 30 public: 31 explicit BiboumiComponent(std::shared_ptr<Poller>& poller, const std::string& hostname, const std::string& secret); 32 ~BiboumiComponent() = default; 33 34 BiboumiComponent(const BiboumiComponent&) = delete; 35 BiboumiComponent(BiboumiComponent&&) = delete; 36 BiboumiComponent& operator=(const BiboumiComponent&) = delete; 37 BiboumiComponent& operator=(BiboumiComponent&&) = delete; 38 39 void after_handshake() override final; 40 41 /** 42 * Returns the bridge for the given user. If it does not exist, return 43 * nullptr. 44 */ 45 Bridge* find_user_bridge(const std::string& full_jid); 46 /** 47 * Return a list of all the managed bridges. 48 */ 49 std::vector<Bridge*> get_bridges() const; 50 51 /** 52 * Send a "close" message to all our connected peers. That message 53 * depends on the protocol used (this may be a QUIT irc message, or a 54 * <stream/>, etc). We may also directly close the connection, or we may 55 * wait for the remote peer to acknowledge it before closing. 56 */ 57 void shutdown(); 58 /** 59 * Run a check on all bridges, to remove all disconnected (socket is 60 * closed, or no channel is joined) IrcClients. Some kind of garbage collector. 61 */ 62 void clean(); 63 /** 64 * Send a result IQ with the gateway disco informations. 65 */ 66 void send_self_disco_info(const std::string& id, const std::string& jid_to); 67 /** 68 * Send a result IQ with the disco informations regarding IRC server JIDs. 69 */ 70 void send_irc_server_disco_info(const std::string& id, const std::string& jid_to, const std::string& jid_from); 71 /** 72 * Sends the allowed namespaces in MUC message, according to 73 * http://xmpp.org/extensions/xep-0045.html#impl-service-traffic 74 */ 75 void send_irc_channel_muc_traffic_info(const std::string& id, const std::string& jid_to, const std::string& jid_from); 76 void send_irc_channel_disco_info(const std::string& id, const std::string& jid_to, const std::string& jid_from, 77 const IrcChannel* irc_channel); 78 /** 79 * Send a ping request 80 */ 81 void send_ping_request(const std::string& from, 82 const std::string& jid_to, 83 const std::string& id); 84 /** 85 * Send the channels list in one big stanza 86 */ 87 void send_iq_room_list_result(const std::string& id, const std::string& to_jid, const std::string& from, 88 const ChannelList& channel_list, std::vector<ListElement>::const_iterator begin, 89 std::vector<ListElement>::const_iterator end, const ResultSetInfo& rs_info); 90 void send_invitation(const std::string& room_target, const std::string& jid_to, const std::string& author_nick); 91 private: 92 void send_invitation_from_fulljid(const std::string& room_target, const std::string& jid_to, const std::string& from); 93 public: 94 void accept_subscription(const std::string& from, const std::string& to); 95 void ask_subscription(const std::string& from, const std::string& to); 96 void send_presence_to_contact(const std::string& from, const std::string& to, const std::string& type, const std::string& id=""); 97 void on_irc_client_connected(const std::string& irc_hostname, const std::string& jid); 98 void on_irc_client_disconnected(const std::string& irc_hostname, const std::string& jid); 99 100 /** 101 * Handle the various stanza types 102 */ 103 void handle_presence(const Stanza& stanza); 104 void handle_message(const Stanza& stanza); 105 void handle_iq(const Stanza& stanza); 106 107 #ifdef USE_DATABASE 108 bool handle_mam_request(const Stanza& stanza); 109 void send_archived_message(const Database::MucLogLine& log_line, const std::string& from, const std::string& to, 110 const std::string& queryid); 111 bool handle_room_configuration_form_request(const std::string& from, const Jid& to, const std::string& id); 112 bool handle_room_configuration_form(const XmlNode& query, const std::string& from, const Jid& to, const std::string& id); 113 #endif 114 115 /** 116 * Return the bridge associated with the bare JID. Create a new one 117 * if none already exist. 118 */ 119 Bridge* get_user_bridge(const std::string& user_jid); 120 121 private: 122 /** 123 * A map of id -> callback. When we want to wait for an iq result, we add 124 * the callback to this map, with the iq id as the key. When an iq result 125 * is received, we look for a corresponding callback in this map. If 126 * found, we call it and remove it. 127 */ 128 std::map<std::string, iq_responder_callback_t> waiting_iq; 129 130 /** 131 * One bridge for each user of the component. Indexed by the user's bare 132 * jid 133 */ 134 std::unordered_map<std::string, std::unique_ptr<Bridge>> bridges; 135 136 AdhocCommandsHandler irc_server_adhoc_commands_handler; 137 AdhocCommandsHandler irc_channel_adhoc_commands_handler; 138 }; 139 140 141