Ejemplo n.º 1
0
class SLIPMsgParser(MsgParser):
    """This class is responsible for taking raw serial bytes and searching them for valid SLIP messages.

    Attributes:
        crc: CRC calculator.
        msg: Parsed SLIP message with SLIP bytes extracted.
        parsedMsg: Valid serial message stored in this variable upon confirmation of valid CRC.
    """
    def __init__(self, config):
        MsgParser.__init__(self, config)

        self.crc = crcmod.mkCrcFun(0x107, initCrc=0, xorOut=0,
                                   rev=False)  # CRC-8
        self.crcLength = 1
        self.msg = SLIPMsg(256)

    def parseSerialMsg(self, msgBytes, msgStart):
        """Searches raw serial data for SLIP 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.slip

        return msgBytes
Ejemplo n.º 2
0
    def test_bufferTxMsg(self):
        """Test bufferTxMsg method of SerialComm."""
        # Create message parser for testing purposes
        msg = SLIPMsg(self.nodeParams.config.parseMsgMax)
        self.serialComm.msgParser.msg = msg

        # Test that encoded message buffered
        msgBytes = b'ZYXWVU'
        assert (len(self.serialComm.radio.txBuffer) == 0
                )  # confirm empty tx buffer
        self.serialComm.bufferTxMsg(msgBytes)
        encoder = SLIPMsg(256)
        encoder.encodeMsg(msgBytes)
        truthMsg = encoder.encoded
        assert (self.serialComm.radio.txBuffer == truthMsg
                )  # confirm encoded message placed in tx buffer
Ejemplo n.º 3
0
class TestSLIPMsg:
    
    def setup_method(self, method):
        self.slipMsg = SLIPMsg(256)
        self.truthCRC = packData(self.slipMsg.crc(testMsg), self.slipMsg.crcLength)
        pass        
    
    def test_encodeMsg(self):
        """Test encodeMsg method of SLIPMsg."""
        self.slipMsg.encodeMsg(testMsg)
        minLength = len(truthSLIPMsg + self.truthCRC)
        assert(len(self.slipMsg.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.slipMsg.encoded) == minLength): # no reserved bytes in CRC
            assert(self.slipMsg.encoded == truthSLIPMsg[:-1] + self.truthCRC + truthSLIPMsg[-1:])
        else: # CRC contained reserved bytes:
            assert(self.slipMsg.encoded[:-(self.slipMsg.crcLength+1)] == truthSLIPMsg[:-1]) # skip over CRC
        assert(self.slipMsg.encoded[-1] == truthSLIPMsg[-1])
    
    def test_parseMsg(self):
        """Test parseMsg method of SLIPMsg."""
        
        self.slipMsg.encodeMsg(testMsg) # encode messaging for parsing
        
        # Parse message from encoded message
        parsedMsg = self.slipMsg.parseMsg(self.slipMsg.encoded, 0)
        assert(parsedMsg == testMsg)

        # Parse message with surrounding bytes
        inputMsg = b'9876' + self.slipMsg.encoded + b'1234'
        parsedMsg = self.slipMsg.parseMsg(inputMsg, 0)
        assert(parsedMsg == testMsg)
        
        # Parse partial message    
        self.slipMsg = SLIPMsg(256)
        self.slipMsg.encodeMsg(testMsg)
        self.slipMsg.parseMsg(self.slipMsg.encoded[:-1], 0)
        assert(self.slipMsg.msgEnd == -1) # message end not found
        parsedMsg = self.slipMsg.parseMsg(self.slipMsg.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.slipMsg = SLIPMsg(256)
        msg = b'123' + SLIP_ESC + b'456'
        self.slipMsg.encodeMsg(msg)
        self.slipMsg.parseMsg(self.slipMsg.encoded[0:4], 0) # length prior to escape sequence
        msgLen = self.slipMsg.msgLength
        self.slipMsg.parseMsg(self.slipMsg.encoded[4:5],0) # parse SLIP_ESC
        assert(msgLen == self.slipMsg.msgLength) # message length should be unchanged until entire escape sequence read
        self.slipMsg.parseMsg(self.slipMsg.encoded[5:6], 0) # read entire escape sequence
        assert(self.slipMsg.msgLength == msgLen + 1)
        parsedMsg = self.slipMsg.parseMsg(self.slipMsg.encoded[6:], 0) # test successful parsing of remainder of message
        assert(parsedMsg == msg) # verify message contents
        assert(len(parsedMsg) == len(msg)) # verify message length
Ejemplo n.º 4
0
    def test_parseSerialMsg(self):
        """Test parseSerialMessage method of SLIPMsgParser."""
        # Check rejection of message with invalid CRC
        self.msgParser.parseSerialMsg(truthSLIPMsg, 0)
        assert (self.msgParser.msg.msgFound == True)  # slip msg found
        assert (self.msgParser.msg.msgEnd != 1)  # message end found
        assert (self.msgParser.parsedMsgs == [])  # message rejected

        # Check acceptance of message with valid CRC
        crc = self.msgParser.msg.crc(testMsg)
        slipMsg = SLIPMsg(256)
        slipMsg.encodeMsg(testMsg)
        self.msgParser.parseSerialMsg(slipMsg.encoded, 0)
        assert (self.msgParser.msg.msgFound == True)  # slip msg found
        assert (self.msgParser.msg.msgEnd != 1)  # message end found
        assert (self.msgParser.parsedMsgs[0] == testMsg)  # message accepted

        # Check that proper message end position is returned
        self.msgParser.parsedMsgs = []
        paddedMsg = slipMsg.encoded + b'989898'
        msgEnd = self.msgParser.parseSerialMsg(paddedMsg, 0)
        assert (self.msgParser.parsedMsgs[0] == testMsg)
        assert (msgEnd == len(slipMsg.encoded) - 1)
Ejemplo n.º 5
0
class TestSLIPMsg:
    def setup_method(self, method):
        self.slipMsg = SLIPMsg(256)
        pass

    def test_encodeMsg(self):
        """Test encodeMsg method of SLIPMsg."""
        self.slipMsg.encodeMsg(testMsg)
        assert (self.slipMsg.slip == truthSLIPMsg)
        pass

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

        # Test decoding entire message contents
        self.slipMsg = SLIPMsg(256)
        self.slipMsg.encodeMsg(testMsg)
        assert (self.slipMsg.msgEnd == -1)
        self.slipMsg.decodeMsg(self.slipMsg.slip, 0)
        assert (self.slipMsg.msg == testMsg)  # verify message contents
        assert (self.slipMsg.msgLength == len(testMsg)
                )  # verify message length
        assert (self.slipMsg.msgEnd == len(truthSLIPMsg) - 1
                )  # verify message end location

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

        # Test decoding partial message in middle of escape sequence
        self.slipMsg = SLIPMsg(256)
        msg = b'123' + SLIP_ESC + b'456'
        self.slipMsg.encodeMsg(msg)
        self.slipMsg.decodeMsg(self.slipMsg.slip[0:4],
                               0)  # length prior to escape sequence
        msgLen = self.slipMsg.msgLength
        self.slipMsg.decodeMsg(self.slipMsg.slip[4:5], 0)  # parse SLIP_ESC
        assert (
            msgLen == self.slipMsg.msgLength
        )  # message length should be unchanged until entire escape sequence read
        self.slipMsg.decodeMsg(self.slipMsg.slip[5:6],
                               0)  # read entire escape sequence
        assert (self.slipMsg.msgLength == msgLen + 1)
        self.slipMsg.decodeMsg(
            self.slipMsg.slip[6:],
            0)  # test successful parsing of remainder of message
        assert (self.slipMsg.msg == msg)  # verify message contents
        assert (self.slipMsg.msgLength == len(msg))  # verify message length
Ejemplo n.º 6
0
 def test_encodeMsg(self):
     """Test encodeMsg method of SLIPMsgParser."""
     slipMsg = SLIPMsg(256)
     slipMsg.encodeMsg(testMsg)
     encodedMsg = self.msgParser.encodeMsg(testMsg)
     assert (encodedMsg == slipMsg.encoded)