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 #include <windows.h> | 7 #include <windows.h> |
8 #include <setupapi.h> | 8 #include <setupapi.h> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 // If the bitrate doesn't match that of one of the standard | 42 // If the bitrate doesn't match that of one of the standard |
43 // index constants, it may be provided as-is to the DCB | 43 // index constants, it may be provided as-is to the DCB |
44 // structure, according to MSDN. | 44 // structure, according to MSDN. |
45 return bitrate; | 45 return bitrate; |
46 } | 46 } |
47 #undef BITRATE_TO_SPEED_CASE | 47 #undef BITRATE_TO_SPEED_CASE |
48 } | 48 } |
49 | 49 |
50 int DataBitsEnumToConstant(serial::DataBits data_bits) { | 50 int DataBitsEnumToConstant(serial::DataBits data_bits) { |
51 switch (data_bits) { | 51 switch (data_bits) { |
52 case serial::DATA_BITS_SEVEN: | 52 case serial::DataBits::SEVEN: |
53 return 7; | 53 return 7; |
54 case serial::DATA_BITS_EIGHT: | 54 case serial::DataBits::EIGHT: |
55 default: | 55 default: |
56 return 8; | 56 return 8; |
57 } | 57 } |
58 } | 58 } |
59 | 59 |
60 int ParityBitEnumToConstant(serial::ParityBit parity_bit) { | 60 int ParityBitEnumToConstant(serial::ParityBit parity_bit) { |
61 switch (parity_bit) { | 61 switch (parity_bit) { |
62 case serial::PARITY_BIT_EVEN: | 62 case serial::ParityBit::EVEN: |
63 return EVENPARITY; | 63 return EVENPARITY; |
64 case serial::PARITY_BIT_ODD: | 64 case serial::ParityBit::ODD: |
65 return ODDPARITY; | 65 return ODDPARITY; |
66 case serial::PARITY_BIT_NO: | 66 case serial::ParityBit::NO: |
67 default: | 67 default: |
68 return NOPARITY; | 68 return NOPARITY; |
69 } | 69 } |
70 } | 70 } |
71 | 71 |
72 int StopBitsEnumToConstant(serial::StopBits stop_bits) { | 72 int StopBitsEnumToConstant(serial::StopBits stop_bits) { |
73 switch (stop_bits) { | 73 switch (stop_bits) { |
74 case serial::STOP_BITS_TWO: | 74 case serial::StopBits::TWO: |
75 return TWOSTOPBITS; | 75 return TWOSTOPBITS; |
76 case serial::STOP_BITS_ONE: | 76 case serial::StopBits::ONE: |
77 default: | 77 default: |
78 return ONESTOPBIT; | 78 return ONESTOPBIT; |
79 } | 79 } |
80 } | 80 } |
81 | 81 |
82 int SpeedConstantToBitrate(int speed) { | 82 int SpeedConstantToBitrate(int speed) { |
83 #define SPEED_TO_BITRATE_CASE(x) \ | 83 #define SPEED_TO_BITRATE_CASE(x) \ |
84 case CBR_##x: \ | 84 case CBR_##x: \ |
85 return x; | 85 return x; |
86 switch (speed) { | 86 switch (speed) { |
(...skipping 16 matching lines...) Expand all Loading... |
103 // it should be an integral baud rate, according to | 103 // it should be an integral baud rate, according to |
104 // MSDN. | 104 // MSDN. |
105 return speed; | 105 return speed; |
106 } | 106 } |
107 #undef SPEED_TO_BITRATE_CASE | 107 #undef SPEED_TO_BITRATE_CASE |
108 } | 108 } |
109 | 109 |
110 serial::DataBits DataBitsConstantToEnum(int data_bits) { | 110 serial::DataBits DataBitsConstantToEnum(int data_bits) { |
111 switch (data_bits) { | 111 switch (data_bits) { |
112 case 7: | 112 case 7: |
113 return serial::DATA_BITS_SEVEN; | 113 return serial::DataBits::SEVEN; |
114 case 8: | 114 case 8: |
115 default: | 115 default: |
116 return serial::DATA_BITS_EIGHT; | 116 return serial::DataBits::EIGHT; |
117 } | 117 } |
118 } | 118 } |
119 | 119 |
120 serial::ParityBit ParityBitConstantToEnum(int parity_bit) { | 120 serial::ParityBit ParityBitConstantToEnum(int parity_bit) { |
121 switch (parity_bit) { | 121 switch (parity_bit) { |
122 case EVENPARITY: | 122 case EVENPARITY: |
123 return serial::PARITY_BIT_EVEN; | 123 return serial::ParityBit::EVEN; |
124 case ODDPARITY: | 124 case ODDPARITY: |
125 return serial::PARITY_BIT_ODD; | 125 return serial::ParityBit::ODD; |
126 case NOPARITY: | 126 case NOPARITY: |
127 default: | 127 default: |
128 return serial::PARITY_BIT_NO; | 128 return serial::ParityBit::NO; |
129 } | 129 } |
130 } | 130 } |
131 | 131 |
132 serial::StopBits StopBitsConstantToEnum(int stop_bits) { | 132 serial::StopBits StopBitsConstantToEnum(int stop_bits) { |
133 switch (stop_bits) { | 133 switch (stop_bits) { |
134 case TWOSTOPBITS: | 134 case TWOSTOPBITS: |
135 return serial::STOP_BITS_TWO; | 135 return serial::StopBits::TWO; |
136 case ONESTOPBIT: | 136 case ONESTOPBIT: |
137 default: | 137 default: |
138 return serial::STOP_BITS_ONE; | 138 return serial::StopBits::ONE; |
139 } | 139 } |
140 } | 140 } |
141 | 141 |
142 // Searches for the COM port in the device's friendly name, assigns its value to | 142 // Searches for the COM port in the device's friendly name, assigns its value to |
143 // com_port, and returns whether the operation was successful. | 143 // com_port, and returns whether the operation was successful. |
144 bool GetCOMPort(const std::string friendly_name, std::string* com_port) { | 144 bool GetCOMPort(const std::string friendly_name, std::string* com_port) { |
145 return RE2::PartialMatch(friendly_name, ".* \\((COM[0-9]+)\\)", com_port); | 145 return RE2::PartialMatch(friendly_name, ".* \\((COM[0-9]+)\\)", com_port); |
146 } | 146 } |
147 | 147 |
148 } // namespace | 148 } // namespace |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 return; | 220 return; |
221 } | 221 } |
222 | 222 |
223 std::string com_port; | 223 std::string com_port; |
224 if (!GetCOMPort(friendly_name, &com_port)) { | 224 if (!GetCOMPort(friendly_name, &com_port)) { |
225 DVPLOG(1) << "Failed to get port name from \"" << friendly_name << "\"."; | 225 DVPLOG(1) << "Failed to get port name from \"" << friendly_name << "\"."; |
226 return; | 226 return; |
227 } | 227 } |
228 | 228 |
229 if (port() == com_port) | 229 if (port() == com_port) |
230 CancelRead(serial::RECEIVE_ERROR_DEVICE_LOST); | 230 CancelRead(serial::ReceiveError::DEVICE_LOST); |
231 } | 231 } |
232 | 232 |
233 bool SerialIoHandlerWin::PostOpen() { | 233 bool SerialIoHandlerWin::PostOpen() { |
234 DCHECK(!comm_context_); | 234 DCHECK(!comm_context_); |
235 DCHECK(!read_context_); | 235 DCHECK(!read_context_); |
236 DCHECK(!write_context_); | 236 DCHECK(!write_context_); |
237 | 237 |
238 base::MessageLoopForIO::current()->RegisterIOHandler(file().GetPlatformFile(), | 238 base::MessageLoopForIO::current()->RegisterIOHandler(file().GetPlatformFile(), |
239 this); | 239 this); |
240 | 240 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 | 278 |
279 if (!SetCommMask(file().GetPlatformFile(), EV_RXCHAR)) { | 279 if (!SetCommMask(file().GetPlatformFile(), EV_RXCHAR)) { |
280 VPLOG(1) << "Failed to set serial event flags"; | 280 VPLOG(1) << "Failed to set serial event flags"; |
281 } | 281 } |
282 | 282 |
283 event_mask_ = 0; | 283 event_mask_ = 0; |
284 BOOL ok = ::WaitCommEvent( | 284 BOOL ok = ::WaitCommEvent( |
285 file().GetPlatformFile(), &event_mask_, &comm_context_->overlapped); | 285 file().GetPlatformFile(), &event_mask_, &comm_context_->overlapped); |
286 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 286 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
287 VPLOG(1) << "Failed to receive serial event"; | 287 VPLOG(1) << "Failed to receive serial event"; |
288 QueueReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); | 288 QueueReadCompleted(0, serial::ReceiveError::SYSTEM_ERROR); |
289 } | 289 } |
290 is_comm_pending_ = true; | 290 is_comm_pending_ = true; |
291 } | 291 } |
292 | 292 |
293 void SerialIoHandlerWin::WriteImpl() { | 293 void SerialIoHandlerWin::WriteImpl() { |
294 DCHECK(CalledOnValidThread()); | 294 DCHECK(CalledOnValidThread()); |
295 DCHECK(pending_write_buffer()); | 295 DCHECK(pending_write_buffer()); |
296 DCHECK(file().IsValid()); | 296 DCHECK(file().IsValid()); |
297 | 297 |
298 BOOL ok = ::WriteFile(file().GetPlatformFile(), | 298 BOOL ok = ::WriteFile(file().GetPlatformFile(), |
299 pending_write_buffer(), | 299 pending_write_buffer(), |
300 pending_write_buffer_len(), | 300 pending_write_buffer_len(), |
301 NULL, | 301 NULL, |
302 &write_context_->overlapped); | 302 &write_context_->overlapped); |
303 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 303 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
304 VPLOG(1) << "Write failed"; | 304 VPLOG(1) << "Write failed"; |
305 QueueWriteCompleted(0, serial::SEND_ERROR_SYSTEM_ERROR); | 305 QueueWriteCompleted(0, serial::SendError::SYSTEM_ERROR); |
306 } | 306 } |
307 } | 307 } |
308 | 308 |
309 void SerialIoHandlerWin::CancelReadImpl() { | 309 void SerialIoHandlerWin::CancelReadImpl() { |
310 DCHECK(CalledOnValidThread()); | 310 DCHECK(CalledOnValidThread()); |
311 DCHECK(file().IsValid()); | 311 DCHECK(file().IsValid()); |
312 ::CancelIo(file().GetPlatformFile()); | 312 ::CancelIo(file().GetPlatformFile()); |
313 } | 313 } |
314 | 314 |
315 void SerialIoHandlerWin::CancelWriteImpl() { | 315 void SerialIoHandlerWin::CancelWriteImpl() { |
(...skipping 16 matching lines...) Expand all Loading... |
332 config.fAbortOnError = TRUE; | 332 config.fAbortOnError = TRUE; |
333 config.fOutxDsrFlow = FALSE; | 333 config.fOutxDsrFlow = FALSE; |
334 config.fDtrControl = DTR_CONTROL_ENABLE; | 334 config.fDtrControl = DTR_CONTROL_ENABLE; |
335 config.fDsrSensitivity = FALSE; | 335 config.fDsrSensitivity = FALSE; |
336 config.fOutX = FALSE; | 336 config.fOutX = FALSE; |
337 config.fInX = FALSE; | 337 config.fInX = FALSE; |
338 | 338 |
339 DCHECK(options().bitrate); | 339 DCHECK(options().bitrate); |
340 config.BaudRate = BitrateToSpeedConstant(options().bitrate); | 340 config.BaudRate = BitrateToSpeedConstant(options().bitrate); |
341 | 341 |
342 DCHECK(options().data_bits != serial::DATA_BITS_NONE); | 342 DCHECK(options().data_bits != serial::DataBits::NONE); |
343 config.ByteSize = DataBitsEnumToConstant(options().data_bits); | 343 config.ByteSize = DataBitsEnumToConstant(options().data_bits); |
344 | 344 |
345 DCHECK(options().parity_bit != serial::PARITY_BIT_NONE); | 345 DCHECK(options().parity_bit != serial::ParityBit::NONE); |
346 config.Parity = ParityBitEnumToConstant(options().parity_bit); | 346 config.Parity = ParityBitEnumToConstant(options().parity_bit); |
347 | 347 |
348 DCHECK(options().stop_bits != serial::STOP_BITS_NONE); | 348 DCHECK(options().stop_bits != serial::StopBits::NONE); |
349 config.StopBits = StopBitsEnumToConstant(options().stop_bits); | 349 config.StopBits = StopBitsEnumToConstant(options().stop_bits); |
350 | 350 |
351 DCHECK(options().has_cts_flow_control); | 351 DCHECK(options().has_cts_flow_control); |
352 if (options().cts_flow_control) { | 352 if (options().cts_flow_control) { |
353 config.fOutxCtsFlow = TRUE; | 353 config.fOutxCtsFlow = TRUE; |
354 config.fRtsControl = RTS_CONTROL_HANDSHAKE; | 354 config.fRtsControl = RTS_CONTROL_HANDSHAKE; |
355 } else { | 355 } else { |
356 config.fOutxCtsFlow = FALSE; | 356 config.fOutxCtsFlow = FALSE; |
357 config.fRtsControl = RTS_CONTROL_ENABLE; | 357 config.fRtsControl = RTS_CONTROL_ENABLE; |
358 } | 358 } |
(...skipping 22 matching lines...) Expand all Loading... |
381 base::MessageLoopForIO::IOContext* context, | 381 base::MessageLoopForIO::IOContext* context, |
382 DWORD bytes_transferred, | 382 DWORD bytes_transferred, |
383 DWORD error) { | 383 DWORD error) { |
384 DCHECK(CalledOnValidThread()); | 384 DCHECK(CalledOnValidThread()); |
385 if (context == comm_context_.get()) { | 385 if (context == comm_context_.get()) { |
386 DWORD errors; | 386 DWORD errors; |
387 COMSTAT status; | 387 COMSTAT status; |
388 if (!ClearCommError(file().GetPlatformFile(), &errors, &status) || | 388 if (!ClearCommError(file().GetPlatformFile(), &errors, &status) || |
389 errors != 0) { | 389 errors != 0) { |
390 if (errors & CE_BREAK) { | 390 if (errors & CE_BREAK) { |
391 ReadCompleted(0, serial::RECEIVE_ERROR_BREAK); | 391 ReadCompleted(0, serial::ReceiveError::BREAK); |
392 } else if (errors & CE_FRAME) { | 392 } else if (errors & CE_FRAME) { |
393 ReadCompleted(0, serial::RECEIVE_ERROR_FRAME_ERROR); | 393 ReadCompleted(0, serial::ReceiveError::FRAME_ERROR); |
394 } else if (errors & CE_OVERRUN) { | 394 } else if (errors & CE_OVERRUN) { |
395 ReadCompleted(0, serial::RECEIVE_ERROR_OVERRUN); | 395 ReadCompleted(0, serial::ReceiveError::OVERRUN); |
396 } else if (errors & CE_RXOVER) { | 396 } else if (errors & CE_RXOVER) { |
397 ReadCompleted(0, serial::RECEIVE_ERROR_BUFFER_OVERFLOW); | 397 ReadCompleted(0, serial::ReceiveError::BUFFER_OVERFLOW); |
398 } else if (errors & CE_RXPARITY) { | 398 } else if (errors & CE_RXPARITY) { |
399 ReadCompleted(0, serial::RECEIVE_ERROR_PARITY_ERROR); | 399 ReadCompleted(0, serial::ReceiveError::PARITY_ERROR); |
400 } else { | 400 } else { |
401 ReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); | 401 ReadCompleted(0, serial::ReceiveError::SYSTEM_ERROR); |
402 } | 402 } |
403 return; | 403 return; |
404 } | 404 } |
405 | 405 |
406 if (read_canceled()) { | 406 if (read_canceled()) { |
407 ReadCompleted(bytes_transferred, read_cancel_reason()); | 407 ReadCompleted(bytes_transferred, read_cancel_reason()); |
408 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { | 408 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { |
409 ReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); | 409 ReadCompleted(0, serial::ReceiveError::SYSTEM_ERROR); |
410 } else if (pending_read_buffer()) { | 410 } else if (pending_read_buffer()) { |
411 BOOL ok = ::ReadFile(file().GetPlatformFile(), | 411 BOOL ok = ::ReadFile(file().GetPlatformFile(), |
412 pending_read_buffer(), | 412 pending_read_buffer(), |
413 pending_read_buffer_len(), | 413 pending_read_buffer_len(), |
414 NULL, | 414 NULL, |
415 &read_context_->overlapped); | 415 &read_context_->overlapped); |
416 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 416 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
417 VPLOG(1) << "Read failed"; | 417 VPLOG(1) << "Read failed"; |
418 ReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); | 418 ReadCompleted(0, serial::ReceiveError::SYSTEM_ERROR); |
419 } | 419 } |
420 } | 420 } |
421 } else if (context == read_context_.get()) { | 421 } else if (context == read_context_.get()) { |
422 if (read_canceled()) { | 422 if (read_canceled()) { |
423 ReadCompleted(bytes_transferred, read_cancel_reason()); | 423 ReadCompleted(bytes_transferred, read_cancel_reason()); |
424 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { | 424 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { |
425 ReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); | 425 ReadCompleted(0, serial::ReceiveError::SYSTEM_ERROR); |
426 } else { | 426 } else { |
427 ReadCompleted(bytes_transferred, | 427 ReadCompleted(bytes_transferred, |
428 error == ERROR_SUCCESS | 428 error == ERROR_SUCCESS |
429 ? serial::RECEIVE_ERROR_NONE | 429 ? serial::ReceiveError::NONE |
430 : serial::RECEIVE_ERROR_SYSTEM_ERROR); | 430 : serial::ReceiveError::SYSTEM_ERROR); |
431 } | 431 } |
432 } else if (context == write_context_.get()) { | 432 } else if (context == write_context_.get()) { |
433 DCHECK(pending_write_buffer()); | 433 DCHECK(pending_write_buffer()); |
434 if (write_canceled()) { | 434 if (write_canceled()) { |
435 WriteCompleted(0, write_cancel_reason()); | 435 WriteCompleted(0, write_cancel_reason()); |
436 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { | 436 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { |
437 WriteCompleted(0, serial::SEND_ERROR_SYSTEM_ERROR); | 437 WriteCompleted(0, serial::SendError::SYSTEM_ERROR); |
438 if (error == ERROR_GEN_FAILURE && IsReadPending()) { | 438 if (error == ERROR_GEN_FAILURE && IsReadPending()) { |
439 // For devices using drivers such as FTDI, CP2xxx, when device is | 439 // For devices using drivers such as FTDI, CP2xxx, when device is |
440 // disconnected, the context is comm_context_ and the error is | 440 // disconnected, the context is comm_context_ and the error is |
441 // ERROR_OPERATION_ABORTED. | 441 // ERROR_OPERATION_ABORTED. |
442 // However, for devices using CDC-ACM driver, when device is | 442 // However, for devices using CDC-ACM driver, when device is |
443 // disconnected, the context is write_context_ and the error is | 443 // disconnected, the context is write_context_ and the error is |
444 // ERROR_GEN_FAILURE. In this situation, in addition to a write error | 444 // ERROR_GEN_FAILURE. In this situation, in addition to a write error |
445 // signal, also need to generate a read error signal | 445 // signal, also need to generate a read error signal |
446 // serial::OnReceiveError which will notify the app about the | 446 // serial::OnReceiveError which will notify the app about the |
447 // disconnection. | 447 // disconnection. |
448 CancelRead(serial::RECEIVE_ERROR_SYSTEM_ERROR); | 448 CancelRead(serial::ReceiveError::SYSTEM_ERROR); |
449 } | 449 } |
450 } else { | 450 } else { |
451 WriteCompleted(bytes_transferred, | 451 WriteCompleted(bytes_transferred, error == ERROR_SUCCESS |
452 error == ERROR_SUCCESS ? serial::SEND_ERROR_NONE | 452 ? serial::SendError::NONE |
453 : serial::SEND_ERROR_SYSTEM_ERROR); | 453 : serial::SendError::SYSTEM_ERROR); |
454 } | 454 } |
455 } else { | 455 } else { |
456 NOTREACHED() << "Invalid IOContext"; | 456 NOTREACHED() << "Invalid IOContext"; |
457 } | 457 } |
458 } | 458 } |
459 | 459 |
460 bool SerialIoHandlerWin::Flush() const { | 460 bool SerialIoHandlerWin::Flush() const { |
461 if (!PurgeComm(file().GetPlatformFile(), PURGE_RXCLEAR | PURGE_TXCLEAR)) { | 461 if (!PurgeComm(file().GetPlatformFile(), PURGE_RXCLEAR | PURGE_TXCLEAR)) { |
462 VPLOG(1) << "Failed to flush serial port"; | 462 VPLOG(1) << "Failed to flush serial port"; |
463 return false; | 463 return false; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { | 534 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { |
535 // For COM numbers less than 9, CreateFile is called with a string such as | 535 // For COM numbers less than 9, CreateFile is called with a string such as |
536 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added. | 536 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added. |
537 if (port_name.length() > std::string("COM9").length()) | 537 if (port_name.length() > std::string("COM9").length()) |
538 return std::string("\\\\.\\").append(port_name); | 538 return std::string("\\\\.\\").append(port_name); |
539 | 539 |
540 return port_name; | 540 return port_name; |
541 } | 541 } |
542 | 542 |
543 } // namespace device | 543 } // namespace device |
OLD | NEW |