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 "configurationmanager_interface.h"
23 : #include "manager.h"
24 : #include "logger.h"
25 : #include "fileutils.h"
26 : #include "sip/sipaccount.h"
27 : #include "jamidht/jamiaccount.h"
28 : #include "jamidht/service_manager.h"
29 : #include "sip/sipaccount_config.h"
30 : #include "jamidht/jamiaccount_config.h"
31 : #include "audio/audiolayer.h"
32 : #include "system_codec_container.h"
33 : #include "account_const.h"
34 : #include "security_const.h"
35 : #include "client/jami_signal.h"
36 : #include "audio/ringbufferpool.h"
37 : #include "connectivity/security/tlsvalidator.h"
38 :
39 : #include <dhtnet/ip_utils.h>
40 : #include <dhtnet/upnp/upnp_context.h>
41 : #include <dhtnet/certstore.h>
42 :
43 : #ifdef __APPLE__
44 : #include <TargetConditionals.h>
45 : #endif
46 :
47 : #ifdef _MSC_VER
48 : #include "windirent.h"
49 : #else
50 : #include <dirent.h>
51 : #endif
52 :
53 : #include <cerrno>
54 : #include <cstring>
55 :
56 : #ifdef _WIN32
57 : #undef interface
58 : #endif
59 :
60 : namespace libjami {
61 :
62 : constexpr unsigned CODECS_NOT_LOADED = 0x1000; /** Codecs not found */
63 :
64 : using jami::SIPAccount;
65 : using jami::JamiAccount;
66 : using jami::tls::TlsValidator;
67 : using jami::AudioDeviceType;
68 :
69 : void
70 0 : registerConfHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>& handlers)
71 : {
72 0 : registerSignalHandlers(handlers);
73 0 : }
74 :
75 : std::map<std::string, std::string>
76 0 : getAccountDetails(const std::string& accountId)
77 : {
78 0 : return jami::Manager::instance().getAccountDetails(accountId);
79 : }
80 :
81 : std::map<std::string, std::string>
82 0 : getVolatileAccountDetails(const std::string& accountId)
83 : {
84 0 : return jami::Manager::instance().getVolatileAccountDetails(accountId);
85 : }
86 :
87 : std::map<std::string, std::string>
88 0 : validateCertificate(const std::string& accountId, const std::string& certificate)
89 : {
90 : try {
91 0 : if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
92 0 : return TlsValidator {acc->certStore(), acc->certStore().getCertificate(certificate)}.getSerializedChecks();
93 0 : } catch (const std::runtime_error& e) {
94 0 : JAMI_WARNING("Certificate loading failed: {}", e.what());
95 0 : }
96 0 : return {{Certificate::ChecksNames::EXIST, Certificate::CheckValuesNames::FAILED}};
97 0 : }
98 :
99 : std::map<std::string, std::string>
100 0 : validateCertificatePath(const std::string& accountId,
101 : const std::string& certificate,
102 : const std::string& privateKey,
103 : const std::string& privateKeyPass,
104 : const std::string& caList)
105 : {
106 : try {
107 0 : if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
108 0 : return TlsValidator {acc->certStore(), certificate, privateKey, privateKeyPass, caList}.getSerializedChecks();
109 0 : } catch (const std::runtime_error& e) {
110 0 : JAMI_WARNING("Certificate loading failed: {}", e.what());
111 0 : return {{Certificate::ChecksNames::EXIST, Certificate::CheckValuesNames::FAILED}};
112 0 : }
113 0 : return {};
114 0 : }
115 :
116 : std::map<std::string, std::string>
117 0 : getCertificateDetails(const std::string& accountId, const std::string& certificate)
118 : {
119 : try {
120 0 : if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
121 0 : return TlsValidator {acc->certStore(), acc->certStore().getCertificate(certificate)}.getSerializedDetails();
122 0 : } catch (const std::runtime_error& e) {
123 0 : JAMI_WARNING("Certificate loading failed: {}", e.what());
124 0 : }
125 0 : return {};
126 : }
127 :
128 : std::map<std::string, std::string>
129 0 : getCertificateDetailsPath(const std::string& accountId,
130 : const std::string& certificate,
131 : const std::string& privateKey,
132 : const std::string& privateKeyPassword)
133 : {
134 : try {
135 0 : auto crt = std::make_shared<dht::crypto::Certificate>(jami::fileutils::loadFile(certificate));
136 0 : if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
137 0 : TlsValidator validator {acc->certStore(), certificate, privateKey, privateKeyPassword};
138 0 : acc->certStore().pinCertificate(validator.getCertificate(), false);
139 0 : return validator.getSerializedDetails();
140 0 : }
141 0 : } catch (const std::runtime_error& e) {
142 0 : JAMI_WARNING("Certificate loading failed: {}", e.what());
143 0 : }
144 0 : return {};
145 : }
146 :
147 : std::vector<std::string>
148 0 : getPinnedCertificates(const std::string& accountId)
149 : {
150 0 : if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
151 0 : return acc->certStore().getPinnedCertificates();
152 0 : return {};
153 : }
154 :
155 : std::vector<std::string>
156 0 : pinCertificate(const std::string& accountId, const std::vector<uint8_t>& certificate, bool local)
157 : {
158 0 : if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
159 0 : return acc->certStore().pinCertificate(certificate, local);
160 0 : return {};
161 : }
162 :
163 : void
164 0 : pinCertificatePath(const std::string& accountId, const std::string& path)
165 : {
166 0 : if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
167 0 : acc->certStore().pinCertificatePath(path);
168 0 : }
169 :
170 : bool
171 0 : unpinCertificate(const std::string& accountId, const std::string& certId)
172 : {
173 0 : if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
174 0 : return acc->certStore().unpinCertificate(certId);
175 0 : return {};
176 : }
177 :
178 : unsigned
179 0 : unpinCertificatePath(const std::string& accountId, const std::string& path)
180 : {
181 0 : if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
182 0 : return acc->certStore().unpinCertificatePath(path);
183 0 : return {};
184 : }
185 :
186 : bool
187 0 : pinRemoteCertificate(const std::string& accountId, const std::string& certId)
188 : {
189 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
190 0 : acc->dht()->findCertificate(dht::PkId(certId), [](const std::shared_ptr<dht::crypto::Certificate>& /*crt*/) {});
191 0 : return true;
192 0 : }
193 0 : return false;
194 : }
195 :
196 : bool
197 0 : setCertificateStatus(const std::string& accountId, const std::string& certId, const std::string& ststr)
198 : {
199 : try {
200 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
201 0 : auto status = dhtnet::tls::TrustStore::statusFromStr(ststr.c_str());
202 0 : return acc->setCertificateStatus(certId, status);
203 0 : }
204 0 : } catch (const std::out_of_range& e) {
205 0 : JAMI_WARNING("Argument out of range when setting certificate status: {}", e);
206 0 : }
207 0 : return false;
208 : }
209 :
210 : std::vector<std::string>
211 0 : getCertificatesByStatus(const std::string& accountId, const std::string& ststr)
212 : {
213 0 : auto status = dhtnet::tls::TrustStore::statusFromStr(ststr.c_str());
214 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
215 0 : return acc->getCertificatesByStatus(status);
216 0 : return {};
217 : }
218 :
219 : void
220 16 : setAccountDetails(const std::string& accountId, const std::map<std::string, std::string>& details)
221 : {
222 16 : jami::Manager::instance().setAccountDetails(accountId, details);
223 16 : }
224 :
225 : void
226 0 : setAccountActive(const std::string& accountId, bool enable, bool shutdownConnections)
227 : {
228 0 : jami::Manager::instance().setAccountActive(accountId, enable, shutdownConnections);
229 0 : }
230 :
231 : void
232 0 : loadAccountAndConversation(const std::string& accountId, bool loadAll, const std::string& convId)
233 : {
234 0 : jami::Manager::instance().loadAccountAndConversation(accountId, loadAll, convId);
235 0 : }
236 :
237 : void
238 0 : sendRegister(const std::string& accountId, bool enable)
239 : {
240 0 : jami::Manager::instance().sendRegister(accountId, enable);
241 0 : }
242 :
243 : bool
244 0 : isPasswordValid(const std::string& accountId, const std::string& password)
245 : {
246 0 : if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(accountId))
247 0 : return acc->isPasswordValid(password);
248 0 : return false;
249 : }
250 :
251 : std::vector<uint8_t>
252 0 : getPasswordKey(const std::string& accountID, const std::string& password)
253 : {
254 0 : if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(accountID))
255 0 : return acc->getPasswordKey(password);
256 0 : return {};
257 : }
258 :
259 : void
260 0 : registerAllAccounts()
261 : {
262 0 : jami::Manager::instance().registerAccounts();
263 0 : }
264 :
265 : uint64_t
266 0 : sendAccountTextMessage(const std::string& accountId,
267 : const std::string& to,
268 : const std::map<std::string, std::string>& payloads,
269 : int32_t flags)
270 : {
271 0 : bool onlyConnected = flags & 0x1;
272 0 : return jami::Manager::instance().sendTextMessage(accountId, to, payloads, onlyConnected);
273 : }
274 :
275 : std::vector<Message>
276 0 : getLastMessages(const std::string& accountId, const uint64_t& base_timestamp)
277 : {
278 0 : if (const auto acc = jami::Manager::instance().getAccount(accountId))
279 0 : return acc->getLastMessages(base_timestamp);
280 0 : return {};
281 : }
282 :
283 : std::map<std::string, std::string>
284 0 : getNearbyPeers(const std::string& accountId)
285 : {
286 0 : return jami::Manager::instance().getNearbyPeers(accountId);
287 : }
288 :
289 : void
290 0 : updateProfile(const std::string& accountId,
291 : const std::string& displayName,
292 : const std::string& avatar,
293 : const std::string& fileType,
294 : const std::string& botOwner,
295 : int32_t flag)
296 : {
297 0 : if (const auto acc = jami::Manager::instance().getAccount(accountId)) {
298 0 : acc->updateProfile(displayName, avatar, fileType, botOwner, flag);
299 0 : }
300 0 : }
301 :
302 : int
303 0 : getMessageStatus(uint64_t messageId)
304 : {
305 0 : return jami::Manager::instance().getMessageStatus(messageId);
306 : }
307 :
308 : int
309 0 : getMessageStatus(const std::string& accountId, uint64_t messageId)
310 : {
311 0 : return jami::Manager::instance().getMessageStatus(accountId, messageId);
312 : }
313 :
314 : void
315 5 : setIsComposing(const std::string& accountId, const std::string& conversationUri, bool isWriting)
316 : {
317 5 : if (const auto acc = jami::Manager::instance().getAccount(accountId))
318 5 : acc->setIsComposing(conversationUri, isWriting);
319 5 : }
320 :
321 : bool
322 2 : setMessageDisplayed(const std::string& accountId,
323 : const std::string& conversationUri,
324 : const std::string& messageId,
325 : int status)
326 : {
327 2 : if (const auto acc = jami::Manager::instance().getAccount(accountId))
328 2 : return acc->setMessageDisplayed(conversationUri, messageId, status);
329 0 : return false;
330 : }
331 :
332 : int32_t
333 5 : addDevice(const std::string& accountId, const std::string& uri)
334 : {
335 5 : JAMI_DEBUG("[LinkDevice {}] exportToPeer called.", accountId);
336 5 : if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
337 5 : return account->addDevice(uri);
338 5 : }
339 0 : return static_cast<int32_t>(jami::AccountManager::AddDeviceError::GENERIC);
340 : }
341 :
342 : bool
343 4 : confirmAddDevice(const std::string& accountId, uint32_t op_id)
344 : {
345 4 : if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
346 4 : return account->confirmAddDevice(op_id);
347 4 : }
348 0 : return false;
349 : }
350 :
351 : bool
352 0 : cancelAddDevice(const std::string& accountId, uint32_t op_id)
353 : {
354 0 : if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
355 0 : return account->cancelAddDevice(op_id);
356 0 : }
357 0 : return false;
358 : }
359 :
360 : bool
361 7 : provideAccountAuthentication(const std::string& accountId,
362 : const std::string& credentialsFromUser,
363 : const std::string& scheme)
364 : {
365 7 : if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
366 : // send the password to the channel for communicationg with the old device
367 7 : account->provideAccountAuthentication(credentialsFromUser, scheme);
368 7 : return true;
369 7 : }
370 0 : return false;
371 : }
372 :
373 : bool
374 0 : exportToFile(const std::string& accountId,
375 : const std::string& destinationPath,
376 : const std::string& scheme,
377 : const std::string& password)
378 : {
379 0 : if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
380 0 : return account->exportArchive(destinationPath, scheme, password);
381 0 : }
382 0 : return false;
383 : }
384 :
385 : bool
386 0 : revokeDevice(const std::string& accountId,
387 : const std::string& deviceId,
388 : const std::string& scheme,
389 : const std::string& password)
390 : {
391 0 : if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
392 0 : return account->revokeDevice(deviceId, scheme, password);
393 0 : }
394 0 : return false;
395 : }
396 :
397 : std::map<std::string, std::string>
398 0 : getKnownRingDevices(const std::string& accountId)
399 : {
400 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
401 0 : return acc->getKnownDevices();
402 0 : return {};
403 : }
404 :
405 : /* Local-service exposure */
406 :
407 : namespace {
408 : std::map<std::string, std::string>
409 0 : serviceRecordToMap(const jami::ServiceRecord& r)
410 : {
411 0 : std::map<std::string, std::string> m;
412 0 : m["id"] = r.id;
413 0 : m["type"] = r.type;
414 0 : m["name"] = r.name;
415 0 : m["description"] = r.description;
416 0 : m["scheme"] = r.scheme;
417 0 : m["localHost"] = r.localHost;
418 0 : m["localPort"] = std::to_string(r.localPort);
419 0 : m["preferredPort"] = std::to_string(r.preferredPort);
420 0 : m["directory"] = r.directory;
421 0 : m["enabled"] = r.enabled ? "true" : "false";
422 0 : switch (r.policy) {
423 0 : case jami::AccessPolicy::PUBLIC:
424 0 : m["policy"] = "public";
425 0 : break;
426 0 : case jami::AccessPolicy::SPECIFIC_CONTACTS:
427 0 : m["policy"] = "specific";
428 0 : break;
429 0 : case jami::AccessPolicy::CONTACTS_ONLY:
430 : default:
431 0 : m["policy"] = "contacts";
432 0 : break;
433 : }
434 0 : std::string allowed;
435 0 : for (size_t i = 0; i < r.allowedContacts.size(); ++i) {
436 0 : if (i)
437 0 : allowed.push_back(',');
438 0 : allowed += r.allowedContacts[i];
439 : }
440 0 : m["allowedContacts"] = std::move(allowed);
441 0 : return m;
442 0 : }
443 :
444 : jami::ServiceRecord
445 0 : mapToServiceRecord(const std::map<std::string, std::string>& m)
446 : {
447 0 : jami::ServiceRecord r;
448 0 : auto get = [&](const char* k, const std::string& def = {}) {
449 0 : auto it = m.find(k);
450 0 : return it == m.end() ? def : it->second;
451 0 : };
452 0 : r.id = get("id");
453 0 : r.type = get("type", "custom");
454 0 : if (r.type.empty())
455 0 : r.type = "custom";
456 0 : r.name = get("name");
457 0 : r.description = get("description");
458 0 : r.scheme = get("scheme");
459 0 : auto host = get("localHost");
460 0 : if (!host.empty())
461 0 : r.localHost = host;
462 0 : auto portStr = get("localPort");
463 0 : if (!portStr.empty()) {
464 : try {
465 0 : r.localPort = static_cast<uint16_t>(std::stoi(portStr));
466 0 : } catch (...) {
467 0 : }
468 : }
469 0 : auto prefPortStr = get("preferredPort");
470 0 : if (!prefPortStr.empty()) {
471 : try {
472 0 : r.preferredPort = static_cast<uint16_t>(std::stoi(prefPortStr));
473 0 : } catch (...) {
474 0 : }
475 : }
476 0 : r.directory = get("directory");
477 0 : auto pol = get("policy", "contacts");
478 0 : if (pol == "public")
479 0 : r.policy = jami::AccessPolicy::PUBLIC;
480 0 : else if (pol == "specific")
481 0 : r.policy = jami::AccessPolicy::SPECIFIC_CONTACTS;
482 : else
483 0 : r.policy = jami::AccessPolicy::CONTACTS_ONLY;
484 0 : auto allowed = get("allowedContacts");
485 0 : if (!allowed.empty()) {
486 0 : size_t start = 0;
487 0 : while (start <= allowed.size()) {
488 0 : auto end = allowed.find(',', start);
489 0 : auto piece = allowed.substr(start, end - start);
490 0 : if (!piece.empty())
491 0 : r.allowedContacts.push_back(std::move(piece));
492 0 : if (end == std::string::npos)
493 0 : break;
494 0 : start = end + 1;
495 0 : }
496 : }
497 0 : auto en = get("enabled", "true");
498 0 : r.enabled = (en == "true" || en == "1");
499 0 : return r;
500 0 : }
501 : } // namespace
502 :
503 : std::string
504 0 : addExposedService(const std::string& accountId, const std::map<std::string, std::string>& details)
505 : {
506 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId); acc && acc->hasServiceManager())
507 0 : return acc->serviceManager().addService(mapToServiceRecord(details), acc->rand);
508 0 : return {};
509 : }
510 :
511 : bool
512 0 : updateExposedService(const std::string& accountId, const std::map<std::string, std::string>& details)
513 : {
514 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId); acc && acc->hasServiceManager()) {
515 0 : auto rec = mapToServiceRecord(details);
516 : // Tear down any active inbound tunnels first; if the update changes
517 : // the local target (host/port) or disables the service, existing
518 : // peer connections must be severed. A new connection from a peer
519 : // will pick up the updated record.
520 0 : acc->closeServerTunnelsForService(rec.id);
521 0 : return acc->serviceManager().updateService(rec);
522 0 : }
523 0 : return false;
524 : }
525 :
526 : bool
527 0 : removeExposedService(const std::string& accountId, const std::string& serviceId)
528 : {
529 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId); acc && acc->hasServiceManager()) {
530 0 : acc->closeServerTunnelsForService(serviceId);
531 0 : return acc->serviceManager().removeService(serviceId);
532 0 : }
533 0 : return false;
534 : }
535 :
536 : std::vector<std::map<std::string, std::string>>
537 0 : getExposedServices(const std::string& accountId)
538 : {
539 0 : std::vector<std::map<std::string, std::string>> out;
540 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId); acc && acc->hasServiceManager()) {
541 0 : auto recs = acc->serviceManager().getServices();
542 0 : out.reserve(recs.size());
543 0 : for (auto& r : recs)
544 0 : out.push_back(serviceRecordToMap(r));
545 0 : }
546 0 : return out;
547 0 : }
548 :
549 : uint32_t
550 1 : queryPeerServices(const std::string& accountId, const std::string& peerUri)
551 : {
552 1 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
553 1 : return acc->queryPeerServices(peerUri);
554 0 : return 0;
555 : }
556 :
557 : std::string
558 1 : openServiceTunnel(const std::string& accountId,
559 : const std::string& peerUri,
560 : const std::string& deviceId,
561 : const std::string& serviceId,
562 : const std::string& serviceName,
563 : uint16_t localPort)
564 : {
565 1 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
566 1 : return acc->openServiceTunnel(peerUri, deviceId, serviceId, serviceName, localPort);
567 0 : return {};
568 : }
569 :
570 : bool
571 1 : closeServiceTunnel(const std::string& accountId, const std::string& tunnelId)
572 : {
573 1 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
574 1 : return acc->closeServiceTunnel(tunnelId);
575 0 : return false;
576 : }
577 :
578 : std::vector<std::map<std::string, std::string>>
579 0 : getActiveTunnels(const std::string& accountId)
580 : {
581 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
582 0 : return acc->getActiveServiceTunnels();
583 0 : return {};
584 : }
585 :
586 : bool
587 4 : changeAccountPassword(const std::string& accountId, const std::string& password_old, const std::string& password_new)
588 : {
589 4 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
590 4 : return acc->changeArchivePassword(password_old, password_new);
591 0 : return false;
592 : }
593 :
594 : /* contacts */
595 :
596 : void
597 0 : addContact(const std::string& accountId, const std::string& uri)
598 : {
599 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
600 0 : return acc->addContact(uri);
601 : }
602 :
603 : void
604 0 : removeContact(const std::string& accountId, const std::string& uri, bool ban)
605 : {
606 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
607 0 : return acc->removeContact(uri, ban);
608 : }
609 :
610 : std::map<std::string, std::string>
611 0 : getContactDetails(const std::string& accountId, const std::string& uri)
612 : {
613 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
614 0 : return acc->getContactDetails(uri);
615 0 : return {};
616 : }
617 :
618 : std::vector<std::map<std::string, std::string>>
619 1 : getContacts(const std::string& accountId)
620 : {
621 1 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
622 1 : return acc->getContacts();
623 0 : return {};
624 : }
625 :
626 : /* contact requests */
627 : std::vector<std::map<std::string, std::string>>
628 0 : getTrustRequests(const std::string& accountId)
629 : {
630 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
631 0 : return acc->getTrustRequests();
632 0 : return {};
633 : }
634 :
635 : bool
636 0 : acceptTrustRequest(const std::string& accountId, const std::string& from)
637 : {
638 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
639 0 : return acc->acceptTrustRequest(from);
640 0 : return false;
641 : }
642 :
643 : bool
644 0 : discardTrustRequest(const std::string& accountId, const std::string& from)
645 : {
646 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
647 0 : return acc->discardTrustRequest(from);
648 0 : return false;
649 : }
650 :
651 : void
652 0 : sendTrustRequest(const std::string& accountId, const std::string& to, const std::vector<uint8_t>& payload)
653 : {
654 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
655 0 : acc->sendTrustRequest(to, payload);
656 0 : }
657 :
658 : /// This function is used as a base for new accounts for clients that support it
659 : std::map<std::string, std::string>
660 348 : getAccountTemplate(const std::string& accountType)
661 : {
662 348 : if (accountType == Account::ProtocolNames::RING)
663 325 : return jami::JamiAccountConfig().toMap();
664 23 : else if (accountType == Account::ProtocolNames::SIP)
665 23 : return jami::SipAccountConfig().toMap();
666 0 : return {};
667 : }
668 :
669 : std::string
670 0 : addAccount(const std::map<std::string, std::string>& details, const std::string& accountId)
671 : {
672 0 : return jami::Manager::instance().addAccount(details, accountId);
673 : }
674 :
675 : void
676 0 : monitor(bool continuous)
677 : {
678 0 : return jami::Manager::instance().monitor(continuous);
679 : }
680 :
681 : std::vector<std::map<std::string, std::string>>
682 0 : getConnectionList(const std::string& accountId, const std::string& conversationId)
683 : {
684 0 : return jami::Manager::instance().getConnectionList(accountId, conversationId);
685 : }
686 :
687 : std::vector<std::map<std::string, std::string>>
688 0 : getConversationConnectivity(const std::string& accountId, const std::string& conversationId)
689 : {
690 0 : if (auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
691 0 : return account->getConversationConnectivity(conversationId);
692 0 : }
693 0 : return {};
694 : }
695 :
696 : std::vector<std::map<std::string, std::string>>
697 0 : getConversationTrackedMembers(const std::string& accountId, const std::string& conversationId)
698 : {
699 0 : if (auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
700 0 : return account->getConversationTrackedMembers(conversationId);
701 0 : }
702 0 : return {};
703 : }
704 :
705 : std::vector<std::map<std::string, std::string>>
706 0 : getChannelList(const std::string& accountId, const std::string& connectionId)
707 : {
708 0 : return jami::Manager::instance().getChannelList(accountId, connectionId);
709 : }
710 :
711 : void
712 0 : removeAccount(const std::string& accountId)
713 : {
714 0 : return jami::Manager::instance().removeAccount(accountId, true); // with 'flush' enabled
715 : }
716 :
717 : std::vector<std::string>
718 0 : getAccountList()
719 : {
720 0 : return jami::Manager::instance().getAccountList();
721 : }
722 :
723 : /**
724 : * Send the list of all codecs loaded to the client through DBus.
725 : * Can stay global, as only the active codecs will be set per accounts
726 : */
727 : std::vector<unsigned>
728 0 : getCodecList()
729 : {
730 : std::vector<unsigned> list {
731 0 : jami::Manager::instance().getSystemCodecContainer()->getSystemCodecInfoIdList(jami::MEDIA_ALL)};
732 0 : if (list.empty())
733 0 : jami::emitSignal<ConfigurationSignal::Error>(CODECS_NOT_LOADED);
734 0 : return list;
735 0 : }
736 :
737 : std::vector<std::string>
738 0 : getSupportedTlsMethod()
739 : {
740 0 : return SIPAccount::getSupportedTlsProtocols();
741 : }
742 :
743 : std::vector<std::string>
744 0 : getSupportedCiphers(const std::string& accountId)
745 : {
746 0 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId))
747 0 : return SIPAccount::getSupportedTlsCiphers();
748 0 : JAMI_ERROR("SIP account {} doesn't exist", accountId);
749 0 : return {};
750 : }
751 :
752 : bool
753 0 : setCodecDetails(const std::string& accountId, const unsigned& codecId, const std::map<std::string, std::string>& details)
754 : {
755 0 : auto acc = jami::Manager::instance().getAccount(accountId);
756 0 : if (!acc) {
757 0 : JAMI_ERROR("Unable to find account {}. Unable to set codec details", accountId);
758 0 : return false;
759 : }
760 :
761 0 : auto codec = acc->searchCodecById(codecId, jami::MEDIA_ALL);
762 0 : if (!codec) {
763 0 : JAMI_ERROR("Unable to find codec {}", codecId);
764 0 : return false;
765 : }
766 : try {
767 0 : if (codec->mediaType & jami::MEDIA_AUDIO) {
768 0 : if (auto foundCodec = std::static_pointer_cast<jami::SystemAudioCodecInfo>(codec)) {
769 0 : foundCodec->setCodecSpecifications(details);
770 0 : jami::emitSignal<ConfigurationSignal::MediaParametersChanged>(accountId);
771 0 : return true;
772 0 : }
773 : }
774 :
775 0 : if (codec->mediaType & jami::MEDIA_VIDEO) {
776 0 : if (auto foundCodec = std::static_pointer_cast<jami::SystemVideoCodecInfo>(codec)) {
777 0 : foundCodec->setCodecSpecifications(details);
778 0 : JAMI_WARNING("parameters for {} changed ", foundCodec->name);
779 0 : if (auto call = jami::Manager::instance().getCurrentCall()) {
780 0 : if (call->getVideoCodec() == foundCodec) {
781 0 : JAMI_WARNING("{} running. Need to restart encoding", foundCodec->name);
782 0 : call->restartMediaSender();
783 : }
784 0 : }
785 0 : jami::emitSignal<ConfigurationSignal::MediaParametersChanged>(accountId);
786 0 : return true;
787 0 : }
788 : }
789 0 : } catch (const std::exception& e) {
790 0 : JAMI_ERROR("Unable to set codec specifications: {}", e.what());
791 0 : }
792 :
793 0 : return false;
794 0 : }
795 :
796 : std::map<std::string, std::string>
797 0 : getCodecDetails(const std::string& accountId, const unsigned& codecId)
798 : {
799 0 : auto acc = jami::Manager::instance().getAccount(accountId);
800 0 : if (!acc) {
801 0 : JAMI_ERROR("Unable to find account {} return default codec details", accountId);
802 0 : return jami::Account::getDefaultCodecDetails(codecId);
803 : }
804 :
805 0 : auto codec = acc->searchCodecById(codecId, jami::MEDIA_ALL);
806 0 : if (!codec) {
807 0 : jami::emitSignal<ConfigurationSignal::Error>(CODECS_NOT_LOADED);
808 0 : return {};
809 : }
810 :
811 0 : if (codec->mediaType & jami::MEDIA_AUDIO)
812 0 : if (auto foundCodec = std::static_pointer_cast<jami::SystemAudioCodecInfo>(codec))
813 0 : return foundCodec->getCodecSpecifications();
814 :
815 0 : if (codec->mediaType & jami::MEDIA_VIDEO)
816 0 : if (auto foundCodec = std::static_pointer_cast<jami::SystemVideoCodecInfo>(codec))
817 0 : return foundCodec->getCodecSpecifications();
818 :
819 0 : jami::emitSignal<ConfigurationSignal::Error>(CODECS_NOT_LOADED);
820 0 : return {};
821 0 : }
822 :
823 : std::vector<unsigned>
824 0 : getActiveCodecList(const std::string& accountId)
825 : {
826 0 : if (auto acc = jami::Manager::instance().getAccount(accountId))
827 0 : return acc->getActiveCodecs();
828 0 : JAMI_ERROR("Unable to find account {}, returning default", accountId);
829 0 : return jami::Account::getDefaultCodecsId();
830 : }
831 :
832 : void
833 0 : setActiveCodecList(const std::string& accountId, const std::vector<unsigned>& list)
834 : {
835 0 : if (auto acc = jami::Manager::instance().getAccount(accountId)) {
836 0 : acc->setActiveCodecs(list);
837 0 : jami::Manager::instance().saveConfig(acc);
838 : } else {
839 0 : JAMI_ERROR("Unable to find account {}", accountId);
840 0 : }
841 0 : }
842 :
843 : std::vector<std::string>
844 0 : getAudioPluginList()
845 : {
846 0 : return {PCM_DEFAULT, PCM_DMIX_DSNOOP};
847 : }
848 :
849 : void
850 0 : setAudioPlugin(const std::string& audioPlugin)
851 : {
852 0 : return jami::Manager::instance().setAudioPlugin(audioPlugin);
853 : }
854 :
855 : std::vector<std::string>
856 0 : getAudioOutputDeviceList()
857 : {
858 0 : return jami::Manager::instance().getAudioOutputDeviceList();
859 : }
860 :
861 : std::vector<std::string>
862 0 : getAudioInputDeviceList()
863 : {
864 0 : return jami::Manager::instance().getAudioInputDeviceList();
865 : }
866 :
867 : void
868 0 : setAudioOutputDevice(int32_t index)
869 : {
870 0 : return jami::Manager::instance().setAudioDevice(index, AudioDeviceType::PLAYBACK);
871 : }
872 :
873 : void
874 0 : setAudioInputDevice(int32_t index)
875 : {
876 0 : return jami::Manager::instance().setAudioDevice(index, AudioDeviceType::CAPTURE);
877 : }
878 :
879 : void
880 0 : setAudioRingtoneDevice(int32_t index)
881 : {
882 0 : return jami::Manager::instance().setAudioDevice(index, AudioDeviceType::RINGTONE);
883 : }
884 :
885 : std::vector<std::string>
886 0 : getCurrentAudioDevicesIndex()
887 : {
888 0 : return jami::Manager::instance().getCurrentAudioDevicesIndex();
889 : }
890 :
891 : int32_t
892 0 : getAudioInputDeviceIndex(const std::string& name)
893 : {
894 0 : return jami::Manager::instance().getAudioInputDeviceIndex(name);
895 : }
896 :
897 : int32_t
898 0 : getAudioOutputDeviceIndex(const std::string& name)
899 : {
900 0 : return jami::Manager::instance().getAudioOutputDeviceIndex(name);
901 : }
902 :
903 : std::string
904 0 : getCurrentAudioOutputPlugin()
905 : {
906 0 : auto plugin = jami::Manager::instance().getCurrentAudioOutputPlugin();
907 0 : JAMI_LOG("Get audio plugin {}", plugin);
908 0 : return plugin;
909 0 : }
910 :
911 : std::string
912 0 : getNoiseSuppressState()
913 : {
914 0 : return jami::Manager::instance().getNoiseSuppressState();
915 : }
916 :
917 : void
918 0 : setNoiseSuppressState(const std::string& state)
919 : {
920 0 : jami::Manager::instance().setNoiseSuppressState(state);
921 0 : }
922 :
923 : std::string
924 0 : getEchoCancellationState()
925 : {
926 0 : return jami::Manager::instance().getEchoCancellationState();
927 : }
928 :
929 : void
930 0 : setEchoCancellationState(const std::string& state)
931 : {
932 0 : jami::Manager::instance().setEchoCancellationState(state);
933 0 : }
934 :
935 : bool
936 0 : getVoiceActivityDetectionState()
937 : {
938 0 : return jami::Manager::instance().getVoiceActivityDetectionState();
939 : }
940 :
941 : void
942 0 : setVoiceActivityDetectionState(bool state)
943 : {
944 0 : jami::Manager::instance().setVoiceActivityDetectionState(state);
945 0 : }
946 :
947 : bool
948 0 : isAgcEnabled()
949 : {
950 0 : return jami::Manager::instance().isAGCEnabled();
951 : }
952 :
953 : void
954 0 : setAgcState(bool enabled)
955 : {
956 0 : jami::Manager::instance().setAGCState(enabled);
957 0 : }
958 :
959 : std::string
960 0 : getRecordPath()
961 : {
962 0 : return jami::Manager::instance().audioPreference.getRecordPath();
963 : }
964 :
965 : void
966 5 : setRecordPath(const std::string& recPath)
967 : {
968 5 : jami::Manager::instance().audioPreference.setRecordPath(recPath);
969 5 : }
970 :
971 : bool
972 0 : getIsAlwaysRecording()
973 : {
974 0 : return jami::Manager::instance().getIsAlwaysRecording();
975 : }
976 :
977 : void
978 6 : setIsAlwaysRecording(bool rec)
979 : {
980 6 : jami::Manager::instance().setIsAlwaysRecording(rec);
981 6 : }
982 :
983 : bool
984 0 : getRecordPreview()
985 : {
986 : #ifdef ENABLE_VIDEO
987 0 : return jami::Manager::instance().videoPreferences.getRecordPreview();
988 : #else
989 : return false;
990 : #endif
991 : }
992 :
993 : void
994 0 : setRecordPreview(bool rec)
995 : {
996 : #ifdef ENABLE_VIDEO
997 0 : jami::Manager::instance().videoPreferences.setRecordPreview(rec);
998 0 : jami::Manager::instance().saveConfig();
999 : #endif
1000 0 : }
1001 :
1002 : int32_t
1003 0 : getRecordQuality()
1004 : {
1005 : #ifdef ENABLE_VIDEO
1006 0 : return jami::Manager::instance().videoPreferences.getRecordQuality();
1007 : #else
1008 : return 0;
1009 : #endif
1010 : }
1011 :
1012 : void
1013 0 : setRecordQuality(int32_t quality)
1014 : {
1015 : #ifdef ENABLE_VIDEO
1016 0 : jami::Manager::instance().videoPreferences.setRecordQuality(quality);
1017 0 : jami::Manager::instance().saveConfig();
1018 : #endif
1019 0 : }
1020 :
1021 : std::string
1022 0 : getConferenceResolution()
1023 : {
1024 : #ifdef ENABLE_VIDEO
1025 0 : return jami::Manager::instance().videoPreferences.getConferenceResolution();
1026 : #else
1027 : return {};
1028 : #endif
1029 : }
1030 :
1031 : void
1032 0 : setConferenceResolution(const std::string& resolution)
1033 : {
1034 : #ifdef ENABLE_VIDEO
1035 0 : jami::Manager::instance().videoPreferences.setConferenceResolution(resolution);
1036 0 : jami::Manager::instance().saveConfig();
1037 : #endif
1038 0 : }
1039 :
1040 : int32_t
1041 0 : getHistoryLimit()
1042 : {
1043 0 : return jami::Manager::instance().getHistoryLimit();
1044 : }
1045 :
1046 : void
1047 0 : setHistoryLimit(int32_t days)
1048 : {
1049 0 : jami::Manager::instance().setHistoryLimit(days);
1050 0 : }
1051 :
1052 : int32_t
1053 0 : getRingingTimeout()
1054 : {
1055 0 : return static_cast<int32_t>(jami::Manager::instance().getRingingTimeout().count());
1056 : }
1057 :
1058 : void
1059 0 : setRingingTimeout(int32_t timeout)
1060 : {
1061 0 : jami::Manager::instance().setRingingTimeout(std::chrono::seconds(timeout));
1062 0 : }
1063 :
1064 : std::vector<std::string>
1065 0 : getSupportedAudioManagers()
1066 : {
1067 0 : return jami::AudioPreference::getSupportedAudioManagers();
1068 : }
1069 :
1070 : bool
1071 0 : setAudioManager(const std::string& api)
1072 : {
1073 0 : return jami::Manager::instance().setAudioManager(api);
1074 : }
1075 :
1076 : std::string
1077 0 : getAudioManager()
1078 : {
1079 0 : return jami::Manager::instance().getAudioManager();
1080 : }
1081 :
1082 : void
1083 0 : setVolume(const std::string& device, double value)
1084 : {
1085 0 : if (auto audiolayer = jami::Manager::instance().getAudioDriver()) {
1086 0 : JAMI_LOG("set volume for {}: {}", device, value);
1087 :
1088 0 : if (device == "speaker")
1089 0 : audiolayer->setPlaybackGain(value);
1090 0 : else if (device == "mic")
1091 0 : audiolayer->setCaptureGain(value);
1092 :
1093 0 : jami::emitSignal<ConfigurationSignal::VolumeChanged>(device, value);
1094 : } else {
1095 0 : JAMI_ERROR("Audio layer not valid while updating volume");
1096 0 : }
1097 0 : }
1098 :
1099 : double
1100 0 : getVolume(const std::string& device)
1101 : {
1102 0 : if (auto audiolayer = jami::Manager::instance().getAudioDriver()) {
1103 0 : if (device == "speaker")
1104 0 : return audiolayer->getPlaybackGain();
1105 0 : if (device == "mic")
1106 0 : return audiolayer->getCaptureGain();
1107 0 : }
1108 :
1109 0 : JAMI_ERROR("Audio layer not valid while updating volume");
1110 0 : return 0.0;
1111 : }
1112 :
1113 : // FIXME: we should store "muteDtmf" instead of "playDtmf"
1114 : // in config and avoid negating like this
1115 : bool
1116 0 : isDtmfMuted()
1117 : {
1118 0 : return not jami::Manager::instance().voipPreferences.getPlayDtmf();
1119 : }
1120 :
1121 : void
1122 0 : muteDtmf(bool mute)
1123 : {
1124 0 : jami::Manager::instance().voipPreferences.setPlayDtmf(not mute);
1125 0 : }
1126 :
1127 : bool
1128 0 : isCaptureMuted()
1129 : {
1130 0 : if (auto audiolayer = jami::Manager::instance().getAudioDriver())
1131 0 : return audiolayer->isCaptureMuted();
1132 :
1133 0 : JAMI_ERROR("Audio layer not valid");
1134 0 : return false;
1135 : }
1136 :
1137 : void
1138 0 : muteCapture(bool mute)
1139 : {
1140 0 : if (auto audiolayer = jami::Manager::instance().getAudioDriver())
1141 0 : return audiolayer->muteCapture(mute);
1142 :
1143 0 : JAMI_ERROR("Audio layer not valid");
1144 0 : return;
1145 : }
1146 :
1147 : bool
1148 0 : isPlaybackMuted()
1149 : {
1150 0 : if (auto audiolayer = jami::Manager::instance().getAudioDriver())
1151 0 : return audiolayer->isPlaybackMuted();
1152 :
1153 0 : JAMI_ERROR("Audio layer not valid");
1154 0 : return false;
1155 : }
1156 :
1157 : void
1158 0 : mutePlayback(bool mute)
1159 : {
1160 0 : if (auto audiolayer = jami::Manager::instance().getAudioDriver())
1161 0 : return audiolayer->mutePlayback(mute);
1162 :
1163 0 : JAMI_ERROR("Audio layer not valid");
1164 0 : return;
1165 : }
1166 :
1167 : bool
1168 0 : isRingtoneMuted()
1169 : {
1170 0 : if (auto audiolayer = jami::Manager::instance().getAudioDriver())
1171 0 : return audiolayer->isRingtoneMuted();
1172 :
1173 0 : JAMI_ERROR("Audio layer not valid");
1174 0 : return false;
1175 : }
1176 :
1177 : void
1178 0 : muteRingtone(bool mute)
1179 : {
1180 0 : if (auto audiolayer = jami::Manager::instance().getAudioDriver())
1181 0 : return audiolayer->muteRingtone(mute);
1182 :
1183 0 : JAMI_ERROR("Audio layer not valid");
1184 0 : return;
1185 : }
1186 :
1187 : void
1188 0 : setAccountsOrder(const std::string& order)
1189 : {
1190 0 : jami::Manager::instance().setAccountsOrder(order);
1191 0 : }
1192 :
1193 : std::string
1194 0 : getAddrFromInterfaceName(const std::string& interface)
1195 : {
1196 0 : auto addr = dhtnet::ip_utils::getInterfaceAddr(interface, AF_INET);
1197 0 : if (not addr)
1198 0 : addr = dhtnet::ip_utils::getInterfaceAddr(interface, AF_INET6);
1199 0 : return addr;
1200 : }
1201 :
1202 : std::vector<std::string>
1203 0 : getAllIpInterface()
1204 : {
1205 0 : return dhtnet::ip_utils::getAllIpInterface();
1206 : }
1207 :
1208 : std::vector<std::string>
1209 0 : getAllIpInterfaceByName()
1210 : {
1211 0 : return dhtnet::ip_utils::getAllIpInterfaceByName();
1212 : }
1213 :
1214 : std::vector<std::map<std::string, std::string>>
1215 0 : getCredentials(const std::string& accountId)
1216 : {
1217 0 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId))
1218 0 : return sipaccount->getCredentials();
1219 0 : return {};
1220 : }
1221 :
1222 : void
1223 0 : setCredentials(const std::string& accountId, const std::vector<std::map<std::string, std::string>>& details)
1224 : {
1225 0 : if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) {
1226 0 : sipaccount->doUnregister();
1227 0 : sipaccount->editConfig([&](jami::SipAccountConfig& config) { config.setCredentials(details); });
1228 0 : sipaccount->loadConfig();
1229 0 : if (sipaccount->isEnabled())
1230 0 : sipaccount->doRegister();
1231 0 : jami::Manager::instance().saveConfig(sipaccount);
1232 0 : }
1233 0 : }
1234 :
1235 : void
1236 0 : connectivityChanged()
1237 : {
1238 0 : JAMI_WARNING("received connectivity changed - attempting to re-connect enabled accounts");
1239 :
1240 : // reset the UPnP context
1241 : #if !(defined(TARGET_OS_IOS) && TARGET_OS_IOS)
1242 : try {
1243 0 : jami::Manager::instance().upnpContext()->connectivityChanged();
1244 0 : } catch (std::runtime_error& e) {
1245 0 : JAMI_ERROR("UPnP context error: {}", e.what());
1246 0 : }
1247 : #endif
1248 :
1249 0 : for (const auto& account : jami::Manager::instance().getAllAccounts()) {
1250 0 : account->connectivityChanged();
1251 0 : }
1252 0 : }
1253 :
1254 : bool
1255 3 : lookupName(const std::string& account, const std::string& nameserver, const std::string& name)
1256 : {
1257 3 : if (account.empty()) {
1258 : auto cb =
1259 0 : [name](const std::string& regName, const std::string& address, jami::NameDirectory::Response response) {
1260 0 : jami::emitSignal<libjami::ConfigurationSignal::RegisteredNameFound>("",
1261 0 : name,
1262 : (int) response,
1263 : address,
1264 : regName);
1265 0 : };
1266 0 : if (nameserver.empty())
1267 0 : jami::NameDirectory::lookupUri(name, "", cb);
1268 : else
1269 0 : jami::NameDirectory::instance(nameserver).lookupName(name, cb);
1270 0 : return true;
1271 3 : } else if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(account)) {
1272 3 : acc->lookupName(name);
1273 3 : return true;
1274 3 : }
1275 0 : JAMI_ERROR("lookupName: Unknown account: {}", account);
1276 0 : return false;
1277 : }
1278 :
1279 : bool
1280 3 : lookupAddress(const std::string& account, const std::string& nameserver, const std::string& address)
1281 : {
1282 3 : if (account.empty()) {
1283 0 : jami::NameDirectory::instance(nameserver)
1284 0 : .lookupAddress(address,
1285 0 : [address](const std::string& regName,
1286 : const std::string& addr,
1287 : jami::NameDirectory::Response response) {
1288 0 : jami::emitSignal<libjami::ConfigurationSignal::RegisteredNameFound>("",
1289 0 : address,
1290 : (int) response,
1291 : addr,
1292 : regName);
1293 0 : });
1294 0 : return true;
1295 3 : } else if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(account)) {
1296 3 : acc->lookupAddress(address);
1297 3 : return true;
1298 3 : }
1299 0 : JAMI_ERROR("lookupAddress: Unknown account: {}", account);
1300 0 : return false;
1301 : }
1302 :
1303 : bool
1304 0 : searchUser(const std::string& account, const std::string& query)
1305 : {
1306 0 : if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(account)) {
1307 0 : return acc->searchUser(query);
1308 0 : }
1309 0 : return false;
1310 : }
1311 :
1312 : bool
1313 1 : registerName(const std::string& account, const std::string& name, const std::string& scheme, const std::string& password)
1314 : {
1315 1 : if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(account)) {
1316 1 : acc->registerName(name, scheme, password);
1317 1 : return true;
1318 1 : }
1319 0 : JAMI_ERROR("registerName: Unknown account: {}", account);
1320 0 : return false;
1321 : }
1322 :
1323 : void
1324 0 : setPushNotificationToken(const std::string& token)
1325 : {
1326 0 : for (const auto& account : jami::Manager::instance().getAllAccounts()) {
1327 0 : account->setPushNotificationToken(token);
1328 0 : }
1329 0 : }
1330 :
1331 : void
1332 0 : setPushNotificationTopic(const std::string& topic)
1333 : {
1334 0 : for (const auto& account : jami::Manager::instance().getAllAccounts()) {
1335 0 : account->setPushNotificationTopic(topic);
1336 0 : }
1337 0 : }
1338 :
1339 : void
1340 0 : setPushNotificationConfig(const std::map<std::string, std::string>& data)
1341 : {
1342 0 : for (const auto& account : jami::Manager::instance().getAllAccounts()) {
1343 0 : account->setPushNotificationConfig(data);
1344 0 : }
1345 0 : }
1346 :
1347 : void
1348 0 : pushNotificationReceived(const std::string& from, const std::map<std::string, std::string>& data)
1349 : {
1350 : try {
1351 0 : auto it = data.find("to");
1352 0 : if (it != data.end()) {
1353 0 : if (auto account = jami::Manager::instance().getAccount<JamiAccount>(it->second))
1354 0 : account->pushNotificationReceived(from, data);
1355 : }
1356 : #if defined(__ANDROID__) || defined(ANDROID) || defined(__Apple__)
1357 : else {
1358 : for (const auto& sipAccount : jami::Manager::instance().getAllAccounts<SIPAccount>()) {
1359 : sipAccount->pushNotificationReceived(from, data);
1360 : }
1361 : }
1362 : #endif
1363 0 : } catch (const std::exception& e) {
1364 0 : JAMI_ERROR("Error processing push notification: {}", e.what());
1365 0 : }
1366 0 : }
1367 :
1368 : bool
1369 0 : isAudioMeterActive(const std::string& id)
1370 : {
1371 0 : return jami::Manager::instance().getRingBufferPool().isAudioMeterActive(id);
1372 : }
1373 :
1374 : void
1375 0 : setAudioMeterState(const std::string& id, bool state)
1376 : {
1377 0 : jami::Manager::instance().getRingBufferPool().setAudioMeterState(id, state);
1378 0 : }
1379 :
1380 : void
1381 0 : setDefaultModerator(const std::string& accountId, const std::string& peerURI, bool state)
1382 : {
1383 0 : jami::Manager::instance().setDefaultModerator(accountId, peerURI, state);
1384 0 : }
1385 :
1386 : std::vector<std::string>
1387 0 : getDefaultModerators(const std::string& accountId)
1388 : {
1389 0 : return jami::Manager::instance().getDefaultModerators(accountId);
1390 : }
1391 :
1392 : void
1393 0 : enableLocalModerators(const std::string& accountId, bool isModEnabled)
1394 : {
1395 0 : jami::Manager::instance().enableLocalModerators(accountId, isModEnabled);
1396 0 : }
1397 :
1398 : bool
1399 0 : isLocalModeratorsEnabled(const std::string& accountId)
1400 : {
1401 0 : return jami::Manager::instance().isLocalModeratorsEnabled(accountId);
1402 : }
1403 :
1404 : void
1405 0 : setAllModerators(const std::string& accountId, bool allModerators)
1406 : {
1407 0 : jami::Manager::instance().setAllModerators(accountId, allModerators);
1408 0 : }
1409 :
1410 : bool
1411 0 : isAllModerators(const std::string& accountId)
1412 : {
1413 0 : return jami::Manager::instance().isAllModerators(accountId);
1414 : }
1415 :
1416 : void
1417 0 : setResourceDirPath(const std::string& resourceDir)
1418 : {
1419 0 : jami::fileutils::set_resource_dir_path(resourceDir);
1420 0 : }
1421 :
1422 : } // namespace libjami
|