summaryrefslogtreecommitdiff
path: root/src/xmpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpp')
-rw-r--r--src/xmpp/biboumi_component.cpp61
-rw-r--r--src/xmpp/biboumi_component.hpp3
2 files changed, 61 insertions, 3 deletions
diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index 1c7cd92..f3381aa 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -83,6 +83,15 @@ void BiboumiComponent::shutdown()
{
for (auto& pair: this->bridges)
pair.second->shutdown("Gateway shutdown");
+#ifdef USE_DATABASE
+ const auto full_roster = Database::get_full_roster();
+ for (const Database::RosterItem& roster_item: full_roster)
+ {
+ this->send_presence_to_contact(roster_item.col<Database::LocalJid>(),
+ roster_item.col<Database::RemoteJid>(),
+ "unavailable");
+ }
+#endif
}
void BiboumiComponent::clean()
@@ -160,10 +169,28 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
{
if (type == "subscribe")
{ // Auto-accept any subscription request for an IRC server
- this->accept_subscription(to_str, from.bare());
- this->ask_subscription(to_str, from.bare());
+ this->send_presence_to_contact(to_str, from.bare(), "subscribed", id);
+ if (iid.type == Iid::Type::None)
+ this->send_presence_to_contact(to_str, from.bare(), "");
+ this->send_presence_to_contact(to_str, from.bare(), "subscribe");
+#ifdef USE_DATABASE
+ if (!Database::has_roster_item(to_str, from.bare()))
+ Database::add_roster_item(to_str, from.bare());
+#endif
+ }
+ else if (type == "unsubscribe")
+ {
+#ifdef USE_DATABASE
+ const bool res = Database::has_roster_item(to_str, from.bare());
+ if (res)
+ Database::delete_roster_item(to_str, from.bare());
+#endif
+ }
+ else if (type.empty())
+ { // We just receive a presence from someone (as the result of a probe,
+ // or a directed presence, or a normal presence change)
+ this->send_presence_to_contact(to_str, from.bare(), "");
}
-
}
else
{
@@ -979,3 +1006,31 @@ void BiboumiComponent::ask_subscription(const std::string& from, const std::stri
presence["type"] = "subscribe";
this->send_stanza(presence);
}
+
+void BiboumiComponent::send_presence_to_contact(const std::string& from, const std::string& to,
+ const std::string& type, const std::string& id)
+{
+ Stanza presence("presence");
+ presence["from"] = from;
+ presence["to"] = to;
+ if (!type.empty())
+ presence["type"] = type;
+ if (!id.empty())
+ presence["id"] = id;
+ this->send_stanza(presence);
+}
+
+void BiboumiComponent::after_handshake()
+{
+ XmppComponent::after_handshake();
+
+#ifdef USE_DATABASE
+ const auto contacts = Database::get_contact_list(this->get_served_hostname());
+
+ for (const Database::RosterItem& roster_item: contacts)
+ {
+ const auto remote_jid = roster_item.col<Database::RemoteJid>();
+ this->send_presence_to_contact(this->get_served_hostname(), remote_jid, "probe");
+ }
+#endif
+}
diff --git a/src/xmpp/biboumi_component.hpp b/src/xmpp/biboumi_component.hpp
index 87311f9..2d67f8b 100644
--- a/src/xmpp/biboumi_component.hpp
+++ b/src/xmpp/biboumi_component.hpp
@@ -36,6 +36,8 @@ public:
BiboumiComponent& operator=(const BiboumiComponent&) = delete;
BiboumiComponent& operator=(BiboumiComponent&&) = delete;
+ void after_handshake() override final;
+
/**
* Returns the bridge for the given user. If it does not exist, return
* nullptr.
@@ -87,6 +89,7 @@ public:
void send_invitation(const std::string& room_target, const std::string& jid_to, const std::string& author_nick);
void accept_subscription(const std::string& from, const std::string& to);
void ask_subscription(const std::string& from, const std::string& to);
+ void send_presence_to_contact(const std::string& from, const std::string& to, const std::string& type, const std::string& id="");
/**
* Handle the various stanza types
*/