Example #1
0
void RemoteSync::syncConnected(WP::err code)
{
    if (code != WP::kOk)
        return;

    QString branch = fDatabase->branch();
    QString lastSyncCommit = fDatabase->getLastSyncCommit(fRemoteStorage->getUid(), branch);

    QByteArray outData;
    ProtocolOutStream outStream(&outData);

    IqOutStanza *iqStanza = new IqOutStanza(kGet);
    outStream.pushStanza(iqStanza);

    OutStanza *syncStanza = new OutStanza("sync_pull");
    syncStanza->addAttribute("branch", branch);
    syncStanza->addAttribute("base", lastSyncCommit);

    outStream.pushChildStanza(syncStanza);

    outStream.flush();

    if (fServerReply != NULL)
        fServerReply->disconnect();
    fServerReply = fRemoteConnection->send(outData);
    connect(fServerReply, SIGNAL(finished(WP::err)), this, SLOT(syncReply(WP::err)));
}
Example #2
0
void RemoteSync::syncReply(WP::err code)
{
    if (code != WP::kOk)
        return;

    QByteArray data = fServerReply->readAll();
    fServerReply = NULL;

    IqInStanzaHandler iqHandler(kResult);
    SyncPullData syncPullData;
    SyncPullHandler *syncPullHandler = new SyncPullHandler(&syncPullData);
    iqHandler.addChildHandler(syncPullHandler);

    ProtocolInStream inStream(data);
    inStream.addHandler(&iqHandler);

    inStream.parse();

    QString localBranch = fDatabase->branch();
    QString localTipCommit = fDatabase->getTip();
    QString lastSyncCommit = fDatabase->getLastSyncCommit(fRemoteStorage->getUid(), localBranch);

    if (!syncPullHandler->hasBeenHandled() || syncPullData.branch != localBranch) {
        // error occured, the server should at least send back the branch name
        // TODO better error message
        emit syncFinished(WP::kBadValue);
        return;
    }
    if (syncPullData.tip == localTipCommit) {
        // done
        emit syncFinished(WP::kOk);
        return;
    }
    // see if the server is ahead by checking if we got packages
    if (syncPullData.pack.size() != 0) {
        fSyncUid = syncPullData.tip;
        WP::err error = fDatabase->importPack(syncPullData.pack, lastSyncCommit,
                                              syncPullData.tip);
        if (error != WP::kOk) {
            emit syncFinished(error);
            return;
        }

        localTipCommit = fDatabase->getTip();
        // done? otherwise it was a merge and we have to push our merge
        if (localTipCommit == lastSyncCommit) {
            emit syncFinished(WP::kOk);
            return;
        }
    }

    // we are ahead of the server: push changes to the server
    QByteArray pack;
    WP::err error = fDatabase->exportPack(pack, lastSyncCommit, localTipCommit, fSyncUid);
    if (error != WP::kOk) {
        emit syncFinished(error);
        return;
    }
    fSyncUid = localTipCommit;

    QByteArray outData;
    ProtocolOutStream outStream(&outData);

    IqOutStanza *iqStanza = new IqOutStanza(kSet);
    outStream.pushStanza(iqStanza);
    OutStanza *pushStanza = new OutStanza("sync_push");
    pushStanza->addAttribute("branch", localBranch);
    pushStanza->addAttribute("start_commit", syncPullData.tip);
    pushStanza->addAttribute("last_commit", localTipCommit);
    outStream.pushChildStanza(pushStanza);
    OutStanza *pushPackStanza = new OutStanza("pack");
    pushPackStanza->setText(pack.toBase64());
    outStream.pushChildStanza(pushPackStanza);

    outStream.flush();

    fServerReply = fRemoteConnection->send(outData);
    connect(fServerReply, SIGNAL(finished(WP::err)), this, SLOT(syncPushReply(WP::err)));
}
Example #3
0
void MailMessenger::authConnected(WP::err error)
{
    if (error == WP::kContactNeeded) {
        startContactRequest();
        return;
    } else if (error != WP::kOk) {
        emit jobDone(error);
        return;
    }

    MessageChannelRef targetMessageChannel = MessageChannelRef();
    if (message->getChannel().staticCast<MessageChannel>()->isNewLocale()) {
        targetMessageChannel = MessageChannelRef(
            new MessageChannel(message->getChannel().staticCast<MessageChannel>(), targetContact,
                                              targetContact->getKeys()->getMainKeyId()));
    }

    QByteArray data;
    ProtocolOutStream outStream(&data);
    IqOutStanza *iqStanza = new IqOutStanza(kSet);
    outStream.pushStanza(iqStanza);

    Contact *myself = userIdentity->getMyself();
    OutStanza *messageStanza =  new OutStanza("put_message");
    messageStanza->addAttribute("server_user", targetUser);
    messageStanza->addAttribute("channel", message->getChannel()->getUid());
    outStream.pushChildStanza(messageStanza);

    QString signatureKeyId = myself->getKeys()->getMainKeyId();

    // write new channel
    if (targetMessageChannel != NULL) {
        error = XMLSecureParcel::write(&outStream, myself, signatureKeyId,
                                       targetMessageChannel.data(), "channel");
        if (error != WP::kOk) {
            emit jobDone(error);
            return;
        }
    }

    // write new channel info
    MessageChannelInfoRef info = message->getChannelInfo();
    if (info->isNewLocale()) {
        error = XMLSecureParcel::write(&outStream, myself, signatureKeyId, info.data(),
                                       "channel_info");
        if (error != WP::kOk) {
            emit jobDone(error);
            return;
        }
    }

    // write message
    error = XMLSecureParcel::write(&outStream, myself, signatureKeyId, message.data(), "message");
    if (error != WP::kOk) {
        emit jobDone(error);
        return;
    }

    outStream.flush();

    message = MessageRef();

    serverReply = remoteConnection->send(data);
    connect(serverReply, SIGNAL(finished(WP::err)), this, SLOT(handleReply(WP::err)));
}