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