OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "device/serial/serial_io_handler.h" | 5 #include "device/serial/serial_io_handler.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 | 11 |
12 namespace device { | 12 namespace device { |
13 | 13 |
14 SerialIoHandler::SerialIoHandler( | 14 SerialIoHandler::SerialIoHandler( |
15 scoped_refptr<base::MessageLoopProxy> file_thread_message_loop, | 15 scoped_refptr<base::MessageLoopProxy> file_thread_message_loop, |
16 scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop) | 16 scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop) |
17 : file_thread_message_loop_(file_thread_message_loop), | 17 : file_thread_message_loop_(file_thread_message_loop), |
18 ui_thread_message_loop_(ui_thread_message_loop) { | 18 ui_thread_message_loop_(ui_thread_message_loop) { |
| 19 options_.bitrate = 9600; |
| 20 options_.data_bits = serial::DATA_BITS_EIGHT; |
| 21 options_.parity_bit = serial::PARITY_BIT_NO; |
| 22 options_.stop_bits = serial::STOP_BITS_ONE; |
| 23 options_.cts_flow_control = false; |
| 24 options_.has_cts_flow_control = true; |
19 } | 25 } |
20 | 26 |
21 SerialIoHandler::~SerialIoHandler() { | 27 SerialIoHandler::~SerialIoHandler() { |
22 DCHECK(CalledOnValidThread()); | 28 DCHECK(CalledOnValidThread()); |
23 Close(); | 29 Close(); |
24 } | 30 } |
25 | 31 |
26 void SerialIoHandler::Open(const std::string& port, | 32 void SerialIoHandler::Open(const std::string& port, |
| 33 const serial::ConnectionOptions& options, |
27 const OpenCompleteCallback& callback) { | 34 const OpenCompleteCallback& callback) { |
28 DCHECK(CalledOnValidThread()); | 35 DCHECK(CalledOnValidThread()); |
29 DCHECK(open_complete_.is_null()); | 36 DCHECK(open_complete_.is_null()); |
30 open_complete_ = callback; | 37 open_complete_ = callback; |
31 DCHECK(file_thread_message_loop_.get()); | 38 DCHECK(file_thread_message_loop_.get()); |
32 DCHECK(ui_thread_message_loop_.get()); | 39 DCHECK(ui_thread_message_loop_.get()); |
| 40 MergeConnectionOptions(options); |
33 RequestAccess(port, file_thread_message_loop_, ui_thread_message_loop_); | 41 RequestAccess(port, file_thread_message_loop_, ui_thread_message_loop_); |
34 } | 42 } |
35 | 43 |
36 void SerialIoHandler::RequestAccess( | 44 void SerialIoHandler::RequestAccess( |
37 const std::string& port, | 45 const std::string& port, |
38 scoped_refptr<base::MessageLoopProxy> file_message_loop, | 46 scoped_refptr<base::MessageLoopProxy> file_message_loop, |
39 scoped_refptr<base::MessageLoopProxy> ui_message_loop) { | 47 scoped_refptr<base::MessageLoopProxy> ui_message_loop) { |
40 OnRequestAccessComplete(port, true /* success */); | 48 OnRequestAccessComplete(port, true /* success */); |
41 } | 49 } |
42 | 50 |
(...skipping 11 matching lines...) Expand all Loading... |
54 return; | 62 return; |
55 } else { | 63 } else { |
56 DCHECK(!open_complete_.is_null()); | 64 DCHECK(!open_complete_.is_null()); |
57 OpenCompleteCallback callback = open_complete_; | 65 OpenCompleteCallback callback = open_complete_; |
58 open_complete_.Reset(); | 66 open_complete_.Reset(); |
59 callback.Run(false); | 67 callback.Run(false); |
60 return; | 68 return; |
61 } | 69 } |
62 } | 70 } |
63 | 71 |
| 72 void SerialIoHandler::MergeConnectionOptions( |
| 73 const serial::ConnectionOptions& options) { |
| 74 if (options.bitrate) { |
| 75 options_.bitrate = options.bitrate; |
| 76 } |
| 77 if (options.data_bits != serial::DATA_BITS_NONE) { |
| 78 options_.data_bits = options.data_bits; |
| 79 } |
| 80 if (options.parity_bit != serial::PARITY_BIT_NONE) { |
| 81 options_.parity_bit = options.parity_bit; |
| 82 } |
| 83 if (options.stop_bits != serial::STOP_BITS_NONE) { |
| 84 options_.stop_bits = options.stop_bits; |
| 85 } |
| 86 if (options.has_cts_flow_control) { |
| 87 DCHECK(options_.has_cts_flow_control); |
| 88 options_.cts_flow_control = options.cts_flow_control; |
| 89 } |
| 90 } |
| 91 |
64 void SerialIoHandler::StartOpen( | 92 void SerialIoHandler::StartOpen( |
65 const std::string& port, | 93 const std::string& port, |
66 scoped_refptr<base::MessageLoopProxy> io_message_loop) { | 94 scoped_refptr<base::MessageLoopProxy> io_message_loop) { |
67 DCHECK(!open_complete_.is_null()); | 95 DCHECK(!open_complete_.is_null()); |
68 DCHECK(file_thread_message_loop_->RunsTasksOnCurrentThread()); | 96 DCHECK(file_thread_message_loop_->RunsTasksOnCurrentThread()); |
69 DCHECK(!file_.IsValid()); | 97 DCHECK(!file_.IsValid()); |
70 // It's the responsibility of the API wrapper around SerialIoHandler to | 98 // It's the responsibility of the API wrapper around SerialIoHandler to |
71 // validate the supplied path against the set of valid port names, and | 99 // validate the supplied path against the set of valid port names, and |
72 // it is a reasonable assumption that serial port names are ASCII. | 100 // it is a reasonable assumption that serial port names are ASCII. |
73 DCHECK(base::IsStringASCII(port)); | 101 DCHECK(base::IsStringASCII(port)); |
74 base::FilePath path(base::FilePath::FromUTF8Unsafe(MaybeFixUpPortName(port))); | 102 base::FilePath path(base::FilePath::FromUTF8Unsafe(MaybeFixUpPortName(port))); |
75 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | | 103 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | |
76 base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_WRITE | | 104 base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_WRITE | |
77 base::File::FLAG_EXCLUSIVE_WRITE | base::File::FLAG_ASYNC | | 105 base::File::FLAG_EXCLUSIVE_WRITE | base::File::FLAG_ASYNC | |
78 base::File::FLAG_TERMINAL_DEVICE; | 106 base::File::FLAG_TERMINAL_DEVICE; |
79 base::File file(path, flags); | 107 base::File file(path, flags); |
80 io_message_loop->PostTask( | 108 io_message_loop->PostTask( |
81 FROM_HERE, | 109 FROM_HERE, |
82 base::Bind(&SerialIoHandler::FinishOpen, this, Passed(file.Pass()))); | 110 base::Bind(&SerialIoHandler::FinishOpen, this, Passed(file.Pass()))); |
83 } | 111 } |
84 | 112 |
85 void SerialIoHandler::FinishOpen(base::File file) { | 113 void SerialIoHandler::FinishOpen(base::File file) { |
86 DCHECK(CalledOnValidThread()); | 114 DCHECK(CalledOnValidThread()); |
87 DCHECK(!open_complete_.is_null()); | 115 DCHECK(!open_complete_.is_null()); |
88 OpenCompleteCallback callback = open_complete_; | 116 OpenCompleteCallback callback = open_complete_; |
89 open_complete_.Reset(); | 117 open_complete_.Reset(); |
90 | 118 |
91 if (!file.IsValid()) { | 119 if (!file.IsValid()) { |
| 120 LOG(ERROR) << "Failed to open serial port: " |
| 121 << base::File::ErrorToString(file.error_details()); |
92 callback.Run(false); | 122 callback.Run(false); |
93 return; | 123 return; |
94 } | 124 } |
95 | 125 |
96 file_ = file.Pass(); | 126 file_ = file.Pass(); |
97 | 127 |
98 bool success = PostOpen(); | 128 bool success = PostOpen() && ConfigurePortImpl(); |
99 if (!success) | 129 if (!success) { |
100 Close(); | 130 Close(); |
| 131 } |
| 132 |
101 callback.Run(success); | 133 callback.Run(success); |
102 } | 134 } |
103 | 135 |
104 bool SerialIoHandler::PostOpen() { | 136 bool SerialIoHandler::PostOpen() { |
105 return true; | 137 return true; |
106 } | 138 } |
107 | 139 |
108 void SerialIoHandler::Close() { | 140 void SerialIoHandler::Close() { |
109 if (file_.IsValid()) { | 141 if (file_.IsValid()) { |
110 DCHECK(file_thread_message_loop_.get()); | 142 DCHECK(file_thread_message_loop_.get()); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 | 216 |
185 void SerialIoHandler::CancelWrite(serial::SendError reason) { | 217 void SerialIoHandler::CancelWrite(serial::SendError reason) { |
186 DCHECK(CalledOnValidThread()); | 218 DCHECK(CalledOnValidThread()); |
187 if (IsWritePending() && !write_canceled_) { | 219 if (IsWritePending() && !write_canceled_) { |
188 write_canceled_ = true; | 220 write_canceled_ = true; |
189 write_cancel_reason_ = reason; | 221 write_cancel_reason_ = reason; |
190 CancelWriteImpl(); | 222 CancelWriteImpl(); |
191 } | 223 } |
192 } | 224 } |
193 | 225 |
| 226 bool SerialIoHandler::ConfigurePort(const serial::ConnectionOptions& options) { |
| 227 MergeConnectionOptions(options); |
| 228 return ConfigurePortImpl(); |
| 229 } |
| 230 |
194 void SerialIoHandler::QueueReadCompleted(int bytes_read, | 231 void SerialIoHandler::QueueReadCompleted(int bytes_read, |
195 serial::ReceiveError error) { | 232 serial::ReceiveError error) { |
196 base::MessageLoop::current()->PostTask( | 233 base::MessageLoop::current()->PostTask( |
197 FROM_HERE, | 234 FROM_HERE, |
198 base::Bind(&SerialIoHandler::ReadCompleted, this, bytes_read, error)); | 235 base::Bind(&SerialIoHandler::ReadCompleted, this, bytes_read, error)); |
199 } | 236 } |
200 | 237 |
201 void SerialIoHandler::QueueWriteCompleted(int bytes_written, | 238 void SerialIoHandler::QueueWriteCompleted(int bytes_written, |
202 serial::SendError error) { | 239 serial::SendError error) { |
203 base::MessageLoop::current()->PostTask( | 240 base::MessageLoop::current()->PostTask( |
204 FROM_HERE, | 241 FROM_HERE, |
205 base::Bind(&SerialIoHandler::WriteCompleted, this, bytes_written, error)); | 242 base::Bind(&SerialIoHandler::WriteCompleted, this, bytes_written, error)); |
206 } | 243 } |
207 | 244 |
208 } // namespace device | 245 } // namespace device |
OLD | NEW |