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
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 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
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
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)
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)
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)
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
def setup_method(self, method): self.hdlcMsg = HDLCMsg(256) self.truthCRC = packData(self.hdlcMsg.crc(testMsg), self.hdlcMsg.crcLength) pass
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
def setup_method(self, method): # Create HDLCMsgParser instance self.msgParser = MsgParser({'parseMsgMax': 10}, HDLCMsg(256))
def test_encodeMsg(self): """Test encodeMsg method of HDLCMsgParser.""" hdlcMsg = HDLCMsg(256) hdlcMsg.encodeMsg(testMsg) encodedMsg = self.msgParser.encodeMsg(testMsg) assert (encodedMsg == hdlcMsg.encoded)