def set_aspect_mode(self, mode): """ Args: mode (str): One of ("letterbox" | "fill" | "stretch") """ self._get_player_interface().SetAspectMode(ObjectPath('/not/used'), String(mode))
def set_alpha(self, alpha): """ Args: alpha (float): The transparency (0..255) """ self._get_player_interface().SetAlpha(ObjectPath('/not/used'), Int64(alpha))
def __init__(self, iface: str = 'hci0', ioc: str = 'NoInputNoOutput'): super().__init__(iface=iface) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) sys_bus = SystemBus() self.agent_registered = False def register_agent_callback(): logger.info('Agent object registered') print(INFO_INDENT, "IO capability: {}".format( self.bluescan_agent.io_capability), sep='') self.agent_registered = True def register_agent_error_callback(error): logger.error("Failed to register agent object") print(ERROR_INDENT, "{}".format(error), sep='') print(ERROR_INDENT, "IO capability: {}".format( self.bluescan_agent.io_capability), sep='') self.agent_registered = False self.bluescan_agent = BluescanAgent(sys_bus, 0, ioc) self.agent_mgr_1_iface = dbus.Interface( sys_bus.get_object(BLUEZ_NAME, '/org/bluez'), IFACE_AGENT_MGR_1) self.agent_mgr_1_iface.RegisterAgent( ObjectPath(self.bluescan_agent.path), self.bluescan_agent.io_capability, reply_handler=register_agent_callback, error_handler=register_agent_error_callback)
def video_pos(self): """ Returns: """ position_string = self._player_interface.VideoPos( ObjectPath('/not/used'), String(position)) return list(map(int, position_string.split(" ")))
def unhide_stream(self): logger.debug('CameraStream: Unhide stream instruction ' + self.name + ' received from dbus interface') if platform.system() == "Linux": if self.dbusconnection is not None: self.dbusconnection.player_interface.SetAlpha(ObjectPath('/not/used'), Int64(255)) else: logger.error('CameraStream: ' + self.name + ' has no dbus connection, probably because omxplayer crashed because it can not connect to this stream. As a result we could not unhide this stream at this time.')
def set_videopos(self,new_coordinates): logger.debug('CameraStream: ' + self.name + ' Set new position for ' + self.name + ' with new coordinates: + ' + str(new_coordinates) + ' on dbus interface') if platform.system() == "Linux": if self.dbusconnection is not None: self.dbusconnection.VideoPosWrapper((ObjectPath('/not/used'), String(" ".join(map(str,new_coordinates))))) else: logger.error('CameraStream: ' + self.name + ' has no dbus connection, probably because omxplayer crashed because it can not connect to this stream. As a result we could not change its videopos dynamically for this stream at this time.')
def __init__(self, iface: str = 'hci0', ioc: str = 'NoInputNoOutput'): super().__init__(iface=iface) self.result = GattScanResult() self.gatt_client = None self.spinner = Halo() dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) sys_bus = SystemBus() self.agent_registered = False def register_agent_callback(): logger.debug('Agent object registered\n' "IO capability: {}".format( self.bluescan_agent.io_capability)) self.agent_registered = True def register_agent_error_callback(error): logger.error( "Failed to register agent object.\n" + "{}\n".format(error) + "IO capability: {}".format(self.bluescan_agent.io_capability)) self.agent_registered = False self.bluescan_agent = BluescanAgent(sys_bus, 0, ioc) self.agent_mgr_1_iface = dbus.Interface( sys_bus.get_object(BLUEZ_NAME, '/org/bluez'), IFACE_AGENT_MGR_1) self.agent_mgr_1_iface.RegisterAgent( ObjectPath(self.bluescan_agent.path), self.bluescan_agent.io_capability, reply_handler=register_agent_callback, error_handler=register_agent_error_callback)
def set_alpha(self, alpha): """ Set the transparency of the video overlay Args: alpha (float): The transparency (0..255) """ self._player_interface.SetAlpha(ObjectPath('/not/used'), Int64(alpha))
def set_position(self, position): """ Args: position (float): The position in seconds. """ self._get_player_interface().SetPosition(ObjectPath("/not/used"), Int64(position * 1000 * 1000)) self.positionEvent(self, position)
def set_video_crop(self, x1, y1, x2, y2): """ Args: Image position (int, int, int, int): """ crop = "%s %s %s %s" % (str(x1), str(y1), str(x2), str(y2)) self._get_player_interface().SetVideoCropPos(ObjectPath('/not/used'), String(crop))
def set_video_pos(self, x1, y1, x2, y2): """ Args: Image position (int, int, int, int): """ position = "%s %s %s %s" % (str(x1), str(y1), str(x2), str(y2)) self._get_player_interface().VideoPos(ObjectPath('/not/used'), String(position))
def video_pos(self): """ Returns: (int, int, int, int): Video spatial position (x1, y1, x2, y2) where (x1, y1) is top left, and (x2, y2) is bottom right. All values in px. """ position_string = self._player_interface.VideoPos( ObjectPath('/not/used')) return list(map(int, position_string.split(" ")))
def set_position(self, position): """ Set the video to playback position to `position` seconds from the start of the video Args: position (float): The position in seconds. """ self._player_interface.SetPosition(ObjectPath("/not/used"), Int64(position * 1000.0 * 1000)) self.positionEvent(self, position)
def set_video_crop(self, x1, y1, x2, y2): """ Args: x1 (int): Top left x coordinate (px) y1 (int): Top left y coordinate (px) x2 (int): Bottom right x coordinate (px) y2 (int): Bottom right y coordinate (px) """ crop = "%s %s %s %s" % (str(x1), str(y1), str(x2), str(y2)) self._player_interface.SetVideoCropPos(ObjectPath('/not/used'), String(crop))
def set_video_pos(self, x1, y1, x2, y2): """ Set the video position on the screen Args: x1 (int): Top left x coordinate (px) y1 (int): Top left y coordinate (px) x2 (int): Bottom right x coordinate (px) y2 (int): Bottom right y coordinate (px) """ position = "%s %s %s %s" % (str(x1), str(y1), str(x2), str(y2)) self._player_interface.VideoPos(ObjectPath('/not/used'), String(position))
def _message_cb(self, connection, message): if not isinstance(message, MethodCallMessage): return try: # lookup candidate method and parent method method_name = message.get_member() interface_name = message.get_interface() (candidate_method, parent_method) = _method_lookup(self, method_name, interface_name) # set up method call parameters args = message.get_args_list( **parent_method._dbus_get_args_options) keywords = {} if parent_method._dbus_out_signature is not None: signature = Signature(parent_method._dbus_out_signature) else: signature = None # set up async callback functions if parent_method._dbus_async_callbacks: (return_callback, error_callback) = parent_method._dbus_async_callbacks keywords[ return_callback] = lambda *retval: _method_reply_return( connection, message, method_name, signature, *retval) keywords[ error_callback] = lambda exception: _method_reply_error( connection, message, exception) # include the sender etc. if desired if parent_method._dbus_sender_keyword: keywords[ parent_method._dbus_sender_keyword] = message.get_sender() if parent_method._dbus_path_keyword: keywords[parent_method._dbus_path_keyword] = message.get_path() if parent_method._dbus_rel_path_keyword: path = message.get_path() rel_path = path for exp in self._locations: # pathological case: if we're exported in two places, # one of which is a subtree of the other, then pick the # subtree by preference (i.e. minimize the length of # rel_path) if exp[0] is connection: if path == exp[1]: rel_path = '/' break if exp[1] == '/': # we already have rel_path == path at the beginning continue if path.startswith(exp[1] + '/'): # yes we're in this exported subtree suffix = path[len(exp[1]):] if len(suffix) < len(rel_path): rel_path = suffix rel_path = ObjectPath(rel_path) keywords[parent_method._dbus_rel_path_keyword] = rel_path if parent_method._dbus_destination_keyword: keywords[ parent_method. _dbus_destination_keyword] = message.get_destination() if parent_method._dbus_message_keyword: keywords[parent_method._dbus_message_keyword] = message if parent_method._dbus_connection_keyword: keywords[parent_method._dbus_connection_keyword] = connection # call method retval = candidate_method(self, *args, **keywords) # we're done - the method has got callback functions to reply with if parent_method._dbus_async_callbacks: return # otherwise we send the return values in a reply. if we have a # signature, use it to turn the return value into a tuple as # appropriate if signature is not None: signature_tuple = tuple(signature) # if we have zero or one return values we want make a tuple # for the _method_reply_return function, otherwise we need # to check we're passing it a sequence if len(signature_tuple) == 0: if retval is None: retval = () else: raise TypeError( '%s has an empty output signature but did not return None' % method_name) elif len(signature_tuple) == 1: retval = (retval, ) else: if isinstance(retval, Sequence): # multi-value signature, multi-value return... proceed # unchanged pass else: raise TypeError( '%s has multiple output values in signature %s but did not return a sequence' % (method_name, signature)) # no signature, so just turn the return into a tuple and send it as normal else: if retval is None: retval = () elif (isinstance(retval, tuple) and not isinstance(retval, Struct)): # If the return is a tuple that is not a Struct, we use it # as-is on the assumption that there are multiple return # values - this is the usual Python idiom. (fd.o #10174) pass else: retval = (retval, ) _method_reply_return(connection, message, method_name, signature, *retval) except Exception as exception: # send error reply _method_reply_error(connection, message, exception)
def scan(self, bdaddr, addr_type, include_descriptor: bool): """ bdaddr - Remote BD_ADDR """ def run_mainloop(): mainloop.run() mainloop_thread = threading.Thread(target=run_mainloop, args=[]) mainloop_thread.start() try: try: target = Peripheral(bdaddr, iface=self.devid, addrType=addr_type) except BTLEDisconnectError as e: logger.error("BTLEDisconnectError") print(ERROR_INDENT, e, sep='') return services = target.getServices() print("Number of services: %s\n\n" % len(services)) # Show service for service in services: logger.debug('Start handle: {}'.format(service.hndStart)) logger.debug('End handle: {}'.format(service.hndEnd)) try: characteristics = [] characteristics = service.getCharacteristics() except BTLEException as e: logger.warning("BTLEException") print(WARNING_INDENT, e, sep='') # continue print( blue('Service'), '(0x%04x - 0x%04x, %s characteristics)' % (service.hndStart, service.hndEnd, len(characteristics))) print( indent + 'Handle: 0x%04x' % service.hndStart ) # ", "\"attr handle\" by using gatttool -b <BD_ADDR> --primary print(indent + 'Type: (May be primary service 0x2800)') print(indent + 'Value (Service UUID): ', blue(str(service.uuid).replace(sig_uuid_suffix, '')), end=' ') try: print( '(' + services_spec['0x' + ("%s" % service.uuid)[4:8].upper()]['Name'] + ')', '\x1B[0m') except KeyError: print('(' + red('unknown') + ')', '\x1B[0m') print( indent + 'Permission: Read Only, No Authentication, No Authorization\n' ) # Show characteristic for characteristic in characteristics: descriptors = [] # 对每个 characteristic 都获取 descriptor 会很耗时 # 有些设备会因此断开连接。于是这里提供了一个是否获取 descriptor 的选项 if include_descriptor: descriptors = characteristic.getDescriptors() try: print(indent + yellow('Characteristic'), '(%s descriptors)' % len(descriptors)) #print('-'*8) print(indent * 2 + 'Handle: %#06x' % (characteristic.getHandle() - 1)) print(indent * 2 + 'Type: 0x2803 (Characteristic)') print(indent * 2 + 'Value:') print(indent * 3 + 'Characteristic properties:', green(characteristic.propertiesToString())) print(indent * 3 + 'Characteristic value handle: %#06x' % characteristic.getHandle()) print( indent * 3 + 'Characteristic UUID: ', green( str(characteristic.uuid).replace( sig_uuid_suffix, '')), end=' ' ) # This UUID is also the type field of characteristic value declaration attribute. try: print('(' + characteristics_spec['0x' + ( "%s" % characteristic.uuid)[4:8].upper()]['Name'] + ')') except KeyError: print('(' + red('unknown') + ')') print( indent * 3 + 'Permission: Read Only, No Authentication, No Authorization' ) if characteristic.supportsRead(): print(indent + yellow('Characteristic value')) print(indent * 2 + 'Handle:', green('%#06x' % characteristic.getHandle())) print( indent * 2 + 'Type:', str(characteristic.uuid).replace( sig_uuid_suffix, '')) print(indent * 2 + 'Value:', green(str(characteristic.read()))) print( indent * 2 + 'Permission: Higher layer profile or implementation-specific' ) except BTLEException as e: print(' ' + str(e)) # Show descriptor for descriptor in descriptors: try: print(indent + yellow('Descriptor')) print(indent * 2 + 'Handle:', green('%#06x' % descriptor.handle)) print(indent * 2 + 'Type:', str(descriptor.uuid).replace( sig_uuid_suffix, ''), end=' ') try: print('(' + descriptors_spec['0x' + ( "%s" % descriptor.uuid)[4:8].upper()]['Name'] + ')') except KeyError: print('(Unknown descriptor)') print(indent * 2 + 'Value:', green(str(descriptor.read()))) print(indent * 2 + 'Permissions:') except BTLEException as e: print(indent * 2 + str(e)) print() print() # Set remote device untursted output = subprocess.check_output(' '.join( ['bluetoothctl', 'untrust', bdaddr]), stderr=STDOUT, timeout=60, shell=True) logger.info(output.decode()) # output = subprocess.check_output( # ' '.join(['sudo', 'systemctl', 'stop', 'bluetooth.service']), # stderr=STDOUT, timeout=60, shell=True) # output = subprocess.check_output( # ' '.join(['sudo', 'rm', '-rf', '/var/lib/bluetooth/' + \ # self.hci_bdaddr + '/' + bdaddr.upper()]), # stderr=STDOUT, timeout=60, shell=True) # output = subprocess.check_output( # ' '.join(['sudo', 'systemctl', 'start', 'bluetooth.service']), # stderr=STDOUT, timeout=60, shell=True) finally: if self.agent_registered: self.agent_mgr_1_iface.UnregisterAgent( ObjectPath(self.bluescan_agent.path)) logger.info('Unregistered Agent object') mainloop.quit()
def scan(self, addr: str, addr_type: str) -> GattScanResult: logger.debug("Entered scan()") try: def run_mainloop(): # logger.info('mainloop run\n' # "mainloop: {}".format(mainloop)) mainloop.run() # logger.info('mainloop stop') mainloop_thread = threading.Thread(target=run_mainloop, args=[]) mainloop_thread.start() self.result.addr = addr.upper() self.result.addr_type = addr_type if self.result.addr_type is None: self.result.addr_type = self.determine_addr_type() self.gatt_client = GattClient(self.iface) logger.debug("Address: {}\n".format(self.result.addr) + "Address type: {}".format(self.result.addr_type)) try: self.spinner.start("Connecting...") self.gatt_client.connect(self.result.addr, self.result.addr_type) except TimeoutError: raise RuntimeError( "Failed to connect remote device {}".format(addr)) try: self.spinner.text = "Discovering all primary services..." services = self.gatt_client.discover_all_primary_services() except TimeoutError: self.spinner.text = "Reconnecting..." self.gatt_client.reconnect() try: self.spinner.text = "Discovering all primary services..." services = self.gatt_client.discover_all_primary_services() except TimeoutError: raise RuntimeError( "Can't discover primary service, the remote device may be not connectable" ) logger.debug("number of services: {}".format(len(services))) for service in services: self.result.add_service(service) logger.debug( "Service\n" + "start_handle: 0x{:04x}\n".format(service.start_handle) + "end_handle: 0x{:04x}\n".format(service.end_handle) + "UUID: {}".format(service.uuid)) self.spinner.text = "Discovering all characteristics of each service..." for service in services: try: self.spinner.text = "Discovering all characteristics of service 0x{:04x}...".format( service.start_handle) characts = self.gatt_client.discover_all_characts_of_a_service( service) logger.debug("characts: {}".format(characts)) for charact in characts: logger.debug("Characteristics\n" + "Handle: 0x{:04x}\n".format( charact.declar.handle) + "Properties: 0x{:02X}\n".format( charact.declar.value.properties) + "Value handle: 0x{:04x}\n".format( charact.declar.value.handle) + "UUID: {}".format( charact.declar.value.uuid)) service.add_charact(charact) except TimeoutError as e: # When discovering all characteristics fo a service encounters a timeout, # reconnect and try once again self.spinner.text = "Reconnecting..." self.gatt_client.reconnect() try: characts = self.gatt_client.discover_all_characts_of_a_service( service) for charact in characts: service.add_charact(charact) except TimeoutError as e: logger.error( "scan() \n" + "{}\n".format(e.__class__.__name__) + "Discover all characteristics of a service (start 0x{:04x} - end 0x{:04x}" .format(service.start_handle, service.end_handle)) # 这里如果不重连,wireshark 会显示 server 返回的 # 第一个 ATT_READ_RSP PDU 为 malformed packet。 # 但是本身并不是 malformed packet,不知道为什么。 self.spinner.text = "Reconnecting..." self.gatt_client.reconnect() self.spinner.text = "Reading value of each characteristic..." for service in services: for charact in service.get_characts(): if CharactProperties.READ.name in charact.declar.get_property_names( ): try: self.spinner.text = "Reading value of a characteristic, value handle = 0x{:04x}...".format( charact.declar.value.handle) value = self.gatt_client.read_charact_value( charact) charact.set_value_declar( CharactValueDeclar(charact.declar.value.handle, charact.declar.value.uuid, value)) # logger.info("Characteristics Value") # print("Handle: 0x{:04x}".format(charact.value_declar.handle)) # print("Type: {}".format(charact.value_declar.type)) # print("Value: {}".format(charact.value_declar.value)) except TimeoutError: # When reading the characteristic value encounters a timeout, # reconnect and try to read once again self.spinner.text = "Reconnecting..." self.gatt_client.reconnect() try: value = self.gatt_client.read_charact_value( charact) charact.set_value_declar( CharactValueDeclar( charact.declar.value.handle, charact.declar.value.uuid, value)) except TimeoutError: value_declar = CharactValueDeclar( charact.declar.value.handle, charact.declar.value.uuid, None) value_declar.set_read_error( ReadCharactValueError("Read Timeout")) charact.set_value_declar(value_declar) except ReadCharactValueError as e: value_declar = CharactValueDeclar( charact.declar.value.handle, charact.declar.value.uuid, None) value_declar.set_read_error(e) charact.set_value_declar(value_declar) except ReadCharactValueError as e: value_declar = CharactValueDeclar( charact.declar.value.handle, charact.declar.value.uuid, None) value_declar.set_read_error(e) charact.set_value_declar(value_declar) self.spinner.text = "Discovering descriptors of each characteristic..." for service in services: characts = service.get_characts() if len(characts) == 0: continue for idx in range(0, len(characts) - 1): start_handle = characts[idx].declar.value.handle + 1 end_handle = characts[idx + 1].declar.value.handle - 1 if end_handle < start_handle: continue try: self.spinner.text = "Discovering all descriptors of characteristic 0x{:04x}...".format( characts[idx].declar.handle) descriptors = self.gatt_client.discover_all_charact_descriptors( start_handle, end_handle) logger.debug( "Number of discovered descriptors: {}".format( len(descriptors))) for descriptor in descriptors: characts[idx].add_descriptor_declar(descriptor) except TimeoutError: self.spinner.text = "Reconnecting..." self.gatt_client.reconnect() try: descriptors = self.gatt_client.discover_all_charact_descriptors( start_handle, end_handle) for descriptor in descriptors: characts[idx].add_descriptor_declar(descriptor) except TimeoutError: pass # Find descriptor of the last charactertisc in current service. start_handle = characts[-1].declar.value.handle + 1 end_handle = service.end_handle if end_handle < start_handle: continue try: self.spinner.text = "Discovering all descriptors of characteristic 0x{:04x}...".format( characts[-1].declar.handle) descriptors = self.gatt_client.discover_all_charact_descriptors( start_handle, end_handle) for descriptor in descriptors: characts[-1].add_descriptor_declar(descriptor) except TimeoutError: self.spinner.text = "Reconnecting..." self.gatt_client.reconnect() try: self.spinner.text = "Discovering all descriptors of characteristic 0x{:04x}...".format( characts[-1].declar.handle) descriptors = self.gatt_client.discover_all_charact_descriptors( start_handle, end_handle) for descriptor in descriptors: characts[-1].add_descriptor_declar(descriptor) except TimeoutError: pass self.spinner.text = "Reading value of each descriptor..." for service in services: for characts in service.get_characts(): for descriptor in characts.get_descriptors(): try: self.spinner.text = "Reading value of the descriptor 0x{:04x}... ".format( descriptor.handle) value = self.gatt_client.read_charact_descriptor( descriptor.handle) descriptor.set_value(value) except TimeoutError: # When reading the descriptor encounters a timeout, # reconnect and try to read once again self.spinner.text = "Reconnecting..." self.gatt_client.reconnect() try: value = self.gatt_client.read_charact_descriptor( descriptor.handle) descriptor.set_value(value) except TimeoutError: descriptor.set_read_error( ReadCharactDescriptorError("Read Timeout")) descriptor.set_value(None) except ReadCharactDescriptorError as e: descriptor.set_read_error(e) descriptor.set_value(None) except ReadCharactDescriptorError as e: descriptor.set_read_error(e) descriptor.set_value(None) # secondary_service_groups = req_groups(addr, addr_type, GattAttrTypes.SECONDARY_SERVICE) # include_groups = req_groups(addr, addr_type, GattAttrTypes.INCLUDE) # print(secondary_service_groups) # print(include_groups) except RuntimeError as e: logger.error("scan()\n" + "{}\n".format(e.__class__.__name__) + "{}".format(e)) finally: self.spinner.stop() if self.gatt_client is not None: self.gatt_client.close() if self.agent_registered: self.agent_mgr_1_iface.UnregisterAgent( ObjectPath(self.bluescan_agent.path)) logger.debug("Unregistered agent object") mainloop.quit() self.agent_registered = False try: # Reset and clean bluetooth service output = subprocess.check_output( ' '.join(['bluetoothctl', 'untrust', addr]), stderr=STDOUT, timeout=60, shell=True) # 这个 untrust 用于解决本地自动重连被扫描设备的问题 logger.debug(output.decode()) except subprocess.CalledProcessError: pass output = subprocess.check_output(' '.join( ['sudo', 'systemctl', 'stop', 'bluetooth.service']), stderr=STDOUT, timeout=60, shell=True) output = subprocess.check_output( ' '.join(['sudo', 'rm', '-rf', '/var/lib/bluetooth/' + \ self.hci_bdaddr + '/' + addr.upper()]), stderr=STDOUT, timeout=60, shell=True) output = subprocess.check_output(' '.join( ['sudo', 'systemctl', 'start', 'bluetooth.service']), stderr=STDOUT, timeout=60, shell=True) return self.result