Ejemplo n.º 1
0
def get_header(raw_file: io.FileIO) -> Header:
    """Get the raw file header from an open ATOP file.

    Args:
        raw_file: An open ATOP file capable of reading as bytes.

    Returns:
        raw_header: The header at the beginning of an ATOP file.

    Raises:
        ValueError: If there are not enough bytes to read the header, or the bytes were invalid.
    """
    # Read the header directly into the struct, there is no padding to consume or add.
    # Use default Header as the baseline in order to check the version. It can be transferred without re-reading.
    header = _HEADER_BY_VERSION[_DEFAULT_VERSION]()
    raw_file.readinto(header)

    if header.magic != MAGIC:
        msg = f'File does not contain raw atop output (wrong magic number): {hex(header.magic)}'
        raise ValueError(msg)

    header_version = header.get_version()
    if header_version != _DEFAULT_VERSION and header_version in _HEADER_BY_VERSION:
        # Header byte length is consistent across versions. Transfer the initial read into the versioned header.
        header = _HEADER_BY_VERSION[header_version].from_buffer(header)

    # Ensure all struct lengths match the lengths specific in the header. If not, we cannot read the file further.
    header.check_compatibility()

    return header
Ejemplo n.º 2
0
def build_blob(bin1: FileIO, bin2: FileIO, out: FileIO) -> None:
    """Combines two firmware binary blobs ``bin1`` and ``bin2`` into a single
    firmware blob and saves them in ``out``.
    """
    bin1_size = os.fstat(bin1.fileno()).st_size
    bin2_size = os.fstat(bin2.fileno()).st_size
    bin2_offset = BIN2_BASE_OFFSET - BIN1_BASE_OFFSET
    size = bin2_offset + bin2_size
    max_size = FLASH_SIZE - BIN1_BASE_OFFSET

    if bin1_size >= bin2_offset:
        raise ValueError(f"{bin1.name} is too big!")
    if size >= max_size:
        raise ValueError(f"{bin2.name} is too big!")

    # Create a new combined firmware blob
    blob = memoryview(bytearray(size))
    bin1.readinto(blob)
    bin2.readinto(blob[bin2_offset:])

    # Read Reset_Handler pointers in vector tables.
    bin1_reset_handler = blob[4:8].tobytes()
    bin2_reset_handler = blob[bin2_offset + 4 : bin2_offset + 8].tobytes()

    # Swap Reset_Handler pointers. This will cause the second
    # firmware to boot first.
    blob[4:8] = bin2_reset_handler
    blob[bin2_offset + 4 : bin2_offset + 8] = bin1_reset_handler

    # The final checksum is for the entire new blob
    # This overrides the checksum of the second firmware.
    blob[-4:] = crc32_checksum(BytesIO(blob), max_size).to_bytes(4, "little")

    out.write(blob)
Ejemplo n.º 3
0
def get_record(raw_file: io.FileIO, record_cls: Type[Record]) -> Record:
    """Get the next raw record from an open ATOP file.

    Args:
        raw_file: An open ATOP file capable of reading as bytes.
        record_cls: Record struct class to read the raw bytes into.

    Returns:
        record: A single record representing the data before an SStat struct.

    Raises:
        ValueError: If there are not enough bytes to read a single record.
    """
    record = record_cls()
    raw_file.readinto(record)
    return record
Ejemplo n.º 4
0
class HidrawDS4Device(DS4Device):
    def __init__(self, name, addr, type, hidraw_device, event_device):
        try:
            self.report_fd = os.open(hidraw_device, os.O_RDWR | os.O_NONBLOCK)
            self.fd = FileIO(self.report_fd, "rb+", closefd=False)
            self.input_device = InputDevice(event_device)
            self.input_device.grab()
        except (OSError, IOError) as err:
            raise DeviceError(err)

        self.buf = bytearray(self.report_size)

        super(HidrawDS4Device, self).__init__(name, addr, type)

    def read_report(self):
        try:
            ret = self.fd.readinto(self.buf)
        except IOError:
            return

        # Disconnection
        if ret == 0:
            return

        # Invalid report size or id, just ignore it
        if ret < self.report_size or self.buf[0] != self.valid_report_id:
            return False

        if self.type == "bluetooth":
            # Cut off bluetooth data
            buf = zero_copy_slice(self.buf, 2)
        else:
            buf = self.buf

        return self.parse_report(buf)

    def read_feature_report(self, report_id, size):
        op = HIDIOCGFEATURE(size + 1)
        buf = bytearray(size + 1)
        buf[0] = report_id

        return fcntl.ioctl(self.fd, op, bytes(buf))

    def write_report(self, report_id, data):
        if self.type == "bluetooth":
            # TODO: Add a check for a kernel that supports writing
            # output reports when such a kernel has been released.
            return

        hid = bytearray((report_id,))
        self.fd.write(hid + data)

    def close(self):
        try:
            self.fd.close()
            self.input_device.ungrab()
        except IOError:
            pass
