1// Copyright 2014 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#include "device/serial/serial_connection_factory.h" 6 7#include "base/bind.h" 8#include "base/location.h" 9#include "device/serial/serial_connection.h" 10#include "device/serial/serial_io_handler.h" 11 12namespace device { 13namespace { 14 15void FillDefaultConnectionOptions(serial::ConnectionOptions* options) { 16 if (!options->bitrate) 17 options->bitrate = 9600; 18 if (options->data_bits == serial::DATA_BITS_NONE) 19 options->data_bits = serial::DATA_BITS_EIGHT; 20 if (options->stop_bits == serial::STOP_BITS_NONE) 21 options->stop_bits = serial::STOP_BITS_ONE; 22 if (options->parity_bit == serial::PARITY_BIT_NONE) 23 options->parity_bit = serial::PARITY_BIT_NO; 24 if (!options->has_cts_flow_control) { 25 options->has_cts_flow_control = true; 26 options->cts_flow_control = false; 27 } 28} 29 30} // namespace 31 32class SerialConnectionFactory::ConnectTask 33 : public base::RefCountedThreadSafe<SerialConnectionFactory::ConnectTask> { 34 public: 35 ConnectTask(scoped_refptr<SerialConnectionFactory> factory, 36 const std::string& path, 37 serial::ConnectionOptionsPtr options, 38 mojo::InterfaceRequest<serial::Connection> connection_request, 39 mojo::InterfaceRequest<serial::DataSink> sink, 40 mojo::InterfaceRequest<serial::DataSource> source); 41 void Run(); 42 43 private: 44 friend class base::RefCountedThreadSafe<SerialConnectionFactory::ConnectTask>; 45 virtual ~ConnectTask(); 46 void Connect(); 47 void OnConnected(bool success); 48 49 scoped_refptr<SerialConnectionFactory> factory_; 50 const std::string path_; 51 serial::ConnectionOptionsPtr options_; 52 mojo::InterfaceRequest<serial::Connection> connection_request_; 53 mojo::InterfaceRequest<serial::DataSink> sink_; 54 mojo::InterfaceRequest<serial::DataSource> source_; 55 scoped_refptr<SerialIoHandler> io_handler_; 56 57 DISALLOW_COPY_AND_ASSIGN(ConnectTask); 58}; 59 60SerialConnectionFactory::SerialConnectionFactory( 61 const IoHandlerFactory& io_handler_factory, 62 scoped_refptr<base::MessageLoopProxy> connect_message_loop) 63 : io_handler_factory_(io_handler_factory), 64 connect_message_loop_(connect_message_loop) { 65} 66 67void SerialConnectionFactory::CreateConnection( 68 const std::string& path, 69 serial::ConnectionOptionsPtr options, 70 mojo::InterfaceRequest<serial::Connection> connection_request, 71 mojo::InterfaceRequest<serial::DataSink> sink, 72 mojo::InterfaceRequest<serial::DataSource> source) { 73 scoped_refptr<ConnectTask> task(new ConnectTask(this, 74 path, 75 options.Pass(), 76 connection_request.Pass(), 77 sink.Pass(), 78 source.Pass())); 79 task->Run(); 80} 81 82SerialConnectionFactory::~SerialConnectionFactory() { 83} 84 85SerialConnectionFactory::ConnectTask::ConnectTask( 86 scoped_refptr<SerialConnectionFactory> factory, 87 const std::string& path, 88 serial::ConnectionOptionsPtr options, 89 mojo::InterfaceRequest<serial::Connection> connection_request, 90 mojo::InterfaceRequest<serial::DataSink> sink, 91 mojo::InterfaceRequest<serial::DataSource> source) 92 : factory_(factory), 93 path_(path), 94 options_(options.Pass()), 95 connection_request_(connection_request.Pass()), 96 sink_(sink.Pass()), 97 source_(source.Pass()) { 98} 99 100void SerialConnectionFactory::ConnectTask::Run() { 101 factory_->connect_message_loop_->PostTask( 102 FROM_HERE, 103 base::Bind(&SerialConnectionFactory::ConnectTask::Connect, this)); 104} 105 106SerialConnectionFactory::ConnectTask::~ConnectTask() { 107} 108 109void SerialConnectionFactory::ConnectTask::Connect() { 110 io_handler_ = factory_->io_handler_factory_.Run(); 111 io_handler_->Open( 112 path_, 113 base::Bind(&SerialConnectionFactory::ConnectTask::OnConnected, this)); 114} 115 116void SerialConnectionFactory::ConnectTask::OnConnected(bool success) { 117 DCHECK(io_handler_.get()); 118 if (!success) 119 return; 120 if (!options_) 121 options_ = serial::ConnectionOptions::New(); 122 FillDefaultConnectionOptions(options_.get()); 123 if (!io_handler_->ConfigurePort(*options_)) 124 return; 125 mojo::BindToRequest( 126 new SerialConnection(io_handler_, sink_.Pass(), source_.Pass()), 127 &connection_request_); 128} 129 130} // namespace device 131