OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <windows.h> | 5 #include <windows.h> |
6 | 6 |
7 #include "chrome/browser/extensions/api/serial/serial_io_handler_win.h" | 7 #include "chrome/browser/extensions/api/serial/serial_io_handler_win.h" |
8 | 8 |
9 namespace extensions { | 9 namespace extensions { |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... |
31 BITRATE_TO_SPEED_CASE(256000); | 31 BITRATE_TO_SPEED_CASE(256000); |
32 default: | 32 default: |
33 // If the bitrate doesn't match that of one of the standard | 33 // If the bitrate doesn't match that of one of the standard |
34 // index constants, it may be provided as-is to the DCB | 34 // index constants, it may be provided as-is to the DCB |
35 // structure, according to MSDN. | 35 // structure, according to MSDN. |
36 return bitrate; | 36 return bitrate; |
37 } | 37 } |
38 #undef BITRATE_TO_SPEED_CASE | 38 #undef BITRATE_TO_SPEED_CASE |
39 } | 39 } |
40 | 40 |
41 int DataBitsEnumToConstant(api::serial::DataBits data_bits) { | 41 int DataBitsEnumToConstant(device::serial::DataBits data_bits) { |
42 switch (data_bits) { | 42 switch (data_bits) { |
43 case api::serial::DATA_BITS_SEVEN: | 43 case device::serial::DATA_BITS_SEVEN: |
44 return 7; | 44 return 7; |
45 case api::serial::DATA_BITS_EIGHT: | 45 case device::serial::DATA_BITS_EIGHT: |
46 default: | 46 default: |
47 return 8; | 47 return 8; |
48 } | 48 } |
49 } | 49 } |
50 | 50 |
51 int ParityBitEnumToConstant(api::serial::ParityBit parity_bit) { | 51 int ParityBitEnumToConstant(device::serial::ParityBit parity_bit) { |
52 switch (parity_bit) { | 52 switch (parity_bit) { |
53 case api::serial::PARITY_BIT_EVEN: | 53 case device::serial::PARITY_BIT_EVEN: |
54 return EVENPARITY; | 54 return EVENPARITY; |
55 case api::serial::PARITY_BIT_ODD: | 55 case device::serial::PARITY_BIT_ODD: |
56 return SPACEPARITY; | 56 return SPACEPARITY; |
57 case api::serial::PARITY_BIT_NO: | 57 case device::serial::PARITY_BIT_NO: |
58 default: | 58 default: |
59 return NOPARITY; | 59 return NOPARITY; |
60 } | 60 } |
61 } | 61 } |
62 | 62 |
63 int StopBitsEnumToConstant(api::serial::StopBits stop_bits) { | 63 int StopBitsEnumToConstant(device::serial::StopBits stop_bits) { |
64 switch (stop_bits) { | 64 switch (stop_bits) { |
65 case api::serial::STOP_BITS_TWO: | 65 case device::serial::STOP_BITS_TWO: |
66 return TWOSTOPBITS; | 66 return TWOSTOPBITS; |
67 case api::serial::STOP_BITS_ONE: | 67 case device::serial::STOP_BITS_ONE: |
68 default: | 68 default: |
69 return ONESTOPBIT; | 69 return ONESTOPBIT; |
70 } | 70 } |
71 } | 71 } |
72 | 72 |
73 int SpeedConstantToBitrate(int speed) { | 73 int SpeedConstantToBitrate(int speed) { |
74 #define SPEED_TO_BITRATE_CASE(x) \ | 74 #define SPEED_TO_BITRATE_CASE(x) \ |
75 case CBR_##x: \ | 75 case CBR_##x: \ |
76 return x; | 76 return x; |
77 switch (speed) { | 77 switch (speed) { |
(...skipping 13 matching lines...) Expand all Loading... |
91 SPEED_TO_BITRATE_CASE(256000); | 91 SPEED_TO_BITRATE_CASE(256000); |
92 default: | 92 default: |
93 // If it's not one of the standard index constants, | 93 // If it's not one of the standard index constants, |
94 // it should be an integral baud rate, according to | 94 // it should be an integral baud rate, according to |
95 // MSDN. | 95 // MSDN. |
96 return speed; | 96 return speed; |
97 } | 97 } |
98 #undef SPEED_TO_BITRATE_CASE | 98 #undef SPEED_TO_BITRATE_CASE |
99 } | 99 } |
100 | 100 |
101 api::serial::DataBits DataBitsConstantToEnum(int data_bits) { | 101 device::serial::DataBits DataBitsConstantToEnum(int data_bits) { |
102 switch (data_bits) { | 102 switch (data_bits) { |
103 case 7: | 103 case 7: |
104 return api::serial::DATA_BITS_SEVEN; | 104 return device::serial::DATA_BITS_SEVEN; |
105 case 8: | 105 case 8: |
106 default: | 106 default: |
107 return api::serial::DATA_BITS_EIGHT; | 107 return device::serial::DATA_BITS_EIGHT; |
108 } | 108 } |
109 } | 109 } |
110 | 110 |
111 api::serial::ParityBit ParityBitConstantToEnum(int parity_bit) { | 111 device::serial::ParityBit ParityBitConstantToEnum(int parity_bit) { |
112 switch (parity_bit) { | 112 switch (parity_bit) { |
113 case EVENPARITY: | 113 case EVENPARITY: |
114 return api::serial::PARITY_BIT_EVEN; | 114 return device::serial::PARITY_BIT_EVEN; |
115 case ODDPARITY: | 115 case ODDPARITY: |
116 return api::serial::PARITY_BIT_ODD; | 116 return device::serial::PARITY_BIT_ODD; |
117 case NOPARITY: | 117 case NOPARITY: |
118 default: | 118 default: |
119 return api::serial::PARITY_BIT_NO; | 119 return device::serial::PARITY_BIT_NO; |
120 } | 120 } |
121 } | 121 } |
122 | 122 |
123 api::serial::StopBits StopBitsConstantToEnum(int stop_bits) { | 123 device::serial::StopBits StopBitsConstantToEnum(int stop_bits) { |
124 switch (stop_bits) { | 124 switch (stop_bits) { |
125 case TWOSTOPBITS: | 125 case TWOSTOPBITS: |
126 return api::serial::STOP_BITS_TWO; | 126 return device::serial::STOP_BITS_TWO; |
127 case ONESTOPBIT: | 127 case ONESTOPBIT: |
128 default: | 128 default: |
129 return api::serial::STOP_BITS_ONE; | 129 return device::serial::STOP_BITS_ONE; |
130 } | 130 } |
131 } | 131 } |
132 | 132 |
133 } // namespace | 133 } // namespace |
134 | 134 |
135 // static | 135 // static |
136 scoped_refptr<SerialIoHandler> SerialIoHandler::Create() { | 136 scoped_refptr<SerialIoHandler> SerialIoHandler::Create() { |
137 return new SerialIoHandlerWin(); | 137 return new SerialIoHandlerWin(); |
138 } | 138 } |
139 | 139 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 | 188 |
189 void SerialIoHandlerWin::ReadImpl() { | 189 void SerialIoHandlerWin::ReadImpl() { |
190 DCHECK(CalledOnValidThread()); | 190 DCHECK(CalledOnValidThread()); |
191 DCHECK(pending_read_buffer()); | 191 DCHECK(pending_read_buffer()); |
192 DCHECK(file().IsValid()); | 192 DCHECK(file().IsValid()); |
193 | 193 |
194 DWORD errors; | 194 DWORD errors; |
195 COMSTAT status; | 195 COMSTAT status; |
196 if (!ClearCommError(file().GetPlatformFile(), &errors, &status) || | 196 if (!ClearCommError(file().GetPlatformFile(), &errors, &status) || |
197 errors != 0) { | 197 errors != 0) { |
198 QueueReadCompleted(0, api::serial::RECEIVE_ERROR_SYSTEM_ERROR); | 198 QueueReadCompleted(0, device::serial::RECEIVE_ERROR_SYSTEM_ERROR); |
199 return; | 199 return; |
200 } | 200 } |
201 | 201 |
202 SetCommMask(file().GetPlatformFile(), EV_RXCHAR); | 202 SetCommMask(file().GetPlatformFile(), EV_RXCHAR); |
203 | 203 |
204 event_mask_ = 0; | 204 event_mask_ = 0; |
205 BOOL ok = ::WaitCommEvent( | 205 BOOL ok = ::WaitCommEvent( |
206 file().GetPlatformFile(), &event_mask_, &comm_context_->overlapped); | 206 file().GetPlatformFile(), &event_mask_, &comm_context_->overlapped); |
207 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 207 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
208 QueueReadCompleted(0, api::serial::RECEIVE_ERROR_SYSTEM_ERROR); | 208 QueueReadCompleted(0, device::serial::RECEIVE_ERROR_SYSTEM_ERROR); |
209 } | 209 } |
210 is_comm_pending_ = true; | 210 is_comm_pending_ = true; |
211 } | 211 } |
212 | 212 |
213 void SerialIoHandlerWin::WriteImpl() { | 213 void SerialIoHandlerWin::WriteImpl() { |
214 DCHECK(CalledOnValidThread()); | 214 DCHECK(CalledOnValidThread()); |
215 DCHECK(pending_write_buffer()); | 215 DCHECK(pending_write_buffer()); |
216 DCHECK(file().IsValid()); | 216 DCHECK(file().IsValid()); |
217 | 217 |
218 BOOL ok = ::WriteFile(file().GetPlatformFile(), | 218 BOOL ok = ::WriteFile(file().GetPlatformFile(), |
219 pending_write_buffer()->data(), | 219 pending_write_buffer()->data(), |
220 pending_write_buffer_len(), | 220 pending_write_buffer_len(), |
221 NULL, | 221 NULL, |
222 &write_context_->overlapped); | 222 &write_context_->overlapped); |
223 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 223 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
224 QueueWriteCompleted(0, api::serial::SEND_ERROR_SYSTEM_ERROR); | 224 QueueWriteCompleted(0, device::serial::SEND_ERROR_SYSTEM_ERROR); |
225 } | 225 } |
226 } | 226 } |
227 | 227 |
228 void SerialIoHandlerWin::CancelReadImpl() { | 228 void SerialIoHandlerWin::CancelReadImpl() { |
229 DCHECK(CalledOnValidThread()); | 229 DCHECK(CalledOnValidThread()); |
230 DCHECK(file().IsValid()); | 230 DCHECK(file().IsValid()); |
231 ::CancelIo(file().GetPlatformFile()); | 231 ::CancelIo(file().GetPlatformFile()); |
232 } | 232 } |
233 | 233 |
234 void SerialIoHandlerWin::CancelWriteImpl() { | 234 void SerialIoHandlerWin::CancelWriteImpl() { |
(...skipping 12 matching lines...) Expand all Loading... |
247 | 247 |
248 void SerialIoHandlerWin::OnIOCompleted( | 248 void SerialIoHandlerWin::OnIOCompleted( |
249 base::MessageLoopForIO::IOContext* context, | 249 base::MessageLoopForIO::IOContext* context, |
250 DWORD bytes_transferred, | 250 DWORD bytes_transferred, |
251 DWORD error) { | 251 DWORD error) { |
252 DCHECK(CalledOnValidThread()); | 252 DCHECK(CalledOnValidThread()); |
253 if (context == comm_context_) { | 253 if (context == comm_context_) { |
254 if (read_canceled()) { | 254 if (read_canceled()) { |
255 ReadCompleted(bytes_transferred, read_cancel_reason()); | 255 ReadCompleted(bytes_transferred, read_cancel_reason()); |
256 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { | 256 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { |
257 ReadCompleted(0, api::serial::RECEIVE_ERROR_SYSTEM_ERROR); | 257 ReadCompleted(0, device::serial::RECEIVE_ERROR_SYSTEM_ERROR); |
258 } else if (pending_read_buffer()) { | 258 } else if (pending_read_buffer()) { |
259 BOOL ok = ::ReadFile(file().GetPlatformFile(), | 259 BOOL ok = ::ReadFile(file().GetPlatformFile(), |
260 pending_read_buffer()->data(), | 260 pending_read_buffer()->data(), |
261 pending_read_buffer_len(), | 261 pending_read_buffer_len(), |
262 NULL, | 262 NULL, |
263 &read_context_->overlapped); | 263 &read_context_->overlapped); |
264 if (!ok && GetLastError() != ERROR_IO_PENDING) { | 264 if (!ok && GetLastError() != ERROR_IO_PENDING) { |
265 ReadCompleted(0, api::serial::RECEIVE_ERROR_SYSTEM_ERROR); | 265 ReadCompleted(0, device::serial::RECEIVE_ERROR_SYSTEM_ERROR); |
266 } | 266 } |
267 } | 267 } |
268 } else if (context == read_context_) { | 268 } else if (context == read_context_) { |
269 if (read_canceled()) { | 269 if (read_canceled()) { |
270 ReadCompleted(bytes_transferred, read_cancel_reason()); | 270 ReadCompleted(bytes_transferred, read_cancel_reason()); |
271 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { | 271 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { |
272 ReadCompleted(0, api::serial::RECEIVE_ERROR_SYSTEM_ERROR); | 272 ReadCompleted(0, device::serial::RECEIVE_ERROR_SYSTEM_ERROR); |
273 } else { | 273 } else { |
274 ReadCompleted( | 274 ReadCompleted(bytes_transferred, |
275 bytes_transferred, | 275 error == ERROR_SUCCESS |
276 error == ERROR_SUCCESS ? api::serial::RECEIVE_ERROR_NONE | 276 ? device::serial::RECEIVE_ERROR_NONE |
277 : api::serial::RECEIVE_ERROR_SYSTEM_ERROR); | 277 : device::serial::RECEIVE_ERROR_SYSTEM_ERROR); |
278 } | 278 } |
279 } else if (context == write_context_) { | 279 } else if (context == write_context_) { |
280 DCHECK(pending_write_buffer()); | 280 DCHECK(pending_write_buffer()); |
281 if (write_canceled()) { | 281 if (write_canceled()) { |
282 WriteCompleted(0, write_cancel_reason()); | 282 WriteCompleted(0, write_cancel_reason()); |
283 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { | 283 } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { |
284 WriteCompleted(0, api::serial::SEND_ERROR_SYSTEM_ERROR); | 284 WriteCompleted(0, device::serial::SEND_ERROR_SYSTEM_ERROR); |
285 } else { | 285 } else { |
286 WriteCompleted( | 286 WriteCompleted(bytes_transferred, |
287 bytes_transferred, | 287 error == ERROR_SUCCESS |
288 error == ERROR_SUCCESS ? api::serial::SEND_ERROR_NONE | 288 ? device::serial::SEND_ERROR_NONE |
289 : api::serial::SEND_ERROR_SYSTEM_ERROR); | 289 : device::serial::SEND_ERROR_SYSTEM_ERROR); |
290 } | 290 } |
291 } else { | 291 } else { |
292 NOTREACHED() << "Invalid IOContext"; | 292 NOTREACHED() << "Invalid IOContext"; |
293 } | 293 } |
294 } | 294 } |
295 | 295 |
296 bool SerialIoHandlerWin::ConfigurePort( | 296 bool SerialIoHandlerWin::ConfigurePort( |
297 const api::serial::ConnectionOptions& options) { | 297 const device::serial::ConnectionOptions& options) { |
298 DCB config = {0}; | 298 DCB config = {0}; |
299 config.DCBlength = sizeof(config); | 299 config.DCBlength = sizeof(config); |
300 if (!GetCommState(file().GetPlatformFile(), &config)) { | 300 if (!GetCommState(file().GetPlatformFile(), &config)) { |
301 return false; | 301 return false; |
302 } | 302 } |
303 if (options.bitrate.get()) | 303 if (options.bitrate) |
304 config.BaudRate = BitrateToSpeedConstant(*options.bitrate); | 304 config.BaudRate = BitrateToSpeedConstant(options.bitrate); |
305 if (options.data_bits != api::serial::DATA_BITS_NONE) | 305 if (options.data_bits != device::serial::DATA_BITS_NONE) |
306 config.ByteSize = DataBitsEnumToConstant(options.data_bits); | 306 config.ByteSize = DataBitsEnumToConstant(options.data_bits); |
307 if (options.parity_bit != api::serial::PARITY_BIT_NONE) | 307 if (options.parity_bit != device::serial::PARITY_BIT_NONE) |
308 config.Parity = ParityBitEnumToConstant(options.parity_bit); | 308 config.Parity = ParityBitEnumToConstant(options.parity_bit); |
309 if (options.stop_bits != api::serial::STOP_BITS_NONE) | 309 if (options.stop_bits != device::serial::STOP_BITS_NONE) |
310 config.StopBits = StopBitsEnumToConstant(options.stop_bits); | 310 config.StopBits = StopBitsEnumToConstant(options.stop_bits); |
311 if (options.cts_flow_control.get()) { | 311 if (options.has_cts_flow_control) { |
312 if (*options.cts_flow_control) { | 312 if (options.cts_flow_control) { |
313 config.fOutxCtsFlow = TRUE; | 313 config.fOutxCtsFlow = TRUE; |
314 config.fRtsControl = RTS_CONTROL_HANDSHAKE; | 314 config.fRtsControl = RTS_CONTROL_HANDSHAKE; |
315 } else { | 315 } else { |
316 config.fOutxCtsFlow = FALSE; | 316 config.fOutxCtsFlow = FALSE; |
317 config.fRtsControl = RTS_CONTROL_ENABLE; | 317 config.fRtsControl = RTS_CONTROL_ENABLE; |
318 } | 318 } |
319 } | 319 } |
320 return SetCommState(file().GetPlatformFile(), &config) != 0; | 320 return SetCommState(file().GetPlatformFile(), &config) != 0; |
321 } | 321 } |
322 | 322 |
323 bool SerialIoHandlerWin::Flush() const { | 323 bool SerialIoHandlerWin::Flush() const { |
324 return PurgeComm(file().GetPlatformFile(), PURGE_RXCLEAR | PURGE_TXCLEAR) != | 324 return PurgeComm(file().GetPlatformFile(), PURGE_RXCLEAR | PURGE_TXCLEAR) != |
325 0; | 325 0; |
326 } | 326 } |
327 | 327 |
328 bool SerialIoHandlerWin::GetControlSignals( | 328 device::serial::DeviceControlSignalsPtr SerialIoHandlerWin::GetControlSignals() |
329 api::serial::DeviceControlSignals* signals) const { | 329 const { |
330 DWORD status; | 330 DWORD status; |
331 if (!GetCommModemStatus(file().GetPlatformFile(), &status)) { | 331 if (!GetCommModemStatus(file().GetPlatformFile(), &status)) { |
332 return false; | 332 return device::serial::DeviceControlSignalsPtr(); |
333 } | 333 } |
| 334 |
| 335 device::serial::DeviceControlSignalsPtr signals( |
| 336 device::serial::DeviceControlSignals::New()); |
334 signals->dcd = (status & MS_RLSD_ON) != 0; | 337 signals->dcd = (status & MS_RLSD_ON) != 0; |
335 signals->cts = (status & MS_CTS_ON) != 0; | 338 signals->cts = (status & MS_CTS_ON) != 0; |
336 signals->dsr = (status & MS_DSR_ON) != 0; | 339 signals->dsr = (status & MS_DSR_ON) != 0; |
337 signals->ri = (status & MS_RING_ON) != 0; | 340 signals->ri = (status & MS_RING_ON) != 0; |
338 return true; | 341 return signals.Pass(); |
339 } | 342 } |
340 | 343 |
341 bool SerialIoHandlerWin::SetControlSignals( | 344 bool SerialIoHandlerWin::SetControlSignals( |
342 const api::serial::HostControlSignals& signals) { | 345 const device::serial::HostControlSignals& signals) { |
343 if (signals.dtr.get()) { | 346 if (signals.has_dtr) { |
344 if (!EscapeCommFunction(file().GetPlatformFile(), | 347 if (!EscapeCommFunction(file().GetPlatformFile(), |
345 *signals.dtr ? SETDTR : CLRDTR)) { | 348 signals.dtr ? SETDTR : CLRDTR)) { |
346 return false; | 349 return false; |
347 } | 350 } |
348 } | 351 } |
349 if (signals.rts.get()) { | 352 if (signals.has_rts) { |
350 if (!EscapeCommFunction(file().GetPlatformFile(), | 353 if (!EscapeCommFunction(file().GetPlatformFile(), |
351 *signals.rts ? SETRTS : CLRRTS)) { | 354 signals.rts ? SETRTS : CLRRTS)) { |
352 return false; | 355 return false; |
353 } | 356 } |
354 } | 357 } |
355 return true; | 358 return true; |
356 } | 359 } |
357 | 360 |
358 bool SerialIoHandlerWin::GetPortInfo(api::serial::ConnectionInfo* info) const { | 361 device::serial::ConnectionInfoPtr SerialIoHandlerWin::GetPortInfo() const { |
359 DCB config = {0}; | 362 DCB config = {0}; |
360 config.DCBlength = sizeof(config); | 363 config.DCBlength = sizeof(config); |
361 if (!GetCommState(file().GetPlatformFile(), &config)) { | 364 if (!GetCommState(file().GetPlatformFile(), &config)) { |
362 return false; | 365 return device::serial::ConnectionInfoPtr(); |
363 } | 366 } |
364 info->bitrate.reset(new int(SpeedConstantToBitrate(config.BaudRate))); | 367 device::serial::ConnectionInfoPtr info(device::serial::ConnectionInfo::New()); |
| 368 info->bitrate = SpeedConstantToBitrate(config.BaudRate); |
365 info->data_bits = DataBitsConstantToEnum(config.ByteSize); | 369 info->data_bits = DataBitsConstantToEnum(config.ByteSize); |
366 info->parity_bit = ParityBitConstantToEnum(config.Parity); | 370 info->parity_bit = ParityBitConstantToEnum(config.Parity); |
367 info->stop_bits = StopBitsConstantToEnum(config.StopBits); | 371 info->stop_bits = StopBitsConstantToEnum(config.StopBits); |
368 info->cts_flow_control.reset(new bool(config.fOutxCtsFlow != 0)); | 372 info->cts_flow_control = config.fOutxCtsFlow != 0; |
369 return true; | 373 return info.Pass(); |
370 } | 374 } |
371 | 375 |
372 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { | 376 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { |
373 // For COM numbers less than 9, CreateFile is called with a string such as | 377 // For COM numbers less than 9, CreateFile is called with a string such as |
374 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added. | 378 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added. |
375 if (port_name.length() > std::string("COM9").length()) | 379 if (port_name.length() > std::string("COM9").length()) |
376 return std::string("\\\\.\\").append(port_name); | 380 return std::string("\\\\.\\").append(port_name); |
377 | 381 |
378 return port_name; | 382 return port_name; |
379 } | 383 } |
380 | 384 |
381 } // namespace extensions | 385 } // namespace extensions |
OLD | NEW |