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