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
Beispiel #2
0
    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)
Beispiel #3
0
 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_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 #5
0
    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
Beispiel #6
0
    def setup_method(self, method):

        self.nodeParams = NodeParams(configFile=configFilePath)
        self.nodeParams.config.commConfig['transmitSlot'] = 1
        self.radio = Radio(None, {'uartNumBytesToRead': self.nodeParams.config.uartNumBytesToRead, 'rxBufferSize': 2000})
        msgParser = MsgParser({'parseMsgMax': self.nodeParams.config.parseMsgMax}, HDLCMsg(256))
        self.tdmaComm = TDMAComm([TDMACmdProcessor], self.radio, msgParser, self.nodeParams)
    
        # Test article
        self.meshController = MeshController(self.nodeParams, self.tdmaComm)
Beispiel #7
0
    def test_parseSerialMsg(self):
        """Test parseSerialMessage method of HDLCMsgParser."""
        # Check rejection of message with invalid CRC
        self.msgParser.parseSerialMsg(truthHDLCMsg, 0)
        assert (self.msgParser.msg.msgFound == True)  # hdlc 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)
        hdlcMsg = HDLCMsg(256)
        hdlcMsg.encodeMsg(testMsg)
        self.msgParser.parseSerialMsg(hdlcMsg.encoded, 0)
        assert (self.msgParser.msg.msgFound == True)  # hdlc 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 = hdlcMsg.encoded + b'989898'
        msgEnd = self.msgParser.parseSerialMsg(paddedMsg, 0)
        assert (self.msgParser.parsedMsgs[0] == testMsg)
        assert (msgEnd == len(hdlcMsg.encoded) - 1)
Beispiel #8
0
    def setup_method(self, method):

        if testSerialPort:
            serialPort = serial.Serial(port=testSerialPort, baudrate=57600, timeout=0)
        else:
            serialPort = []

        self.nodeParams = NodeParams(configFile=configFilePath)
        self.nodeParams.config.commConfig['transmitSlot'] = 1
        self.radio = Radio(serialPort, {'uartNumBytesToRead': self.nodeParams.config.uartNumBytesToRead, 'rxBufferSize': 2000})
        msgParser = MsgParser({'parseMsgMax': self.nodeParams.config.parseMsgMax}, HDLCMsg(256))
        self.tdmaComm = TDMAComm([TDMACmdProcessor], self.radio, msgParser, self.nodeParams)
  
        # Flush radio
        self.radio.serial.read(100)
Beispiel #9
0
    def __init__(self, configFile, meshNum, runFlag):
        super().__init__(name="CommProcess")

        # Node control run flag
        self.nodeControlRunFlag = runFlag

        # Configuration
        self.nodeParams = NodeParams(configFile=configFile)

        # Node/Comm interface
        interfaceConfig = {
            'uartNumBytesToRead': self.nodeParams.config.uartNumBytesToRead,
            'rxBufferSize': self.nodeParams.config.rxBufferSize,
            'ipAddr': self.nodeParams.config.interface['nodeCommIntIP'],
            'readPort': self.nodeParams.config.interface['commRdPort'],
            'writePort': self.nodeParams.config.interface['commWrPort']
        }
        #self.interface = SerialComm([], UDPRadio(interfaceConfig), SLIPMsgParser({'parseMsgMax': self.nodeParams.config.parseMsgMax}))
        self.interface = SerialComm(
            [], self.nodeParams, UDPRadio(interfaceConfig),
            MsgParser({'parseMsgMax': self.nodeParams.config.parseMsgMax},
                      SLIPMsg(256)))  # UDP connection to node control process

        # Interprocess data package (Google protocol buffer interface to node control process)
        self.dataPackage = NodeThreadMsg()
        self.cmdTxLog = {}
        self.lastNodeCmdTime = []

        ## Create comm object
        # Serial connection
        ser = serial.Serial(port=self.nodeParams.config.meshDevices[meshNum],
                            baudrate=self.nodeParams.config.meshBaudrate,
                            timeout=0)

        # Radio
        radioConfig = {
            'uartNumBytesToRead': self.nodeParams.config.uartNumBytesToRead,
            'rxBufferSize': self.nodeParams.config.rxBufferSize
        }
        if (self.nodeParams.config.commConfig['fpga'] == True):
            from mesh.generic.fpgaRadio import FPGARadio
            radio = FPGARadio(ser, radioConfig)
        else:
            if self.nodeParams.config.radios[meshNum] == "Xbee":
                radio = XbeeRadio(ser, radioConfig, "P8_12")
            elif self.nodeParams.config.radios[meshNum] == "Li-1":
                radio = Li1Radio(ser, radioConfig)

        # Message parser
        parserConfig = {'parseMsgMax': self.nodeParams.config.parseMsgMax}
        if self.nodeParams.config.msgParsers[meshNum] == "HDLC":
            msgParser = MsgParser(parserConfig, HDLCMsg(256))
        elif self.nodeParams.config.msgParsers[meshNum] == "standard":
            msgParser = MsgParser(parserConfig)

        # Create comm
        if (self.nodeParams.config.commConfig['fpga'] == True):
            from mesh.generic.tdmaComm_fpga import TDMAComm_FPGA as TDMAComm
        else:
            from mesh.generic.tdmaComm import TDMAComm

        self.comm = TDMAComm([], radio, msgParser, self.nodeParams)

        # Node control run time bounds
        if (self.nodeParams.config.commConfig['fpga'] == False
            ):  # only needed for software-controlled comm
            if self.comm.transmitSlot == 1:  # For first node, run any time after transmit slot
                self.maxNodeControlTime = self.comm.frameLength - self.comm.slotLength
                self.minNodeControlTime = self.comm.slotLength
            else:  # For other nodes, avoid running near transmit slot
                self.minNodeControlTime = (
                    self.comm.transmitSlot - 2
                ) * self.comm.slotLength  # don't run within 1 slot of transmit
                self.maxNodeControlTime = self.comm.transmitSlot * self.comm.slotLength
 def setup_method(self, method):
     self.hdlcMsg = HDLCMsg(256)
     pass
Beispiel #11
0
 def setup_method(self, method):
     self.hdlcMsg = HDLCMsg(256)
     self.truthCRC = packData(self.hdlcMsg.crc(testMsg),
                              self.hdlcMsg.crcLength)
     pass
Beispiel #12
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
Beispiel #13
0
 def setup_method(self, method):
     # Create HDLCMsgParser instance
     self.msgParser = MsgParser({'parseMsgMax': 10}, HDLCMsg(256))
Beispiel #14
0
 def test_encodeMsg(self):
     """Test encodeMsg method of HDLCMsgParser."""
     hdlcMsg = HDLCMsg(256)
     hdlcMsg.encodeMsg(testMsg)
     encodedMsg = self.msgParser.encodeMsg(testMsg)
     assert (encodedMsg == hdlcMsg.encoded)