aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2013-07-19 20:44:59 +0200
committerJakob Odersky <jodersky@gmail.com>2013-07-19 20:44:59 +0200
commit09eb7f7803e6935ea6e8f694d17fa1c245eda39d (patch)
tree38a8caea46822985c7d574e0e6bad3e51ecc0bf2
parent3356df969fbfdd80c3e6e8fd7390c93f630f590f (diff)
downloadakka-serial-09eb7f7803e6935ea6e8f694d17fa1c245eda39d.tar.gz
akka-serial-09eb7f7803e6935ea6e8f694d17fa1c245eda39d.tar.bz2
akka-serial-09eb7f7803e6935ea6e8f694d17fa1c245eda39d.zip
add some documentation
-rw-r--r--flow-main/src/main/scala/com/github/jodersky/flow/Parity.scala1
-rw-r--r--flow-main/src/main/scala/com/github/jodersky/flow/Serial.scala26
-rw-r--r--flow-main/src/main/scala/com/github/jodersky/flow/SerialExt.scala1
-rw-r--r--flow-main/src/main/scala/com/github/jodersky/flow/SerialManager.scala16
-rw-r--r--flow-main/src/main/scala/com/github/jodersky/flow/SerialOperator.scala14
-rw-r--r--flow-main/src/main/scala/com/github/jodersky/flow/exceptions.scala11
-rw-r--r--flow-main/src/main/scala/com/github/jodersky/flow/internal/InternalSerial.scala8
7 files changed, 47 insertions, 30 deletions
diff --git a/flow-main/src/main/scala/com/github/jodersky/flow/Parity.scala b/flow-main/src/main/scala/com/github/jodersky/flow/Parity.scala
index 9a0d3ac..9bf52a6 100644
--- a/flow-main/src/main/scala/com/github/jodersky/flow/Parity.scala
+++ b/flow-main/src/main/scala/com/github/jodersky/flow/Parity.scala
@@ -1,5 +1,6 @@
package com.github.jodersky.flow
+/** Specifies available parities used in serial communication. */
object Parity extends Enumeration {
type Parity = Value
val None = Value(0)
diff --git a/flow-main/src/main/scala/com/github/jodersky/flow/Serial.scala b/flow-main/src/main/scala/com/github/jodersky/flow/Serial.scala
index adcfb06..5c34487 100644
--- a/flow-main/src/main/scala/com/github/jodersky/flow/Serial.scala
+++ b/flow-main/src/main/scala/com/github/jodersky/flow/Serial.scala
@@ -4,18 +4,22 @@ import akka.actor.ActorRef
import akka.actor.ExtensionKey
import akka.util.ByteString
-/** Defines messages used by serial IO layer. */
+/** Defines messages used by flow's serial IO layer. */
object Serial extends ExtensionKey[SerialExt] {
- /** A message extending this trait is to be viewed as a command, that is an outbound message. */
+ /** A message extending this trait is to be viewed as a command, that is an out-bound message. */
trait Command
- /** A message extending this trait is to be viewed as an event, that is an inbound message. */
+ /** A message extending this trait is to be viewed as an event, that is an in-bound message. */
trait Event
/**
- * Open a new serial port. Send this command to the serial manager to request the opening of a new port.
- * @param handler actor that will receive events from the specified serial port
+ * Open a new serial port. Send this command to the serial manager to request the opening of a serial port. The manager will
+ * attempt to open a serial port with the specified parameters and, if successful, create a `SerialOperator` actor associated to the port.
+ * The operator actor acts as an intermediate to the underlying native serial port, dealing with threading issues and the such. It will send any events
+ * to the given `handler` actorref.
+ * The manager will respond with an `Opened` in case the port was successfully opened, or `OpenFailed` in case of failure.
+ * @param handler actor that will receive events from the specified serial port (via an operator)
* @param port name of serial port
* @param baud baud rate to use with serial port
* @param characterSize size of a character of the data sent through the serial port
@@ -25,7 +29,7 @@ object Serial extends ExtensionKey[SerialExt] {
case class Open(handler: ActorRef, port: String, baud: Int, characterSize: Int = 8, twoStopBits: Boolean = false, parity: Parity.Parity = Parity.None) extends Command
/**
- * Event sent from a port operator, indicating that a serial port was successfully opened.
+ * Event sent from a port operator, indicating that a serial port was successfully opened. The sender of this message is the operator associated to the given serial port.
* @param port name of serial port
* @param baud baud rate to use with serial port
* @param characterSize size of a character of the data sent through the serial port
@@ -35,7 +39,7 @@ object Serial extends ExtensionKey[SerialExt] {
case class Opened(port: String, baud: Int, characterSize: Int, twoStopBits: Boolean, parity: Parity.Parity) extends Event
/**
- * Event sent from manager, indicating that a serial port could not be opened.
+ * Event sent from the serial manager, indicating that a serial port could not be opened.
* @param reason throwable containing reason to why the requested port could not be opened
* @param port name of serial port
* @param baud baud rate to use with serial port
@@ -52,7 +56,7 @@ object Serial extends ExtensionKey[SerialExt] {
case class Received(data: ByteString) extends Event
/**
- * Command sent to operator, requesting the writing of data to the operator's serial port. Optionally request acknowledgment when data is written.
+ * Write data to serial port. Send this command to an operator to write the given data to its associated serial port.
* @param data data to be written to port
* @param ack set to true to receive acknowledgment on successful write
* @see Wrote
@@ -61,16 +65,16 @@ object Serial extends ExtensionKey[SerialExt] {
/**
* Event sent by operator, acknowledging that data was written to its serial port. Note that such an acknowledgment only guarantees that data has been written
- * to the serial port's output buffer (managed by the operating system), the actual reception of the data on the remote device is not guaranteed.
+ * to the serial port's output buffer (managed by the operating system), the actual sending of the data to the remote device is not guaranteed.
* @param data the data that has been written
*/
case class Wrote(data: ByteString) extends Event
- /** Command sent to operator to request the closing of its serial port. */
+ /** Request closing of port. Send this command to an operator to close its associated port. */
case object Close extends Command
/**
- * Event sent from operator, indicating that its port has been closed. An optional reason explains the error that caused the closing of the port.
+ * Event sent from operator, indicating that its port has been closed. An optional reason explains the error (if any) that caused the closing of the port.
* @param reason Some(exception) explaining the exception that caused the closing, None if the port was closed by sending a `Close` message.
*/
case class Closed(reason: Option[Exception]) extends Event
diff --git a/flow-main/src/main/scala/com/github/jodersky/flow/SerialExt.scala b/flow-main/src/main/scala/com/github/jodersky/flow/SerialExt.scala
index 080ddd3..826a4e9 100644
--- a/flow-main/src/main/scala/com/github/jodersky/flow/SerialExt.scala
+++ b/flow-main/src/main/scala/com/github/jodersky/flow/SerialExt.scala
@@ -4,6 +4,7 @@ import akka.actor.ExtendedActorSystem
import akka.actor.Props
import akka.io.IO
+/** Provides the serial IO manager. */
class SerialExt(system: ExtendedActorSystem) extends IO.Extension {
lazy val manager = system.actorOf(Props(classOf[SerialManager]), name = "IO-SERIAL")
} \ No newline at end of file
diff --git a/flow-main/src/main/scala/com/github/jodersky/flow/SerialManager.scala b/flow-main/src/main/scala/com/github/jodersky/flow/SerialManager.scala
index 1f32ecd..993ebda 100644
--- a/flow-main/src/main/scala/com/github/jodersky/flow/SerialManager.scala
+++ b/flow-main/src/main/scala/com/github/jodersky/flow/SerialManager.scala
@@ -18,6 +18,10 @@ import akka.actor.SupervisorStrategy.Escalate
import akka.actor.SupervisorStrategy.Stop
import akka.actor.actorRef2Scala
+/**
+ * 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.
+ */
class SerialManager extends Actor with ActorLogging {
import SerialManager._
import context._
@@ -30,16 +34,8 @@ class SerialManager extends Actor with ActorLogging {
def receive = {
case Open(handler, port, baud, cs, tsb, parity) => Try { InternalSerial.open(port, baud, cs, tsb, parity.id) } match {
- case Failure(t) => {
- log.debug(s"failed to open low serial port at ${port}, baud ${baud}, reason: " + t.getMessage())
- handler ! OpenFailed(t, port, baud, cs, tsb, parity)
- }
-
- case Success(serial) => {
- log.debug(s"opened low-level serial port at ${port}, baud ${baud}")
- context.actorOf(Props(classOf[SerialOperator], handler, serial), name = escapePortString(port))
- }
-
+ case Failure(t) => handler ! OpenFailed(t, port, baud, cs, tsb, parity)
+ case Success(serial) => context.actorOf(Props(classOf[SerialOperator], handler, serial), name = escapePortString(port))
}
}
diff --git a/flow-main/src/main/scala/com/github/jodersky/flow/SerialOperator.scala b/flow-main/src/main/scala/com/github/jodersky/flow/SerialOperator.scala
index 4e46343..194abd3 100644
--- a/flow-main/src/main/scala/com/github/jodersky/flow/SerialOperator.scala
+++ b/flow-main/src/main/scala/com/github/jodersky/flow/SerialOperator.scala
@@ -17,12 +17,12 @@ import akka.actor.Terminated
import akka.actor.actorRef2Scala
import akka.util.ByteString
+/** Operator associated to an open serial port. All communication with a port is done via an operator. Operators are created though the serial manager. */
class SerialOperator(handler: ActorRef, serial: InternalSerial) extends Actor with ActorLogging {
+ import SerialOperator._
import context._
- case class ReadException(ex: Exception)
-
- object Reader extends Thread {
+ private object Reader extends Thread {
def enterReadLoop() = {
var continueReading = true
@@ -47,12 +47,12 @@ class SerialOperator(handler: ActorRef, serial: InternalSerial) extends Actor wi
}
def name = this.getName()
-
+
override def run() {
this.setName("flow-reader " + serial.port)
enterReadLoop()
}
-
+
}
override def preStart() = {
@@ -94,4 +94,8 @@ class SerialOperator(handler: ActorRef, serial: InternalSerial) extends Actor wi
}
+}
+
+object SerialOperator {
+ private case class ReadException(ex: Exception)
} \ No newline at end of file
diff --git a/flow-main/src/main/scala/com/github/jodersky/flow/exceptions.scala b/flow-main/src/main/scala/com/github/jodersky/flow/exceptions.scala
index f91aa1b..5923ba6 100644
--- a/flow-main/src/main/scala/com/github/jodersky/flow/exceptions.scala
+++ b/flow-main/src/main/scala/com/github/jodersky/flow/exceptions.scala
@@ -2,9 +2,20 @@ package com.github.jodersky.flow
import java.io.IOException
+/** The requested port could not be found. */
class NoSuchPortException(message: String) extends Exception(message)
+
+/** The requested port is in use by someone else. */
class PortInUseException(message: String) extends Exception(message)
+
+/** Permissions are not sufficient to open a serial port. */
class AccessDeniedException(message: String) extends Exception(message)
+
+/** The settings specified are invalid. */
class InvalidSettingsException(message: String) extends Exception(message)
+
+/** A blocking operation on a port was interrupted, most likely indicating that the port is closing. */
class PortInterruptedException(message: String) extends Exception(message)
+
+/** The specified port has been closed. */
class PortClosedException(message: String) extends Exception(message) \ No newline at end of file
diff --git a/flow-main/src/main/scala/com/github/jodersky/flow/internal/InternalSerial.scala b/flow-main/src/main/scala/com/github/jodersky/flow/internal/InternalSerial.scala
index c7752b2..e69f91a 100644
--- a/flow-main/src/main/scala/com/github/jodersky/flow/internal/InternalSerial.scala
+++ b/flow-main/src/main/scala/com/github/jodersky/flow/internal/InternalSerial.scala
@@ -4,7 +4,7 @@ import java.io.IOException
import com.github.jodersky.flow._
import java.util.concurrent.atomic.AtomicBoolean
-/** Wraps NativeSerial in a more object-oriented style, still quite low level. */
+/** Wraps `NativeSerial` in a more object-oriented style, still quite low level. */
class InternalSerial private (val port: String, val baud: Int, val characterSize: Int, val twoStopBits: Boolean, val parity: Int, private val pointer: Long) {
import InternalSerial._
@@ -17,7 +17,7 @@ class InternalSerial private (val port: String, val baud: Int, val characterSize
if (!closed.get()) {
closed.set(true)
except(NativeSerial.interrupt(pointer), port)
- if (writing.get()) wait() // if reading, wait for read to finish
+ if (writing.get()) wait()
if (reading.get()) wait()
except(NativeSerial.close(pointer), port)
}
@@ -36,7 +36,7 @@ class InternalSerial private (val port: String, val baud: Int, val characterSize
} finally {
synchronized {
reading.set(false)
- if (closed.get) notify(); //read was interrupted by close
+ if (closed.get) notify()
}
}
} else {
@@ -86,7 +86,7 @@ object InternalSerial {
new InternalSerial(port, baud, characterSize, twoStopBits, parity, pointer(0))
}
- /** Set debugging for all serial connections. Debugging results in printing extra messages (from the native library) in case of errors. */
+ /** Set debugging for all serial connections. Debugging results in printing extra messages from the native library in case of errors. */
def debug(value: Boolean) = NativeSerial.debug(value)
} \ No newline at end of file