0

I'm trying to write bytes using the write() Unix system call, but any 8-bit value I send that starts with 1 is turned into a 32-bit value. I've tried looking to see if there are any termios flags to fix this, but I can't seem to find any.

struct termios config;

if(!isatty(fd)) { std::cout << "Not a TTY" << std::endl; }
if(tcgetattr(fd, &config) < 0) {std::cout << "Termios structure is broken" << std::endl;}

config.c_iflag  = 0;//&= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON);
config.c_oflag = 0; //&= ~(OCRNL | ONLCR | ONLRET | ONOCR | CSTOPB | ONOEOT| OFILL | OPOST);
config.c_cflag &= ~(CSIZE | PARENB | CSTOPB); // 8bits, no parity, 1 stop
config.c_cflag |= CS8 | CREAD | HUPCL;
config.c_cc[VMIN]  = 0;
config.c_cc[VTIME] = 1;

// Communication speed (simple version, using the predefined constants)
if(cfsetispeed(&config, B9600) < 0 || cfsetospeed(&config, B9600) < 0) {
    std::cout << "Speed is messed up" << std::endl;
}

// Finally, apply the configuration
if(tcsetattr(fd, TCSAFLUSH, &config) < 0) { std::cout << "Applied Configuration is broken" << std::endl;}

// uint8_t c[2] = {'D','A'};
// write(fd,&c,2);
 write(fd,&command[6],2);

Sample of the input:

BIN6: 10111110 -------- HEX6:be -------- DEC6: 190 -------- ASCII6: ?

BIN7: 11101100 -------- HEX7: ec -------- DEC7: 236 -------- ASCII7: ?

Sample of the output:

BIN6: 000000011111111111111111111111110111110 -------- HEX: FFFFFFBE -------- DEC: -66 -------- ASCII: ¾

BIN7: 000000011111111111111111111111111101100 -------- HEX: FFFFFFEC -------- DEC: -20

Any idea how to fix this? Thanks!

Community
  • 1
  • 1
Nick Sweet
  • 2,030
  • 3
  • 31
  • 48

2 Answers2

1

The problem is not the terminal setting, but how characters are sign extended into 16-bit values. In your code snippet, you write two bytes. If you want to write only one byte, change the byte count to 1:

write (fd, &command[6], 1);
wallyk
  • 56,922
  • 16
  • 83
  • 148
  • I should clarify – command is an array of uint8_t, and the two bytes I'm writing are two bytes that start with 1 (in binary). For example, if I do `write (fd, &command[2], 1);` I actually get a worthwhile output that's exactly the same as the input: `2BIN: 00010000 -------- HEX: 10 -------- DEC: 16 -------- ASCII: 3` `BIN: 00000101 -------- HEX: 5 -------- DEC: 5 -------- ASCII:` – Nick Sweet Jul 04 '12 at 18:50
0

This was a simple, stupid error – turns out I was reading it as char instead of unsigned char.

Nick Sweet
  • 2,030
  • 3
  • 31
  • 48