Line data Source code
1 : /*
2 : * Copyright (C) 2004-2024 Savoir-faire Linux Inc.
3 : *
4 : * Author: Patrick Keroulas <patrick.keroulas@savoirfairelinux.com>
5 : * Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
6 : * Author: Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
7 : *
8 : * This program is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU General Public License as published by
10 : * the Free Software Foundation; either version 3 of the License, or
11 : * (at your option) any later version.
12 : *
13 : * This program is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU General Public License
19 : * along with this program; if not, write to the Free Software
20 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 : */
22 :
23 : #ifdef HAVE_CONFIG_H
24 : #include "config.h"
25 : #endif
26 :
27 : #include "presencemanager_interface.h"
28 :
29 : #include <cerrno>
30 : #include <sstream>
31 : #include <cstring>
32 :
33 : #include "logger.h"
34 : #include "manager.h"
35 : #include "sip/sipaccount.h"
36 : #include "sip/sippresence.h"
37 : #include "sip/pres_sub_client.h"
38 : #include "client/ring_signal.h"
39 : #include "compiler_intrinsics.h"
40 :
41 : #include "jamidht/jamiaccount.h"
42 :
43 : namespace libjami {
44 :
45 : using jami::SIPAccount;
46 :
47 : void
48 0 : registerPresHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>& handlers)
49 : {
50 0 : registerSignalHandlers(handlers);
51 0 : }
52 :
53 : /**
54 : * Un/subscribe to buddySipUri for an accountId
55 : */
56 : void
57 0 : subscribeBuddy(const std::string& accountId, const std::string& uri, bool flag)
58 : {
59 0 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) {
60 0 : auto pres = sipaccount->getPresence();
61 0 : if (pres and pres->isEnabled() and pres->isSupported(PRESENCE_FUNCTION_SUBSCRIBE)) {
62 0 : JAMI_DEBUG("{}ubscribePresence (acc:{}, buddy:{})",
63 : flag ? "S" : "Uns",
64 : accountId,
65 : uri);
66 0 : pres->subscribeClient(uri, flag);
67 : }
68 0 : } else if (auto ringaccount = jami::Manager::instance().getAccount<jami::JamiAccount>(
69 0 : accountId)) {
70 0 : ringaccount->trackBuddyPresence(uri, flag);
71 : } else
72 0 : JAMI_ERROR("Could not find account {}", accountId);
73 0 : }
74 :
75 : /**
76 : * push a presence for a account
77 : * Notify for IP2IP account
78 : * For JamiAccount status is ignored but note is used
79 : */
80 : void
81 3 : publish(const std::string& accountId, bool status, const std::string& note)
82 : {
83 3 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) {
84 0 : auto pres = sipaccount->getPresence();
85 0 : if (pres and pres->isEnabled() and pres->isSupported(PRESENCE_FUNCTION_PUBLISH)) {
86 0 : JAMI_DEBUG("Send Presence (acc:{}, status {}).",
87 : accountId,
88 : status ? "online" : "offline");
89 0 : pres->sendPresence(status, note);
90 : }
91 6 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(
92 3 : accountId)) {
93 3 : acc->sendPresenceNote(note);
94 : } else
95 6 : JAMI_ERROR("Could not find account {}", accountId);
96 3 : }
97 :
98 : /**
99 : * Accept or not a PresSubServer request for IP2IP account
100 : */
101 : void
102 0 : answerServerRequest(UNUSED const std::string& uri, UNUSED bool flag)
103 : {
104 : #if 0 // DISABLED: removed IP2IP support, tuleap: #448
105 : auto account = jami::Manager::instance().getIP2IPAccount();
106 : if (auto sipaccount = static_cast<SIPAccount *>(account.get())) {
107 : JAMI_DEBUG("Approve presence (acc:IP2IP, serv:{}, flag:{})", uri, flag);
108 :
109 : if (auto pres = sipaccount->getPresence())
110 : pres->approvePresSubServer(uri, flag);
111 : else
112 : JAMI_ERROR("Presence not initialized");
113 : } else
114 : JAMI_ERROR("Could not find account IP2IP");
115 : #else
116 0 : JAMI_ERROR("answerServerRequest() is deprecated and does nothing");
117 : #endif
118 0 : }
119 :
120 : /**
121 : * Get all active subscriptions for "accountId"
122 : */
123 : std::vector<std::map<std::string, std::string>>
124 2 : getSubscriptions(const std::string& accountId)
125 : {
126 2 : std::vector<std::map<std::string, std::string>> ret;
127 :
128 2 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) {
129 0 : if (auto pres = sipaccount->getPresence()) {
130 0 : const auto& subs = pres->getClientSubscriptions();
131 0 : ret.reserve(subs.size());
132 0 : for (const auto& s : subs) {
133 0 : ret.push_back(
134 0 : {{libjami::Presence::BUDDY_KEY, std::string(s->getURI())},
135 0 : {libjami::Presence::STATUS_KEY, s->isPresent() ? libjami::Presence::ONLINE_KEY : libjami::Presence::OFFLINE_KEY},
136 0 : {libjami::Presence::LINESTATUS_KEY, std::string(s->getLineStatus())}});
137 : }
138 : } else
139 0 : JAMI_ERROR("Presence not initialized");
140 4 : } else if (auto ringaccount = jami::Manager::instance().getAccount<jami::JamiAccount>(
141 2 : accountId)) {
142 2 : const auto& trackedBuddies = ringaccount->getTrackedBuddyPresence();
143 2 : ret.reserve(trackedBuddies.size());
144 4 : for (const auto& tracked_id : trackedBuddies) {
145 6 : ret.push_back(
146 2 : {{libjami::Presence::BUDDY_KEY, tracked_id.first},
147 : {libjami::Presence::STATUS_KEY,
148 2 : tracked_id.second ? libjami::Presence::ONLINE_KEY : libjami::Presence::OFFLINE_KEY}});
149 : }
150 2 : } else
151 4 : JAMI_ERROR("Could not find account {}", accountId);
152 :
153 2 : return ret;
154 0 : }
155 :
156 : /**
157 : * Batch subscribing of URIs
158 : */
159 : void
160 1 : setSubscriptions(const std::string& accountId, const std::vector<std::string>& uris)
161 : {
162 1 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) {
163 0 : if (auto pres = sipaccount->getPresence()) {
164 0 : for (const auto& u : uris)
165 0 : pres->subscribeClient(u, true);
166 : } else
167 0 : JAMI_ERROR("Presence not initialized");
168 2 : } else if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(
169 1 : accountId)) {
170 3 : for (const auto& u : uris)
171 2 : acc->trackBuddyPresence(u, true);
172 : } else
173 2 : JAMI_ERROR("Could not find account {}", accountId);
174 1 : }
175 :
176 : } // namespace libjami
|