changeset 269:19eec3548675

DIO-17:UART.generateBreak() is not implemented correctly Summary: This change resolves an issue with invalid DIO implementation of UART.generateBreak(...) method. The result of the call to ioctl(..., TCSBRKP, positive) is undefined. Instead, an approach with the sequency is taken: ioctl(..., TIOCSBRK, 0); followed by usleep() followed by ioctl(..., TIOCCBRK, 0); Reviewed-by:snazarki Contributed-by:bkvartsk
author onazarkina
date Wed, 09 Mar 2016 16:17:38 +0300
parents ad12ae44e850
children 68069d97828b
files src/share/linux/native/com/oracle/dio/uart/serial.c src/share/linux/native/com/oracle/dio/uart/uart.c
diffstat 2 files changed, 27 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/linux/native/com/oracle/dio/uart/serial.c	Mon Feb 29 19:06:11 2016 +0300
+++ b/src/share/linux/native/com/oracle/dio/uart/serial.c	Wed Mar 09 16:17:38 2016 +0300
@@ -94,7 +94,7 @@
 
     // allocate input buffer
     if(JAVACALL_OK != javautil_circular_buffer_create(&(p->inBuffer), p->buffer_max_size, sizeof(char))){
-        JAVACALL_REPORT_ERROR(JC_DIO, "[UART] income buffer initialization error");
+        JAVACALL_REPORT_ERROR(JC_DIO, "[UART] input buffer initialization error");
         return JAVACALL_FAIL;
     }
 
@@ -212,6 +212,10 @@
         JAVACALL_REPORT_ERROR(JC_SERIAL, "[UART] cfsetispeed failed");
         return JAVACALL_FAIL;
     }
+
+    term.c_iflag |= IGNBRK;
+    term.c_iflag &= ~BRKINT;
+
     if (tcsetattr(fd, TCSANOW, &term)) {
         JAVACALL_REPORT_ERROR(JC_SERIAL, "[UART] tcsetattr failed");
         return JAVACALL_FAIL;
@@ -761,7 +765,7 @@
                         error = JAVACALL_TRUE;
                     }else if(pfds[1].revents & (POLLERR | POLLHUP | POLLNVAL)){
                         error = JAVACALL_TRUE;
-                        JAVACALL_REPORT_ERROR1(JC_SERIAL, "[UART] vent_fd error: errno=%d", errno);
+                        JAVACALL_REPORT_ERROR1(JC_SERIAL, "[UART] event_fd error: errno=%d", errno);
                     }
                 }else{//if(res != -1)
                     error = JAVACALL_TRUE;
--- a/src/share/linux/native/com/oracle/dio/uart/uart.c	Mon Feb 29 19:06:11 2016 +0300
+++ b/src/share/linux/native/com/oracle/dio/uart/uart.c	Wed Mar 09 16:17:38 2016 +0300
@@ -24,6 +24,7 @@
  */
 
 #include "serial.h"
+#include "unistd.h"
 #include "javacall_uart.h"
 
 typedef enum {
@@ -123,7 +124,7 @@
     javacall_dio_result res;
 
     ((uart_handle)handle)->notifiedEvents &= ~(SERIAL_IN_AVAILABLE | SERIAL_IN_OVERRUN);
-
+    
     pthread_mutex_lock( &((serial_handle)handle)->lock );
 
     if (JAVACALL_FAIL == jc_serial_read_common((serial_handle)handle, buffer, size, bytesRead, &bytesAvailable)){
@@ -135,6 +136,7 @@
         }
         res = JAVACALL_DIO_OK;
     }
+
     pthread_mutex_unlock( &((serial_handle)handle)->lock );
 
     return res;
@@ -675,13 +677,28 @@
 static void* break_thread(void* args) {
     javacall_dio_result result = JAVACALL_DIO_OK;
     struct tuple *data = (struct tuple *)args;
-    if (-1 == tcsendbreak(data->uart->serial_descr.fd, data->duration)) {
-        JAVACALL_REPORT_ERROR1(JC_DIO, "tcsendbreak error:%s", strerror(errno));
-        result = JAVACALL_FAIL;
+    SERIAL_DESC* p = &data->uart->serial_descr;
+    
+    // 1000 seconds limit. Note that data->duration is millis
+    useconds_t uSeconds = (useconds_t)(data->duration > 1000000 ? 1000000000: data->duration * 1000);
+
+    pthread_mutex_lock(&p->write_lock);
+    if (0 != ioctl(p->fd, TIOCSBRK, 0)) {
+        JAVACALL_REPORT_ERROR1(JC_DIO, "ioctl(..., TIOCSBRK,...) error: %s", strerror(errno));
+        result = JAVACALL_DIO_FAIL;
     }
+    
+    usleep(uSeconds); 
+    
+    if (0 != ioctl(data->uart->serial_descr.fd, TIOCCBRK, 0)) {
+        result = JAVACALL_DIO_FAIL;
+    }   
+    pthread_mutex_unlock(&p->write_lock);
+    
     // most safe event at this time
     javanotify_serial_event(JAVACALL_EVENT_SERIAL_CLOSE, data->uart, result);
     javacall_free(data);
+
     return (void*)result;
 }