Ejemplo n.º 5
0
class HidrawDS4Device(DS4Device):
    def __init__(self, name, addr, type, hidraw_device, event_device):
        try:
            self.report_fd = os.open(hidraw_device, os.O_RDWR | os.O_NONBLOCK)
            self.fd = FileIO(self.report_fd, "rb+", closefd=False)
            self.input_device = InputDevice(event_device)
            self.input_device.grab()
        except (OSError, IOError) as err:
            raise DeviceError(err)

        self.buf = bytearray(self.report_size)

        super(HidrawDS4Device, self).__init__(name, addr, type)

    def read_report(self):
        try:
            ret = self.fd.readinto(self.buf)
        except IOError:
            return 'ioerror'

        # Disconnection
        if ret == 0:
            return 'disconnection'

        # Invalid report size or id, just ignore it
        if ret < self.report_size or self.buf[0] != self.valid_report_id:
            return False

        if self.type == "bluetooth":
            # Cut off bluetooth data
            buf = zero_copy_slice(self.buf, 2)
        else:
            buf = self.buf

        return self.parse_report(buf)

    def read_feature_report(self, report_id, size):
        op = HIDIOCGFEATURE(size + 1)
        buf = bytearray(size + 1)
        buf[0] = report_id

        return fcntl.ioctl(self.fd, op, bytes(buf))

    def write_report(self, report_id, data):
        hid = bytearray((report_id, ))
        self.fd.write(hid + data)

    def close(self):
        try:
            # Reset LED to original hidraw pairing colour.
            self.set_led(0, 0, 1)

            self.fd.close()
            self.input_device.ungrab()
        except IOError:
            pass
Ejemplo n.º 6
0
def _bench_file_read(hasher, expect):
    f = FileIO(tmpf.name, "r")
    b = bytearray(blksize)

    h = hasher()
    while 1:
        n = f.readinto(b)
        if n == 0:
            break

        h.update(xbuffer(b, 0, n))  # NOTE b[:n] does copy

    f.close()
    assert h.digest() == expect
Ejemplo n.º 7
0
 def set_challenge(self, ep0: io.FileIO) -> None:
     buf = AuthReport()
     ep0.readinto(buf)  #type: ignore[arg-type]
     crc = zlib.crc32(
         bytes(buf)[:ctypes.sizeof(AuthReport) - ctypes.sizeof(c_uint32)])
     if crc != buf.crc32:
         # TODO do we need to do more here?
         logger.warning("Invalid CRC32.")
     if buf.type != int(ReportType.set_challenge):
         raise TypeError('Invalid request type for request set_challenge.')
     if buf.page != 0 and buf.seq != self._seq:
         logger.warning("Inconsistent sequence value.")
     elif buf.page != self._req_page:
         logger.warning("Out of order challenge write.")
     self._seq = buf.seq
     valid_data_size = min(
         max(0, AUTH_REQ_SIZE - buf.page * self._req_size), self._req_size)
     self._nonce.write(
         memoryview(cast(bytearray,
                         buf.data))[:valid_data_size])  # bytearray-like
     if self._req_page == self._req_max_page:
         self._status = 0x01
         self._rsa_task.submit(self.prepare_challenge)
     self._req_page += 1
