changeset 207:a6ebf331b2a7

8130397: DCE/DTE signal controls are not implemented Summary: setter/getters are implemented. Listener is stubbed due to ioctl blocking nature. Reviewed-by: alkonsta
author snazarki
date Mon, 06 Jul 2015 17:39:20 +0300
parents 6fe0b4719c4d
children 8a4f5b92a3bf
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, 136 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/linux/native/com/oracle/dio/uart/serial.c	Fri Jul 03 19:54:13 2015 +0300
+++ b/src/share/linux/native/com/oracle/dio/uart/serial.c	Mon Jul 06 17:39:20 2015 +0300
@@ -23,6 +23,7 @@
  * questions.
  */
 
+#include "linux/serial.h"
 #include "serial.h"
 #include "list_helper.h"
 #include "privilege_manager.h"
@@ -533,7 +534,23 @@
 javacall_result /*OPTIONAL*/ javacall_serial_get_signal_line_mode(javacall_handle handle,
                                                                   javacall_serial_signal_type signal,
                                                                   javacall_serial_signal_line_mode *mode) {
-    return JAVACALL_NOT_IMPLEMENTED;
+    switch (signal) {
+    case DTR_SIGNAL:
+    case RTS_SIGNAL:
+        *mode = OUTPUT_MODE;
+        break;
+    case DCD_SIGNAL:
+    case DSR_SIGNAL:
+    case RI_SIGNAL:
+    case CTS_SIGNAL:
+        *mode = INPUT_MODE;
+        break;
+    default:
+        JAVACALL_REPORT_WARN1(JC_SERIAL, "[UART] Invalid signal type %d", signal);
+        return JAVACALL_INVALID_ARGUMENT;
+    }
+
+    return JAVACALL_OK;
 }
 
 
@@ -542,7 +559,27 @@
  */
 javacall_result /*OPTIONAL: PART OF DEVICE ACCESS API*/
 javacall_serial_set_dte_signal(javacall_handle handle, javacall_serial_signal_type signal, javacall_bool value) {
-    return JAVACALL_NOT_IMPLEMENTED;
+    int fd = ((serial_handle)handle)->fd;
+    int line;
+    int cmd = (value) ? TIOCMBIS : TIOCMBIC;
+    switch (signal) {
+    case DTR_SIGNAL:
+        line = TIOCM_DTR;
+        break;
+    case RTS_SIGNAL:
+        line = TIOCM_RTS;
+        break;
+    default:
+        JAVACALL_REPORT_WARN1(JC_SERIAL, "[UART] Invalid DTE signal type %d", signal);
+        return JAVACALL_INVALID_ARGUMENT;
+    }
+
+    if (0 != ioctl(fd, cmd, &line)) {
+        JAVACALL_REPORT_ERROR1(JC_SERIAL, "[UART] can't set DTE signal %s", strerror(errno));
+        return JAVACALL_FAIL;
+    }
+
+    return JAVACALL_OK;
 }
 
 /**
@@ -550,15 +587,105 @@
  */
 javacall_result /*OPTIONAL: PART OF DEVICE ACCESS API*/
 javacall_serial_get_dce_signal(javacall_handle handle, javacall_serial_signal_type signal, javacall_bool* value) {
-    return JAVACALL_NOT_IMPLEMENTED;
+    int fd = ((serial_handle)handle)->fd;
+    int bit_value;
+    *value = JAVACALL_FALSE;
+
+    if (0 != ioctl(fd, TIOCMGET, &bit_value)) {
+        JAVACALL_REPORT_ERROR1(JC_SERIAL, "[UART] can't get DCE signal %s", strerror(errno));
+        return JAVACALL_FAIL;
+    }
+
+    switch (signal) {
+    case DCD_SIGNAL:
+        *value = bit_value & TIOCM_CAR;
+        break;
+    case DSR_SIGNAL:
+        *value = bit_value & TIOCM_DSR;
+        break;
+    case RI_SIGNAL:
+        *value = bit_value & TIOCM_RNG;
+        break;
+    case CTS_SIGNAL:
+        *value = bit_value & TIOCM_CTS;
+        break;
+    default:
+        JAVACALL_REPORT_WARN1(JC_SERIAL, "[UART] Invalid DCE signal type %d", signal);
+        return JAVACALL_INVALID_ARGUMENT;
+    }
+
+    return JAVACALL_OK;
 }
 
