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

Generated by: LCOV version 2.0-1