def createEncodedMsg(msg):
    """Create encoded SLIP message with CRC."""
    crc16 = crcmod.predefined.mkCrcFun('crc16')
    crc = crc16(msg)
    slipMsg = SLIPMsg(256)
    slipMsg.encodeSLIPmsg(msg + pack('H',crc))
    return slipMsg.slip
示例#2
0
    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)
示例#3
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
示例#4
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
示例#5
0
    def test_processMsgs(self):
        """Test processMsgs method of SerialComm."""
        # Create message parser for testing purposes
        msg = SLIPMsg(self.nodeParams.config.parseMsgMax)
        self.serialComm.msgParser.msg = msg

        # Create and send test messages
        nodeStatus = [NodeState(node + 1) for node in range(5)]
        clock = FormationClock()

        cmdId1 = NodeCmds['NoOp']  # No op command
        cmdMsg1 = Command(cmdId1, None, [cmdId1, 1, 200]).serialize()
        cmdId2 = NodeCmds['GCSCmd']  # GCS command
        cmdMsg2 = Command(cmdId2, {
            'destId': 1,
            'mode': 2
        }, [cmdId2, 1, 201]).serialize()
        self.serialComm.sendMsg(cmdMsg1)
        self.serialComm.sendMsg(cmdMsg2)
        time.sleep(0.1)

        # Test processing
        self.serialComm.processMsgs(
            args={
                'logFile': [],
                'nav': [],
                'nodeStatus': nodeStatus,
                'clock': clock,
                'comm': self.serialComm
            })

        assert (cmdId1 in self.serialComm.cmdQueue
                )  # Test that correct message added to cmdQueue
        assert (cmdId2 in self.serialComm.cmdQueue
                )  # Test that correct message added to cmdQueue
    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
示例#7
0
 def setup_method(self, method):
     self.nodeStatus = [NodeState(i + 1) for i in range(5)]
     self.nodeParams = NodeParams(configFile=configFilePath)
     msgParser = MsgParser(
         {'parseMsgMax': self.nodeParams.config.parseMsgMax}, SLIPMsg(256))
     radio = Radio(
         [], {
             'uartNumBytesToRead':
             self.nodeParams.config.uartNumBytesToRead,
             'rxBufferSize': 2000
         })
     self.comm = TDMAComm([TDMACmdProcessor], radio, msgParser,
                          self.nodeParams)
示例#8
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)
示例#9
0
    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
示例#10
0
    def test_sendMsg(self):
        """Test sendMsg method of SerialComm."""
        # Create message parser for testing purposes
        msg = SLIPMsg(self.nodeParams.config.parseMsgMax)
        self.serialComm.msgParser.msg = msg

        # Send test message
        msgBytes = b'12345'
        self.serialPort.read(100)  # clear serial buffer
        self.serialComm.sendMsg(msgBytes)
        time.sleep(0.1)

        # Read message back and compare
        readBytes = self.serialComm.readMsgs()
        assert (len(self.serialComm.msgParser.parsedMsgs) == 1)
        assert (self.serialComm.msgParser.parsedMsgs[0] == msgBytes)
