Reading HEX values from a serial port (Posix) - c++

I wrote a class to handle data coming from a module to the serial port.
The goal is having the port always listening and when it's needed transmit some messages.
The module communicates using hexadecimal tokens.
Here is my code for the receiving part:
int serial::serial_receive (string &s_buffer, int &rcp)
{
struct pollfd fds[1];
fds[0].fd = ptr;
fds[0].events = POLLIN ;
int pollrc = poll( fds, 1, 1000);
if (pollrc < 0)
{
perror("poll");
}
else if( pollrc > 0)
{
if( fds[0].revents & POLLIN )
{
char buff[1024];
ssize_t rc = read(ptr, buff, sizeof(buff) );
if (rc > 0)
{
s_buffer = buff;
rcp = rc;
}
else {cout << "error reading fd";}
}
}
return pollrc;
}
In my test main:
using namespace std;
char test[] = {0xAA,0x34,0x00,0x22};
int main(void) {
stringstream ss;
const char* mybuff;
string serial_buffer;
int rcl;
serial mymodule ("/dev/ttymxc5",115200, 0); //port configuration
ss << std::hex << setfill('0');
mymodule.serial_send(test,4); //send method
usleep(2000);
mymodule.serial_receive(serial_buffer,rcl); //receive method
mybuff = serial_buffer.c_str();
for (int i = 0; i < 8; ++i)
{
ss << std::setw(2) << static_cast<unsigned>(mybuff[i]);
}
cout << ss.str() << endl;
return 0;
}
My serial port configuration is:
int serial::serial_set()
{
struct termios options;
if (tcgetattr (ptr, &options) != 0)
{
return EXIT_FAILURE;
}
cfsetospeed (&options, B115200);
cfsetispeed (&options, B115200);
options.c_cflag = (options.c_cflag & ~CSIZE) | CS8;
options.c_iflag &= ~IGNBRK;
options.c_lflag = 0;
options.c_oflag = 0;
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 5;
options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~(PARENB | PARODD);
options.c_cflag |= serial_parity;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CRTSCTS;
if (tcsetattr (ptr, TCSANOW, &options) != 0)
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Please note that ISTRIP bit is set as 0, not to lose the 8th bit.
The resoult i get is "almost" correct.
I'm aspecting a AA B4 04 01 00 00 00 94 sequence but instead i get a AA B4 04 01 00 A8 4A F0 sequence.
This mistake is repeatable, every time I send given command to the module.
Do you possible have some ints or suggestions ?

After some thinking, I found out that i can't simply cast string = char*.
I used a string method instead to build my string:
std::string check(reinterpret_cast<char*>(buff), 8);
Where buff is the char array to convert and 8 is the number of elements.
Thanks to Neil Butterworth who pointed out the unsafe casting.

Related

Difficulty communicating over serial ports in Linux

I have success writing code in Windows and performing serial port communication. But not in Linux so far.
Here is the code I wrote:
I have used Picocom to verify that I can communicate over the serial ports via my (USB to NULL Modem to USB) cable.
Setting the code to None blocking yields "errno: 11 Resource temporarily unavailable" on both client and server."
When I set to Blocking, it hangs in code at the Read File method. If I comment that line out it runs... but not getting data.
Server sends packets continuous.
Client receives packets continuous.
Problem seems to be bytes aren't received at the client. They are sent, however at the server.
CLIENT:
RECV(1611912): NumChars: 0 String:
RECV(1611913): NumChars: 0 String:
RECV(1611918): NumChars: 0 String:
RECV(1611919): NumChars: 0 String:
RECV(1611920): NumChars: 0 String:
SERVER:
SENT(106775): NumChars: 10 String: 0123456789
SENT(106776): NumChars: 10 String: 0123456789
SENT(106777): NumChars: 10 String: 0123456789
SENT(106778): NumChars: 10 String: 0123456789
SENT(106779): NumChars: 10 String: 0123456789
to run:
g++ -o sp serialport.cpp
client: ./sp /dev/ttyS0 c
server: ./sp /dev/ttyS4 s
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
class C_SerialPort
{
private:
int giFD;
char gpcDevice[100] = {0};
public:
//------------------------------------------------
//
//------------------------------------------------
int GetError(char* pcMessage = (char*)"")
{
char pcError[100] = {0};
sprintf(pcError, " (%s): errno: %d %s\n", pcMessage, errno, strerror(errno));
if(errno > 0)
{
printf("%s", pcError);
}
return errno;
}
//------------------------------------------------
//
//------------------------------------------------
int Connect()
{
return Connect((char*)"/dev/ttyS0");
//return Connect((char*)"/dev/ttyUSB0");
}
//------------------------------------------------
//
//------------------------------------------------
int Connect(char *pcDevice)
{
strcpy(gpcDevice, pcDevice);
struct termios s_TA;
// Open the serial port
giFD = open(gpcDevice, O_RDWR | O_NOCTTY | O_NDELAY | O_FSYNC );
if(giFD < 0)
{
printf("open_port: Unable to open %s\n%s", gpcDevice, strerror(errno));
printf("EXITING...\n");
return 1;
}
else
{
printf("Connect Device: %s\n", gpcDevice);
}
// get attributes
if(tcgetattr(giFD, &s_TA) != 0)
{
GetError((char*)"tcgetattr");
printf("EXITING...\n");
return 1;
}
// clear terminalAttributes data
//memset(&s_TA, 0, sizeof(struct termios));
if(0)
{
// 57600 bauds; 8 bits per word; Ignore modem control lines; Enable receiver.
s_TA.c_cflag = B57600 | CS8 | CLOCAL | CREAD;
// Ignore framing errors and parity errors.
s_TA.c_iflag = IGNPAR | ONLCR;
//Enable implementation-defined output processing.
s_TA.c_oflag = OPOST;
// min time; min bytes to read
s_TA.c_cc[VTIME] = 1;
s_TA.c_cc[VMIN] = 1;// none zero blocks
}
else
{
cfsetospeed(&s_TA, B9600);
cfsetispeed(&s_TA, B9600);
s_TA.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
s_TA.c_cflag &= ~CSIZE;
s_TA.c_cflag |= CS8; /* 8-bit characters */
s_TA.c_cflag &= ~PARENB; /* no parity bit */
s_TA.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
s_TA.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
/* setup for non-canonical mode */
s_TA.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
s_TA.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
s_TA.c_oflag &= ~OPOST;
/* fetch bytes as they become available */
s_TA.c_cc[VMIN] = 1; // 0 1
s_TA.c_cc[VTIME] = 1; // 0 1
}
//int iVal = fcntl(giFD, F_SETFL, 0); // set blocking?
//printf("file status = 0x%x\n", iVal);
//GetError((char*)"fcntl");
// Set the port to our state
if (tcsetattr(giFD, TCSANOW, &s_TA) != 0)
{
GetError((char*)"tcsetattr");
printf("EXITING...\n");
return 1;
}
// flushes data written but not transmitted.
// flushes data received but not read.
tcflush(giFD, TCOFLUSH);
tcflush(giFD, TCIFLUSH);
printf("CONNECTION OK\n");
//return giFD;
return 0;
}
//------------------------------------------------
//
//------------------------------------------------
void Disconnect(void)
{
close(giFD);
printf("nPort 1 has been CLOSED and %d is the file descriptionn", giFD);
GetError((char*)"Disconnect");
}
//------------------------------------------------
//
//------------------------------------------------
int SendArray(unsigned char *buffer, int len)
{
int n = write(giFD, buffer, len);
// error catch
if(n < 0)
GetError((char*)"write");
return n;
}
//------------------------------------------------
//
//------------------------------------------------
int GetArray (unsigned char *buffer, int len)
{
int n = 0;
int len2 = BytesToRead();
n = read(giFD, buffer, len2); // this line is an issue? with settings?
// error catch
//if(n < 0)
// GetError((char*)"read");
return n;
}
//------------------------------------------------
//
//------------------------------------------------
void Clear()
{
tcflush(giFD, TCIFLUSH);
tcflush(giFD, TCOFLUSH);
}
//------------------------------------------------
//
//------------------------------------------------
int BytesToRead()
{
int iBytes = 0;
ioctl(giFD, FIONREAD, &iBytes);
//printf("Byte2Read: %d\n", iBytes);
// error catch
GetError((char*)"BytesToRead");
return iBytes;
}
};
//------------------------------------------------
//
//------------------------------------------------
int main(int argc, char const *argv[])
{
// device
char *pcDevice = (char*)argv[1];
printf("init:device:%s\n", pcDevice);
// connection type
char cConnType = argv[2][0];
printf("ConnectionType:%c\n", cConnType);
// instantiate SerialPort
C_SerialPort c_SP;
// connect
int iReturn = c_SP.Connect(pcDevice);
if(iReturn != 0)
{
printf("EXITING...\n");
return 1;
}
// clear buffer
c_SP.Clear();
printf("clear\n");
printf("prior...\n");
// main loop
while(1)
{
int iSleep_ms = 200;
usleep(iSleep_ms);
char pcArray[100] = {0};
int iNumChars = 0;
if(cConnType == 's')
{
static long lCount = 0;
// Send
strcpy(pcArray, "0123456789");
iNumChars = c_SP.SendArray((unsigned char*)pcArray, 10);
if(iNumChars > 0)
{
printf("SENT(%ld): NumChars: %d String: %s\n", lCount, iNumChars, pcArray);
}
lCount++;
}
if(cConnType == 'c')
{
static long lCount = 0;
// Receive
iNumChars = c_SP.GetArray((unsigned char*)pcArray, sizeof(pcArray));
if(iNumChars > 0)
{
printf("RECV(%ld): NumChars: %d String: %s\n", lCount, iNumChars, pcArray);
}
else
{
//printf("RECV: NumChars: %d String: %s\n", iNumChars, pcArray);
}
lCount++;
}
}
c_SP.Disconnect();
return 0;
}
You have four major bugs:
Your GetArray function ignores the return value of BytesToRead. It should read the lesser of the buffer size or the number of bytes available.
Your code has no ability to sanely handle the case where BytesToRead returns zero.
You ignore the return value of GetArray. When you print pcArray, you do not tell printf how many characters to output. So how is it supposed to know what to print?
You overwrite the returned values from tcgetattr by calling memset.
The issue is the serial port to communicate through.
The /dev/ttyS0 and /dev/ttyS4 are the serial ports after the USB in the NULL modem cable hook up. But to communicate I had to use /dev/ttyUSB0 and /dev/ttyUSB1

Serial data sniffer not working as expected

I'm trying to get serial data from one port /dev/ttyUSB0 and pass it to the second one /dev/ttyUSB1 and vice versa. By my, apparently, flaunted logic the code below should work as expected. But the data seems not to reach the second port correctly, as I am not getting a correct response. I need my own program because I need to control the flow of data between the two serial devices.
#include <iostream>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
using namespace std;
int set_interface_attribs(int fd, int speed)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error from tcgetattr: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
/* setup for non-canonical mode */
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_oflag &= ~OPOST;
/* fetch bytes as they become available */
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 1;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}
void set_mincount(int fd, int mcount)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error tcgetattr: %s\n", strerror(errno));
return;
}
tty.c_cc[VMIN] = mcount ? 1 : 0;
tty.c_cc[VTIME] = 5; /* half second timer */
if (tcsetattr(fd, TCSANOW, &tty) < 0)
printf("Error tcsetattr: %s\n", strerror(errno));
}
void read_send(int port1, int port2)
{
unsigned char buf[1024];
int rdlen;
int wlen;
printf("Reading port 1\n");
rdlen = read(port1, buf, sizeof(buf) - 1);
if (rdlen > 0) {
unsigned char *p;
printf("Writing %d:\n", rdlen);
wlen = write (port2, buf, rdlen);
tcdrain(port2);
if (wlen != rdlen) {
printf("Error from write: %d, %s\n", wlen, strerror(errno));
}
} else if (rdlen < 0) {
printf("Error from read: %d: %s\n", rdlen, strerror(errno));
}
}
void connect_data(int port1, int port2)
{
//read 1 write on 2; read 2 write on 1
read_send(port1, port2);
read_send(port2, port1);
}
int main()
{
char *portname_cp = "/dev/ttyUSB0";
char *portname_rfid = "/dev/ttyUSB1";
int fd_cp;
int fd_rfid;
int wlen;
fd_rfid = open(portname_rfid, O_RDWR | O_NOCTTY | O_SYNC);
fd_cp = open(portname_cp, O_RDWR | O_NOCTTY | O_SYNC);
if (fd_rfid < 0) {
printf("Error opening %s: %s\n", portname_rfid, strerror(errno));
return -1;
}
if (fd_cp < 0) {
printf("Error opening %s: %s\n", portname_cp, strerror(errno));
return -1;
}
printf("Ports opened\n");
/*baudrate 115200, 8 bits, no parity, 1 stop bit */
set_interface_attribs(fd_rfid, B115200);
//set_mincount(fd_rfid, 0); /* set to pure timed read */
set_interface_attribs(fd_cp, B115200);
//set_mincount(fd_cp, 0); /* set to pure timed read */
do {
connect_data(fd_cp, fd_rfid);
} while(true);
return 0;
}

