LCOV - code coverage report
Current view: top level - src/client - configurationmanager.cpp (source / functions) Coverage Total Hit
Test: jami-coverage-filtered.info Lines: 8.0 % 690 55
Test Date: 2026-06-13 09:18:46 Functions: 7.2 % 209 15

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

Generated by: LCOV version 2.0-1