Ejemplo n.º 8
0
class FileDataReader(AbstractDataReader):
    """ A reader that can read data from a file
    """

    def __init__(self, filename):
        """
        :param filename: The file to read
        :type filename: str
        :raise spinnman.exceptions.SpinnmanIOException: If the file\
                    cannot found or opened for reading
        """
        try:
            self._fileio = FileIO(filename, "r")
        except IOError as e:
            raise SpinnmanIOException(str(e))

    def read(self, n_bytes):
        """ See :py:meth:`spinnman.data.abstract_data_reader.AbstractDataReader.read`
        """
        return bytearray(self._fileio.read(n_bytes))

    def readinto(self, data):
        """ See :py:meth:`spinnman.data.abstract_data_reader.AbstractDataReader.readinto`
        """
        return self._fileio.readinto(data)

    def readall(self):
        """ See :py:meth:`spinnman.data.abstract_data_reader.AbstractDataReader.readall`
        """
        return self._fileio.readall()

    def close(self):
        """ Closes the file

        :return: Nothing is returned:
        :rtype: None
        :raise spinnman.exceptions.SpinnmanIOException: If the file\
                    cannot be closed
        """
        try:
            self._fileio.close()
        except IOError as e:
            raise SpinnmanIOException(str(e))
Ejemplo n.º 9
0
def _bench_file_readbig(hasher, expect):
    f = FileIO(tmpf.name, "r")
    # b = mmap(-1, filesize, MAP_SHARED | MAP_ANONYMOUS, PROT_READ | PROT_WRITE)
    b = bytearray(filesize)
    bm = memoryview(b)

    h = hasher()
    pos = 0
    while 1:
        n = f.readinto(bm[pos:])
        if n == 0:
            break

        h.update(xbuffer(b, pos, n))  # NOTE b[pos:n] does copy
        pos += n

    del bm
    del b
    f.close()
    assert h.digest() == expect