serial port read/write returns too early

I have written a small and simple serial port read/write application to connect to my modem and to run commands. There is a problem. The program works perfectly for the most part but when the command takes a bit of time to execute and respond, the program acts strangely. Here is my code:
void write (char cmd[256]) {
int n_written = 0;
char atcmd [259];
sprintf (atcmd, "%s\r\n", cmd);
n_written = write( fd, &atcmd, strlen(atcmd) );
printf ("WROTE: %d\n", n_written);
}
void read (char * cmdresp) {
int n = 0;
char response[1024];
memset(response, 0 , sizeof response);
n = read( fd, &response, sizeof (response) );
if (n < 0) {
printf ("ERROR=%d - %s\n", errno, strerror(errno));
} else if (n == 0) {
printf ("Read nothing!\n");
} else {
printf ("READ: %s\n", response);
strcpy (cmdresp, response);
}
}
void manage_transaction (char * message, char * response) {
tv.tv_sec = 5;
tv.tv_usec = 0;
write (message);
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
int retval = select(fd+1, &rfds, NULL, NULL, &tv);
if (retval == -1) {
perror("select()");
} else if (retval) {
if (FD_ISSET(fd, &rfds) ) {
usleep(200000);
read(response);
}
} else {
printf("No data within five seconds.\n");
}
}
Here is two successive runs, one successful one unsuccessful:
Successful:
AT> AT+CGSN
Client ConnectedHere is the message: AT+CGSN
WROTE: 11
READ: AT+CGSN
123456789012345
OK
AT+CGSN
123456789012345
OK
FAILED:
AT> ATD11234567890;
Here is the message: ATD11234567890;
WROTE: 19
READ: ATD11234567890;
AT> 1234567890;
<<-- If I press an enter key or send another message the rest of the message comes through:
Here is the message:
WROTE: 4
READ:
OK
OK
AT>
Am I missing something? How can I fix this problem?
Any ideas is greatly appreciated.
*********** EDIT ***************
Here are the open and config codes:
int open_port(void)
{
fd = open("/dev/ttyUSB2", O_RDWR | O_NOCTTY);
if(fd == -1) {
perror("open_port: Unable to open /dev/ttyUSB2");
}
else {
fcntl(fd, F_SETFL, 0);
printf("port is open.\n");
}
tcflush(fd, TCIFLUSH);
tcflush(fd, TCOFLUSH);
return fd;
}
void config () {
struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);
if ( tcgetattr ( fd, &tty ) != 0 ) {
printf ("ERROR=%d - %s\n", errno, strerror(errno));
}
tty_old = tty;
/* Set Baud Rate */
cfsetospeed (&tty, (speed_t)B115200);
cfsetispeed (&tty, (speed_t)B115200);
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_iflag &= ~INPCK;
tty.c_iflag |= (IGNBRK | BRKINT);
tty.c_iflag |= IGNPAR;
tty.c_iflag &= ~ICRNL;
tty.c_iflag &= ~IXON;
tty.c_iflag &= ~ISTRIP;
tty.c_iflag &= ~INLCR;
tty.c_iflag &= ~IGNCR;
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 0; // 5 seconds read timeout
tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
tty.c_iflag &= ~(IXON |IXOFF|IXANY); /* no XON/XOFF flow control */
tty.c_oflag &= ~(IXON |IXOFF|IXANY); /* no XON/XOFF flow control */
tty.c_oflag &= ~(OPOST | ONLCR );
/* Make raw */
cfmakeraw(&tty);
/* Flush Port, then applies attributes */
tcflush(fd, TCIFLUSH );
tcflush(fd, TCIOFLUSH );
int reuse = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse));
if ( (tcsetattr(fd,TCSANOW,&tty) < 0) ) {
printf ("ERROR=%d - %s\n", errno, strerror(errno));
}
}

