From be1319577af4bf5545ee645ae61e385d95a969f9 Mon Sep 17 00:00:00 2001 From: Melvin Keskin Date: Wed, 26 Oct 2022 21:55:08 +0200 Subject: OmemoManagerPrivate: Fix device setup --- src/omemo/QXmppOmemoManager_p.cpp | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'src/omemo/QXmppOmemoManager_p.cpp') diff --git a/src/omemo/QXmppOmemoManager_p.cpp b/src/omemo/QXmppOmemoManager_p.cpp index d85c8a7a..18e0d34d 100644 --- a/src/omemo/QXmppOmemoManager_p.cpp +++ b/src/omemo/QXmppOmemoManager_p.cpp @@ -620,24 +620,44 @@ QFuture ManagerPrivate::setUpDeviceId() auto future = pubSubManager->requestPepItemIds(ns_omemo_2_bundles); await(future, q, [=](QXmppPubSubManager::ItemIdsResult result) mutable { - if (auto error = std::get_if(&result)) { - warning("Existing / Published device IDs could not be retrieved"); + // There can be the following cases: + // 1. There is no PubSub node for device bundles: XEP-0030 states that a server must + // respond with an error (at least ejabberd 22.05 responds with an empty node instead). + // 2. There is an empty PubSub node for device bundles: XEP-0030 states that a server must + // respond with a node without included items. + if (auto error = std::get_if(&result); error && !(error->type() == Error::Cancel && error->condition() == Error::ItemNotFound)) { + warning("Existing / Published device IDs could not be retrieved: " % errorToString(*error)); reportFinishedResult(interface, false); } else { - const auto &deviceIds = std::get>(result); - - while (true) { - uint32_t deviceId = 0; + auto generateDeviceId = [this, interface](uint32_t &deviceId) mutable -> bool { if (signal_protocol_key_helper_generate_registration_id(&deviceId, 0, globalContext.get()) < 0) { warning("Device ID could not be generated"); reportFinishedResult(interface, false); - break; + return false; } - if (!deviceIds.contains(QString::number(deviceId))) { + return true; + }; + + // The first generated device ID can be used if no device bundle node exists. + // Otherwise, duplicates must be avoided. + if (error) { + uint32_t deviceId = 0; + if (generateDeviceId(deviceId)) { ownDevice.id = deviceId; reportFinishedResult(interface, true); - break; + } + } else { + const auto &deviceIds = std::get>(result); + + while (true) { + uint32_t deviceId = 0; + + if (generateDeviceId(deviceId) && !deviceIds.contains(QString::number(deviceId))) { + ownDevice.id = deviceId; + reportFinishedResult(interface, true); + break; + } } } } -- cgit v1.2.3