Ejemplo n.º 10
0
class Joystick(Part):
    """Joystick to drive the car around manually without keyboard."""
    def __init__(self, config):
        """Joystick to drive the car around manually without keyboard."""
        super(Joystick, self).__init__(config, "joystick", [])

        # State/Controls
        self.speed = 0
        self.steer = 0
        self.speed_offset = 0
        self.steer_offset = 0
        self.is_calibrated = True
        self.is_autonomous = False
        self.state = DS4State()
        self.last_state = DS4State()
        self.__fd = None
        self.__input_device = None
        self.__report_fd = None
        self.__report_id = 0x11
        self.__keep_running = True
        self.__connect()

    def __del__(self):
        self.publish("action", isManual=True, speed=0, steer=0)
        self.publish("controller",
                     isAutonomous=False,
                     speedOffset=0,
                     steerOffset=0,
                     exit=True)
        super(Joystick, self).__del__()
        try:
            self.send(red=1, rumble_high=1)
            time.sleep(0.5)
            self.send(blue=0.1, green=0.1, red=0.5)
        except:
            pass
        if self.__fd is not None:
            self.__fd.close()
        if self.__input_device is not None:
            self.__input_device.ungrab()

    def __find_device(self):
        context = Context()
        for hidraw_device in context.list_devices(subsystem="hidraw"):
            hid_device = hidraw_device.parent
            if hid_device.subsystem != "hid" or hid_device.get(
                    "HID_NAME") != "Wireless Controller":
                continue
            for child in hid_device.parent.children:
                event_device = child.get("DEVNAME", "")
                if event_device.startswith("/dev/input/event"):
                    break
            else:
                continue

            device_addr = hid_device.get("HID_UNIQ", "").upper()
            return device_addr, hidraw_device.device_node, event_device
        return None, None, None

    def __connect(self):
        device_addr, hidraw_device, event_device = self.__find_device()
        if device_addr is None:
            return False
        self.__report_fd = os.open(hidraw_device, os.O_RDWR | os.O_NONBLOCK)
        self.__fd = FileIO(self.__report_fd, "rb+", closefd=False)
        self.__input_device = InputDevice(event_device)
        self.__input_device.grab()
        buf = bytearray(38)
        buf[0] = 0x02
        try:
            return bool(fcntl.ioctl(self.__fd, 3223734279, bytes(buf)))
        except:
            pass
        if self.recv():
            self.update_controller()

    def __in_deadzone(self, value):
        """ Deadzone checker for analog sticks """
        return 128 - self._config["deadzone"] < value <= 128 + self._config[
            "deadzone"]

    def __normalize_stick(self, value, deadzone):
        """
        Normalize stick value from [0, 255] to [0, 1]
        Ignore a 128-centered deadzone
        """
        value -= 128
        value = value - deadzone if value > 0 else value + deadzone
        value /= 127 - deadzone
        return value

    def recv(self, limit=1000, duration=0.001, report_size=78):
        """
        Attempt to get a message from the device. 
        Args:
            limit (int): number of device polls to do
            duration (int): how long to wait between polls
        Returns:
            Whether we have successfully updated the status of the program
        """
        for i in range(limit):
            time.sleep(duration)
            recv_buffer = bytearray(report_size)
            try:
                ret = self.__fd.readinto(recv_buffer)
            except IOError:
                # print("joystick: IO Error")
                continue
            except AttributeError:
                # print("joystick: Attribute Error")
                continue
            if ret is None:
                # print("joystick: ret is none")
                continue
            if ret < report_size:
                # print("joystick: ret too small (%i) expected (%i)" % (ret, report_size))
                continue
            if recv_buffer[0] != self.__report_id:
                # print("joystick: Wrong report id (%i) expected (%i):"
                #      % (recv_buffer[0], self.__report_id))
                continue
            self._timestamp = derp.util.get_timestamp()
            self.last_state = self.state
            self.state = DS4State(recv_buffer)
            self.process_state()
            return True
        return False

    def update_controller(self):
        """Send the state of the system to the controller"""
        green = 1.0 if self.is_autonomous else 0
        red = 1.0 if self.is_calibrated else 0
        blue = 1.0
        light_on = 1.0
        light_off = 0.0
        self.send(red=red,
                  green=green,
                  blue=blue,
                  light_on=light_on,
                  light_off=light_off)
        return True

    def send(self,
             rumble_high=0,
             rumble_low=0,
             red=0,
             green=0,
             blue=0,
             light_on=0,
             light_off=0):
        """Actuate the controller by setting its rumble or light color/blink"""
        packet = bytearray(79)
        packet[:5] = [0xA2, 0x11, 0x80, 0x00, 0xFF]
        packet[7] = int(rumble_high * 255 + 0.5)
        packet[8] = int(rumble_low * 255 + 0.5)
        packet[9] = int(red * 255 + 0.5)
        packet[10] = int(green * 255 + 0.5)
        packet[11] = int(blue * 255 + 0.5)
        packet[12] = int(light_on * 255 + 0.5)
        packet[13] = int(light_off * 255 + 0.5)
        crc = crc32(packet[:-4])
        packet[-4] = crc & 0x000000FF
        packet[-3] = (crc & 0x0000FF00) >> 8
        packet[-2] = (crc & 0x00FF0000) >> 16
        packet[-1] = (crc & 0xFF000000) >> 24
        hid = bytearray((self.__report_id, ))
        if self.__fd is not None:
            self.__fd.write(hid + packet[2:])
            return True
        return False

    def process_state(self):
        """
        For the given  input, figure out how we should affect the state
        and put that into out.
        """
        self.controller_changed = False
        self.action_changed = False
        self.__keep_running = not self.state.button_trackpad
        if not self.__in_deadzone(self.state.left_analog_x):
            steer = self.__normalize_stick(
                self.state.left_analog_x,
                self._config["deadzone"]) * self._config['steer_normalizer']
            if steer != self.steer:
                self.steer = steer
                self.action_changed = True
        elif not self.__in_deadzone(self.last_state.left_analog_x):
            self.steer = 0
            self.action_changed = True
        if self.state.left_trigger:
            speed = -self.state.left_trigger / 255 * self._config[
                'speed_normalizer']
            if speed != self.speed:
                self.speed = speed
                self.action_changed = True
        elif self.last_state.left_trigger:
            self.speed = 0
            self.action_changed = True
        if self.state.right_trigger:
            speed = self.state.right_trigger / 255 * self._config[
                'speed_normalizer']
            if speed != self.speed:
                self.speed = speed
                self.action_changed = True
        elif self.last_state.right_trigger:
            self.speed = 0
            self.action_changed = True
        if self.state.left and not self.last_state.left:
            self.steer_offset -= 5 / 255
            self.controller_changed = True
        if self.state.right and not self.last_state.right:
            self.steer_offset += 5 / 255
            self.controller_changed = True
        if self.state.up and not self.last_state.up:
            self.speed_offset += 5 / 255
            self.controller_changed = True
        if self.state.down and not self.last_state.down:
            self.speed_offset -= 5 / 255
            self.controller_changed = True
        if self.state.button_square and not self.last_state.button_square:
            pass
        if self.state.button_cross and not self.last_state.button_cross:
            self.speed = 0
            self.steer = 0
            self.speed_offset = 0
            self.is_autonomous = False
            self.action_changed = True
            self.controller_changed = True
        if self.state.button_triangle and not self.last_state.button_triangle:
            self.is_autonomous = True
            self.controller_changed = True
        if self.state.button_circle and not self.last_state.button_circle:
            self.controller_changed = True

    def run(self):
        """Query one set of inputs from the joystick and send it out."""
        start_time = derp.util.get_timestamp()
        if not self.recv():
            print("joystick: timed out", start_time)
            self.__connect()
            return True
        if self.controller_changed:
            self.update_controller()
            self.publish(
                "controller",
                isAutonomous=self.is_autonomous,
                speedOffset=self.speed_offset,
                steerOffset=self.steer_offset,
            )
        if self.action_changed:
            self.publish("action",
                         isManual=True,
                         speed=self.speed,
                         steer=self.steer)
        return self.__keep_running
