1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/api/serial/serial_connection.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <string>
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/files/file_path.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/lazy_instance.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/api/api_resource_manager.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/api/serial.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace extensions {
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kDefaultBufferSize = 4096;
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdochcore_api::serial::SendError ConvertSendErrorFromMojo(
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    device::serial::SendError input) {
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (input) {
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::SEND_ERROR_NONE:
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::SEND_ERROR_NONE;
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::SEND_ERROR_DISCONNECTED:
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::SEND_ERROR_DISCONNECTED;
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::SEND_ERROR_PENDING:
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::SEND_ERROR_PENDING;
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::SEND_ERROR_TIMEOUT:
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::SEND_ERROR_TIMEOUT;
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::SEND_ERROR_SYSTEM_ERROR:
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::SEND_ERROR_SYSTEM_ERROR;
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return core_api::serial::SEND_ERROR_NONE;
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdochcore_api::serial::ReceiveError ConvertReceiveErrorFromMojo(
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    device::serial::ReceiveError input) {
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (input) {
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::RECEIVE_ERROR_NONE:
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::RECEIVE_ERROR_NONE;
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::RECEIVE_ERROR_DISCONNECTED:
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::RECEIVE_ERROR_DISCONNECTED;
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::RECEIVE_ERROR_TIMEOUT:
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::RECEIVE_ERROR_TIMEOUT;
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::RECEIVE_ERROR_DEVICE_LOST:
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::RECEIVE_ERROR_DEVICE_LOST;
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::RECEIVE_ERROR_SYSTEM_ERROR:
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::RECEIVE_ERROR_SYSTEM_ERROR;
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return core_api::serial::RECEIVE_ERROR_NONE;
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdochcore_api::serial::DataBits ConvertDataBitsFromMojo(
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    device::serial::DataBits input) {
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (input) {
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::DATA_BITS_NONE:
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::DATA_BITS_NONE;
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::DATA_BITS_SEVEN:
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::DATA_BITS_SEVEN;
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::DATA_BITS_EIGHT:
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::DATA_BITS_EIGHT;
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return core_api::serial::DATA_BITS_NONE;
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdochdevice::serial::DataBits ConvertDataBitsToMojo(
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    core_api::serial::DataBits input) {
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (input) {
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case core_api::serial::DATA_BITS_NONE:
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return device::serial::DATA_BITS_NONE;
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case core_api::serial::DATA_BITS_SEVEN:
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return device::serial::DATA_BITS_SEVEN;
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case core_api::serial::DATA_BITS_EIGHT:
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return device::serial::DATA_BITS_EIGHT;
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return device::serial::DATA_BITS_NONE;
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdochcore_api::serial::ParityBit ConvertParityBitFromMojo(
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    device::serial::ParityBit input) {
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (input) {
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::PARITY_BIT_NONE:
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::PARITY_BIT_NONE;
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::PARITY_BIT_ODD:
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::PARITY_BIT_ODD;
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::PARITY_BIT_NO:
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::PARITY_BIT_NO;
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::PARITY_BIT_EVEN:
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::PARITY_BIT_EVEN;
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return core_api::serial::PARITY_BIT_NONE;
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdochdevice::serial::ParityBit ConvertParityBitToMojo(
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    core_api::serial::ParityBit input) {
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (input) {
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case core_api::serial::PARITY_BIT_NONE:
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return device::serial::PARITY_BIT_NONE;
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case core_api::serial::PARITY_BIT_NO:
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return device::serial::PARITY_BIT_NO;
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case core_api::serial::PARITY_BIT_ODD:
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return device::serial::PARITY_BIT_ODD;
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case core_api::serial::PARITY_BIT_EVEN:
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return device::serial::PARITY_BIT_EVEN;
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return device::serial::PARITY_BIT_NONE;
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdochcore_api::serial::StopBits ConvertStopBitsFromMojo(
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    device::serial::StopBits input) {
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (input) {
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::STOP_BITS_NONE:
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::STOP_BITS_NONE;
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::STOP_BITS_ONE:
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::STOP_BITS_ONE;
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case device::serial::STOP_BITS_TWO:
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return core_api::serial::STOP_BITS_TWO;
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return core_api::serial::STOP_BITS_NONE;
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdochdevice::serial::StopBits ConvertStopBitsToMojo(
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    core_api::serial::StopBits input) {
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (input) {
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case core_api::serial::STOP_BITS_NONE:
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return device::serial::STOP_BITS_NONE;
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case core_api::serial::STOP_BITS_ONE:
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return device::serial::STOP_BITS_ONE;
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case core_api::serial::STOP_BITS_TWO:
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return device::serial::STOP_BITS_TWO;
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return device::serial::STOP_BITS_NONE;
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class SendBuffer : public device::ReadOnlyBuffer {
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SendBuffer(
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const std::string& data,
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const base::Callback<void(int, device::serial::SendError)>& callback)
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : data_(data), callback_(callback) {}
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~SendBuffer() {}
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual const char* GetData() OVERRIDE { return data_.c_str(); }
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual uint32_t GetSize() OVERRIDE {
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return static_cast<uint32_t>(data_.size());
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Done(uint32_t bytes_read) OVERRIDE {
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback_.Run(bytes_read, device::serial::SEND_ERROR_NONE);
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void DoneWithError(uint32_t bytes_read, int32_t error) OVERRIDE {
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback_.Run(bytes_read, static_cast<device::serial::SendError>(error));
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const std::string data_;
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::Callback<void(int, device::serial::SendError)> callback_;
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ReceiveBuffer : public device::WritableBuffer {
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ReceiveBuffer(
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      scoped_refptr<net::IOBuffer> buffer,
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      uint32_t size,
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const base::Callback<void(int, device::serial::ReceiveError)>& callback)
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : buffer_(buffer), size_(size), callback_(callback) {}
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~ReceiveBuffer() {}
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual char* GetData() OVERRIDE { return buffer_->data(); }
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual uint32_t GetSize() OVERRIDE { return size_; }
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Done(uint32_t bytes_written) OVERRIDE {
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback_.Run(bytes_written, device::serial::RECEIVE_ERROR_NONE);
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void DoneWithError(uint32_t bytes_written, int32_t error) OVERRIDE {
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback_.Run(bytes_written,
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                  static_cast<device::serial::ReceiveError>(error));
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer_;
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const uint32_t size_;
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::Callback<void(int, device::serial::ReceiveError)> callback_;
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic base::LazyInstance<
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    BrowserContextKeyedAPIFactory<ApiResourceManager<SerialConnection> > >
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    g_factory = LAZY_INSTANCE_INITIALIZER;
188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtemplate <>
191116680a4aac90f2aa7413d9095a592090648e557Ben MurdochBrowserContextKeyedAPIFactory<ApiResourceManager<SerialConnection> >*
192116680a4aac90f2aa7413d9095a592090648e557Ben MurdochApiResourceManager<SerialConnection>::GetFactoryInstance() {
193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return g_factory.Pointer();
194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
196116680a4aac90f2aa7413d9095a592090648e557Ben MurdochSerialConnection::SerialConnection(const std::string& port,
197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   const std::string& owner_extension_id)
198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : ApiResource(owner_extension_id),
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      port_(port),
200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      persistent_(false),
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      buffer_size_(kDefaultBufferSize),
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      receive_timeout_(0),
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      send_timeout_(0),
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      paused_(false),
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      io_handler_(device::SerialIoHandler::Create(
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          content::BrowserThread::GetMessageLoopProxyForThread(
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              content::BrowserThread::FILE))) {
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
211116680a4aac90f2aa7413d9095a592090648e557Ben MurdochSerialConnection::~SerialConnection() {
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  io_handler_->CancelRead(device::serial::RECEIVE_ERROR_DISCONNECTED);
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  io_handler_->CancelWrite(device::serial::SEND_ERROR_DISCONNECTED);
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool SerialConnection::IsPersistent() const {
217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return persistent();
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SerialConnection::set_buffer_size(int buffer_size) {
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  buffer_size_ = buffer_size;
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SerialConnection::set_receive_timeout(int receive_timeout) {
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  receive_timeout_ = receive_timeout;
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SerialConnection::set_send_timeout(int send_timeout) {
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  send_timeout_ = send_timeout;
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SerialConnection::set_paused(bool paused) {
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  paused_ = paused;
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (paused) {
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    io_handler_->CancelRead(device::serial::RECEIVE_ERROR_NONE);
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SerialConnection::Open(const OpenCompleteCallback& callback) {
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  io_handler_->Open(port_, callback);
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool SerialConnection::Receive(const ReceiveCompleteCallback& callback) {
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!receive_complete_.is_null())
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  receive_complete_ = callback;
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  receive_buffer_ = new net::IOBuffer(buffer_size_);
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  io_handler_->Read(scoped_ptr<device::WritableBuffer>(new ReceiveBuffer(
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      receive_buffer_,
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      buffer_size_,
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&SerialConnection::OnAsyncReadComplete, AsWeakPtr()))));
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  receive_timeout_task_.reset();
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (receive_timeout_ > 0) {
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    receive_timeout_task_.reset(new TimeoutTask(
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(&SerialConnection::OnReceiveTimeout, AsWeakPtr()),
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::TimeDelta::FromMilliseconds(receive_timeout_)));
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return true;
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool SerialConnection::Send(const std::string& data,
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            const SendCompleteCallback& callback) {
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!send_complete_.is_null())
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  send_complete_ = callback;
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  io_handler_->Write(scoped_ptr<device::ReadOnlyBuffer>(new SendBuffer(
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      data, base::Bind(&SerialConnection::OnAsyncWriteComplete, AsWeakPtr()))));
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  send_timeout_task_.reset();
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (send_timeout_ > 0) {
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    send_timeout_task_.reset(new TimeoutTask(
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(&SerialConnection::OnSendTimeout, AsWeakPtr()),
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::TimeDelta::FromMilliseconds(send_timeout_)));
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return true;
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool SerialConnection::Configure(
281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const core_api::serial::ConnectionOptions& options) {
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (options.persistent.get())
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    set_persistent(*options.persistent);
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (options.name.get())
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    set_name(*options.name);
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (options.buffer_size.get())
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    set_buffer_size(*options.buffer_size);
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (options.receive_timeout.get())
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    set_receive_timeout(*options.receive_timeout);
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (options.send_timeout.get())
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    set_send_timeout(*options.send_timeout);
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool success = io_handler_->ConfigurePort(
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *device::serial::ConnectionOptions::From(options));
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  io_handler_->CancelRead(device::serial::RECEIVE_ERROR_NONE);
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return success;
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SerialConnection::SetIoHandlerForTest(
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<device::SerialIoHandler> handler) {
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  io_handler_ = handler;
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool SerialConnection::GetInfo(core_api::serial::ConnectionInfo* info) const {
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->paused = paused_;
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->persistent = persistent_;
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->name = name_;
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->buffer_size = buffer_size_;
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->receive_timeout = receive_timeout_;
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->send_timeout = send_timeout_;
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  device::serial::ConnectionInfoPtr port_info = io_handler_->GetPortInfo();
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!port_info)
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->bitrate.reset(new int(port_info->bitrate));
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->data_bits = ConvertDataBitsFromMojo(port_info->data_bits);
318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->parity_bit = ConvertParityBitFromMojo(port_info->parity_bit);
319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->stop_bits = ConvertStopBitsFromMojo(port_info->stop_bits);
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  info->cts_flow_control.reset(new bool(port_info->cts_flow_control));
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return true;
322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool SerialConnection::Flush() const {
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return io_handler_->Flush();
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool SerialConnection::GetControlSignals(
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    core_api::serial::DeviceControlSignals* control_signals) const {
330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  device::serial::DeviceControlSignalsPtr signals =
331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      io_handler_->GetControlSignals();
332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!signals)
333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  control_signals->dcd = signals->dcd;
336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  control_signals->cts = signals->cts;
337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  control_signals->ri = signals->ri;
338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  control_signals->dsr = signals->dsr;
339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return true;
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool SerialConnection::SetControlSignals(
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const core_api::serial::HostControlSignals& control_signals) {
344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return io_handler_->SetControlSignals(
345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *device::serial::HostControlSignals::From(control_signals));
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SerialConnection::OnReceiveTimeout() {
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  io_handler_->CancelRead(device::serial::RECEIVE_ERROR_TIMEOUT);
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SerialConnection::OnSendTimeout() {
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  io_handler_->CancelWrite(device::serial::SEND_ERROR_TIMEOUT);
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SerialConnection::OnAsyncReadComplete(int bytes_read,
359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                           device::serial::ReceiveError error) {
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(!receive_complete_.is_null());
362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ReceiveCompleteCallback callback = receive_complete_;
363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  receive_complete_.Reset();
364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  receive_timeout_task_.reset();
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  callback.Run(std::string(receive_buffer_->data(), bytes_read),
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               ConvertReceiveErrorFromMojo(error));
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  receive_buffer_ = NULL;
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
370116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SerialConnection::OnAsyncWriteComplete(int bytes_sent,
371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            device::serial::SendError error) {
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(!send_complete_.is_null());
374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SendCompleteCallback callback = send_complete_;
375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  send_complete_.Reset();
376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  send_timeout_task_.reset();
377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  callback.Run(bytes_sent, ConvertSendErrorFromMojo(error));
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
380116680a4aac90f2aa7413d9095a592090648e557Ben MurdochSerialConnection::TimeoutTask::TimeoutTask(const base::Closure& closure,
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                           const base::TimeDelta& delay)
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : weak_factory_(this), closure_(closure), delay_(delay) {
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::MessageLoop::current()->PostDelayedTask(
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&TimeoutTask::Run, weak_factory_.GetWeakPtr()),
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      delay_);
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
389116680a4aac90f2aa7413d9095a592090648e557Ben MurdochSerialConnection::TimeoutTask::~TimeoutTask() {
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SerialConnection::TimeoutTask::Run() const {
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  closure_.Run();
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace extensions
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace mojo {
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
401116680a4aac90f2aa7413d9095a592090648e557Ben Murdochdevice::serial::HostControlSignalsPtr
402116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTypeConverter<device::serial::HostControlSignalsPtr,
403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              extensions::core_api::serial::HostControlSignals>::
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Convert(const extensions::core_api::serial::HostControlSignals& input) {
405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  device::serial::HostControlSignalsPtr output(
406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      device::serial::HostControlSignals::New());
407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (input.dtr.get()) {
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    output->has_dtr = true;
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    output->dtr = *input.dtr;
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (input.rts.get()) {
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    output->has_rts = true;
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    output->rts = *input.rts;
414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return output.Pass();
416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
419116680a4aac90f2aa7413d9095a592090648e557Ben Murdochdevice::serial::ConnectionOptionsPtr
420116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTypeConverter<device::serial::ConnectionOptionsPtr,
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              extensions::core_api::serial::ConnectionOptions>::
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Convert(const extensions::core_api::serial::ConnectionOptions& input) {
423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  device::serial::ConnectionOptionsPtr output(
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      device::serial::ConnectionOptions::New());
425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (input.bitrate.get() && *input.bitrate > 0)
426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    output->bitrate = *input.bitrate;
427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  output->data_bits = extensions::ConvertDataBitsToMojo(input.data_bits);
428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  output->parity_bit = extensions::ConvertParityBitToMojo(input.parity_bit);
429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  output->stop_bits = extensions::ConvertStopBitsToMojo(input.stop_bits);
430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (input.cts_flow_control.get()) {
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    output->has_cts_flow_control = true;
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    output->cts_flow_control = *input.cts_flow_control;
433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return output.Pass();
435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace mojo
438