aboutsummaryrefslogtreecommitdiff
path: root/sync/src/main/scala/akka/serial/sync/UnsafeSerial.scala
diff options
context:
space:
mode:
Diffstat (limited to 'sync/src/main/scala/akka/serial/sync/UnsafeSerial.scala')
-rw-r--r--sync/src/main/scala/akka/serial/sync/UnsafeSerial.scala109
1 files changed, 109 insertions, 0 deletions
diff --git a/sync/src/main/scala/akka/serial/sync/UnsafeSerial.scala b/sync/src/main/scala/akka/serial/sync/UnsafeSerial.scala
new file mode 100644
index 0000000..dcca960
--- /dev/null
+++ b/sync/src/main/scala/akka/serial/sync/UnsafeSerial.scala
@@ -0,0 +1,109 @@
+package akka.serial
+package sync
+
+import java.nio.ByteBuffer
+
+import ch.jodersky.jni.nativeLoader
+
+/**
+ * Low-level wrapper of native serial backend.
+ *
+ * WARNING: Methods in this class allocate native structures and deal with pointers. These
+ * pointers are handled as longs by java and are NOT checked for correctness, therefore passing
+ * invalid pointers may have unexpected results, including but not limited to SEGFAULTing the VM.
+ *
+ * See SerialConnection for a higher-level, more secured wrapper
+ * of serial communication.
+ *
+ * @param serialAddr address of natively allocated serial configuration structure
+ */
+@nativeLoader("akkaserial1")
+private[serial] class UnsafeSerial(final val serialAddr: Long) {
+
+ final val ParityNone: Int = 0
+ final val ParityOdd: Int = 1
+ final val ParityEven: Int = 2
+
+ /**
+ * Reads from a previously opened serial port into a direct ByteBuffer. Note that data is only
+ * read into the buffer's allocated memory, its position or limit are not changed.
+ *
+ * The read is blocking, however it may be interrupted by calling cancelRead() on the given
+ * serial port.
+ *
+ * @param buffer direct ByteBuffer to read into
+ * @return number of bytes actually read
+ * @throws IllegalArgumentException if the ByteBuffer is not direct
+ * @throws PortInterruptedException if the call to this function was interrupted
+ * @throws IOException on IO error
+ */
+ @native def read(buffer: ByteBuffer): Int
+
+ /**
+ * Cancels a read (any caller to read or readDirect will return with a
+ * PortInterruptedException). This function may be called from any thread.
+ *
+ * @param serial address of natively allocated serial configuration structure
+ * @throws IOException on IO error
+ */
+ @native def cancelRead(): Unit
+
+ /**
+ * Writes data from a direct ByteBuffer to a previously opened serial port. Note that data is
+ * only taken from the buffer's allocated memory, its position or limit are not changed.
+ *
+ * The write is non-blocking, this function returns as soon as the data is copied into the kernel's
+ * transmission buffer.
+ *
+ * @param serial address of natively allocated serial configuration structure
+ * @param buffer direct ByteBuffer from which data is taken
+ * @param length actual amount of data that should be taken from the buffer (this is needed since the native
+ * backend does not provide a way to query the buffer's current limit)
+ * @return number of bytes actually written
+ * @throws IllegalArgumentException if the ByteBuffer is not direct
+ * @throws IOException on IO error
+ */
+ @native def write(buffer: ByteBuffer, length: Int): Int
+
+ /**
+ * Closes an previously open serial port. Natively allocated resources are freed and the serial
+ * pointer becomes invalid, therefore this function should only be called ONCE per open serial
+ * port.
+ *
+ * A port should not be closed while it is used (by a read or write) as this
+ * results in undefined behaviour.
+ *
+ * @param serial address of natively allocated serial configuration structure
+ * @throws IOException on IO error
+ */
+ @native def close(): Unit
+
+}
+
+private[serial] object UnsafeSerial {
+
+ /**
+ * Opens a serial port.
+ *
+ * @param port name of serial port to open
+ * @param characterSize size of a character of the data sent through the serial port
+ * @param twoStopBits set to use two stop bits instead of one
+ * @param parity type of parity to use with serial port
+ * @return address of natively allocated serial configuration structure
+ * @throws NoSuchPortException if the given port does not exist
+ * @throws AccessDeniedException if permissions of the current user are not sufficient to open port
+ * @throws PortInUseException if port is already in use
+ * @throws InvalidSettingsException if any of the specified settings are invalid
+ * @throws IOException on IO error
+ */
+ @native def open(port: String, baud: Int, characterSize: Int, twoStopBits: Boolean, parity: Int): Long
+
+ /**
+ * Sets native debugging mode. If debugging is enabled, detailed error messages
+ * are printed (to stderr) from native method calls.
+ *
+ * @param value set to enable debugging
+ */
+ @native def debug(value: Boolean): Unit
+
+}