11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/cast_channel/cast_transport.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <string> 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/format_macros.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/numerics/safe_conversions.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/stringprintf.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/cast_channel/cast_framer.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/cast_channel/cast_message_util.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/cast_channel/logger.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/cast_channel/logger_util.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/api/cast_channel/cast_channel.pb.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/net_errors.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define VLOG_WITH_CONNECTION(level) \ 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG(level) << "[" << socket_->ip_endpoint().ToString() \ 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << ", auth=" << socket_->channel_auth() << "] " 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace extensions { 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace core_api { 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace cast_channel { 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciCastTransport::CastTransport(CastSocketInterface* socket, 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Delegate* read_delegate, 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<Logger> logger) 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : socket_(socket), 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_delegate_(read_delegate), 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci write_state_(WRITE_STATE_NONE), 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_state_(READ_STATE_NONE), 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_(logger) { 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(socket); 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(read_delegate); 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Buffer is reused across messages to minimize unnecessary buffer 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // [re]allocations. 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_buffer_ = new net::GrowableIOBuffer(); 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_buffer_->SetCapacity(MessageFramer::MessageHeader::max_message_size()); 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci framer_.reset(new MessageFramer(read_buffer_)); 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciCastTransport::~CastTransport() { 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FlushWriteQueue(); 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciproto::ReadState CastTransport::ReadStateToProto( 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CastTransport::ReadState state) { 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (state) { 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CastTransport::READ_STATE_NONE: 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::READ_STATE_NONE; 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CastTransport::READ_STATE_READ: 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::READ_STATE_READ; 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CastTransport::READ_STATE_READ_COMPLETE: 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::READ_STATE_READ_COMPLETE; 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CastTransport::READ_STATE_DO_CALLBACK: 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::READ_STATE_DO_CALLBACK; 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CastTransport::READ_STATE_ERROR: 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::READ_STATE_ERROR; 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::READ_STATE_NONE; 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciproto::WriteState CastTransport::WriteStateToProto( 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CastTransport::WriteState state) { 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (state) { 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CastTransport::WRITE_STATE_NONE: 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::WRITE_STATE_NONE; 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CastTransport::WRITE_STATE_WRITE: 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::WRITE_STATE_WRITE; 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CastTransport::WRITE_STATE_WRITE_COMPLETE: 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::WRITE_STATE_WRITE_COMPLETE; 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CastTransport::WRITE_STATE_DO_CALLBACK: 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::WRITE_STATE_DO_CALLBACK; 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CastTransport::WRITE_STATE_ERROR: 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::WRITE_STATE_ERROR; 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::WRITE_STATE_NONE; 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciproto::ErrorState CastTransport::ErrorStateToProto(ChannelError state) { 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (state) { 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CHANNEL_ERROR_NONE: 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_NONE; 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CHANNEL_ERROR_CHANNEL_NOT_OPEN: 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_CHANNEL_NOT_OPEN; 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CHANNEL_ERROR_AUTHENTICATION_ERROR: 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_AUTHENTICATION_ERROR; 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CHANNEL_ERROR_CONNECT_ERROR: 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_CONNECT_ERROR; 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CHANNEL_ERROR_SOCKET_ERROR: 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_SOCKET_ERROR; 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CHANNEL_ERROR_TRANSPORT_ERROR: 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_TRANSPORT_ERROR; 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CHANNEL_ERROR_INVALID_MESSAGE: 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_INVALID_MESSAGE; 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CHANNEL_ERROR_INVALID_CHANNEL_ID: 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_INVALID_CHANNEL_ID; 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CHANNEL_ERROR_CONNECT_TIMEOUT: 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_CONNECT_TIMEOUT; 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case CHANNEL_ERROR_UNKNOWN: 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_UNKNOWN; 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return proto::CHANNEL_ERROR_NONE; 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CastTransport::FlushWriteQueue() { 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (; !write_queue_.empty(); write_queue_.pop()) { 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback& callback = write_queue_.front().callback; 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(net::ERR_FAILED); 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Reset(); 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CastTransport::SendMessage(const CastMessage& message, 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const net::CompletionCallback& callback) { 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string serialized_message; 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!MessageFramer::Serialize(message, &serialized_message)) { 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketEventForMessage(socket_->id(), 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proto::SEND_MESSAGE_FAILED, 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci message.namespace_(), 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "Error when serializing message."); 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(net::ERR_FAILED); 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteRequest write_request( 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci message.namespace_(), serialized_message, callback); 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci write_queue_.push(write_request); 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketEventForMessage( 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci socket_->id(), 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proto::MESSAGE_ENQUEUED, 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci message.namespace_(), 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::StringPrintf("Queue size: %" PRIuS, write_queue_.size())); 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (write_state_ == WRITE_STATE_NONE) { 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetWriteState(WRITE_STATE_WRITE); 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnWriteResult(net::OK); 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciCastTransport::WriteRequest::WriteRequest( 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& namespace_, 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& payload, 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const net::CompletionCallback& callback) 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : message_namespace(namespace_), callback(callback) { 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG(2) << "WriteRequest size: " << payload.size(); 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(payload), 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci payload.size()); 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciCastTransport::WriteRequest::~WriteRequest() { 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CastTransport::SetReadState(ReadState read_state) { 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (read_state_ != read_state) { 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_state_ = read_state; 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketReadState(socket_->id(), ReadStateToProto(read_state_)); 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CastTransport::SetWriteState(WriteState write_state) { 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (write_state_ != write_state) { 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci write_state_ = write_state; 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketWriteState(socket_->id(), 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteStateToProto(write_state_)); 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CastTransport::SetErrorState(ChannelError error_state) { 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error_state_ != error_state) { 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_state_ = error_state; 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketErrorState(socket_->id(), 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ErrorStateToProto(error_state_)); 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CastTransport::OnWriteResult(int result) { 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG_WITH_CONNECTION(1) << "OnWriteResult queue size: " 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << write_queue_.size(); 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (write_queue_.empty()) { 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetWriteState(WRITE_STATE_NONE); 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Network operations can either finish synchronously or asynchronously. 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This method executes the state machine transitions in a loop so that 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // write state transitions happen even when network operations finish 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // synchronously. 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv = result; 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci do { 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteState state = write_state_; 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci write_state_ = WRITE_STATE_NONE; 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (state) { 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case WRITE_STATE_WRITE: 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = DoWrite(); 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case WRITE_STATE_WRITE_COMPLETE: 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = DoWriteComplete(rv); 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case WRITE_STATE_DO_CALLBACK: 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = DoWriteCallback(); 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case WRITE_STATE_ERROR: 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = DoWriteError(rv); 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED() << "BUG in write flow. Unknown state: " << state; 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } while (!write_queue_.empty() && rv != net::ERR_IO_PENDING && 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci write_state_ != WRITE_STATE_NONE); 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // No state change occurred in do-while loop above. This means state has 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // transitioned to NONE. 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (write_state_ == WRITE_STATE_NONE) { 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketWriteState(socket_->id(), 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteStateToProto(write_state_)); 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If write loop is done because the queue is empty then set write 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // state to NONE 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (write_queue_.empty()) { 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetWriteState(WRITE_STATE_NONE); 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Write loop is done - if the result is ERR_FAILED then close with error. 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv == net::ERR_FAILED) { 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_NE(CHANNEL_ERROR_NONE, error_state_); 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci socket_->CloseWithError(error_state_); 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FlushWriteQueue(); 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint CastTransport::DoWrite() { 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!write_queue_.empty()); 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteRequest& request = write_queue_.front(); 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG_WITH_CONNECTION(2) << "WriteData byte_count = " 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << request.io_buffer->size() << " bytes_written " 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << request.io_buffer->BytesConsumed(); 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetWriteState(WRITE_STATE_WRITE_COMPLETE); 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv = socket_->Write( 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request.io_buffer.get(), 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request.io_buffer->BytesRemaining(), 2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&CastTransport::OnWriteResult, base::Unretained(this))); 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketEventWithRv(socket_->id(), proto::SOCKET_WRITE, rv); 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return rv; 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint CastTransport::DoWriteComplete(int result) { 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG_WITH_CONNECTION(2) << "DoWriteComplete result=" << result; 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!write_queue_.empty()); 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (result <= 0) { // NOTE that 0 also indicates an error 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetErrorState(CHANNEL_ERROR_TRANSPORT_ERROR); 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetWriteState(WRITE_STATE_ERROR); 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return result == 0 ? net::ERR_FAILED : result; 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Some bytes were successfully written 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteRequest& request = write_queue_.front(); 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer; 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci io_buffer->DidConsume(result); 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (io_buffer->BytesRemaining() == 0) { // Message fully sent 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetWriteState(WRITE_STATE_DO_CALLBACK); 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetWriteState(WRITE_STATE_WRITE); 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::OK; 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint CastTransport::DoWriteCallback() { 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG_WITH_CONNECTION(2) << "DoWriteCallback"; 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!write_queue_.empty()); 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetWriteState(WRITE_STATE_WRITE); 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteRequest& request = write_queue_.front(); 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int bytes_consumed = request.io_buffer->BytesConsumed(); 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketEventForMessage( 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci socket_->id(), 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proto::MESSAGE_WRITTEN, 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request.message_namespace, 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::StringPrintf("Bytes: %d", bytes_consumed)); 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request.callback.Run(net::OK); 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci write_queue_.pop(); 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::OK; 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint CastTransport::DoWriteError(int result) { 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG_WITH_CONNECTION(2) << "DoWriteError result=" << result; 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_NE(CHANNEL_ERROR_NONE, error_state_); 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_LT(result, 0); 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::ERR_FAILED; 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CastTransport::StartReadLoop() { 3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Read loop would have already been started if read state is not NONE 3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (read_state_ == READ_STATE_NONE) { 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetReadState(READ_STATE_READ); 3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnReadResult(net::OK); 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CastTransport::OnReadResult(int result) { 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(thread_checker_.CalledOnValidThread()); 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Network operations can either finish synchronously or asynchronously. 3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This method executes the state machine transitions in a loop so that 3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // write state transitions happen even when network operations finish 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // synchronously. 3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv = result; 3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci do { 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ReadState state = read_state_; 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_state_ = READ_STATE_NONE; 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (state) { 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case READ_STATE_READ: 3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = DoRead(); 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case READ_STATE_READ_COMPLETE: 3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = DoReadComplete(rv); 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case READ_STATE_DO_CALLBACK: 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = DoReadCallback(); 3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case READ_STATE_ERROR: 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = DoReadError(rv); 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(read_state_, READ_STATE_NONE); 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED() << "BUG in read flow. Unknown state: " << state; 3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } while (rv != net::ERR_IO_PENDING && read_state_ != READ_STATE_NONE); 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // No state change occurred in do-while loop above. This means state has 3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // transitioned to NONE. 3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (read_state_ == READ_STATE_NONE) { 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketReadState(socket_->id(), ReadStateToProto(read_state_)); 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rv == net::ERR_FAILED) { 3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_NE(CHANNEL_ERROR_NONE, error_state_); 3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci socket_->CloseWithError(error_state_); 3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FlushWriteQueue(); 3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_delegate_->OnError( 3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci socket_, error_state_, logger_->GetLastErrors(socket_->id())); 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint CastTransport::DoRead() { 3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG_WITH_CONNECTION(2) << "DoRead"; 3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetReadState(READ_STATE_READ_COMPLETE); 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Determine how many bytes need to be read. 3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t num_bytes_to_read = framer_->BytesRequested(); 3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Read up to num_bytes_to_read into |current_read_buffer_|. 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int rv = socket_->Read( 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_buffer_.get(), 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::checked_cast<uint32>(num_bytes_to_read), 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&CastTransport::OnReadResult, base::Unretained(this))); 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return rv; 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint CastTransport::DoReadComplete(int result) { 3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG_WITH_CONNECTION(2) << "DoReadComplete result = " << result; 3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (result <= 0) { 3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetErrorState(CHANNEL_ERROR_TRANSPORT_ERROR); 3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetReadState(READ_STATE_ERROR); 3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return result == 0 ? net::ERR_FAILED : result; 3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t message_size; 3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(current_message_.get() == NULL); 3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci current_message_ = framer_->Ingest(result, &message_size, &error_state_); 3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (current_message_.get()) { 4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(error_state_, CHANNEL_ERROR_NONE); 4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_GT(message_size, static_cast<size_t>(0)); 4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketEventForMessage( 4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci socket_->id(), 4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proto::MESSAGE_READ, 4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci current_message_->namespace_(), 4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::StringPrintf("Message size: %u", 4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<uint32>(message_size))); 4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetReadState(READ_STATE_DO_CALLBACK); 4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (error_state_ != CHANNEL_ERROR_NONE) { 4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(current_message_.get() == NULL); 4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetErrorState(CHANNEL_ERROR_INVALID_MESSAGE); 4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetReadState(READ_STATE_ERROR); 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(current_message_.get() == NULL); 4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetReadState(READ_STATE_READ); 4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::OK; 4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint CastTransport::DoReadCallback() { 4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG_WITH_CONNECTION(2) << "DoReadCallback"; 4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetReadState(READ_STATE_READ); 4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!IsCastMessageValid(*current_message_)) { 4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetReadState(READ_STATE_ERROR); 4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetErrorState(CHANNEL_ERROR_INVALID_MESSAGE); 4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::ERR_INVALID_RESPONSE; 4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci logger_->LogSocketEventForMessage(socket_->id(), 4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proto::NOTIFY_ON_MESSAGE, 4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci current_message_->namespace_(), 4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string()); 4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_delegate_->OnMessage(socket_, *current_message_); 4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci current_message_.reset(); 4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::OK; 4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint CastTransport::DoReadError(int result) { 4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG_WITH_CONNECTION(2) << "DoReadError"; 4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_NE(CHANNEL_ERROR_NONE, error_state_); 4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_LE(result, 0); 4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::ERR_FAILED; 4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace cast_channel 4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace core_api 4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace extensions 447