Beispiel #1
0
class HDLCMsgParser(MsgParser):
    """This class is responsible for taking raw serial bytes and searching them for valid SLIP messages.

    Attributes:
        crc: CRC calculator.
        msg: Parsed HDLC message with HDLC bytes extracted.
    """
    def __init__(self, config):
        MsgParser.__init__(self, config)

        self.crc = crcmod.mkCrcFun(0x11021,
                                   initCrc=0xFFFF,
                                   xorOut=0,
                                   rev=False)  # CRC-16
        self.crcLength = 2
        self.msg = HDLCMsg(2058)

    def parseSerialMsg(self, msgBytes, msgStart):
        """Searches raw serial data for HDLC messages and then validates message integrity by comparing a computed CRC to the CRC found in the message.  Valid messages are then stored for processing.
        
        Args:
            msgBytes: Raw serial data to be parsed.
            msgStart: Start location to begin looking for serial message in msgBytes data array.
        """
        if len(msgBytes) > 0:
            # Process serial message
            self.msg.decodeMsg(msgBytes, msgStart)
            if self.msg.msgFound == True:  # Message start found
                if self.msg.msgEnd != -1:  # entire msg found
                    # Check msg CRC
                    crc = self.crc(self.msg.msg[:-self.crcLength])
                    if self.msg.msg[-self.crcLength:] == packData(
                            crc,
                            self.crcLength):  # CRC matches - valid message
                        #print("CRC matches")
                        self.parsedMsgs.append(self.msg.msg[:-self.crcLength])
                    return self.msg.msgEnd

                else:  # partial msg found
                    pass

            else:  # No message found
                pass

            return len(
                msgBytes)  # all bytes parsed so return length of input message

        else:
            return 0

    def encodeMsg(self, msgBytes):
        if msgBytes:  # Add CRC
            crc = self.crc(msgBytes)
            msgBytes = msgBytes + packData(crc, self.crcLength)
            self.msg.encodeMsg(msgBytes)
            return self.msg.hdlc

        return msgBytes
class TestHDLCMsg:
    def setup_method(self, method):
        self.hdlcMsg = HDLCMsg(256)
        pass

    def test_encodeMsg(self):
        """Test encodeMsg method of HDLCMsg."""
        self.hdlcMsg.encodeMsg(testMsg)
        assert (self.hdlcMsg.hdlc == truthHDLCMsg)

    def test_decodeMsg(self):
        """Test decodeMsg method of HDLCMsg. Will also test decodeMsgContents."""
        # Test clearing of partial message
        self.hdlcMsg = HDLCMsg(256)
        self.hdlcMsg.msgFound = True
        self.hdlcMsg.msg = b'123'
        self.hdlcMsg.msgEnd = 5
        self.hdlcMsg.msgLength = 10
        self.hdlcMsg.decodeMsg(b'12345', 0)
        assert (self.hdlcMsg.msgFound == False)
        assert (self.hdlcMsg.msg == b'')
        assert (self.hdlcMsg.msgLength == 0)
        assert (self.hdlcMsg.msgEnd == -1)

        # Test decoding entire message contents
        self.hdlcMsg = HDLCMsg(256)
        self.hdlcMsg.encodeMsg(testMsg)
        assert (self.hdlcMsg.msgEnd == -1)
        self.hdlcMsg.decodeMsg(self.hdlcMsg.hdlc, 0)
        assert (self.hdlcMsg.msg == testMsg)  # verify message contents
        assert (self.hdlcMsg.msgLength == len(testMsg)
                )  # verify message length
        assert (self.hdlcMsg.msgEnd == len(truthHDLCMsg) - 1
                )  # verify message end location

        # Test decoding partial message
        self.hdlcMsg = HDLCMsg(256)
        self.hdlcMsg.encodeMsg(testMsg)
        self.hdlcMsg.decodeMsg(self.hdlcMsg.hdlc[:-1], 0)
        assert (self.hdlcMsg.msgEnd == -1)  # message end not found
        self.hdlcMsg.decodeMsg(self.hdlcMsg.hdlc[-1:],
                               0)  # parse remaining message
        assert (self.hdlcMsg.msg == testMsg)  # verify message contents
        assert (self.hdlcMsg.msgLength == len(testMsg)
                )  # verify message length

        # Test decoding partial message in middle of escape sequence
        self.hdlcMsg = HDLCMsg(256)
        msg = b'123' + HDLC_ESC + b'456'
        self.hdlcMsg.encodeMsg(msg)
        self.hdlcMsg.decodeMsg(self.hdlcMsg.hdlc[0:4],
                               0)  # length prior to escape sequence
        msgLen = self.hdlcMsg.msgLength
        self.hdlcMsg.decodeMsg(self.hdlcMsg.hdlc[4:5], 0)  # parse HDLC_ESC
        assert (
            msgLen == self.hdlcMsg.msgLength
        )  # message length should be unchanged until entire escape sequence read
        self.hdlcMsg.decodeMsg(self.hdlcMsg.hdlc[5:6],
                               0)  # read entire escape sequence
        assert (self.hdlcMsg.msgLength == msgLen + 1)
        self.hdlcMsg.decodeMsg(
            self.hdlcMsg.hdlc[6:],
            0)  # test successful parsing of remainder of message
        assert (self.hdlcMsg.msg == msg)  # verify message contents
        assert (self.hdlcMsg.msgLength == len(msg))  # verify message length
