def send_header(self, device_id: int, packet_type: int, packet_size: int): ''' Sends a header to the SDK :param device_id: The id of the device to send a header for :param packet_type: A utils.PacketType :param packet_size: The full size of the data to be sent after the header ''' if self.sock is None: raise utils.OpenRGBDisconnected() if not self.lock.acquire(timeout=10): raise utils.OpenRGBDisconnected( "SDK server did not respond to previous request") try: data = struct.pack('ccccIII', b'O', b'R', b'G', b'B', device_id, packet_type, packet_size) sent = self.sock.send(data, NOSIGNAL) if sent != len(data): self.stop_connection() raise utils.OpenRGBDisconnected() if packet_size == 0 and packet_type not in (utils.PacketType.REQUEST_CONTROLLER_COUNT,\ utils.PacketType.REQUEST_CONTROLLER_DATA,\ utils.PacketType.REQUEST_PROTOCOL_VERSION,\ utils.PacketType.REQUEST_PROFILE_LIST): self.lock.release() except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e
def send_data(self, data: bytes, release_lock: bool = True): ''' Sends data to the SDK :param data: The data to send ''' if self.sock is None: raise utils.OpenRGBDisconnected() try: self.sock.send(data, NOSIGNAL) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e finally: if release_lock: self.lock.release()
def send_data(self, data: bytes, release_lock: bool = True): ''' Sends data to the SDK :param data: The data to send ''' if not self.connected: raise utils.OpenRGBDisconnected() try: sent = self.sock.send(data, NOSIGNAL) # type: ignore if sent != len(data): self.stop_connection() raise utils.OpenRGBDisconnected() if release_lock: self.lock.release() except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e
def requestDeviceData(self, device: int): ''' Sends the request for a device's data :param device: the id of the device to request data for ''' if self.sock is None: raise utils.OpenRGBDisconnected() self.send_header(device, utils.PacketType.REQUEST_CONTROLLER_DATA, struct.calcsize('I')) self.send_data(struct.pack("I", self._protocol_version), False) self.read()
def send_header(self, device_id: int, packet_type: int, packet_size: int): ''' Sends a header to the SDK :param device_id: The id of the device to send a header for :param packet_type: A utils.PacketType :param packet_size: The full size of the data to be sent after the header ''' if self.sock is None: raise utils.OpenRGBDisconnected() if packet_size > 0 or packet_type in (utils.PacketType.REQUEST_CONTROLLER_COUNT,\ utils.PacketType.REQUEST_CONTROLLER_DATA,\ utils.PacketType.REQUEST_PROTOCOL_VERSION,\ utils.PacketType.REQUEST_PROFILE_LIST): self.lock.acquire() try: self.sock.send( struct.pack('ccccIII', b'O', b'R', b'G', b'B', device_id, packet_type, packet_size), NOSIGNAL) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e
def read(self): ''' Reads responses from the SDK :raises OpenRGBDisconnected: when it loses connection to the SDK ''' if self.sock is None: raise utils.OpenRGBDisconnected() header = bytearray(utils.HEADER_SIZE) try: self.sock.recv_into(header) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e if header == '\x00' * utils.HEADER_SIZE: self.stop_connection() raise utils.OpenRGBDisconnected() # Unpacking the contents of the raw header struct into a list buff = list(struct.unpack('ccccIII', header)) # print(buff[:4]) if buff[:4] == [b'O', b'R', b'G', b'B']: device_id, packet_type, packet_size = buff[4:] # print(device_id, packet_type, packet_size) if packet_type == utils.PacketType.REQUEST_CONTROLLER_COUNT: try: buff = struct.unpack("I", self.sock.recv(packet_size)) self.lock.release() self.callback(device_id, packet_type, buff[0]) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e finally: try: self.lock.release() except RuntimeError: pass elif packet_type == utils.PacketType.REQUEST_CONTROLLER_DATA: try: data = bytearray() while len(data) < packet_size: data += self.sock.recv(packet_size - len(data)) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e finally: self.lock.release() self.callback( device_id, packet_type, utils.ControllerData.unpack(data, self._protocol_version)) elif packet_type == utils.PacketType.DEVICE_LIST_UPDATED: assert device_id == 0 and packet_size == 0 self.read() self.callback(device_id, packet_type, 0) elif packet_type == utils.PacketType.REQUEST_PROTOCOL_VERSION: try: self.max_protocol_version = min( struct.unpack("I", self.sock.recv(packet_size))[0], OPENRGB_PROTOCOL_VERSION) self._protocol_version = min(self.max_protocol_version, self._protocol_version) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e finally: self.lock.release() elif packet_type == utils.PacketType.REQUEST_PROFILE_LIST: try: data = bytearray() while len(data) < packet_size: data += self.sock.recv(packet_size - len(data)) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e finally: self.lock.release() self.callback( device_id, packet_type, utils.parse_list(utils.Profile, data, self._protocol_version, 4)[1])
def read(self): ''' Reads responses from the SDK :raises utils.OpenRGBDisconnected: when it loses connection to the SDK ''' if not self.connected: raise utils.OpenRGBDisconnected() header = bytearray(utils.HEADER_SIZE) try: self.sock.recv_into(header) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e if header == '\x00' * utils.HEADER_SIZE: self.stop_connection() raise utils.OpenRGBDisconnected() # Unpacking the contents of the raw header struct into a list buff = list(struct.unpack('ccccIII', header)) # Checking packet signature if buff[:4] == [b'O', b'R', b'G', b'B']: device_id, packet_type, packet_size = buff[4:] # Parse information from each packet type if packet_type == utils.PacketType.REQUEST_CONTROLLER_COUNT: try: buff = struct.unpack("I", self.sock.recv(packet_size)) self.lock.release() self.callback(device_id, packet_type, buff[0]) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e finally: try: self.lock.release() except RuntimeError: pass elif packet_type == utils.PacketType.REQUEST_CONTROLLER_DATA: try: data = bytes() while len(data) < packet_size: data += self.sock.recv(packet_size - len(data)) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e finally: self.lock.release() try: self.callback( device_id, packet_type, utils.ControllerData.unpack(data, self._protocol_version)) except utils.PARSING_ERRORS as e: raise utils.ControllerParsingError( f"Unable to parse data from request `{packet_type}` for device #{device_id}" ) from e elif packet_type == utils.PacketType.DEVICE_LIST_UPDATED: assert device_id == 0 and packet_size == 0 self.read() self.callback(device_id, packet_type, 0) elif packet_type == utils.PacketType.REQUEST_PROTOCOL_VERSION: try: self.max_protocol_version = min( struct.unpack("I", self.sock.recv(packet_size))[0], OPENRGB_PROTOCOL_VERSION) self._protocol_version = min(self.max_protocol_version, self._protocol_version) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e finally: self.lock.release() elif packet_type == utils.PacketType.REQUEST_PROFILE_LIST: try: data = bytes() while len(data) < packet_size: data += self.sock.recv(packet_size - len(data)) idata = iter(data) for _ in range(4): next(idata) except utils.CONNECTION_ERRORS as e: self.stop_connection() raise utils.OpenRGBDisconnected() from e finally: self.lock.release() self.callback( device_id, packet_type, utils.parse_list(utils.Profile, idata, self._protocol_version))