示例#11
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
示例#12
0
    def reinit(self, nodeParams, initDelay=None):

        self.nodeParams = nodeParams

        # TDMA config       
        self.tdmaMode = TDMAMode.sleep
        self.frameStartTime = []
        self.commStartTime = None # time that TDMA comm was started - initialized manually by first node or parsed from messages received for nodes joining existing mesh
        self.networkConfigConfirmed = None
        self.networkConfigRcvd = False
        self.maxNumSlots = nodeParams.config.commConfig['maxNumSlots'] # Maximum number of slots
        self.enableLength = nodeParams.config.commConfig['enableLength']
        self.slotTime = 0.0
        self.slotNum = 1        
        self.slotStartTime = 0.0
        self.networkMsgQueue = []   
 
        # TDMA Frame variables
        self.frameTime = 0.0
        self.frameCount = 0
        self.frameLength = nodeParams.config.commConfig['frameLength']
        self.cycleLength = nodeParams.config.commConfig['cycleLength']
        self.adminEnabled = nodeParams.config.commConfig['adminEnable']
        self.adminLength = nodeParams.config.commConfig['adminLength']

        # TDMA status
        self.tdmaStatus = TDMAStatus.nominal
        self.tdmaFailsafe = False
        self.timeOffsetTimer = None
        self.frameExceedanceCount = 0       
 
        # Mesh initialization variables
        self.inited = False
        self.initTimeToWait = nodeParams.config.commConfig['initTimeToWait'] # Time to wait before assuming no existing mesh network
        self.initStartTime = None
        
        # Mesh network commands
        self.tdmaCmds = dict()
        self.tdmaCmdParser = MsgParser({'parseMsgMax': nodeParams.config.parseMsgMax}, SLIPMsg(2048))
        
        # Transmit period variables
        self.transmitSlot = nodeParams.config.commConfig['transmitSlot'] # Slot in cycle that this node is schedule to transmit
        self.beginTxTime = self.enableLength + nodeParams.config.commConfig['preTxGuardLength']
        self.endTxTime = self.beginTxTime + nodeParams.config.commConfig['txLength']
        self.transmitComplete = False       
    
        # Receive period variables
        self.beginRxTime = self.enableLength
        self.endRxTime = self.beginRxTime + nodeParams.config.commConfig['rxLength']
        self.slotLength = nodeParams.config.commConfig['slotLength'] # total length of slot
        self.rxLength = nodeParams.config.commConfig['rxLength']
        self.rxReadTime = self.beginTxTime + nodeParams.config.commConfig['rxDelay'] # time to begin reading serial
        self.receiveComplete = False

        # Current read position in radio rx buffer
        self.rxBufferReadPos = 0

        # Mesh header information
        self.meshPacketHeaderFormat = '<BBHHHB'
        self.meshHeaderLen = struct.calcsize(self.meshPacketHeaderFormat)

        # Block Tx information
        self.blockTx = None
        self.blockTxInProgress = False
        self.blockTxPacketStatus = dict() # stores transmitted packet status until all receipt requests received
        self.blockTxPacketReceipts = []

        # Comm enable flag
        self.enabled = True

        # Mesh data in/out buffers
        #self.meshQueueIn = [b''] * (self.maxNumSlots + 1)
        self.meshQueueIn = []
        self.hostBuffer = bytearray()
        self.blockTxOut = dict()

        # Network graph
        #self.meshGraph = [0] * self.maxNumSlots # timestamps of last received message from each other node
        self.lastGraphUpdate = 0.0
        self.meshPaths = [[]*self.maxNumSlots] * self.maxNumSlots
        self.neighbors = []

        # Delay init (for full network restart)
        if (initDelay):
            time.sleep(initDelay)

        # Network metrics
        self.bytesSent = 0
        self.bytesRcvd = 0
示例#13
0
    def __init__(self, configFile, runFlag):
        super().__init__(name="NodeControlProcess", )

        # Run flag
        self.runFlag = runFlag

        # Configuration
        nodeParams = NodeParams(configFile=configFile)

        # Create radios
        radios = []
        radioConfig = {
            'uartNumBytesToRead': nodeParams.config.uartNumBytesToRead,
            'rxBufferSize': nodeParams.config.rxBufferSize,
            'ipAddr': nodeParams.config.interface['nodeCommIntIP'],
            'readPort': nodeParams.config.interface['commWrPort'],
            'writePort': nodeParams.config.interface['commRdPort']
        }
        for i in range(nodeParams.config.numMeshNetworks):
            radios.append(
                UDPRadio(radioConfig))  # connection to communication processes

        # Create message parsers
        msgParsers = []
        parserConfig = {'parseMsgMax': nodeParams.config.parseMsgMax}
        for i in range(nodeParams.config.numMeshNetworks):
            #if nodeParams.config.msgParsers[i] == "SLIP":
            msgParsers.append(MsgParser(parserConfig, SLIPMsg(256)))
        #elif nodeParams.config.msgParsers[i] == "standard":
        #    msgParsers.append(MsgParser(parserConfig))

        # Open logfiles
        currentTime = str(time.time())
        FCLogFilename = 'fc_' + currentTime + '.log'
        self.FCLogFile = open(FCLogFilename, 'w')
        nodeCommLogFilename = 'node_' + currentTime + '.log'
        self.nodeCommLogFile = open(nodeCommLogFilename, 'w')

        # Failsafe LED interval
        failsafeLEDTime = 1.0  # seconds
        failsafeLEDOnTime = -1.0
        failsafeLEDOn = False

        # Initialize node and flight computer communication variables
        nodeComm = [[]] * nodeParams.config.numMeshNetworks
        FCComm = []

        # Instantiate specific node software
        self.nodeController = []
        self.nodeExecutive = []
        for case in switch(nodeParams.config.platform
                           ):  # Platform specific initializations
            if case("SpecificNode"):
                pass
            else:  # generic node
                from mesh.generic.serialComm import SerialComm
                from demoController import DemoController
                from mesh.generic.nodeExecutive import NodeExecutive

                print("Initializing generic node")

                # Initialize communication variables
                for i in range(nodeParams.config.numMeshNetworks):
                    nodeComm[i] = SerialComm([], nodeParams, radios[i],
                                             msgParsers[i])

                # Flight computer comm
                if (nodeParams.config.FCCommDevice):
                    FCSer = serial.Serial(
                        port=nodeParams.config.FCCommDevice,
                        baudrate=nodeParams.config.FCBaudrate,
                        timeout=0)
                    FCRadio = Radio(FCSer, radioConfig)
                    FCMsgParser = MsgParser(parserConfig, SLIPMsg(256))
                    FCComm = SerialComm([], FCRadio, FCMsgParser, nodeParams)
                else:
                    FCComm = None

                # Node controller
                self.nodeController = DemoController(nodeParams,
                                                     self.nodeCommLogFile)

                # Node executive
                self.nodeExecutive = NodeExecutive(nodeParams,
                                                   self.nodeController,
                                                   nodeComm, FCComm,
                                                   self.FCLogFile)