Ejemplo n.º 11
0
    "/dev/input/js1", os.O_RDWR | os.O_NONBLOCK
)  # Ouvre le fichier contenant les données HID en mode R/W de manière asynchrone
fd = FileIO(
    report_fd, "rb", closefd=False
)  # Ouvre un FLUX de lecture du fichier concerné. Mode lecture binaire
defBuf = bytearray(230)  # Crée un bytearray de 230 octets vides

voiture = Voiture()  # Initialise la classe voiture

dernierEvt = False  # Dernier Event reçu (False si c'est le permier)

while True:
    sleep(0.1)

    buf = defBuf  # Buf = Buffer = Bytearray
    r = fd.readinto(buf)  # Remplit le bytearray vide

    evt = Event(buf)  # Crée un événement depuis le bytearray
    if evt.spam:
        evt = dernierEvt  # Si c'est un spam, alors garder

    evt.comparer(dernierEvt)  # Compare Event et dernierEvt

    if (DEBUG):
        logEvData(evt.changement)  # Affiche des données formatées

    voiture.interagir(
        evt
    )  # Envoie les données à l'objet Voiture pour interagir avec les GPIO

    dernierEvt = evt
Ejemplo n.º 12
0
class File(RawIOBase):
    'Create a file object wrapping an e[x]ploded zip file'

    HEADER = 0
    DATA = 1
    DESCRIPTOR = 2
    DIRECTORY = 3

    def __init__(self, path, flags, info, fh=None, base='.', depth=0):
        super(File, self).__init__()

        self.path = path
        self.flags = flags
        self.fh = fh

        self.info = info
        self.depth = depth
        self.cursor = 0
        self.offset = 0
        self.state = File.HEADER

        # stream item info
        self.stream_offset = 0
        self.zip_header = b''
        self.descriptor = b''

        # data file info
        self.data = None
        self.data_name = ''
        self.data_len = 0

        # streams
        prefix = os.path.join(base, 'meta', os.path.basename(path))
        self.stream = FileIO(prefix + '.stream', 'rb')
        self.dir = FileIO(prefix + '.dir', 'rb')
        self.data_dir = os.path.join(base, 'data')

        # init
        self._load_stream_item()
        self.lock = threading.Lock()

    def _load_stream_item(self):
        'Sets the next stream item as current.'

        if self.data:
            self.data.close()
            self.data = None

        # open the header so we can know the data file to open, and the
        # length of the var fields
        raw_header = self.stream.read(STREAM_ITEM.size)
        header = StreamItem._make(STREAM_ITEM.unpack(raw_header))

        var_fields = header.filename_len + header.extra_field_len
        # I would think that b2a_hex should decode the raw bytes...
        sha1 = b2a_hex(header.sha).decode('ascii')

        # only save the zip part of the header
        self.zip_header = (raw_header[:HEADER_DIFF] +
                           self.stream.read(var_fields))

        self.descriptor = self.stream.read(header.descriptor_len)

        self.data_name = path.join(*([self.data_dir] +
                                     list(sha1[:self.depth]) + [sha1]))

    def _open_data_file(self):
        self.data = FileIO(self.data_name, 'rb')
        self.data_len = self.data.seek(0, 2)
        self.data.seek(0)

    def close(self):
        self.stream.close()
        self.dir.close()
        if self.data: self.data.close()

    def fileno(self):
        return self.fh

    def isatty(self):
        return False

    def read(self, count=-1):
        if count < 0: return self.readall()
        elif count == 0: return b''

        state = self.state
        if state == File.HEADER:
            previous_offset = self.offset
            self.offset += count

            result = self.zip_header[previous_offset:self.offset]
            self.cursor += len(result)

            if self.offset >= len(self.zip_header):
                self.state = File.DATA
                if not self.data: self._open_data_file()

            return result

        elif state == File.DATA:
            result = self.data.read(count)
            self.cursor += len(result)

            if self.data.tell() >= self.data_len:
                self.state = File.DESCRIPTOR
                self.offset = 0

            # empty data file (state will now be DESCRIPTOR)
            if not result: return self.read(count)

            return result

        elif state == File.DESCRIPTOR:
            previous_offset = self.offset
            self.offset += count

            result = self.descriptor[previous_offset:self.offset]
            self.cursor += len(result)

            if self.offset >= len(self.descriptor):
                if self.cursor >= self.info.directory_offset:
                    self.state = File.DIRECTORY
                    self.dir.seek(0)
                    self.stream_offset = None

                    if self.data:
                        self.data.close()
                        self.data = None

                else:
                    self.state = File.HEADER
                    self.offset = 0
                    self.stream_offset = self.stream.tell()
                    self._load_stream_item()

            # descriptor is optional (state will now be HEADER or DIRECTORY)
            if not result: return self.read(count)

            return result
        elif state == File.DIRECTORY:
            result = self.dir.read(count)
            self.cursor += len(result)

            return result
        else:
            raise RuntimeError('Invalid state: %r' % self.state)

    def readable(self):
        return True

    def readinto(self, b):
        count = len(b)
        if count == 0: return 0

        state = self.state
        if state == File.HEADER:
            header_len = len(self.zip_header)
            previous_offset = self.offset

            current_offset = self.offset = \
                    min(previous_offset + count, header_len)

            read = current_offset - previous_offset
            b[:read] = self.zip_header[previous_offset:current_offset]
            self.cursor += read

            if current_offset == header_len:
                self.state = File.DATA
                if not self.data: self._open_data_file()

            return read

        elif state == File.DATA:
            read = self.data.readinto(b)
            self.cursor += read

            if self.data.tell() >= self.data_len:
                self.state = File.DESCRIPTOR
                self.offset = 0

            # empty data file (state will now be DESCRIPTOR)
            if not read: return self.readinto(b)

            return read

        elif state == File.DESCRIPTOR:
            descriptor_len = len(self.descriptor)
            previous_offset = self.offset

            current_offset = self.offset = \
                    min(previous_offset + count, descriptor_len)

            read = current_offset - previous_offset
            b[:read] = self.descriptor[previous_offset:current_offset]
            self.cursor += read

            if current_offset == descriptor_len:
                if self.cursor >= self.info.directory_offset:
                    self.state = File.DIRECTORY
                    self.dir.seek(0)
                    self.stream_offset = None

                    if self.data:
                        self.data.close()
                        self.data = None

                else:
                    self.state = File.HEADER
                    self.offset = 0
                    self.stream_offset = self.stream.tell()
                    self._load_stream_item()

            # descriptor is optional (state will now be HEADER or DIRECTORY)
            if not read: return self.readinto(b)

            return read
        elif state == File.DIRECTORY:
            read = self.dir.readinto(b)
            self.cursor += read

            return read
        else:
            raise RuntimeError('Invalid state: %r' % self.state)

    def seek(self, pos, offset=0):
        if offset == 1:
            pos += self.cursor
        elif offset == 2:
            pos += self.info.filesize

        if pos == self.cursor: return pos
        self.cursor = pos

        # skip directly to the central directory
        if pos >= self.info.directory_offset:
            if self.data:
                self.data.close()
                self.data = None

            self.state = File.DIRECTORY
            self.stream_offset = None
            self.dir.seek(pos - self.info.directory_offset)
            return pos

        # calculate the offset into the stream file
        z_offset, s_offset = self.info.jump_tree.find(pos).location
        additional = pos - z_offset

        # we're looking at a different data file
        # (load local header into memory)
        if s_offset != self.stream_offset:
            self.stream_offset = s_offset
            self.stream.seek(s_offset)
            self._load_stream_item()

        header_len = len(self.zip_header)
        if additional < header_len:
            self.state = File.HEADER
            self.offset = additional
            return pos

        # assume currently in the data file
        additional -= header_len
        self.state = File.DATA

        # if the file hasn't been opened yet, open it and find its size
        if not self.data: self._open_data_file()

        if additional < self.data_len:
            self.data.seek(additional)
        else:
            self.state = File.DESCRIPTOR
            self.offset = additional - self.data_len

        return pos

    def seekable(self):
        return True

    def tell(self):
        return self.cursor

    def writeable(self):
        return False
