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))); }
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))); }
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))); }