| 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_win.h" | 5 #include "device/serial/serial_io_handler_win.h" |
| 6 | 6 |
| 7 #define INITGUID | 7 #define INITGUID |
| 8 #include <devpkey.h> | 8 #include <devpkey.h> |
| 9 #include <setupapi.h> | 9 #include <setupapi.h> |
| 10 #include <windows.h> | 10 #include <windows.h> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/scoped_observer.h" | 14 #include "base/scoped_observer.h" |
| 15 #include "base/threading/thread_checker.h" | 15 #include "base/sequence_checker.h" |
| 16 #include "device/base/device_info_query_win.h" | 16 #include "device/base/device_info_query_win.h" |
| 17 #include "device/base/device_monitor_win.h" | 17 #include "device/base/device_monitor_win.h" |
| 18 #include "third_party/re2/src/re2/re2.h" | 18 #include "third_party/re2/src/re2/re2.h" |
| 19 | 19 |
| 20 namespace device { | 20 namespace device { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 int BitrateToSpeedConstant(int bitrate) { | 24 int BitrateToSpeedConstant(int bitrate) { |
| 25 #define BITRATE_TO_SPEED_CASE(x) \ | 25 #define BITRATE_TO_SPEED_CASE(x) \ |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 ScopedObserver<DeviceMonitorWin, DeviceMonitorWin::Observer> device_observer_; | 189 ScopedObserver<DeviceMonitorWin, DeviceMonitorWin::Observer> device_observer_; |
| 190 | 190 |
| 191 // This weak pointer is only valid when checked on this task runner. | 191 // This weak pointer is only valid when checked on this task runner. |
| 192 base::WeakPtr<SerialIoHandlerWin> io_handler_; | 192 base::WeakPtr<SerialIoHandlerWin> io_handler_; |
| 193 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_; | 193 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_; |
| 194 | 194 |
| 195 DISALLOW_COPY_AND_ASSIGN(UiThreadHelper); | 195 DISALLOW_COPY_AND_ASSIGN(UiThreadHelper); |
| 196 }; | 196 }; |
| 197 | 197 |
| 198 void SerialIoHandlerWin::OnDeviceRemoved(const std::string& device_path) { | 198 void SerialIoHandlerWin::OnDeviceRemoved(const std::string& device_path) { |
| 199 DCHECK(CalledOnValidThread()); | 199 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 200 | 200 |
| 201 DeviceInfoQueryWin device_info_query; | 201 DeviceInfoQueryWin device_info_query; |
| 202 if (!device_info_query.device_info_list_valid()) { | 202 if (!device_info_query.device_info_list_valid()) { |
| 203 DVPLOG(1) << "Failed to create a device information set"; | 203 DVPLOG(1) << "Failed to create a device information set"; |
| 204 return; | 204 return; |
| 205 } | 205 } |
| 206 | 206 |
| 207 // This will add the device so we can query driver info. | 207 // This will add the device so we can query driver info. |
| 208 if (!device_info_query.AddDevice(device_path)) { | 208 if (!device_info_query.AddDevice(device_path)) { |
| 209 DVPLOG(1) << "Failed to get device interface data for " << device_path; | 209 DVPLOG(1) << "Failed to get device interface data for " << device_path; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 timeouts.ReadIntervalTimeout = MAXDWORD; | 259 timeouts.ReadIntervalTimeout = MAXDWORD; |
| 260 if (!::SetCommTimeouts(file().GetPlatformFile(), &timeouts)) { | 260 if (!::SetCommTimeouts(file().GetPlatformFile(), &timeouts)) { |
| 261 VPLOG(1) << "Failed to set serial timeouts"; | 261 VPLOG(1) << "Failed to set serial timeouts"; |
| 262 return false; | 262 return false; |
| 263 } | 263 } |
| 264 | 264 |
| 265 return true; | 265 return true; |
| 266 } | 266 } |
| 267 | 267 |
| 268 void SerialIoHandlerWin::ReadImpl() { | 268 void SerialIoHandlerWin::ReadImpl() { |
| 269 DCHECK(CalledOnValidThread()); | 269 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 270 DCHECK(pending_read_buffer()); | 270 DCHECK(pending_read_buffer()); |
| 271 DCHECK(file().IsValid()); | 271 DCHECK(file().IsValid()); |
| 272 | 272 |
| 273 if (!SetCommMask(file().GetPlatformFile(), EV_RXCHAR)) { | 273 if (!SetCommMask(file().GetPlatformFile(), EV_RXCHAR)) { |
| 274 VPLOG(1) << "Failed to set serial event flags"; | 274 VPLOG(1) << "Failed to set serial event flags"; |
| 275 } | 275 } |
| 276 | 276 |
| 277 event_mask_ = 0; | 277 event_mask_ = 0; |
| 278 BOOL ok = ::WaitCommEvent( | 278 BOOL ok = ::WaitCommEvent( |
| 279 file().GetPlatformFile(), &event_mask_, &comm_context_->overlapped); | 279 file().GetPlatformFile(), &event_mask_, &comm_context_->overlapped); |
| 280 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 280 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
| 281 VPLOG(1) << "Failed to receive serial event"; | 281 VPLOG(1) << "Failed to receive serial event"; |
| 282 QueueReadCompleted(0, serial::ReceiveError::SYSTEM_ERROR); | 282 QueueReadCompleted(0, serial::ReceiveError::SYSTEM_ERROR); |
| 283 } | 283 } |
| 284 is_comm_pending_ = true; | 284 is_comm_pending_ = true; |
| 285 } | 285 } |
| 286 | 286 |
| 287 void SerialIoHandlerWin::WriteImpl() { | 287 void SerialIoHandlerWin::WriteImpl() { |
| 288 DCHECK(CalledOnValidThread()); | 288 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 289 DCHECK(pending_write_buffer()); | 289 DCHECK(pending_write_buffer()); |
| 290 DCHECK(file().IsValid()); | 290 DCHECK(file().IsValid()); |
| 291 | 291 |
| 292 BOOL ok = ::WriteFile(file().GetPlatformFile(), | 292 BOOL ok = ::WriteFile(file().GetPlatformFile(), |
| 293 pending_write_buffer(), | 293 pending_write_buffer(), |
| 294 pending_write_buffer_len(), | 294 pending_write_buffer_len(), |
| 295 NULL, | 295 NULL, |
| 296 &write_context_->overlapped); | 296 &write_context_->overlapped); |
| 297 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 297 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
| 298 VPLOG(1) << "Write failed"; | 298 VPLOG(1) << "Write failed"; |
| 299 QueueWriteCompleted(0, serial::SendError::SYSTEM_ERROR); | 299 QueueWriteCompleted(0, serial::SendError::SYSTEM_ERROR); |
| 300 } | 300 } |
| 301 } | 301 } |
| 302 | 302 |
| 303 void SerialIoHandlerWin::CancelReadImpl() { | 303 void SerialIoHandlerWin::CancelReadImpl() { |
| 304 DCHECK(CalledOnValidThread()); | 304 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 305 DCHECK(file().IsValid()); | 305 DCHECK(file().IsValid()); |
| 306 ::CancelIo(file().GetPlatformFile()); | 306 ::CancelIo(file().GetPlatformFile()); |
| 307 } | 307 } |
| 308 | 308 |
| 309 void SerialIoHandlerWin::CancelWriteImpl() { | 309 void SerialIoHandlerWin::CancelWriteImpl() { |
| 310 DCHECK(CalledOnValidThread()); | 310 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 311 DCHECK(file().IsValid()); | 311 DCHECK(file().IsValid()); |
| 312 ::CancelIo(file().GetPlatformFile()); | 312 ::CancelIo(file().GetPlatformFile()); |
| 313 } | 313 } |
| 314 | 314 |
| 315 bool SerialIoHandlerWin::ConfigurePortImpl() { | 315 bool SerialIoHandlerWin::ConfigurePortImpl() { |
| 316 DCB config = {0}; | 316 DCB config = {0}; |
| 317 config.DCBlength = sizeof(config); | 317 config.DCBlength = sizeof(config); |
| 318 if (!GetCommState(file().GetPlatformFile(), &config)) { | 318 if (!GetCommState(file().GetPlatformFile(), &config)) { |
| 319 VPLOG(1) << "Failed to get serial port info"; | 319 VPLOG(1) << "Failed to get serial port info"; |
| 320 return false; | 320 return false; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 weak_factory_(this) {} | 368 weak_factory_(this) {} |
| 369 | 369 |
| 370 SerialIoHandlerWin::~SerialIoHandlerWin() { | 370 SerialIoHandlerWin::~SerialIoHandlerWin() { |
| 371 ui_thread_task_runner()->DeleteSoon(FROM_HERE, helper_); | 371 ui_thread_task_runner()->DeleteSoon(FROM_HERE, helper_); |
| 372 } | 372 } |
| 373 | 373 |
| 374 void SerialIoHandlerWin::OnIOCompleted( | 374 void SerialIoHandlerWin::OnIOCompleted( |
| 375 base::MessageLoopForIO::IOContext* context, | 375 base::MessageLoopForIO::IOContext* context, |
| 376 DWORD bytes_transferred, | 376 DWORD bytes_transferred, |
| 377 DWORD error) { | 377 DWORD error) { |
| 378 DCHECK(CalledOnValidThread()); | 378 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 379 if (context == comm_context_.get()) { | 379 if (context == comm_context_.get()) { |
| 380 DWORD errors; | 380 DWORD errors; |
| 381 COMSTAT status; | 381 COMSTAT status; |
| 382 if (!ClearCommError(file().GetPlatformFile(), &errors, &status) || | 382 if (!ClearCommError(file().GetPlatformFile(), &errors, &status) || |
| 383 errors != 0) { | 383 errors != 0) { |
| 384 if (errors & CE_BREAK) { | 384 if (errors & CE_BREAK) { |
| 385 ReadCompleted(0, serial::ReceiveError::BREAK); | 385 ReadCompleted(0, serial::ReceiveError::BREAK); |
| 386 } else if (errors & CE_FRAME) { | 386 } else if (errors & CE_FRAME) { |
| 387 ReadCompleted(0, serial::ReceiveError::FRAME_ERROR); | 387 ReadCompleted(0, serial::ReceiveError::FRAME_ERROR); |
| 388 } else if (errors & CE_OVERRUN) { | 388 } else if (errors & CE_OVERRUN) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { | 528 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { |
| 529 // For COM numbers less than 9, CreateFile is called with a string such as | 529 // For COM numbers less than 9, CreateFile is called with a string such as |
| 530 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added. | 530 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added. |
| 531 if (port_name.length() > std::string("COM9").length()) | 531 if (port_name.length() > std::string("COM9").length()) |
| 532 return std::string("\\\\.\\").append(port_name); | 532 return std::string("\\\\.\\").append(port_name); |
| 533 | 533 |
| 534 return port_name; | 534 return port_name; |
| 535 } | 535 } |
| 536 | 536 |
| 537 } // namespace device | 537 } // namespace device |
| OLD | NEW |