LCOV - code coverage report
Current view: top level - src/client - configurationmanager.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 49 526 9.3 %
Date: 2024-04-26 09:41:19 Functions: 12 126 9.5 %

          Line data    Source code
       1             : /*
       2             :  *  Copyright (C) 2004-2024 Savoir-faire Linux Inc.
       3             :  *
       4             :  *  Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
       5             :  *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
       6             :  *  Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@savoirfairelinux.com>
       7             :  *  Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
       8             :  *  Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
       9             :  *
      10             :  *  This program is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU General Public License as published by
      12             :  *  the Free Software Foundation; either version 3 of the License, or
      13             :  *  (at your option) any later version.
      14             :  *
      15             :  *  This program is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU General Public License
      21             :  *  along with this program; if not, write to the Free Software
      22             :  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
      23             :  */
      24             : 
      25             : #ifdef HAVE_CONFIG_H
      26             : #include "config.h"
      27             : #endif
      28             : 
      29             : #include "configurationmanager_interface.h"
      30             : #include "account_schema.h"
      31             : #include "manager.h"
      32             : #include "logger.h"
      33             : #include "fileutils.h"
      34             : #include "archiver.h"
      35             : #include "sip/sipaccount.h"
      36             : #include "jamidht/jamiaccount.h"
      37             : #include "sip/sipaccount_config.h"
      38             : #include "jamidht/jamiaccount_config.h"
      39             : #include "audio/audiolayer.h"
      40             : #include "system_codec_container.h"
      41             : #include "account_const.h"
      42             : #include "client/ring_signal.h"
      43             : #include "audio/ringbufferpool.h"
      44             : #include "connectivity/security/tlsvalidator.h"
      45             : 
      46             : #include <dhtnet/ip_utils.h>
      47             : #include <dhtnet/upnp/upnp_context.h>
      48             : #include <dhtnet/certstore.h>
      49             : 
      50             : #ifdef __APPLE__
      51             : #include <TargetConditionals.h>
      52             : #endif
      53             : 
      54             : #ifdef _MSC_VER
      55             : #include "windirent.h"
      56             : #else
      57             : #include <dirent.h>
      58             : #endif
      59             : 
      60             : #include <cerrno>
      61             : #include <cstring>
      62             : #include <sstream>
      63             : 
      64             : #ifdef _WIN32
      65             : #undef interface
      66             : #endif
      67             : 
      68             : namespace libjami {
      69             : 
      70             : constexpr unsigned CODECS_NOT_LOADED = 0x1000; /** Codecs not found */
      71             : 
      72             : using jami::SIPAccount;
      73             : using jami::JamiAccount;
      74             : using jami::tls::TlsValidator;
      75             : using jami::AudioDeviceType;
      76             : 
      77             : void
      78           0 : registerConfHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>& handlers)
      79             : {
      80           0 :     registerSignalHandlers(handlers);
      81           0 : }
      82             : 
      83             : std::map<std::string, std::string>
      84           0 : getAccountDetails(const std::string& accountId)
      85             : {
      86           0 :     return jami::Manager::instance().getAccountDetails(accountId);
      87             : }
      88             : 
      89             : std::map<std::string, std::string>
      90           0 : getVolatileAccountDetails(const std::string& accountId)
      91             : {
      92           0 :     return jami::Manager::instance().getVolatileAccountDetails(accountId);
      93             : }
      94             : 
      95             : std::map<std::string, std::string>
      96           0 : validateCertificate(const std::string& accountId, const std::string& certificate)
      97             : {
      98             :     try {
      99           0 :         if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     100           0 :             return TlsValidator {acc->certStore(), acc->certStore().getCertificate(certificate)}
     101           0 :                 .getSerializedChecks();
     102           0 :     } catch (const std::runtime_error& e) {
     103           0 :         JAMI_WARN("Certificate loading failed: %s", e.what());
     104           0 :     }
     105           0 :     return {{Certificate::ChecksNames::EXIST, Certificate::CheckValuesNames::FAILED}};
     106             : }
     107             : 
     108             : std::map<std::string, std::string>
     109           0 : validateCertificatePath(const std::string& accountId,
     110             :                         const std::string& certificate,
     111             :                         const std::string& privateKey,
     112             :                         const std::string& privateKeyPass,
     113             :                         const std::string& caList)
     114             : {
     115             :     try {
     116           0 :         if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     117           0 :             return TlsValidator {acc->certStore(), certificate, privateKey, privateKeyPass, caList}
     118           0 :                 .getSerializedChecks();
     119           0 :     } catch (const std::runtime_error& e) {
     120           0 :         JAMI_WARN("Certificate loading failed: %s", e.what());
     121           0 :         return {{Certificate::ChecksNames::EXIST, Certificate::CheckValuesNames::FAILED}};
     122           0 :     }
     123           0 :     return {};
     124             : }
     125             : 
     126             : std::map<std::string, std::string>
     127           0 : getCertificateDetails(const std::string& accountId, const std::string& certificate)
     128             : {
     129             :     try {
     130           0 :         if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     131           0 :             return TlsValidator {acc->certStore(), acc->certStore().getCertificate(certificate)}
     132           0 :                 .getSerializedDetails();
     133           0 :     } catch (const std::runtime_error& e) {
     134           0 :         JAMI_WARN("Certificate loading failed: %s", e.what());
     135           0 :     }
     136           0 :     return {};
     137             : }
     138             : 
     139             : std::map<std::string, std::string>
     140           0 : getCertificateDetailsPath(const std::string& accountId,
     141             :                           const std::string& certificate,
     142             :                           const std::string& privateKey,
     143             :                           const std::string& privateKeyPassword)
     144             : {
     145             :     try {
     146             :         auto crt = std::make_shared<dht::crypto::Certificate>(
     147           0 :             jami::fileutils::loadFile(certificate));
     148           0 :         if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
     149           0 :             TlsValidator validator {acc->certStore(), certificate, privateKey, privateKeyPassword};
     150           0 :             acc->certStore().pinCertificate(validator.getCertificate(), false);
     151           0 :             return validator.getSerializedDetails();
     152           0 :         }
     153           0 :     } catch (const std::runtime_error& e) {
     154           0 :         JAMI_WARN("Certificate loading failed: %s", e.what());
     155           0 :     }
     156           0 :     return {};
     157             : }
     158             : 
     159             : std::vector<std::string>
     160           0 : getPinnedCertificates(const std::string& accountId)
     161             : {
     162           0 :     if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     163           0 :         return acc->certStore().getPinnedCertificates();
     164           0 :     return {};
     165             : }
     166             : 
     167             : std::vector<std::string>
     168           0 : pinCertificate(const std::string& accountId, const std::vector<uint8_t>& certificate, bool local)
     169             : {
     170           0 :     if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     171           0 :         return acc->certStore().pinCertificate(certificate, local);
     172           0 :     return {};
     173             : }
     174             : 
     175             : void
     176           0 : pinCertificatePath(const std::string& accountId, const std::string& path)
     177             : {
     178           0 :     if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     179           0 :         acc->certStore().pinCertificatePath(path);
     180           0 : }
     181             : 
     182             : bool
     183           0 : unpinCertificate(const std::string& accountId, const std::string& certId)
     184             : {
     185           0 :     if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     186           0 :         return acc->certStore().unpinCertificate(certId);
     187           0 :     return {};
     188             : }
     189             : 
     190             : unsigned
     191           0 : unpinCertificatePath(const std::string& accountId, const std::string& path)
     192             : {
     193           0 :     if (const auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     194           0 :         return acc->certStore().unpinCertificatePath(path);
     195           0 :     return {};
     196             : }
     197             : 
     198             : bool
     199           0 : pinRemoteCertificate(const std::string& accountId, const std::string& certId)
     200             : {
     201           0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
     202           0 :         acc->dht()->findCertificate(dht::InfoHash(certId),
     203           0 :                                     [](const std::shared_ptr<dht::crypto::Certificate>& crt) {});
     204           0 :         return true;
     205           0 :     }
     206           0 :     return false;
     207             : }
     208             : 
     209             : bool
     210           0 : setCertificateStatus(const std::string& accountId,
     211             :                      const std::string& certId,
     212             :                      const std::string& ststr)
     213             : {
     214             :     try {
     215           0 :         if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
     216           0 :             auto status = dhtnet::tls::TrustStore::statusFromStr(ststr.c_str());
     217           0 :             return acc->setCertificateStatus(certId, status);
     218           0 :         }
     219           0 :     } catch (const std::out_of_range&) {
     220           0 :     }
     221           0 :     return false;
     222             : }
     223             : 
     224             : std::vector<std::string>
     225           0 : getCertificatesByStatus(const std::string& accountId, const std::string& ststr)
     226             : {
     227           0 :     auto status = dhtnet::tls::TrustStore::statusFromStr(ststr.c_str());
     228           0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     229           0 :         return acc->getCertificatesByStatus(status);
     230           0 :     return {};
     231             : }
     232             : 
     233             : void
     234          13 : setAccountDetails(const std::string& accountId, const std::map<std::string, std::string>& details)
     235             : {
     236          13 :     jami::Manager::instance().setAccountDetails(accountId, details);
     237          13 : }
     238             : 
     239             : void
     240           0 : setAccountActive(const std::string& accountId, bool enable, bool shutdownConnections)
     241             : {
     242           0 :     jami::Manager::instance().setAccountActive(accountId, enable, shutdownConnections);
     243           0 : }
     244             : 
     245             : void
     246           0 : loadAccountAndConversation(const std::string& accountId, bool loadAll, const std::string& convId)
     247             : {
     248           0 :     jami::Manager::instance().loadAccountAndConversation(accountId, loadAll, convId);
     249           0 : }
     250             : 
     251             : void
     252           0 : sendRegister(const std::string& accountId, bool enable)
     253             : {
     254           0 :     jami::Manager::instance().sendRegister(accountId, enable);
     255           0 : }
     256             : 
     257             : bool
     258           0 : isPasswordValid(const std::string& accountId, const std::string& password)
     259             : {
     260           0 :     if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(accountId))
     261           0 :         return acc->isPasswordValid(password);
     262           0 :     return false;
     263             : }
     264             : 
     265             : std::vector<uint8_t>
     266           0 : getPasswordKey(const std::string& accountID, const std::string& password)
     267             : {
     268           0 :     if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(accountID))
     269           0 :         return acc->getPasswordKey(password);
     270           0 :     return {};
     271             : }
     272             : 
     273             : void
     274           0 : registerAllAccounts()
     275             : {
     276           0 :     jami::Manager::instance().registerAccounts();
     277           0 : }
     278             : 
     279             : uint64_t
     280           0 : sendAccountTextMessage(const std::string& accountId,
     281             :                        const std::string& to,
     282             :                        const std::map<std::string, std::string>& payloads,
     283             :                        int32_t flags)
     284             : {
     285           0 :     bool onlyConnected = flags & 0x1;
     286           0 :     return jami::Manager::instance().sendTextMessage(accountId, to, payloads, onlyConnected);
     287             : }
     288             : 
     289             : std::vector<Message>
     290           0 : getLastMessages(const std::string& accountId, const uint64_t& base_timestamp)
     291             : {
     292           0 :     if (const auto acc = jami::Manager::instance().getAccount(accountId))
     293           0 :         return acc->getLastMessages(base_timestamp);
     294           0 :     return {};
     295             : }
     296             : 
     297             : std::map<std::string, std::string>
     298           0 : getNearbyPeers(const std::string& accountId)
     299             : {
     300           0 :     return jami::Manager::instance().getNearbyPeers(accountId);
     301             : }
     302             : 
     303             : int
     304           0 : getMessageStatus(uint64_t messageId)
     305             : {
     306           0 :     return jami::Manager::instance().getMessageStatus(messageId);
     307             : }
     308             : 
     309             : int
     310           0 : getMessageStatus(const std::string& accountId, uint64_t messageId)
     311             : {
     312           0 :     return jami::Manager::instance().getMessageStatus(accountId, messageId);
     313             : }
     314             : 
     315             : bool
     316           0 : cancelMessage(const std::string& accountId, uint64_t messageId)
     317             : {
     318           0 :     return {};
     319             : }
     320             : 
     321             : void
     322           5 : setIsComposing(const std::string& accountId, const std::string& conversationUri, bool isWriting)
     323             : {
     324           5 :     if (const auto acc = jami::Manager::instance().getAccount(accountId))
     325           5 :         acc->setIsComposing(conversationUri, isWriting);
     326           5 : }
     327             : 
     328             : bool
     329           2 : setMessageDisplayed(const std::string& accountId,
     330             :                     const std::string& conversationUri,
     331             :                     const std::string& messageId,
     332             :                     int status)
     333             : {
     334           2 :     if (const auto acc = jami::Manager::instance().getAccount(accountId))
     335           2 :         return acc->setMessageDisplayed(conversationUri, messageId, status);
     336           0 :     return false;
     337             : }
     338             : 
     339             : bool
     340           2 : exportOnRing(const std::string& accountId, const std::string& password)
     341             : {
     342           2 :     if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
     343           2 :         account->addDevice(password);
     344           2 :         return true;
     345           2 :     }
     346           0 :     return false;
     347             : }
     348             : 
     349             : bool
     350           0 : exportToFile(const std::string& accountId,
     351             :              const std::string& destinationPath,
     352             :              const std::string& scheme,
     353             :              const std::string& password)
     354             : {
     355           0 :     if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
     356           0 :         return account->exportArchive(destinationPath, scheme, password);
     357           0 :     }
     358           0 :     return false;
     359             : }
     360             : 
     361             : bool
     362           0 : revokeDevice(const std::string& accountId,
     363             :              const std::string& deviceId,
     364             :              const std::string& scheme,
     365             :              const std::string& password)
     366             : {
     367           0 :     if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
     368           0 :         return account->revokeDevice(deviceId, scheme, password);
     369           0 :     }
     370           0 :     return false;
     371             : }
     372             : 
     373             : std::map<std::string, std::string>
     374           0 : getKnownRingDevices(const std::string& accountId)
     375             : {
     376           0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     377           0 :         return acc->getKnownDevices();
     378           0 :     return {};
     379             : }
     380             : 
     381             : bool
     382           4 : changeAccountPassword(const std::string& accountId,
     383             :                       const std::string& password_old,
     384             :                       const std::string& password_new)
     385             : {
     386           4 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     387           4 :         return acc->changeArchivePassword(password_old, password_new);
     388           0 :     return false;
     389             : }
     390             : 
     391             : /* contacts */
     392             : 
     393             : void
     394           0 : addContact(const std::string& accountId, const std::string& uri)
     395             : {
     396           0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     397           0 :         return acc->addContact(uri);
     398             : }
     399             : 
     400             : void
     401           0 : removeContact(const std::string& accountId, const std::string& uri, bool ban)
     402             : {
     403           0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     404           0 :         return acc->removeContact(uri, ban);
     405             : }
     406             : 
     407             : std::map<std::string, std::string>
     408           0 : getContactDetails(const std::string& accountId, const std::string& uri)
     409             : {
     410           0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     411           0 :         return acc->getContactDetails(uri);
     412           0 :     return {};
     413             : }
     414             : 
     415             : std::vector<std::map<std::string, std::string>>
     416           0 : getContacts(const std::string& accountId)
     417             : {
     418           0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     419           0 :         return acc->getContacts();
     420           0 :     return {};
     421             : }
     422             : 
     423             : /* contact requests */
     424             : std::vector<std::map<std::string, std::string>>
     425           6 : getTrustRequests(const std::string& accountId)
     426             : {
     427           6 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     428           6 :         return acc->getTrustRequests();
     429           0 :     return {};
     430             : }
     431             : 
     432             : bool
     433           0 : acceptTrustRequest(const std::string& accountId, const std::string& from)
     434             : {
     435           0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     436           0 :         return acc->acceptTrustRequest(from);
     437           0 :     return false;
     438             : }
     439             : 
     440             : bool
     441           0 : discardTrustRequest(const std::string& accountId, const std::string& from)
     442             : {
     443           0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     444           0 :         return acc->discardTrustRequest(from);
     445           0 :     return false;
     446             : }
     447             : 
     448             : void
     449           0 : sendTrustRequest(const std::string& accountId,
     450             :                  const std::string& to,
     451             :                  const std::vector<uint8_t>& payload)
     452             : {
     453           0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     454           0 :         acc->sendTrustRequest(to, payload);
     455           0 : }
     456             : 
     457             : /// This function is used as a base for new accounts for clients that support it
     458             : std::map<std::string, std::string>
     459         249 : getAccountTemplate(const std::string& accountType)
     460             : {
     461         249 :     if (accountType == Account::ProtocolNames::JAMI || accountType == Account::ProtocolNames::RING)
     462         452 :         return jami::JamiAccountConfig().toMap();
     463          23 :     else if (accountType == Account::ProtocolNames::SIP)
     464          46 :         return jami::SipAccountConfig().toMap();
     465           0 :     return {};
     466             : }
     467             : 
     468             : std::string
     469           0 : addAccount(const std::map<std::string, std::string>& details, const std::string& accountId)
     470             : {
     471           0 :     return jami::Manager::instance().addAccount(details, accountId);
     472             : }
     473             : 
     474             : void
     475           0 : monitor(bool continuous)
     476             : {
     477           0 :     return jami::Manager::instance().monitor(continuous);
     478             : }
     479             : 
     480             : std::vector<std::map<std::string, std::string>>
     481           0 : getConnectionList(const std::string& accountId, const std::string& conversationId)
     482             : {
     483           0 :     return jami::Manager::instance().getConnectionList(accountId, conversationId);
     484             : }
     485             : 
     486             : std::vector<std::map<std::string, std::string>>
     487           0 : getChannelList(const std::string& accountId, const std::string& connectionId)
     488             : {
     489           0 :     return jami::Manager::instance().getChannelList(accountId, connectionId);
     490             : }
     491             : 
     492             : void
     493           0 : removeAccount(const std::string& accountId)
     494             : {
     495           0 :     return jami::Manager::instance().removeAccount(accountId, true); // with 'flush' enabled
     496             : }
     497             : 
     498             : std::vector<std::string>
     499           0 : getAccountList()
     500             : {
     501           0 :     return jami::Manager::instance().getAccountList();
     502             : }
     503             : 
     504             : /**
     505             :  * Send the list of all codecs loaded to the client through DBus.
     506             :  * Can stay global, as only the active codecs will be set per accounts
     507             :  */
     508             : std::vector<unsigned>
     509           0 : getCodecList()
     510             : {
     511             :     std::vector<unsigned> list {
     512           0 :         jami::getSystemCodecContainer()->getSystemCodecInfoIdList(jami::MEDIA_ALL)};
     513           0 :     if (list.empty())
     514           0 :         jami::emitSignal<ConfigurationSignal::Error>(CODECS_NOT_LOADED);
     515           0 :     return list;
     516           0 : }
     517             : 
     518             : std::vector<std::string>
     519           0 : getSupportedTlsMethod()
     520             : {
     521           0 :     return SIPAccount::getSupportedTlsProtocols();
     522             : }
     523             : 
     524             : std::vector<std::string>
     525           0 : getSupportedCiphers(const std::string& accountId)
     526             : {
     527           0 :     if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId))
     528           0 :         return SIPAccount::getSupportedTlsCiphers();
     529           0 :     JAMI_ERR("SIP account %s doesn't exist", accountId.c_str());
     530           0 :     return {};
     531             : }
     532             : 
     533             : bool
     534           0 : setCodecDetails(const std::string& accountId,
     535             :                 const unsigned& codecId,
     536             :                 const std::map<std::string, std::string>& details)
     537             : {
     538           0 :     auto acc = jami::Manager::instance().getAccount(accountId);
     539           0 :     if (!acc) {
     540           0 :         JAMI_ERR("Could not find account %s. can not set codec details", accountId.c_str());
     541           0 :         return false;
     542             :     }
     543             : 
     544           0 :     auto codec = acc->searchCodecById(codecId, jami::MEDIA_ALL);
     545           0 :     if (!codec) {
     546           0 :         JAMI_ERR("can not find codec %d", codecId);
     547           0 :         return false;
     548             :     }
     549             :     try {
     550           0 :         if (codec->mediaType & jami::MEDIA_AUDIO) {
     551           0 :             if (auto foundCodec = std::static_pointer_cast<jami::SystemAudioCodecInfo>(codec)) {
     552           0 :                 foundCodec->setCodecSpecifications(details);
     553           0 :                 jami::emitSignal<ConfigurationSignal::MediaParametersChanged>(accountId);
     554           0 :                 return true;
     555           0 :             }
     556             :         }
     557             : 
     558           0 :         if (codec->mediaType & jami::MEDIA_VIDEO) {
     559           0 :             if (auto foundCodec = std::static_pointer_cast<jami::SystemVideoCodecInfo>(codec)) {
     560           0 :                 foundCodec->setCodecSpecifications(details);
     561           0 :                 JAMI_WARN("parameters for %s changed ", foundCodec->name.c_str());
     562           0 :                 if (auto call = jami::Manager::instance().getCurrentCall()) {
     563           0 :                     if (call->getVideoCodec() == foundCodec) {
     564           0 :                         JAMI_WARN("%s running. Need to restart encoding", foundCodec->name.c_str());
     565           0 :                         call->restartMediaSender();
     566             :                     }
     567           0 :                 }
     568           0 :                 jami::emitSignal<ConfigurationSignal::MediaParametersChanged>(accountId);
     569           0 :                 return true;
     570           0 :             }
     571             :         }
     572           0 :     } catch (const std::exception& e) {
     573           0 :         JAMI_ERR("Cannot set codec specifications: %s", e.what());
     574           0 :     }
     575             : 
     576           0 :     return false;
     577           0 : }
     578             : 
     579             : std::map<std::string, std::string>
     580           0 : getCodecDetails(const std::string& accountId, const unsigned& codecId)
     581             : {
     582           0 :     auto acc = jami::Manager::instance().getAccount(accountId);
     583           0 :     if (!acc) {
     584           0 :         JAMI_ERR("Could not find account %s return default codec details", accountId.c_str());
     585           0 :         return jami::Account::getDefaultCodecDetails(codecId);
     586             :     }
     587             : 
     588           0 :     auto codec = acc->searchCodecById(codecId, jami::MEDIA_ALL);
     589           0 :     if (!codec) {
     590           0 :         jami::emitSignal<ConfigurationSignal::Error>(CODECS_NOT_LOADED);
     591           0 :         return {};
     592             :     }
     593             : 
     594           0 :     if (codec->mediaType & jami::MEDIA_AUDIO)
     595           0 :         if (auto foundCodec = std::static_pointer_cast<jami::SystemAudioCodecInfo>(codec))
     596           0 :             return foundCodec->getCodecSpecifications();
     597             : 
     598           0 :     if (codec->mediaType & jami::MEDIA_VIDEO)
     599           0 :         if (auto foundCodec = std::static_pointer_cast<jami::SystemVideoCodecInfo>(codec))
     600           0 :             return foundCodec->getCodecSpecifications();
     601             : 
     602           0 :     jami::emitSignal<ConfigurationSignal::Error>(CODECS_NOT_LOADED);
     603           0 :     return {};
     604           0 : }
     605             : 
     606             : std::vector<unsigned>
     607           0 : getActiveCodecList(const std::string& accountId)
     608             : {
     609           0 :     if (auto acc = jami::Manager::instance().getAccount(accountId))
     610           0 :         return acc->getActiveCodecs();
     611           0 :     JAMI_ERR("Could not find account %s, returning default", accountId.c_str());
     612           0 :     return jami::Account::getDefaultCodecsId();
     613             : }
     614             : 
     615             : void
     616           0 : setActiveCodecList(const std::string& accountId, const std::vector<unsigned>& list)
     617             : {
     618           0 :     if (auto acc = jami::Manager::instance().getAccount(accountId)) {
     619           0 :         acc->setActiveCodecs(list);
     620           0 :         jami::Manager::instance().saveConfig(acc);
     621             :     } else {
     622           0 :         JAMI_ERR("Could not find account %s", accountId.c_str());
     623           0 :     }
     624           0 : }
     625             : 
     626             : std::vector<std::string>
     627           0 : getAudioPluginList()
     628             : {
     629           0 :     return {PCM_DEFAULT, PCM_DMIX_DSNOOP};
     630             : }
     631             : 
     632             : void
     633           0 : setAudioPlugin(const std::string& audioPlugin)
     634             : {
     635           0 :     return jami::Manager::instance().setAudioPlugin(audioPlugin);
     636             : }
     637             : 
     638             : std::vector<std::string>
     639           0 : getAudioOutputDeviceList()
     640             : {
     641           0 :     return jami::Manager::instance().getAudioOutputDeviceList();
     642             : }
     643             : 
     644             : std::vector<std::string>
     645           0 : getAudioInputDeviceList()
     646             : {
     647           0 :     return jami::Manager::instance().getAudioInputDeviceList();
     648             : }
     649             : 
     650             : void
     651           0 : setAudioOutputDevice(int32_t index)
     652             : {
     653           0 :     return jami::Manager::instance().setAudioDevice(index, AudioDeviceType::PLAYBACK);
     654             : }
     655             : 
     656             : void
     657           0 : setAudioInputDevice(int32_t index)
     658             : {
     659           0 :     return jami::Manager::instance().setAudioDevice(index, AudioDeviceType::CAPTURE);
     660             : }
     661             : 
     662             : void
     663           0 : startAudio()
     664             : {
     665           0 :     jami::Manager::instance().startAudio();
     666           0 : }
     667             : 
     668             : void
     669           0 : setAudioRingtoneDevice(int32_t index)
     670             : {
     671           0 :     return jami::Manager::instance().setAudioDevice(index, AudioDeviceType::RINGTONE);
     672             : }
     673             : 
     674             : std::vector<std::string>
     675           0 : getCurrentAudioDevicesIndex()
     676             : {
     677           0 :     return jami::Manager::instance().getCurrentAudioDevicesIndex();
     678             : }
     679             : 
     680             : int32_t
     681           0 : getAudioInputDeviceIndex(const std::string& name)
     682             : {
     683           0 :     return jami::Manager::instance().getAudioInputDeviceIndex(name);
     684             : }
     685             : 
     686             : int32_t
     687           0 : getAudioOutputDeviceIndex(const std::string& name)
     688             : {
     689           0 :     return jami::Manager::instance().getAudioOutputDeviceIndex(name);
     690             : }
     691             : 
     692             : std::string
     693           0 : getCurrentAudioOutputPlugin()
     694             : {
     695           0 :     auto plugin = jami::Manager::instance().getCurrentAudioOutputPlugin();
     696           0 :     JAMI_DBG("Get audio plugin %s", plugin.c_str());
     697           0 :     return plugin;
     698           0 : }
     699             : 
     700             : std::string
     701           0 : getNoiseSuppressState()
     702             : {
     703           0 :     return jami::Manager::instance().getNoiseSuppressState();
     704             : }
     705             : 
     706             : void
     707           0 : setNoiseSuppressState(const std::string& state)
     708             : {
     709           0 :     jami::Manager::instance().setNoiseSuppressState(state);
     710           0 : }
     711             : 
     712             : bool
     713           0 : isAgcEnabled()
     714             : {
     715           0 :     return jami::Manager::instance().isAGCEnabled();
     716             : }
     717             : 
     718             : void
     719           0 : setAgcState(bool enabled)
     720             : {
     721           0 :     jami::Manager::instance().setAGCState(enabled);
     722           0 : }
     723             : 
     724             : std::string
     725           0 : getRecordPath()
     726             : {
     727           0 :     return jami::Manager::instance().audioPreference.getRecordPath();
     728             : }
     729             : 
     730             : void
     731           5 : setRecordPath(const std::string& recPath)
     732             : {
     733           5 :     jami::Manager::instance().audioPreference.setRecordPath(recPath);
     734           5 : }
     735             : 
     736             : bool
     737           0 : getIsAlwaysRecording()
     738             : {
     739           0 :     return jami::Manager::instance().getIsAlwaysRecording();
     740             : }
     741             : 
     742             : void
     743           6 : setIsAlwaysRecording(bool rec)
     744             : {
     745           6 :     jami::Manager::instance().setIsAlwaysRecording(rec);
     746           6 : }
     747             : 
     748             : bool
     749           0 : getRecordPreview()
     750             : {
     751             : #ifdef ENABLE_VIDEO
     752           0 :     return jami::Manager::instance().videoPreferences.getRecordPreview();
     753             : #else
     754             :     return false;
     755             : #endif
     756             : }
     757             : 
     758             : void
     759           0 : setRecordPreview(bool rec)
     760             : {
     761             : #ifdef ENABLE_VIDEO
     762           0 :     jami::Manager::instance().videoPreferences.setRecordPreview(rec);
     763           0 :     jami::Manager::instance().saveConfig();
     764             : #endif
     765           0 : }
     766             : 
     767             : int32_t
     768           0 : getRecordQuality()
     769             : {
     770             : #ifdef ENABLE_VIDEO
     771           0 :     return jami::Manager::instance().videoPreferences.getRecordQuality();
     772             : #else
     773             :     return 0;
     774             : #endif
     775             : }
     776             : 
     777             : void
     778           0 : setRecordQuality(int32_t quality)
     779             : {
     780             : #ifdef ENABLE_VIDEO
     781           0 :     jami::Manager::instance().videoPreferences.setRecordQuality(quality);
     782           0 :     jami::Manager::instance().saveConfig();
     783             : #endif
     784           0 : }
     785             : 
     786             : int32_t
     787           0 : getHistoryLimit()
     788             : {
     789           0 :     return jami::Manager::instance().getHistoryLimit();
     790             : }
     791             : 
     792             : void
     793           0 : setHistoryLimit(int32_t days)
     794             : {
     795           0 :     jami::Manager::instance().setHistoryLimit(days);
     796           0 : }
     797             : 
     798             : int32_t
     799           0 : getRingingTimeout()
     800             : {
     801           0 :     return jami::Manager::instance().getRingingTimeout();
     802             : }
     803             : 
     804             : void
     805           0 : setRingingTimeout(int32_t timeout)
     806             : {
     807           0 :     jami::Manager::instance().setRingingTimeout(timeout);
     808           0 : }
     809             : 
     810             : std::vector<std::string>
     811           0 : getSupportedAudioManagers()
     812             : {
     813           0 :     return jami::AudioPreference::getSupportedAudioManagers();
     814             : }
     815             : 
     816             : bool
     817           0 : setAudioManager(const std::string& api)
     818             : {
     819           0 :     return jami::Manager::instance().setAudioManager(api);
     820             : }
     821             : 
     822             : std::string
     823           0 : getAudioManager()
     824             : {
     825           0 :     return jami::Manager::instance().getAudioManager();
     826             : }
     827             : 
     828             : void
     829           0 : setVolume(const std::string& device, double value)
     830             : {
     831           0 :     if (auto audiolayer = jami::Manager::instance().getAudioDriver()) {
     832           0 :         JAMI_DBG("set volume for %s: %f", device.c_str(), value);
     833             : 
     834           0 :         if (device == "speaker")
     835           0 :             audiolayer->setPlaybackGain(value);
     836           0 :         else if (device == "mic")
     837           0 :             audiolayer->setCaptureGain(value);
     838             : 
     839           0 :         jami::emitSignal<ConfigurationSignal::VolumeChanged>(device, value);
     840             :     } else {
     841           0 :         JAMI_ERR("Audio layer not valid while updating volume");
     842           0 :     }
     843           0 : }
     844             : 
     845             : double
     846           0 : getVolume(const std::string& device)
     847             : {
     848           0 :     if (auto audiolayer = jami::Manager::instance().getAudioDriver()) {
     849           0 :         if (device == "speaker")
     850           0 :             return audiolayer->getPlaybackGain();
     851           0 :         if (device == "mic")
     852           0 :             return audiolayer->getCaptureGain();
     853           0 :     }
     854             : 
     855           0 :     JAMI_ERR("Audio layer not valid while updating volume");
     856           0 :     return 0.0;
     857             : }
     858             : 
     859             : // FIXME: we should store "muteDtmf" instead of "playDtmf"
     860             : // in config and avoid negating like this
     861             : bool
     862           0 : isDtmfMuted()
     863             : {
     864           0 :     return not jami::Manager::instance().voipPreferences.getPlayDtmf();
     865             : }
     866             : 
     867             : void
     868           0 : muteDtmf(bool mute)
     869             : {
     870           0 :     jami::Manager::instance().voipPreferences.setPlayDtmf(not mute);
     871           0 : }
     872             : 
     873             : bool
     874           0 : isCaptureMuted()
     875             : {
     876           0 :     if (auto audiolayer = jami::Manager::instance().getAudioDriver())
     877           0 :         return audiolayer->isCaptureMuted();
     878             : 
     879           0 :     JAMI_ERR("Audio layer not valid");
     880           0 :     return false;
     881             : }
     882             : 
     883             : void
     884           0 : muteCapture(bool mute)
     885             : {
     886           0 :     if (auto audiolayer = jami::Manager::instance().getAudioDriver())
     887           0 :         return audiolayer->muteCapture(mute);
     888             : 
     889           0 :     JAMI_ERR("Audio layer not valid");
     890           0 :     return;
     891             : }
     892             : 
     893             : bool
     894           0 : isPlaybackMuted()
     895             : {
     896           0 :     if (auto audiolayer = jami::Manager::instance().getAudioDriver())
     897           0 :         return audiolayer->isPlaybackMuted();
     898             : 
     899           0 :     JAMI_ERR("Audio layer not valid");
     900           0 :     return false;
     901             : }
     902             : 
     903             : void
     904           0 : mutePlayback(bool mute)
     905             : {
     906           0 :     if (auto audiolayer = jami::Manager::instance().getAudioDriver())
     907           0 :         return audiolayer->mutePlayback(mute);
     908             : 
     909           0 :     JAMI_ERR("Audio layer not valid");
     910           0 :     return;
     911             : }
     912             : 
     913             : bool
     914           0 : isRingtoneMuted()
     915             : {
     916           0 :     if (auto audiolayer = jami::Manager::instance().getAudioDriver())
     917           0 :         return audiolayer->isRingtoneMuted();
     918             : 
     919           0 :     JAMI_ERR("Audio layer not valid");
     920           0 :     return false;
     921             : }
     922             : 
     923             : void
     924           0 : muteRingtone(bool mute)
     925             : {
     926           0 :     if (auto audiolayer = jami::Manager::instance().getAudioDriver())
     927           0 :         return audiolayer->muteRingtone(mute);
     928             : 
     929           0 :     JAMI_ERR("Audio layer not valid");
     930           0 :     return;
     931             : }
     932             : 
     933             : void
     934           0 : setAccountsOrder(const std::string& order)
     935             : {
     936           0 :     jami::Manager::instance().setAccountsOrder(order);
     937           0 : }
     938             : 
     939             : std::string
     940           0 : getAddrFromInterfaceName(const std::string& interface)
     941             : {
     942           0 :     return dhtnet::ip_utils::getInterfaceAddr(interface, AF_INET);
     943             : }
     944             : 
     945             : std::vector<std::string>
     946           0 : getAllIpInterface()
     947             : {
     948           0 :     return dhtnet::ip_utils::getAllIpInterface();
     949             : }
     950             : 
     951             : std::vector<std::string>
     952           0 : getAllIpInterfaceByName()
     953             : {
     954           0 :     return dhtnet::ip_utils::getAllIpInterfaceByName();
     955             : }
     956             : 
     957             : std::vector<std::map<std::string, std::string>>
     958           0 : getCredentials(const std::string& accountId)
     959             : {
     960           0 :     if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId))
     961           0 :         return sipaccount->getCredentials();
     962           0 :     return {};
     963             : }
     964             : 
     965             : void
     966           0 : setCredentials(const std::string& accountId,
     967             :                const std::vector<std::map<std::string, std::string>>& details)
     968             : {
     969           0 :     if (auto sipaccount = jami::Manager::instance().getAccount<SIPAccount>(accountId)) {
     970           0 :         sipaccount->doUnregister([&](bool /* transport_free */) {
     971           0 :             sipaccount->editConfig(
     972           0 :                 [&](jami::SipAccountConfig& config) { config.setCredentials(details); });
     973           0 :             sipaccount->loadConfig();
     974           0 :             if (sipaccount->isEnabled())
     975           0 :                 sipaccount->doRegister();
     976           0 :         });
     977           0 :         jami::Manager::instance().saveConfig(sipaccount);
     978           0 :     }
     979           0 : }
     980             : 
     981             : void
     982           0 : connectivityChanged()
     983             : {
     984           0 :     JAMI_WARN("received connectivity changed - trying to re-connect enabled accounts");
     985             : 
     986             :     // reset the UPnP context
     987             : #if !(defined(TARGET_OS_IOS) && TARGET_OS_IOS)
     988             :     try {
     989           0 :         jami::Manager::instance().upnpContext()->connectivityChanged();
     990           0 :     } catch (std::runtime_error& e) {
     991           0 :         JAMI_ERR("UPnP context error: %s", e.what());
     992           0 :     }
     993             : #endif
     994             : 
     995           0 :     for (const auto& account : jami::Manager::instance().getAllAccounts()) {
     996           0 :         account->connectivityChanged();
     997           0 :     }
     998           0 : }
     999             : 
    1000             : bool
    1001           4 : lookupName(const std::string& account, const std::string& nameserver, const std::string& name)
    1002             : {
    1003             : #if HAVE_RINGNS
    1004           4 :     if (account.empty()) {
    1005           0 :         auto cb = [name](const std::string& result, jami::NameDirectory::Response response) {
    1006           0 :             jami::emitSignal<libjami::ConfigurationSignal::RegisteredNameFound>("",
    1007             :                                                                                 (int) response,
    1008             :                                                                                 result,
    1009           0 :                                                                                 name);
    1010           0 :         };
    1011           0 :         if (nameserver.empty())
    1012           0 :             jami::NameDirectory::lookupUri(name, "", cb);
    1013             :         else
    1014           0 :             jami::NameDirectory::instance(nameserver).lookupName(name, cb);
    1015           0 :         return true;
    1016           4 :     } else if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(account)) {
    1017           4 :         acc->lookupName(name);
    1018           4 :         return true;
    1019           4 :     }
    1020             : #endif
    1021           0 :     return false;
    1022             : }
    1023             : 
    1024             : bool
    1025           2 : lookupAddress(const std::string& account, const std::string& nameserver, const std::string& address)
    1026             : {
    1027             : #if HAVE_RINGNS
    1028           2 :     if (account.empty()) {
    1029           0 :         jami::NameDirectory::instance(nameserver)
    1030           0 :             .lookupAddress(address,
    1031           0 :                            [address](const std::string& result,
    1032             :                                      jami::NameDirectory::Response response) {
    1033           0 :                                jami::emitSignal<libjami::ConfigurationSignal::RegisteredNameFound>(
    1034           0 :                                    "", (int) response, address, result);
    1035           0 :                            });
    1036           0 :         return true;
    1037           2 :     } else if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(account)) {
    1038           2 :         acc->lookupAddress(address);
    1039           2 :         return true;
    1040           2 :     }
    1041             : #endif
    1042           0 :     return false;
    1043             : }
    1044             : 
    1045             : bool
    1046           0 : searchUser(const std::string& account, const std::string& query)
    1047             : {
    1048           0 :     if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(account)) {
    1049           0 :         return acc->searchUser(query);
    1050           0 :     }
    1051           0 :     return false;
    1052             : }
    1053             : 
    1054             : bool
    1055           1 : registerName(const std::string& account,
    1056             :              const std::string& name,
    1057             :              const std::string& scheme,
    1058             :              const std::string& password)
    1059             : {
    1060             : #if HAVE_RINGNS
    1061           1 :     if (auto acc = jami::Manager::instance().getAccount<JamiAccount>(account)) {
    1062           1 :         acc->registerName(name, scheme, password);
    1063           1 :         return true;
    1064           1 :     }
    1065             : #endif
    1066           0 :     return false;
    1067             : }
    1068             : 
    1069             : void
    1070           0 : setPushNotificationToken(const std::string& token)
    1071             : {
    1072           0 :     for (const auto& account : jami::Manager::instance().getAllAccounts()) {
    1073           0 :         account->setPushNotificationToken(token);
    1074           0 :     }
    1075           0 : }
    1076             : 
    1077             : void
    1078           0 : setPushNotificationTopic(const std::string& topic)
    1079             : {
    1080           0 :     for (const auto& account : jami::Manager::instance().getAllAccounts()) {
    1081           0 :         account->setPushNotificationTopic(topic);
    1082           0 :     }
    1083           0 : }
    1084             : 
    1085             : void
    1086           0 : setPushNotificationConfig(const std::map<std::string, std::string>& data)
    1087             : {
    1088           0 :     for (const auto& account : jami::Manager::instance().getAllAccounts()) {
    1089           0 :         account->setPushNotificationConfig(data);
    1090           0 :     }
    1091           0 : }
    1092             : 
    1093             : void
    1094           0 : pushNotificationReceived(const std::string& from, const std::map<std::string, std::string>& data)
    1095             : {
    1096             :     try {
    1097           0 :         auto it = data.find("to");
    1098           0 :         if (it != data.end()) {
    1099           0 :             if (auto account = jami::Manager::instance().getAccount<JamiAccount>(it->second))
    1100           0 :                 account->pushNotificationReceived(from, data);
    1101             :         }
    1102             : #if defined(__ANDROID__) || defined(ANDROID) || defined(__Apple__)
    1103             :         else {
    1104             :             for (const auto& sipAccount : jami::Manager::instance().getAllAccounts<SIPAccount>()) {
    1105             :                 sipAccount->pushNotificationReceived(from, data);
    1106             :             }
    1107             :         }
    1108             : #endif
    1109           0 :     } catch (const std::exception& e) {
    1110           0 :         JAMI_ERR("Error processing push notification: %s", e.what());
    1111           0 :     }
    1112           0 : }
    1113             : 
    1114             : bool
    1115           0 : isAudioMeterActive(const std::string& id)
    1116             : {
    1117           0 :     return jami::Manager::instance().getRingBufferPool().isAudioMeterActive(id);
    1118             : }
    1119             : 
    1120             : void
    1121           0 : setAudioMeterState(const std::string& id, bool state)
    1122             : {
    1123           0 :     jami::Manager::instance().getRingBufferPool().setAudioMeterState(id, state);
    1124           0 : }
    1125             : 
    1126             : void
    1127           0 : setDefaultModerator(const std::string& accountId, const std::string& peerURI, bool state)
    1128             : {
    1129           0 :     jami::Manager::instance().setDefaultModerator(accountId, peerURI, state);
    1130           0 : }
    1131             : 
    1132             : std::vector<std::string>
    1133           0 : getDefaultModerators(const std::string& accountId)
    1134             : {
    1135           0 :     return jami::Manager::instance().getDefaultModerators(accountId);
    1136             : }
    1137             : 
    1138             : void
    1139           0 : enableLocalModerators(const std::string& accountId, bool isModEnabled)
    1140             : {
    1141           0 :     jami::Manager::instance().enableLocalModerators(accountId, isModEnabled);
    1142           0 : }
    1143             : 
    1144             : bool
    1145           0 : isLocalModeratorsEnabled(const std::string& accountId)
    1146             : {
    1147           0 :     return jami::Manager::instance().isLocalModeratorsEnabled(accountId);
    1148             : }
    1149             : 
    1150             : void
    1151           0 : setAllModerators(const std::string& accountId, bool allModerators)
    1152             : {
    1153           0 :     jami::Manager::instance().setAllModerators(accountId, allModerators);
    1154           0 : }
    1155             : 
    1156             : bool
    1157           0 : isAllModerators(const std::string& accountId)
    1158             : {
    1159           0 :     return jami::Manager::instance().isAllModerators(accountId);
    1160             : }
    1161             : 
    1162             : } // namespace libjami

Generated by: LCOV version 1.14