Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: device/serial/serial_io_handler_posix.cc

Issue 873903002: Set serial connection parameters immediately on connect. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add a comment explaing the "set" notation. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/serial/serial_io_handler_posix.h ('k') | device/serial/serial_io_handler_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_posix.h" 5 #include "device/serial/serial_io_handler_posix.h"
6 6
7 #include <sys/ioctl.h> 7 #include <sys/ioctl.h>
8 #include <termios.h> 8 #include <termios.h>
9 9
10 #include "base/posix/eintr_wrapper.h" 10 #include "base/posix/eintr_wrapper.h"
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 QueueReadCompleted(0, read_cancel_reason()); 189 QueueReadCompleted(0, read_cancel_reason());
190 } 190 }
191 191
192 void SerialIoHandlerPosix::CancelWriteImpl() { 192 void SerialIoHandlerPosix::CancelWriteImpl() {
193 DCHECK(CalledOnValidThread()); 193 DCHECK(CalledOnValidThread());
194 is_watching_writes_ = false; 194 is_watching_writes_ = false;
195 file_write_watcher_.StopWatchingFileDescriptor(); 195 file_write_watcher_.StopWatchingFileDescriptor();
196 QueueWriteCompleted(0, write_cancel_reason()); 196 QueueWriteCompleted(0, write_cancel_reason());
197 } 197 }
198 198
199 bool SerialIoHandlerPosix::ConfigurePortImpl() {
200 struct termios config;
201 if (tcgetattr(file().GetPlatformFile(), &config) != 0) {
202 VPLOG(1) << "Failed to get port attributes";
203 return false;
204 }
205
206 // Set flags for 'raw' operation
207 config.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL | ISIG);
208 config.c_iflag &=
209 ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
210 config.c_oflag &= ~OPOST;
211
212 // CLOCAL causes the system to disregard the DCD signal state.
213 // CREAD enables reading from the port.
214 config.c_cflag |= (CLOCAL | CREAD);
215
216 DCHECK(options().bitrate);
217 speed_t bitrate_opt = B0;
218 if (BitrateToSpeedConstant(options().bitrate, &bitrate_opt)) {
219 cfsetispeed(&config, bitrate_opt);
220 cfsetospeed(&config, bitrate_opt);
221 } else {
222 // Attempt to set a custom speed.
223 if (!SetCustomBitrate(file().GetPlatformFile(), &config,
224 options().bitrate)) {
225 return false;
226 }
227 }
228
229 DCHECK(options().data_bits != serial::DATA_BITS_NONE);
230 config.c_cflag &= ~CSIZE;
231 switch (options().data_bits) {
232 case serial::DATA_BITS_SEVEN:
233 config.c_cflag |= CS7;
234 break;
235 case serial::DATA_BITS_EIGHT:
236 default:
237 config.c_cflag |= CS8;
238 break;
239 }
240
241 DCHECK(options().parity_bit != serial::PARITY_BIT_NONE);
242 switch (options().parity_bit) {
243 case serial::PARITY_BIT_EVEN:
244 config.c_cflag |= PARENB;
245 config.c_cflag &= ~PARODD;
246 break;
247 case serial::PARITY_BIT_ODD:
248 config.c_cflag |= (PARODD | PARENB);
249 break;
250 case serial::PARITY_BIT_NO:
251 default:
252 config.c_cflag &= ~(PARODD | PARENB);
253 break;
254 }
255
256 DCHECK(options().stop_bits != serial::STOP_BITS_NONE);
257 switch (options().stop_bits) {
258 case serial::STOP_BITS_TWO:
259 config.c_cflag |= CSTOPB;
260 break;
261 case serial::STOP_BITS_ONE:
262 default:
263 config.c_cflag &= ~CSTOPB;
264 break;
265 }
266
267 DCHECK(options().has_cts_flow_control);
268 if (options().cts_flow_control) {
269 config.c_cflag |= CRTSCTS;
270 } else {
271 config.c_cflag &= ~CRTSCTS;
272 }
273
274 if (tcsetattr(file().GetPlatformFile(), TCSANOW, &config) != 0) {
275 VPLOG(1) << "Failed to set port attributes";
276 return false;
277 }
278 return true;
279 }
280
199 SerialIoHandlerPosix::SerialIoHandlerPosix( 281 SerialIoHandlerPosix::SerialIoHandlerPosix(
200 scoped_refptr<base::MessageLoopProxy> file_thread_message_loop, 282 scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
201 scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop) 283 scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop)
202 : SerialIoHandler(file_thread_message_loop, ui_thread_message_loop), 284 : SerialIoHandler(file_thread_message_loop, ui_thread_message_loop),
203 is_watching_reads_(false), 285 is_watching_reads_(false),
204 is_watching_writes_(false) { 286 is_watching_writes_(false) {
205 } 287 }
206 288
207 SerialIoHandlerPosix::~SerialIoHandlerPosix() { 289 SerialIoHandlerPosix::~SerialIoHandlerPosix() {
208 } 290 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 is_watching_writes_ = 357 is_watching_writes_ =
276 base::MessageLoopForIO::current()->WatchFileDescriptor( 358 base::MessageLoopForIO::current()->WatchFileDescriptor(
277 file().GetPlatformFile(), 359 file().GetPlatformFile(),
278 true, 360 true,
279 base::MessageLoopForIO::WATCH_WRITE, 361 base::MessageLoopForIO::WATCH_WRITE,
280 &file_write_watcher_, 362 &file_write_watcher_,
281 this); 363 this);
282 } 364 }
283 } 365 }
284 366
285 bool SerialIoHandlerPosix::ConfigurePort( 367 bool SerialIoHandlerPosix::Flush() const {
286 const serial::ConnectionOptions& options) { 368 if (tcflush(file().GetPlatformFile(), TCIOFLUSH) != 0) {
287 struct termios config; 369 VPLOG(1) << "Failed to flush port";
288 tcgetattr(file().GetPlatformFile(), &config); 370 return false;
289 if (options.bitrate) {
290 speed_t bitrate_opt = B0;
291 if (BitrateToSpeedConstant(options.bitrate, &bitrate_opt)) {
292 cfsetispeed(&config, bitrate_opt);
293 cfsetospeed(&config, bitrate_opt);
294 } else {
295 // Attempt to set a custom speed.
296 if (!SetCustomBitrate(
297 file().GetPlatformFile(), &config, options.bitrate)) {
298 return false;
299 }
300 }
301 } 371 }
302 if (options.data_bits != serial::DATA_BITS_NONE) { 372 return true;
303 config.c_cflag &= ~CSIZE;
304 switch (options.data_bits) {
305 case serial::DATA_BITS_SEVEN:
306 config.c_cflag |= CS7;
307 break;
308 case serial::DATA_BITS_EIGHT:
309 default:
310 config.c_cflag |= CS8;
311 break;
312 }
313 }
314 if (options.parity_bit != serial::PARITY_BIT_NONE) {
315 switch (options.parity_bit) {
316 case serial::PARITY_BIT_EVEN:
317 config.c_cflag |= PARENB;
318 config.c_cflag &= ~PARODD;
319 break;
320 case serial::PARITY_BIT_ODD:
321 config.c_cflag |= (PARODD | PARENB);
322 break;
323 case serial::PARITY_BIT_NO:
324 default:
325 config.c_cflag &= ~(PARODD | PARENB);
326 break;
327 }
328 }
329 if (options.stop_bits != serial::STOP_BITS_NONE) {
330 switch (options.stop_bits) {
331 case serial::STOP_BITS_TWO:
332 config.c_cflag |= CSTOPB;
333 break;
334 case serial::STOP_BITS_ONE:
335 default:
336 config.c_cflag &= ~CSTOPB;
337 break;
338 }
339 }
340 if (options.has_cts_flow_control) {
341 if (options.cts_flow_control) {
342 config.c_cflag |= CRTSCTS;
343 } else {
344 config.c_cflag &= ~CRTSCTS;
345 }
346 }
347 return tcsetattr(file().GetPlatformFile(), TCSANOW, &config) == 0;
348 }
349
350 bool SerialIoHandlerPosix::PostOpen() {
351 struct termios config;
352 tcgetattr(file().GetPlatformFile(), &config);
353
354 // Set flags for 'raw' operation
355 config.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL | ISIG);
356 config.c_iflag &=
357 ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
358 config.c_oflag &= ~OPOST;
359
360 // CLOCAL causes the system to disregard the DCD signal state.
361 // CREAD enables reading from the port.
362 config.c_cflag |= (CLOCAL | CREAD);
363
364 return tcsetattr(file().GetPlatformFile(), TCSANOW, &config) == 0;
365 }
366
367 bool SerialIoHandlerPosix::Flush() const {
368 return tcflush(file().GetPlatformFile(), TCIOFLUSH) == 0;
369 } 373 }
370 374
371 serial::DeviceControlSignalsPtr SerialIoHandlerPosix::GetControlSignals() 375 serial::DeviceControlSignalsPtr SerialIoHandlerPosix::GetControlSignals()
372 const { 376 const {
373 int status; 377 int status;
374 if (ioctl(file().GetPlatformFile(), TIOCMGET, &status) == -1) { 378 if (ioctl(file().GetPlatformFile(), TIOCMGET, &status) == -1) {
379 VPLOG(1) << "Failed to get port control signals";
375 return serial::DeviceControlSignalsPtr(); 380 return serial::DeviceControlSignalsPtr();
376 } 381 }
377 382
378 serial::DeviceControlSignalsPtr signals(serial::DeviceControlSignals::New()); 383 serial::DeviceControlSignalsPtr signals(serial::DeviceControlSignals::New());
379 signals->dcd = (status & TIOCM_CAR) != 0; 384 signals->dcd = (status & TIOCM_CAR) != 0;
380 signals->cts = (status & TIOCM_CTS) != 0; 385 signals->cts = (status & TIOCM_CTS) != 0;
381 signals->dsr = (status & TIOCM_DSR) != 0; 386 signals->dsr = (status & TIOCM_DSR) != 0;
382 signals->ri = (status & TIOCM_RI) != 0; 387 signals->ri = (status & TIOCM_RI) != 0;
383 return signals.Pass(); 388 return signals.Pass();
384 } 389 }
385 390
386 bool SerialIoHandlerPosix::SetControlSignals( 391 bool SerialIoHandlerPosix::SetControlSignals(
387 const serial::HostControlSignals& signals) { 392 const serial::HostControlSignals& signals) {
388 int status; 393 int status;
389 394
390 if (ioctl(file().GetPlatformFile(), TIOCMGET, &status) == -1) { 395 if (ioctl(file().GetPlatformFile(), TIOCMGET, &status) == -1) {
396 VPLOG(1) << "Failed to get port control signals";
391 return false; 397 return false;
392 } 398 }
393 399
394 if (signals.has_dtr) { 400 if (signals.has_dtr) {
395 if (signals.dtr) { 401 if (signals.dtr) {
396 status |= TIOCM_DTR; 402 status |= TIOCM_DTR;
397 } else { 403 } else {
398 status &= ~TIOCM_DTR; 404 status &= ~TIOCM_DTR;
399 } 405 }
400 } 406 }
401 407
402 if (signals.has_rts) { 408 if (signals.has_rts) {
403 if (signals.rts) { 409 if (signals.rts) {
404 status |= TIOCM_RTS; 410 status |= TIOCM_RTS;
405 } else { 411 } else {
406 status &= ~TIOCM_RTS; 412 status &= ~TIOCM_RTS;
407 } 413 }
408 } 414 }
409 415
410 return ioctl(file().GetPlatformFile(), TIOCMSET, &status) == 0; 416 if (ioctl(file().GetPlatformFile(), TIOCMSET, &status) != 0) {
417 VPLOG(1) << "Failed to set port control signals";
418 return false;
419 }
420 return true;
411 } 421 }
412 422
413 serial::ConnectionInfoPtr SerialIoHandlerPosix::GetPortInfo() const { 423 serial::ConnectionInfoPtr SerialIoHandlerPosix::GetPortInfo() const {
414 struct termios config; 424 struct termios config;
415 if (tcgetattr(file().GetPlatformFile(), &config) == -1) { 425 if (tcgetattr(file().GetPlatformFile(), &config) == -1) {
426 VPLOG(1) << "Failed to get port info";
416 return serial::ConnectionInfoPtr(); 427 return serial::ConnectionInfoPtr();
417 } 428 }
418 serial::ConnectionInfoPtr info(serial::ConnectionInfo::New()); 429 serial::ConnectionInfoPtr info(serial::ConnectionInfo::New());
419 speed_t ispeed = cfgetispeed(&config); 430 speed_t ispeed = cfgetispeed(&config);
420 speed_t ospeed = cfgetospeed(&config); 431 speed_t ospeed = cfgetospeed(&config);
421 if (ispeed == ospeed) { 432 if (ispeed == ospeed) {
422 int bitrate = 0; 433 int bitrate = 0;
423 if (SpeedConstantToBitrate(ispeed, &bitrate)) { 434 if (SpeedConstantToBitrate(ispeed, &bitrate)) {
424 info->bitrate = bitrate; 435 info->bitrate = bitrate;
425 } else if (ispeed > 0) { 436 } else if (ispeed > 0) {
(...skipping 17 matching lines...) Expand all
443 (config.c_cflag & CSTOPB) ? serial::STOP_BITS_TWO : serial::STOP_BITS_ONE; 454 (config.c_cflag & CSTOPB) ? serial::STOP_BITS_TWO : serial::STOP_BITS_ONE;
444 info->cts_flow_control = (config.c_cflag & CRTSCTS) != 0; 455 info->cts_flow_control = (config.c_cflag & CRTSCTS) != 0;
445 return info.Pass(); 456 return info.Pass();
446 } 457 }
447 458
448 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { 459 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) {
449 return port_name; 460 return port_name;
450 } 461 }
451 462
452 } // namespace device 463 } // namespace device
OLDNEW
« no previous file with comments | « device/serial/serial_io_handler_posix.h ('k') | device/serial/serial_io_handler_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698