Line data Source code
1 : /* 2 : * Copyright (C) 2004-2025 Savoir-faire Linux Inc. 3 : * 4 : * This program is free software: you can redistribute it and/or modify 5 : * it under the terms of the GNU General Public License as published by 6 : * the Free Software Foundation, either version 3 of the License, or 7 : * (at your option) any later version. 8 : * 9 : * This program is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 : * GNU General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU General Public License 15 : * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 : */ 17 : 18 : #ifdef HAVE_CONFIG_H 19 : #include "config.h" 20 : #endif 21 : 22 : #include "presencemanager_interface.h" 23 : 24 : #include <cerrno> 25 : #include <sstream> 26 : #include <cstring> 27 : 28 : #include "logger.h" 29 : #include "manager.h" 30 : #include "sip/sipaccount.h" 31 : #include "sip/sippresence.h" 32 : #include "sip/pres_sub_client.h" 33 : #include "client/ring_signal.h" 34 : #include "compiler_intrinsics.h" 35 : 36 : #include "jamidht/jamiaccount.h" 37 : 38 : namespace libjami { 39 : 40 : using jami::SIPAccount; 41 : 42 : void 43 0 : registerPresHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>& handlers) 44 : { 45 0 : registerSignalHandlers(handlers); 46 0 : } 47 : 48 : /** 49 : * Un/subscribe to buddySipUri for an accountId 50 : */ 51 : void 52 0 : subscribeBuddy(const std::string& accountId, const std::string& uri, bool flag) 53 : { 54 0 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 55 0 : auto pres = sipaccount->getPresence(); 56 0 : if (pres and pres->isEnabled() and pres->isSupported(PRESENCE_FUNCTION_SUBSCRIBE)) { 57 0 : JAMI_DEBUG("{}ubscribePresence (acc:{}, buddy:{})", flag ? "S" : "Uns", accountId, uri); 58 0 : pres->subscribeClient(uri, flag); 59 : } 60 0 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) { 61 0 : acc->trackBuddyPresence(uri, flag); 62 : } else 63 0 : JAMI_ERROR("Unable to find account {}", accountId); 64 0 : } 65 : 66 : /** 67 : * push a presence for a account 68 : * Notify for IP2IP account 69 : * For JamiAccount status is ignored but note is used 70 : */ 71 : void 72 3 : publish(const std::string& accountId, bool status, const std::string& note) 73 : { 74 3 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 75 0 : auto pres = sipaccount->getPresence(); 76 0 : if (pres and pres->isEnabled() and pres->isSupported(PRESENCE_FUNCTION_PUBLISH)) { 77 0 : JAMI_DEBUG("Send Presence (acc:{}, status {}).", accountId, status ? "online" : "offline"); 78 0 : pres->sendPresence(status, note); 79 : } 80 3 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) { 81 3 : acc->sendPresenceNote(note); 82 : } else 83 6 : JAMI_ERROR("Unable to find account {}", accountId); 84 3 : } 85 : 86 : /** 87 : * Accept or not a PresSubServer request for IP2IP account 88 : */ 89 : void 90 0 : answerServerRequest(UNUSED const std::string& uri, UNUSED bool flag) 91 : { 92 : #if 0 // DISABLED: removed IP2IP support, tuleap: #448 93 : auto account = jami::Manager::instance().getIP2IPAccount(); 94 : if (auto sipaccount = static_cast<SIPAccount *>(account.get())) { 95 : JAMI_DEBUG("Approve presence (acc:IP2IP, serv:{}, flag:{})", uri, flag); 96 : 97 : if (auto pres = sipaccount->getPresence()) 98 : pres->approvePresSubServer(uri, flag); 99 : else 100 : JAMI_ERROR("Presence not initialized"); 101 : } else 102 : JAMI_ERROR("Unable to find account IP2IP"); 103 : #else 104 0 : JAMI_ERROR("answerServerRequest() is deprecated and does nothing"); 105 : #endif 106 0 : } 107 : 108 : /** 109 : * Get all active subscriptions for "accountId" 110 : */ 111 : std::vector<std::map<std::string, std::string>> 112 2 : getSubscriptions(const std::string& accountId) 113 : { 114 2 : std::vector<std::map<std::string, std::string>> ret; 115 : 116 2 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 117 0 : if (auto pres = sipaccount->getPresence()) { 118 0 : const auto& subs = pres->getClientSubscriptions(); 119 0 : ret.reserve(subs.size()); 120 0 : for (const auto& s : subs) { 121 0 : ret.push_back({{libjami::Presence::BUDDY_KEY, std::string(s->getURI())}, 122 : {libjami::Presence::STATUS_KEY, 123 0 : s->isPresent() ? libjami::Presence::ONLINE_KEY : libjami::Presence::OFFLINE_KEY}, 124 0 : {libjami::Presence::LINESTATUS_KEY, std::string(s->getLineStatus())}}); 125 : } 126 : } else 127 0 : JAMI_ERROR("Presence not initialized"); 128 2 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) { 129 2 : const auto& trackedBuddies = acc->getTrackedBuddyPresence(); 130 2 : ret.reserve(trackedBuddies.size()); 131 4 : for (const auto& tracked_id : trackedBuddies) { 132 8 : ret.push_back({{libjami::Presence::BUDDY_KEY, tracked_id.first}, 133 : {libjami::Presence::STATUS_KEY, 134 2 : tracked_id.second ? libjami::Presence::ONLINE_KEY : libjami::Presence::OFFLINE_KEY}}); 135 : } 136 2 : } else 137 4 : JAMI_ERROR("Unable to find account {}", accountId); 138 : 139 2 : return ret; 140 0 : } 141 : 142 : /** 143 : * Batch subscribing of URIs 144 : */ 145 : void 146 1 : setSubscriptions(const std::string& accountId, const std::vector<std::string>& uris) 147 : { 148 1 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 149 0 : if (auto pres = sipaccount->getPresence()) { 150 0 : for (const auto& u : uris) 151 0 : pres->subscribeClient(u, true); 152 : } else 153 0 : JAMI_ERROR("Presence not initialized"); 154 1 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) { 155 3 : for (const auto& u : uris) 156 2 : acc->trackBuddyPresence(u, true); 157 : } else 158 2 : JAMI_ERROR("Unable to find account {}", accountId); 159 1 : } 160 : 161 : } // namespace libjami