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 : #include "call_factory.h"
19 : #include "sip/sipcall.h"
20 : #include "sip/sipaccountbase.h"
21 :
22 : namespace jami {
23 :
24 : // generate something like 7ea037947eb9fb2f
25 : std::string
26 405 : CallFactory::getNewCallID() const
27 : {
28 405 : std::string random_id;
29 : do {
30 405 : random_id = std::to_string(std::uniform_int_distribution<uint64_t>(1, JAMI_ID_MAX_VAL)(rand_));
31 405 : } while (hasCall(random_id));
32 405 : return random_id;
33 0 : }
34 :
35 : std::shared_ptr<SIPCall>
36 371 : CallFactory::newSipCall(const std::shared_ptr<SIPAccountBase>& account,
37 : Call::CallType type,
38 : const std::vector<libjami::MediaMap>& mediaList)
39 : {
40 371 : if (not allowNewCall_) {
41 0 : JAMI_WARNING("Creation of new calls is not allowed");
42 0 : return {};
43 : }
44 :
45 371 : std::lock_guard lk(callMapsMutex_);
46 371 : auto id = getNewCallID();
47 371 : auto call = std::make_shared<SIPCall>(account, id, type, mediaList);
48 371 : callMaps_[call->getLinkType()].emplace(id, call);
49 371 : account->attach(call);
50 371 : return call;
51 371 : }
52 :
53 : void
54 38 : CallFactory::forbid()
55 : {
56 38 : allowNewCall_ = false;
57 38 : }
58 :
59 : void
60 386 : CallFactory::removeCall(Call& call)
61 : {
62 386 : std::lock_guard lk(callMapsMutex_);
63 :
64 386 : const auto& id = call.getCallId();
65 1544 : JAMI_LOG("Removing call {}", id);
66 386 : auto& map = callMaps_.at(call.getLinkType());
67 386 : map.erase(id);
68 1544 : JAMI_LOG("Remaining {} call", map.size());
69 386 : }
70 :
71 : void
72 0 : CallFactory::removeCall(const std::string& id)
73 : {
74 0 : std::lock_guard lk(callMapsMutex_);
75 :
76 0 : if (auto call = getCall(id)) {
77 0 : removeCall(*call);
78 : } else
79 0 : JAMI_ERROR("No call with ID {}", id);
80 0 : }
81 :
82 : bool
83 405 : CallFactory::hasCall(const std::string& id) const
84 : {
85 405 : std::lock_guard lk(callMapsMutex_);
86 :
87 797 : for (const auto& item : callMaps_) {
88 392 : const auto& map = item.second;
89 392 : if (map.find(id) != map.cend())
90 0 : return true;
91 : }
92 :
93 405 : return false;
94 405 : }
95 :
96 : bool
97 0 : CallFactory::empty() const
98 : {
99 0 : std::lock_guard lk(callMapsMutex_);
100 :
101 0 : for (const auto& item : callMaps_) {
102 0 : if (not item.second.empty())
103 0 : return false;
104 : }
105 :
106 0 : return true;
107 0 : }
108 :
109 : void
110 39 : CallFactory::clear()
111 : {
112 39 : std::lock_guard lk(callMapsMutex_);
113 39 : callMaps_.clear();
114 39 : }
115 :
116 : std::shared_ptr<Call>
117 1567 : CallFactory::getCall(const std::string& id) const
118 : {
119 1567 : std::lock_guard lk(callMapsMutex_);
120 :
121 1647 : for (const auto& item : callMaps_) {
122 1566 : const auto& map = item.second;
123 1566 : const auto& iter = map.find(id);
124 1566 : if (iter != map.cend())
125 1486 : return iter->second;
126 : }
127 :
128 81 : return nullptr;
129 1567 : }
130 :
131 : std::vector<std::shared_ptr<Call>>
132 307 : CallFactory::getAllCalls() const
133 : {
134 307 : std::lock_guard lk(callMapsMutex_);
135 307 : std::vector<std::shared_ptr<Call>> v;
136 :
137 586 : for (const auto& itemmap : callMaps_) {
138 279 : const auto& map = itemmap.second;
139 279 : v.reserve(v.size() + map.size());
140 1588 : for (const auto& item : map)
141 1309 : v.push_back(item.second);
142 : }
143 :
144 614 : return v;
145 307 : }
146 :
147 : std::vector<std::string>
148 0 : CallFactory::getCallIDs() const
149 : {
150 0 : std::vector<std::string> v;
151 :
152 0 : for (const auto& item : callMaps_) {
153 0 : const auto& map = item.second;
154 0 : for (const auto& it : map)
155 0 : v.push_back(it.first);
156 : }
157 :
158 0 : v.shrink_to_fit();
159 0 : return v;
160 0 : }
161 :
162 : std::size_t
163 38 : CallFactory::callCount() const
164 : {
165 38 : std::lock_guard lk(callMapsMutex_);
166 38 : std::size_t count = 0;
167 :
168 48 : for (const auto& itemmap : callMaps_)
169 10 : count += itemmap.second.size();
170 :
171 38 : return count;
172 38 : }
173 :
174 : bool
175 0 : CallFactory::hasCall(const std::string& id, Call::LinkType link) const
176 : {
177 0 : std::lock_guard lk(callMapsMutex_);
178 :
179 0 : const auto* const map = getMap_(link);
180 0 : return map and map->find(id) != map->cend();
181 0 : }
182 :
183 : bool
184 32 : CallFactory::empty(Call::LinkType link) const
185 : {
186 32 : std::lock_guard lk(callMapsMutex_);
187 :
188 32 : const auto* const map = getMap_(link);
189 64 : return !map or map->empty();
190 32 : }
191 :
192 : std::shared_ptr<Call>
193 0 : CallFactory::getCall(const std::string& id, Call::LinkType link) const
194 : {
195 0 : std::lock_guard lk(callMapsMutex_);
196 :
197 0 : const auto* const map = getMap_(link);
198 0 : if (!map)
199 0 : return nullptr;
200 :
201 0 : const auto& it = map->find(id);
202 0 : if (it == map->cend())
203 0 : return nullptr;
204 :
205 0 : return it->second;
206 0 : }
207 :
208 : std::vector<std::shared_ptr<Call>>
209 0 : CallFactory::getAllCalls(Call::LinkType link) const
210 : {
211 0 : std::lock_guard lk(callMapsMutex_);
212 0 : std::vector<std::shared_ptr<Call>> v;
213 :
214 0 : const auto* const map = getMap_(link);
215 0 : if (map) {
216 0 : for (const auto& it : *map)
217 0 : v.push_back(it.second);
218 : }
219 :
220 0 : v.shrink_to_fit();
221 0 : return v;
222 0 : }
223 :
224 : std::vector<std::string>
225 0 : CallFactory::getCallIDs(Call::LinkType link) const
226 : {
227 0 : std::lock_guard lk(callMapsMutex_);
228 0 : std::vector<std::string> v;
229 :
230 0 : const auto* const map = getMap_(link);
231 0 : if (map) {
232 0 : for (const auto& it : *map)
233 0 : v.push_back(it.first);
234 : }
235 :
236 0 : v.shrink_to_fit();
237 0 : return v;
238 0 : }
239 :
240 : std::size_t
241 0 : CallFactory::callCount(Call::LinkType link) const
242 : {
243 0 : std::lock_guard lk(callMapsMutex_);
244 :
245 0 : const auto* const map = getMap_(link);
246 0 : if (!map)
247 0 : return 0;
248 :
249 0 : return map->size();
250 0 : }
251 :
252 : } // namespace jami
|