Ejemplo n.º 13
0
class HidrawDS4Device(DS4Device):
    def __init__(self, name, addr, type, hidraw_device, event_device):
        try:
            self.report_fd = os.open(hidraw_device, os.O_RDWR | os.O_NONBLOCK)
            self.fd = FileIO(self.report_fd, "rb+", closefd=False)
            self.input_device = InputDevice(event_device)
            self.input_device.grab()
        except (OSError, IOError) as err:
            raise DeviceError(err)

        self.buf = bytearray(self.report_size)

        super(HidrawDS4Device, self).__init__(name, addr, type)

    def read_report(self):
        try:
            ret = self.fd.readinto(self.buf)
        except IOError:
            return

        # Disconnection
        if ret == 0:
            return

        # Invalid report size or id, just ignore it
        if ret < self.report_size or self.buf[0] != self.valid_report_id:
            return False

        if self.type == "bluetooth":
            # Cut off bluetooth data
            buf = zero_copy_slice(self.buf, 2)
        else:
            buf = self.buf

        return self.parse_report(buf)

    def read_feature_report(self, report_id, size):
        op = HIDIOCGFEATURE(size + 1)
        buf = bytearray(size + 1)
        buf[0] = report_id

        return fcntl.ioctl(self.fd, op, bytes(buf))

    def write_report(self, report_id, report):
        """
        Send a feature report.
        """
        tmp = [0] * 79
        tmp[:7] = [0xa2, 0x11, 0xC0, 0x00, 0xff, 0x00, 0x00]
        tmp[7] = report[5]  #rumble weak
        tmp[8] = report[6]  #rumble strong
        tmp[9] = report[7]  #red
        tmp[10] = report[8]  #green
        tmp[11] = report[9]  #blue
        tmp[12] = report[10]  # Time to flash bright (255 = 2.5 seconds)
        tmp[13] = report[11]  # Time to flash dim (255 = 2.5 seconds)

        buf = bytearray(tmp)

        crc = zlib.crc32(bytes(buf[:(len(buf) - 4)])) & 0xffffffff

        buf[len(buf) - 4] = (crc & 0xFF)
        buf[len(buf) - 3] = ((crc & 0xFF00) >> 8)
        buf[len(buf) - 2] = ((crc & 0xFF0000) >> 16)
        buf[len(buf) - 1] = ((crc & 0xFF000000) >> 24)

        self.fd.write(buf[1:])

    def close(self):
        try:
            # Reset LED to original hidraw pairing colour.
            # self.set_led(0, 0, 1)

            # Set LED to blinking orange to notify the driver disconnection. (0, 0, 1) is almost off so not that useful.
            self.set_led(255, 69, 0)  # Orange
            self.start_led_flash(90, 50)

            self.fd.close()
            self.input_device.ungrab()
        except IOError:
            pass
