Chromium Code Reviews| 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" | |
| 6 | |
| 5 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <setupapi.h> | |
| 6 | 9 |
| 7 #include "device/serial/serial_io_handler_win.h" | 10 #include "base/bind.h" |
| 11 #include "base/scoped_observer.h" | |
| 12 #include "base/threading/thread_checker.h" | |
| 13 #include "device/core/device_info_query_win.h" | |
| 14 #include "device/core/device_monitor_win.h" | |
| 15 #include "third_party/re2/re2/re2.h" | |
| 8 | 16 |
| 9 namespace device { | 17 namespace device { |
| 10 | 18 |
| 11 namespace { | 19 namespace { |
| 12 | 20 |
| 13 int BitrateToSpeedConstant(int bitrate) { | 21 int BitrateToSpeedConstant(int bitrate) { |
| 14 #define BITRATE_TO_SPEED_CASE(x) \ | 22 #define BITRATE_TO_SPEED_CASE(x) \ |
| 15 case x: \ | 23 case x: \ |
| 16 return CBR_##x; | 24 return CBR_##x; |
| 17 switch (bitrate) { | 25 switch (bitrate) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 serial::StopBits StopBitsConstantToEnum(int stop_bits) { | 131 serial::StopBits StopBitsConstantToEnum(int stop_bits) { |
| 124 switch (stop_bits) { | 132 switch (stop_bits) { |
| 125 case TWOSTOPBITS: | 133 case TWOSTOPBITS: |
| 126 return serial::STOP_BITS_TWO; | 134 return serial::STOP_BITS_TWO; |
| 127 case ONESTOPBIT: | 135 case ONESTOPBIT: |
| 128 default: | 136 default: |
| 129 return serial::STOP_BITS_ONE; | 137 return serial::STOP_BITS_ONE; |
| 130 } | 138 } |
| 131 } | 139 } |
| 132 | 140 |
| 141 // Searches for the COM port in the device's friendly name, assigns its value to | |
| 142 // com_port, and returns whether the operation was successful. | |
| 143 bool GetCOMPort(const std::string friendly_name, std::string* com_port) { | |
| 144 return RE2::PartialMatch(friendly_name, ".* \\((COM[0-9]+)\\)", com_port); | |
| 145 } | |
| 146 | |
| 133 } // namespace | 147 } // namespace |
| 134 | 148 |
| 135 // static | 149 // static |
| 136 scoped_refptr<SerialIoHandler> SerialIoHandler::Create( | 150 scoped_refptr<SerialIoHandler> SerialIoHandler::Create( |
| 137 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, | 151 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, |
| 138 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) { | 152 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) { |
| 139 return new SerialIoHandlerWin(file_thread_task_runner, ui_thread_task_runner); | 153 return new SerialIoHandlerWin(file_thread_task_runner, ui_thread_task_runner); |
| 140 } | 154 } |
| 141 | 155 |
| 156 class SerialIoHandlerWin::UiThreadHelper : public DeviceMonitorWin::Observer { | |
| 157 public: | |
| 158 UiThreadHelper( | |
| 159 base::WeakPtr<SerialIoHandlerWin> io_handler, | |
| 160 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner) | |
| 161 : device_observer_(this), | |
| 162 io_handler_(io_handler), | |
| 163 io_thread_task_runner_(io_thread_task_runner) {} | |
| 164 | |
| 165 ~UiThreadHelper() { DCHECK(thread_checker_.CalledOnValidThread()); } | |
| 166 | |
| 167 static void Start(UiThreadHelper* self) { | |
| 168 self->thread_checker_.DetachFromThread(); | |
| 169 DeviceMonitorWin* device_monitor = DeviceMonitorWin::GetForAllInterfaces(); | |
| 170 if (device_monitor) | |
| 171 self->device_observer_.Add(device_monitor); | |
| 172 } | |
| 173 | |
| 174 private: | |
| 175 // DeviceMonitorWin::Observer | |
| 176 void OnDeviceRemoved(const GUID& class_guid, | |
| 177 const std::string& device_path) override { | |
| 178 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 179 io_thread_task_runner_->PostTask( | |
| 180 FROM_HERE, base::Bind(&SerialIoHandlerWin::OnDeviceRemoved, io_handler_, | |
| 181 device_path)); | |
| 182 } | |
| 183 | |
| 184 base::ThreadChecker thread_checker_; | |
| 185 ScopedObserver<DeviceMonitorWin, DeviceMonitorWin::Observer> device_observer_; | |
| 186 | |
| 187 // This weak pointer is only valid when checked on this task runner. | |
| 188 base::WeakPtr<SerialIoHandlerWin> io_handler_; | |
| 189 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_; | |
| 190 | |
| 191 DISALLOW_COPY_AND_ASSIGN(UiThreadHelper); | |
| 192 }; | |
| 193 | |
| 194 void SerialIoHandlerWin::OnDeviceRemoved(const std::string& device_path) { | |
| 195 DCHECK(CalledOnValidThread()); | |
| 196 | |
| 197 device::DeviceInfoQueryWin device_info_query; | |
| 198 if (!device_info_query.device_info_list_valid()) { | |
| 199 DVPLOG(1) << "Failed to create a device information set"; | |
| 200 return; | |
| 201 } | |
| 202 | |
| 203 // This will add the device so we can query driver info. | |
| 204 if (!device_info_query.AddDevice(device_path.c_str())) { | |
| 205 DVPLOG(1) << "Failed to get device interface data for " << device_path; | |
| 206 return; | |
| 207 } | |
| 208 | |
| 209 if (!device_info_query.GetDeviceInfo()) { | |
| 210 DVPLOG(1) << "Failed to get device info for " << device_path; | |
| 211 return; | |
| 212 } | |
| 213 | |
| 214 BYTE friendly_name[512]; | |
| 215 if (!SetupDiGetDeviceRegistryPropertyA( | |
| 216 device_info_query.device_info_list(), | |
| 217 device_info_query.device_info_data(), SPDRP_FRIENDLYNAME, NULL, | |
| 218 friendly_name, sizeof(friendly_name), NULL)) { | |
| 219 DVPLOG(1) << "Failed to get device service property"; | |
| 220 return; | |
| 221 } | |
| 222 | |
| 223 std::string com_port; | |
| 224 if (!GetCOMPort(reinterpret_cast<const char*>(friendly_name), &com_port)) { | |
| 225 DVPLOG(1) << "Failed to get port name from \"" << friendly_name << "\"."; | |
| 226 return; | |
| 227 } | |
| 228 | |
| 229 if (port() == com_port) | |
| 230 CancelRead(serial::RECEIVE_ERROR_DISCONNECTED); | |
| 231 } | |
| 232 | |
| 142 bool SerialIoHandlerWin::PostOpen() { | 233 bool SerialIoHandlerWin::PostOpen() { |
| 143 DCHECK(!comm_context_); | 234 DCHECK(!comm_context_); |
| 144 DCHECK(!read_context_); | 235 DCHECK(!read_context_); |
| 145 DCHECK(!write_context_); | 236 DCHECK(!write_context_); |
| 146 | 237 |
| 147 base::MessageLoopForIO::current()->RegisterIOHandler(file().GetPlatformFile(), | 238 base::MessageLoopForIO::current()->RegisterIOHandler(file().GetPlatformFile(), |
| 148 this); | 239 this); |
| 149 | 240 |
| 150 comm_context_.reset(new base::MessageLoopForIO::IOContext()); | 241 comm_context_.reset(new base::MessageLoopForIO::IOContext()); |
| 151 comm_context_->handler = this; | 242 comm_context_->handler = this; |
| 152 memset(&comm_context_->overlapped, 0, sizeof(comm_context_->overlapped)); | 243 memset(&comm_context_->overlapped, 0, sizeof(comm_context_->overlapped)); |
| 153 | 244 |
| 154 read_context_.reset(new base::MessageLoopForIO::IOContext()); | 245 read_context_.reset(new base::MessageLoopForIO::IOContext()); |
| 155 read_context_->handler = this; | 246 read_context_->handler = this; |
| 156 memset(&read_context_->overlapped, 0, sizeof(read_context_->overlapped)); | 247 memset(&read_context_->overlapped, 0, sizeof(read_context_->overlapped)); |
| 157 | 248 |
| 158 write_context_.reset(new base::MessageLoopForIO::IOContext()); | 249 write_context_.reset(new base::MessageLoopForIO::IOContext()); |
| 159 write_context_->handler = this; | 250 write_context_->handler = this; |
| 160 memset(&write_context_->overlapped, 0, sizeof(write_context_->overlapped)); | 251 memset(&write_context_->overlapped, 0, sizeof(write_context_->overlapped)); |
| 161 | 252 |
| 253 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner = | |
| 254 base::ThreadTaskRunnerHandle::Get(); | |
| 255 helper_ = | |
| 256 new UiThreadHelper(weak_factory_.GetWeakPtr(), io_thread_task_runner); | |
| 257 ui_thread_task_runner()->PostTask( | |
| 258 FROM_HERE, base::Bind(&UiThreadHelper::Start, helper_)); | |
| 259 | |
| 162 // A ReadIntervalTimeout of MAXDWORD will cause async reads to complete | 260 // A ReadIntervalTimeout of MAXDWORD will cause async reads to complete |
| 163 // immediately with any data that's available, even if there is none. | 261 // immediately with any data that's available, even if there is none. |
| 164 // This is OK because we never issue a read request until WaitCommEvent | 262 // This is OK because we never issue a read request until WaitCommEvent |
| 165 // signals that data is available. | 263 // signals that data is available. |
| 166 COMMTIMEOUTS timeouts = {0}; | 264 COMMTIMEOUTS timeouts = {0}; |
| 167 timeouts.ReadIntervalTimeout = MAXDWORD; | 265 timeouts.ReadIntervalTimeout = MAXDWORD; |
| 168 if (!::SetCommTimeouts(file().GetPlatformFile(), &timeouts)) { | 266 if (!::SetCommTimeouts(file().GetPlatformFile(), &timeouts)) { |
| 169 VPLOG(1) << "Failed to set serial timeouts"; | 267 DVPLOG(1) << "Failed to set serial timeouts"; |
|
Reilly Grant (use Gerrit)
2015/11/14 01:54:54
Don't change all of these to debug logs as well. T
juncai
2015/11/16 21:10:33
Done.
| |
| 170 return false; | 268 return false; |
| 171 } | 269 } |
| 172 | 270 |
| 173 return true; | 271 return true; |
| 174 } | 272 } |
| 175 | 273 |
| 176 void SerialIoHandlerWin::ReadImpl() { | 274 void SerialIoHandlerWin::ReadImpl() { |
| 177 DCHECK(CalledOnValidThread()); | 275 DCHECK(CalledOnValidThread()); |
| 178 DCHECK(pending_read_buffer()); | 276 DCHECK(pending_read_buffer()); |
| 179 DCHECK(file().IsValid()); | 277 DCHECK(file().IsValid()); |
| 180 | 278 |
| 181 if (!SetCommMask(file().GetPlatformFile(), EV_RXCHAR)) { | 279 if (!SetCommMask(file().GetPlatformFile(), EV_RXCHAR)) { |
| 182 VPLOG(1) << "Failed to set serial event flags"; | 280 DVPLOG(1) << "Failed to set serial event flags"; |
| 183 } | 281 } |
| 184 | 282 |
| 185 event_mask_ = 0; | 283 event_mask_ = 0; |
| 186 BOOL ok = ::WaitCommEvent( | 284 BOOL ok = ::WaitCommEvent( |
| 187 file().GetPlatformFile(), &event_mask_, &comm_context_->overlapped); | 285 file().GetPlatformFile(), &event_mask_, &comm_context_->overlapped); |
| 188 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 286 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
| 189 VPLOG(1) << "Failed to receive serial event"; | 287 DVPLOG(1) << "Failed to receive serial event"; |
| 190 QueueReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); | 288 QueueReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); |
| 191 } | 289 } |
| 192 is_comm_pending_ = true; | 290 is_comm_pending_ = true; |
| 193 } | 291 } |
| 194 | 292 |
| 195 void SerialIoHandlerWin::WriteImpl() { | 293 void SerialIoHandlerWin::WriteImpl() { |
| 196 DCHECK(CalledOnValidThread()); | 294 DCHECK(CalledOnValidThread()); |
| 197 DCHECK(pending_write_buffer()); | 295 DCHECK(pending_write_buffer()); |
| 198 DCHECK(file().IsValid()); | 296 DCHECK(file().IsValid()); |
| 199 | 297 |
| 200 BOOL ok = ::WriteFile(file().GetPlatformFile(), | 298 BOOL ok = ::WriteFile(file().GetPlatformFile(), |
| 201 pending_write_buffer(), | 299 pending_write_buffer(), |
| 202 pending_write_buffer_len(), | 300 pending_write_buffer_len(), |
| 203 NULL, | 301 NULL, |
| 204 &write_context_->overlapped); | 302 &write_context_->overlapped); |
| 205 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 303 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
| 206 VPLOG(1) << "Write failed"; | 304 DVPLOG(1) << "Write failed"; |
| 207 QueueWriteCompleted(0, serial::SEND_ERROR_SYSTEM_ERROR); | 305 QueueWriteCompleted(0, serial::SEND_ERROR_SYSTEM_ERROR); |
| 208 } | 306 } |
| 209 } | 307 } |
| 210 | 308 |
| 211 void SerialIoHandlerWin::CancelReadImpl() { | 309 void SerialIoHandlerWin::CancelReadImpl() { |
| 212 DCHECK(CalledOnValidThread()); | 310 DCHECK(CalledOnValidThread()); |
| 213 DCHECK(file().IsValid()); | 311 DCHECK(file().IsValid()); |
| 214 ::CancelIo(file().GetPlatformFile()); | 312 ::CancelIo(file().GetPlatformFile()); |
| 215 } | 313 } |
| 216 | 314 |
| 217 void SerialIoHandlerWin::CancelWriteImpl() { | 315 void SerialIoHandlerWin::CancelWriteImpl() { |
| 218 DCHECK(CalledOnValidThread()); | 316 DCHECK(CalledOnValidThread()); |
| 219 DCHECK(file().IsValid()); | 317 DCHECK(file().IsValid()); |
| 220 ::CancelIo(file().GetPlatformFile()); | 318 ::CancelIo(file().GetPlatformFile()); |
| 221 } | 319 } |
| 222 | 320 |
| 223 bool SerialIoHandlerWin::ConfigurePortImpl() { | 321 bool SerialIoHandlerWin::ConfigurePortImpl() { |
| 224 DCB config = {0}; | 322 DCB config = {0}; |
| 225 config.DCBlength = sizeof(config); | 323 config.DCBlength = sizeof(config); |
| 226 if (!GetCommState(file().GetPlatformFile(), &config)) { | 324 if (!GetCommState(file().GetPlatformFile(), &config)) { |
| 227 VPLOG(1) << "Failed to get serial port info"; | 325 DVPLOG(1) << "Failed to get serial port info"; |
| 228 return false; | 326 return false; |
| 229 } | 327 } |
| 230 | 328 |
| 231 // Set up some sane default options that are not configurable. | 329 // Set up some sane default options that are not configurable. |
| 232 config.fBinary = TRUE; | 330 config.fBinary = TRUE; |
| 233 config.fParity = TRUE; | 331 config.fParity = TRUE; |
| 234 config.fAbortOnError = TRUE; | 332 config.fAbortOnError = TRUE; |
| 235 config.fOutxDsrFlow = FALSE; | 333 config.fOutxDsrFlow = FALSE; |
| 236 config.fDtrControl = DTR_CONTROL_ENABLE; | 334 config.fDtrControl = DTR_CONTROL_ENABLE; |
| 237 config.fDsrSensitivity = FALSE; | 335 config.fDsrSensitivity = FALSE; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 253 DCHECK(options().has_cts_flow_control); | 351 DCHECK(options().has_cts_flow_control); |
| 254 if (options().cts_flow_control) { | 352 if (options().cts_flow_control) { |
| 255 config.fOutxCtsFlow = TRUE; | 353 config.fOutxCtsFlow = TRUE; |
| 256 config.fRtsControl = RTS_CONTROL_HANDSHAKE; | 354 config.fRtsControl = RTS_CONTROL_HANDSHAKE; |
| 257 } else { | 355 } else { |
| 258 config.fOutxCtsFlow = FALSE; | 356 config.fOutxCtsFlow = FALSE; |
| 259 config.fRtsControl = RTS_CONTROL_ENABLE; | 357 config.fRtsControl = RTS_CONTROL_ENABLE; |
| 260 } | 358 } |
| 261 | 359 |
| 262 if (!SetCommState(file().GetPlatformFile(), &config)) { | 360 if (!SetCommState(file().GetPlatformFile(), &config)) { |
| 263 VPLOG(1) << "Failed to set serial port info"; | 361 DVPLOG(1) << "Failed to set serial port info"; |
| 264 return false; | 362 return false; |
| 265 } | 363 } |
| 266 return true; | 364 return true; |
| 267 } | 365 } |
| 268 | 366 |
| 269 SerialIoHandlerWin::SerialIoHandlerWin( | 367 SerialIoHandlerWin::SerialIoHandlerWin( |
| 270 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, | 368 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, |
| 271 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) | 369 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) |
| 272 : SerialIoHandler(file_thread_task_runner, ui_thread_task_runner), | 370 : SerialIoHandler(file_thread_task_runner, ui_thread_task_runner), |
| 273 event_mask_(0), | 371 event_mask_(0), |
| 274 is_comm_pending_(false) { | 372 is_comm_pending_(false), |
| 275 } | 373 weak_factory_(this) {} |
| 276 | 374 |
| 277 SerialIoHandlerWin::~SerialIoHandlerWin() { | 375 SerialIoHandlerWin::~SerialIoHandlerWin() { |
| 376 ui_thread_task_runner()->DeleteSoon(FROM_HERE, helper_); | |
| 278 } | 377 } |
| 279 | 378 |
| 280 void SerialIoHandlerWin::OnIOCompleted( | 379 void SerialIoHandlerWin::OnIOCompleted( |
| 281 base::MessageLoopForIO::IOContext* context, | 380 base::MessageLoopForIO::IOContext* context, |
| 282 DWORD bytes_transferred, | 381 DWORD bytes_transferred, |
| 283 DWORD error) { | 382 DWORD error) { |
| 284 DCHECK(CalledOnValidThread()); | 383 DCHECK(CalledOnValidThread()); |
| 285 if (context == comm_context_) { | 384 if (context == comm_context_) { |
| 286 DWORD errors; | 385 DWORD errors; |
| 287 COMSTAT status; | 386 COMSTAT status; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 307 ReadCompleted(bytes_transferred, read_cancel_reason()); | 406 ReadCompleted(bytes_transferred, read_cancel_reason()); |
| 308 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { | 407 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { |
| 309 ReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); | 408 ReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); |
| 310 } else if (pending_read_buffer()) { | 409 } else if (pending_read_buffer()) { |
| 311 BOOL ok = ::ReadFile(file().GetPlatformFile(), | 410 BOOL ok = ::ReadFile(file().GetPlatformFile(), |
| 312 pending_read_buffer(), | 411 pending_read_buffer(), |
| 313 pending_read_buffer_len(), | 412 pending_read_buffer_len(), |
| 314 NULL, | 413 NULL, |
| 315 &read_context_->overlapped); | 414 &read_context_->overlapped); |
| 316 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 415 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
| 317 VPLOG(1) << "Read failed"; | 416 DVPLOG(1) << "Read failed"; |
| 318 ReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); | 417 ReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); |
| 319 } | 418 } |
| 320 } | 419 } |
| 321 } else if (context == read_context_) { | 420 } else if (context == read_context_) { |
| 322 if (read_canceled()) { | 421 if (read_canceled()) { |
| 323 ReadCompleted(bytes_transferred, read_cancel_reason()); | 422 ReadCompleted(bytes_transferred, read_cancel_reason()); |
| 324 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { | 423 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { |
| 325 ReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); | 424 ReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); |
| 326 } else { | 425 } else { |
| 327 ReadCompleted(bytes_transferred, | 426 ReadCompleted(bytes_transferred, |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 352 error == ERROR_SUCCESS ? serial::SEND_ERROR_NONE | 451 error == ERROR_SUCCESS ? serial::SEND_ERROR_NONE |
| 353 : serial::SEND_ERROR_SYSTEM_ERROR); | 452 : serial::SEND_ERROR_SYSTEM_ERROR); |
| 354 } | 453 } |
| 355 } else { | 454 } else { |
| 356 NOTREACHED() << "Invalid IOContext"; | 455 NOTREACHED() << "Invalid IOContext"; |
| 357 } | 456 } |
| 358 } | 457 } |
| 359 | 458 |
| 360 bool SerialIoHandlerWin::Flush() const { | 459 bool SerialIoHandlerWin::Flush() const { |
| 361 if (!PurgeComm(file().GetPlatformFile(), PURGE_RXCLEAR | PURGE_TXCLEAR)) { | 460 if (!PurgeComm(file().GetPlatformFile(), PURGE_RXCLEAR | PURGE_TXCLEAR)) { |
| 362 VPLOG(1) << "Failed to flush serial port"; | 461 DVPLOG(1) << "Failed to flush serial port"; |
| 363 return false; | 462 return false; |
| 364 } | 463 } |
| 365 return true; | 464 return true; |
| 366 } | 465 } |
| 367 | 466 |
| 368 serial::DeviceControlSignalsPtr SerialIoHandlerWin::GetControlSignals() const { | 467 serial::DeviceControlSignalsPtr SerialIoHandlerWin::GetControlSignals() const { |
| 369 DWORD status; | 468 DWORD status; |
| 370 if (!GetCommModemStatus(file().GetPlatformFile(), &status)) { | 469 if (!GetCommModemStatus(file().GetPlatformFile(), &status)) { |
| 371 VPLOG(1) << "Failed to get port control signals"; | 470 DVPLOG(1) << "Failed to get port control signals"; |
| 372 return serial::DeviceControlSignalsPtr(); | 471 return serial::DeviceControlSignalsPtr(); |
| 373 } | 472 } |
| 374 | 473 |
| 375 serial::DeviceControlSignalsPtr signals(serial::DeviceControlSignals::New()); | 474 serial::DeviceControlSignalsPtr signals(serial::DeviceControlSignals::New()); |
| 376 signals->dcd = (status & MS_RLSD_ON) != 0; | 475 signals->dcd = (status & MS_RLSD_ON) != 0; |
| 377 signals->cts = (status & MS_CTS_ON) != 0; | 476 signals->cts = (status & MS_CTS_ON) != 0; |
| 378 signals->dsr = (status & MS_DSR_ON) != 0; | 477 signals->dsr = (status & MS_DSR_ON) != 0; |
| 379 signals->ri = (status & MS_RING_ON) != 0; | 478 signals->ri = (status & MS_RING_ON) != 0; |
| 380 return signals.Pass(); | 479 return signals.Pass(); |
| 381 } | 480 } |
| 382 | 481 |
| 383 bool SerialIoHandlerWin::SetControlSignals( | 482 bool SerialIoHandlerWin::SetControlSignals( |
| 384 const serial::HostControlSignals& signals) { | 483 const serial::HostControlSignals& signals) { |
| 385 if (signals.has_dtr) { | 484 if (signals.has_dtr) { |
| 386 if (!EscapeCommFunction(file().GetPlatformFile(), | 485 if (!EscapeCommFunction(file().GetPlatformFile(), |
| 387 signals.dtr ? SETDTR : CLRDTR)) { | 486 signals.dtr ? SETDTR : CLRDTR)) { |
| 388 VPLOG(1) << "Failed to configure DTR signal"; | 487 DVPLOG(1) << "Failed to configure DTR signal"; |
| 389 return false; | 488 return false; |
| 390 } | 489 } |
| 391 } | 490 } |
| 392 if (signals.has_rts) { | 491 if (signals.has_rts) { |
| 393 if (!EscapeCommFunction(file().GetPlatformFile(), | 492 if (!EscapeCommFunction(file().GetPlatformFile(), |
| 394 signals.rts ? SETRTS : CLRRTS)) { | 493 signals.rts ? SETRTS : CLRRTS)) { |
| 395 VPLOG(1) << "Failed to configure RTS signal"; | 494 DVPLOG(1) << "Failed to configure RTS signal"; |
| 396 return false; | 495 return false; |
| 397 } | 496 } |
| 398 } | 497 } |
| 399 return true; | 498 return true; |
| 400 } | 499 } |
| 401 | 500 |
| 402 serial::ConnectionInfoPtr SerialIoHandlerWin::GetPortInfo() const { | 501 serial::ConnectionInfoPtr SerialIoHandlerWin::GetPortInfo() const { |
| 403 DCB config = {0}; | 502 DCB config = {0}; |
| 404 config.DCBlength = sizeof(config); | 503 config.DCBlength = sizeof(config); |
| 405 if (!GetCommState(file().GetPlatformFile(), &config)) { | 504 if (!GetCommState(file().GetPlatformFile(), &config)) { |
| 406 VPLOG(1) << "Failed to get serial port info"; | 505 DVPLOG(1) << "Failed to get serial port info"; |
| 407 return serial::ConnectionInfoPtr(); | 506 return serial::ConnectionInfoPtr(); |
| 408 } | 507 } |
| 409 serial::ConnectionInfoPtr info(serial::ConnectionInfo::New()); | 508 serial::ConnectionInfoPtr info(serial::ConnectionInfo::New()); |
| 410 info->bitrate = SpeedConstantToBitrate(config.BaudRate); | 509 info->bitrate = SpeedConstantToBitrate(config.BaudRate); |
| 411 info->data_bits = DataBitsConstantToEnum(config.ByteSize); | 510 info->data_bits = DataBitsConstantToEnum(config.ByteSize); |
| 412 info->parity_bit = ParityBitConstantToEnum(config.Parity); | 511 info->parity_bit = ParityBitConstantToEnum(config.Parity); |
| 413 info->stop_bits = StopBitsConstantToEnum(config.StopBits); | 512 info->stop_bits = StopBitsConstantToEnum(config.StopBits); |
| 414 info->cts_flow_control = config.fOutxCtsFlow != 0; | 513 info->cts_flow_control = config.fOutxCtsFlow != 0; |
| 415 return info.Pass(); | 514 return info.Pass(); |
| 416 } | 515 } |
| 417 | 516 |
| 418 bool SerialIoHandlerWin::SetBreak() { | 517 bool SerialIoHandlerWin::SetBreak() { |
| 419 if (!SetCommBreak(file().GetPlatformFile())) { | 518 if (!SetCommBreak(file().GetPlatformFile())) { |
| 420 VPLOG(1) << "Failed to set break"; | 519 DVPLOG(1) << "Failed to set break"; |
| 421 return false; | 520 return false; |
| 422 } | 521 } |
| 423 return true; | 522 return true; |
| 424 } | 523 } |
| 425 | 524 |
| 426 bool SerialIoHandlerWin::ClearBreak() { | 525 bool SerialIoHandlerWin::ClearBreak() { |
| 427 if (!ClearCommBreak(file().GetPlatformFile())) { | 526 if (!ClearCommBreak(file().GetPlatformFile())) { |
| 428 VPLOG(1) << "Failed to clear break"; | 527 DVPLOG(1) << "Failed to clear break"; |
| 429 return false; | 528 return false; |
| 430 } | 529 } |
| 431 return true; | 530 return true; |
| 432 } | 531 } |
| 433 | 532 |
| 434 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { | 533 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { |
| 435 // For COM numbers less than 9, CreateFile is called with a string such as | 534 // For COM numbers less than 9, CreateFile is called with a string such as |
| 436 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added. | 535 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added. |
| 437 if (port_name.length() > std::string("COM9").length()) | 536 if (port_name.length() > std::string("COM9").length()) |
| 438 return std::string("\\\\.\\").append(port_name); | 537 return std::string("\\\\.\\").append(port_name); |
| 439 | 538 |
| 440 return port_name; | 539 return port_name; |
| 441 } | 540 } |
| 442 | 541 |
| 443 } // namespace device | 542 } // namespace device |
| OLD | NEW |