title: Ubuntu C++ termios.h example program
body: <p>I searched a lot and tried many different ways, but I cannot send data to gtkterm via virtual serial bridge (for testing!).</p>
  
  <p>My idea is to communicate with an Atmega uC later on, but first I wanted to test the serial communication by setting up a virtual serial bridge with the help of soccat and controlling the output serial port with gtkterm. The problem is that I'm just receiving useless things in gtkterm... (see screenshots)</p>
  
  <p>soccat command:</p>
  
  <pre><code>socat -d -d PTY: PTY:
  </code></pre>
  
  <p>The soccat virtual serial port bridge seems to be ok, because I can send data from one serial terminal to another...</p>
  
  <p>gtkterm port preferences:</p>
  
  <pre><code>Port: /dev/pts/6
  Baudrate: 9600
  Parity: none
  Bits: 8
  Stopbits: 1
  Flow control: none
  </code></pre>
  
  <p>My little GUI compiles and runs fine, with the input path "/dev/pts/6" and the input baudrate 9600. The program seems to run fine, but in gtkterm are just question marks and quadangles with symbols in every corner coming up. Let's say its not interpretable and independent by the signs as input, BUT the lengths of the output in gtkterm changes by the length of the input (the amount of signs I type in).</p>
  
  <p>Finally here's my code:</p>
  
  <p>main.cpp:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include "serial/serial_communication.cpp"
  
  std::string inputStringUser = "";
  int inputIntUser = 0;
  std::string pathSerial = "/dev/...";
  int baudrate = 19200;
  
  int main()
  {
      std::cout &lt;&lt; "main() [communication_serial_uC] started..." &lt;&lt;        std::endl;
  
      //GETTING STARTED
      std::cout &lt;&lt; "Use default port? " &lt;&lt; pathSerial &lt;&lt; " (Yes = y/ change port = insert the new path" &lt;&lt; std::endl;
      std::cin &gt;&gt; inputStringUser;
      if(inputStringUser != "y" &amp;&amp; inputStringUser != "Y")
          pathSerial = inputStringUser;
      std::cout &lt;&lt; "Serial Port is set to: " + pathSerial &lt;&lt; std::endl;
  
      std::cout &lt;&lt; "Use default baudrate? " &lt;&lt; baudrate &lt;&lt; "Yes = 0/     change baudrate = insert new baudrate" &lt;&lt; std::endl;
      std::cin &gt;&gt; inputIntUser;
  
      if(inputIntUser &gt; 0)
          baudrate = inputIntUser;
      std::cout &lt;&lt; "Baudrate is set to: " &lt;&lt; baudrate &lt;&lt; std::endl;
  
      Serial_communication myPort(pathSerial, baudrate);
  
      //OPEN/ CONFIGURATE PORT
      if(myPort.openPort(pathSerial, baudrate) &lt; 0)
      {
          std::cout &lt;&lt; "Error: opening" &lt;&lt; std::endl;
          return -1;
      }
  
      //WRITE PORT
      std::cout &lt;&lt; "Insert your 'message': (exit = 'exit')" &lt;&lt; std::endl;
      std::cin &gt;&gt; inputStringUser;
      while(inputStringUser != "exit")
      {
          if(myPort.sendPort(inputStringUser) &lt; 0)
          {
              std::cout &lt;&lt; "Error: sending" &lt;&lt; std::endl;
              return -1;
          }
          std::cout &lt;&lt; "Insert your 'message': (exit = 'exit')" &lt;&lt; std::endl;
          std::cin &gt;&gt; inputStringUser;
      }
  
      //CLOSE PORT
      if(myPort.closePort() &lt; 0)
      {
          std::cout &lt;&lt; "Error: closing" &lt;&lt; std::endl;
          return -1;
      }
  
      std::cout &lt;&lt; "main() [communication_serial_uC] beendet..." &lt;&lt; std::endl;
      return 0;
  }
  </code></pre>
  
  <p>serial/serial_communication.hpp:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;cstring&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;termios.h&gt;
  
  class Serial_communication{
  
      public:
          Serial_communication(std::string paramPathSerial, int paramBaudrate);
          ~Serial_communication();
  
          int openPort(std::string pathSerial, int baudrate);
          int sendPort(std::string testString);
          int closePort();
  
      private:
          std::string pathSerial;
          int baudrate;
  
          //filedescriptors
          int fd;
  };
  </code></pre>
  
  <p>serial/serial_communcation.cpp</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  #include "serial_communication.h"
  
  Serial_communication::Serial_communication(std::string paramPathSerial, int paramBaudrate)
  {
      fd = 0;
      pathSerial = paramPathSerial;
      baudrate = paramBaudrate;
  }
  
  Serial_communication::~Serial_communication()
  {
  }
  
  int Serial_communication::openPort(std::string pathSerial, int baudrate)
  {
      std::cout &lt;&lt; "openPort() [serial_communication] started with the following paramters... pathSerial = " &lt;&lt; pathSerial &lt;&lt; ", baudrate = " &lt;&lt; baudrate &lt;&lt; std::endl;
  
      //OPENING PORT
  
      //open serial port
      fd = open(pathSerial.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
      if(fd &lt; 0)
      {
          std::cout &lt;&lt; "Error [serial_communcation]: opening Port: " &lt;&lt; pathSerial &lt;&lt; std::endl;
          return -1;
      }
  
      //struct termios
      struct termios serial, serial_old;
  
      //get parameters associated with the terminal
      if(tcgetattr(fd, &amp;serial) &lt; 0)
      {
          std::cout &lt;&lt; "Error [serial_communication]: getting configuration" &lt;&lt; std::endl;
          return -1;
      }
  
      //safe old parameters
      serial_old = serial;
  
      std::cout &lt;&lt; "[serial_communication]: Port opened" &lt;&lt; std::endl;
      //SERIAL CONFIGURATION
      /* Set Baud Rate */
      cfsetospeed (&amp;serial, (speed_t)baudrate);
      cfsetispeed (&amp;serial, (speed_t)baudrate);
  
  //     Setting other Port Stuff
      serial.c_cflag     &amp;=  ~PARENB;            // Make 8n1
      serial.c_cflag     &amp;=  ~CSTOPB;
      serial.c_cflag     &amp;=  ~CSIZE;
      serial.c_cflag     |=  CS8;
  
      serial.c_cflag     &amp;=  ~CRTSCTS;           // no flow control
      serial.c_cc[VMIN]   =  1;                  // read doesn't block
      serial.c_cc[VTIME]  =  5;                  // 0.5 seconds read timeout
      serial.c_cflag     |=  CREAD | CLOCAL;     // turn on READ &amp; ignore ctrl lines
  
  
  
      /* Make raw */
      cfmakeraw(&amp;serial);
  
      /* Flush Port, then applies attributes */
      tcflush( fd, TCIFLUSH );
  
      //set attributes to port
      if(tcsetattr(fd, TCSANOW, &amp;serial) &lt; 0)
      {
          std::cout &lt;&lt; "Error [serial_communication]: set attributes" &lt;&lt; std::endl;
          return -1;
      }
  
      //CONFIGURATION FINISHED
      std::cout &lt;&lt; "openPort() [serial_communication] finished..." &lt;&lt; std::endl;
      return 1;
  }
  
  int Serial_communication::sendPort(std::string textString)
  {
      std::cout &lt;&lt; "write() [Serial_communication] started with the following parameter... textString = " &lt;&lt; textString &lt;&lt; std::endl;
      //attempt to send
      if(write(fd, &amp;textString, std::strlen(textString.c_str())) &lt; 0)
      {
          std::cout &lt;&lt; "Error [serial_communcation]: write";
          return -1;
      }
  
      //SENDING FINISHED
      std::cout &lt;&lt; "write() [serial_communcation] finished..." &lt;&lt; std::endl;
      return 1;
  }
  
  int Serial_communication::closePort()
  {
      close(fd);
      return 1;
  }
  </code></pre>
  
  <p>So... thats all I got. I tried my best and joined the information from many websites and tried a lots of example codes. My problem is that I dont even know where to search for, so I'm appreciate for any clue...
  If there are any questions or information missing, pls let me know it!</p>
  
  <p>Thanks in advance
  Thorben</p>
  
  <p>BTW: I'm not THAT experienced with C++ and I'm opened up for comments about my style, but that should not be the main problem...</p>