Beispiel #3
0
class TestHDLCMsg:
    def setup_method(self, method):
        self.hdlcMsg = HDLCMsg(256)
        self.truthCRC = packData(self.hdlcMsg.crc(testMsg),
                                 self.hdlcMsg.crcLength)
        pass

    def test_encodeMsg(self):
        """Test encodeMsg method of HDLCMsg."""
        self.hdlcMsg.encodeMsg(testMsg)
        #        assert(self.hdlcMsg.encoded == truthHDLCMsg + self.truthCRC)
        minLength = len(truthHDLCMsg + self.truthCRC)
        assert (
            len(self.hdlcMsg.encoded) >= minLength
        )  # length should be at least length of encoded raw bytes plus crc (could be longer if CRC included reserved bytes)
        if (len(self.hdlcMsg.encoded) == minLength
            ):  # no reserved bytes in CRC
            assert (self.hdlcMsg.encoded == (truthHDLCMsg[:-1] +
                                             self.truthCRC +
                                             truthHDLCMsg[-1:]))
        else:  # CRC contained reserved bytes
            assert (self.hdlcMsg.encoded[:-(self.hdlcMsg.crcLength +
                                            1)] == truthHDLCMsg[:-1]
                    )  # skip over CRC
            assert (self.hdlcMsg.encoded[-1] == truthHDLCMsg[-1])

    def test_decodeMsg(self):
        """Test decodeMsg method of HDLCMsg. Will also test decodeMsgContents."""
        # Test clearing of partial message
        self.hdlcMsg = HDLCMsg(256)
        self.hdlcMsg.msgFound = True
        self.hdlcMsg.msg = b'123'
        self.hdlcMsg.msgEnd = 5
        self.hdlcMsg.msgLength = 10
        self.hdlcMsg.decodeMsg(b'12345', 0)
        assert (self.hdlcMsg.msgFound == False)
        assert (self.hdlcMsg.msg == b'')
        assert (self.hdlcMsg.msgLength == 0)
        assert (self.hdlcMsg.msgEnd == -1)

    def test_parseMsg(self):
        """Test parseMsg method of HLDCMsg."""

        self.hdlcMsg.encodeMsg(testMsg)  # encode messaging for parsing

        # Parse message from encoded message
        parsedMsg = self.hdlcMsg.parseMsg(self.hdlcMsg.encoded, 0)
        assert (parsedMsg == testMsg)

        # Parse message with surrounding bytes
        inputMsg = b'9876' + self.hdlcMsg.encoded + b'1234'
        parsedMsg = self.hdlcMsg.parseMsg(inputMsg, 0)
        assert (parsedMsg == testMsg)

        # Parse partial message
        self.hdlcMsg = HDLCMsg(256)
        self.hdlcMsg.encodeMsg(testMsg)
        self.hdlcMsg.parseMsg(self.hdlcMsg.encoded[:-1], 0)
        assert (self.hdlcMsg.msgEnd == -1)  # message end not found
        parsedMsg = self.hdlcMsg.parseMsg(self.hdlcMsg.encoded[-1:],
                                          0)  # parse remaining message
        assert (parsedMsg == testMsg)  # verify message contents
        assert (len(parsedMsg) == len(testMsg))  # verify message length

        # Test parsing partial message in middle of escape sequence
        self.hdlcMsg = HDLCMsg(256)
        msg = b'123' + HDLC_ESC + b'456'
        self.hdlcMsg.encodeMsg(msg)
        self.hdlcMsg.parseMsg(self.hdlcMsg.encoded[0:4],
                              0)  # length prior to escape sequence
        msgLen = self.hdlcMsg.msgLength
        self.hdlcMsg.parseMsg(self.hdlcMsg.encoded[4:5], 0)  # parse HDLC_ESC
        assert (
            msgLen == self.hdlcMsg.msgLength
        )  # message length should be unchanged until entire escape sequence read
        self.hdlcMsg.parseMsg(self.hdlcMsg.encoded[5:6],
                              0)  # read entire escape sequence
        assert (self.hdlcMsg.msgLength == msgLen + 1)
        parsedMsg = self.hdlcMsg.parseMsg(
            self.hdlcMsg.encoded[6:],
            0)  # test successful parsing of remainder of message
        assert (parsedMsg == msg)  # verify message contents
        assert (len(parsedMsg) == len(msg))  # verify message length