summaryrefslogtreecommitdiff
path: root/Network
diff options
context:
space:
mode:
Diffstat (limited to 'Network')
-rw-r--r--Network/EBus/Layer2.hs94
1 files changed, 27 insertions, 67 deletions
diff --git a/Network/EBus/Layer2.hs b/Network/EBus/Layer2.hs
index c4f1d47..b194ee6 100644
--- a/Network/EBus/Layer2.hs
+++ b/Network/EBus/Layer2.hs
@@ -1,56 +1,10 @@
-module Network.EBus.Layer2 where
+module Network.EBus.Layer2(
+ ebusParserLayer2,
+ EbusPacket) where
-import Control.Applicative
-import Data.Attoparsec
-import Data.Attoparsec.Enumerator (iterParser)
-import Data.Attoparsec.Combinator as C
-import Data.ByteString (ByteString)
-import Data.Enumerator
-import Data.Enumerator.Binary (enumHandle)
+import Control.Applicative ((<|>))
+import Data.Attoparsec (anyWord8, count, skipMany, try, Parser, word8)
import Data.Word (Word8)
-import System.IO (hSetBinaryMode,stdin)
-
--- ebus :: Parser EbusPacket
--- ebus = do{ skipMany1 $ char '\xaa'
--- ; source <- anyChar
--- ; destination <- anyChar
--- ; primaryCommand <- anyChar
--- ; secondaryCommand <- anyChar
--- ; payloadLength <- anyChar
--- ; payload <- count (fromEnum payloadLength) ebusPayload
--- ; followup <-
--- if destination == '\xfe' then
--- -- Broadcast - no further data
--- do{ crc <- anyChar
--- ; syn <- char '\xaa'
--- ; return "broadcast"
--- <|> fail "Failed to parse Broadcast Packet"
--- }
--- else
--- try( -- Master-Master - no further data
--- do{ crc <- anyChar
--- ; ack <- char '\x00' -- ACK OK
--- ; syn <- char '\xaa'
--- ; return "master-master"
--- })
--- <|>
--- try( -- Master Slave
--- do{ crc <- anyChar
--- ; ack <- char '\x00'
--- ; payloadSlaveLength <- anyChar
--- ; payloadSlave <- count (fromEnum payloadSlaveLength) ebusPayload
--- ; crcSlave <- anyChar
--- ; ackSlave <- char '\x00'
--- ; synSlave <- char '\xaa'
--- ; return "master-slave"
--- })
--- <|> fail "Failed to parse Master-Master/Master-Slave Packet"
--- ; return $ EbusPacket
--- source destination
--- primaryCommand secondaryCommand
--- payloadLength followup []
--- }
-
-- | Ebus Layer2 Constants
ebusConstant :: String -> Word8
@@ -75,11 +29,11 @@ data EbusPacket = EbusPacket {
ebusPacketDestination :: Word8,
ebusPacketPrimaryCommand :: Word8,
ebusPacketSecondaryCommand :: Word8,
- ebusPacketPayloadLength :: Word8,
ebusPacketPayload :: [Word8],
ebusPacketPayloadSlave :: Maybe [Word8]
} deriving (Show)
+-- | Ebus Binary Escape Sequences for payload data
parserPayload :: Parser Word8
parserPayload = do{ word8 $ ebusConstant "ESCAPE"
; word8 $ ebusConstant "ESCAPE_ESCAPE"
@@ -91,21 +45,25 @@ parserPayload = do{ word8 $ ebusConstant "ESCAPE"
<|>
anyWord8;
-parser :: Parser EbusPacket
-parser = do{
- C.skipMany $ word8 $ ebusConstant "SYN"
+-- | Parse one Ebus Packet, skips leading SYNs
+ebusParserLayer2 :: Parser EbusPacket
+ebusParserLayer2 = do{
+ skipMany $ word8 $ ebusConstant "SYN"
; source <- anyWord8
; destination <- anyWord8
; primaryCommand <- anyWord8
; secondaryCommand <- anyWord8
; payloadLength <- anyWord8
- ; payload <- C.count (fromIntegral payloadLength) parserPayload
+ ; payload <- count (fromIntegral payloadLength) parserPayload
; followup <-
if destination == 0xfe then
-- Broadcast
do{ crc <- anyWord8
; {- syn -} word8 $ ebusConstant "SYN"
- ; return (EbusBroadcast, crc, Nothing)}
+ ; if True then -- CHECK CRC
+ return $ EbusPacket EbusMasterMaster source destination primaryCommand secondaryCommand payload Nothing
+ else
+ fail "Broadcast: CRC Check failed"}
<|>
fail "Failed to parse Broadcast Paket"
else
@@ -114,25 +72,27 @@ parser = do{
do{ crc <- anyWord8
; {- ack -} word8 $ ebusConstant "ACK"
; {- syn -} word8 $ ebusConstant "SYN"
- ; return (EbusMasterMaster, crc, Nothing)})
+ ; if True then -- CHECK CRC
+ return $ EbusPacket EbusMasterMaster source destination primaryCommand secondaryCommand payload Nothing
+ else
+ fail "Master-Master: CRC Check failed"})
<|>
-- Master Slave
try(
do{ crc <- anyWord8
; {- ack -} word8 $ ebusConstant "ACK"
; payloadSlaveLength <- anyWord8
- ; payloadSlave <- C.count (fromIntegral payloadSlaveLength) parserPayload
+ ; payloadSlave <- count (fromIntegral payloadSlaveLength) parserPayload
; crcSlave <- anyWord8
; {- ackSlave -} word8 $ ebusConstant "ACK"
; {- synSlave -} word8 $ ebusConstant "SYN"
- ; return (EbusMasterSlave, crc, (Just (payloadSlave, crcSlave)))})
+ ; if True then -- Check CRC
+ return $ EbusPacket EbusMasterSlave source destination primaryCommand secondaryCommand payload (Just payloadSlave)
+ else
+ fail "Master-Slave: CRC Check failed"})
+
<|>
fail "Failed to parse Master-Master/Master-Slave Packet"
- ; do {
- if True then --CHECK CRC
- return $ EbusPacket EbusMasterMaster source destination primaryCommand secondaryCommand payloadLength payload (Just [])
- else
- fail "CRC Check failed"}
+ ; return followup
<|> fail "Failed to parse packet"
- }
-
+ } \ No newline at end of file