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 2 : }
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
|