LCOV - code coverage report
Current view: top level - src/client - configurationmanager.cpp (source / functions) Coverage Total Hit
Test: jami-coverage-filtered.info Lines: 9.6 % 696 67
Test Date: 2026-08-23 08:52:56 Functions: 11.6 % 147 17

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

Generated by: LCOV version 2.0-1