LCOV - code coverage report
Current view: top level - foo/src/client - callmanager.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 103 348 29.6 %
Date: 2026-02-28 10:41:24 Functions: 19 62 30.6 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2004-2026 Savoir-faire Linux Inc.
       3             :  *
       4             :  * This program is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 3 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with this program. If not, see <https://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include <vector>
      19             : #include <cstring>
      20             : 
      21             : #include "callmanager_interface.h"
      22             : #include "call_factory.h"
      23             : 
      24             : #include "sip/siptransport.h"
      25             : #include "sip/sipvoiplink.h"
      26             : #include "sip/sipcall.h"
      27             : #include "string_utils.h"
      28             : 
      29             : #include "logger.h"
      30             : #include "manager.h"
      31             : #include "jamidht/jamiaccount.h"
      32             : 
      33             : namespace libjami {
      34             : 
      35             : void
      36           0 : registerCallHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>& handlers)
      37             : {
      38           0 :     registerSignalHandlers(handlers);
      39           0 : }
      40             : 
      41             : std::string
      42           0 : placeCall(const std::string& accountId, const std::string& to)
      43             : {
      44             :     // TODO. Remove ASAP.
      45           0 :     JAMI_WARN("This API is deprecated, use placeCallWithMedia() instead");
      46           0 :     return placeCallWithMedia(accountId, to, {});
      47             : }
      48             : 
      49             : std::string
      50         106 : placeCallWithMedia(const std::string& accountId, const std::string& to, const std::vector<libjami::MediaMap>& mediaList)
      51             : {
      52             :     // Check if a destination number is available
      53         106 :     if (to.empty()) {
      54           0 :         JAMI_DBG("No number entered - Call aborted");
      55           0 :         return {};
      56             :     } else {
      57         106 :         return jami::Manager::instance().outgoingCall(accountId, to, mediaList);
      58             :     }
      59             : }
      60             : 
      61             : bool
      62          15 : requestMediaChange(const std::string& accountId,
      63             :                    const std::string& callId,
      64             :                    const std::vector<libjami::MediaMap>& mediaList)
      65             : {
      66          15 :     if (auto account = jami::Manager::instance().getAccount(accountId)) {
      67          15 :         if (auto call = account->getCall(callId)) {
      68          12 :             return call->requestMediaChange(mediaList);
      69           3 :         } else if (auto conf = account->getConference(callId)) {
      70           3 :             return conf->requestMediaChange(mediaList);
      71          18 :         }
      72          15 :     }
      73           0 :     return false;
      74             : }
      75             : 
      76             : bool
      77           1 : refuse(const std::string& accountId, const std::string& callId)
      78             : {
      79           1 :     return jami::Manager::instance().refuseCall(accountId, callId);
      80             : }
      81             : 
      82             : bool
      83           0 : accept(const std::string& accountId, const std::string& callId)
      84             : {
      85           0 :     return jami::Manager::instance().acceptCall(accountId, callId);
      86             : }
      87             : 
      88             : bool
      89           9 : acceptWithMedia(const std::string& accountId, const std::string& callId, const std::vector<libjami::MediaMap>& mediaList)
      90             : {
      91           9 :     return jami::Manager::instance().acceptCall(accountId, callId, mediaList);
      92             : }
      93             : 
      94             : bool
      95           2 : answerMediaChangeRequest(const std::string& accountId,
      96             :                          const std::string& callId,
      97             :                          const std::vector<libjami::MediaMap>& mediaList)
      98             : {
      99           2 :     if (auto account = jami::Manager::instance().getAccount(accountId))
     100           2 :         if (auto call = account->getCall(callId)) {
     101             :             try {
     102           2 :                 call->answerMediaChangeRequest(mediaList);
     103           2 :                 return true;
     104           0 :             } catch (const std::runtime_error& e) {
     105           0 :                 JAMI_ERR("%s", e.what());
     106           0 :             }
     107           4 :         }
     108           0 :     return false;
     109             : }
     110             : 
     111             : bool
     112          11 : hangUp(const std::string& accountId, const std::string& callId)
     113             : {
     114          11 :     return jami::Manager::instance().hangupCall(accountId, callId);
     115             : }
     116             : 
     117             : bool
     118           0 : hangUpConference(const std::string& accountId, const std::string& confId)
     119             : {
     120           0 :     return jami::Manager::instance().hangupConference(accountId, confId);
     121             : }
     122             : 
     123             : bool
     124           2 : hold(const std::string& accountId, const std::string& callId)
     125             : {
     126           2 :     return jami::Manager::instance().holdCall(accountId, callId);
     127             : }
     128             : 
     129             : bool
     130           2 : resume(const std::string& accountId, const std::string& callId)
     131             : {
     132           2 :     return jami::Manager::instance().resumeCall(accountId, callId);
     133             : }
     134             : 
     135             : bool
     136           0 : muteLocalMedia(const std::string& accountId, const std::string& callId, const std::string& mediaType, bool mute)
     137             : {
     138           0 :     if (auto account = jami::Manager::instance().getAccount(accountId)) {
     139           0 :         if (auto call = account->getCall(callId)) {
     140           0 :             JAMI_DBG("Muting [%s] for call %s", mediaType.c_str(), callId.c_str());
     141           0 :             call->muteMedia(mediaType, mute);
     142           0 :             return true;
     143           0 :         } else if (auto conf = account->getConference(callId)) {
     144           0 :             JAMI_DEBUG("[conf:{}] Muting local host [{}]", callId, mediaType);
     145           0 :             conf->muteLocalHost(mute, mediaType);
     146           0 :             return true;
     147             :         } else {
     148           0 :             JAMI_WARNING("ID {} doesn't match any call or conference", callId);
     149           0 :         }
     150           0 :     }
     151           0 :     return false;
     152             : }
     153             : 
     154             : bool
     155           1 : transfer(const std::string& accountId, const std::string& callId, const std::string& to)
     156             : {
     157           1 :     return jami::Manager::instance().transferCall(accountId, callId, to);
     158             : }
     159             : 
     160             : bool
     161           0 : attendedTransfer(const std::string& accountId, const std::string& transferID, const std::string& targetID)
     162             : {
     163           0 :     if (auto account = jami::Manager::instance().getAccount(accountId))
     164           0 :         if (auto call = account->getCall(transferID))
     165           0 :             return call->attendedTransfer(targetID);
     166           0 :     return false;
     167             : }
     168             : 
     169             : bool
     170           0 : joinParticipant(const std::string& accountId,
     171             :                 const std::string& sel_callId,
     172             :                 const std::string& account2Id,
     173             :                 const std::string& drag_callId)
     174             : {
     175           0 :     return jami::Manager::instance().joinParticipant(accountId, sel_callId, account2Id, drag_callId);
     176             : }
     177             : 
     178             : void
     179           0 : createConfFromParticipantList(const std::string& accountId, const std::vector<std::string>& participants)
     180             : {
     181           0 :     jami::Manager::instance().createConfFromParticipantList(accountId, participants);
     182           0 : }
     183             : 
     184             : void
     185           0 : setConferenceLayout(const std::string& accountId, const std::string& confId, uint32_t layout)
     186             : {
     187           0 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     188           0 :         if (auto conf = account->getConference(confId)) {
     189           0 :             conf->setLayout(static_cast<int>(layout));
     190           0 :         } else if (auto call = account->getCall(confId)) {
     191           0 :             Json::Value root;
     192           0 :             root["layout"] = layout;
     193           0 :             call->sendConfOrder(root);
     194           0 :         }
     195           0 :     }
     196           0 : }
     197             : 
     198             : bool
     199           0 : isConferenceParticipant(const std::string& accountId, const std::string& callId)
     200             : {
     201           0 :     if (auto account = jami::Manager::instance().getAccount(accountId))
     202           0 :         if (auto call = account->getCall(callId))
     203           0 :             return call->isConferenceParticipant();
     204           0 :     return false;
     205             : }
     206             : 
     207             : bool
     208           0 : addParticipant(const std::string& accountId,
     209             :                const std::string& callId,
     210             :                const std::string& account2Id,
     211             :                const std::string& confId)
     212             : {
     213           0 :     return jami::Manager::instance().addSubCall(accountId, callId, account2Id, confId);
     214             : }
     215             : 
     216             : bool
     217           0 : addMainParticipant(const std::string& accountId, const std::string& confId)
     218             : {
     219           0 :     return jami::Manager::instance().addMainParticipant(accountId, confId);
     220             : }
     221             : 
     222             : bool
     223           0 : detachLocalParticipant()
     224             : {
     225           0 :     return jami::Manager::instance().detachHost();
     226             : }
     227             : 
     228             : bool
     229           0 : detachParticipant(const std::string&, const std::string& callId)
     230             : {
     231           0 :     return jami::Manager::instance().detachParticipant(callId);
     232             : }
     233             : 
     234             : bool
     235           0 : joinConference(const std::string& accountId,
     236             :                const std::string& sel_confId,
     237             :                const std::string& account2Id,
     238             :                const std::string& drag_confId)
     239             : {
     240           0 :     return jami::Manager::instance().joinConference(accountId, sel_confId, account2Id, drag_confId);
     241             : }
     242             : 
     243             : bool
     244           0 : holdConference(const std::string& accountId, const std::string& confId)
     245             : {
     246           0 :     return jami::Manager::instance().holdConference(accountId, confId);
     247             : }
     248             : 
     249             : bool
     250           0 : resumeConference(const std::string& accountId, const std::string& confId)
     251             : {
     252           0 :     return jami::Manager::instance().resumeConference(accountId, confId);
     253             : }
     254             : 
     255             : std::map<std::string, std::string>
     256           0 : getConferenceDetails(const std::string& accountId, const std::string& confId)
     257             : {
     258           0 :     if (const auto account = jami::Manager::instance().getAccount(accountId))
     259           0 :         if (auto conf = account->getConference(confId))
     260             :             return {{"ID", confId},
     261           0 :                     {"STATE", conf->getStateStr()},
     262             : #ifdef ENABLE_VIDEO
     263           0 :                     {"VIDEO_SOURCE", conf->getVideoInput()},
     264             : #endif
     265           0 :                     {"RECORDING", conf->isRecording() ? jami::TRUE_STR : jami::FALSE_STR}};
     266           0 :     return {};
     267             : }
     268             : 
     269             : std::vector<std::map<std::string, std::string>>
     270           0 : currentMediaList(const std::string& accountId, const std::string& callId)
     271             : {
     272           0 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     273           0 :         if (auto call = account->getCall(callId)) {
     274           0 :             return call->currentMediaList();
     275           0 :         } else if (auto conf = account->getConference(callId)) {
     276           0 :             return conf->currentMediaList();
     277           0 :         }
     278           0 :     }
     279           0 :     JAMI_WARN("Call not found %s", callId.c_str());
     280           0 :     return {};
     281             : }
     282             : 
     283             : std::vector<std::string>
     284           4 : getConferenceList(const std::string& accountId)
     285             : {
     286           4 :     if (const auto account = jami::Manager::instance().getAccount(accountId))
     287           4 :         return account->getConferenceList();
     288           0 :     return {};
     289             : }
     290             : 
     291             : std::vector<std::string>
     292           4 : getParticipantList(const std::string& accountId, const std::string& confId)
     293             : {
     294           4 :     if (const auto account = jami::Manager::instance().getAccount(accountId))
     295           4 :         if (auto conf = account->getConference(confId)) {
     296           4 :             const auto& subcalls(conf->getSubCalls());
     297           4 :             return {subcalls.begin(), subcalls.end()};
     298          12 :         }
     299           0 :     return {};
     300             : }
     301             : 
     302             : std::string
     303           0 : getConferenceId(const std::string& accountId, const std::string& callId)
     304             : {
     305           0 :     if (const auto account = jami::Manager::instance().getAccount(accountId))
     306           0 :         if (auto call = account->getCall(callId))
     307           0 :             if (auto conf = call->getConference())
     308           0 :                 return conf->getConfId();
     309           0 :     return {};
     310             : }
     311             : 
     312             : bool
     313           0 : startRecordedFilePlayback(const std::string& filepath)
     314             : {
     315           0 :     return jami::Manager::instance().startRecordedFilePlayback(filepath);
     316             : }
     317             : 
     318             : void
     319           0 : stopRecordedFilePlayback()
     320             : {
     321           0 :     jami::Manager::instance().stopRecordedFilePlayback();
     322           0 : }
     323             : 
     324             : bool
     325           4 : toggleRecording(const std::string& accountId, const std::string& callId)
     326             : {
     327           4 :     return jami::Manager::instance().toggleRecordingCall(accountId, callId);
     328             : }
     329             : 
     330             : void
     331           0 : setRecording(const std::string& accountId, const std::string& callId)
     332             : {
     333           0 :     toggleRecording(accountId, callId);
     334           0 : }
     335             : 
     336             : void
     337           0 : recordPlaybackSeek(double value)
     338             : {
     339           0 :     jami::Manager::instance().recordingPlaybackSeek(value);
     340           0 : }
     341             : 
     342             : bool
     343           0 : getIsRecording(const std::string& accountId, const std::string& callId)
     344             : {
     345           0 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     346           0 :         if (auto call = account->getCall(callId)) {
     347           0 :             return call->isRecording();
     348           0 :         } else if (auto conf = account->getConference(callId)) {
     349           0 :             return conf->isRecording();
     350           0 :         }
     351           0 :     }
     352           0 :     return false;
     353             : }
     354             : 
     355             : std::map<std::string, std::string>
     356         346 : getCallDetails(const std::string& accountId, const std::string& callId)
     357             : {
     358         346 :     if (const auto account = jami::Manager::instance().getAccount(accountId))
     359         346 :         if (auto call = account->getCall(callId))
     360         692 :             return call->getDetails();
     361           0 :     return {};
     362             : }
     363             : 
     364             : std::vector<std::string>
     365           0 : getCallList()
     366             : {
     367           0 :     return jami::Manager::instance().getCallList();
     368             : }
     369             : 
     370             : std::vector<std::string>
     371           0 : getCallList(const std::string& accountId)
     372             : {
     373           0 :     if (accountId.empty())
     374           0 :         return jami::Manager::instance().getCallList();
     375           0 :     else if (const auto account = jami::Manager::instance().getAccount(accountId))
     376           0 :         return account->getCallList();
     377           0 :     JAMI_WARN("Unknown account: %s", accountId.c_str());
     378           0 :     return {};
     379             : }
     380             : 
     381             : std::vector<std::map<std::string, std::string>>
     382           0 : getConferenceInfos(const std::string& accountId, const std::string& confId)
     383             : {
     384           0 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     385           0 :         if (auto conf = account->getConference(confId))
     386           0 :             return conf->getConferenceInfos();
     387           0 :         else if (auto call = account->getCall(confId))
     388           0 :             return call->getConferenceInfos();
     389           0 :     }
     390           0 :     return {};
     391             : }
     392             : 
     393             : void
     394           0 : playDTMF(const std::string& key)
     395             : {
     396           0 :     auto code = key.data()[0];
     397           0 :     jami::Manager::instance().playDtmf(code);
     398             : 
     399           0 :     if (auto current_call = jami::Manager::instance().getCurrentCall())
     400           0 :         current_call->carryingDTMFdigits(code);
     401           0 : }
     402             : 
     403             : void
     404           0 : startTone(int32_t start, int32_t type)
     405             : {
     406           0 :     if (start) {
     407           0 :         if (type == 0)
     408           0 :             jami::Manager::instance().playTone();
     409             :         else
     410           0 :             jami::Manager::instance().playToneWithMessage();
     411             :     } else
     412           0 :         jami::Manager::instance().stopTone();
     413           0 : }
     414             : 
     415             : bool
     416           1 : switchInput(const std::string& accountId, const std::string& callId, const std::string& resource)
     417             : {
     418           1 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     419           0 :         if (auto conf = account->getConference(callId)) {
     420           0 :             conf->switchInput(resource);
     421           0 :             return true;
     422           0 :         } else if (auto call = account->getCall(callId)) {
     423           0 :             call->switchInput(resource);
     424           0 :             return true;
     425           0 :         }
     426           1 :     }
     427           1 :     return false;
     428             : }
     429             : 
     430             : void
     431           0 : sendTextMessage(const std::string& accountId,
     432             :                 const std::string& callId,
     433             :                 const std::map<std::string, std::string>& messages,
     434             :                 const std::string& from,
     435             :                 bool isMixed)
     436             : {
     437           0 :     jami::runOnMainThread([accountId, callId, messages, from, isMixed] {
     438           0 :         jami::Manager::instance().sendCallTextMessage(accountId, callId, messages, from, isMixed);
     439           0 :     });
     440           0 : }
     441             : 
     442             : void
     443           1 : setModerator(const std::string& accountId, const std::string& confId, const std::string& peerId, const bool& state)
     444             : {
     445           1 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     446           1 :         if (auto conf = account->getConference(confId)) {
     447           1 :             conf->setModerator(peerId, state);
     448             :         } else {
     449           0 :             JAMI_WARNING("[conf:{}] Failed to change moderator {} (conference not found)", confId, peerId);
     450           1 :         }
     451           1 :     }
     452           1 : }
     453             : 
     454             : void
     455           0 : muteParticipant(const std::string& accountId, const std::string& confId, const std::string& peerId, const bool& state)
     456             : {
     457           0 :     JAMI_ERROR("muteParticipant is deprecated, please use muteStream");
     458           0 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     459           0 :         if (auto conf = account->getConference(confId)) {
     460           0 :             conf->muteParticipant(peerId, state);
     461           0 :         } else if (auto call = account->getCall(confId)) {
     462           0 :             Json::Value root;
     463           0 :             root["muteParticipant"] = peerId;
     464           0 :             root["muteState"] = state ? jami::TRUE_STR : jami::FALSE_STR;
     465           0 :             call->sendConfOrder(root);
     466           0 :         }
     467           0 :     }
     468           0 : }
     469             : 
     470             : void
     471           4 : muteStream(const std::string& accountId,
     472             :            const std::string& confId,
     473             :            const std::string& accountUri,
     474             :            const std::string& deviceId,
     475             :            const std::string& streamId,
     476             :            const bool& state)
     477             : {
     478           4 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     479           4 :         if (auto conf = account->getConference(confId)) {
     480           3 :             conf->muteStream(accountUri, deviceId, streamId, state);
     481           1 :         } else if (auto call = account->getCall(confId)) {
     482           0 :             if (call->conferenceProtocolVersion() == 1) {
     483           0 :                 Json::Value sinkVal;
     484           0 :                 sinkVal["muteAudio"] = state;
     485           0 :                 Json::Value mediasObj;
     486           0 :                 mediasObj[streamId] = sinkVal;
     487           0 :                 Json::Value deviceVal;
     488           0 :                 deviceVal["medias"] = mediasObj;
     489           0 :                 Json::Value deviceObj;
     490           0 :                 deviceObj[deviceId] = deviceVal;
     491           0 :                 Json::Value accountVal;
     492           0 :                 deviceVal["devices"] = deviceObj;
     493           0 :                 Json::Value root;
     494           0 :                 root[accountUri] = deviceVal;
     495           0 :                 root["version"] = 1;
     496           0 :                 call->sendConfOrder(root);
     497           0 :             } else if (call->conferenceProtocolVersion() == 0) {
     498           0 :                 Json::Value root;
     499           0 :                 root["muteParticipant"] = accountUri;
     500           0 :                 root["muteState"] = state ? jami::TRUE_STR : jami::FALSE_STR;
     501           0 :                 call->sendConfOrder(root);
     502           0 :             }
     503           5 :         }
     504           4 :     }
     505           4 : }
     506             : 
     507             : void
     508           0 : setActiveParticipant(const std::string& accountId, const std::string& confId, const std::string& participant)
     509             : {
     510           0 :     JAMI_ERR() << "setActiveParticipant is deprecated, please use setActiveStream";
     511           0 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     512           0 :         if (auto conf = account->getConference(confId)) {
     513           0 :             conf->setActiveParticipant(participant);
     514           0 :         } else if (auto call = account->getCall(confId)) {
     515           0 :             Json::Value root;
     516           0 :             root["activeParticipant"] = participant;
     517           0 :             call->sendConfOrder(root);
     518           0 :         }
     519           0 :     }
     520           0 : }
     521             : 
     522             : void
     523           2 : setActiveStream(const std::string& accountId,
     524             :                 const std::string& confId,
     525             :                 const std::string& accountUri,
     526             :                 const std::string& deviceId,
     527             :                 const std::string& streamId,
     528             :                 const bool& state)
     529             : {
     530           2 :     if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
     531           2 :         if (auto conf = account->getConference(confId)) {
     532           1 :             conf->setActiveStream(streamId, state);
     533           2 :         } else if (auto call = std::static_pointer_cast<jami::SIPCall>(account->getCall(confId))) {
     534           0 :             call->setActiveMediaStream(accountUri, deviceId, streamId, state);
     535           3 :         }
     536           2 :     }
     537           2 : }
     538             : 
     539             : void
     540           2 : hangupParticipant(const std::string& accountId,
     541             :                   const std::string& confId,
     542             :                   const std::string& accountUri,
     543             :                   const std::string& deviceId)
     544             : {
     545           2 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     546           2 :         if (auto conf = account->getConference(confId)) {
     547           1 :             conf->hangupParticipant(accountUri, deviceId);
     548           2 :         } else if (auto call = std::static_pointer_cast<jami::SIPCall>(account->getCall(confId))) {
     549           0 :             if (call->conferenceProtocolVersion() == 1) {
     550           0 :                 Json::Value deviceVal;
     551           0 :                 deviceVal["hangup"] = jami::TRUE_STR;
     552           0 :                 Json::Value deviceObj;
     553           0 :                 deviceObj[deviceId] = deviceVal;
     554           0 :                 Json::Value accountVal;
     555           0 :                 deviceVal["devices"] = deviceObj;
     556           0 :                 Json::Value root;
     557           0 :                 root[accountUri] = deviceVal;
     558           0 :                 root["version"] = 1;
     559           0 :                 call->sendConfOrder(root);
     560           0 :             } else if (call->conferenceProtocolVersion() == 0) {
     561           0 :                 Json::Value root;
     562           0 :                 root["hangupParticipant"] = accountUri;
     563           0 :                 call->sendConfOrder(root);
     564           0 :             }
     565           3 :         }
     566           2 :     }
     567           2 : }
     568             : 
     569             : void
     570           0 : raiseParticipantHand(const std::string& accountId,
     571             :                      const std::string& confId,
     572             :                      const std::string& peerId,
     573             :                      const bool& state)
     574             : {
     575           0 :     JAMI_ERR() << "raiseParticipantHand is deprecated, please use raiseHand";
     576           0 :     if (const auto account = jami::Manager::instance().getAccount(accountId)) {
     577           0 :         if (auto conf = account->getConference(confId)) {
     578           0 :             if (auto call = std::static_pointer_cast<jami::SIPCall>(conf->getCallFromPeerID(peerId))) {
     579           0 :                 if (auto* transport = call->getTransport())
     580           0 :                     conf->setHandRaised(std::string(transport->deviceId()), state);
     581           0 :             }
     582           0 :         } else if (auto call = account->getCall(confId)) {
     583           0 :             Json::Value root;
     584           0 :             root["handRaised"] = peerId;
     585           0 :             root["handState"] = state ? jami::TRUE_STR : jami::FALSE_STR;
     586           0 :             call->sendConfOrder(root);
     587           0 :         }
     588           0 :     }
     589           0 : }
     590             : 
     591             : void
     592           9 : raiseHand(const std::string& accountId,
     593             :           const std::string& confId,
     594             :           const std::string& accountUri,
     595             :           const std::string& deviceId,
     596             :           const bool& state)
     597             : {
     598           9 :     if (const auto account = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
     599           9 :         if (auto conf = account->getConference(confId)) {
     600           2 :             auto device = deviceId;
     601           2 :             if (device.empty())
     602           0 :                 device = std::string(account->currentDeviceId());
     603           2 :             conf->setHandRaised(device, state);
     604          16 :         } else if (auto call = std::static_pointer_cast<jami::SIPCall>(account->getCall(confId))) {
     605           6 :             if (call->conferenceProtocolVersion() == 1) {
     606           6 :                 Json::Value deviceVal;
     607           6 :                 deviceVal["raiseHand"] = state;
     608           6 :                 Json::Value deviceObj;
     609           6 :                 std::string device = deviceId.empty() ? std::string(account->currentDeviceId()) : deviceId;
     610           6 :                 deviceObj[device] = deviceVal;
     611           6 :                 Json::Value accountVal;
     612           6 :                 deviceVal["devices"] = deviceObj;
     613           6 :                 Json::Value root;
     614           6 :                 std::string uri = accountUri.empty() ? account->getUsername() : accountUri;
     615           6 :                 root[uri] = deviceVal;
     616           6 :                 root["version"] = 1;
     617           6 :                 call->sendConfOrder(root);
     618           6 :             } else if (call->conferenceProtocolVersion() == 0) {
     619           0 :                 Json::Value root;
     620           0 :                 root["handRaised"] = account->getUsername();
     621           0 :                 root["handState"] = state ? jami::TRUE_STR : jami::FALSE_STR;
     622           0 :                 call->sendConfOrder(root);
     623           0 :             }
     624          16 :         }
     625           9 :     }
     626           9 : }
     627             : 
     628             : } // namespace libjami

Generated by: LCOV version 1.14