Ejemplo n.º 14
0
import os, sys, datetime, colored
from time import sleep
from io import FileIO

report_fd = os.open("/dev/input/js1", os.O_RDWR | os.O_NONBLOCK)
fd = FileIO(report_fd, "rb+", closefd=False)

defBuf = bytearray(230)

while True:
    buf = defBuf
    r = fd.readinto(buf)
    key = []
    arr = []
    sign = buf[2]

    i = 0
    while i < len(buf):
        try:
            if (buf[i] == sign and buf[i + 1] == 0):
                key.append(i + 2)
                key.append(i + 3)
        except Exception as e:
            pass

        i += 1

    i = 0
    if (buf[5] != 0):
        arr.append(colored.bg("blue") + "!!" + colored.attr("reset"))
Ejemplo n.º 15
0
class FakeDS4Device(DS4Device):
    def __init__(self, name, addr, type, hidraw_device, event_device):
        try:
            self.report_fd = os.open(hidraw_device, os.O_RDWR | os.O_NONBLOCK)
            self.fd = FileIO(self.report_fd, "rb+", closefd=False)
            self.input_device = InputDevice(event_device)
            self.input_device.grab()
        except (OSError, IOError) as err:
            raise DeviceError(err)

        self.buf = bytearray(self.report_size)

        super(FakeDS4Device, self).__init__(name, addr, type)

    def parse_report(self, buf):
        """parse a buffer containing a hid report."""
        dpad = buf[5] % 16

        return FakeDS4Report(
            # left analog stick
            buf[1],
            buf[2],
            # right analog stick
            buf[3],
            buf[4],
            # dpad up, down, left, right
            (dpad in (0, 1, 7)),
            (dpad in (3, 4, 5)),
            (dpad in (5, 6, 7)),
            (dpad in (1, 2, 3)),
            # buttons cross, circle, square, triangle
            (buf[5] & 32) != 0,
            (buf[5] & 64) != 0,
            (buf[5] & 16) != 0,
            (buf[5] & 128) != 0,
            # l1, r1 buttons
            (buf[6] & 1) != 0,
            (buf[6] & 2) != 0,
            # r1, r2 buttons
            (buf[6] & 4) != 0,
            (buf[6] & 8) != 0,
            # share and option buttons
            (buf[6] & 16) != 0,
            (buf[6] & 32) != 0,
            # l3 and r3 buttons
            (buf[6] & 64) != 0,
            (buf[6] & 128) != 0,
            # ps and trackpack buttons
            (buf[7] & 1) != 0,
            (buf[7] & 2) != 0,
            # l2 analog, r2 analog
            buf[8],
            buf[9],
            # timestamp and battery
            buf[7] >> 2,
            buf[30] % 16,
            # external inputs (usb, audio, mic)
            (buf[30] & 16) != 0,
            (buf[30] & 32) != 0,
            (buf[30] & 64) != 0)

    def read_report(self):
        try:
            ret = self.fd.readinto(self.buf)
        except IOError:
            return

        # Disconnection
        if ret == 0:
            return

        # Invalid report size or id, just ignore it
        if ret < self.report_size or self.buf[0] != self.valid_report_id:
            return False

        if self.type == "bluetooth":
            # Cut off bluetooth data
            buf = zero_copy_slice(self.buf, 2)
        else:
            buf = self.buf

        return self.parse_report(buf)

    def read_feature_report(self, report_id, size):
        op = HIDIOCGFEATURE(size + 1)
        buf = bytearray(size + 1)
        buf[0] = report_id

        return fcntl.ioctl(self.fd, op, bytes(buf))

    def write_report(self, report_id, data):
        hid = bytearray((report_id, ))
        self.fd.write(hid + data)

    def close(self):
        try:
            # Reset LED to original hidraw pairing colour.
            self.set_led(0, 0, 1)

            self.fd.close()
            self.input_device.ungrab()
        except IOError:
            pass