Try to handle both fetch-config and call in the same command #LINQT-2306

This commit is contained in:
Gaelle Braud 2026-02-03 17:45:16 +01:00
parent ca4380bfd0
commit c4602541f4
3 changed files with 49 additions and 17 deletions

View file

@ -782,17 +782,20 @@ void App::initCore() {
if (mIsRestarting) {
if (CoreModel::getInstance()->mConfigStatus == linphone::ConfiguringState::Failed) {
QMetaObject::invokeMethod(thread(), [this]() {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
auto message = CoreModel::getInstance()->mConfigMessage;
//: not reachable
if (message.isEmpty()) message = tr("configuration_error_detail");
mustBeInMainThread(log().arg(Q_FUNC_INFO));
lWarning() << log().arg("Configuration failed (reason: %1)").arg(message);
//: Error
Utils::showInformationPopup(
tr("info_popup_error_title"),
//: Remote provisioning failed : %1
tr("info_popup_configuration_failed_message").arg(message), false);
});
} else {
} else if (CoreModel::getInstance()->mConfigStatus ==
linphone::ConfiguringState::Successful) {
lInfo() << log().arg("Configuration succeed");
mPossiblyLookForAddedAccount = true;
if (mAccountList && mAccountList->getCount() > 0) {
auto defaultConnected =
@ -805,7 +808,7 @@ void App::initCore() {
}
}
checkForUpdate();
mIsRestarting = false;
setIsRestarting(false);
window->show();
window->requestActivate();
@ -1045,7 +1048,7 @@ void App::restart() {
FriendsManager::getInstance()->clearMaps();
CoreModel::getInstance()->getCore()->stop();
mCoreModelConnection->invokeToCore([this]() {
mIsRestarting = true;
setIsRestarting(true);
if (mAccountList) mAccountList->resetData();
if (mCallList) mCallList->resetData();
if (mCallHistoryList) mCallHistoryList->resetData();
@ -1151,6 +1154,17 @@ void App::setCoreStarted(bool started) {
}
}
bool App::isRestarting() const {
return mIsRestarting;
}
void App::setIsRestarting(bool restarting) {
if (mIsRestarting != restarting) {
mIsRestarting = restarting;
emit isRestartingChanged(mIsRestarting);
}
}
static QObject *findParentWindow(QObject *item) {
return !item || item->isWindowType() ? item : findParentWindow(item->parent());
}

View file

@ -147,6 +147,9 @@ public:
bool getCoreStarted() const;
void setCoreStarted(bool started);
bool isRestarting() const;
void setIsRestarting(bool restarting);
QQuickWindow *getCallsWindow();
void handleAccountActivity(QSharedPointer<AccountCore> accountCore);
Q_INVOKABLE void handleAppActivity();
@ -212,6 +215,7 @@ public:
signals:
void mainWindowChanged();
void coreStartedChanged(bool coreStarted);
void isRestartingChanged(bool restarting);
void accountsChanged();
void defaultAccountChanged();
void callsChanged();

View file

@ -85,7 +85,7 @@ std::shared_ptr<CliModel> CliModel::getInstance() {
// FIXME: Do not accept args without value like: cmd toto.
// In the future `toto` could be a boolean argument.
QRegularExpression
CliModel::mRegExpArgs("(?:(?:([\\w-]+)\\s*)=\\s*(?:\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|([^\\s]+)\\s*))");
CliModel::mRegExpArgs("(?:(?:([\\w-]+)\\s*)(?:=|\\s)(?:\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|([^\\s]+)\\s*))");
QRegularExpression CliModel::mRegExpFunctionName("^\\s*([a-z-]+)\\s*");
QString CliModel::parseFunctionName(const QString &command, bool isOptional) {
@ -106,6 +106,7 @@ QString CliModel::parseFunctionName(const QString &command, bool isOptional) {
return QString("");
}
lDebug() << QStringLiteral("Function parsed : %1").arg(functionName);
return functionName;
}
@ -249,11 +250,11 @@ void CliModel::Command::execute(QHash<QString, QString> &args, CliModel *parent)
// Check missing arguments.
for (const auto &argName : mArgsScheme.keys()) {
if (!mArgsScheme[argName].isOptional && (!args.contains(argName) || args[argName].isEmpty())) {
qWarning() << QStringLiteral("Missing argument for command: `%1 (%2)`.").arg(mFunctionName).arg(argName);
qWarning() << QStringLiteral("Missing argument for command: '%1' (%2).").arg(mFunctionName).arg(argName);
return;
}
}
qDebug() << "Execute";
qDebug() << "Execute" << mFunctionName;
(parent->*mFunction)(args);
/*
// Execute!
@ -280,17 +281,26 @@ void CliModel::Command::execute(QHash<QString, QString> &args, CliModel *parent)
void CliModel::Command::executeUri(QString address, QHash<QString, QString> args, CliModel *parent) {
QUrl url(address);
QString query = url.query();
lDebug() << QStringLiteral("CliModel : execute uri : %1").arg(query);
QStringList parameters = query.split('&');
for (int i = 0; i < parameters.size(); ++i) {
QStringList parameter = parameters[i].split('=');
if (parameter[0] != "" && parameter[0] != "method") {
if (parameter.size() > 1) args[parameter[0]] = QByteArray::fromBase64(parameter[1].toUtf8());
else args[parameter[0]] = "";
lDebug() << QStringLiteral("CliModel : Detecting parameter : %1").arg(parameter[0]);
QHash<QString, QString> args = parent->parseArgs(parameters[i]);
for (auto it = args.begin(); it != args.end(); ++it) {
auto subfonction = parent->parseFunctionName(it.key(), true);
if (!subfonction.isEmpty()) {
QHash<QString, QString> arg;
arg[it.key()] = QByteArray::fromBase64(it.value().toUtf8());
lDebug() << "parsing parameters" << it.key() << it.value();
parent->addProcess(ProcessCommand(mCommands[it.key()], arg, 1, parent));
}
}
}
args["sip-address"] = address;
args["sip-address"] = address.left(address.indexOf('?'));
lDebug() << "CliModel: getting sip address " << args["sip-address"];
parent->addProcess(ProcessCommand(*this, args, 0, parent));
}
@ -373,7 +383,10 @@ void CliModel::executeCommand(const QString &command) { //, CommandFormat *forma
{QString("sip"), "sip-" + QString(EXECUTABLE_NAME).toLower(), QString("sips"),
"sips-" + QString(EXECUTABLE_NAME).toLower(), QString(EXECUTABLE_NAME).toLower() + "-sip",
QString(EXECUTABLE_NAME).toLower() + "-sips", QString("tel"), QString("callto"), configURI})
if (scheme == validScheme) ok = true;
if (scheme == validScheme) {
ok = true;
break;
}
if (!ok) {
qWarning()
<< QStringLiteral("Not a valid URI: `%1` Unsupported scheme: `%2`.").arg(command).arg(scheme);
@ -399,16 +412,17 @@ void CliModel::executeCommand(const QString &command) { //, CommandFormat *forma
addProcess(ProcessCommand(mCommands["fetch-config"], arg, 5, this));
} else {
std::shared_ptr<linphone::Address> address;
QString qAddress = transformedCommand;
QString qAddress = transformedCommand; //.left(transformedCommand.indexOf('?'));
if (Utils::isUsername(transformedCommand)) {
address = linphone::Factory::get()->createAddress(
Utils::appStringToCoreString(transformedCommand + "@to.remove"));
address->setDomain("");
qAddress = Utils::coreStringToAppString(address->asString());
if (address && qAddress.isEmpty()) qAddress = transformedCommand;
} else
} else {
address = linphone::Factory::get()->createAddress(
Utils::appStringToCoreString(transformedCommand)); // Test if command is an address
Utils::appStringToCoreString(qAddress)); // Test if command is an address
}
// if (format) *format = UriFormat;
lInfo() << log().arg("Detecting URI command: `%1`…").arg(command);
QString functionName;
@ -427,6 +441,7 @@ void CliModel::executeCommand(const QString &command) { //, CommandFormat *forma
if (functionName.isEmpty()) functionName = "call";
}
}
functionName = functionName.toLower();
if (functionName.isEmpty()) {
lWarning() << log().arg("There is no method set in `%1`.").arg(command);
@ -438,7 +453,6 @@ void CliModel::executeCommand(const QString &command) { //, CommandFormat *forma
QHash<QString, QString> headers;
if (address) {
// TODO: check if there is too much headers.
for (const auto &argName : mCommands[functionName].mArgsScheme.keys()) {
const std::string header = address->getHeader(Utils::appStringToCoreString(argName));
headers[argName] = QByteArray::fromBase64(QByteArray(header.c_str(), int(header.length())));
@ -466,4 +480,4 @@ void CliModel::runProcess() {
void CliModel::resetProcesses() {
mQueue.clear();
}
}