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_H_ 6 #define OSP_PUBLIC_PROTOCOL_CONNECTION_H_ 7 8 #include <cstddef> 9 #include <cstdint> 10 #include <type_traits> 11 12 #include "osp/msgs/osp_messages.h" 13 #include "platform/base/error.h" 14 #include "util/osp_logging.h" 15 16 namespace openscreen { 17 18 class Error; 19 20 namespace osp { 21 22 template <typename T> 23 using MessageEncodingFunction = 24 std::add_pointer_t<bool(const T&, msgs::CborEncodeBuffer*)>; 25 26 struct NetworkMetrics; 27 28 // Represents an embedder's view of a connection between an Open Screen 29 // controller and a receiver. Both the controller and receiver will have a 30 // ProtocolConnection object, although the information known about the other 31 // party may not be symmetrical. 32 // 33 // A ProtocolConnection supports multiple protocols defined by the Open Screen 34 // standard and can be extended by embedders with additional protocols. 35 // 36 // TODO(jophba): move to sharing underlying QUIC connections between multiple 37 // instances of ProtocolConnection. 38 class ProtocolConnection { 39 public: 40 class Observer { 41 public: 42 virtual ~Observer() = default; 43 44 // Called when |connection| is no longer available, either because the 45 // underlying transport was terminated, the underying system resource was 46 // closed, or data can no longer be exchanged. 47 virtual void OnConnectionClosed(const ProtocolConnection& connection) = 0; 48 }; 49 50 ProtocolConnection(uint64_t endpoint_id, uint64_t connection_id); 51 virtual ~ProtocolConnection() = default; 52 53 // TODO(mfoltz): Define extension API exposed to embedders. This would be 54 // used, for example, to query for and implement vendor-specific protocols 55 // alongside the Open Screen Protocol. 56 57 // NOTE: ProtocolConnection instances that are owned by clients will have a 58 // ServiceInfo attached with data from discovery and QUIC connection 59 // establishment. What about server connections? We probably want to have 60 // two different structures representing what the client and server know about 61 // a connection. 62 63 void SetObserver(Observer* observer); 64 65 template <typename T> WriteMessage(const T & message,MessageEncodingFunction<T> encoder)66 Error WriteMessage(const T& message, MessageEncodingFunction<T> encoder) { 67 msgs::CborEncodeBuffer buffer; 68 69 if (!encoder(message, &buffer)) { 70 OSP_LOG_WARN << "failed to properly encode presentation message"; 71 return Error::Code::kParseError; 72 } 73 74 Write(buffer.data(), buffer.size()); 75 76 return Error::None(); 77 } 78 79 // TODO(btolsch): This should be derived from the handshake auth identifier 80 // when that is finalized and implemented. endpoint_id()81 uint64_t endpoint_id() const { return endpoint_id_; } id()82 uint64_t id() const { return id_; } 83 84 virtual void Write(const uint8_t* data, size_t data_size) = 0; 85 virtual void CloseWriteEnd() = 0; 86 87 protected: 88 uint64_t endpoint_id_; 89 uint64_t id_; 90 Observer* observer_ = nullptr; 91 }; 92 93 class ProtocolConnectionServiceObserver { 94 public: 95 // Called when the state becomes kRunning. 96 virtual void OnRunning() = 0; 97 // Called when the state becomes kStopped. 98 virtual void OnStopped() = 0; 99 100 // Called when metrics have been collected by the service. 101 virtual void OnMetrics(const NetworkMetrics& metrics) = 0; 102 // Called when an error has occurred. 103 virtual void OnError(const Error& error) = 0; 104 105 protected: 106 virtual ~ProtocolConnectionServiceObserver() = default; 107 }; 108 109 } // namespace osp 110 } // namespace openscreen 111 112 #endif // OSP_PUBLIC_PROTOCOL_CONNECTION_H_ 113