linux c++ serial port echoes output

In my program which sends bytes to a serial port, I receive bytes which I send. I don't want to receive bytes which I send, and I don't know how to do this?
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/ioctl.h>
int fd;
struct termios tio, old_tio;
time_t SubTime_mSec(timeval val1, timeval val2)
{
timeval tv;
if (val1.tv_sec > val2.tv_sec) return (0);
if (val1.tv_sec == val2.tv_sec)
if (val1.tv_usec > val2.tv_usec) return (0);
tv.tv_sec = val2.tv_sec - val1.tv_sec;
if (val1.tv_usec < val2.tv_usec) {
tv.tv_usec = val2.tv_usec - val1.tv_usec;
} else {
tv.tv_sec --;
tv.tv_usec = 1000000 + val2.tv_usec - val1.tv_usec;
}
return(tv.tv_sec*1000 + tv.tv_usec/1000);
}
void RTUOutMessage(int cnt1, int cnt2)
{
unsigned char msg[13] = {0x01, 0x10, 0x00, 0x2F, 0x00, 0x02, 0x04, 0x4B, 0x64, 0x3D, 0xD9, 0x36, 0xC6};
int Len = 13;
int status, i, j;
ioctl(fd, TIOCMGET, &status);
status = status | TIOCM_RTS | TIOCM_DTR;
ioctl(fd, TIOCMSET, &status);
write(fd, msg, Len);
for (j = 0; j < cnt1; j ++)
for (i = 0; i < cnt2; i ++);
ioctl(fd, TIOCMGET, &status);
status &= ~TIOCM_RTS;
status &= ~TIOCM_DTR;
ioctl(fd, TIOCMSET, &status);
timeval start_t, curr_t;
char Buff[80];
int l;
gettimeofday(&start_t, NULL);
curr_t = start_t;
while (SubTime_mSec(start_t, curr_t) < 1000) {
l = read(fd, Buff, 80);
if (l > 0) {
printf("BUFFER=");
for(i = 0; i < l; i++) {
printf(" %x", Buff[i]);
}
//printf("\n");
}
gettimeofday(&curr_t, NULL);
}
}
void InitPort(void)
{
int StopBits = 2;
if ((fd = open("/dev/ttyAM2", O_RDWR | O_NDELAY)) < 0) {
printf("Couldn't open //dev//ttyAM2\n");
}
tcflush(fd, TCIOFLUSH);
int n = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, n & ~O_NDELAY);
tcgetattr(fd, &old_tio);
tcgetattr(fd, &tio);
cfsetospeed(&tio, (speed_t)B9600);
cfsetispeed(&tio, (speed_t)B9600);
tio.c_cflag = (tio.c_cflag & ~CSIZE) | CS8;
tio.c_cflag |= CLOCAL | CREAD ;
tio.c_cflag &= ~OFILL;
//parity
tio.c_cflag &= ~(PARENB | PARODD);
tio.c_cflag &= ~CRTSCTS;
if (StopBits == 2) tio.c_cflag |= CSTOPB;
else tio.c_cflag &= ~CSTOPB;
tio.c_iflag=IGNBRK;
tio.c_iflag &= ~(IXON|IXOFF|IXANY);
tio.c_lflag=0;
tio.c_oflag=0;
tio.c_cc[VTIME]=0;
tio.c_cc[VMIN]=0;
if (tcsetattr(fd, TCSANOW, &tio)!=0) printf("tcsetattr() 1 failed\n");
int mcs=0;
ioctl(fd, TIOCMGET, &mcs);
mcs |= TIOCM_RTS;
ioctl(fd, TIOCMSET, &mcs);
if (tcgetattr(fd, &tio)!=0) printf("tcgetattr() 4 failed\n");
tio.c_cflag &= ~CRTSCTS;
if (tcsetattr(fd, TCSANOW, &tio)!=0) printf("tcsetattr() 2 failed\n");
}
int main(int argc, char **argv)
{
InitPort();
int cnt1, cnt2;
cnt1 = 3;
cnt2 = 20000;
cnt1 = atoi(argv[1]);
cnt2 = atoi(argv[2]);
for(;;) {
RTUOutMessage(cnt1, cnt2);
usleep(1000000);
}
tcsetattr(fd, TCSANOW, &old_tio);
close(fd);
printf("End\n");
return 0;
}
If you are receiving the chars that you sent, then the remote's serial port is apparently echoing its input.
You will either have to disable input echo at the other device, or perform "echo cancellation" in your receive logic. I.E. create an "echo FIFO". Each byte output to the serial port is also written to the "echo FIFO". Set a flag indicating that an echo is expected. As input is received, compare it to the "echo FIFO", and remove chars when it matches, and toss the receive char. If no match, then accept receive char. Clear the echo flag when the "echo FIFO" is empty.
BTW the code appears to set the serial port to raw or non-canonical mode. The preferred method would be to use
cfmakeraw(&tio);
rather than
tio.c_iflag=IGNBRK;
tio.c_iflag &= ~(IXON|IXOFF|IXANY);
tio.c_lflag=0;
tio.c_oflag=0;