示例#14
0
    def __init__(self, msgProcessors, radio, msgParser, nodeParams):
        if not msgProcessors:
            msgProcessors = [TDMACmdProcessor]

        super().__init__(msgProcessors, nodeParams, radio, parser=msgParser)

        self.nodeParams = nodeParams

        # TDMA config
        self.tdmaMode = TDMAMode.sleep
        self.frameStartTime = []
        self.commStartTime = None  # time that TDMA comm was started - initialized manually by first node or parsed from messages received for nodes joining existing mesh
        self.maxNumSlots = nodeParams.config.commConfig[
            'maxNumSlots']  # Maximum number of slots
        self.enableLength = nodeParams.config.commConfig['enableLength']
        self.slotTime = 0.0
        self.slotNum = 1
        self.slotStartTime = 0.0

        # TDMA Frame variables
        self.frameTime = 0.0
        self.frameLength = nodeParams.config.commConfig['frameLength']
        self.cycleLength = nodeParams.config.commConfig['cycleLength']

        # TDMA status
        self.tdmaStatus = TDMAStatus.nominal
        self.tdmaFailsafe = False
        self.timeOffsetTimer = None
        self.frameExceedanceCount = 0

        # Mesh initialization variables
        self.inited = False
        self.initTimeToWait = nodeParams.config.commConfig[
            'initTimeToWait']  # Time to wait before assuming no existing mesh network
        self.initStartTime = None

        # Mesh network commands
        self.tdmaCmds = dict()
        self.tdmaCmdParser = MsgParser(
            {'parseMsgMax': nodeParams.config.parseMsgMax}, SLIPMsg(256))

        # Transmit period variables
        self.transmitSlot = nodeParams.config.commConfig[
            'transmitSlot']  # Slot in cycle that this node is schedule to transmit
        self.beginTxTime = self.enableLength + nodeParams.config.commConfig[
            'preTxGuardLength']
        self.endTxTime = self.beginTxTime + nodeParams.config.commConfig[
            'txLength']
        self.transmitComplete = False

        # Receive period variables
        self.beginRxTime = self.enableLength
        self.endRxTime = self.beginRxTime + nodeParams.config.commConfig[
            'rxLength']
        self.slotLength = nodeParams.config.commConfig[
            'slotLength']  # total length of slot
        self.rxLength = nodeParams.config.commConfig['rxLength']
        self.rxReadTime = self.beginTxTime + nodeParams.config.commConfig[
            'rxDelay']  # time to begin reading serial
        self.receiveComplete = False

        # Current read position in radio rx buffer
        self.rxBufferReadPos = 0

        # Block TX init
        self.resetBlockTxStatus()
        self.clearDataBlock()

        # Comm enable flag
        self.enabled = True

        # Mesh data in/out buffers
        self.meshQueueIn = [b''] * (self.maxNumSlots + 1)
        self.hostBuffer = bytearray()

        # Network graph
        #self.meshGraph = [0] * self.maxNumSlots # timestamps of last received message from each other node
        self.lastGraphUpdate = 0.0
        self.meshPaths = [[] * self.maxNumSlots] * self.maxNumSlots
示例#15
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
示例#16
0
 def setup_method(self, method):
     self.slipMsg = SLIPMsg(256)
     pass
示例#17
0
 def setup_method(self, method):
     # Create SLIPMsgParser instance
     self.msgParser = MsgParser({'parseMsgMax': 10}, SLIPMsg(256))
示例#18
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)
示例#19
0
 def setup_method(self, method):
     self.slipMsg = SLIPMsg(256)
     self.truthCRC = packData(self.slipMsg.crc(testMsg), self.slipMsg.crcLength)
     pass