Search code examples
usbuartttyusbserial

Connecting to tty port through C++ fails unless you've connected through screen first


I picked up an AUPS-A10-R11 DC UPS, and am working with their API to build some monitoring software for my xen host. Their API runs over the USB connection on the device, which presents itself as /dev/ttyUSB# on the host.

I've got things working fine except for one thing that's puzzling me. When I first power on or reboot the host it's connected to, I can't communicate with the device. However, if I open up a screen connection to it:

screen /dev/ttyUSB0 9600

and then close it (ctrl+a, k) then it will work perfectly fine until the next time that you reboot the host.

Does anyone have any idea as to why I would have to connect to the device over screen first? I've pasted my code here: http://susepaste.org/0b8bb37f . When connecting on a fresh reboot, it stops at the "Read Nothing" section of the if...else clause. After connecting to the device with screen, it works fine.

Any thoughts??


Solution

  • Does anyone have any idea as to why I would have to connect to the device over screen first?

    Such behavior is almost always related to incomplete termios initialization by your program.

    The ideal program would configure a serial terminal for its purposes, and on exit restore the termios configuration back to the way it found it.
    But most programs, including terminal emulation programs such as minicom and apparently screen, simply leave their termios configuration instead of restoring it.
    Fortunately for you, this leftover termios configuration fills in the missing pieces that allows your program to access the serial terminal as expected.

    Review of "your" code suggests that it was copied from the accepted answer of this question. Based on the number of up-votes, this code apparently works for a lot of people. However the author admits it was written before POSIX standards, and therefore the code should not be considered portable. In other words, your mileage may vary.

    Apparently you overlooked the alternative answer which is POSIX compliant. A tested termios configuration for blocking non-canonical mode is in that program.
    If you prefer to simplify with the use of the cfmakeraw() macro, then here's another code example.