1 /*
2  * AccountSettingsModel.cpp
3  * Copyright (C) 2017  Belledonne Communications, Grenoble, France
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  *  Created on: February 2, 2017
20  *      Author: Ronan Abhamon
21  */
22 
23 #include "../../app/paths/Paths.hpp"
24 #include "../../utils/Utils.hpp"
25 #include "../core/CoreManager.hpp"
26 
27 #include "AccountSettingsModel.hpp"
28 
29 using namespace std;
30 
31 // =============================================================================
32 
mapLinphoneRegistrationStateToUi(linphone::RegistrationState state)33 inline AccountSettingsModel::RegistrationState mapLinphoneRegistrationStateToUi (linphone::RegistrationState state) {
34   switch (state) {
35     case linphone::RegistrationStateNone:
36     case linphone::RegistrationStateCleared:
37     case linphone::RegistrationStateFailed:
38       return AccountSettingsModel::RegistrationStateNotRegistered;
39 
40     case linphone::RegistrationStateProgress:
41       return AccountSettingsModel::RegistrationStateInProgress;
42 
43     case linphone::RegistrationStateOk:
44       break;
45   }
46 
47   return AccountSettingsModel::RegistrationStateRegistered;
48 }
49 
50 // -----------------------------------------------------------------------------
51 
AccountSettingsModel(QObject * parent)52 AccountSettingsModel::AccountSettingsModel (QObject *parent) : QObject(parent) {
53   QObject::connect(
54     CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::registrationStateChanged,
55     this, &AccountSettingsModel::handleRegistrationStateChanged
56   );
57 }
58 
59 // -----------------------------------------------------------------------------
60 
addOrUpdateProxyConfig(const shared_ptr<linphone::ProxyConfig> & proxyConfig)61 bool AccountSettingsModel::addOrUpdateProxyConfig (const shared_ptr<linphone::ProxyConfig> &proxyConfig) {
62   Q_CHECK_PTR(proxyConfig);
63 
64   shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
65 
66   list<shared_ptr<linphone::ProxyConfig> > proxyConfigs = core->getProxyConfigList();
67   if (find(proxyConfigs.cbegin(), proxyConfigs.cend(), proxyConfig) != proxyConfigs.cend()) {
68     if (proxyConfig->done() == -1) {
69       qWarning() << QStringLiteral("Unable to update proxy config: `%1`.")
70         .arg(::Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asString()));
71       return false;
72     }
73   } else if (core->addProxyConfig(proxyConfig) == -1) {
74     qWarning() << QStringLiteral("Unable to add proxy config: `%1`.")
75       .arg(::Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asString()));
76     return false;
77   }
78 
79   emit accountSettingsUpdated();
80 
81   return true;
82 }
83 
getProxyConfigDescription(const shared_ptr<linphone::ProxyConfig> & proxyConfig)84 QVariantMap AccountSettingsModel::getProxyConfigDescription (const shared_ptr<linphone::ProxyConfig> &proxyConfig) {
85   Q_CHECK_PTR(proxyConfig);
86 
87   QVariantMap map;
88 
89   {
90     const shared_ptr<const linphone::Address> address = proxyConfig->getIdentityAddress();
91     map["sipAddress"] = address
92       ? ::Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asStringUriOnly())
93       : QString("");
94   }
95 
96   map["serverAddress"] = ::Utils::coreStringToAppString(proxyConfig->getServerAddr());
97   map["registrationDuration"] = proxyConfig->getPublishExpires();
98   map["transport"] = ::Utils::coreStringToAppString(proxyConfig->getTransport());
99   map["route"] = ::Utils::coreStringToAppString(proxyConfig->getRoute());
100   map["contactParams"] = ::Utils::coreStringToAppString(proxyConfig->getContactParameters());
101   map["avpfInterval"] = proxyConfig->getAvpfRrInterval();
102   map["registerEnabled"] = proxyConfig->registerEnabled();
103   map["publishPresence"] = proxyConfig->publishEnabled();
104   map["avpfEnabled"] = proxyConfig->getAvpfMode() == linphone::AVPFMode::AVPFModeEnabled;
105   map["registrationState"] = ::mapLinphoneRegistrationStateToUi(proxyConfig->getState());
106 
107   return map;
108 }
109 
setDefaultProxyConfig(const shared_ptr<linphone::ProxyConfig> & proxyConfig)110 void AccountSettingsModel::setDefaultProxyConfig (const shared_ptr<linphone::ProxyConfig> &proxyConfig) {
111   CoreManager::getInstance()->getCore()->setDefaultProxyConfig(proxyConfig);
112   emit accountSettingsUpdated();
113 }
114 
removeProxyConfig(const shared_ptr<linphone::ProxyConfig> & proxyConfig)115 void AccountSettingsModel::removeProxyConfig (const shared_ptr<linphone::ProxyConfig> &proxyConfig) {
116   Q_CHECK_PTR(proxyConfig);
117 
118   CoreManager::getInstance()->getCore()->removeProxyConfig(proxyConfig);
119   emit accountSettingsUpdated();
120 }
121 
addOrUpdateProxyConfig(const shared_ptr<linphone::ProxyConfig> & proxyConfig,const QVariantMap & data)122 bool AccountSettingsModel::addOrUpdateProxyConfig (
123   const shared_ptr<linphone::ProxyConfig> &proxyConfig,
124   const QVariantMap &data
125 ) {
126   Q_CHECK_PTR(proxyConfig);
127 
128   QString literal = data["sipAddress"].toString();
129 
130   // Sip address.
131   {
132     shared_ptr<linphone::Address> address = linphone::Factory::get()->createAddress(
133         ::Utils::appStringToCoreString(literal)
134       );
135     if (!address) {
136       qWarning() << QStringLiteral("Unable to create sip address object from: `%1`.").arg(literal);
137       return false;
138     }
139 
140     if (proxyConfig->setIdentityAddress(address)) {
141       qWarning() << QStringLiteral("Unable to set identity address: `%1`.")
142         .arg(::Utils::coreStringToAppString(address->asStringUriOnly()));
143       return false;
144     }
145   }
146 
147   // Server address.
148   {
149     QString serverAddress = data["serverAddress"].toString();
150 
151     if (proxyConfig->setServerAddr(::Utils::appStringToCoreString(serverAddress))) {
152       qWarning() << QStringLiteral("Unable to add server address: `%1`.").arg(serverAddress);
153       return false;
154     }
155   }
156 
157   proxyConfig->setPublishExpires(data["registrationDuration"].toInt());
158   proxyConfig->setRoute(::Utils::appStringToCoreString(data["route"].toString()));
159   proxyConfig->setContactParameters(::Utils::appStringToCoreString(data["contactParams"].toString()));
160   proxyConfig->setAvpfRrInterval(static_cast<uint8_t>(data["avpfInterval"].toInt()));
161   proxyConfig->enableRegister(data["registerEnabled"].toBool());
162   proxyConfig->enablePublish(data["publishPresence"].toBool());
163   proxyConfig->setAvpfMode(data["avpfEnabled"].toBool()
164     ? linphone::AVPFMode::AVPFModeEnabled
165     : linphone::AVPFMode::AVPFModeDefault
166   );
167 
168   return addOrUpdateProxyConfig(proxyConfig);
169 }
170 
createProxyConfig()171 shared_ptr<linphone::ProxyConfig> AccountSettingsModel::createProxyConfig () {
172   shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
173 
174   core->getConfig()->loadFromXmlFile(
175     Paths::getAssistantConfigDirPath() + "create-linphone-sip-account.rc"
176   );
177 
178   return core->createProxyConfig();
179 }
180 
addAuthInfo(const shared_ptr<linphone::AuthInfo> & authInfo,const QString & password,const QString & userId)181 void AccountSettingsModel::addAuthInfo (
182   const shared_ptr<linphone::AuthInfo> &authInfo,
183   const QString &password,
184   const QString &userId
185 ) {
186   authInfo->setPasswd(::Utils::appStringToCoreString(password));
187   authInfo->setUserid(::Utils::appStringToCoreString(userId));
188 
189   CoreManager::getInstance()->getCore()->addAuthInfo(authInfo);
190 }
191 
eraseAllPasswords()192 void AccountSettingsModel::eraseAllPasswords () {
193   CoreManager::getInstance()->getCore()->clearAllAuthInfo();
194 }
195 
196 // -----------------------------------------------------------------------------
197 
getUsername() const198 QString AccountSettingsModel::getUsername () const {
199   shared_ptr<const linphone::Address> address = getUsedSipAddress();
200   const string displayName = address->getDisplayName();
201 
202   return ::Utils::coreStringToAppString(
203     displayName.empty() ? address->getUsername() : displayName
204   );
205 }
206 
setUsername(const QString & username)207 void AccountSettingsModel::setUsername (const QString &username) {
208   shared_ptr<const linphone::Address> address = getUsedSipAddress();
209   shared_ptr<linphone::Address> newAddress = address->clone();
210 
211   if (newAddress->setDisplayName(::Utils::appStringToCoreString(username))) {
212     qWarning() << QStringLiteral("Unable to set displayName on sip address: `%1`.")
213       .arg(::Utils::coreStringToAppString(newAddress->asStringUriOnly()));
214   } else {
215     setUsedSipAddress(newAddress);
216   }
217 
218   emit accountSettingsUpdated();
219 }
220 
getSipAddress() const221 QString AccountSettingsModel::getSipAddress () const {
222   return ::Utils::coreStringToAppString(getUsedSipAddress()->asStringUriOnly());
223 }
224 
getRegistrationState() const225 AccountSettingsModel::RegistrationState AccountSettingsModel::getRegistrationState () const {
226   shared_ptr<linphone::ProxyConfig> proxyConfig = CoreManager::getInstance()->getCore()->getDefaultProxyConfig();
227   return proxyConfig ? ::mapLinphoneRegistrationStateToUi(proxyConfig->getState()) : RegistrationStateNotRegistered;
228 }
229 
230 // -----------------------------------------------------------------------------
231 
getPrimaryUsername() const232 QString AccountSettingsModel::getPrimaryUsername () const {
233   return ::Utils::coreStringToAppString(
234     CoreManager::getInstance()->getCore()->getPrimaryContactParsed()->getUsername()
235   );
236 }
237 
setPrimaryUsername(const QString & username)238 void AccountSettingsModel::setPrimaryUsername (const QString &username) {
239   shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
240   shared_ptr<linphone::Address> primary = core->getPrimaryContactParsed();
241 
242   primary->setUsername(
243     username.isEmpty() ? "linphone" : ::Utils::appStringToCoreString(username)
244   );
245   core->setPrimaryContact(primary->asString());
246 
247   emit accountSettingsUpdated();
248 }
249 
getPrimaryDisplayName() const250 QString AccountSettingsModel::getPrimaryDisplayName () const {
251   return ::Utils::coreStringToAppString(
252     CoreManager::getInstance()->getCore()->getPrimaryContactParsed()->getDisplayName()
253   );
254 }
255 
setPrimaryDisplayName(const QString & displayName)256 void AccountSettingsModel::setPrimaryDisplayName (const QString &displayName) {
257   shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
258   shared_ptr<linphone::Address> primary = core->getPrimaryContactParsed();
259 
260   primary->setDisplayName(::Utils::appStringToCoreString(displayName));
261   core->setPrimaryContact(primary->asString());
262 
263   emit accountSettingsUpdated();
264 }
265 
getPrimarySipAddress() const266 QString AccountSettingsModel::getPrimarySipAddress () const {
267   return ::Utils::coreStringToAppString(
268     CoreManager::getInstance()->getCore()->getPrimaryContactParsed()->asString()
269   );
270 }
271 
272 // -----------------------------------------------------------------------------
273 
getAccounts() const274 QVariantList AccountSettingsModel::getAccounts () const {
275   shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
276   QVariantList accounts;
277 
278   {
279     QVariantMap account;
280     account["sipAddress"] = ::Utils::coreStringToAppString(core->getPrimaryContactParsed()->asStringUriOnly());
281     accounts << account;
282   }
283 
284   for (const auto &proxyConfig : core->getProxyConfigList()) {
285     QVariantMap account;
286     account["sipAddress"] = ::Utils::coreStringToAppString(proxyConfig->getIdentityAddress()->asStringUriOnly());
287     account["proxyConfig"].setValue(proxyConfig);
288     accounts << account;
289   }
290 
291   return accounts;
292 }
293 
294 // -----------------------------------------------------------------------------
295 
setUsedSipAddress(const shared_ptr<const linphone::Address> & address)296 void AccountSettingsModel::setUsedSipAddress (const shared_ptr<const linphone::Address> &address) {
297   shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
298   shared_ptr<linphone::ProxyConfig> proxyConfig = core->getDefaultProxyConfig();
299 
300   proxyConfig ? proxyConfig->setIdentityAddress(address) : core->setPrimaryContact(address->asString());
301 }
302 
getUsedSipAddress() const303 shared_ptr<const linphone::Address> AccountSettingsModel::getUsedSipAddress () const {
304   shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
305   shared_ptr<linphone::ProxyConfig> proxyConfig = core->getDefaultProxyConfig();
306 
307   return proxyConfig ? proxyConfig->getIdentityAddress() : core->getPrimaryContactParsed();
308 }
309 
310 // -----------------------------------------------------------------------------
311 
handleRegistrationStateChanged(const shared_ptr<linphone::ProxyConfig> &,linphone::RegistrationState)312 void AccountSettingsModel::handleRegistrationStateChanged (
313   const shared_ptr<linphone::ProxyConfig> &,
314   linphone::RegistrationState
315 ) {
316   emit accountSettingsUpdated();
317 }
318