+/*
+struct signals_watcher_data {
+    serial_handle uart;
+    javacall_handle listener;
+};
+
+
+void* signals_watcher(void* args) {
+    struct signals_watcher_data* data = (struct signals_watcher_data*)args;
+    int fd = data->uart->fd;
+    struct serial_icounter_struct counter;
+    const int signals = TIOCM_RNG | TIOCM_DSR | TIOCM_CD | TIOCM_CTS;
+    while (1) {
+        if (0 != ioctl(fd, TIOCMIWAIT, signals)) {
+            JAVACALL_REPORT_ERROR1(JC_SERIAL, "[UART] can't wait DCE signal: %s", strerror(errno));
+            break;
+        }
+        if (0 != ioctl(fd, TIOCGICOUNT, &counter)) {
+            JAVACALL_REPORT_ERROR1(JC_SERIAL, "[UART] can't wait DCE signal event counter: %s", strerror(errno));
+            break;
+        }
+        if(counter.cts) {
+            javacall_bool value;
+            javacall_serial_get_dce_signal(data->uart, CTS_SIGNAL, &value);
+            javanotify_serial_signal(data->uart, data->listener, CTS_SIGNAL, value);
+        }
+        if(counter.dsr) {
+            javacall_bool value;
+            javacall_serial_get_dce_signal(data->uart, DSR_SIGNAL, &value);
+            javanotify_serial_signal(data->uart, data->listener, DSR_SIGNAL, value);
+        }
+        if(counter.rng) {
+            javacall_bool value;
+            javacall_serial_get_dce_signal(data->uart, RI_SIGNAL, &value);
+            javanotify_serial_signal(data->uart, data->listener, RI_SIGNAL, value);
+        }
+        if(counter.dcd) {
+            javacall_bool value;
+            javacall_serial_get_dce_signal(data->uart, DCD_SIGNAL, &value);
+            javanotify_serial_signal(data->uart, data->listener, DCD_SIGNAL, value);
+        }
+    }
+    JAVACALL_REPORT_INFO(JC_SERIAL, "[UART] DCE signal listener is released");
+    return 0;
+}
+*/
 /**
  * See javacall_serial.h for definition
  */
 javacall_result /*OPTIONAL: PART OF DEVICE ACCESS API*/
 javacall_serial_start_dce_signal_listening(javacall_handle handle, javacall_handle owner, javacall_handle* context) {
     return JAVACALL_NOT_IMPLEMENTED;
+
+/*  The code is commented until we find a way how to interrupt ioctl(.., TIOCMIWAIT, ..)
+    serial_handle uart = (serial_handle)handle;
+    pthread_t thread_id;
+    struct signals_watcher_data *data = (struct signals_watcher_data*) javacall_malloc (sizeof(struct signals_watcher_data));
+    data->uart = uart;
+    data->listener = owner;
+    if (pthread_create(&thread_id, NULL, signals_watcher, data) == 0) {
+        pthread_detach(thread_id);
+        *context = (javacall_handle)thread_id;
+    } else {
+        JAVACALL_REPORT_ERROR1(JC_SERIAL,
+                "[UART] failed to create thread: errno=%d", strerror(errno));
+        return JAVACALL_FAIL;
+    }
+    return JAVACALL_OK;
+*/
 }
 
 /**
@@ -567,6 +694,10 @@
 javacall_result /*OPTIONAL: PART OF DEVICE ACCESS API*/
 javacall_serial_stop_dce_signal_listening(javacall_handle context) {
     return JAVACALL_NOT_IMPLEMENTED;
+/*
+    JAVACALL_REPORT_WARN(JC_SERIAL, "[UART] Signal is not stopped if port is alive");
+    return JAVACALL_OK;
+*/
 }
 
 void* write_thread(void* arg) {
--- a/src/share/linux/native/com/oracle/dio/uart/uart.c	Fri Jul 03 19:54:13 2015 +0300
+++ b/src/share/linux/native/com/oracle/dio/uart/uart.c	Mon Jul 06 17:39:20 2015 +0300
@@ -697,9 +697,10 @@
     if (pthread_create(&thread_id, NULL, break_thread, data) == 0) {
         pthread_detach(thread_id);
     } else {
+        javacall_free(data);
         JAVACALL_REPORT_ERROR1(JC_DIO,
                 "[UART] failed to create thread: errno=%d", errno);
-        return JAVACALL_FAIL;
+        return JAVACALL_DIO_FAIL;
     }
     return JAVACALL_DIO_WOULD_BLOCK;
 }