Line data Source code
1 : /* 2 : * Copyright (C) 2004-2026 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 <cstring> 26 : 27 : #include "logger.h" 28 : #include "manager.h" 29 : #include "presence_const.h" 30 : #include "sip/sipaccount.h" 31 : #include "sip/sippresence.h" 32 : #include "sip/pres_sub_client.h" 33 : #include "compiler_intrinsics.h" 34 : 35 : #include "jamidht/jamiaccount.h" 36 : 37 : namespace libjami { 38 : 39 : using jami::SIPAccount; 40 : 41 : void 42 0 : registerPresHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>& handlers) 43 : { 44 0 : registerSignalHandlers(handlers); 45 0 : } 46 : 47 : /** 48 : * Un/subscribe to buddySipUri for an accountId 49 : */ 50 : void 51 0 : subscribeBuddy(const std::string& accountId, const std::string& uri, bool flag) 52 : { 53 0 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 54 0 : auto* pres = sipaccount->getPresence(); 55 0 : if (pres and pres->isEnabled() and pres->isSupported(PRESENCE_FUNCTION_SUBSCRIBE)) { 56 0 : JAMI_DEBUG("{}ubscribePresence (acc:{}, buddy:{})", flag ? "S" : "Uns", accountId, uri); 57 0 : pres->subscribeClient(uri, flag); 58 : } 59 0 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) { 60 0 : acc->trackBuddyPresence(uri, flag); 61 : } else 62 0 : JAMI_ERROR("Unable to find account {}", accountId); 63 0 : } 64 : 65 : /** 66 : * push a presence for a account 67 : * Notify for IP2IP account 68 : * For JamiAccount status is ignored but note is used 69 : */ 70 : void 71 3 : publish(const std::string& accountId, bool status, const std::string& note) 72 : { 73 3 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 74 0 : auto* pres = sipaccount->getPresence(); 75 0 : if (pres and pres->isEnabled() and pres->isSupported(PRESENCE_FUNCTION_PUBLISH)) { 76 0 : JAMI_DEBUG("Send Presence (acc:{}, status {}).", accountId, status ? "online" : "offline"); 77 0 : pres->sendPresence(status, note); 78 : } 79 3 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) { 80 3 : acc->sendPresenceNote(note); 81 : } else 82 6 : JAMI_ERROR("Unable to find account {}", accountId); 83 3 : } 84 : 85 : /** 86 : * Accept or not a PresSubServer request for IP2IP account 87 : */ 88 : void 89 0 : answerServerRequest(UNUSED const std::string& uri, UNUSED bool flag) 90 : { 91 : #if 0 // DISABLED: removed IP2IP support, tuleap: #448 92 : auto account = jami::Manager::instance().getIP2IPAccount(); 93 : if (auto sipaccount = static_cast<SIPAccount *>(account.get())) { 94 : JAMI_DEBUG("Approve presence (acc:IP2IP, serv:{}, flag:{})", uri, flag); 95 : 96 : if (auto pres = sipaccount->getPresence()) 97 : pres->approvePresSubServer(uri, flag); 98 : else 99 : JAMI_ERROR("Presence not initialized"); 100 : } else 101 : JAMI_ERROR("Unable to find account IP2IP"); 102 : #else 103 0 : JAMI_ERROR("answerServerRequest() is deprecated and does nothing"); 104 : #endif 105 0 : } 106 : 107 : /** 108 : * Get all active subscriptions for "accountId" 109 : */ 110 : std::vector<std::map<std::string, std::string>> 111 2 : getSubscriptions(const std::string& accountId) 112 : { 113 2 : std::vector<std::map<std::string, std::string>> ret; 114 : 115 2 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 116 0 : if (auto* pres = sipaccount->getPresence()) { 117 0 : const auto& subs = pres->getClientSubscriptions(); 118 0 : ret.reserve(subs.size()); 119 0 : for (const auto& s : subs) { 120 0 : ret.push_back({{libjami::Presence::BUDDY_KEY, std::string(s->getURI())}, 121 : {libjami::Presence::STATUS_KEY, 122 0 : s->isPresent() ? libjami::Presence::ONLINE_KEY : libjami::Presence::OFFLINE_KEY}, 123 0 : {libjami::Presence::LINESTATUS_KEY, std::string(s->getLineStatus())}}); 124 : } 125 : } else 126 0 : JAMI_ERROR("Presence not initialized"); 127 2 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) { 128 2 : const auto& trackedBuddies = acc->getTrackedBuddyPresence(); 129 2 : ret.reserve(trackedBuddies.size()); 130 4 : for (const auto& tracked_id : trackedBuddies) { 131 8 : ret.push_back({{libjami::Presence::BUDDY_KEY, tracked_id.first}, 132 : {libjami::Presence::STATUS_KEY, 133 2 : tracked_id.second ? libjami::Presence::ONLINE_KEY : libjami::Presence::OFFLINE_KEY}}); 134 : } 135 2 : } else 136 4 : JAMI_ERROR("Unable to find account {}", accountId); 137 : 138 2 : return ret; 139 0 : } 140 : 141 : /** 142 : * Batch subscribing of URIs 143 : */ 144 : void 145 1 : setSubscriptions(const std::string& accountId, const std::vector<std::string>& uris) 146 : { 147 1 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 148 0 : if (auto* pres = sipaccount->getPresence()) { 149 0 : for (const auto& u : uris) 150 0 : pres->subscribeClient(u, true); 151 : } else 152 0 : JAMI_ERROR("Presence not initialized"); 153 1 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) { 154 3 : for (const auto& u : uris) 155 2 : acc->trackBuddyPresence(u, true); 156 : } else 157 2 : JAMI_ERROR("Unable to find account {}", accountId); 158 1 : } 159 : 160 : } // namespace libjami