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