Serial port : Read data problem, not reading complete data

I have an application where I am sending data via serial port from PC1 (Java App) and reading that data in PC2 (C++ App). The problem that I am facing is that my PC2 (C++ App) is not able to read complete data sent by PC1 i.e. from my PC1 I am sending 190 bytes but PC2 is able to read close to 140 bytes though I am trying to read in a loop.
Below is code snippet of my C++ App
/**Open the connection to serial port**/
serialfd = open( serialPortName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if (serialfd == -1)
{
/*
* Could not open the port.
*/
TRACE << "Unable to open port: " << serialPortName << endl;
}
else
{
TRACE << "Connected to serial port: " << serialPortName << endl;
fcntl(serialfd, F_SETFL, 0);
}
/**Configure the Serial Port parameters**/
struct termios options;
/*
* Get the current options for the port...
*/
tcgetattr(serialfd, &options);
/*
* Set the baud rates to 9600...
*/
cfsetispeed(&options, B38400);
cfsetospeed(&options, B38400);
/*
* 8N1
* Data bits - 8
* Parity - None
* Stop bits - 1
*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
/*
* Enable hardware flow control
*/
options.c_cflag |= CRTSCTS;
/*
* Enable the receiver and set local mode...
*/
options.c_cflag |= (CLOCAL | CREAD);
// Flush the earlier data
tcflush(serialfd, TCIFLUSH);
/*
* Set the new options for the port...
*/
tcsetattr(serialfd, TCSANOW, &options);
**Now I am reading data**
const int MAXDATASIZE = 512;
std::vector<char> m_vRequestBuf;
char buffer[MAXDATASIZE];
int totalBytes = 0;
fcntl(serialfd, F_SETFL, FNDELAY);
while(1) {
bytesRead = read(serialfd, &buffer, MAXDATASIZE);
if(bytesRead == -1)
{
//Sleep for some time and read again
usleep(900000);
}
else
{
totalBytes += bytesRead;
//Add data read to vector
for(int i =0; i < bytesRead; i++)
{
m_vRequestBuf.push_back(buffer[i]);
}
int newBytesRead = 0;
//Now keep trying to read more data
while(newBytesRead != -1)
{
//clear contents of buffer
memset((void*)&buffer, 0, sizeof(char) * MAXDATASIZE);
newBytesRead = read(serialfd, &buffer, MAXDATASIZE);
totalBytes += newBytesRead;
for(int j = 0; j < newBytesRead; j++)
{
m_vRequestBuf.push_back(buffer[j]);
}
}//inner while
break;
} //while
Lateee response, but if you are reading in non-canonical mode, consider setting VMIN to the number of bytes you want to read.