From 509b087163f05cf6b25fe2f0e3df7ca08dcf2bc3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sergi=20Hern=C3=A0ndez=20Juan?= <shernand@iri.upc.edu>
Date: Wed, 27 Jan 2016 22:27:21 +0000
Subject: [PATCH] Chnages to allow non-standard baudrates.

---
 src/serial/rs232.cpp | 145 ++++++++++++++++---------------------------
 src/serial/rs232.h   |   2 +-
 2 files changed, 56 insertions(+), 91 deletions(-)

diff --git a/src/serial/rs232.cpp b/src/serial/rs232.cpp
index d085f02..9bf6cb9 100644
--- a/src/serial/rs232.cpp
+++ b/src/serial/rs232.cpp
@@ -14,82 +14,38 @@ CRS232::CRS232(const std::string& comm_id) : CComm(comm_id)
 
 void CRS232::set_baudrate(int baud)
 {
-  struct termios config;
-  int baudrate;
+  struct termios2 config;
+  int error;
 
-  if(tcgetattr(this->serial_fd,&config)==-1)
-  {
+  if((error=ioctl(this->serial_fd,TCGETS2,&config))<0)
+  { 
     /* handle exceptions */
-    throw CRS232Exception(_HERE_,"Impossible to get the attribute structure.\n",this->comm_id);
+    throw CRS232Exception(_HERE_,"Impossible to execute the IOCTL to get the configuration structure.\n",this->comm_id);
   }
   else
   {
-    switch(baud)
-    {
-      case 50: baudrate=B50;
-               break; 
-      case 75: baudrate=B75;
-               break;
-      case 110: baudrate=B110;
-                break;
-      case 134: baudrate=B134;
-                break;
-      case 150: baudrate=B150;
-                break;
-      case 200: baudrate=B200;
-                break;
-      case 300: baudrate=B300;
-                break;
-      case 600: baudrate=B600; 
-                break;
-      case 1200: baudrate=B1200;
-                 break;
-      case 1800: baudrate=B1800;
-                 break;
-      case 2400: baudrate=B2400;
-                 break;
-      case 4800: baudrate=B4800;
-                 break;
-      case 9600: baudrate=B9600;
-                 break;
-      case 19200: baudrate=B19200;
-                  break;
-      case 38400: baudrate=B38400;
-                  break;
-      case 57600: baudrate=B57600;
-                  break;
-      case 115200: baudrate=B115200;
-                   break;
-      case 230400: baudrate=B230400;
-                   break;
-      case 460800: baudrate=B460800;
-                   break;
-      case 921600: baudrate=B921600;
-                   break;
-      default: /* handle exception */
-               throw CRS232Exception(_HERE_,"Invalid baudrate. See the documentation for the possible values.\n",this->comm_id);
-               break;
-    }
-    cfsetispeed(&config,baudrate);
-    cfsetospeed(&config,baudrate);
+    config.c_cflag &= ~CBAUD;
+    config.c_cflag |= BOTHER;
+    config.c_ispeed = baud;
+    config.c_ospeed = baud;
     this->serial_config.baud=baud;
-    if(tcsetattr(this->serial_fd,TCSANOW,&config)==-1)
-    {
+    if((error=ioctl(this->serial_fd,TCSETS2,&config))<0)
+    { 
       /* handle exceptions */
-      throw CRS232Exception(_HERE_,"Impossible to set up the new attribute structure.\n",this->comm_id);
-    }
+     throw CRS232Exception(_HERE_,"Impossible to execute the IOCTL to set the configuration structure.\n",this->comm_id);
+    } 
   }
 }
 
 void CRS232::set_num_bits(char num_bits)
 {
-  struct termios config;
-  int bits;
+  struct termios2 config;
+  int error,bits;
 
-  if(tcgetattr(this->serial_fd,&config)==-1)
-  {
+  if((error=ioctl(this->serial_fd,TCGETS2,&config))<0)
+  { 
     /* handle exceptions */
-    throw CRS232Exception(_HERE_,"Impossible to get the attribute structure.\n",this->comm_id);
+    throw CRS232Exception(_HERE_,"Impossible to execute the IOCTL to get the configuration structure.\n",this->comm_id);
   }
   else
   {
@@ -110,22 +66,23 @@ void CRS232::set_num_bits(char num_bits)
     config.c_cflag&=~CSIZE;
     config.c_cflag|=bits;
     this->serial_config.num_bits=num_bits;
-    if(tcsetattr(this->serial_fd,TCSANOW,&config)==-1)
-    {
+    if((error=ioctl(this->serial_fd,TCSETS2,&config))<0)
+    { 
       /* handle exceptions */
-      throw CRS232Exception(_HERE_,"Impossible to set up the new attribute structure.\n",this->comm_id);
+      throw CRS232Exception(_HERE_,"Impossible to execute the IOCTL to set the configuration structure.\n",this->comm_id);
     }
   }
 }
 
 void CRS232::set_parity(parity_type parity)
 {
-  struct termios config;
+  struct termios2 config;
+  int error;
 
-  if(tcgetattr(this->serial_fd,&config)==-1)
-  {
-    /* handle exception */
-    throw CRS232Exception(_HERE_,"Impossible to get the attribute structure.\n",this->comm_id);
+  if((error=ioctl(this->serial_fd,TCGETS2,&config))<0)
+  { 
+    /* handle exceptions */
+    throw CRS232Exception(_HERE_,"Impossible to execute the IOCTL to get the configuration structure.\n",this->comm_id);
   }
   else
   {
@@ -142,23 +99,24 @@ void CRS232::set_parity(parity_type parity)
     }
     else config.c_cflag&=~PARENB;
     this->serial_config.parity=parity;
-    if(tcsetattr(this->serial_fd,TCSANOW,&config)==-1)
-    {
+    if((error=ioctl(this->serial_fd,TCSETS2,&config))<0)
+    { 
       /* handle exceptions */
-      throw CRS232Exception(_HERE_,"Impossible to set up the new attribute structure.\n",this->comm_id);
+      throw CRS232Exception(_HERE_,"Impossible to execute the IOCTL to set the configuration structure.\n",this->comm_id);
     }
   }
 }
 
 void CRS232::set_stop_bits(char stop_bits)
 {
-  struct termios config;
+  struct termios2 config;
+  int error;
 
-  if(tcgetattr(this->serial_fd,&config)==-1)
-  {
+  if((error=ioctl(this->serial_fd,TCGETS2,&config))<0)
+  { 
     /* handle exceptions */
-    throw CRS232Exception(_HERE_,"Impossible to get the attribute structure.\n",this->comm_id);
-  } 
+    throw CRS232Exception(_HERE_,"Impossible to execute the IOCTL to get the configuration structure.\n",this->comm_id);
+  }
   else
   {
     if(stop_bits==2) config.c_cflag|=CSTOPB;
@@ -169,10 +127,10 @@ void CRS232::set_stop_bits(char stop_bits)
       throw CRS232Exception(_HERE_,"Invalid number of stop bits. See the documentation for the possible values.\n",this->comm_id);
     }
     this->serial_config.stop_bits=stop_bits;
-    if(tcsetattr(this->serial_fd,TCSANOW,&config)==-1)
-    {
-      /* handle exception */
-      throw CRS232Exception(_HERE_,"Impossible to set up the new attribute structure.\n",this->comm_id);
+    if((error=ioctl(this->serial_fd,TCSETS2,&config))<0)
+    { 
+      /* handle exceptions */
+      throw CRS232Exception(_HERE_,"Impossible to execute the IOCTL to set the configuration structure.\n",this->comm_id);
     }
   }
 }
@@ -180,7 +138,8 @@ void CRS232::set_stop_bits(char stop_bits)
 void CRS232::hard_open(void *comm_dev)
 {
   std::string *serial_dev=(std::string *)comm_dev;
-  struct termios config;
+  struct termios2 config;
+  int error;
 
   if(serial_dev->size()==0)
   {
@@ -197,10 +156,10 @@ void CRS232::hard_open(void *comm_dev)
     }
     else
     {
-      if(tcgetattr(this->serial_fd,&config)==-1)
-      {
+      if((error=ioctl(this->serial_fd,TCGETS2,&config))<0)
+      { 
         /* handle exceptions */
-        throw CRS232Exception(_HERE_,"Impossible to get the attribute structure.\n",this->comm_id);
+        throw CRS232Exception(_HERE_,"Impossible to execute the IOCTL to get the configuration structure.\n",this->comm_id);
       }
       else
       {
@@ -213,10 +172,10 @@ void CRS232::hard_open(void *comm_dev)
         config.c_cc[VMIN]=0;
         config.c_cc[VTIME]=100;
         this->serial_device=*serial_dev;
-        if(tcsetattr(this->serial_fd,TCSANOW,&config)==-1)
-        {
+        if((error=ioctl(this->serial_fd,TCSETS2,&config))<0)
+        { 
           /* handle exceptions */
-          throw CRS232Exception(_HERE_,"Impossible to set up the new attribute structure.\n",this->comm_id);
+          throw CRS232Exception(_HERE_,"Impossible to execute the IOCTL to set the configuration structure.\n",this->comm_id);
         }
       }
     }
@@ -249,7 +208,13 @@ int CRS232::hard_write(unsigned char *data, int len)
 {
   int num_written=0;
 
-  tcdrain(this->serial_fd);
+  if(ioctl(this->serial_fd,TCSBRK,1)!=0) 
+  {
+//    static int tcsb_warned=0;
+//    if (!tcsb_warned) fprintf(stderr, "TCSBRK doesn't work!\n");
+//    tcsb_warned=1;
+  }
+  //tcdrain(this->serial_fd);
   if((num_written=::write(this->serial_fd,data,len))==-1)
   {
     return -1;
diff --git a/src/serial/rs232.h b/src/serial/rs232.h
index 8a14e65..f8921ba 100644
--- a/src/serial/rs232.h
+++ b/src/serial/rs232.h
@@ -6,7 +6,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>
-#include <termios.h>
+#include <asm/termbits.h>
 #include <unistd.h>  
 #include <fcntl.h>
 #include <errno.h>
-- 
GitLab