diff options
Diffstat (limited to 'ebus-scala/Main.scala')
-rw-r--r-- | ebus-scala/Main.scala | 152 |
1 files changed, 97 insertions, 55 deletions
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("-")) |