3
votes

I've been working for quite while on little project of mine with some XBee's. Until now all the code has been tested and working on a UBUNTU-SERVER 10.04 LTS, making use of the libftdi libraries for serial-usb simulation/conversion.

At the beginning of this week, I've tried to use the exact same code on a laptop with kubuntu 12.04 make using of the same library versions of libftdi.

The thing is that, in my Satellite L755 - 18K laptop, every time I now try to open my XBee device at /dev/ttyUSB0, it gives me "Bad file descriptor". From the log messages from dmesg, the device registers quite normally and can't seem to put my finger one it.

Here it is the part of code used to open the device:

cfmakeraw(&tio);
cfsetospeed(&tio,B9600);            // 9600 baud
cfsetispeed(&tio,B9600);            // 9600 baud
tio.c_cc[VMIN]=0;
tio.c_cc[VTIME]=10;

serial_fd=open("/dev/ttyUSB0", O_RDWR);

tcsetattr(serial_fd,TCSANOW,&tio);


if (serial_fd < 0){

    cout << "Error while opening device... " << "errno = " << errno << endl;

    printf("Something went wrong with open()! %s\n", strerror(errno));
    exit(1);
}

Any thoughts on the subject would be greatly appreciated.

Regards

2
Nope! Running it as my normal user.cvicente
Well try running it as root since you request RDWR on /dev/* :) I need to run sermon as root on my system when I want to get RDRW access to /dev/ttyUSBxJite

2 Answers

5
votes

The problem is that you're calling open() and tcsetattr() in sequence, then only check afterwards for an error condition with the file.

Consider open() fails for some reason. It will return -1 and set errno to that reason. However, the code in your question proceeds into calling tcsetattr() nonetheless, which will fail since serial_fd will be -1 in our case, and will overwrite errno with the reason why (EBADF, -1 is not a valid file descriptor).

You should instead check for an error condition immediately after opening the file:

serial_fd = open("/dev/ttyUSB0", O_RDWR);
if (serial_fd < 0) {
    cout << "Error while opening device... " << "errno = " << errno << endl;
    perror("Something went wrong with open()");
    exit(1);
}

And only then, issue:

tcsetattr(serial_fd, TCSANOW, &tio);
3
votes

Look at Frédéric's answer and then make sure you have permission to open the device. I need to be root to access (perhaps only to get write permission to) /dev/ttyUSB0 on my system. I think it's distro-dependent because on Debian I was able to open it as a regular user but I need to be root on my Arch distro. Might be possible to fix by looking at groups and permissions for /dev/ttyUSBx.

EDIT: Actually I'm able to get a file descriptor with a simple test program, so it might be a sermon-specific problem in my case.

Simple solution might be to run the program as root.