aboutsummaryrefslogtreecommitdiff
path: root/flow-native
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2014-01-13 17:40:34 +0100
committerJakob Odersky <jodersky@gmail.com>2014-01-14 15:43:00 +0100
commit5c94ee017051d51f51e06a61a8bc4e70a15e36da (patch)
tree2e48701ebb4177557234dbbd22b3b7058cad36de /flow-native
parent84f640208ed6e4e155e87ebcb73a82c021174ea7 (diff)
downloadakka-serial-5c94ee017051d51f51e06a61a8bc4e70a15e36da.tar.gz
akka-serial-5c94ee017051d51f51e06a61a8bc4e70a15e36da.tar.bz2
akka-serial-5c94ee017051d51f51e06a61a8bc4e70a15e36da.zip
enable easier cross-compilation
Diffstat (limited to 'flow-native')
-rw-r--r--flow-native/shared/include/flow.h80
-rw-r--r--flow-native/unix/src/flow.c312
2 files changed, 0 insertions, 392 deletions
diff --git a/flow-native/shared/include/flow.h b/flow-native/shared/include/flow.h
deleted file mode 100644
index ebb845a..0000000
--- a/flow-native/shared/include/flow.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef FLOW_H
-#define FLOW_H
-
-#include <stdbool.h>
-
-//general error codes that are returned by functions
-#define E_IO -1 //I/O error (port should be closed)
-#define E_ACCESS_DENIED -2 //access denied
-#define E_BUSY -3 // port is busy
-#define E_INVALID_SETTINGS -4 // some port settings are invalid
-#define E_INTERRUPT -5 // not really an error, function call aborted because port is closed
-#define E_NO_PORT -6 //requested port does not exist
-
-#define PARITY_NONE 0
-#define PARITY_ODD 1
-#define PARITY_EVEN 2
-
-/** Represents an open serial port. */
-struct serial_config;
-
-/**Opens a serial port and allocates memory for storing configuration. Note: if this function fails,
- * any internally allocated resources will be freed.
- * @param port_name name of port
- * @param baud baud rate
- * @param char_size character size of data transmitted through serial device
- * @param two_stop_bits set to use two stop bits instead of one
- * @param parity kind of parity checking to use
- * @param serial pointer to memory that will be allocated with a serial structure
- * @return 0 on success
- * @return E_NO_PORT if the given port does not exist
- * @return E_ACCESS_DENIED if permissions are not sufficient to open port
- * @return E_BUSY if port is already in use
- * @return E_INVALID_SETTINGS if any of the specified settings are not supported
- * @return E_IO on other error */
-int serial_open(
- const char* port_name,
- int baud,
- int char_size,
- bool two_stop_bits,
- int parity,
- struct serial_config** serial);
-
-/**Closes a previously opened serial port and frees memory containing the configuration. Note: after a call to
- * this function, the 'serial' pointer will become invalid, make sure you only call it once. This function is NOT
- * thread safe, make sure no read or write is in prgress when this function is called (the reason is that per
- * close manual page, close should not be called on a file descriptor that is in use by another thread).
- * @param serial pointer to serial configuration that is to be closed (and freed)
- * @return 0 on success
- * @return E_IO on error */
-int serial_close(struct serial_config* serial);
-
-/**Starts a read from a previously opened serial port. The read is blocking, however it may be
- * interrupted by calling 'serial_interrupt' on the given serial port.
- * @param serial pointer to serial configuration from which to read
- * @param buffer buffer into which data is read
- * @param size maximum buffer size
- * @return n>0 the number of bytes read into buffer
- * @return E_INTERRUPT if the call to this function was interrupted
- * @return E_IO on IO error */
-int serial_read(struct serial_config* serial, unsigned char* buffer, size_t size);
-
-/**Interrupts a blocked read call.
- * @param serial_config the serial port to interrupt
- * @return 0 on success
- * @return E_IO on error */
-int serial_interrupt(struct serial_config* serial);
-
-/**Writes data to a previously opened serial port. Non bocking.
- * @param serial pointer to serial configuration to which to write
- * @param data data to write
- * @param size number of bytes to write from data
- * @return n>0 the number of bytes written
- * @return E_IO on IO error */
-int serial_write(struct serial_config* serial, unsigned char* data, size_t size);
-
-/**Sets debugging option. If debugging is enabled, detailed error message are printed from method calls. */
-void serial_debug(bool value);
-
-
-#endif /* FLOW_H */
diff --git a/flow-native/unix/src/flow.c b/flow-native/unix/src/flow.c
deleted file mode 100644
index caf7b9b..0000000
--- a/flow-native/unix/src/flow.c
+++ /dev/null
@@ -1,312 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <termios.h>
-#include <fcntl.h>
-#include "com_github_jodersky_flow_internal_NativeSerial.h"
-#include "flow.h"
-
-static bool debug = false;
-#define DEBUG(f) if (debug) {f}
-
-void serial_debug(bool value) {
- debug = value;
-}
-
-//contains file descriptors used in managing a serial port
-struct serial_config {
-
- int port_fd; // file descriptor of serial port
-
- /* a pipe is used to abort a serial read by writing something into the
- * write end of the pipe */
- int pipe_read_fd; // file descriptor, read end of pipe
- int pipe_write_fd; // file descriptor, write end of pipe
-
-};
-
-int serial_open(
- const char* port_name,
- int baud,
- int char_size,
- bool two_stop_bits,
- int parity,
- struct serial_config** serial) {
-
- int fd = open(port_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
-
- if (fd < 0) {
- int en = errno;
- DEBUG(perror("obtain file descriptor"););
- if (en == EACCES) return E_ACCESS_DENIED;
- if (en == ENOENT) return E_NO_PORT;
- return E_IO;
- }
-
- if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
- DEBUG(perror("acquire lock on port"););
- close(fd);
- return E_BUSY;
- }
-
- /* configure new port settings */
- struct termios newtio;
-
- /* following calls correspond to makeraw() */
- newtio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
- newtio.c_oflag &= ~OPOST;
- newtio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- newtio.c_cflag &= ~(CSIZE | PARENB);
-
- /* set speed */
- 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:
- close(fd);
- return E_INVALID_SETTINGS;
- }
-
- if (cfsetspeed(&newtio, bd) < 0) {
- DEBUG(perror("set baud rate"););
- close(fd);
- return E_IO;
- }
-
- /* set char size*/
- switch (char_size) {
- case 5: newtio.c_cflag |= CS5; break;
- case 6: newtio.c_cflag |= CS6; break;
- case 7: newtio.c_cflag |= CS7; break;
- case 8: newtio.c_cflag |= CS8; break;
- default:
- close(fd);
- return E_INVALID_SETTINGS;
- }
-
- /* use two stop bits */
- if (two_stop_bits){
- newtio.c_cflag |= CSTOPB;
- }
-
- /* set parity */
- switch (parity) {
- case PARITY_NONE: break;
- case PARITY_ODD: newtio.c_cflag |= (PARENB | PARODD); break;
- case PARITY_EVEN: newtio.c_cflag |= PARENB; break;
- default:
- close(fd);
- return E_INVALID_SETTINGS;
- }
-
- if (tcflush(fd, TCIOFLUSH) < 0) {
- DEBUG(perror("flush serial settings"););
- close(fd);
- return E_IO;
- }
-
- if (tcsetattr(fd, TCSANOW, &newtio) < 0) {
- DEBUG(perror("apply serial settings"););
- close(fd);
- return E_IO;
- }
-
- int pipe_fd[2];
- if (pipe(pipe_fd) < 0) {
- DEBUG(perror("open pipe"););
- close(fd);
- return E_IO;
- }
-
- if (fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK) < 0 || fcntl(pipe_fd[1], F_SETFL, O_NONBLOCK) < 0) {
- DEBUG(perror("make pipe non-blocking"););
- close(fd);
- return E_IO;
- }
-
- struct serial_config* s = malloc(sizeof(s));
- if (s == NULL) {
- DEBUG(perror("allocate memory for serial configuration"););
- close(fd);
- close(pipe_fd[0]);
- close(pipe_fd[1]);
- return E_IO;
- }
-
- s->port_fd = fd;
- s->pipe_read_fd = pipe_fd[0];
- s->pipe_write_fd = pipe_fd[1];
- (*serial) = s;
-
- return 0;
-}
-
-int serial_close(struct serial_config* serial) {
- if (close(serial->pipe_write_fd) < 0) {
- DEBUG(perror("close write end of pipe"););
- return E_IO;
- }
- if (close(serial->pipe_read_fd) < 0) {
- DEBUG(perror("close read end of pipe"););
- return E_IO;
- }
-
- if (flock(serial->port_fd, LOCK_UN) < 0){
- DEBUG(perror("release lock on port"););
- return E_IO;
- }
- if (close(serial->port_fd) < 0) {
- DEBUG(perror("close port"););
- return E_IO;
- }
-
- free(serial);
- return 0;
-}
-
-int serial_read(struct serial_config* serial, unsigned char* buffer, size_t size) {
- int port = serial->port_fd;
- int pipe = serial->pipe_read_fd;
-
- fd_set rfds;
- FD_ZERO(&rfds);
- FD_SET(port, &rfds);
- FD_SET(pipe, &rfds);
-
- int nfds = pipe + 1;
- if (pipe < port) nfds = port + 1;
-
- int n = select(nfds, &rfds, NULL, NULL, NULL);
- if (n < 0) {
- DEBUG(perror("select"););
- return E_IO;
- }
-
- if (FD_ISSET(port, &rfds)) {
- int r = read(port, 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) {
- DEBUG(perror("read"););
- return E_IO;
- }
- return r;
- } else if (FD_ISSET(pipe, &rfds)) {
- return E_INTERRUPT;
- } else {
- fputs("select: unknown read sets", stderr);
- return E_IO;
- }
-}
-
-int serial_write(struct serial_config* serial, unsigned char* data, size_t size) {
- int r = write(serial->port_fd, data, size);
- if (r < 0) {
- DEBUG(perror("write"););
- return E_IO;
- }
- return r;
-}
-
-int serial_interrupt(struct serial_config* serial) {
- int data = 0xffffffff;
-
- //write to pipe to wake up any blocked read thread (self-pipe trick)
- if (write(serial->pipe_write_fd, &data, 1) < 0) {
- DEBUG(perror("write to pipe for interrupt"););
- return E_IO;
- }
-
- return 0;
-}
-
-
-// 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_internal_NativeSerial_open
- (JNIEnv *env, jclass clazz, jstring port_name, jint baud, jint char_size, jboolean two_stop_bits, jint parity, jlongArray jserialp)
-{
- const char *dev = (*env)->GetStringUTFChars(env, port_name, 0);
- struct serial_config* serial;
- int r = serial_open(dev, baud, char_size, two_stop_bits, parity, &serial);
- (*env)->ReleaseStringUTFChars(env, port_name, dev);
-
- long serialp = s2j(serial);
- (*env)->SetLongArrayRegion(env, jserialp, 0, 1, &serialp);
-
- return r;
-}
-
-JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_close
- (JNIEnv * env, jclass clazz, jlong serial)
-{
- serial_close(j2s(serial));
-}
-
-JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_internal_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_internal_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 jint JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_interrupt
- (JNIEnv * env, jclass clazz, jlong serial)
-{
- return serial_interrupt(j2s(serial));
-}
-
-JNIEXPORT void JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_debug
- (JNIEnv *env, jclass clazz, jboolean value)
-{
- serial_debug((bool) value);
-}