// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "cast/common/channel/cast_socket_message_port.h" #include #include "cast/common/channel/message_util.h" #include "cast/common/channel/proto/cast_channel.pb.h" #include "cast/common/channel/virtual_connection.h" namespace openscreen { namespace cast { CastSocketMessagePort::CastSocketMessagePort(VirtualConnectionRouter* router) : router_(router) {} CastSocketMessagePort::~CastSocketMessagePort() { ResetClient(); } // NOTE: we assume here that this message port is already the client for // the passed in socket, so leave the socket's client unchanged. However, // since sockets should map one to one with receiver sessions, we reset our // client. The consumer of this message port should call SetClient with the new // message port client after setting the socket. void CastSocketMessagePort::SetSocket(WeakPtr socket) { ResetClient(); socket_ = socket; } int CastSocketMessagePort::GetSocketId() { return ToCastSocketId(socket_.get()); } void CastSocketMessagePort::SetClient(MessagePort::Client* client, std::string client_sender_id) { ResetClient(); client_ = client; client_sender_id_ = std::move(client_sender_id); router_->AddHandlerForLocalId(client_sender_id_, this); } void CastSocketMessagePort::ResetClient() { if (!client_) { return; } client_ = nullptr; router_->RemoveHandlerForLocalId(client_sender_id_); router_->RemoveConnectionsByLocalId(client_sender_id_); client_sender_id_.clear(); } void CastSocketMessagePort::PostMessage( const std::string& destination_sender_id, const std::string& message_namespace, const std::string& message) { if (!client_) { OSP_DLOG_WARN << "Not posting message due to nullptr client_"; return; } if (!socket_) { client_->OnError(Error::Code::kAlreadyClosed); return; } VirtualConnection connection{client_sender_id_, destination_sender_id, socket_->socket_id()}; if (!router_->GetConnectionData(connection)) { router_->AddConnection(connection, VirtualConnection::AssociatedData{}); } const Error send_error = router_->Send( std::move(connection), MakeSimpleUTF8Message(message_namespace, message)); if (!send_error.ok()) { client_->OnError(std::move(send_error)); } } void CastSocketMessagePort::OnMessage(VirtualConnectionRouter* router, CastSocket* socket, ::cast::channel::CastMessage message) { OSP_DCHECK(router == router_); OSP_DCHECK(!socket || socket_.get() == socket); // Message ports are for specific virtual connections, and do not pass-through // broadcasts. if (message.destination_id() == kBroadcastId) { return; } OSP_DVLOG << "Received a cast socket message"; if (!client_) { OSP_DLOG_WARN << "Dropping message due to nullptr client_"; return; } client_->OnMessage(message.source_id(), message.namespace_(), message.payload_utf8()); } } // namespace cast } // namespace openscreen