1*3f982cf4SFabien Sanglard // Copyright 2019 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_PRESENTATION_PRESENTATION_CONNECTION_H_ 6*3f982cf4SFabien Sanglard #define OSP_PUBLIC_PRESENTATION_PRESENTATION_CONNECTION_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <cstdint> 9*3f982cf4SFabien Sanglard #include <map> 10*3f982cf4SFabien Sanglard #include <memory> 11*3f982cf4SFabien Sanglard #include <string> 12*3f982cf4SFabien Sanglard #include <vector> 13*3f982cf4SFabien Sanglard 14*3f982cf4SFabien Sanglard #include "absl/strings/string_view.h" 15*3f982cf4SFabien Sanglard #include "absl/types/optional.h" 16*3f982cf4SFabien Sanglard #include "osp/public/message_demuxer.h" 17*3f982cf4SFabien Sanglard #include "platform/api/time.h" 18*3f982cf4SFabien Sanglard #include "platform/base/error.h" 19*3f982cf4SFabien Sanglard #include "platform/base/ip_address.h" 20*3f982cf4SFabien Sanglard #include "platform/base/macros.h" 21*3f982cf4SFabien Sanglard #include "util/osp_logging.h" 22*3f982cf4SFabien Sanglard 23*3f982cf4SFabien Sanglard namespace openscreen { 24*3f982cf4SFabien Sanglard namespace osp { 25*3f982cf4SFabien Sanglard 26*3f982cf4SFabien Sanglard class ProtocolConnection; 27*3f982cf4SFabien Sanglard 28*3f982cf4SFabien Sanglard enum class TerminationReason { 29*3f982cf4SFabien Sanglard kReceiverTerminateCalled = 0, 30*3f982cf4SFabien Sanglard kReceiverUserTerminated, 31*3f982cf4SFabien Sanglard kControllerTerminateCalled, 32*3f982cf4SFabien Sanglard kControllerUserTerminated, 33*3f982cf4SFabien Sanglard kReceiverPresentationReplaced, 34*3f982cf4SFabien Sanglard kReceiverIdleTooLong, 35*3f982cf4SFabien Sanglard kReceiverPresentationUnloaded, 36*3f982cf4SFabien Sanglard kReceiverShuttingDown, 37*3f982cf4SFabien Sanglard kReceiverError, 38*3f982cf4SFabien Sanglard }; 39*3f982cf4SFabien Sanglard 40*3f982cf4SFabien Sanglard class Connection { 41*3f982cf4SFabien Sanglard public: 42*3f982cf4SFabien Sanglard enum class CloseReason { 43*3f982cf4SFabien Sanglard kClosed = 0, 44*3f982cf4SFabien Sanglard kDiscarded, 45*3f982cf4SFabien Sanglard kError, 46*3f982cf4SFabien Sanglard }; 47*3f982cf4SFabien Sanglard 48*3f982cf4SFabien Sanglard enum class State { 49*3f982cf4SFabien Sanglard // The library is currently attempting to connect to the presentation. 50*3f982cf4SFabien Sanglard kConnecting, 51*3f982cf4SFabien Sanglard // The connection to the presentation is open and communication is possible. 52*3f982cf4SFabien Sanglard kConnected, 53*3f982cf4SFabien Sanglard // The connection is closed or could not be opened. No communication is 54*3f982cf4SFabien Sanglard // possible but it may be possible to reopen the connection via 55*3f982cf4SFabien Sanglard // ReconnectPresentation. 56*3f982cf4SFabien Sanglard kClosed, 57*3f982cf4SFabien Sanglard // The connection is closed and the receiver has been terminated. 58*3f982cf4SFabien Sanglard kTerminated, 59*3f982cf4SFabien Sanglard }; 60*3f982cf4SFabien Sanglard 61*3f982cf4SFabien Sanglard // An object to receive callbacks related to a single Connection. 62*3f982cf4SFabien Sanglard class Delegate { 63*3f982cf4SFabien Sanglard public: 64*3f982cf4SFabien Sanglard Delegate() = default; 65*3f982cf4SFabien Sanglard 66*3f982cf4SFabien Sanglard // State changes. 67*3f982cf4SFabien Sanglard virtual void OnConnected() = 0; 68*3f982cf4SFabien Sanglard 69*3f982cf4SFabien Sanglard // Explicit close by other endpoint. 70*3f982cf4SFabien Sanglard virtual void OnClosedByRemote() = 0; 71*3f982cf4SFabien Sanglard 72*3f982cf4SFabien Sanglard // Closed because the script connection object was discarded. 73*3f982cf4SFabien Sanglard virtual void OnDiscarded() = 0; 74*3f982cf4SFabien Sanglard 75*3f982cf4SFabien Sanglard // Closed because of an error. 76*3f982cf4SFabien Sanglard virtual void OnError(const absl::string_view message) = 0; 77*3f982cf4SFabien Sanglard 78*3f982cf4SFabien Sanglard // Terminated through a different connection. 79*3f982cf4SFabien Sanglard virtual void OnTerminated() = 0; 80*3f982cf4SFabien Sanglard 81*3f982cf4SFabien Sanglard // A UTF-8 string message was received. 82*3f982cf4SFabien Sanglard virtual void OnStringMessage(const absl::string_view message) = 0; 83*3f982cf4SFabien Sanglard 84*3f982cf4SFabien Sanglard // A binary message was received. 85*3f982cf4SFabien Sanglard virtual void OnBinaryMessage(const std::vector<uint8_t>& data) = 0; 86*3f982cf4SFabien Sanglard 87*3f982cf4SFabien Sanglard protected: 88*3f982cf4SFabien Sanglard virtual ~Delegate() = default; 89*3f982cf4SFabien Sanglard 90*3f982cf4SFabien Sanglard private: 91*3f982cf4SFabien Sanglard OSP_DISALLOW_COPY_AND_ASSIGN(Delegate); 92*3f982cf4SFabien Sanglard }; 93*3f982cf4SFabien Sanglard 94*3f982cf4SFabien Sanglard // Allows different close, termination, and destruction behavior for both 95*3f982cf4SFabien Sanglard // possible parents: controller and receiver. This is different from the 96*3f982cf4SFabien Sanglard // normal delegate above, which would be supplied by the embedder to link it's 97*3f982cf4SFabien Sanglard // presentation connection functionality. 98*3f982cf4SFabien Sanglard class ParentDelegate { 99*3f982cf4SFabien Sanglard public: 100*3f982cf4SFabien Sanglard ParentDelegate() = default; 101*3f982cf4SFabien Sanglard virtual ~ParentDelegate() = default; 102*3f982cf4SFabien Sanglard 103*3f982cf4SFabien Sanglard virtual Error CloseConnection(Connection* connection, 104*3f982cf4SFabien Sanglard CloseReason reason) = 0; 105*3f982cf4SFabien Sanglard virtual Error OnPresentationTerminated(const std::string& presentation_id, 106*3f982cf4SFabien Sanglard TerminationReason reason) = 0; 107*3f982cf4SFabien Sanglard virtual void OnConnectionDestroyed(Connection* connection) = 0; 108*3f982cf4SFabien Sanglard 109*3f982cf4SFabien Sanglard private: 110*3f982cf4SFabien Sanglard OSP_DISALLOW_COPY_AND_ASSIGN(ParentDelegate); 111*3f982cf4SFabien Sanglard }; 112*3f982cf4SFabien Sanglard 113*3f982cf4SFabien Sanglard struct PresentationInfo { 114*3f982cf4SFabien Sanglard std::string id; 115*3f982cf4SFabien Sanglard std::string url; 116*3f982cf4SFabien Sanglard }; 117*3f982cf4SFabien Sanglard 118*3f982cf4SFabien Sanglard // Constructs a new connection using |delegate| for callbacks. 119*3f982cf4SFabien Sanglard Connection(const PresentationInfo& info, 120*3f982cf4SFabien Sanglard Delegate* delegate, 121*3f982cf4SFabien Sanglard ParentDelegate* parent_delegate); 122*3f982cf4SFabien Sanglard ~Connection(); 123*3f982cf4SFabien Sanglard 124*3f982cf4SFabien Sanglard // Returns the ID and URL of this presentation. presentation_info()125*3f982cf4SFabien Sanglard const PresentationInfo& presentation_info() const { return presentation_; } 126*3f982cf4SFabien Sanglard state()127*3f982cf4SFabien Sanglard State state() const { return state_; } 128*3f982cf4SFabien Sanglard get_protocol_connection()129*3f982cf4SFabien Sanglard ProtocolConnection* get_protocol_connection() const { 130*3f982cf4SFabien Sanglard return protocol_connection_.get(); 131*3f982cf4SFabien Sanglard } 132*3f982cf4SFabien Sanglard 133*3f982cf4SFabien Sanglard // These methods should only be called when we are connected. endpoint_id()134*3f982cf4SFabien Sanglard uint64_t endpoint_id() const { 135*3f982cf4SFabien Sanglard OSP_CHECK(endpoint_id_); 136*3f982cf4SFabien Sanglard return endpoint_id_.value(); 137*3f982cf4SFabien Sanglard } connection_id()138*3f982cf4SFabien Sanglard uint64_t connection_id() const { 139*3f982cf4SFabien Sanglard OSP_CHECK(connection_id_); 140*3f982cf4SFabien Sanglard return connection_id_.value(); 141*3f982cf4SFabien Sanglard } 142*3f982cf4SFabien Sanglard 143*3f982cf4SFabien Sanglard // Sends a UTF-8 string message. 144*3f982cf4SFabien Sanglard Error SendString(absl::string_view message); 145*3f982cf4SFabien Sanglard 146*3f982cf4SFabien Sanglard // Sends a binary message. 147*3f982cf4SFabien Sanglard Error SendBinary(std::vector<uint8_t>&& data); 148*3f982cf4SFabien Sanglard 149*3f982cf4SFabien Sanglard // Closes the connection. This can be based on an explicit request from the 150*3f982cf4SFabien Sanglard // embedder or because the connection object is being discarded (page 151*3f982cf4SFabien Sanglard // navigated, object GC'd, etc.). 152*3f982cf4SFabien Sanglard Error Close(CloseReason reason); 153*3f982cf4SFabien Sanglard 154*3f982cf4SFabien Sanglard // Terminates the presentation associated with this connection. 155*3f982cf4SFabien Sanglard void Terminate(TerminationReason reason); 156*3f982cf4SFabien Sanglard 157*3f982cf4SFabien Sanglard void OnConnecting(); 158*3f982cf4SFabien Sanglard 159*3f982cf4SFabien Sanglard // Called by the receiver when the OnPresentationStarted logic happens. This 160*3f982cf4SFabien Sanglard // notifies the delegate and updates our internal stream and ids. 161*3f982cf4SFabien Sanglard void OnConnected(uint64_t connection_id, 162*3f982cf4SFabien Sanglard uint64_t endpoint_id, 163*3f982cf4SFabien Sanglard std::unique_ptr<ProtocolConnection> stream); 164*3f982cf4SFabien Sanglard 165*3f982cf4SFabien Sanglard void OnClosedByError(Error cause); 166*3f982cf4SFabien Sanglard void OnClosedByRemote(); 167*3f982cf4SFabien Sanglard void OnTerminated(); 168*3f982cf4SFabien Sanglard get_delegate()169*3f982cf4SFabien Sanglard Delegate* get_delegate() { return delegate_; } 170*3f982cf4SFabien Sanglard 171*3f982cf4SFabien Sanglard private: 172*3f982cf4SFabien Sanglard // Helper method that handles closing down our internal state. 173*3f982cf4SFabien Sanglard // Returns whether or not the connection state changed (and thus 174*3f982cf4SFabien Sanglard // whether or not delegates should be informed). 175*3f982cf4SFabien Sanglard bool OnClosed(); 176*3f982cf4SFabien Sanglard 177*3f982cf4SFabien Sanglard PresentationInfo presentation_; 178*3f982cf4SFabien Sanglard State state_ = State::kConnecting; 179*3f982cf4SFabien Sanglard Delegate* delegate_; 180*3f982cf4SFabien Sanglard ParentDelegate* parent_delegate_; 181*3f982cf4SFabien Sanglard absl::optional<uint64_t> connection_id_; 182*3f982cf4SFabien Sanglard absl::optional<uint64_t> endpoint_id_; 183*3f982cf4SFabien Sanglard std::unique_ptr<ProtocolConnection> protocol_connection_; 184*3f982cf4SFabien Sanglard 185*3f982cf4SFabien Sanglard OSP_DISALLOW_COPY_AND_ASSIGN(Connection); 186*3f982cf4SFabien Sanglard }; 187*3f982cf4SFabien Sanglard 188*3f982cf4SFabien Sanglard class ConnectionManager final : public MessageDemuxer::MessageCallback { 189*3f982cf4SFabien Sanglard public: 190*3f982cf4SFabien Sanglard explicit ConnectionManager(MessageDemuxer* demuxer); 191*3f982cf4SFabien Sanglard 192*3f982cf4SFabien Sanglard void AddConnection(Connection* connection); 193*3f982cf4SFabien Sanglard void RemoveConnection(Connection* connection); 194*3f982cf4SFabien Sanglard 195*3f982cf4SFabien Sanglard // MessasgeDemuxer::MessageCallback overrides. 196*3f982cf4SFabien Sanglard ErrorOr<size_t> OnStreamMessage(uint64_t endpoint_id, 197*3f982cf4SFabien Sanglard uint64_t connection_id, 198*3f982cf4SFabien Sanglard msgs::Type message_type, 199*3f982cf4SFabien Sanglard const uint8_t* buffer, 200*3f982cf4SFabien Sanglard size_t buffer_size, 201*3f982cf4SFabien Sanglard Clock::time_point now) override; 202*3f982cf4SFabien Sanglard 203*3f982cf4SFabien Sanglard Connection* GetConnection(uint64_t connection_id); 204*3f982cf4SFabien Sanglard 205*3f982cf4SFabien Sanglard private: 206*3f982cf4SFabien Sanglard // TODO(btolsch): Connection IDs were changed to be per-endpoint, but this 207*3f982cf4SFabien Sanglard // table then needs to be <endpoint id, connection id> since connection id is 208*3f982cf4SFabien Sanglard // still not unique globally. 209*3f982cf4SFabien Sanglard std::map<uint64_t, Connection*> connections_; 210*3f982cf4SFabien Sanglard 211*3f982cf4SFabien Sanglard MessageDemuxer::MessageWatch message_watch_; 212*3f982cf4SFabien Sanglard MessageDemuxer::MessageWatch close_request_watch_; 213*3f982cf4SFabien Sanglard MessageDemuxer::MessageWatch close_event_watch_; 214*3f982cf4SFabien Sanglard 215*3f982cf4SFabien Sanglard OSP_DISALLOW_COPY_AND_ASSIGN(ConnectionManager); 216*3f982cf4SFabien Sanglard }; 217*3f982cf4SFabien Sanglard 218*3f982cf4SFabien Sanglard } // namespace osp 219*3f982cf4SFabien Sanglard } // namespace openscreen 220*3f982cf4SFabien Sanglard 221*3f982cf4SFabien Sanglard #endif // OSP_PUBLIC_PRESENTATION_PRESENTATION_CONNECTION_H_ 222