linux c++ serial port echoes output - c++

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;

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));
}
}

Serial port polling not working on Beaglebone Black

I simply cannot get the poll() function to respond to data being sent over UART1 / /dev/ttyO1. Code as follows, maybe someone can spot my silly mistake?
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/poll.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
int openPort()
{
struct termios oldtio, newtio;
int fd = open("/dev/ttyO1",O_RDWR|O_NOCTTY|O_NONBLOCK|O_NDELAY);
if (fd == -1)
{
printf( "could not open tty" );
return -1;
}
if ( tcgetattr( fd, &oldtio ) == -1 )
{
printf( "error getting tcattr\n" );
close( fd );
return -1;
}
cfmakeraw( &newtio );
cfsetispeed( &newtio, B9600 );
cfsetospeed( &newtio, B9600 );
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8 | B9600;
newtio.c_cflag |= (CLOCAL | CREAD);
newtio.c_cflag &= ~(PARENB | PARODD);
newtio.c_cflag &= ~CRTSCTS;
newtio.c_cflag &= ~CSTOPB;
newtio.c_iflag = 0;//IGNPAR;
//newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
newtio.c_lflag = 0;
newtio.c_oflag = 0;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 1;
tcflush( fd, TCIOFLUSH );
if ( tcsetattr( fd, TCSANOW, &newtio ) == -1 )
{
close( fd );
printf( "error setting attrs\n" );
return -1;
}
return fd;
}
void selectLoop( int fd )
{
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN;
int rc = poll( fds, 1, 100000 );
if (rc < 0)
{
perror( "poll" );
}
else if (rc > 0)
{
char buffer[32] = {0};
int r = read( fd, buffer, sizeof(buffer) );
if (r == -1)
{
printf( "error: %s\n", strerror( errno ) );
}
else
{
printf( buffer );
}
}
else
{
printf( "No data\n" );
}
//close( fd );
sleep( 1 );
}
int main( int c, char ** v )
{
int fd = openPort();
if (fd >= 0)
{
while(1)
{
selectLoop(fd);
}
}
return 0;
}
I get the same result using select(). However if I attach a signal to "data received" then the signal fires, though this is a scenario I am trying to avoid as it plays havoc with Netbeans' debug environment.
FYI: board revision is B6, UART1 is connected by TX/RX only. The "screen" program successfully receives and sends characters from the UART, so I know that it fundamentally works.
Replace this with something sensible:
printf( buffer );
Perhaps:
for (int i = 0; i < r; ++i)
putchar(buffer[i]);
fflush(stdout);
This flushes and doesn't risk printing more characters than read if the buffer is full.

C++ code to send messages with GSM

I just connected my raspberry Pi with a SM5100b GSM. I would like to test it sending a simple message in my mobile. I can do it with emulators like cutecom and minicom (because I have raspbian linux version). But Is there any code in C++ which does this job? I do not use Arduino, only a SM5100B. I wrote this code until now and of course it does not work yet
#include <stdio.h> // standard input / output functions
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitionss
#include <time.h> // time calls
int open_port(void)
{
int fd; // file description for the serial port
fd = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY);
if(fd == -1) // if open is unsucessful
{
//perror("open_port: Unable to open /dev/ttyAMA0 - ");
printf("open_port: Unable to open /dev/ttyAMA0. \n");
}
else
{
fcntl(fd, F_SETFL, 0);
printf("port is open.\n");
}
return(fd);
} //open_port
int configure_port(int fd) // configure the port
{
struct termios port_settings; // structure to store the port settings in
cfsetispeed(&port_settings, B9600); // set baud rates
cfsetospeed(&port_settings, B9600);
port_settings.c_cflag &= ~PARENB; // set no parity, stop bits, data bits
port_settings.c_cflag &= ~CSTOPB;
port_settings.c_cflag &= ~CSIZE;
port_settings.c_cflag |= CS8;
tcsetattr(fd, TCSANOW, &port_settings); // apply the settings to the port
return(fd);
} //configure_port
int query_modem(int fd) // query modem with an AT command
{
char n;
fd_set rdfs;
struct timeval timeout;
// initialise the timeout structure
timeout.tv_sec = 10; // ten second timeout
timeout.tv_usec = 0;
unsigned char send_bytes[] = "AT+CMGF=1";
unsigned char send_bytes1[] = "AT+CMGS=\"603*****\"";
unsigned char send_bytes3[] = "TEST";
// puts(send_bytes);
write(fd, send_bytes, 13); //Send data
write(fd, send_bytes1, 13);
write(fd, send_bytes3, 13);
//printf("Wrote the bytes. \n");
// do the select
n = select(fd + 1, &rdfs, NULL, NULL, &timeout);
// check if an error has occured
if(n < 0)
{
perror("select failed\n");
}
else if (n == 0)
{
puts("Timeout!");
}
else
{
printf("\nBytes detected on the port!\n");
}
return 0;
} //query_modem
int main(void)
{
int fd = open_port();
configure_port(fd);
query_modem(fd);
return(0);
} //main
Open the relevant serial port (/dev/ttySx, where x is most likely a number), use write or fwrite to write to the port, close the port, exit program.