LCOV - code coverage report
Current view: top level - src/client - configurationmanager.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 52 534 9.7 %
Date: 2024-12-21 08:56:24 Functions: 13 128 10.2 %

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

Generated by: LCOV version 1.14