summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/erebos/pairing.h4
-rw-r--r--src/pairing.cpp30
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<void(const Peer &)> RequestInitHook;
void onRequestInit(RequestInitHook);
- typedef function<future<bool>(const Peer &, string)> ConfirmHook;
+ typedef function<future<bool>(const Peer &, string, future<bool> &&)> ConfirmHook;
void onResponse(ConfirmHook);
void onRequest(ConfirmHook);
@@ -72,6 +73,7 @@ private:
StatePhase phase;
vector<uint8_t> nonce;
vector<uint8_t> peerCheck;
+ promise<bool> success;
};
map<Peer, State> 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<uint8_t> & digest)
void PairingServiceBase::waitForConfirmation(Peer peer, string confirm)
{
ConfirmHook hook;
+ future<bool> 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<LocalState> & 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);
+ }
}
}