/* * Copyright (c) 2010-2024 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ToolModel.hpp" #include "core/App.hpp" #include "core/path/Paths.hpp" #include "model/core/CoreModel.hpp" #include "tool/Utils.hpp" #include #include DEFINE_ABSTRACT_OBJECT(ToolModel) ToolModel::ToolModel(QObject *parent) { } ToolModel::~ToolModel() { } std::shared_ptr ToolModel::interpretUrl(const QString &address) { bool usePrefix = false; // TODO // CoreManager::getInstance()->getAccountSettingsModel()->getUseInternationalPrefixForCallsAndChats(); auto interpretedAddress = CoreModel::getInstance()->getCore()->interpretUrl(Utils::appStringToCoreString(address), usePrefix); if (!interpretedAddress) { // Try by removing scheme. QStringList splitted = address.split(":"); if (splitted.size() > 0 && splitted[0] == "sip") { splitted.removeFirst(); interpretedAddress = CoreModel::getInstance()->getCore()->interpretUrl( Utils::appStringToCoreString(splitted.join(":")), usePrefix); } } return interpretedAddress; } std::shared_ptr ToolModel::makeLinphoneNumber(const QString &label, const QString &number) { auto linphoneNumber = std::make_shared(nullptr); linphoneNumber->setLabel(Utils::appStringToCoreString(label)); linphoneNumber->setLabel(Utils::appStringToCoreString(number)); return linphoneNumber; } std::shared_ptr ToolModel::findAudioDevice(const QString &id) { std::string devId = Utils::appStringToCoreString(id); auto devices = CoreModel::getInstance()->getCore()->getExtendedAudioDevices(); auto audioDevice = find_if(devices.cbegin(), devices.cend(), [&](const std::shared_ptr &audioItem) { return audioItem->getId() == devId; }); if (audioDevice != devices.cend()) { return *audioDevice; } return nullptr; } QString ToolModel::getDisplayName(const std::shared_ptr &address) { QString displayName; if (address) { displayName = Utils::coreStringToAppString(address->getDisplayName()); if (displayName.isEmpty()) { displayName = Utils::coreStringToAppString(address->getUsername()); displayName.replace('.', ' '); } // TODO // std::shared_ptr cleanAddress = address->clone(); // cleanAddress->clean(); // QString qtAddress = Utils::coreStringToAppString(cleanAddress->asStringUriOnly()); // auto sipAddressEntry = getSipAddressEntry(qtAddress, cleanAddress); // displayName = sipAddressEntry->displayNames.get(); } return displayName; } QString ToolModel::getDisplayName(QString address) { mustBeInLinphoneThread(QString(gClassName) + " : " + Q_FUNC_INFO); QString displayName = getDisplayName(interpretUrl(address)); return displayName.isEmpty() ? address : displayName; } bool ToolModel::createCall(const QString &sipAddress, const QVariantMap &options, const QString &prepareTransfertAddress, const QHash &headers, linphone::MediaEncryption mediaEncryption, QString *errorMessage) { bool waitRegistrationForCall = true; // getSettingsModel()->getWaitRegistrationForCall() std::shared_ptr core = CoreModel::getInstance()->getCore(); bool cameraEnabled = options.contains("cameraEnabled") ? options["cameraEnabled"].toBool() : false; std::shared_ptr address = interpretUrl(sipAddress); if (!address) { qCritical() << "[" + QString(gClassName) + "] The calling address is not an interpretable SIP address: " << sipAddress; if (errorMessage) { *errorMessage = tr("The calling address is not an interpretable SIP address : "); errorMessage->append(sipAddress); } return false; } std::shared_ptr params = core->createCallParams(nullptr); params->enableVideo(true); params->setVideoDirection(cameraEnabled ? linphone::MediaDirection::SendRecv : linphone::MediaDirection::Inactive); params->setMediaEncryption(mediaEncryption); if (Utils::coreStringToAppString(params->getRecordFile()).isEmpty()) { params->setRecordFile( Paths::getCapturesDirPath() .append(Utils::generateSavedFilename(QString::fromStdString(address->getUsername()), "")) .append(".mkv") .toStdString()); } QHashIterator iterator(headers); while (iterator.hasNext()) { iterator.next(); params->addCustomHeader(Utils::appStringToCoreString(iterator.key()), Utils::appStringToCoreString(iterator.value())); } if (core->getDefaultAccount()) params->setAccount(core->getDefaultAccount()); auto call = core->inviteAddressWithParams(address, params); call->enableCamera(cameraEnabled); return call != nullptr; /* TODO transfer std::shared_ptr currentAccount = core->getDefaultAccount(); if (currentAccount) { if (!waitRegistrationForCall || currentAccount->getState() == linphone::RegistrationState::Ok) { qWarning() << "prepareTransfert not impolemented"; // CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress); } else { qWarning() << "Waiting registration not implemented"; // QObject *context = new QObject(); // QObject::connect( // CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::registrationStateChanged, context, // [address, core, params, currentAccount, prepareTransfertAddress, context]( // const std::shared_ptr &account, linphone::RegistrationState state) mutable { // if (context && account == currentAccount && state == linphone::RegistrationState::Ok) { // CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), // prepareTransfertAddress); // context->deleteLater(); // context = nullptr; // } // }); } } else qWarning() << "prepareTransfert not impolemented"; // CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress); */ } std::shared_ptr ToolModel::findAccount(const std::shared_ptr &address) { std::shared_ptr account; for (auto item : CoreModel::getInstance()->getCore()->getAccountList()) { if (item->getContactAddress()->weakEqual(address)) { account = item; break; } } return account; } bool ToolModel::isMe(const QString &address) { bool isMe = false; auto linAddr = ToolModel::interpretUrl(address); if (!CoreModel::getInstance()->getCore()->getDefaultAccount()) { // for (auto &account : CoreModel::getInstance()->getCore()->getAccountList()) { // if (account->getContactAddress()->weakEqual(linAddr)) return true; // } isMe = false; } else { auto accountAddr = CoreModel::getInstance()->getCore()->getDefaultAccount()->getContactAddress(); isMe = linAddr && accountAddr ? accountAddr->weakEqual(linAddr) : false; } return isMe; } bool ToolModel::isMe(const std::shared_ptr &address) { auto currentAccount = CoreModel::getInstance()->getCore()->getDefaultAccount(); if (!currentAccount) { // Default account is selected : Me is all local accounts. return findAccount(address) != nullptr; } else return address ? currentAccount->getContactAddress()->weakEqual(address) : false; } bool ToolModel::isLocal(const std::shared_ptr &conference, const std::shared_ptr &device) { auto deviceAddress = device->getAddress(); auto callAddress = conference->getMe()->getAddress(); auto gruuAddress = findAccount(callAddress)->getContactAddress(); return deviceAddress->equal(gruuAddress); }