Exemplo n.º 1
0
 def _rx_ext_packet(cls,
                    msg: Message,
                    command: int,
                    rx_length: int,
                    check_ack: bool = True,
                    check_length: bool = True) -> Message:
     """
     Parse a received packet
     :param msg: data to parse
     :param command: The extended command sent
     :param rx_length: Expected length of the received data
     :param check_ack: If true, checks the first byte as an AK byte
     :param tx_payload: what was sent, used if an exception needs to be thrown
     :return: The payload of the extended message
     """
     assert (msg['command'] == 0x56)
     if not cls.VEX_CRC16.compute(msg.rx) == 0:
         raise VEXCommError(
             "CRC of message didn't match 0: {}".format(
                 cls.VEX_CRC16.compute(msg.rx)), msg)
     assert (msg['payload'][0] == command)
     msg = msg['payload'][1:-2]
     if check_ack:
         nacks = {
             0xFF: "General NACK",
             0xCE: "CRC error on recv'd packet",
             0xD0: "Payload too small",
             0xD1: "Request transfer size too large",
             0xD2: "Program CRC error",
             0xD3: "Program file error",
             0xD4: "Attempted to download/upload uninitialized",
             0xD5: "Initialization invalid for this function",
             0xD6: "Data not a multiple of 4 bytes",
             0xD7: "Packet address does not match expected",
             0xD8: "Data downloaded does not match initial length",
             0xD9: "Directory entry does not exist",
             0xDA: "Max user files, no more room for another user program",
             0xDB: "User file exists"
         }
         if msg[0] in nacks.keys():
             raise VEXCommError(
                 "Device NACK'd with reason: {}".format(nacks[msg[0]]), msg)
         elif msg[0] != cls.ACK_BYTE:
             raise VEXCommError("Device didn't ACK", msg)
         msg = msg[1:]
     if len(msg) > 0:
         logger(cls).debug('Set msg window to {}'.format(bytes_to_str(msg)))
     if len(msg) != rx_length and check_length:
         raise VEXCommError(
             "Received length doesn't match {} (got {})".format(
                 rx_length, len(msg)), msg)
     return msg
Exemplo n.º 2
0
 def _txrx_ack_packet(self, command: int, timeout=0.1):
     """
             Goes through a send/receive cycle with a VEX device.
             Transmits the command with the optional additional payload, then reads and parses the outer layer
             of the response
             :param command: Command to send the device
             :param retries: Number of retries to attempt to parse the output before giving up and raising an error
             :return: Returns a dictionary containing the received command field and the payload. Correctly computes
             the payload length even if the extended command (0x56) is used (only applies to the V5).
             """
     tx = self._tx_packet(command)
     self._rx_ack(timeout=timeout)
     logger(__name__).debug('TX: {}'.format(bytes_to_str(tx)))
Exemplo n.º 3
0
 def _rx_packet(
     self,
     timeout: Optional[float] = None
 ) -> Dict[str, Union[Union[int, bytes, bytearray], Any]]:
     # Optimized to read as quickly as possible w/o delay
     start_time = time.time()
     response_header = bytes([0xAA, 0x55])
     response_header_stack = list(response_header)
     rx = bytearray()
     if timeout is None:
         timeout = self.default_timeout
     while (len(rx) > 0 or time.time() - start_time < timeout
            ) and len(response_header_stack) > 0:
         b = self.port.read(1)
         if len(b) == 0:
             continue
         b = b[0]
         if b == response_header_stack[0]:
             response_header_stack.pop(0)
             rx.append(b)
         else:
             logger(__name__).debug(
                 "Tossing rx ({}) because {} didn't match".format(
                     bytes_to_str(rx), b))
             response_header_stack = bytearray(response_header)
             rx = bytearray()
     if not rx == bytearray(response_header):
         raise IOError(
             f"Couldn't find the response header in the device response after {timeout} s. "
             f"Got {rx.hex()} but was expecting {response_header.hex()}")
     rx.extend(self.port.read(1))
     command = rx[-1]
     rx.extend(self.port.read(1))
     payload_length = rx[-1]
     if command == 0x56 and (payload_length & 0x80) == 0x80:
         logger(__name__).debug('Found an extended message payload')
         rx.extend(self.port.read(1))
         payload_length = ((payload_length & 0x7f) << 8) + rx[-1]
     payload = self.port.read(payload_length)
     rx.extend(payload)
     return {'command': command, 'payload': payload, 'raw': rx}
Exemplo n.º 4
0
 def __str__(self):
     return 'TX:{}\tRX:{}'.format(bytes_to_str(self.tx),
                                  bytes_to_str(self.rx))