From 3f4272c2e1e495cb6874b80169229504955be5dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Sat, 13 Feb 2021 22:12:12 +0100 Subject: Pairing: provide future to signal pairing success --- include/erebos/pairing.h | 4 +++- src/pairing.cpp | 30 +++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/include/erebos/pairing.h b/include/erebos/pairing.h index f0952d8..4457426 100644 --- a/include/erebos/pairing.h +++ b/include/erebos/pairing.h @@ -17,6 +17,7 @@ using std::function; using std::future; using std::map; using std::mutex; +using std::promise; using std::string; using std::variant; using std::vector; @@ -31,7 +32,7 @@ public: typedef function RequestInitHook; void onRequestInit(RequestInitHook); - typedef function(const Peer &, string)> ConfirmHook; + typedef function(const Peer &, string, future &&)> ConfirmHook; void onResponse(ConfirmHook); void onRequest(ConfirmHook); @@ -72,6 +73,7 @@ private: StatePhase phase; vector nonce; vector peerCheck; + promise success; }; map peerStates; diff --git a/src/pairing.cpp b/src/pairing.cpp index 9e161df..4ae215b 100644 --- a/src/pairing.cpp +++ b/src/pairing.cpp @@ -98,7 +98,10 @@ void PairingServiceBase::handle(Context & ctx) if (check != state.peerCheck) { if (requestNonceFailedHook) requestNonceFailedHook(ctx.peer()); - state.phase = StatePhase::PairingFailed; + if (state.phase < StatePhase::PairingDone) { + state.phase = StatePhase::PairingFailed; + state.success.set_value(false); + } return; } @@ -113,10 +116,18 @@ void PairingServiceBase::handle(Context & ctx) state.phase = StatePhase::PeerRequestConfirm; } + else if (auto decline = rec->item("decline").asText()) { + if (state.phase < StatePhase::PairingDone) { + state.phase = StatePhase::PairingFailed; + state.success.set_value(false); + } + } + else { if (state.phase == StatePhase::OurRequestReady) { handlePairingResult(ctx); state.phase = StatePhase::PairingDone; + state.success.set_value(true); } else { result = ctx.ref(); } @@ -171,6 +182,7 @@ string PairingServiceBase::confirmationNumber(const vector & digest) void PairingServiceBase::waitForConfirmation(Peer peer, string confirm) { ConfirmHook hook; + future success; { lock_guard lock(stateLock); auto & state = peerStates.try_emplace(peer, State()).first->second; @@ -178,9 +190,11 @@ void PairingServiceBase::waitForConfirmation(Peer peer, string confirm) hook = responseHook; if (state.phase == StatePhase::PeerRequestConfirm) hook = requestHook; + + success = state.success.get_future(); } - bool ok = hook(peer, confirm).get(); + bool ok = hook(peer, confirm, std::move(success)).get(); lock_guard lock(stateLock); auto & state = peerStates.try_emplace(peer, State()).first->second; @@ -191,22 +205,28 @@ void PairingServiceBase::waitForConfirmation(Peer peer, string confirm) peer.server().localHead().update([&] (const Stored & local) { Service::Context ctx(new Service::Context::Priv { .ref = *result, - .peer = peer, - .local = local, + .peer = peer, + .local = local, }); handlePairingResult(ctx); return ctx.local(); }); state.phase = StatePhase::PairingDone; + state.success.set_value(true); } else { state.phase = StatePhase::OurRequestReady; } } else if (state.phase == StatePhase::PeerRequestConfirm) { peer.send(uuid(), handlePairingCompleteRef(peer)); state.phase = StatePhase::PairingDone; + state.success.set_value(true); } } else { - state.phase = StatePhase::PairingFailed; + if (state.phase != StatePhase::PairingFailed) { + peer.send(uuid(), Object(Record({{ "decline", string() }}))); + state.phase = StatePhase::PairingFailed; + state.success.set_value(false); + } } } -- cgit v1.2.3