summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ebus-scala/.ensime9
-rw-r--r--ebus-scala/Main.scala152
2 files changed, 106 insertions, 55 deletions
diff --git a/ebus-scala/.ensime b/ebus-scala/.ensime
new file mode 100644
index 0000000..414848a
--- /dev/null
+++ b/ebus-scala/.ensime
@@ -0,0 +1,9 @@
+;; This config was generated using ensime-config-gen. Feel free to customize its contents manually.
+
+(
+
+:project-package "org.xapek.ebus"
+
+:use-sbt t
+
+)
diff --git a/ebus-scala/Main.scala b/ebus-scala/Main.scala
index 8444f37..e91de0a 100644
--- a/ebus-scala/Main.scala
+++ b/ebus-scala/Main.scala
@@ -6,7 +6,7 @@ import scala.xml.{XML, Node, NodeSeq}
class EbusDefinition(val ebusXmlFile: String) {
val xml = XML.loadFile(ebusXmlFile)
- def packetFromCommandId(primaryCommand: Char, secondaryCommand: Char): NodeSeq = {
+ def packetFromCommandId(primaryCommand: Int, secondaryCommand: Int): NodeSeq = {
val packet = (xml \ "packets" \ "packet").filter(n =>
n.attribute("primary").get.text.toInt == primaryCommand &&
n.attribute("secondary").get.text.toInt == secondaryCommand)
@@ -36,13 +36,14 @@ object EbusField {
}
}
-class EbusL2Packet(val source: Char,
- val destination: Char,
- val primaryCommand: Char,
- val secondaryCommand: Char,
- val payloadLength: Char,
- val payload: List[Char],
- val crc: Char,
+
+class EbusL2Packet(val source: Int,
+ val destination: Int,
+ val primaryCommand: Int,
+ val secondaryCommand: Int,
+ val payloadLength: Int,
+ val payload: List[Int],
+ val crc: Int,
val rawLength: Int) {
val length = 6 + payload.size
@@ -65,7 +66,7 @@ class EbusL2Packet(val source: Char,
*
* Generatorpol. 11001101
*/
- def calcCrc: Char = {
+ def calcCrc: Int = {
//val foo = payload.reduce((a, b) => ((a.intValue + b.intValue) % 256).toChar)
//val sum = destination + primaryCommand + secondaryCommand + payloadLength + foo
@@ -74,6 +75,8 @@ class EbusL2Packet(val source: Char,
}
}
+class FakePacket(val length : Int);
+
object EbusL2Packet {
/**
* Wird von {@link EbusReader} mit einer Streamposition aufgerufen.
@@ -82,57 +85,73 @@ object EbusL2Packet {
* Im Erfolgsfall wird eine EbusL2Packet-Instanz als Option zurückgegen,
* sonst None
*/
- def apply(stream: Stream[Int]): Option[EbusL2Packet] = {
+ def apply(stream: Stream[Int]): Option[Any] = {
try {
var rawLength = 0
- val source = stream.apply(0).toChar
- val destination = stream.apply(1).toChar
- val primaryCommand = stream.apply(2).toChar
- val secondaryCommand = stream.apply(3).toChar
- val payloadLength = stream.apply(4).toChar
+ val source = stream(0)
+ val destination = stream(1)
+ val primaryCommand = stream(2)
+ val secondaryCommand = stream(3)
+ val payloadLength = stream(4)
rawLength = 5
+ println("source=0x%02x destination=0x%02x primaryCommand=0x%02x secondaryCommand=0x%02x payloadLength=0x%02x".format(
+ source, destination, primaryCommand, secondaryCommand, payloadLength))
+
// Maximale payload Grösse = 16 Byte
if (payloadLength > 16) {
- println("Erkannte payload Groesse zu gross: %d".format(payloadLength.toInt))
+ println("Erkannte payload Groesse zu gross: %d".format(payloadLength))
return None
+ } else {
+ println("Payload = " + payloadLength);
}
- var payload = List[Char]()
+
+ var payload = List[Int]()
for (i <- 0 until payloadLength) {
- var it = stream.apply(rawLength).toChar
+ var it = stream(rawLength)
rawLength += 1
// Handle escape sequences
// "eBUS Spezifikation Physikalische Schicht – OSI 1
// Verbindungsschicht – OSI 2 V.1.3.1" auf Seite 8
- if (it == 0xa9.toChar) {
- val itNext = stream.apply(rawLength).toChar
+ if (it == 0xa9) {
+ val itNext = stream.apply(rawLength)
rawLength += 1
- if (itNext == 0x00.toChar) {
- it = 0xa9.toChar
- } else if (itNext == 0x01.toChar) {
- it = 0xaa.toChar
+ if (itNext == 0x00) {
+ it = 0xa9
+ } else if (itNext == 0x01) {
+ it = 0xaa
} else {
App.println("Ignore escape sequence 0xa9 0x%02x".format(itNext))
rawLength -= 1
}
}
payload = payload :+ it
+ println("Payload: " + payload.map((it) => "0x%02x".format(it)).foldLeft(""){(s1,s2) => s1+","+s2})
}
- val crc = stream.apply(5 + payloadLength).toChar
- val ack = stream.apply(6 + payloadLength).toChar
- if (ack != 0x00.toChar) {
- println("Fehlerhaftes ACK")
- return None
+ val crc = stream.apply(rawLength + 0)
+ println("CRC=0x%x".format(crc))
+ val ack = stream.apply(rawLength + 1)
+ println("ACK=0x%02x".format(ack))
+ if (destination == 0xfe) {
+ // Broadcast
+ if (ack != 0xaa) {
+ println("ACK Bei Broadcast Paket unerwertet nicht 0xaa sondern 0x%02x".format(ack))
+ }
+ } else {
+ if (ack != 0x00) {
+ println("ACK unerwartet nicht 0x00 sondern 0x%02x".format(ack))
+ }
}
- rawLength += 2
-
- if (stream.apply(6+payloadLength).toChar == 0xaa.toChar) {
+ rawLength += 0
+
+ if (stream.apply(rawLength + 4) == 0xaa) {
// Broadcast oder Master-Master
return Some(new EbusL2Packet(source, destination,
primaryCommand, secondaryCommand,
payloadLength, payload, crc, rawLength))
} else {
// Master-Slave
+ return Some(new FakePacket(rawLength))
}
} catch {
case exc: IndexOutOfBoundsException => {
@@ -144,27 +163,34 @@ object EbusL2Packet {
}
}
+
+
object EbusReader {
def apply(streamI: Stream[Int]) : EbusL2Packet = {
var stream = streamI
while (true) {
+ // Synchronisiere
+ while (stream(0) != 0xaa && stream(1) != 0xaa) {
+ stream = stream.drop(1)
+ }
// Überspringe Synchronisationszeichen
- //stream = stream.dropWhile(v => v.toChar == 0xaa.toChar)
- // Überspringe solange nicht mindestens 6 Zeichen ohne 0xaa vorkommen
- while (stream.take(6).filter({v :Int => v.toChar == 0xaa.toChar}).size > 0) {
-// println("skip")
+ while (stream(0).toChar == 0xaa) {
stream = stream.drop(1)
}
EbusL2Packet(stream) match {
- case Some(packet) => {
+ case Some(packet : EbusL2Packet) => {
return packet
}
+ case Some(packet : FakePacket) => {
+ println("Fake paket - forward %d bytes".format(packet.length))
+ stream = stream.drop(packet.length)
+ }
case None => {
// Es konnte kein Paket eingelesen werden
// verschiebe die Anfangsposition um ein Byte
+ App.println("Paket konnte nicht gelesen werden, verschiebe start um 1 byte")
stream = stream.drop(1)
- App.println("skip 1 byte")
}
}
}
@@ -173,8 +199,7 @@ object EbusReader {
}
object EbusL7Packet {
- def apply(l2packet : EbusL2Packet, ebusDefinition : EbusDefinition)
- : Option[EbusL7Packet] = {
+ def apply(l2packet : EbusL2Packet, ebusDefinition : EbusDefinition) : Option[EbusL7Packet] = {
val packetDef = ebusDefinition.packetFromCommandId(
l2packet.primaryCommand, l2packet.secondaryCommand)
@@ -185,6 +210,8 @@ object EbusL7Packet {
}
}
+
+
class EbusL7Packet(val l2packet : EbusL2Packet, val packetDefinition : NodeSeq) {
def name : String = {
packetDefinition.map({p :Node => p.attributes.apply("name")}).mkString
@@ -223,10 +250,10 @@ object App {
while (true) {
val v = s.getInputStream.read
if (v == -1) {
- println("Fehler: las -1")
+ println("Fehler: read == -1")
System.exit(1)
}
- print(v.toChar)
+ System.out.write(v)
}
} else {
println("Missing Arguments")
@@ -245,29 +272,44 @@ object App {
throw new EOFException("End of File reached (read returned -1)")
value
})
+
var stream: Stream[Int] = Stream.continually(read())
while (true) {
- EbusReader(stream) match {
- case l2packet : EbusL2Packet => {
- EbusL7Packet(l2packet, ebusDefinition) match {
- case Some(l7packet) => {
+ try {
+ EbusReader(stream) match {
+ case l2packet : EbusL2Packet => {
+ println("Read l2 packaet: " + l2packet);
+ /*
+ EbusL7Packet(l2packet, ebusDefinition) match {
+ case Some(l7packet) => {
println(l7packet)
- }
+ }
case _ => {}
- }
- println(l2packet)
- // Spule den Stream zur naechstmoeglichen Paketposition
- stream = stream.drop(l2packet.rawLength)
- }
- case null => {
- println("null")
+ }
+ */
+ println(l2packet)
+
+ // Spule den Stream zur naechstmoeglichen Paketposition
+ stream = stream.drop(l2packet.rawLength)
+ }
+ case null => {
+ println("null")
System.exit(1)
- }
+ }
+ }
+ } catch {
+ case exc : EOFException => {
+ println("EOF")
+ source.close
+ exit(0)
+ }
}
}
println("exiting")
source.close
}
}
+
+App.main(Array("-"))