diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2021-01-24 22:46:48 +0100 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2021-01-29 22:28:01 +0100 |
commit | a16b33031c7bcf2eabf1e0c3571000234b7740df (patch) | |
tree | f012ff7814abe7fa22c5a610388faf4310d53772 /include/erebos/pairing.h | |
parent | 3a3cce8eed7e43faa8c9f606e56bb43ba3bd9451 (diff) |
Attach service
Diffstat (limited to 'include/erebos/pairing.h')
-rw-r--r-- | include/erebos/pairing.h | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/include/erebos/pairing.h b/include/erebos/pairing.h new file mode 100644 index 0000000..f0952d8 --- /dev/null +++ b/include/erebos/pairing.h @@ -0,0 +1,104 @@ +#pragma once + +#include <erebos/identity.h> +#include <erebos/network.h> +#include <erebos/service.h> + +#include <future> +#include <map> +#include <mutex> +#include <string> +#include <variant> +#include <vector> + +namespace erebos { + +using std::function; +using std::future; +using std::map; +using std::mutex; +using std::string; +using std::variant; +using std::vector; + +/** + * Template-less base class for the paring functionality that does not depend + * on the result parameter. + */ +class PairingServiceBase : public Service +{ +public: + typedef function<void(const Peer &)> RequestInitHook; + void onRequestInit(RequestInitHook); + + typedef function<future<bool>(const Peer &, string)> ConfirmHook; + void onResponse(ConfirmHook); + void onRequest(ConfirmHook); + + typedef function<void(const Peer &)> RequestNonceFailedHook; + void onRequestNonceFailed(RequestNonceFailedHook); + +protected: + void requestPairing(UUID serviceId, const Peer & peer); + virtual void handle(Context &) override; + virtual Ref handlePairingCompleteRef(const Peer &) = 0; + virtual void handlePairingResult(Context &) = 0; + +private: + static vector<uint8_t> nonceDigest(const Identity & id1, const Identity & id2, + const vector<uint8_t> & nonce1, const vector<uint8_t> & nonce2); + static string confirmationNumber(const vector<uint8_t> &); + void waitForConfirmation(Peer peer, string confirm); + + RequestInitHook requestInitHook; + ConfirmHook responseHook; + ConfirmHook requestHook; + RequestNonceFailedHook requestNonceFailedHook; + + optional<Ref> result; + + enum class StatePhase { + NoPairing, + OurRequest, + OurRequestConfirm, + OurRequestReady, + PeerRequest, + PeerRequestConfirm, + PairingDone, + PairingFailed + }; + + struct State { + StatePhase phase; + vector<uint8_t> nonce; + vector<uint8_t> peerCheck; + }; + + map<Peer, State> peerStates; + mutex stateLock; +}; + +template<class Result> +class PairingService : public PairingServiceBase +{ +protected: + virtual Stored<Result> handlePairingComplete(const Peer &) = 0; + virtual void handlePairingResult(Context &, Stored<Result>) = 0; + + virtual Ref handlePairingCompleteRef(const Peer &) override final; + virtual void handlePairingResult(Context &) override final; +}; + +template<class Result> +Ref PairingService<Result>::handlePairingCompleteRef(const Peer & peer) +{ + return handlePairingComplete(peer).ref(); +} + +template<class Result> +void PairingService<Result>::handlePairingResult(Context & ctx) +{ + handlePairingResult(ctx, Stored<Result>::load(ctx.ref())); +} + +} |