title: Making a blocking read() from UART on Linux
body: <p>I am trying to write to the serial port (sending a handshake) and then subsequently I try to read the serial port. When reading the port, I notice I am getting garbage reads (even if there is nothing connected to the RX line) or part of the write string I am sending to the TX line. Why am I getting part of that string? I am not supposed to be seeing that!</p>
  
  <p>Here is my code:</p>
  
  <pre><code>   class UART{
  
      public:
          UART();
          ~UART();
          int open_port();
          int configure_port(); // All port configurations such as parity, baud rate, hardware flow, etc
          int uart_write(std::string);     // Send characters to the serial port
          int uart_read(std::string*, int);            // Read from serial port
          // Close
          void close_port();
  
      private:
          int fd;
  </code></pre>
  
  <p>uart.cpp:</p>
  
  <pre><code>UART::UART(){
      open_port();
      configure_port();
  }
  
  UART::~UART(){
      close_port();
  }
  
  int UART::open_port()
  {
      // Open ttys4
      fd = open("/dev/ttyS4", O_RDWR | O_NOCTTY | O_NDELAY);
  
      if(fd == -1) // if open is unsucessful
      {
          //perror("open_port: Unable to open /dev/ttyS0 - ");
          printf("open_port: Unable to open /dev/ttyS4. \n");
      }
      else
      {
          fcntl(fd, F_SETFL, 0);
          printf("port is open.\n");
      }
  
      return(fd);
  } //open_port
  
  // configure the port
  int UART::configure_port()      
  {
      struct termios port_settings;      // structure to store the port settings in
  
      cfsetispeed(&amp;port_settings, B9600);    // set baud rates
      cfsetospeed(&amp;port_settings, B9600);
  
      port_settings.c_cflag &amp;= ~PARENB;    // set no parity, stop bits, data bits
      port_settings.c_cflag &amp;= ~CSTOPB;
      port_settings.c_cflag &amp;= ~CSIZE;
      port_settings.c_cflag |= CS8;
      port_settings.c_cflag |=  CREAD | CLOCAL;     // turn on READ &amp; ignore ctrl lines
  
      port_settings.c_cc[VTIME]     =   10;                  // n seconds read timeout
      port_settings.c_iflag     &amp;=  ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
      port_settings.c_lflag     &amp;=  ~(ICANON | ECHO | ECHOE | ISIG); // make raw
      port_settings.c_oflag     &amp;=  ~OPOST;              // make raw
  
      tcsetattr(fd, TCSANOW, &amp;port_settings);    // apply the settings to the port
      return(fd);
  } 
  
   // Write to serial port
  int UART::uart_write(string data)  
  {
      int buffer_size = data.length();
      char * data_write = new char[data.length()+1];
      strcpy (data_write, data.c_str());
  
      int n = write(fd, data_write, buffer_size);  //Send data
  
      usleep(1000);
      tcdrain(fd);
  
      printf("Wrote the bytes. \n");
  
      /* Error Handling */
      int status = 0;
      if (n &lt; 0)
      {
           cout &lt;&lt; "Error Writing: " &lt;&lt; strerror(errno) &lt;&lt; endl;
           status = 0;
      }else{
          status = 1;
      }
  
      delete[] data_write;
  
      return status;
  }
  
  int UART::uart_read(string *data,int buffer_size)
  {
      // Buffer
      char * buf = new char[buffer_size+1];
  
      usleep(1000);
      tcflush(fd, TCIOFLUSH);
  
      // Read
      /*I NEED THIS PART TO BE BLOCKING*/
      int n = read( fd, buf , buffer_size );
  
      /* Error Handling */
      if (n &lt; 0)
      {
           cout &lt;&lt; "Error reading: " &lt;&lt; strerror(errno) &lt;&lt; endl;
      }
  
      // String received
      string data_received(buf,buffer_size);
      *data = data_received;
  
      delete[] buf;
  
      cout &lt;&lt; "data_received: " &lt;&lt; *data &lt;&lt; endl;
  
      // Did we get blank data?
      if( data_received.length() == 0 )
          return 0;
      else
          return 1;
  }
  </code></pre>
  
  <p>main</p>
  
  <pre><code>int main()
  { 
      UART uart_connection;
  
      string handshake = "handshake!";
      uart_connection.uart_write(handshake);
  
      string data;
      string *data_ptr = &amp;data;
      uart_connection.uart_read(data_ptr );
  
      cout &lt;&lt; data &lt;&lt; endl;
  
  }
  </code></pre>
  
  <p>When printing the received data, I usually get part of the sent data. So on cout &lt;&lt; data &lt;&lt; endl I am getting the following:</p>
  
  <pre><code>dshake
  </code></pre>
  
  <p>along with some weird characters after it, or if I don't write anything to the serial port then I just get random characters. </p>
  
  <p>Specifically I want <strong>int n = read( fd, buf , buffer_size );</strong> to be a blocking function, which apparently it's not happening... It just goes through and it returns a bunch of weird characters or it reads part of the string sent with write. </p>
  
  <p>Please note that the code works and when I do actually send something to the RX line, I can read it just fine. However, I am finding it difficult to send large chunks of data without getting bad reads. </p>
  
  <p>I believe this could all be solved if I could make the read() function a blocking function, and avoid it reading those weird characters.  </p>