aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jakob@odersky.com>2017-01-08 21:16:25 +0100
committerJakob Odersky <jakob@odersky.com>2017-01-21 17:22:10 -0800
commit23959966760174477a6b0fcbf9dd1e8ef37c643b (patch)
tree9a0ee44eb43a8c13af57b0d06313f3aabf9e4555
parent6c371ba6d69c891c1f0d6df00bb643e1d543cc9d (diff)
downloadakka-serial-23959966760174477a6b0fcbf9dd1e8ef37c643b.tar.gz
akka-serial-23959966760174477a6b0fcbf9dd1e8ef37c643b.tar.bz2
akka-serial-23959966760174477a6b0fcbf9dd1e8ef37c643b.zip
Rename project to akka-serial
-rw-r--r--.travis.yml2
-rw-r--r--CHANGELOG.md4
-rw-r--r--Documentation/developer.md18
-rw-r--r--Documentation/manual.md34
-rw-r--r--README.md32
-rw-r--r--build.sbt45
-rw-r--r--core/build.sbt (renamed from flow-core/build.sbt)4
-rw-r--r--core/src/main/scala/akka/serial/Serial.scala (renamed from flow-core/src/main/scala/ch/jodersky/flow/Serial.scala)12
-rw-r--r--core/src/main/scala/akka/serial/SerialExt.scala (renamed from flow-core/src/main/scala/ch/jodersky/flow/SerialExt.scala)2
-rw-r--r--core/src/main/scala/akka/serial/SerialManager.scala (renamed from flow-core/src/main/scala/ch/jodersky/flow/SerialManager.scala)7
-rw-r--r--core/src/main/scala/akka/serial/SerialOperator.scala (renamed from flow-core/src/main/scala/ch/jodersky/flow/SerialOperator.scala)13
-rw-r--r--core/src/main/scala/akka/serial/Watcher.scala (renamed from flow-core/src/main/scala/ch/jodersky/flow/Watcher.scala)6
-rw-r--r--core/src/test/resources/reference.conf3
-rw-r--r--core/src/test/scala/akka/serial/SerialManagerSpec.scala (renamed from flow-core/src/test/scala/ch/jodersky/flow/SerialManagerSpec.scala)4
-rw-r--r--core/src/test/scala/akka/serial/SerialOperatorSpec.scala (renamed from flow-core/src/test/scala/ch/jodersky/flow/SerialOperatorSpec.scala)3
-rwxr-xr-xflow-native/lib_native/armv7l-linux/libflow4.sobin12852 -> 0 bytes
-rw-r--r--flow-native/lib_native/i686-linux/libflow4.sobin14735 -> 0 bytes
-rw-r--r--flow-native/lib_native/x86_64-darwin/libflow4.dylibbin18336 -> 0 bytes
-rwxr-xr-xflow-native/lib_native/x86_64-linux/libflow4.sobin16791 -> 0 bytes
-rw-r--r--flow-native/src/include/ch_jodersky_flow_UnsafeSerial.h45
-rw-r--r--flow-native/src/include/ch_jodersky_flow_UnsafeSerial__.h29
-rw-r--r--flow-native/src/platform/windows/README1
-rw-r--r--flow-samples/README.md3
-rw-r--r--native/build.sbt (renamed from flow-native/build.sbt)0
-rw-r--r--native/src/.gitignore (renamed from flow-native/src/.gitignore)0
-rw-r--r--native/src/CMakeLists.txt (renamed from flow-native/src/CMakeLists.txt)4
-rw-r--r--native/src/akka_serial_jni.c (renamed from flow-native/src/flow_jni.c)42
-rw-r--r--native/src/include/akka_serial.h (renamed from flow-native/src/include/flow.h)6
-rw-r--r--native/src/include/akka_serial_sync_UnsafeSerial.h45
-rw-r--r--native/src/include/akka_serial_sync_UnsafeSerial__.h29
-rw-r--r--native/src/platform/posix/akka_serial.c (renamed from flow-native/src/platform/posix/flow.c)2
-rw-r--r--native/src/platform/windows/README1
-rw-r--r--native/src/platform/windows/akka_serial.c.disabled (renamed from flow-native/src/platform/windows/flow.c.disabled)0
-rw-r--r--native/src/readme.md (renamed from flow-native/src/readme.md)2
-rw-r--r--project/Dependencies.scala8
-rw-r--r--samples/README.md3
-rw-r--r--samples/terminal-stream/src/main/scala/akka/serial/samples/terminalstream/Main.scala (renamed from flow-samples/terminal-stream/src/main/scala/ch/jodersky/flow/samples/terminalstream/Main.scala)2
-rw-r--r--samples/terminal/src/main/scala/akka/serial/samples/terminal/ConsoleReader.scala (renamed from flow-samples/terminal/src/main/scala/ch/jodersky/flow/samples/terminal/ConsoleReader.scala)2
-rw-r--r--samples/terminal/src/main/scala/akka/serial/samples/terminal/Main.scala (renamed from flow-samples/terminal/src/main/scala/ch/jodersky/flow/samples/terminal/Main.scala)4
-rw-r--r--samples/terminal/src/main/scala/akka/serial/samples/terminal/Terminal.scala (renamed from flow-samples/terminal/src/main/scala/ch/jodersky/flow/samples/terminal/Terminal.scala)2
-rw-r--r--samples/watcher/src/main/scala/akka/serial/samples/watcher/main.scala (renamed from flow-samples/watcher/src/main/scala/ch/jodersky/flow/samples/watcher/main.scala)4
-rw-r--r--stream/build.sbt (renamed from flow-stream/build.sbt)2
-rw-r--r--stream/src/main/scala/akka/serial/stream/Serial.scala (renamed from flow-stream/src/main/scala/ch/jodersky/flow/stream/Serial.scala)5
-rw-r--r--stream/src/main/scala/akka/serial/stream/StreamSerialException.scala (renamed from flow-stream/src/main/scala/ch/jodersky/flow/stream/StreamSerialException.scala)2
-rw-r--r--stream/src/main/scala/akka/serial/stream/StreamWatcherException.scala (renamed from flow-stream/src/main/scala/ch/jodersky/flow/stream/StreamWatcherException.scala)2
-rw-r--r--stream/src/main/scala/akka/serial/stream/impl/SerialConnectionLogic.scala (renamed from flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/SerialConnectionLogic.scala)14
-rw-r--r--stream/src/main/scala/akka/serial/stream/impl/SerialConnectionStage.scala (renamed from flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/SerialConnectionStage.scala)2
-rw-r--r--stream/src/main/scala/akka/serial/stream/impl/WatcherLogic.scala (renamed from flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/WatcherLogic.scala)4
-rw-r--r--stream/src/main/scala/akka/serial/stream/impl/WatcherStage.scala (renamed from flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/WatcherStage.scala)2
-rw-r--r--stream/src/test/resources/application.conf3
-rw-r--r--stream/src/test/scala/akka/serial/stream/SerialSpec.scala (renamed from flow-stream/src/test/scala/ch/jodersky/flow/stream/SerialSpec.scala)4
-rw-r--r--sync/build.sbt5
-rw-r--r--sync/src/main/scala/akka/serial/Parity.scala (renamed from flow-core/src/main/scala/ch/jodersky/flow/Parity.scala)2
-rw-r--r--sync/src/main/scala/akka/serial/SerialSettings.scala (renamed from flow-core/src/main/scala/ch/jodersky/flow/SerialSettings.scala)2
-rw-r--r--sync/src/main/scala/akka/serial/exceptions.scala (renamed from flow-core/src/main/scala/ch/jodersky/flow/exceptions.scala)2
-rw-r--r--sync/src/main/scala/akka/serial/sync/SerialConnection.scala (renamed from flow-core/src/main/scala/ch/jodersky/flow/SerialConnection.scala)22
-rw-r--r--sync/src/main/scala/akka/serial/sync/UnsafeSerial.scala (renamed from flow-core/src/main/scala/ch/jodersky/flow/UnsafeSerial.scala)9
-rw-r--r--sync/src/test/scala/akka/serial/PseudoTerminal.scala (renamed from flow-core/src/test/scala/ch/jodersky/flow/PseudoTerminal.scala)4
-rw-r--r--sync/src/test/scala/akka/serial/sync/SerialConnectionSpec.scala101
59 files changed, 373 insertions, 237 deletions
diff --git a/.travis.yml b/.travis.yml
index a8d4609..4232fd1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,6 +20,6 @@ cache:
- "$HOME/.sbt/boot/"
before_cache:
- - find $HOME/.ivy2/cache/ch.jodersky -depth -name "flow*" -exec rm -r {} \;
+ - find $HOME/.ivy2/cache/ch.jodersky -depth -name "akka-serial*" -exec rm -r {} \;
- find $HOME/.ivy2 -name "ivydata-*.properties" -delete
- find $HOME/.sbt -name "*.lock" -delete
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 90d5e47..ee0f076 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# (unreleased)
+- Rename project to akka-serial
+- Move non-akka-dependent serial code into separate project, "akka-serial-sync"
+
# Version 3.0.4
- Implement unit tests
- Upgrade Akka to 2.4.14
diff --git a/Documentation/developer.md b/Documentation/developer.md
index 62f64d4..e7c581f 100644
--- a/Documentation/developer.md
+++ b/Documentation/developer.md
@@ -7,7 +7,7 @@ title: Developer Guide
{:toc}
# Building from Source
-A complete build of flow involves two parts
+A complete build of akka-serial involves two parts
1. Building Scala sources (the front-end), resulting in a platform independent artifact (i.e. a jar file).
@@ -19,7 +19,7 @@ Both steps are independent, their only interaction being a header file generated
Run `sbt core/package` in the base directory. This simply compiles Scala sources as with any standard sbt project and packages the resulting class files into a jar.
## Building Native Sources
-The back-end is managed by CMake and all relevant files are contained in `flow-native/src`.
+The back-end is managed by CMake and all relevant files are contained in `native/src`.
### Build Process
Several steps are involved in producing the native library:
@@ -45,9 +45,9 @@ Several steps are involved in producing the native library:
- put into a "fat" jar, useful for dependency management with sbt (see next section)
### Creating a Fat Jar
-The native library produced in the previous step may be bundled into a "fat" jar so that it can be included in SBT projects through its regular dependency mechanisms. In this process, sbt basically acts as a wrapper script around CMake, calling the native build process and packaging generated libraries. Running `sbt native/package` produces the fat jar in `flow-native/target`.
+The native library produced in the previous step may be bundled into a "fat" jar so that it can be included in sbt projects through its regular dependency mechanisms. In this process, sbt basically acts as a wrapper script around CMake, calling the native build process and packaging generated libraries. Running `sbt native/package` produces the fat jar in `native/target`.
-Note: an important feature of fat jars is to include native libraries for several platforms. To copy binaries compiled on other platforms to the fat jar, place them in a subfolder of `flow-native/lib_native`. The subfolder should have the name `$(arch)-$(kernel)`, where `arch` and `kernel` are, respectively, the lower-case values returned by `uname -m` and `uname -s`.
+Note: an important feature of fat jars is to include native libraries for several platforms. To copy binaries compiled on other platforms to the fat jar, place them in a subfolder of `native/lib_native`. The subfolder should have the name `$(arch)-$(kernel)`, where `arch` and `kernel` are, respectively, the lower-case values returned by `uname -m` and `uname -s`.
### Note About Versioning
The project and package versions follow a [semantic](http://semver.org/) pattern: `M.m.p`, where
@@ -58,11 +58,11 @@ The project and package versions follow a [semantic](http://semver.org/) pattern
- `p` is the patch number, representing internal modifications such as bug-fixes
-Usually (following most Linux distribution's conventions), shared libraries produced by a project `name` of version `M.m.p` are named `libname.so.M.m.p`. However, since when accessing shared libraries through the JVM, only the `name` can be specified and no particular version, the convention adopted by flow is to append `M` to the library name and always keep the major version at zero. E.g. `libflow.so.3.1.2` becomes `libflow3.so.0.1.2`.
+Usually (following most Linux distribution's conventions), shared libraries produced by a project `name` of version `M.m.p` are named `libname.so.M.m.p`. However, since when accessing shared libraries through the JVM, only the `name` can be specified and no particular version, the convention adopted by akka-serial is to append `M` to the library name and always keep the major version at zero. E.g. `libakkaserial.so.3.1.2` becomes `libakakserial3.so.0.1.2`.
# Testing
-`flow-samples` directory contains fully functional application examples of flow. To run an example, change to the base directory of flow and run sbt samples<SampleName>/run.
-All projects, including samples, can be listed by running sbt projects.
+The `samples` directory contains fully functional application examples of akka-serial. To run an example, change to the base directory of akka-serial and run sbt samples<SampleName>/run.
+All projects, including samples, can be listed by running `sbt projects`.
To be able connect you can use real device (arduino) burned with sample-echo (`dev/arduino-terminal`) code, or create Virtual Serial Port pair
@@ -101,11 +101,11 @@ socat -d -d pty,raw,echo=0 "exec:/bin/cat,pty,raw,echo=0"
```
# Publishing and Releasing
-Releases are handled automatically by the continuous integration and deployment system (Travis CI). A release will be performed for every annotated Git tag that is pushed to the main repository.
+Releases are handled automatically by the continuous integration and deployment system, Travis CI. A release will be performed for every annotated Git tag that is pushed to the main repository.
Here are a couple of observations on the release process:
-- During a release, only readily available libraries in `lib_native` are packaged into the fat jar, no local native compilation is performed. The rationale behind this is that while native libraries rarely change, they are still tied to the version of libc of the compiling system. Since the releases are mostly done on a development machine (cutting-edge OS), compiling native libraries locally could break compatibility with older systems.
+- During a release, only readily available libraries in `native/lib_native` are packaged into the fat jar, no local native compilation is performed. The rationale behind this is that while native libraries rarely change, they are still tied to the version of libc of the compiling system. Since the releases are mostly done on a development machine with a cutting-edge OS, compiling native libraries locally could break compatibility with older systems.
- The website is not automatically updated. After creating a new release:
diff --git a/Documentation/manual.md b/Documentation/manual.md
index d1bd335..f51689f 100644
--- a/Documentation/manual.md
+++ b/Documentation/manual.md
@@ -7,13 +7,13 @@ title: User Guide
{:toc}
# Getting Started
-Flow uses sbt as build system. To get started, include a dependency to flow in your project:
+akka-serial uses sbt as build system. To get started, include a dependency to akka-serial in your project:
~~~scala
-libraryDependencies += "ch.jodersky" %% "flow-core" % "@version@"
+libraryDependencies += "ch.jodersky" %% "akka-serial-core" % "@version@"
~~~
-Next, you need to include flow's native library that supports communication for serial devices.
+Next, you need to include akka-serial's native library that supports communication for serial devices.
## Including Native Library
There are two options to include the native library:
@@ -28,19 +28,19 @@ It is recommended that you use the first option for testing purposes or end-user
In case your kernel/architecture combination is present in the "supported platforms" table in the [downloads section]({{site.url}}/downloads/), add a second dependency to your project:
~~~scala
-libraryDependencies += "ch.jodersky" % "flow-native" % "@version@" % "runtime"
+libraryDependencies += "ch.jodersky" % "akka-serial-native" % "@version@" % "runtime"
~~~
This will add a jar to your classpath containing native libraries for various platforms. At run-time, the correct library for the current platform is selected, extracted and loaded. This solution enables running applications seamlessly, as if they were pure JVM applications.
### Maximum Portability
-Start by obtaining a copy of the native library, either by [building flow](./developer) or by [downloading]({{site.url}}/downloads/) a native archive. In order to work with this version of flow, native libraries need to be of major version @native_major@ and minor version greater or equal to @native_minor@.
+Start by obtaining a copy of the native library, either by [building akka-serial](./developer) or by [downloading]({{site.url}}/downloads/) a native archive. In order to work with this version of akka-serial, native libraries need to be of major version @native_major@ and minor version greater or equal to @native_minor@.
-Then, for every end-user application that relies on flow, manually add the native library for the current platform to the JVM's library path. This can be achieved through various ways, notably:
+Then, for every end-user application that relies on akka-serial, manually add the native library for the current platform to the JVM's library path. This can be achieved through various ways, notably:
- Per application:
- Run your program with the command-line option ```-Djava.library.path=".:<folder containing libflow@native_major@.so>"```. E.g. ```java -Djava.library.path=".:/home/<folder containing libflow@native_major@.so>" -jar your-app.jar```
+ Run your program with the command-line option ```-Djava.library.path=".:<folder containing libakkaserial@native_major@.so>"```. E.g. ```java -Djava.library.path=".:/home/<folder containing libakkaserial@native_major@.so>" -jar your-app.jar```
- System- or user-wide:
@@ -49,15 +49,15 @@ Then, for every end-user application that relies on flow, manually add the nativ
---
# Communication Protocol
-The following is a general guide on the usage of flow. If you prefer a complete example, check out the code contained in the [flow-samples](https://github.com/jodersky/flow/tree/v@version@/flow-samples) directory.
+The following is a general guide on the usage of akak-serial. If you prefer a complete example, check out the code contained in the [samples](https://github.com/jodersky/akka-serial/tree/v@version@/samples) directory.
-Flow's API follows that of an actor based system, where each actor is assigned specific functions involved in serial communication. The two main actor types are:
+akka-serial's API follows that of an actor based system, where each actor is assigned specific functions involved in serial communication. The two main actor types are:
1. Serial "manager". The manager is a singleton actor that is instantiated once per actor system, a reference to it may be obtained with `IO(Serial)`. It is typically used to open serial ports (see following section).
2. Serial "operators". Operators are created once per open serial port and serve as an intermediate between client code and native code dealing with serial data transmission and reception. They isolate the user from threading issues and enable the reactive dispatch of incoming data. A serial operator is said to be "associated" to its underlying open serial port.
-The messages understood by flow's actors are all contained in the `ch.jodersky.flow.Serial` object. They are well documented and should serve as the entry point when searching the API documentation.
+The messages understood by akka-serial's actors are all contained in the `akka.serial.Serial` object. They are well documented and should serve as the entry point when searching the API documentation.
## Opening a Port
A serial port is opened by sending an `Open` message to the serial manager. The response varies on the outcome of opening the underlying serial port.
@@ -67,7 +67,7 @@ A serial port is opened by sending an `Open` message to the serial manager. The
2. In case of success, the sender is notified with an `Opened` message. This message is sent from an operator actor, spawned by the serial manager. It is useful to capture the sender (i.e. the operator) of this message as all further communication with the newly opened port must pass through the operator.
~~~scala
-import ch.jodersky.flow.{ Serial, SerialSettings, AccessDeniedException }
+import akka.serial.{ Serial, SerialSettings, AccessDeniedException }
val port = "/dev/ttyXXX"
val settings = SerialSettings(
@@ -138,7 +138,7 @@ The opposite is not true by default, i.e. if the operator crashes (this can happ
---
# Watching Ports
-As of version 2.2.0, flow can watch directories for new files. On most unix systems this can be used for watching for new serial ports in `/dev/`.
+akka-serial can watch directories for new files. On most unix systems this can be used for watching for new serial ports in `/dev/`.
Watching happens through a message-based, publish-subscribe protocol as explained in the sections below.
## Subscribing
@@ -183,13 +183,13 @@ Note that the manager has a deathwatch on every subscribed client. Hence, should
---
# Stream Support
-Flow provides support for Akka streams and thus can be interfaced with reactive-streams. Support is implemented in a separate module, which needs to be added as a library dependency:
+akka-serial provides support for Akka streams and thus can be interfaced with reactive-streams. Support is implemented in a separate module, which needs to be added as a library dependency:
~~~scala
-libraryDependencies += "ch.jodersky" %% "flow-stream" % "@version@"
+libraryDependencies += "ch.jodersky" %% "akka-serial-stream" % "@version@"
~~~
-The main entry point for serial streaming is `ch.jodersky.flow.stream.Serial`. It's API is also well documented and should serve as the starting point when searching documentation on serial streaming.
+The main entry point for serial streaming is `akka.serial.stream.Serial`. Its API is also well documented and should serve as the starting point when searching documentation on serial streaming.
## Opening a Port
Connection is established by materializing a `Flow[ByteString, ByteString, Future[Connection]]` obtained by calling `Serial().open()`
@@ -217,6 +217,6 @@ Note that backpressure is only available for writing, to add backpressure on the
The underlying serial port is closed when its materialized serial flow is closed.
## Errors and Resource Handling
-Any errors described in flow-core can also be encountered in flow-streaming. When thrown, they will be wrapped as the cause of a `StreamSerialException` and cause the the serial `Flow` stage to fail.
+Any errors described in akka-serial-core can also be encountered in akka-serial-stream. When thrown, they will be wrapped as the cause of a `StreamSerialException` and cause the the serial `Flow` stage to fail.
-As with flow-core, native resources are handled by underlying Akka mechanisms and any crashes in user code will automatically case the resources to be freed.
+As with akka-serial-core, native resources are handled by underlying Akka mechanisms and any crashes in user code will automatically case the resources to be freed.
diff --git a/README.md b/README.md
index 9a53ee8..cf37fd8 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
-[![Build Status](https://travis-ci.org/jodersky/flow.svg?branch=master)](https://travis-ci.org/jodersky/flow)
-[![Download](https://img.shields.io/maven-central/v/ch.jodersky/flow-native.svg?maxAge=2592000)](http://search.maven.org/#search|ga|1|ch.jodersky%20flow-)
+[![Build Status](https://travis-ci.org/jodersky/akka-serial.svg?branch=master)](https://travis-ci.org/jodersky/akka-serial)
+[![Download](https://img.shields.io/maven-central/v/ch.jodersky/akka-serial-native.svg?maxAge=2592000)](http://search.maven.org/#search|ga|1|ch.jodersky%20akka-serial-)
-# flow
-Serial communication library for Scala, designed to be reactive, lightweight and easily integrable with Akka applications. See the [website](https://jodersky.github.io/flow) for a guide.
+# akka-serial
+Serial communication library for Scala, designed to be reactive, lightweight and easily integrable with Akka applications. See the [website](https://jodersky.github.io/akka-serial) for a guide.
## Highlights
- Reactive: only does work when required (no constant polling of ports or blocking IO)
@@ -16,25 +16,29 @@ Since hardware is involved in serial communication, a Scala-only solution is not
## Directory Structure
```
-flow/
+akka-serial/
├── Documentation Sources for user documentation as published on the website.
+├── core Main Scala source files.
├── dev Firmware samples for serial devices, to make testing easier.
-├── flow-core Main Scala source files.
-├── flow-native C sources used to implement serial communication.
-│ └── lib_native Compiled native libraries that are published in flow-native.
-├── flow-samples Runnable example projects.
-├── flow-stream Stream API, used to connect with Akka streams.
-└── project Build configuration.
+├── native C sources used to implement serial communication.
+│ └── lib_native Compiled native libraries that are published in the fat jar.
+├── project Build configuration.
+├── samples Runnable example projects.
+├── stream Stream API, used to connect with Akka streams.
+└── sync Synchronous, non-Akka-dependent code.
```
*Website source code is in the git branch 'gh-pages'.*
## Build
-Detailed documentation on building flow is available on the website (or, equivalently, in [developer.md](Documentation/developer.md)).
+Detailed documentation on building akka-serial is available on the website (or, equivalently, in [developer.md](Documentation/developer.md)).
-Since flow integrates into the Akka-IO framework, a good resource on its general design is the framework's [documentation](http://doc.akka.io/docs/akka/current/scala/io.html).
+Since akka-serial integrates into the Akka-IO framework, a good resource on its general design is the framework's [documentation](http://doc.akka.io/docs/akka/current/scala/io.html).
This project is also an experiment on working with JNI and automating build infrastructure.
## Copying
-flow is released under the terms of the 3-clause BSD license. See LICENSE for details.
+akka-serial is released under the terms of the 3-clause BSD license. See LICENSE for details.
+
+## Notes
+This project used to called "flow". It was renamed to "akka-serial".
diff --git a/build.sbt b/build.sbt
index 50d9f8a..e71b9f6 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,6 +1,6 @@
// Build settings
version in ThisBuild := ("git describe --always --dirty=-SNAPSHOT --match v[0-9].*" !!).tail.trim
-crossScalaVersions in ThisBuild := List("2.11.8", "2.12.0")
+crossScalaVersions in ThisBuild := List("2.12.1", "2.11.8")
scalaVersion in ThisBuild := crossScalaVersions.value.head
scalacOptions in ThisBuild ++= Seq(
"-deprecation",
@@ -9,11 +9,13 @@ scalacOptions in ThisBuild ++= Seq(
"-target:jvm-1.8"
)
fork in ThisBuild := true
+connectInput in run in ThisBuild := true
+outputStrategy in run in ThisBuild := Some(StdoutOutput)
// Publishing
organization in ThisBuild := "ch.jodersky"
licenses in ThisBuild := Seq(("BSD New", url("http://opensource.org/licenses/BSD-3-Clause")))
-homepage in ThisBuild := Some(url("https://jodersky.github.io/flow"))
+homepage in ThisBuild := Some(url("https://jodersky.github.io/akka-serial"))
publishMavenStyle in ThisBuild := true
publishTo in ThisBuild := {
val nexus = "https://oss.sonatype.org/"
@@ -21,8 +23,8 @@ publishTo in ThisBuild := {
}
pomExtra in ThisBuild := {
<scm>
- <url>git@github.com:jodersky/flow.git</url>
- <connection>scm:git:git@github.com:jodersky/flow.git</connection>
+ <url>git@github.com:jodersky/akka-serial.git</url>
+ <connection>scm:git:git@github.com:jodersky/akka-serial.git</connection>
</scm>
<developers>
<developer>
@@ -34,26 +36,30 @@ pomExtra in ThisBuild := {
// Project structure
lazy val root = (project in file("."))
- .aggregate(core, native, stream)
+ .aggregate(core, native, stream, sync)
-lazy val core = (project in file("flow-core"))
- .settings(name := "flow-core")
- .dependsOn(native % "test->runtime")
+lazy val core = (project in file("core"))
+ .settings(name := "akka-serial-core")
+ .dependsOn(sync, sync % "test->test")
+
+lazy val native = (project in file("native"))
+ .settings(name := "akka-serial-native")
-lazy val native = (project in file("flow-native"))
- .settings(name := "flow-native")
+lazy val stream = (project in file("stream"))
+ .settings(name := "akka-serial-stream")
+ .dependsOn(core, sync % "test->test")
-lazy val stream = (project in file("flow-stream"))
- .settings(name := "flow-stream")
- .dependsOn(core, core % "test->test", native % "test->runtime")
+lazy val sync = (project in file("sync"))
+ .settings(name := "akka-serial-sync")
+ .dependsOn(native % "test->runtime")
-lazy val samplesTerminal = (project in file("flow-samples") / "terminal")
+lazy val samplesTerminal = (project in file("samples") / "terminal")
.dependsOn(core, native % Runtime)
-lazy val samplesTerminalStream = (project in file("flow-samples") / "terminal-stream")
+lazy val samplesTerminalStream = (project in file("samples") / "terminal-stream")
.dependsOn(stream, native % Runtime)
-lazy val samplesWatcher = (project in file("flow-samples") / "watcher")
+lazy val samplesWatcher = (project in file("samples") / "watcher")
.dependsOn(core, native % Runtime)
// Root project settings
@@ -68,13 +74,16 @@ enablePlugins(PreprocessPlugin)
sourceDirectory in Preprocess := (baseDirectory in ThisBuild).value / "Documentation"
preprocessVars in Preprocess := Map(
"version" -> version.value,
- "native_major" -> "4",
+ "native_major" -> "1",
"native_minor" -> "0"
)
// Add scaladoc to documentation
enablePlugins(SiteScaladocPlugin)
+import UnidocKeys._
unidocSettings
+unidocProjectFilter in (ScalaUnidoc, unidoc) := inAnyProject -- inProjects(
+ samplesTerminal, samplesTerminalStream, samplesWatcher)
scalacOptions in (ScalaUnidoc, doc) ++= Seq(
"-groups", // Group similar methods together based on the @group annotation.
"-diagrams", // Show classs hierarchy diagrams (requires 'dot' to be available on path)
@@ -83,7 +92,7 @@ scalacOptions in (ScalaUnidoc, doc) ++= Seq(
) ++ {
val latestTag: String = "git describe --abbrev=0 --match v[0-9].*".!!
Opts.doc.sourceUrl(
- s"https://github.com/jodersky/flow/blob/$latestTag€{FILE_PATH}.scala"
+ s"https://github.com/jodersky/akka-serial/blob/$latestTag€{FILE_PATH}.scala"
)
}
siteMappings ++= (mappings in (ScalaUnidoc, packageDoc)).value.map{ case (file, path) =>
diff --git a/flow-core/build.sbt b/core/build.sbt
index fdfcbab..78673ce 100644
--- a/flow-core/build.sbt
+++ b/core/build.sbt
@@ -1,7 +1,5 @@
-import flow.Dependencies
+import akkaserial.Dependencies
libraryDependencies += Dependencies.akkaActor
libraryDependencies += Dependencies.akkaTestKit % "test"
libraryDependencies += Dependencies.scalatest % "test"
-
-target in javah := (baseDirectory in ThisBuild).value / "flow-native" / "src" / "include"
diff --git a/flow-core/src/main/scala/ch/jodersky/flow/Serial.scala b/core/src/main/scala/akka/serial/Serial.scala
index 43b1d19..a8e564a 100644
--- a/flow-core/src/main/scala/ch/jodersky/flow/Serial.scala
+++ b/core/src/main/scala/akka/serial/Serial.scala
@@ -1,18 +1,18 @@
-package ch.jodersky.flow
+package akka.serial
import akka.actor.ExtensionKey
import akka.util.ByteString
-/** Defines messages used by flow's serial IO layer. */
+/** Defines messages used by akka-serial's serial IO layer. */
object Serial extends ExtensionKey[SerialExt] {
- /** Base trait for any flow-related messages. */
+ /** Base trait for any akka-serial-related messages. */
sealed trait Message
- /** A message extending this trait is to be viewed as a command, an out-bound message issued by the client to flow's API. */
+ /** A message extending this trait is to be viewed as a command, an out-bound message issued by the client to akka-serial's API. */
trait Command extends Message
- /** A message extending this trait is to be viewed as an event, an in-bound message issued by flow to the client. */
+ /** A message extending this trait is to be viewed as an event, an in-bound message issued by akka-serial to the client. */
trait Event extends Message
/** A command has failed. */
@@ -127,6 +127,6 @@ object Serial extends ExtensionKey[SerialExt] {
*
* @param value set to enable debugging
*/
- def debug(value: Boolean) = UnsafeSerial.debug(value)
+ def debug(value: Boolean) = sync.UnsafeSerial.debug(value)
}
diff --git a/flow-core/src/main/scala/ch/jodersky/flow/SerialExt.scala b/core/src/main/scala/akka/serial/SerialExt.scala
index 4ed3e2e..2fcec7f 100644
--- a/flow-core/src/main/scala/ch/jodersky/flow/SerialExt.scala
+++ b/core/src/main/scala/akka/serial/SerialExt.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
import akka.actor.{ ExtendedActorSystem, Props }
import akka.io.IO
diff --git a/flow-core/src/main/scala/ch/jodersky/flow/SerialManager.scala b/core/src/main/scala/akka/serial/SerialManager.scala
index 7967087..4833165 100644
--- a/flow-core/src/main/scala/ch/jodersky/flow/SerialManager.scala
+++ b/core/src/main/scala/akka/serial/SerialManager.scala
@@ -1,15 +1,16 @@
-package ch.jodersky.flow
+package akka.serial
import akka.actor.{ Actor, ActorLogging, OneForOneStrategy }
import akka.actor.SupervisorStrategy.{ Escalate, Stop }
import scala.util.{ Failure, Success, Try }
+import sync.SerialConnection
/**
* Entry point to the serial API. Actor that manages serial port creation. Once opened, a serial port is handed over to
* a dedicated operator actor that acts as an intermediate between client code and the native system serial port.
* @see SerialOperator
*/
-private[flow] class SerialManager extends Actor {
+private[serial] class SerialManager extends Actor {
import SerialManager._
import context._
@@ -37,7 +38,7 @@ private[flow] class SerialManager extends Actor {
}
-private[flow] object SerialManager {
+private[serial] object SerialManager {
private def escapePortString(port: String) = port map {
case '/' => '-'
diff --git a/flow-core/src/main/scala/ch/jodersky/flow/SerialOperator.scala b/core/src/main/scala/akka/serial/SerialOperator.scala
index d5c131c..cb5b46d 100644
--- a/flow-core/src/main/scala/ch/jodersky/flow/SerialOperator.scala
+++ b/core/src/main/scala/akka/serial/SerialOperator.scala
@@ -1,14 +1,16 @@
-package ch.jodersky.flow
+package akka.serial
-import akka.actor.{ Actor, ActorLogging, ActorRef, Props, Terminated }
+import akka.actor.{ Actor, ActorRef, Props, Terminated }
import akka.util.ByteString
import java.nio.ByteBuffer
+import sync.SerialConnection
+
/**
* Operator associated to an open serial port. All communication with a port is done via an operator. Operators are created though the serial manager.
* @see SerialManager
*/
-private[flow] class SerialOperator(connection: SerialConnection, bufferSize: Int, client: ActorRef) extends Actor {
+private[serial] class SerialOperator(connection: SerialConnection, bufferSize: Int, client: ActorRef) extends Actor {
import SerialOperator._
import context._
@@ -21,8 +23,7 @@ private[flow] class SerialOperator(connection: SerialConnection, bufferSize: Int
while (!connection.isClosed && !stop) {
try {
buffer.clear()
- val length = connection.read(buffer)
- buffer.limit(length)
+ connection.read(buffer)
val data = ByteString.fromByteBuffer(buffer)
client.tell(Serial.Received(data), self)
} catch {
@@ -78,6 +79,6 @@ private[flow] class SerialOperator(connection: SerialConnection, bufferSize: Int
}
-private[flow] object SerialOperator {
+private[serial] object SerialOperator {
def apply(connection: SerialConnection, bufferSize: Int, client: ActorRef) = Props(classOf[SerialOperator], connection, bufferSize, client)
}
diff --git a/flow-core/src/main/scala/ch/jodersky/flow/Watcher.scala b/core/src/main/scala/akka/serial/Watcher.scala
index 9fa519b..faaf39a 100644
--- a/flow-core/src/main/scala/ch/jodersky/flow/Watcher.scala
+++ b/core/src/main/scala/akka/serial/Watcher.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
import akka.actor.{ Actor, ActorRef, Props, Terminated }
import java.nio.file.{ ClosedWatchServiceException, FileSystems, Files, Path, Paths, WatchEvent, WatchKey }
@@ -7,7 +7,7 @@ import scala.collection.JavaConversions._
import scala.collection.mutable.{ HashMap, Map, MultiMap, Set }
import scala.util.{ Failure, Success, Try }
-private[flow] class Watcher(from: Option[ActorRef]) extends Actor {
+private[serial] class Watcher(from: Option[ActorRef]) extends Actor {
case class WatcherDied(reason: Throwable)
object WatcherThread extends Thread {
@@ -135,7 +135,7 @@ private[flow] class Watcher(from: Option[ActorRef]) extends Actor {
}
-private[flow] object Watcher {
+private[serial] object Watcher {
private case class NewFile(directory: Path, file: Path)
def apply(from: ActorRef) = Props(classOf[Watcher], Some(from))
diff --git a/core/src/test/resources/reference.conf b/core/src/test/resources/reference.conf
new file mode 100644
index 0000000..bdf80e2
--- /dev/null
+++ b/core/src/test/resources/reference.conf
@@ -0,0 +1,3 @@
+# Don't fill test output with log messages
+akka.stdout-loglevel = "OFF"
+akka.loglevel = "OFF" \ No newline at end of file
diff --git a/flow-core/src/test/scala/ch/jodersky/flow/SerialManagerSpec.scala b/core/src/test/scala/akka/serial/SerialManagerSpec.scala
index 59af305..eab5013 100644
--- a/flow-core/src/test/scala/ch/jodersky/flow/SerialManagerSpec.scala
+++ b/core/src/test/scala/akka/serial/SerialManagerSpec.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
import akka.actor.ActorSystem
import akka.io.IO
@@ -30,6 +30,8 @@ class SerialManagerSpec
"fail opening a non-existing port" in {
val cmd = Serial.Open("nonexistent", SerialSettings(115200))
manager ! cmd
+
+ //manager.context.set
assert(expectMsgType[Serial.CommandFailed].command == cmd)
}
diff --git a/flow-core/src/test/scala/ch/jodersky/flow/SerialOperatorSpec.scala b/core/src/test/scala/akka/serial/SerialOperatorSpec.scala
index 4c1dd94..6907494 100644
--- a/flow-core/src/test/scala/ch/jodersky/flow/SerialOperatorSpec.scala
+++ b/core/src/test/scala/akka/serial/SerialOperatorSpec.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
import scala.concurrent.duration._
@@ -6,6 +6,7 @@ import akka.actor.{ActorRef, ActorSystem}
import akka.testkit.{ImplicitSender, TestKit}
import akka.util.ByteString
import org.scalatest._
+import sync._
case class Ack(n: Int) extends Serial.Event
diff --git a/flow-native/lib_native/armv7l-linux/libflow4.so b/flow-native/lib_native/armv7l-linux/libflow4.so
deleted file mode 100755
index f5d9ae0..0000000
--- a/flow-native/lib_native/armv7l-linux/libflow4.so
+++ /dev/null
Binary files differ
diff --git a/flow-native/lib_native/i686-linux/libflow4.so b/flow-native/lib_native/i686-linux/libflow4.so
deleted file mode 100644
index fb438e2..0000000
--- a/flow-native/lib_native/i686-linux/libflow4.so
+++ /dev/null
Binary files differ
diff --git a/flow-native/lib_native/x86_64-darwin/libflow4.dylib b/flow-native/lib_native/x86_64-darwin/libflow4.dylib
deleted file mode 100644
index 213415d..0000000
--- a/flow-native/lib_native/x86_64-darwin/libflow4.dylib
+++ /dev/null
Binary files differ
diff --git a/flow-native/lib_native/x86_64-linux/libflow4.so b/flow-native/lib_native/x86_64-linux/libflow4.so
deleted file mode 100755
index 18fb300..0000000
--- a/flow-native/lib_native/x86_64-linux/libflow4.so
+++ /dev/null
Binary files differ
diff --git a/flow-native/src/include/ch_jodersky_flow_UnsafeSerial.h b/flow-native/src/include/ch_jodersky_flow_UnsafeSerial.h
deleted file mode 100644
index f80ada0..0000000
--- a/flow-native/src/include/ch_jodersky_flow_UnsafeSerial.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class ch_jodersky_flow_UnsafeSerial */
-
-#ifndef _Included_ch_jodersky_flow_UnsafeSerial
-#define _Included_ch_jodersky_flow_UnsafeSerial
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: ch_jodersky_flow_UnsafeSerial
- * Method: read
- * Signature: (Ljava/nio/ByteBuffer;)I
- */
-JNIEXPORT jint JNICALL Java_ch_jodersky_flow_UnsafeSerial_read
- (JNIEnv *, jobject, jobject);
-
-/*
- * Class: ch_jodersky_flow_UnsafeSerial
- * Method: cancelRead
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_cancelRead
- (JNIEnv *, jobject);
-
-/*
- * Class: ch_jodersky_flow_UnsafeSerial
- * Method: write
- * Signature: (Ljava/nio/ByteBuffer;I)I
- */
-JNIEXPORT jint JNICALL Java_ch_jodersky_flow_UnsafeSerial_write
- (JNIEnv *, jobject, jobject, jint);
-
-/*
- * Class: ch_jodersky_flow_UnsafeSerial
- * Method: close
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_close
- (JNIEnv *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/flow-native/src/include/ch_jodersky_flow_UnsafeSerial__.h b/flow-native/src/include/ch_jodersky_flow_UnsafeSerial__.h
deleted file mode 100644
index 617875f..0000000
--- a/flow-native/src/include/ch_jodersky_flow_UnsafeSerial__.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class ch_jodersky_flow_UnsafeSerial__ */
-
-#ifndef _Included_ch_jodersky_flow_UnsafeSerial__
-#define _Included_ch_jodersky_flow_UnsafeSerial__
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: ch_jodersky_flow_UnsafeSerial__
- * Method: open
- * Signature: (Ljava/lang/String;IIZI)J
- */
-JNIEXPORT jlong JNICALL Java_ch_jodersky_flow_UnsafeSerial_00024_open
- (JNIEnv *, jobject, jstring, jint, jint, jboolean, jint);
-
-/*
- * Class: ch_jodersky_flow_UnsafeSerial__
- * Method: debug
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_00024_debug
- (JNIEnv *, jobject, jboolean);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/flow-native/src/platform/windows/README b/flow-native/src/platform/windows/README
deleted file mode 100644
index 3d24410..0000000
--- a/flow-native/src/platform/windows/README
+++ /dev/null
@@ -1 +0,0 @@
-The contents of the file flow.c were found in the avrdude project. They look like they may be a good starting point for serial communication on windows.
diff --git a/flow-samples/README.md b/flow-samples/README.md
deleted file mode 100644
index 5460b4d..0000000
--- a/flow-samples/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory contains fully functional application examples of flow. To run an example, change to the base directory of flow (this parent's directory) and run `sbt samples<SampleName>/run`.
-
-All projects, including samples, can be listed by running `sbt projects`.
diff --git a/flow-native/build.sbt b/native/build.sbt
index 2c7ffea..2c7ffea 100644
--- a/flow-native/build.sbt
+++ b/native/build.sbt
diff --git a/flow-native/src/.gitignore b/native/src/.gitignore
index 1785c46..1785c46 100644
--- a/flow-native/src/.gitignore
+++ b/native/src/.gitignore
diff --git a/flow-native/src/CMakeLists.txt b/native/src/CMakeLists.txt
index a57451c..a6b037d 100644
--- a/flow-native/src/CMakeLists.txt
+++ b/native/src/CMakeLists.txt
@@ -11,8 +11,8 @@ set(ignoreMe "${SBT}") # sbt-jni defines -DSBT
# Define project and related variables
# (required by sbt-jni) please use semantic versioning
#
-project (flow)
-set(PROJECT_VERSION_MAJOR 4)
+project (akkaserial)
+set(PROJECT_VERSION_MAJOR 1)
set(PROJECT_VERSION_MINOR 0)
set(PROJECT_VERSION_PATCH 0)
diff --git a/flow-native/src/flow_jni.c b/native/src/akka_serial_jni.c
index 75bffff..126a7bf 100644
--- a/flow-native/src/flow_jni.c
+++ b/native/src/akka_serial_jni.c
@@ -1,9 +1,9 @@
#include <stdint.h>
-#include "flow.h"
+#include "akka_serial.h"
-#include "ch_jodersky_flow_UnsafeSerial.h"
-#include "ch_jodersky_flow_UnsafeSerial__.h"
+#include "akka_serial_sync_UnsafeSerial.h"
+#include "akka_serial_sync_UnsafeSerial__.h"
// suppress unused parameter warnings
#define UNUSED_ARG(x) (void)(x)
@@ -18,11 +18,11 @@ static void check(JNIEnv* env, int ret)
{
switch (ret) {
case -E_IO: throwException(env, "java/io/IOException", ""); break;
- case -E_BUSY: throwException(env, "ch/jodersky/flow/PortInUseException", ""); break;
- case -E_ACCESS_DENIED: throwException(env, "ch/jodersky/flow/AccessDeniedException", ""); break;
- case -E_INVALID_SETTINGS: throwException(env, "ch/jodersky/flow/InvalidSettingsException", ""); break;
- case -E_INTERRUPT: throwException(env, "ch/jodersky/flow/PortInterruptedException", ""); break;
- case -E_NO_PORT: throwException(env, "ch/jodersky/flow/NoSuchPortException", ""); break;
+ case -E_BUSY: throwException(env, "akka/serial/PortInUseException", ""); break;
+ case -E_ACCESS_DENIED: throwException(env, "akka/serial/AccessDeniedException", ""); break;
+ case -E_INVALID_SETTINGS: throwException(env, "akka/serial/InvalidSettingsException", ""); break;
+ case -E_INTERRUPT: throwException(env, "akka/serial/PortInterruptedException", ""); break;
+ case -E_NO_PORT: throwException(env, "akka/serial/NoSuchPortException", ""); break;
default: return;
}
}
@@ -30,18 +30,18 @@ static void check(JNIEnv* env, int ret)
/** Get pointer to serial config associated to an UnsafeSerial instance. */
static struct serial_config* get_config(JNIEnv* env, jobject unsafe_serial)
{
- jclass clazz = (*env)->FindClass(env, "ch/jodersky/flow/UnsafeSerial");
+ jclass clazz = (*env)->FindClass(env, "akka/serial/sync/UnsafeSerial");
jfieldID field = (*env)->GetFieldID(env, clazz, "serialAddr", "J");
jlong addr = (*env)->GetLongField(env, unsafe_serial, field);
return (struct serial_config*) (intptr_t) addr;
}
/*
- * Class: ch_jodersky_flow_UnsafeSerial__
+ * Class: akka_serial_sync_UnsafeSerial__
* Method: open
* Signature: (Ljava/lang/String;IIZI)J
*/
-JNIEXPORT jlong JNICALL Java_ch_jodersky_flow_UnsafeSerial_00024_open
+JNIEXPORT jlong JNICALL Java_akka_serial_sync_UnsafeSerial_00024_open
(JNIEnv *env, jobject instance, jstring port_name, jint baud, jint char_size, jboolean two_stop_bits, jint parity)
{
UNUSED_ARG(instance);
@@ -61,11 +61,11 @@ JNIEXPORT jlong JNICALL Java_ch_jodersky_flow_UnsafeSerial_00024_open
}
/*
- * Class: ch_jodersky_flow_UnsafeSerial
+ * Class: akka_serial_sync_UnsafeSerial
* Method: read
* Signature: (Ljava/nio/ByteBuffer;)I
*/
-JNIEXPORT jint JNICALL Java_ch_jodersky_flow_UnsafeSerial_read
+JNIEXPORT jint JNICALL Java_akka_serial_sync_UnsafeSerial_read
(JNIEnv *env, jobject instance, jobject buffer)
{
char* local_buffer = (char*) (*env)->GetDirectBufferAddress(env, buffer);
@@ -85,11 +85,11 @@ JNIEXPORT jint JNICALL Java_ch_jodersky_flow_UnsafeSerial_read
}
/*
- * Class: ch_jodersky_flow_UnsafeSerial
+ * Class: akka_serial_sync_UnsafeSerial
* Method: cancelRead
* Signature: ()V
*/
-JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_cancelRead
+JNIEXPORT void JNICALL Java_akka_serial_sync_UnsafeSerial_cancelRead
(JNIEnv *env, jobject instance)
{
int r = serial_cancel_read(get_config(env, instance));
@@ -99,11 +99,11 @@ JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_cancelRead
}
/*
- * Class: ch_jodersky_flow_UnsafeSerial
+ * Class: akka_serial_sync_UnsafeSerial
* Method: write
* Signature: (Ljava/nio/ByteBuffer;I)I
*/
-JNIEXPORT jint JNICALL Java_ch_jodersky_flow_UnsafeSerial_write
+JNIEXPORT jint JNICALL Java_akka_serial_sync_UnsafeSerial_write
(JNIEnv *env, jobject instance, jobject buffer, jint size)
{
@@ -122,11 +122,11 @@ JNIEXPORT jint JNICALL Java_ch_jodersky_flow_UnsafeSerial_write
}
/*
- * Class: ch_jodersky_flow_UnsafeSerial
+ * Class: akka_serial_sync_UnsafeSerial
* Method: close
* Signature: ()V
*/
-JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_close
+JNIEXPORT void JNICALL Java_akka_serial_sync_UnsafeSerial_close
(JNIEnv *env, jobject instance)
{
int r = serial_close(get_config(env, instance));
@@ -136,11 +136,11 @@ JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_close
}
/*
- * Class: ch_jodersky_flow_UnsafeSerial__
+ * Class: akka_serial_sync_UnsafeSerial__
* Method: debug
* Signature: (Z)V
*/
-JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_00024_debug
+JNIEXPORT void JNICALL Java_akka_serial_sync_UnsafeSerial_00024_debug
(JNIEnv *env, jobject instance, jboolean value)
{
UNUSED_ARG(env);
diff --git a/flow-native/src/include/flow.h b/native/src/include/akka_serial.h
index e3f33b9..23507a9 100644
--- a/flow-native/src/include/flow.h
+++ b/native/src/include/akka_serial.h
@@ -1,5 +1,5 @@
-#ifndef FLOW_H
-#define FLOW_H
+#ifndef AKKA_SERIAL_H
+#define AKKA_SERIAL_H
#ifdef __cplusplus
extern "C" {
@@ -100,4 +100,4 @@ void serial_debug(bool value);
}
#endif
-#endif /* FLOW_H */
+#endif /* AKKA_SERIAL_H */
diff --git a/native/src/include/akka_serial_sync_UnsafeSerial.h b/native/src/include/akka_serial_sync_UnsafeSerial.h
new file mode 100644
index 0000000..893ccf6
--- /dev/null
+++ b/native/src/include/akka_serial_sync_UnsafeSerial.h
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class akka_serial_sync_UnsafeSerial */
+
+#ifndef _Included_akka_serial_sync_UnsafeSerial
+#define _Included_akka_serial_sync_UnsafeSerial
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: akka_serial_sync_UnsafeSerial
+ * Method: read
+ * Signature: (Ljava/nio/ByteBuffer;)I
+ */
+JNIEXPORT jint JNICALL Java_akka_serial_sync_UnsafeSerial_read
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: akka_serial_sync_UnsafeSerial
+ * Method: cancelRead
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_akka_serial_sync_UnsafeSerial_cancelRead
+ (JNIEnv *, jobject);
+
+/*
+ * Class: akka_serial_sync_UnsafeSerial
+ * Method: write
+ * Signature: (Ljava/nio/ByteBuffer;I)I
+ */
+JNIEXPORT jint JNICALL Java_akka_serial_sync_UnsafeSerial_write
+ (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class: akka_serial_sync_UnsafeSerial
+ * Method: close
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_akka_serial_sync_UnsafeSerial_close
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/native/src/include/akka_serial_sync_UnsafeSerial__.h b/native/src/include/akka_serial_sync_UnsafeSerial__.h
new file mode 100644
index 0000000..5f4bdb9
--- /dev/null
+++ b/native/src/include/akka_serial_sync_UnsafeSerial__.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class akka_serial_sync_UnsafeSerial__ */
+
+#ifndef _Included_akka_serial_sync_UnsafeSerial__
+#define _Included_akka_serial_sync_UnsafeSerial__
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: akka_serial_sync_UnsafeSerial__
+ * Method: open
+ * Signature: (Ljava/lang/String;IIZI)J
+ */
+JNIEXPORT jlong JNICALL Java_akka_serial_sync_UnsafeSerial_00024_open
+ (JNIEnv *, jobject, jstring, jint, jint, jboolean, jint);
+
+/*
+ * Class: akka_serial_sync_UnsafeSerial__
+ * Method: debug
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_akka_serial_sync_UnsafeSerial_00024_debug
+ (JNIEnv *, jobject, jboolean);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/flow-native/src/platform/posix/flow.c b/native/src/platform/posix/akka_serial.c
index 969949b..a2de056 100644
--- a/flow-native/src/platform/posix/flow.c
+++ b/native/src/platform/posix/akka_serial.c
@@ -6,7 +6,7 @@
#include <fcntl.h>
#include <sys/file.h>
#include <sys/select.h>
-#include "flow.h"
+#include "akka_serial.h"
#define DATA_CANCEL 0xffffffff
diff --git a/native/src/platform/windows/README b/native/src/platform/windows/README
new file mode 100644
index 0000000..ea7c736
--- /dev/null
+++ b/native/src/platform/windows/README
@@ -0,0 +1 @@
+The contents of the file akka_serial.c were found in the avrdude project. They look like they may be a good starting point for serial communication on windows.
diff --git a/flow-native/src/platform/windows/flow.c.disabled b/native/src/platform/windows/akka_serial.c.disabled
index 86a267c..86a267c 100644
--- a/flow-native/src/platform/windows/flow.c.disabled
+++ b/native/src/platform/windows/akka_serial.c.disabled
diff --git a/flow-native/src/readme.md b/native/src/readme.md
index 84306fe..9b9d00d 100644
--- a/flow-native/src/readme.md
+++ b/native/src/readme.md
@@ -1,3 +1,3 @@
-# Native backend for flow
+# Native backend for akka-serial
Refer to [developer.md](../../site/jekyll/documentation/developer.md) for information on how to build.
diff --git a/project/Dependencies.scala b/project/Dependencies.scala
index 0e7d1ac..db6ae02 100644
--- a/project/Dependencies.scala
+++ b/project/Dependencies.scala
@@ -1,13 +1,13 @@
-package flow
+package akkaserial
import sbt._
object Dependencies {
- val akkaActor = "com.typesafe.akka" %% "akka-actor" % "2.4.14"
- val akkaStream ="com.typesafe.akka" %% "akka-stream" % "2.4.14"
+ val akkaActor = "com.typesafe.akka" %% "akka-actor" % "2.4.16"
+ val akkaStream ="com.typesafe.akka" %% "akka-stream" % "2.4.16"
- val akkaTestKit = "com.typesafe.akka" %% "akka-testkit" % "2.4.14"
+ val akkaTestKit = "com.typesafe.akka" %% "akka-testkit" % "2.4.16"
val scalatest = "org.scalatest" %% "scalatest" % "3.0.1"
}
diff --git a/samples/README.md b/samples/README.md
new file mode 100644
index 0000000..d51b9c2
--- /dev/null
+++ b/samples/README.md
@@ -0,0 +1,3 @@
+This directory contains fully functional application examples of akka-serial. To run an example, change to the base directory of akka-serial (this parent's directory) and run `sbt samples<SampleName>/run`.
+
+All projects, including samples, can be listed by running `sbt projects`.
diff --git a/flow-samples/terminal-stream/src/main/scala/ch/jodersky/flow/samples/terminalstream/Main.scala b/samples/terminal-stream/src/main/scala/akka/serial/samples/terminalstream/Main.scala
index 74433db..de626a3 100644
--- a/flow-samples/terminal-stream/src/main/scala/ch/jodersky/flow/samples/terminalstream/Main.scala
+++ b/samples/terminal-stream/src/main/scala/akka/serial/samples/terminalstream/Main.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package samples.terminalstream
import scala.concurrent.Future
diff --git a/flow-samples/terminal/src/main/scala/ch/jodersky/flow/samples/terminal/ConsoleReader.scala b/samples/terminal/src/main/scala/akka/serial/samples/terminal/ConsoleReader.scala
index 2b30663..cc14dd4 100644
--- a/flow-samples/terminal/src/main/scala/ch/jodersky/flow/samples/terminal/ConsoleReader.scala
+++ b/samples/terminal/src/main/scala/akka/serial/samples/terminal/ConsoleReader.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package samples.terminal
import akka.actor.Actor
diff --git a/flow-samples/terminal/src/main/scala/ch/jodersky/flow/samples/terminal/Main.scala b/samples/terminal/src/main/scala/akka/serial/samples/terminal/Main.scala
index 80c0f80..0226e72 100644
--- a/flow-samples/terminal/src/main/scala/ch/jodersky/flow/samples/terminal/Main.scala
+++ b/samples/terminal/src/main/scala/akka/serial/samples/terminal/Main.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package samples.terminal
import akka.actor.ActorSystem
@@ -23,7 +23,7 @@ object Main {
println("Starting terminal system, enter :q to exit.")
Serial.debug(true)
- val system = ActorSystem("flow")
+ val system = ActorSystem("akka-serial")
val terminal = system.actorOf(Terminal(port, settings), name = "terminal")
system.registerOnTermination(println("Stopped terminal system."))
}
diff --git a/flow-samples/terminal/src/main/scala/ch/jodersky/flow/samples/terminal/Terminal.scala b/samples/terminal/src/main/scala/akka/serial/samples/terminal/Terminal.scala
index de60620..55b0422 100644
--- a/flow-samples/terminal/src/main/scala/ch/jodersky/flow/samples/terminal/Terminal.scala
+++ b/samples/terminal/src/main/scala/akka/serial/samples/terminal/Terminal.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package samples.terminal
import akka.actor.{ Actor, ActorLogging, ActorRef, Props, Terminated, actorRef2Scala }
diff --git a/flow-samples/watcher/src/main/scala/ch/jodersky/flow/samples/watcher/main.scala b/samples/watcher/src/main/scala/akka/serial/samples/watcher/main.scala
index 650d08e..d9a0d4e 100644
--- a/flow-samples/watcher/src/main/scala/ch/jodersky/flow/samples/watcher/main.scala
+++ b/samples/watcher/src/main/scala/akka/serial/samples/watcher/main.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package samples.watcher
import akka.actor.{ Actor, ActorLogging, ActorSystem, Props }
@@ -41,7 +41,7 @@ class Watcher extends Actor with ActorLogging {
object Main {
def main(args: Array[String]): Unit = {
- val system = ActorSystem("flow")
+ val system = ActorSystem("akka-serial")
val watcher = system.actorOf(Props(classOf[Watcher]), name = "watcher")
StdIn.readLine()
system.terminate()
diff --git a/flow-stream/build.sbt b/stream/build.sbt
index c9aa7eb..e66f1d5 100644
--- a/flow-stream/build.sbt
+++ b/stream/build.sbt
@@ -1,4 +1,4 @@
-import flow.Dependencies
+import akkaserial.Dependencies
libraryDependencies += Dependencies.akkaActor
libraryDependencies += Dependencies.akkaStream
diff --git a/flow-stream/src/main/scala/ch/jodersky/flow/stream/Serial.scala b/stream/src/main/scala/akka/serial/stream/Serial.scala
index d478de8..785001f 100644
--- a/flow-stream/src/main/scala/ch/jodersky/flow/stream/Serial.scala
+++ b/stream/src/main/scala/akka/serial/stream/Serial.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package stream
import akka.stream.scaladsl.Source
@@ -9,9 +9,10 @@ import akka.io.IO
import akka.stream.scaladsl.Flow
import akka.util.ByteString
-import ch.jodersky.flow.{Serial => CoreSerial}
+import akka.serial.{Serial => CoreSerial}
import impl._
+
object Serial extends ExtensionId[Serial] with ExtensionIdProvider {
/**
diff --git a/flow-stream/src/main/scala/ch/jodersky/flow/stream/StreamSerialException.scala b/stream/src/main/scala/akka/serial/stream/StreamSerialException.scala
index 78438f9..e2bb519 100644
--- a/flow-stream/src/main/scala/ch/jodersky/flow/stream/StreamSerialException.scala
+++ b/stream/src/main/scala/akka/serial/stream/StreamSerialException.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package stream
/** Represents a generic exception occured during streaming of serial data. */
diff --git a/flow-stream/src/main/scala/ch/jodersky/flow/stream/StreamWatcherException.scala b/stream/src/main/scala/akka/serial/stream/StreamWatcherException.scala
index 8eee61c..aafbfd6 100644
--- a/flow-stream/src/main/scala/ch/jodersky/flow/stream/StreamWatcherException.scala
+++ b/stream/src/main/scala/akka/serial/stream/StreamWatcherException.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package stream
class StreamWatcherException(message: String, cause: Throwable = null) extends RuntimeException(message, cause)
diff --git a/flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/SerialConnectionLogic.scala b/stream/src/main/scala/akka/serial/stream/impl/SerialConnectionLogic.scala
index 764b054..a650c82 100644
--- a/flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/SerialConnectionLogic.scala
+++ b/stream/src/main/scala/akka/serial/stream/impl/SerialConnectionLogic.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package stream
package impl
@@ -9,7 +9,7 @@ import akka.stream.{FlowShape, Inlet, Outlet}
import akka.stream.stage.{GraphStageLogic, InHandler, OutHandler}
import akka.util.ByteString
-import ch.jodersky.flow.{Serial => CoreSerial, SerialSettings}
+import akka.serial.{Serial => CoreSerial, SerialSettings}
/**
* Graph logic that handles establishing and forwarding serial communication.
@@ -143,11 +143,11 @@ private[stream] class SerialConnectionLogic(
if (isAvailable(out)) {
push(out, data)
} else if (failOnOverflow) {
- /* Note that the native backend does not provide any way of informing about
- * dropped serial data. However, in most cases, a computer capable of running flow
- * is also capable of processing incoming serial data at typical baud rates.
- * Hence packets will usually only be dropped if an application that uses flow
- * backpressures, which can however be detected here. */
+ /* Note that the native backend does not provide any way of informing about dropped serial
+ * data. However, in most cases, a computer capable of running akka-serial is also capable
+ * of processing incoming serial data at typical baud rates. Hence packets will usually
+ * only be dropped if an application that uses akka-serial backpressures, which can
+ * however be detected here. */
failStage(new StreamSerialException("Incoming serial data was dropped."))
}
diff --git a/flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/SerialConnectionStage.scala b/stream/src/main/scala/akka/serial/stream/impl/SerialConnectionStage.scala
index ceeac01..aa67943 100644
--- a/flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/SerialConnectionStage.scala
+++ b/stream/src/main/scala/akka/serial/stream/impl/SerialConnectionStage.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package stream
package impl
diff --git a/flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/WatcherLogic.scala b/stream/src/main/scala/akka/serial/stream/impl/WatcherLogic.scala
index 60b7c90..afab60e 100644
--- a/flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/WatcherLogic.scala
+++ b/stream/src/main/scala/akka/serial/stream/impl/WatcherLogic.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package stream
package impl
@@ -7,7 +7,7 @@ import scala.concurrent.Promise
import akka.actor.{ActorRef, Terminated}
import akka.stream.SourceShape
import akka.stream.stage.GraphStageLogic
-import ch.jodersky.flow.{Serial => CoreSerial}
+import akka.serial.{Serial => CoreSerial}
private[stream] class WatcherLogic(
shape: SourceShape[String],
diff --git a/flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/WatcherStage.scala b/stream/src/main/scala/akka/serial/stream/impl/WatcherStage.scala
index 82fad69..649249f 100644
--- a/flow-stream/src/main/scala/ch/jodersky/flow/stream/impl/WatcherStage.scala
+++ b/stream/src/main/scala/akka/serial/stream/impl/WatcherStage.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package stream
package impl
diff --git a/stream/src/test/resources/application.conf b/stream/src/test/resources/application.conf
new file mode 100644
index 0000000..bdf80e2
--- /dev/null
+++ b/stream/src/test/resources/application.conf
@@ -0,0 +1,3 @@
+# Don't fill test output with log messages
+akka.stdout-loglevel = "OFF"
+akka.loglevel = "OFF" \ No newline at end of file
diff --git a/flow-stream/src/test/scala/ch/jodersky/flow/stream/SerialSpec.scala b/stream/src/test/scala/akka/serial/stream/SerialSpec.scala
index 1a1ebdc..7a64383 100644
--- a/flow-stream/src/test/scala/ch/jodersky/flow/stream/SerialSpec.scala
+++ b/stream/src/test/scala/akka/serial/stream/SerialSpec.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
package stream
import scala.concurrent.Await
@@ -12,7 +12,7 @@ import org.scalatest._
class SerialSpec extends WordSpec with BeforeAndAfterAll with PseudoTerminal {
- implicit val system = ActorSystem("flow-test")
+ implicit val system = ActorSystem("akka-serial-test")
implicit val materializer = ActorMaterializer()
override def afterAll {
diff --git a/sync/build.sbt b/sync/build.sbt
new file mode 100644
index 0000000..547a3fd
--- /dev/null
+++ b/sync/build.sbt
@@ -0,0 +1,5 @@
+import akkaserial.Dependencies
+
+libraryDependencies += Dependencies.scalatest % "test"
+
+target in javah := (baseDirectory in ThisBuild).value / "native" / "src" / "include"
diff --git a/flow-core/src/main/scala/ch/jodersky/flow/Parity.scala b/sync/src/main/scala/akka/serial/Parity.scala
index 30596d2..a1e1d04 100644
--- a/flow-core/src/main/scala/ch/jodersky/flow/Parity.scala
+++ b/sync/src/main/scala/akka/serial/Parity.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
/** Specifies available parities used in serial communication. */
object Parity extends Enumeration {
diff --git a/flow-core/src/main/scala/ch/jodersky/flow/SerialSettings.scala b/sync/src/main/scala/akka/serial/SerialSettings.scala
index 2d3a6ed..56345ae 100644
--- a/flow-core/src/main/scala/ch/jodersky/flow/SerialSettings.scala
+++ b/sync/src/main/scala/akka/serial/SerialSettings.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
/**
* Groups settings used in communication over a serial port.
diff --git a/flow-core/src/main/scala/ch/jodersky/flow/exceptions.scala b/sync/src/main/scala/akka/serial/exceptions.scala
index ee087a8..26dfceb 100644
--- a/flow-core/src/main/scala/ch/jodersky/flow/exceptions.scala
+++ b/sync/src/main/scala/akka/serial/exceptions.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
/** The requested port could not be found. */
class NoSuchPortException(message: String) extends Exception(message)
diff --git a/flow-core/src/main/scala/ch/jodersky/flow/SerialConnection.scala b/sync/src/main/scala/akka/serial/sync/SerialConnection.scala
index 1cd1046..7d80a4c 100644
--- a/flow-core/src/main/scala/ch/jodersky/flow/SerialConnection.scala
+++ b/sync/src/main/scala/akka/serial/sync/SerialConnection.scala
@@ -1,4 +1,5 @@
-package ch.jodersky.flow
+package akka.serial
+package sync
import java.nio.ByteBuffer
import java.util.concurrent.atomic.AtomicBoolean
@@ -10,7 +11,7 @@ import java.util.concurrent.atomic.AtomicBoolean
*
* The underlying serial port is assumed open when this class is initialized.
*/
-private[flow] class SerialConnection private (
+class SerialConnection private (
unsafe: UnsafeSerial,
val port: String
) {
@@ -49,14 +50,14 @@ private[flow] class SerialConnection private (
/**
* Reads data from underlying serial connection into a ByteBuffer.
- * Note that data is read into the buffer's memory, its attributes
- * such as position and limit are not modified.
+ * Note that data is read into the buffer's memory, starting at the
+ * first position. The buffer's limit is set to the number of bytes
+ * read.
*
* A call to this method is blocking, however it is interrupted
* if the connection is closed.
*
- * This method works for direct and indirect buffers but is optimized
- * for the former.
+ * This method works only for direct buffers.
*
* @param buffer a ByteBuffer into which data is read
* @return the actual number of bytes read
@@ -67,7 +68,9 @@ private[flow] class SerialConnection private (
if (!closed.get) {
try {
reading = true
- unsafe.read(buffer)
+ val n = unsafe.read(buffer)
+ buffer.limit(n)
+ n
} finally {
reading = false
if (closed.get) readLock.notify()
@@ -85,8 +88,7 @@ private[flow] class SerialConnection private (
* The write is non-blocking, this function returns as soon as the data is copied into the kernel's
* transmission buffer.
*
- * This method works for direct and indirect buffers but is optimized
- * for the former.
+ * This method works only for direct buffers.
*
* @param buffer a ByteBuffer from which data is taken
* @return the actual number of bytes written
@@ -108,7 +110,7 @@ private[flow] class SerialConnection private (
}
-private[flow] object SerialConnection {
+object SerialConnection {
/**
* Opens a new connection to a serial port.
diff --git a/flow-core/src/main/scala/ch/jodersky/flow/UnsafeSerial.scala b/sync/src/main/scala/akka/serial/sync/UnsafeSerial.scala
index 3126618..dcca960 100644
--- a/flow-core/src/main/scala/ch/jodersky/flow/UnsafeSerial.scala
+++ b/sync/src/main/scala/akka/serial/sync/UnsafeSerial.scala
@@ -1,4 +1,5 @@
-package ch.jodersky.flow
+package akka.serial
+package sync
import java.nio.ByteBuffer
@@ -16,8 +17,8 @@ import ch.jodersky.jni.nativeLoader
*
* @param serialAddr address of natively allocated serial configuration structure
*/
-@nativeLoader("flow4")
-private[flow] class UnsafeSerial(final val serialAddr: Long) {
+@nativeLoader("akkaserial1")
+private[serial] class UnsafeSerial(final val serialAddr: Long) {
final val ParityNone: Int = 0
final val ParityOdd: Int = 1
@@ -79,7 +80,7 @@ private[flow] class UnsafeSerial(final val serialAddr: Long) {
}
-private[flow] object UnsafeSerial {
+private[serial] object UnsafeSerial {
/**
* Opens a serial port.
diff --git a/flow-core/src/test/scala/ch/jodersky/flow/PseudoTerminal.scala b/sync/src/test/scala/akka/serial/PseudoTerminal.scala
index 8e891ae..3e9e9fe 100644
--- a/flow-core/src/test/scala/ch/jodersky/flow/PseudoTerminal.scala
+++ b/sync/src/test/scala/akka/serial/PseudoTerminal.scala
@@ -1,4 +1,4 @@
-package ch.jodersky.flow
+package akka.serial
import java.io.{File, IOException}
import java.nio.file.Files
@@ -12,7 +12,7 @@ trait PseudoTerminal {
final val SetupTimeout = 100.milliseconds
def withEcho[A](action: (String, SerialSettings) => A): A = {
- val dir = Files.createTempDirectory("flow-pty").toFile
+ val dir = Files.createTempDirectory("akka-serial-pty").toFile
val pty = new File(dir, "pty")
val socat = try {
diff --git a/sync/src/test/scala/akka/serial/sync/SerialConnectionSpec.scala b/sync/src/test/scala/akka/serial/sync/SerialConnectionSpec.scala
new file mode 100644
index 0000000..24069d7
--- /dev/null
+++ b/sync/src/test/scala/akka/serial/sync/SerialConnectionSpec.scala
@@ -0,0 +1,101 @@
+package akka.serial
+package sync
+
+import java.nio.ByteBuffer
+import org.scalatest._
+
+class SerialConnectionSpec extends WordSpec with PseudoTerminal {
+
+ def withEchoConnection[A](action: SerialConnection => A): A = {
+ withEcho { (port, settings) =>
+ val connection = SerialConnection.open(port, settings)
+ try {
+ action(connection)
+ } finally {
+ connection.close()
+ }
+ }
+ }
+
+ "A SerialConnection" should {
+
+ "open a valid port" in {
+ withEcho { (port, settings) =>
+ SerialConnection.open(port, settings)
+ }
+ }
+
+ "throw an exception on an invalid port" in {
+ val settings = SerialSettings(baud = 115200)
+ intercept[NoSuchPortException] {
+ SerialConnection.open("/dev/nonexistant", settings)
+ }
+ }
+
+ "read the same data it writes to an echo pty" in {
+ withEchoConnection { conn =>
+ /* Note: this test assumes that all data will be written and read
+ * within single write and read calls. This in turn assumes that
+ * internal operating system buffers have enough capacity to
+ * store all data. */
+ val bufferSize = 64
+
+ val outString = "hello world"
+ val outBuffer = ByteBuffer.allocateDirect(bufferSize)
+ val outData = outString.getBytes
+ outBuffer.put(outData)
+ conn.write(outBuffer)
+
+ val inBuffer = ByteBuffer.allocateDirect(bufferSize)
+ conn.read(inBuffer)
+ val inData = new Array[Byte](inBuffer.remaining())
+ inBuffer.get(inData)
+ val inString = new String(inData)
+
+ assert(inString == outString)
+ }
+ }
+
+ "interrupt a read when closing a port" in {
+ withEchoConnection { conn =>
+ val buffer = ByteBuffer.allocateDirect(64)
+
+ val closer = new Thread {
+ override def run(): Unit = {
+ Thread.sleep(100)
+ conn.close()
+ }
+ }
+ closer.start()
+ intercept[PortInterruptedException]{
+ conn.read(buffer)
+ }
+ closer.join()
+ }
+ }
+
+ "throw an exception when reading from a closed port" in {
+ withEchoConnection { conn =>
+ val buffer = ByteBuffer.allocateDirect(64)
+ conn.close()
+
+ intercept[PortClosedException]{
+ conn.read(buffer)
+ }
+ }
+ }
+
+ "throw an exception when writing to a closed port" in {
+ withEchoConnection { conn =>
+ val buffer = ByteBuffer.allocateDirect(64)
+ conn.close()
+
+ intercept[PortClosedException]{
+ conn.write(buffer)
+ }
+ }
+ }
+
+ }
+
+}