diff options
Diffstat (limited to 'Network')
-rw-r--r-- | Network/EBus/Layer2.hs | 94 |
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 |