diff options
author | Jakob Odersky <jodersky@gmail.com> | 2013-05-21 19:50:15 +0200 |
---|---|---|
committer | Jakob Odersky <jodersky@gmail.com> | 2013-05-21 19:50:15 +0200 |
commit | 3a2edc19f4e9475b09594dcb6642ae230d75ae7f (patch) | |
tree | 7bf63bda42ffe1fa9b29d681d7f8fccb2133521e /src/main | |
parent | 15b42451d124564b9ccf4a6365d2f50f7f3896c9 (diff) | |
download | akka-serial-3a2edc19f4e9475b09594dcb6642ae230d75ae7f.tar.gz akka-serial-3a2edc19f4e9475b09594dcb6642ae230d75ae7f.tar.bz2 akka-serial-3a2edc19f4e9475b09594dcb6642ae230d75ae7f.zip |
move to subproject main
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/c/com_github_jodersky_flow_NativeSerial.h | 73 | ||||
-rw-r--r-- | src/main/c/flow.c | 292 | ||||
-rw-r--r-- | src/main/java/com/github/jodersky/flow/NativeSerial.java | 49 | ||||
-rw-r--r-- | src/main/scala/com/github/jodersky/flow/Main.scala | 26 | ||||
-rw-r--r-- | src/main/scala/com/github/jodersky/flow/NativeLoader.scala | 35 | ||||
-rw-r--r-- | src/main/scala/com/github/jodersky/flow/Serial.scala | 63 | ||||
-rw-r--r-- | src/main/scala/com/github/jodersky/flow/exceptions.scala | 7 |
7 files changed, 0 insertions, 545 deletions
diff --git a/src/main/c/com_github_jodersky_flow_NativeSerial.h b/src/main/c/com_github_jodersky_flow_NativeSerial.h deleted file mode 100644 index e89652c..0000000 --- a/src/main/c/com_github_jodersky_flow_NativeSerial.h +++ /dev/null @@ -1,73 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class com_github_jodersky_flow_NativeSerial */ - -#ifndef _Included_com_github_jodersky_flow_NativeSerial -#define _Included_com_github_jodersky_flow_NativeSerial -#ifdef __cplusplus -extern "C" { -#endif -#undef com_github_jodersky_flow_NativeSerial_E_PERMISSION -#define com_github_jodersky_flow_NativeSerial_E_PERMISSION -1L -#undef com_github_jodersky_flow_NativeSerial_E_OPEN -#define com_github_jodersky_flow_NativeSerial_E_OPEN -2L -#undef com_github_jodersky_flow_NativeSerial_E_BUSY -#define com_github_jodersky_flow_NativeSerial_E_BUSY -3L -#undef com_github_jodersky_flow_NativeSerial_E_BAUD -#define com_github_jodersky_flow_NativeSerial_E_BAUD -4L -#undef com_github_jodersky_flow_NativeSerial_E_PIPE -#define com_github_jodersky_flow_NativeSerial_E_PIPE -5L -#undef com_github_jodersky_flow_NativeSerial_E_MALLOC -#define com_github_jodersky_flow_NativeSerial_E_MALLOC -6L -#undef com_github_jodersky_flow_NativeSerial_E_POINTER -#define com_github_jodersky_flow_NativeSerial_E_POINTER -7L -#undef com_github_jodersky_flow_NativeSerial_E_POLL -#define com_github_jodersky_flow_NativeSerial_E_POLL -8L -#undef com_github_jodersky_flow_NativeSerial_E_IO -#define com_github_jodersky_flow_NativeSerial_E_IO -9L -#undef com_github_jodersky_flow_NativeSerial_E_CLOSE -#define com_github_jodersky_flow_NativeSerial_E_CLOSE -10L -/* - * Class: com_github_jodersky_flow_NativeSerial - * Method: open - * Signature: (Ljava/lang/String;I[J)I - */ -JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_NativeSerial_open - (JNIEnv *, jclass, jstring, jint, jlongArray); - -/* - * Class: com_github_jodersky_flow_NativeSerial - * Method: read - * Signature: (J[B)I - */ -JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_NativeSerial_read - (JNIEnv *, jclass, jlong, jbyteArray); - -/* - * Class: com_github_jodersky_flow_NativeSerial - * Method: write - * Signature: (J[B)I - */ -JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_NativeSerial_write - (JNIEnv *, jclass, jlong, jbyteArray); - -/* - * Class: com_github_jodersky_flow_NativeSerial - * Method: close - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_com_github_jodersky_flow_NativeSerial_close - (JNIEnv *, jclass, jlong); - -/* - * Class: com_github_jodersky_flow_NativeSerial - * Method: debug - * Signature: (Z)V - */ -JNIEXPORT void JNICALL Java_com_github_jodersky_flow_NativeSerial_debug - (JNIEnv *, jclass, jboolean); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/main/c/flow.c b/src/main/c/flow.c deleted file mode 100644 index 3ed66b6..0000000 --- a/src/main/c/flow.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2013 Jakob Odersky - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of the nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <stdbool.h> -#include <unistd.h> -#include <errno.h> -#include <termios.h> -#include <fcntl.h> -#include <poll.h> -#include "com_github_jodersky_flow_NativeSerial.h" - -#define E_PERMISSION -1 -#define E_OPEN -2 -#define E_BUSY -3 -#define E_BAUD -4 -#define E_PIPE -5 -#define E_MALLOC -6 -#define E_POINTER -7 -#define E_POLL -8 -#define E_IO -9 -#define E_CLOSE -10 - - -static bool debug = false; -#define DEBUG(f) if (debug) {f;} - -//contains file descriptors used in managing a serial port -struct serial_config { - - int fd; //serial port - int pipe_read; //event - int pipe_write; //event - -}; - -/* return values: - * 0 ok - * E_PERMISSION don't have permission to open - * E_OPEN can't get file descriptor - * E_BUSY device busy - * E_BAUD invalid baudrate - * E_PIPE can't open pipe for graceful closing - * E_MALLOC malloc error - */ -int serial_open(const char* device, int baud, struct serial_config** serial) { - - int fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); - - if (fd < 0) { - DEBUG(perror(device)); - if (errno == EACCES) return E_PERMISSION; - else return E_OPEN; - } - - if (flock(fd, LOCK_EX | LOCK_NB) < 0) { - DEBUG(perror(device)); - return E_BUSY; - } - - speed_t bd; - switch (baud) { - case 50: bd = B50; break; - case 75: bd = B75; break; - case 110: bd = B110; break; - case 134: bd = B134; break; - case 150: bd = B150; break; - case 200: bd = B200; break; - case 300: bd = B300; break; - case 600: bd = B600; break; - case 1200: bd = B1200; break; - case 1800: bd = B1800; break; - case 2400: bd = B2400; break; - case 4800: bd = B4800; break; - case 9600: bd = B9600; break; - case 19200: bd = B19200; break; - case 38400: bd = B38400; break; - case 57600: bd = B57600; break; - case 115200: bd = B115200; break; - case 230400: bd = B230400; break; - default: return E_BAUD; break; - } - - /* configure new port settings */ - struct termios newtio; - newtio.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS); // 8N1 - newtio.c_cflag |= CS8 | CREAD | CLOCAL; - newtio.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl - newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw - newtio.c_oflag &= ~OPOST; // make raw - - // see: http://unixwiz.net/techtips/termios-vmin-vtime.html - //newtio.c_cc[VMIN] = 1; - //newtio.c_cc[VTIME] = 2*10/baud; - cfsetspeed(&newtio, bd); - - /* load new settings to port */ - tcflush(fd, TCIOFLUSH); - tcsetattr(fd,TCSANOW,&newtio); - - int pipe_fd[2]; - if (pipe2(pipe_fd, O_NONBLOCK) < 0) { - DEBUG(perror(device)); - return E_PIPE; - } - - struct serial_config* s = malloc(sizeof(s)); - if (s == NULL) { - return E_MALLOC; - } - - s->fd = fd; - s->pipe_read = pipe_fd[0]; - s->pipe_write = pipe_fd[1]; - (*serial) = s; - - return 0; -} - -void serial_close(struct serial_config* serial) { - - if (serial == NULL) return; - - int data = 0xffffffff; - - //write to pipe to wake up any blocked read thread (self-pipe trick) - write(serial->pipe_write, &data, 1); - - close(serial->pipe_write); - close(serial->pipe_read); - - flock(serial->fd, LOCK_UN); - close(serial->fd); - - free(serial); -} - -/* return - * >0 number of bytes read - * E_POINTER invalid serial pointer - * E_POLL poll error - * E_IO read error - * E_CLOSE close request - */ -int serial_read(struct serial_config* serial, unsigned char * buffer, size_t size) { - if (serial == NULL) { - return E_POINTER; - } - - struct pollfd sp; //serial poll - sp.fd = serial->fd; - sp.events = POLLIN; - - struct pollfd pp; //pipe poll - pp.fd = serial->pipe_read; - pp.events = POLLIN; - - struct pollfd poll_list[] = {sp, pp}; - - int n = poll(poll_list,(unsigned long)3,-1); - if (n < 0) { - DEBUG(perror("read")); - return E_IO; - } - - if (sp.revents & POLLIN != 0) { - int r = read(sp.fd, buffer, size); - - //treat 0 bytes read as an error to avoid problems on disconnect - //anyway, after a poll there should be more than 0 bytes available to read - if (r <= 0) { - if (r < 0) DEBUG(perror("read")); - return E_IO; - } - return r; - } else { - return E_CLOSE; - } -} - -/*return - * >0 number of bytes written - * E_POINTER invalid serial config (null pointer) - * E_IO write error - */ -int serial_write(struct serial_config* serial, unsigned char* data, size_t size) { - if (serial == NULL) return E_POINTER; - - int r = write(serial->fd, data, size); - if (r < 0) { - DEBUG(perror("write")); - return E_IO; - } - return r; -} - - - -// JNI bindings -// ============ - -inline struct serial_config* j2s(jlong pointer) { - return (struct serial_config*) pointer; -} - -inline jlong s2j(struct serial_config* pointer) { - return (jlong) pointer; -} - -JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_NativeSerial_open - (JNIEnv *env, jclass clazz, jstring device, jint baud, jlongArray jserialp) -{ - const char *dev = (*env)->GetStringUTFChars(env, device, 0); - struct serial_config* serial; - int r = serial_open(dev, baud, &serial); - (*env)->ReleaseStringUTFChars(env, device, dev); - - long serialp = s2j(serial); - (*env)->SetLongArrayRegion(env, jserialp, 0, 1, &serialp); - - return r; -} - -JNIEXPORT void JNICALL Java_com_github_jodersky_flow_NativeSerial_close - (JNIEnv * env, jclass clazz, jlong serial) -{ - serial_close(j2s(serial)); -} - -JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_NativeSerial_read - (JNIEnv * env, jclass clazz, jlong serial, jbyteArray jbuffer) -{ - - jsize size = (*env)->GetArrayLength(env, jbuffer); - - unsigned char buffer[size]; - int n = serial_read(j2s(serial), buffer, size); - if (n < 0) { - return n; - } - - (*env)->SetByteArrayRegion(env, jbuffer, 0, n, (signed char *) buffer); - return n; -} - -JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_NativeSerial_write - (JNIEnv * env, jclass clazz, jlong serial, jbyteArray jbuffer) -{ - unsigned char * buffer = (*env)->GetByteArrayElements(env, jbuffer, NULL); - int size = (*env)->GetArrayLength(env, jbuffer); - int r = serial_write(j2s(serial), buffer, size); - - (*env)->ReleaseByteArrayElements(env, jbuffer, buffer, JNI_ABORT); - - return r; -} - -JNIEXPORT void JNICALL Java_com_github_jodersky_flow_NativeSerial_debug - (JNIEnv *env, jclass clazz, jboolean value) -{ - debug = (bool) value; -} - diff --git a/src/main/java/com/github/jodersky/flow/NativeSerial.java b/src/main/java/com/github/jodersky/flow/NativeSerial.java deleted file mode 100644 index f5d708e..0000000 --- a/src/main/java/com/github/jodersky/flow/NativeSerial.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.github.jodersky.flow; - -public class NativeSerial { - - static { - NativeLoader.load(); - } - - final static int E_PERMISSION = -1; - final static int E_OPEN = -2; - final static int E_BUSY = -3; - final static int E_BAUD = -4; - final static int E_PIPE = -5; - final static int E_MALLOC = -6; - final static int E_POINTER = -7; - final static int E_POLL = -8; - final static int E_IO = -9; - final static int E_CLOSE = -10; - - - /* return values: - * 0 ok - * E_PERMISSION don't have permission to open - * E_OPEN can't get file descriptor - * E_BUSY device busy - * E_BAUD invalid baudrate - * E_PIPE can't open pipe for graceful closing - * E_MALLOC malloc error */ - native static int open(String device, int baud, long[] serial); - - /* return - * >0 number of bytes read - * E_POINTER invalid serial pointer - * E_POLL poll error - * E_IO read error - * E_CLOSE close request */ - native static int read(long serial, byte[] buffer); - - /*return - * >0 number of bytes written - * E_POINTER invalid serial config (null pointer) - * E_IO write error */ - native static int write(long serial, byte[] buffer); - - native static void close(long serial); - - native static void debug(boolean value); - -} diff --git a/src/main/scala/com/github/jodersky/flow/Main.scala b/src/main/scala/com/github/jodersky/flow/Main.scala deleted file mode 100644 index feea51b..0000000 --- a/src/main/scala/com/github/jodersky/flow/Main.scala +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.jodersky.flow - -import scala.concurrent._ -import scala.concurrent.ExecutionContext.Implicits.global - -object Main { - - def main(args: Array[String]): Unit = { - println("opening") - - Serial.debug(true) - val s = Serial.open("/dev/ttyACM0", 115200){ data => - println(data.mkString("[",",","]")) - } - println("press enter to write a loooooooooong array of data") - Console.readLine() - - val data: Array[Byte] = Array.fill(1000000)(42) - s.write(data).map(d => println("sent: " + d.mkString("[",",","]"))).recover{case t => println("write error")} - - println("press enter to exit") - Console.readLine() - println("exiting") - Console.flush() - } -}
\ No newline at end of file diff --git a/src/main/scala/com/github/jodersky/flow/NativeLoader.scala b/src/main/scala/com/github/jodersky/flow/NativeLoader.scala deleted file mode 100644 index 91b3fd8..0000000 --- a/src/main/scala/com/github/jodersky/flow/NativeLoader.scala +++ /dev/null @@ -1,35 +0,0 @@ -package com.github.jodersky.flow - -import java.io.File -import java.io.FileOutputStream - -object NativeLoader { - - def load = { - val os = System.getProperty("os.name").toLowerCase - val arch = System.getProperty("os.arch").toLowerCase - - val in = NativeLoader.getClass().getResourceAsStream("/native/" + os + "/" + arch + "/" + "libflow.so") - val temp = File.createTempFile("flow" + os + arch, ".so"); - temp.deleteOnExit() - val out = new FileOutputStream(temp); - - try { - var read: Int = 0; ; - val buffer = new Array[Byte](4096); - do { - read = in.read(buffer) - if (read != -1) { - out.write(buffer, 0, read); - } - } while (read != -1) - } finally { - in.close() - out.close - } - - System.load(temp.getAbsolutePath()) - - } - -}
\ No newline at end of file diff --git a/src/main/scala/com/github/jodersky/flow/Serial.scala b/src/main/scala/com/github/jodersky/flow/Serial.scala deleted file mode 100644 index 7565cbd..0000000 --- a/src/main/scala/com/github/jodersky/flow/Serial.scala +++ /dev/null @@ -1,63 +0,0 @@ -package com.github.jodersky.flow - -import scala.concurrent._ -import scala.concurrent.ExecutionContext.Implicits._ -import java.io.IOException - -class Serial private (val port: String, private val pointer: Long, reader: Array[Byte] => Unit) { - future { - var n = 0 - val buffer = new Array[Byte](100) - while (n >= 0) { - n = NativeSerial.read(pointer, buffer) - import NativeSerial._ - n match { - case E_POINTER => throw new NullPointerException("pointer to native serial") - case E_POLL => throw new IOException(port + ": polling") - case E_IO => throw new IOException(port + ": reading") - case E_CLOSE => println("close request") - case x if x > 0 => reader(buffer.take(n)) - } - } - } - - private def writeBlock(data: Array[Byte]) = synchronized { - import NativeSerial._ - NativeSerial.write(pointer, data) match { - case E_POINTER => throw new NullPointerException("pointer to native serial") - case E_IO => throw new IOException(port + ": writing") - case r => data.take(r) - } - } - - def write(data: Array[Byte]) = future { writeBlock(data) } - - def close() = synchronized { - NativeSerial.close(pointer) - } - -} - -object Serial { - - def open(port: String, baud: Int)(reader: Array[Byte] => Unit) = synchronized { - val pointer = new Array[Long](1) - val result = NativeSerial.open(port, baud, pointer) - - import NativeSerial._ - result match { - case E_PERMISSION => throw new AccessDeniedException(port) - case E_OPEN => throw new NoSuchPortException(port) - case E_BUSY => throw new PortInUseException(port) - case E_BAUD => throw new IllegalArgumentException( - s"invalid baudrate ${baud}, use standard unix values") - case E_PIPE => throw new IOException("cannot create pipe") - case E_MALLOC => throw new IOException("cannot allocate memory") - case 0 => new Serial(port, pointer(0), reader) - case _ => throw new Exception("cannot open port") - } - } - - def debug(value: Boolean) = NativeSerial.debug(value) - -}
\ No newline at end of file diff --git a/src/main/scala/com/github/jodersky/flow/exceptions.scala b/src/main/scala/com/github/jodersky/flow/exceptions.scala deleted file mode 100644 index a360079..0000000 --- a/src/main/scala/com/github/jodersky/flow/exceptions.scala +++ /dev/null @@ -1,7 +0,0 @@ -package com.github.jodersky.flow - -import java.io.IOException - -class NoSuchPortException(message: String) extends IOException(message) -class PortInUseException(message: String) extends IOException(message) -class AccessDeniedException(message: String) extends IOException(message)
\ No newline at end of file |