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