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