// Copyright 2014 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 "device/serial/serial_connection_factory.h" #include "base/bind.h" #include "base/location.h" #include "device/serial/serial_connection.h" #include "device/serial/serial_io_handler.h" namespace device { namespace { void FillDefaultConnectionOptions(serial::ConnectionOptions* options) { if (!options->bitrate) options->bitrate = 9600; if (options->data_bits == serial::DATA_BITS_NONE) options->data_bits = serial::DATA_BITS_EIGHT; if (options->stop_bits == serial::STOP_BITS_NONE) options->stop_bits = serial::STOP_BITS_ONE; if (options->parity_bit == serial::PARITY_BIT_NONE) options->parity_bit = serial::PARITY_BIT_NO; if (!options->has_cts_flow_control) { options->has_cts_flow_control = true; options->cts_flow_control = false; } } } // namespace class SerialConnectionFactory::ConnectTask : public base::RefCountedThreadSafe { public: ConnectTask(scoped_refptr factory, const std::string& path, serial::ConnectionOptionsPtr options, mojo::InterfaceRequest connection_request, mojo::InterfaceRequest sink, mojo::InterfaceRequest source); void Run(); private: friend class base::RefCountedThreadSafe; virtual ~ConnectTask(); void Connect(); void OnConnected(bool success); scoped_refptr factory_; const std::string path_; serial::ConnectionOptionsPtr options_; mojo::InterfaceRequest connection_request_; mojo::InterfaceRequest sink_; mojo::InterfaceRequest source_; scoped_refptr io_handler_; DISALLOW_COPY_AND_ASSIGN(ConnectTask); }; SerialConnectionFactory::SerialConnectionFactory( const IoHandlerFactory& io_handler_factory, scoped_refptr connect_message_loop) : io_handler_factory_(io_handler_factory), connect_message_loop_(connect_message_loop) { } void SerialConnectionFactory::CreateConnection( const std::string& path, serial::ConnectionOptionsPtr options, mojo::InterfaceRequest connection_request, mojo::InterfaceRequest sink, mojo::InterfaceRequest source) { scoped_refptr task(new ConnectTask(this, path, options.Pass(), connection_request.Pass(), sink.Pass(), source.Pass())); task->Run(); } SerialConnectionFactory::~SerialConnectionFactory() { } SerialConnectionFactory::ConnectTask::ConnectTask( scoped_refptr factory, const std::string& path, serial::ConnectionOptionsPtr options, mojo::InterfaceRequest connection_request, mojo::InterfaceRequest sink, mojo::InterfaceRequest source) : factory_(factory), path_(path), options_(options.Pass()), connection_request_(connection_request.Pass()), sink_(sink.Pass()), source_(source.Pass()) { } void SerialConnectionFactory::ConnectTask::Run() { factory_->connect_message_loop_->PostTask( FROM_HERE, base::Bind(&SerialConnectionFactory::ConnectTask::Connect, this)); } SerialConnectionFactory::ConnectTask::~ConnectTask() { } void SerialConnectionFactory::ConnectTask::Connect() { io_handler_ = factory_->io_handler_factory_.Run(); io_handler_->Open( path_, base::Bind(&SerialConnectionFactory::ConnectTask::OnConnected, this)); } void SerialConnectionFactory::ConnectTask::OnConnected(bool success) { DCHECK(io_handler_.get()); if (!success) return; if (!options_) options_ = serial::ConnectionOptions::New(); FillDefaultConnectionOptions(options_.get()); if (!io_handler_->ConfigurePort(*options_)) return; mojo::BindToRequest( new SerialConnection(io_handler_, sink_.Pass(), source_.Pass()), &connection_request_); } } // namespace device