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:{})", 58 : flag ? "S" : "Uns", 59 : accountId, 60 : uri); 61 0 : pres->subscribeClient(uri, flag); 62 : } 63 0 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) { 64 0 : acc->trackBuddyPresence(uri, flag); 65 : } else 66 0 : JAMI_ERROR("Unable to find account {}", accountId); 67 0 : } 68 : 69 : /** 70 : * push a presence for a account 71 : * Notify for IP2IP account 72 : * For JamiAccount status is ignored but note is used 73 : */ 74 : void 75 3 : publish(const std::string& accountId, bool status, const std::string& note) 76 : { 77 3 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 78 0 : auto pres = sipaccount->getPresence(); 79 0 : if (pres and pres->isEnabled() and pres->isSupported(PRESENCE_FUNCTION_PUBLISH)) { 80 0 : JAMI_DEBUG("Send Presence (acc:{}, status {}).", 81 : accountId, 82 : status ? "online" : "offline"); 83 0 : pres->sendPresence(status, note); 84 : } 85 6 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>( 86 3 : accountId)) { 87 3 : acc->sendPresenceNote(note); 88 : } else 89 6 : JAMI_ERROR("Unable to find account {}", accountId); 90 3 : } 91 : 92 : /** 93 : * Accept or not a PresSubServer request for IP2IP account 94 : */ 95 : void 96 0 : answerServerRequest(UNUSED const std::string& uri, UNUSED bool flag) 97 : { 98 : #if 0 // DISABLED: removed IP2IP support, tuleap: #448 99 : auto account = jami::Manager::instance().getIP2IPAccount(); 100 : if (auto sipaccount = static_cast<SIPAccount *>(account.get())) { 101 : JAMI_DEBUG("Approve presence (acc:IP2IP, serv:{}, flag:{})", uri, flag); 102 : 103 : if (auto pres = sipaccount->getPresence()) 104 : pres->approvePresSubServer(uri, flag); 105 : else 106 : JAMI_ERROR("Presence not initialized"); 107 : } else 108 : JAMI_ERROR("Unable to find account IP2IP"); 109 : #else 110 0 : JAMI_ERROR("answerServerRequest() is deprecated and does nothing"); 111 : #endif 112 0 : } 113 : 114 : /** 115 : * Get all active subscriptions for "accountId" 116 : */ 117 : std::vector<std::map<std::string, std::string>> 118 2 : getSubscriptions(const std::string& accountId) 119 : { 120 2 : std::vector<std::map<std::string, std::string>> ret; 121 : 122 2 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 123 0 : if (auto pres = sipaccount->getPresence()) { 124 0 : const auto& subs = pres->getClientSubscriptions(); 125 0 : ret.reserve(subs.size()); 126 0 : for (const auto& s : subs) { 127 0 : ret.push_back( 128 0 : {{libjami::Presence::BUDDY_KEY, std::string(s->getURI())}, 129 0 : {libjami::Presence::STATUS_KEY, s->isPresent() ? libjami::Presence::ONLINE_KEY : libjami::Presence::OFFLINE_KEY}, 130 0 : {libjami::Presence::LINESTATUS_KEY, std::string(s->getLineStatus())}}); 131 : } 132 : } else 133 0 : JAMI_ERROR("Presence not initialized"); 134 4 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>( 135 2 : accountId)) { 136 2 : const auto& trackedBuddies = acc->getTrackedBuddyPresence(); 137 2 : ret.reserve(trackedBuddies.size()); 138 4 : for (const auto& tracked_id : trackedBuddies) { 139 6 : ret.push_back( 140 2 : {{libjami::Presence::BUDDY_KEY, tracked_id.first}, 141 : {libjami::Presence::STATUS_KEY, 142 2 : tracked_id.second ? libjami::Presence::ONLINE_KEY : libjami::Presence::OFFLINE_KEY}}); 143 : } 144 2 : } else 145 4 : JAMI_ERROR("Unable to find account {}", accountId); 146 : 147 2 : return ret; 148 0 : } 149 : 150 : /** 151 : * Batch subscribing of URIs 152 : */ 153 : void 154 1 : setSubscriptions(const std::string& accountId, const std::vector<std::string>& uris) 155 : { 156 1 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) { 157 0 : if (auto pres = sipaccount->getPresence()) { 158 0 : for (const auto& u : uris) 159 0 : pres->subscribeClient(u, true); 160 : } else 161 0 : JAMI_ERROR("Presence not initialized"); 162 2 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>( 163 1 : accountId)) { 164 3 : for (const auto& u : uris) 165 2 : acc->trackBuddyPresence(u, true); 166 : } else 167 2 : JAMI_ERROR("Unable to find account {}", accountId); 168 1 : } 169 : 170 : } // namespace libjami