1 // Copyright 2019 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 CAST_COMMON_CHANNEL_VIRTUAL_CONNECTION_ROUTER_H_ 6 #define CAST_COMMON_CHANNEL_VIRTUAL_CONNECTION_ROUTER_H_ 7 8 #include <cstdint> 9 #include <map> 10 #include <memory> 11 #include <string> 12 13 #include "absl/types/optional.h" 14 #include "cast/common/channel/proto/cast_channel.pb.h" 15 #include "cast/common/channel/virtual_connection.h" 16 #include "cast/common/public/cast_socket.h" 17 18 namespace openscreen { 19 namespace cast { 20 21 class CastMessageHandler; 22 class ConnectionNamespaceHandler; 23 24 // Handles CastSockets by routing received messages to appropriate message 25 // handlers based on the VirtualConnection's local ID and sending messages over 26 // the appropriate CastSocket for a VirtualConnection. 27 // 28 // Basic model for using this would be: 29 // 30 // 1. Foo is a SenderSocketFactory::Client. 31 // 32 // 2. Foo calls SenderSocketFactory::Connect, optionally with VCRouter as the 33 // CastSocket::Client. 34 // 35 // 3. Foo gets OnConnected callback and makes whatever local notes it needs 36 // (e.g. sink "resolved", init app probing state, etc.), then calls 37 // VCRouter::TakeSocket. 38 // 39 // 4. Anything Foo wants to send (launch, app availability, etc.) goes through 40 // VCRouter::Send via an appropriate VC. The virtual connection is not 41 // created automatically, so AddConnection() must be called first. 42 // 43 // 5. Anything Foo wants to receive must be registered with a handler by calling 44 // AddHandlerForLocalId(). 45 // 46 // 6. Foo is expected to clean-up after itself (#4 and #5) by calling 47 // RemoveConnection() and RemoveHandlerForLocalId(). 48 class VirtualConnectionRouter final : public CastSocket::Client { 49 public: 50 class SocketErrorHandler { 51 public: 52 virtual void OnClose(CastSocket* socket) = 0; 53 virtual void OnError(CastSocket* socket, Error error) = 0; 54 }; 55 56 VirtualConnectionRouter(); 57 ~VirtualConnectionRouter() override; 58 59 // Adds a VirtualConnection, if one does not already exist, to enable routing 60 // of peer-to-peer messages. 61 void AddConnection(VirtualConnection virtual_connection, 62 VirtualConnection::AssociatedData associated_data); 63 64 // Removes a VirtualConnection and returns true if a connection matching 65 // |virtual_connection| was found and removed. 66 bool RemoveConnection(const VirtualConnection& virtual_connection, 67 VirtualConnection::CloseReason reason); 68 69 // Removes all VirtualConnections whose local endpoint matches the given 70 // |local_id|. 71 void RemoveConnectionsByLocalId(const std::string& local_id); 72 73 // Removes all VirtualConnections whose traffic passes over the socket 74 // referenced by |socket_id|. 75 void RemoveConnectionsBySocketId(int socket_id); 76 77 // Returns the AssociatedData for a |virtual_connection| if a connection 78 // exists, nullopt otherwise. The pointer isn't stable in the long term; so, 79 // if it actually needs to be stored for later, the caller should make a copy. 80 absl::optional<const VirtualConnection::AssociatedData*> GetConnectionData( 81 const VirtualConnection& virtual_connection) const; 82 83 // Adds/Removes a CastMessageHandler for all messages destined for the given 84 // |endpoint| referred to by |local_id|, and returns whether the given 85 // |local_id| was successfully added/removed. 86 // 87 // Note: Clients will need to separately call AddConnection(), and 88 // RemoveConnection() or RemoveConnectionsByLocalId(). 89 bool AddHandlerForLocalId(std::string local_id, CastMessageHandler* endpoint); 90 bool RemoveHandlerForLocalId(const std::string& local_id); 91 92 // |error_handler| must live until either its OnError or OnClose is called. 93 void TakeSocket(SocketErrorHandler* error_handler, 94 std::unique_ptr<CastSocket> socket); 95 void CloseSocket(int id); 96 97 Error Send(VirtualConnection virtual_conn, 98 ::cast::channel::CastMessage message); 99 100 Error BroadcastFromLocalPeer(std::string local_id, 101 ::cast::channel::CastMessage message); 102 103 // CastSocket::Client overrides. 104 void OnError(CastSocket* socket, Error error) override; 105 void OnMessage(CastSocket* socket, 106 ::cast::channel::CastMessage message) override; 107 108 protected: 109 friend class ConnectionNamespaceHandler; 110 set_connection_namespace_handler(ConnectionNamespaceHandler * handler)111 void set_connection_namespace_handler(ConnectionNamespaceHandler* handler) { 112 connection_handler_ = handler; 113 } 114 115 private: 116 // This struct simply stores the remainder of the data {VirtualConnection, 117 // VirtualConnection::AssociatedData} that is not broken up into map keys for 118 // |connections_|. 119 struct VCTail { 120 std::string peer_id; 121 VirtualConnection::AssociatedData data; 122 }; 123 124 struct SocketWithHandler { 125 std::unique_ptr<CastSocket> socket; 126 SocketErrorHandler* error_handler; 127 }; 128 129 ConnectionNamespaceHandler* connection_handler_ = nullptr; 130 131 std::map<int /* socket_id */, 132 std::multimap<std::string /* local_id */, VCTail>> 133 connections_; 134 135 std::map<int, SocketWithHandler> sockets_; 136 std::map<std::string /* local_id */, CastMessageHandler*> endpoints_; 137 }; 138 139 } // namespace cast 140 } // namespace openscreen 141 142 #endif // CAST_COMMON_CHANNEL_VIRTUAL_CONNECTION_ROUTER_H_ 143