1*3f982cf4SFabien Sanglard // Copyright 2018 The Chromium Authors. All rights reserved. 2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be 3*3f982cf4SFabien Sanglard // found in the LICENSE file. 4*3f982cf4SFabien Sanglard 5*3f982cf4SFabien Sanglard #ifndef OSP_PUBLIC_PROTOCOL_CONNECTION_CLIENT_H_ 6*3f982cf4SFabien Sanglard #define OSP_PUBLIC_PROTOCOL_CONNECTION_CLIENT_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <memory> 9*3f982cf4SFabien Sanglard #include <ostream> 10*3f982cf4SFabien Sanglard #include <string> 11*3f982cf4SFabien Sanglard 12*3f982cf4SFabien Sanglard #include "osp/public/endpoint_request_ids.h" 13*3f982cf4SFabien Sanglard #include "osp/public/message_demuxer.h" 14*3f982cf4SFabien Sanglard #include "osp/public/protocol_connection.h" 15*3f982cf4SFabien Sanglard #include "platform/base/error.h" 16*3f982cf4SFabien Sanglard #include "platform/base/ip_address.h" 17*3f982cf4SFabien Sanglard #include "platform/base/macros.h" 18*3f982cf4SFabien Sanglard 19*3f982cf4SFabien Sanglard namespace openscreen { 20*3f982cf4SFabien Sanglard namespace osp { 21*3f982cf4SFabien Sanglard 22*3f982cf4SFabien Sanglard // Embedder's view of the network service that initiates OSP connections to OSP 23*3f982cf4SFabien Sanglard // receivers. 24*3f982cf4SFabien Sanglard // 25*3f982cf4SFabien Sanglard // NOTE: This API closely resembles that for the ProtocolConnectionServer; the 26*3f982cf4SFabien Sanglard // client currently lacks Suspend(). Consider factoring out a common 27*3f982cf4SFabien Sanglard // ProtocolConnectionEndpoint when the two APIs are finalized. 28*3f982cf4SFabien Sanglard class ProtocolConnectionClient { 29*3f982cf4SFabien Sanglard public: 30*3f982cf4SFabien Sanglard enum class State { kStopped = 0, kStarting, kRunning, kStopping }; 31*3f982cf4SFabien Sanglard 32*3f982cf4SFabien Sanglard class ConnectionRequestCallback { 33*3f982cf4SFabien Sanglard public: 34*3f982cf4SFabien Sanglard virtual ~ConnectionRequestCallback() = default; 35*3f982cf4SFabien Sanglard 36*3f982cf4SFabien Sanglard // Called when a new connection was created between 5-tuples. 37*3f982cf4SFabien Sanglard virtual void OnConnectionOpened( 38*3f982cf4SFabien Sanglard uint64_t request_id, 39*3f982cf4SFabien Sanglard std::unique_ptr<ProtocolConnection> connection) = 0; 40*3f982cf4SFabien Sanglard virtual void OnConnectionFailed(uint64_t request_id) = 0; 41*3f982cf4SFabien Sanglard }; 42*3f982cf4SFabien Sanglard 43*3f982cf4SFabien Sanglard class ConnectRequest { 44*3f982cf4SFabien Sanglard public: 45*3f982cf4SFabien Sanglard ConnectRequest(); 46*3f982cf4SFabien Sanglard ConnectRequest(ProtocolConnectionClient* parent, uint64_t request_id); 47*3f982cf4SFabien Sanglard ConnectRequest(ConnectRequest&& other); 48*3f982cf4SFabien Sanglard ~ConnectRequest(); 49*3f982cf4SFabien Sanglard ConnectRequest& operator=(ConnectRequest&& other); 50*3f982cf4SFabien Sanglard 51*3f982cf4SFabien Sanglard explicit operator bool() const { return request_id_; } 52*3f982cf4SFabien Sanglard request_id()53*3f982cf4SFabien Sanglard uint64_t request_id() const { return request_id_; } 54*3f982cf4SFabien Sanglard 55*3f982cf4SFabien Sanglard // Records that the requested connect operation is complete so it doesn't 56*3f982cf4SFabien Sanglard // need to attempt a cancel on destruction. MarkComplete()57*3f982cf4SFabien Sanglard void MarkComplete() { request_id_ = 0; } 58*3f982cf4SFabien Sanglard 59*3f982cf4SFabien Sanglard private: 60*3f982cf4SFabien Sanglard ProtocolConnectionClient* parent_ = nullptr; 61*3f982cf4SFabien Sanglard uint64_t request_id_ = 0; 62*3f982cf4SFabien Sanglard }; 63*3f982cf4SFabien Sanglard 64*3f982cf4SFabien Sanglard virtual ~ProtocolConnectionClient(); 65*3f982cf4SFabien Sanglard 66*3f982cf4SFabien Sanglard // Starts the client using the config object. 67*3f982cf4SFabien Sanglard // Returns true if state() == kStopped and the service will be started, 68*3f982cf4SFabien Sanglard // false otherwise. 69*3f982cf4SFabien Sanglard virtual bool Start() = 0; 70*3f982cf4SFabien Sanglard 71*3f982cf4SFabien Sanglard // NOTE: Currently we do not support Suspend()/Resume() for the connection 72*3f982cf4SFabien Sanglard // client. Add those if we can define behavior for the OSP protocol and QUIC 73*3f982cf4SFabien Sanglard // for those operations. 74*3f982cf4SFabien Sanglard // See: https://github.com/webscreens/openscreenprotocol/issues/108 75*3f982cf4SFabien Sanglard 76*3f982cf4SFabien Sanglard // Stops listening and cancels any search in progress. 77*3f982cf4SFabien Sanglard // Returns true if state() != (kStopped|kStopping). 78*3f982cf4SFabien Sanglard virtual bool Stop() = 0; 79*3f982cf4SFabien Sanglard 80*3f982cf4SFabien Sanglard // Open a new connection to |endpoint|. This may succeed synchronously if 81*3f982cf4SFabien Sanglard // there are already connections open to |endpoint|, otherwise it will be 82*3f982cf4SFabien Sanglard // asynchronous. 83*3f982cf4SFabien Sanglard virtual ConnectRequest Connect(const IPEndpoint& endpoint, 84*3f982cf4SFabien Sanglard ConnectionRequestCallback* request) = 0; 85*3f982cf4SFabien Sanglard 86*3f982cf4SFabien Sanglard // Synchronously open a new connection to an endpoint identified by 87*3f982cf4SFabien Sanglard // |endpoint_id|. Returns nullptr if it can't be completed synchronously 88*3f982cf4SFabien Sanglard // (e.g. there are no existing open connections to that endpoint). 89*3f982cf4SFabien Sanglard virtual std::unique_ptr<ProtocolConnection> CreateProtocolConnection( 90*3f982cf4SFabien Sanglard uint64_t endpoint_id) = 0; 91*3f982cf4SFabien Sanglard message_demuxer()92*3f982cf4SFabien Sanglard MessageDemuxer* message_demuxer() const { return demuxer_; } 93*3f982cf4SFabien Sanglard endpoint_request_ids()94*3f982cf4SFabien Sanglard EndpointRequestIds* endpoint_request_ids() { return &endpoint_request_ids_; } 95*3f982cf4SFabien Sanglard 96*3f982cf4SFabien Sanglard // Returns the current state of the listener. state()97*3f982cf4SFabien Sanglard State state() const { return state_; } 98*3f982cf4SFabien Sanglard 99*3f982cf4SFabien Sanglard // Returns the last error reported by this client. last_error()100*3f982cf4SFabien Sanglard const Error& last_error() const { return last_error_; } 101*3f982cf4SFabien Sanglard 102*3f982cf4SFabien Sanglard protected: 103*3f982cf4SFabien Sanglard explicit ProtocolConnectionClient( 104*3f982cf4SFabien Sanglard MessageDemuxer* demuxer, 105*3f982cf4SFabien Sanglard ProtocolConnectionServiceObserver* observer); 106*3f982cf4SFabien Sanglard 107*3f982cf4SFabien Sanglard virtual void CancelConnectRequest(uint64_t request_id) = 0; 108*3f982cf4SFabien Sanglard 109*3f982cf4SFabien Sanglard State state_ = State::kStopped; 110*3f982cf4SFabien Sanglard Error last_error_; 111*3f982cf4SFabien Sanglard MessageDemuxer* const demuxer_; 112*3f982cf4SFabien Sanglard EndpointRequestIds endpoint_request_ids_; 113*3f982cf4SFabien Sanglard ProtocolConnectionServiceObserver* const observer_; 114*3f982cf4SFabien Sanglard 115*3f982cf4SFabien Sanglard OSP_DISALLOW_COPY_AND_ASSIGN(ProtocolConnectionClient); 116*3f982cf4SFabien Sanglard }; 117*3f982cf4SFabien Sanglard 118*3f982cf4SFabien Sanglard std::ostream& operator<<(std::ostream& os, 119*3f982cf4SFabien Sanglard ProtocolConnectionClient::State state); 120*3f982cf4SFabien Sanglard 121*3f982cf4SFabien Sanglard } // namespace osp 122*3f982cf4SFabien Sanglard } // namespace openscreen 123*3f982cf4SFabien Sanglard 124*3f982cf4SFabien Sanglard #endif // OSP_PUBLIC_PROTOCOL_CONNECTION_CLIENT_H_ 125