Example #1
0
def select_devices():
    context = Context()
    devices = context.list_devices(subsystem="usb")
    num = 1
    for dev in devices:
        print "%02d- %s %s SerialNo: %s %s" % (
            num, dev.attributes.get('idVendor'),
            dev.attributes.get('idProduct'), dev.attributes.get('serial'),
            dev.attributes.get('manufacturer'))
        num += 1
    try:
        choice = int(raw_input("Select device: [1-%d] " % (num)))
    except ValueError:
        print "Please enter a number!"
        quit()

    assert choice >= 1 and choice <= num, "Please enter a valid number"

    num = 1
    for dev in devices:
        if num == choice:
            global verbose
            if verbose:
                print "Selected device: "
                display_device_attributes(dev)
            global monitored_idVendor
            monitored_idVendor = dev.attributes.get('idVendor')
            global monitored_idProduct
            monitored_idProduct = dev.attributes.get('idProduct')
            global monitored_serial
            monitored_serial = dev.attributes.get('serial')
            global monitored_path
            monitored_path = dev.device_path
            break
        num += 1
Example #2
0
    def map_nvme(self, info, acpihandles):
        mapped = info[-1]
        num_of_nvme_slots = info[-2]
        ctx = Context()
        for i in filter(lambda x: x.attributes.get('path') in acpihandles,
                        ctx.list_devices(subsystem='acpi')):
            acpi_handle = i.attributes.get('path')
            try:
                phys_node = Devices.from_path(ctx,
                                              f'{i.sys_path}/physical_node')
            except DeviceNotFoundAtPathError:
                return info

            slot = acpihandles[acpi_handle]
            for nvme in filter(lambda x: x.sys_name.startswith('nvme'),
                               phys_node.children):
                mapped[slot] = nvme.sys_name
                break
            else:
                mapped[slot] = None

            if len(mapped) == num_of_nvme_slots:
                return info

        return info
Example #3
0
def select_devices():
    context = Context()
    devices = context.list_devices(subsystem="usb") 
    num = 1
    for dev in devices:
        print "%02d- %s %s SerialNo: %s %s" % (num, dev.attributes.get('idVendor'), dev.attributes.get('idProduct'), dev.attributes.get('serial'), dev.attributes.get('manufacturer'))
        num += 1
    try:
        choice = int(raw_input("Select device: [1-%d] " % (num)))
    except ValueError:
        print "Please enter a number!"
        quit()

    assert choice >=1 and choice <= num, "Please enter a valid number"

    num = 1
    for dev in devices:
        if num == choice:
            global verbose
            if verbose: 
                print "Selected device: "
                display_device_attributes(dev)
            global monitored_idVendor
            monitored_idVendor = dev.attributes.get('idVendor')
            global monitored_idProduct 
            monitored_idProduct = dev.attributes.get('idProduct')
            global monitored_serial
            monitored_serial = dev.attributes.get('serial')
            global monitored_path
            monitored_path = dev.device_path
            break
        num +=1
Example #4
0
    def __init__(self, player):
        try:
            self.player = player
            
             # Create a context, create monitor at kernel level, select devices
            context = Context()
            monitor = Monitor.from_netlink(context)
            monitor.filter_by(subsystem='input')

            self.observer = MonitorObserver(monitor, self.usb_event_callback, name="keyboard")
            self.observer.start()

            self.pressed = False    # Stores state of press
            
            # Check if there is already a keyboard attached
            for device in context.list_devices(subsystem='input'):
                if device.get('ID_INPUT_KEYBOARD') == '1':
                    if device.get('DEVNAME') != None:
                        device_name = InputDevice(device.get('DEVNAME'))
                        thread = threading.Thread(target=self.keyboard_event, args=(device_name,), daemon=True)
                        thread.start()
                        continue


        except Exception as ex:
            print('Keyboard Control: Error starting: ' + str(ex))
Example #5
0
def get_devs(): 

    dmap = dict()
    
    c = Context()

    for d in c.list_devices():
        dmap[ d.device_path ] = D(d)

    for d in list(dmap.itervalues()):
        p = d.d.parent
        if p:
            if p.device_path in dmap:
                pd = dmap[ p.device_path ]
                
            else:
                #print '*** Missing parent: ({0}: {1} => {2})'.format(d.d.sys_name, d.d.device_path, p.device_path)
                pd = D( p )
                dmap[ p.device_path ] = pd
                if p.parent:
                    if p.parent.device_path in dmap:
                        pd.parent = dmap[ p.parent.device_path ]
                        pd.parent.children.append( pd )
                    #else:
                    #    print '     *** Missing parent is missing parent! ', p.parent.device_path
                
            d.parent = pd
            pd.children.append( d )
    return dmap
Example #6
0
def get_device_info(device_path: os.path) -> Result:
    """
    Tries to figure out what type of device this is

    :param device_path: os.path to device.
    :return: Result with Ok or Err
    """
    context = Context()
    sysname = device_path.basename()

    for device in context.list_devices(subsystem='block'):
        if sysname == device.sys_name:
            # Ok we're a block device
            device_id = get_uuid(device)
            media_type = get_media_type(device)
            capacity = get_size(device)
            if capacity is None:
                capacity = 0
            fs_type = get_fs_type(device)
            return Ok(
                Device(id=device_id,
                       name=sysname,
                       media_type=media_type,
                       capacity=capacity,
                       fs_type=fs_type))
    return Err("Unable to find device with name {}".format(device_path))
Example #7
0
def get_connected_devices_names():
    udev_context = Context()
    devs = udev_context.list_devices(subsystem='block', DEVTYPE='disk')
    devs = list(filter(is_usb, devs))
    devs = [item.device_node for item in devs]

    return devs
Example #8
0
    def get_all_usb_devices():
        context = Context()

        devices = []
        for device in context.list_devices(subsystem="usb", DEVTYPE="usb_device"):
            devices.append(device)

        return devices
Example #9
0
def get_device_info(device_node):
    udev_context = Context()
    devs = udev_context.list_devices(subsystem='block', DEVTYPE='disk')
    devs = list(filter(is_usb, devs))

    for dev in devs:
        if dev.device_node == device_node:
            return get_info_from_device(dev)
Example #10
0
def main():
    """ main() -- entry point for this program
    """
    global SEND_SMS
    global DAEMONIZE
    global PID_FILE

    # Parse CLI options
    args = parse_cli()

    DAEMONIZE = args.daemonize
    PID_FILE = args.pid_file
    SEND_SMS = args.sms

    context = Context()

    # Populate list of current USB devices
    for device in context.list_devices(subsystem="usb"):
        busnum = get_device_info(device, "busnum")
        devnum = get_device_info(device, "devnum")
        id_product = get_device_info(device, "idProduct")
        id_vendor = get_device_info(device, "idVendor")
        manufacturer = get_device_info(device, "manufacturer")
        product = get_device_info(device, "product")

        if busnum:
            USB_DEVICES.append((device.device_path, busnum, devnum, id_vendor,
                                id_product, manufacturer, product))

    monitor = Monitor.from_netlink(context)

    monitor.filter_by(subsystem='usb')
    observer = MonitorObserver(monitor)

    observer.connect('device-event', device_event)
    monitor.start()

    if DAEMONIZE:
        usbwatch_pid = os.fork()

        if usbwatch_pid != 0:
            return os.EX_OK

    write_pid_file(PID_FILE, os.getpid())

    xprint("[+] usb-watch by Daniel Roberson @dmfroberson Started. PID %s" % \
        os.getpid())

    try:
        glib.MainLoop().run()
    except KeyboardInterrupt:
        print "[-] Caught Control-C. Andross has ordered us to take you down."
        print "[-] Exiting."

    return os.EX_OK
Example #11
0
def is_block_device(device_path: str) -> Result:
    """
    Check if a device is a block device
    :param device_path: str path to the device to check.
    :return: Result with Ok or Err
    """
    context = Context()
    sysname = os.path.basename(device_path)
    for device in context.list_devices(subsystem='block'):
        if device.sys_name == sysname:
            return Ok(True)
    return Err("Unable to find device with name {}".format(device_path))
def main():
    ctx = Context()
    for device in ctx.list_devices(subsystem='input', ID_INPUT_MOUSE=True):
        if device.sys_name.startswith('event'):
            name = device.parent['NAME']
            try:
                is_touchpad = device.asbool('ID_INPUT_TOUCHPAD')
            except KeyError:
                is_touchpad = False
            print(name, end='')
            if is_touchpad:
                print(' (touchpad)', end='')
            print()
Example #13
0
def main():
    ctx = Context()
    for device in ctx.list_devices(subsystem='input', ID_INPUT_MOUSE=True):
        if device.sys_name.startswith('event'):
            name = device.parent['NAME']
            try:
                is_touchpad = device.asbool('ID_INPUT_TOUCHPAD')
            except KeyError:
                is_touchpad = False
            print(name, end='')
            if is_touchpad:
                print(' (touchpad)', end='')
            print()
Example #14
0
def enumate_keyboard_event_devices(context: pyudev.Context):
    devices = []
    for device in context.list_devices():
        if 'ID_INPUT_KEYBOARD' in device:
            m = re_is_event_path.match(device.sys_path)
            if m is not None:
                p = '/dev/input/' + m[2]
                try:
                    s = os.stat(p)
                except FileNotFoundError:
                    continue
                if stat.S_ISCHR(s.st_mode):
                    devices.append(p)
    return devices
Example #15
0
def getem( subsys ):
    c = Context()

    tops = dict()

    for d in c.list_devices(subsystem=subsys):
        if d.parent and d.parent.subsystem == subsys:
            if not d.parent.device_path in tops:
                tops[ d.parent.device_path ] = TopDev( d.parent )
            tops[ d.parent.device_path ].sub.append( d )
        else:
            if not d.device_path in tops:
                tops[ d.device_path ] = TopDev( d )

    return tops.values()
Example #16
0
    def start_listener(self):
        """Create a context, create monitor at kernel level, select devices"""
        context = Context()
        monitor = Monitor.from_netlink(context)
        monitor.filter_by(subsystem='block')

        observer = MonitorObserver(monitor,
                                   self.event_callback,
                                   name="storage_monitor")
        observer.start()

        # Check if there is already a usb attached
        for device in context.list_devices(subsystem='block',
                                           DEVTYPE='partition'):
            if re.search('/dev/s.+', device.get('DEVNAME')):
                self.usb_add(device)
                continue

        # Check if there is already an sd attached
        for device in context.list_devices(subsystem='block',
                                           DEVTYPE='partition'):
            if re.search('/dev/mmcblk1p1', device.get('DEVNAME')):
                self.sd_add(device)
                continue
Example #17
0
    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
Example #18
0
def find(ctx, name):
    """Find device by name."""
    conf = settings.devices.get(name, dict())
    if conf.get('type') == 'command':
        return conf, name, name

    uuids = ctx.obj['uuids']
    context = Context()
    for dev in iter(context.list_devices()):
        if 'ID_FS_TYPE' in dev:
            if name == uuids.get(dev.get('ID_FS_UUID')):
                return (settings.devices[name], dev['DEVNAME'],
                        settings.devices[name].get('label',
                                                   dev.get('ID_FS_LABEL')))

    print('Device "%s" not found.' % name)
    sys.exit(1)
class UdevManager(object):
    """Manger mixin that takes care of udev event handling."""

    def __init__(self):
        # Create connection to udev.
        self.udev = Context()


    def start_udev_tasks(self):
        """Start monitoring system devices using udev."""

        def udev_handler(action, device):
            if device.subsystem in ('net', 'block'):
                self.raise_event((action, device.subsystem), device)
                self.raise_event((action, device.subsystem, device.sys_name), device)

        # Monitor interesting system events.
        self.monitor = Monitor.from_netlink(self.udev)
        self.observer = MonitorObserver(self.monitor, from_thread(udev_handler))
        self.observer.start()

        # Trigger missed events.
        reactor.callLater(0, self.raise_missed_udev_events)


    def raise_missed_udev_events(self):
        """
        Raise events for all present net and block devices.

        This is intended to be executed right after we subscribe
        to regular udev event notifications to get up to speed with
        current state of the system.

        Raised events are:
            ('add', subsystem)            -> device
            ('add', subsystem, sys_name)  -> device
        """

        for subsystem in ('net', 'block'):
            for device in self.udev.list_devices(subsystem=subsystem):
                self.raise_event(('add', subsystem), device)
                self.raise_event(('add', subsystem, device.sys_name), device)
Example #20
0
    def _device_name(self, dev):
        self.dev_id = str(dev.sys_path)
        # check is a wifi?
        C = Context()
        dev_childs = C.list_devices(subsystem='net')
        for c in dev_childs:
            if c.parent == dev:
                self.dev_type = 'net'
                if ( 'ID_VENDOR_FROM_DATABASE' in c.keys() ) and ( 'ID_MODEL_FROM_DATABASE' in c.keys()  ):
                    self.dev_name = "%s %s" % (str(c['ID_VENDOR_FROM_DATABASE']), str(c['ID_MODEL_FROM_DATABASE']))
                    break
                else:
                    self.dev_name = 'Unknown wifi adapter'
                    break
            

        if len(self.dev_name) != 0:
            return

        # check is a video?
        if 'PCI_ID' in dev.keys():
            pci_id = dev['PCI_ID']
            vendor_id = pci_id[:4]

            if vendor_id == '10DE':
                self.dev_name = 'NVIDIA video adapter'
                nv = NvidiaVersion()
                if nv.nvidia_board_name is not None:
                    self.dev_name = 'NVIDIA %s' % nv.nvidia_board_name
                if nv.nvidia_driver_ver_list is not None:
                    major_module_ver = nv.nvidia_driver_ver_list[0]
                    if major_module_ver == '173':
                        self.dev_driver = 'nvidia-173xx'
                    elif major_module_ver == '96':
                        self.dev_driver = 'nvidia-96xx'
            elif vendor_id == '1002':
                self.dev_name = 'ATI video adapter'

            self.dev_type = 'video'
        else:
            self.dev_name = 'Unknown videoadapter'
            self.dev_type = 'video'
Example #21
0
    def __init__(self):
        #Try to get the Sentelic touchpad device path from udev, fallback to
        #hardcoded one
        try:
            from pyudev import Context
            ctx = Context()

            for dev in ctx.list_devices(subsystem='input', ID_INPUT_MOUSE=True):
                if dev.sys_name.startswith('input') and 'serio' in dev.sys_path:
                    SYS_PATH = dev.sys_path.split('input')[0]
        except ImportError:
            SYS_PATH = "/sys/devices/platform/i8042/serio4"

        self.REG_FILE = os.path.join(SYS_PATH, 'setreg')
        self.STATE_FILE = os.path.join(SYS_PATH, 'flags')
        print "Info: Sentelic device found at %s " % SYS_PATH

        self.__enable_register()
        self.state = False
        self.setState(True, True)
Example #22
0
    def __init__(self,
                 serial_num,
                 obj,
                 refresh=0,
                 baudrate=115200,
                 bytesize=8,
                 parity='N',
                 stopbits=2,
                 timeout=400,
                 debug=False):
        # Name and type of the connection peer
        self.name = ''
        self.type = ''

        self.serial_num = serial_num
        self.object = obj
        self.baudrate = baudrate
        self.bytesize = bytesize
        self.parity = parity
        self.stopbits = stopbits
        self.timeout = timeout

        self._debug = debug

        if refresh > 0:
            self._refresh = refresh

        self._updateTimer = LoopingCall(self.update)

        context = Context()
        for device in context.list_devices(subsystem='tty'):
            if device.get('ID_SERIAL_SHORT') == self.serial_num:
                self._devname = device['DEVNAME']
                self.Connect()

        cm = Monitor.from_netlink(context)
        cm.filter_by(subsystem='tty')
        observer = MonitorObserver(cm,
                                   callback=self.ConnectionMCallBack,
                                   name='monitor-observer')
        observer.start()
Example #23
0
    def __init__(self, serial_num, obj, refresh=0, baudrate=115200):
        # Name and type of the connection peer
        self.name = ''
        self.type = ''

        self.object = obj
        self.baudrate = baudrate
        self.serial_num = serial_num
        self.devpath = ''

        if refresh > 0:
            self._refresh = refresh

        self.device = pylibftdi.Device(mode='b',
                                       device_id=self.serial_num,
                                       lazy_open=True)
        self.device._baudrate = self.baudrate

        self._updateTimer = LoopingCall(self.update)
        self._updateTimer.start(self._refresh)
        self._readTimer = LoopingCall(self.read)
        self._readTimer.start(self._refresh / 10)

        # the following will start a small daemon to monitor the connection and call ConnectionMade and ConnectionLost
        # pyftdi doesn't seem to support this so this pyudev daemon is necessary

        context = Context()
        # find out whether device is already connected and if that is the case open ftdi connection
        for device in context.list_devices(subsystem='usb'):
            if device.get('ID_SERIAL_SHORT') == self.serial_num:
                for ch in device.children:
                    if 'tty' not in ch.get('DEVPATH'):
                        self.devpath = ch.get('DEVPATH')
                        self.ConnectionMade()

        cm = Monitor.from_netlink(context)
        cm.filter_by(subsystem='usb')
        observer = MonitorObserver(cm,
                                   callback=self.ConnectionMCallBack,
                                   name='monitor-observer')
        observer.start()
Example #24
0
def autodiscover():
    """Search the device through udev entries for a rdm630 and
    return the serial device string if we can find one or None
    otherwise"""
    from pyudev import Context

    context = Context()
    path = None

    for device in context.list_devices(subsystem="usb-serial"):
        # this check is not really reliable when multiple
        # usb-to-serial converters are attached (for example
        # when there's an arduino board plugged in too).
        if device.driver == "ftdi_sio":
            if device.parent["PRODUCT"] == USB_CONVERTER_PRODUCT_CODE:
                path = device["DEVPATH"].rsplit("/", 1)[1]
                break

    if not path:
        return None
    return os.path.join(context.device_path, path)
Example #25
0
def autodiscover():
    """Search the device through udev entries for a rdm630 and
    return the serial device string if we can find one or None
    otherwise"""
    from pyudev import Context

    context = Context()
    path = None

    for device in context.list_devices(subsystem="usb-serial"):
        # this check is not really reliable when multiple
        # usb-to-serial converters are attached (for example
        # when there's an arduino board plugged in too).
        if device.driver == "ftdi_sio":
            if device.parent["PRODUCT"] == USB_CONVERTER_PRODUCT_CODE:
                path = device["DEVPATH"].rsplit("/", 1)[1]
                break

    if not path:
        return None
    return os.path.join(context.device_path, path)
Example #26
0
    def devices(self):
        """Wait for new DS4 devices to appear."""
        context = Context()

        existing_devices = context.list_devices(subsystem="hidraw")
        future_devices = self._get_future_devices(context)

        for hidraw_device in itertools.chain(existing_devices, future_devices):
            hid_device = hidraw_device.parent
            if hid_device.subsystem != "hid":
                continue

            cls = HID_DEVICES.get(hid_device.get("HID_NAME"))
            if not cls:
                continue

            for child in hid_device.parent.children:
                event_device = child.get("DEVNAME", "")
                if event_device.startswith("/dev/input/event"):
                    break
            else:
                continue


            try:
                device_addr = hid_device.get("HID_UNIQ", "").upper()
                if device_addr:
                    device_name = "{0} {1}".format(device_addr,
                                                   hidraw_device.sys_name)
                else:
                    device_name = hidraw_device.sys_name

                yield cls(name=device_name,
                          addr=device_addr,
                          type=cls.__type__,
                          hidraw_device=hidraw_device.device_node,
                          event_device=event_device)

            except DeviceError as err:
                self.logger.error("Unable to open DS4 device: {0}", err)
Example #27
0
    def devices(self):
        """Wait for new DS4 devices to appear."""
        context = Context()

        existing_devices = context.list_devices(subsystem="hidraw")
        future_devices = self._get_future_devices(context)

        for hidraw_device in itertools.chain(existing_devices, future_devices):
            hid_device = hidraw_device.parent
            if hid_device.subsystem != "hid":
                continue

            cls = HID_DEVICES.get(hid_device.get("HID_NAME"))
            if not cls:
                continue

            for child in hid_device.parent.children:
                event_device = child.get("DEVNAME", "")

                if event_device.startswith("/dev/input/event"):
                    break
            else:
                continue

            try:
                device_addr = hid_device.get("HID_UNIQ", "").upper()
                if device_addr:
                    device_name = "{0} {1}".format(device_addr,
                                                   hidraw_device.sys_name)
                else:
                    device_name = hidraw_device.sys_name

                yield cls(name=device_name,
                          addr=device_addr,
                          type=cls.__type__,
                          hidraw_device=hidraw_device.device_node,
                          event_device=event_device)

            except DeviceError as err:
                self.logger.error("Unable to open DS device: {0}", err)
Example #28
0
    def detect(self):

        # first check to see if this is a BHYVE instance
        manufacturer = self.middleware.call_sync(
            'system.dmidecode_info')['system-product-name']
        if manufacturer == 'BHYVE':
            # bhyve host configures a scsi_generic device that when sent an inquiry will
            # respond with a string that we use to determine the position of the node
            ctx = Context()
            for i in ctx.list_devices(subsystem='scsi_generic'):
                if (model := i.attributes.get('device/model')) is not None:
                    model = model.decode().strip() if isinstance(
                        model, bytes) else model.strip()
                    if model == 'TrueNAS_A':
                        self.NODE = 'A'
                        self.HARDWARE = manufacturer
                        break
                    elif model == 'TrueNAS_B':
                        self.NODE = 'B'
                        self.HARDWARE = manufacturer
                        break

            return self.HARDWARE, self.NODE
Example #29
0
    def devices(self):
        """Wait for new DS4 devices to appear."""
        context = Context()

        existing_devices = context.list_devices(subsystem="hidraw")
        future_devices = self._get_future_devices(context)

        for hidraw_device in itertools.chain(existing_devices, future_devices):
            hid_device = hidraw_device.parent

            if hid_device.subsystem != "hid":
                continue

            if hid_device["HID_NAME"] not in (HidrawBluetoothDS4Device.hid_name(),
                                              HidrawUSBDS4Device.hid_name()):
                continue

            for child in hid_device.parent.children:
                event_device = child.get("DEVNAME", "")
                if event_device.startswith("/dev/input/event"):
                    break
            else:
                continue

            try:
                if hid_device["HID_NAME"] == HidrawBluetoothDS4Device.hid_name():
                    yield HidrawBluetoothDS4Device(hidraw_device.device_node,
                                                   event_device, "bluetooth",
                                                   hid_device["HID_UNIQ"],
                                                   hidraw_device.sys_name)
                elif hid_device["HID_NAME"] == HidrawUSBDS4Device.hid_name():
                    yield HidrawUSBDS4Device(hidraw_device.device_node,
                                             event_device, "usb",
                                             hidraw_device.sys_name)
            except DeviceError as err:
                self.logger.error("Unable to open DS4 device: {0}", err)
Example #30
0
def test_udev_list_iterate_mock():
    libudev = Mock(name='libudev')
    items = [('spam', 'eggs'), ('foo', 'bar')]
    with pytest.libudev_list(libudev, 'udev_enumerate_get_list_entry', items):
        udev_list = libudev.udev_enumerate_get_list_entry()
        assert list(_util.udev_list_iterate(libudev,
                                            udev_list)) == [('spam', 'eggs'),
                                                            ('foo', 'bar')]


def raise_valueerror():
    raise ValueError('from function')


_CHAR_DEVICES = list(_CONTEXT.list_devices(subsystem="tty"))


@pytest.mark.skipif(len(_CHAR_DEVICES) == 0, reason='no tty devices')
@given(strategies.sampled_from(_CHAR_DEVICES))
@settings(max_examples=5)
def test_get_device_type_character_device(a_device):
    """
    Check that the device type of a character device is actually char.
    """
    assert _util.get_device_type(a_device.device_node) == 'char'


_BLOCK_DEVICES = list(_CONTEXT.list_devices(subsystem="block"))

Example #31
0
class RemovableDeviceComboBox(QComboBox):
    """ComboBox for choosing from a list of removable devices."""
    usbPresent = Signal(bool)

    def __init__(self, parent=None):
        super(RemovableDeviceComboBox, self).__init__(parent)

        self.info = Info()
        self._program_prefix = self.info.getProgramPrefix()
        self.usb_present = False

        self.usbPresent.emit(self.usb_present)

        self.context = Context()

        self.monitor = Monitor.from_netlink(self.context)
        self.monitor.filter_by(subsystem='block')

        self.observer = MonitorObserver(self.monitor)
        self.observer.deviceEvent.connect(self.usb_handler)

        self.monitor.start()

        self.refreshDeviceList()

    def usb_handler(self, device):

        if device.action == "add":
            if device.device_type == 'partition':

                partitions = [
                    device.device_node for device in self.context.list_devices(
                        subsystem='block', DEVTYPE='partition', parent=device)
                ]

                for p in partitions:
                    os.system("udisksctl mount --block-device {}".format(p))

                    # self.addItem(device.get('ID_FS_LABEL'), device.get(''))
                    # self.setCurrentIndex(0)

        self.refreshDeviceList()

    @Slot()
    def refreshDeviceList(self):

        self.usb_present = False

        self.clear()

        self.addItem(self._program_prefix, self._program_prefix)

        removable = [
            device for device in self.context.list_devices(subsystem='block',
                                                           DEVTYPE='disk')
            if device.attributes.asstring('removable') == '1'
        ]

        part_index = 0

        for device in removable:

            partitions = [
                device.device_node for device in self.context.list_devices(
                    subsystem='block', DEVTYPE='partition', parent=device)
            ]

            # print("All removable partitions: {}".format(", ".join(partitions)))
            #
            # print("Mounted removable partitions:")

            for p in psutil.disk_partitions():
                if p.device in partitions:
                    # print("Mounted partition: {}: {}".format(p.device, p.mountpoint))
                    self.addItem(p.mountpoint, p.device)
                    self.usb_present = True
                    part_index += 1

        self.setCurrentIndex(part_index)

        self.usbPresent.emit(self.usb_present)

    @Slot()
    def ejectDevice(self):

        if not self.usb_present:
            # print("USB NOT PRESENT")
            return

        index = self.currentIndex()

        if index == 0:
            # print("CANT UMOUNT HOME")
            return

        device = self.itemData(index)

        self.setCurrentIndex(0)

        os.system("udisksctl unmount --block-device {}".format(device))
        os.system("udisksctl power-off --block-device {}".format(device))

        self.refreshDeviceList()
Example #32
0
# -*- coding: utf-8 -*-

from pyudev import Context
import sys

def uni(s):
    us = s.decode('utf-8', 'ignore')
    return us

#sys.setdefaultencoding("UTF-8")
context = Context()
for dev in context.list_devices():
    print "Device: %s" % dev.sys_path
    print "  Name: %s" % dev.sys_name
    print "  Driver: %s" % dev.driver
    if dev.parent is not None:
        print "  Parent: %s" % dev.parent.sys_path
    print "  Keys:"
    for m in dev.keys():
        print "    %s = %s" % (m, dev[m])
    print "  Attr:"
    for a in dev.attributes.keys():
        print "    %s = %s" % (uni(a), uni(dev.attributes[a]))

Example #33
0
class RazerDaemon(DBusService):
    """
    Daemon class

    This class sets up the main run loop which serves DBus messages. The logger is initialised
    in this module as well as finding and initialising devices.

    Serves the following functions via DBus
    * getDevices - Returns a list of serial numbers
    * enableTurnOffOnScreensaver - Starts/Continues the run loop on the screensaver thread
    * disableTurnOffOnScreensaver - Pauses the run loop on the screensaver thread
    """

    BUS_PATH = 'org.razer'

    def __init__(self,
                 verbose=False,
                 log_dir=None,
                 console_log=False,
                 run_dir=None,
                 config_file=None,
                 test_dir=None):

        # Check if process exists
        exit_code = subprocess.call(['pgrep', 'razer-service'],
                                    stderr=subprocess.DEVNULL,
                                    stdout=subprocess.DEVNULL)

        if exit_code == 0:
            print("Daemon already exists. Please stop that one.",
                  file=sys.stderr)
            exit(-1)

        setproctitle.setproctitle('razer-service')

        # Expanding ~ as python doesnt do it by default, also creating dirs if needed
        if log_dir is not None:
            log_dir = os.path.expanduser(log_dir)
            os.makedirs(log_dir, mode=0o750, exist_ok=True)
        if run_dir is not None:
            run_dir = os.path.expanduser(run_dir)
            os.makedirs(run_dir, mode=0o750, exist_ok=True)
        if config_file is not None:
            config_file = os.path.expanduser(config_file)
            os.makedirs(os.path.dirname(config_file),
                        mode=0o750,
                        exist_ok=True)

        self._test_dir = test_dir
        self._data_dir = run_dir
        self._config_file = config_file
        self._config = configparser.ConfigParser()
        self.read_config(config_file)

        # Setup DBus to use gobject main loop
        dbus.mainloop.glib.threads_init()
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
        DBusService.__init__(self, self.BUS_PATH, '/org/razer')

        self._init_signals()
        self._main_loop = GObject.MainLoop()

        # Listen for input events from udev
        self._udev_context = Context()
        udev_monitor = Monitor.from_netlink(self._udev_context)
        udev_monitor.filter_by(subsystem='input')
        self._udev_observer = MonitorObserver(udev_monitor,
                                              callback=self._udev_input_event,
                                              name='device-monitor')

        # Logging
        logging_level = logging.INFO
        if verbose or self._config.getboolean('General', 'verbose_logging'):
            logging_level = logging.DEBUG

        self.logger = logging.getLogger('razer')
        self.logger.setLevel(logging_level)
        formatter = logging.Formatter(
            '%(asctime)s | %(name)-30s | %(levelname)-8s | %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S')
        # Dont propagate to default logger
        self.logger.propagate = 0

        if console_log:
            console_logger = logging.StreamHandler()
            console_logger.setLevel(logging_level)
            console_logger.setFormatter(formatter)
            self.logger.addHandler(console_logger)

        if log_dir is not None:
            log_file = os.path.join(log_dir, 'razer.log')
            file_logger = logging.handlers.RotatingFileHandler(
                log_file, maxBytes=16777216, backupCount=10)  # 16MiB
            file_logger.setLevel(logging_level)
            file_logger.setFormatter(formatter)
            self.logger.addHandler(file_logger)

        self.logger.info("Initialising Daemon (v%s). Pid: %d", __version__,
                         os.getpid())

        # Setup screensaver thread
        self._screensaver_thread = ScreensaverThread(
            self,
            active=self._config.getboolean('Startup',
                                           'devices_off_on_screensaver'))
        self._screensaver_thread.start()

        self._razer_devices = DeviceCollection()
        self._load_devices(first_run=True)

        # Add DBus methods
        self.logger.info("Adding razer.devices.getDevices method to DBus")
        self.add_dbus_method('razer.devices',
                             'getDevices',
                             self.get_serial_list,
                             out_signature='as')
        self.logger.info(
            "Adding razer.devices.enableTurnOffOnScreensaver method to DBus")
        self.add_dbus_method('razer.devices', 'enableTurnOffOnScreensaver',
                             self.enable_turn_off_on_screensaver)
        self.logger.info(
            "Adding razer.devices.disableTurnOffOnScreensaver method to DBus")
        self.add_dbus_method('razer.devices', 'disableTurnOffOnScreensaver',
                             self.disable_turn_off_on_screensaver)
        self.logger.info("Adding razer.devices.syncEffects method to DBus")
        self.add_dbus_method('razer.devices',
                             'syncEffects',
                             self.sync_effects,
                             in_signature='b')
        self.logger.info("Adding razer.daemon.version method to DBus")
        self.add_dbus_method('razer.daemon',
                             'version',
                             self.version,
                             out_signature='s')
        self.logger.info("Adding razer.daemon.stop method to DBus")
        self.add_dbus_method('razer.daemon', 'stop', self.stop)

        # TODO remove
        self.sync_effects(
            self._config.getboolean('Startup', 'sync_effects_enabled'))
        # TODO ======

    def _init_signals(self):
        """
        Heinous hack to properly handle signals on the mainloop. Necessary
        if we want to use the mainloop run() functionality.
        """
        def signal_action(signum):
            """
            Action to take when a signal is trapped
            """
            self.quit(signum)

        def idle_handler():
            """
            GLib idle handler to propagate signals
            """
            GLib.idle_add(signal_action, priority=GLib.PRIORITY_HIGH)

        def handler(*args):
            """
            Unix signal handler
            """
            signal_action(args[0])

        def install_glib_handler(sig):
            """
            Choose a compatible method and install the handler
            """
            unix_signal_add = None

            if hasattr(GLib, "unix_signal_add"):
                unix_signal_add = GLib.unix_signal_add
            elif hasattr(GLib, "unix_signal_add_full"):
                unix_signal_add = GLib.unix_signal_add_full

            if unix_signal_add:
                unix_signal_add(GLib.PRIORITY_HIGH, sig, handler, sig)
            else:
                print("Can't install GLib signal handler!")

        for sig in signal.SIGINT, signal.SIGTERM, signal.SIGHUP:
            signal.signal(sig, idle_handler)
            GLib.idle_add(install_glib_handler,
                          sig,
                          priority=GLib.PRIORITY_HIGH)

    def read_config(self, config_file):
        """
        Read in the config file and set the defaults

        :param config_file: Config file
        :type config_file: str or None
        """
        # Generate sections as trying to access a value even if a default exists will die if the section does not
        for section in ('General', 'Startup', 'Statistics'):
            self._config[section] = {}

        self._config['DEFAULT'] = {
            'verbose_logging': True,
            'sync_effects_enabled': True,
            'devices_off_on_screensaver': True,
            'key_statistics': False,
        }

        if config_file is not None and os.path.exists(config_file):
            self._config.read(config_file)

    def enable_turn_off_on_screensaver(self):
        """
        Enable the turning off of devices when the screensaver is active
        """
        self._screensaver_thread.active = True

    def disable_turn_off_on_screensaver(self):
        """
        Disable the turning off of devices when the screensaver is active
        """
        self._screensaver_thread.active = False

    def version(self):
        """
        Get the daemon version

        :return: Version string
        :rtype: str
        """
        return __version__

    def suspend_devices(self):
        """
        Suspend all devices
        """
        for device in self._razer_devices:
            device.dbus.suspend_device()

    def resume_devices(self):
        """
        Resume all devices
        """
        for device in self._razer_devices:
            device.dbus.resume_device()

    def get_serial_list(self):
        """
        Get list of devices serials
        """
        serial_list = self._razer_devices.serials()
        self.logger.debug('DBus called get_serial_list')
        return serial_list

    def sync_effects(self, enabled):
        """
        Sync the effects across the devices

        :param enabled: True to sync effects
        :type enabled: bool
        """
        # Todo perhaps move logic to device collection
        for device in self._razer_devices.devices:
            device.dbus.effect_sync = enabled

    def _load_devices(self, first_run=False):
        """
        Go through supported devices and load them

        Loops through the available hardware classes, loops through
        each device in the system and adds it if needs be.
        """
        classes = razer_daemon.hardware.get_device_classes()

        if first_run:
            # Just some pretty output
            max_name_len = max([len(cls.__name__) for cls in classes]) + 2
            for cls in classes:
                format_str = 'Loaded device specification: {0:-<' + str(
                    max_name_len) + '} ({1:04x}:{2:04X})'

                self.logger.debug(
                    format_str.format(cls.__name__ + ' ', cls.USB_VID,
                                      cls.USB_PID))

        for device in self._udev_context.list_devices(subsystem='hid'):
            device_number = 0

            for device_class in classes:
                if device.sys_name in self._razer_devices:
                    continue

                if device_class.match(
                        device.sys_name, device.parent.sys_path
                ):  # Check it matches sys/ ID format and has device_type file
                    self.logger.info('Found device.%d: %s', device_number,
                                     device.sys_name)
                    razer_device = device_class(device.sys_path,
                                                device_number,
                                                self._config,
                                                testing=self._test_dir
                                                is not None)

                    # Wireless devices sometimes dont listen
                    count = 0
                    while count < 3:
                        # Loop to get serial, exit early if it gets one
                        device_serial = razer_device.get_serial()
                        if len(device_serial) > 0:
                            break
                        count += 1
                    else:
                        logging.warning(
                            "Could not get serial for device {0}. Skipping".
                            format(device.sys_name))
                        continue

                    self._razer_devices.add(device.sys_name, device_serial,
                                            razer_device)

                    device_number += 1

    def _remove_devices(self):
        """
        Go through the list of current devices and if they no longer exist then remove them
        """
        hid_devices = [
            dev.sys_name
            for dev in self._udev_context.list_devices(subsystem='hid')
        ]
        devices_to_remove = [
            dev for dev in self._razer_devices if dev not in hid_devices
        ]
        for device in devices_to_remove:
            if self._test_dir is not None:
                # Remove from DBus
                device.dbus.remove_from_connection()

            # Remove device
            self.logger.warning("Device %s is missing. Removing from DBus",
                                device.device_id)
            del self._razer_devices[device.device_id]

    def _udev_input_event(self, device):
        self.logger.debug('Device event [%s]: %s', device.action,
                          device.device_path)
        if device.action == 'add':
            self._load_devices()
        elif device.action == 'remove':
            self._remove_devices()

    def run(self):
        """
        Run the daemon
        """
        self.logger.info('Serving DBus')

        # Start listening for device changes
        self._udev_observer.start()

        # Start the mainloop
        try:
            self._main_loop.run()
        except KeyboardInterrupt:
            self.logger.debug('Shutting down')

    def stop(self):
        """
        Wrapper for quit
        """
        self.quit(None)

    def quit(self, signum):
        """
        Quit by stopping the main loop, observer, and screensaver thread
        """
        # pylint: disable=unused-argument
        if signum is None:
            self.logger.info('Stopping daemon.')
        else:
            self.logger.info('Stopping daemon on signal %d', signum)

        self._main_loop.quit()

        # Stop udev monitor
        self._udev_observer.send_stop()

        # Stop screensaver
        self._screensaver_thread.shutdown = True
        self._screensaver_thread.join(timeout=2)
        if self._screensaver_thread.is_alive():
            self.logger.warning('Could not stop the screensaver thread')

        for device in self._razer_devices:
            device.dbus.close()
Example #34
0
from pyudev import Context
context = Context()
for device in context.list_devices(subsystem='input'):
    '{0} - {1}'.format(device.sys_name, device.device_type)
Example #35
0

def test_udev_list_iterate_mock():
    libudev = Mock(name='libudev')
    items = [('spam', 'eggs'), ('foo', 'bar')]
    with pytest.libudev_list(libudev, 'udev_enumerate_get_list_entry', items):
        udev_list = libudev.udev_enumerate_get_list_entry()
        assert list(_util.udev_list_iterate(libudev, udev_list)) == [
            ('spam', 'eggs'), ('foo', 'bar')]


def raise_valueerror():
    raise ValueError('from function')


_char_devices = list(_CONTEXT.list_devices(subsystem="tty"))
@pytest.mark.skipif(len(_char_devices) == 0, reason='no tty devices')
@given(strategies.sampled_from(_char_devices))
@settings(min_satisfying_examples=1, max_examples=5)
def test_get_device_type_character_device(a_device):
    """
    Check that the device type of a character device is actually char.
    """
    assert _util.get_device_type(a_device.device_node) == 'char'

_block_devices = list(_CONTEXT.list_devices(subsystem="block"))
@pytest.mark.skipif(len(_block_devices) == 0, reason='no block devices')
@given(strategies.sampled_from(_block_devices))
@settings(min_satisfying_examples=1, max_examples=5)
def test_get_device_type_block_device(a_device):
    """
Example #36
0
def test_udev_list_iterate_mock():
    libudev = Mock(name='libudev')
    items = [('spam', 'eggs'), ('foo', 'bar')]
    with pytest.libudev_list(libudev, 'udev_enumerate_get_list_entry', items):
        udev_list = libudev.udev_enumerate_get_list_entry()
        assert list(_util.udev_list_iterate(libudev,
                                            udev_list)) == [('spam', 'eggs'),
                                                            ('foo', 'bar')]


def raise_valueerror():
    raise ValueError('from function')


_char_devices = list(_CONTEXT.list_devices(subsystem="tty"))
if len(_char_devices) > 0:

    @given(strategies.sampled_from(_char_devices),
           settings=Settings(max_examples=5))
    def test_get_device_type_character_device(a_device):
        """
        Check that the device type of a character device is actually char.
        """
        assert _util.get_device_type(a_device.device_node) == 'char'
else:

    def test_get_device_type_character_device():
        """
        Skip this test because not enough appropriate devices.
        """
Example #37
0

def create_static_sets(logger):
    IPSet(name=Config.GLOBAL_EGRESS_IP_WL_IPSET_NAME, logger=logger)\
        .create()\
        .add(ips=Config.GLOBAL_EGRESS_IP_WL)


create_empty_sets(logger=logger)  # so that iptables rules have something to use
create_static_sets(logger=logger)

context = Context()
monitor = Monitor.from_netlink(context)
monitor.filter_by('net')

# if a tun device already exists
for device in context.list_devices(subsystem='net'):
    if match('^tun', device.sys_name):
        logger.info('Tun device already exists, creating ipsets...')
        create_sets(logger=logger)

# monitor (poll) device events
for device in iter(monitor.poll, None):
    if device.action == 'add' and match('^tun', device.sys_name):
        logger.info('New tun device ({}) detected, creating ipsets...'.format(device.sys_name))
        try:
            create_sets(logger=logger)
        except NetscriptsException:
            logger.info('Stopped trying to resolve, waiting for next tun event')
            continue
Example #38
0
class RazerDaemon(DBusService):
    """
    Daemon class

    This class sets up the main run loop which serves DBus messages. The logger is initialised
    in this module as well as finding and initialising devices.

    Serves the following functions via DBus
    * getDevices - Returns a list of serial numbers
    * enableTurnOffOnScreensaver - Starts/Continues the run loop on the screensaver thread
    * disableTurnOffOnScreensaver - Pauses the run loop on the screensaver thread
    """

    BUS_NAME = 'org.razer'

    def __init__(self, verbose=False, log_dir=None, console_log=False, run_dir=None, config_file=None, test_dir=None):

        setproctitle.setproctitle('openrazer-daemon')  # pylint: disable=no-member

        # Expanding ~ as python doesn't do it by default, also creating dirs if needed
        try:
            if log_dir is not None:
                log_dir = os.path.expanduser(log_dir)
                os.makedirs(log_dir, exist_ok=True)
            if run_dir is not None:
                run_dir = os.path.expanduser(run_dir)
                os.makedirs(run_dir, exist_ok=True)
        except NotADirectoryError as e:
            print("Failed to create {}".format(e.filename), file=sys.stderr)
            sys.exit(1)

        if config_file is not None:
            config_file = os.path.expanduser(config_file)
            if not os.path.exists(config_file):
                print("Config file {} does not exist.".format(config_file), file=sys.stderr)
                sys.exit(1)

        self._test_dir = test_dir
        self._run_dir = run_dir
        self._config_file = config_file
        self._config = configparser.ConfigParser()
        self.read_config(config_file)

        # Logging
        log_level = logging.INFO
        if verbose or self._config.getboolean('General', 'verbose_logging'):
            log_level = logging.DEBUG
        self.logger = self._create_logger(log_dir, log_level, console_log)

        # Check for plugdev group
        if not self._check_plugdev_group():
            self.logger.critical("User is not a member of the plugdev group")
            sys.exit(1)

        # Setup DBus to use gobject main loop
        dbus.mainloop.glib.threads_init()
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
        DBusService.__init__(self, self.BUS_NAME, '/org/razer')

        self._init_signals()
        self._main_loop = GLib.MainLoop()

        # Listen for input events from udev
        self._init_udev_monitor()

        # Load Classes
        self._device_classes = openrazer_daemon.hardware.get_device_classes()

        self.logger.info("Initialising Daemon (v%s). Pid: %d", __version__, os.getpid())
        self._init_screensaver_monitor()

        self._razer_devices = DeviceCollection()
        self._load_devices(first_run=True)

        # Add DBus methods
        methods = {
            # interface, method, callback, in-args, out-args
            ('razer.devices', 'getDevices', self.get_serial_list, None, 'as'),
            ('razer.devices', 'supportedDevices', self.supported_devices, None, 's'),
            ('razer.devices', 'enableTurnOffOnScreensaver', self.enable_turn_off_on_screensaver, 'b', None),
            ('razer.devices', 'getOffOnScreensaver', self.get_off_on_screensaver, None, 'b'),
            ('razer.devices', 'syncEffects', self.sync_effects, 'b', None),
            ('razer.devices', 'getSyncEffects', self.get_sync_effects, None, 'b'),
            ('razer.daemon', 'version', self.version, None, 's'),
            ('razer.daemon', 'stop', self.stop, None, None),
        }

        for m in methods:
            self.logger.debug("Adding {}.{} method to DBus".format(m[0], m[1]))
            self.add_dbus_method(m[0], m[1], m[2], in_signature=m[3], out_signature=m[4])

        self._collecting_udev = False
        self._collecting_udev_devices = []

        # TODO remove
        self.sync_effects(self._config.getboolean('Startup', 'sync_effects_enabled'))
        # TODO ======

    @dbus.service.signal('razer.devices')
    def device_removed(self):
        self.logger.debug("Emitted Device Remove Signal")

    @dbus.service.signal('razer.devices')
    def device_added(self):
        self.logger.debug("Emitted Device Added Signal")

    def _create_logger(self, log_dir, log_level, want_console_log):
        """
        Initializes a logger and returns it.

        :param log_dir: If not None, specifies the directory to create the
        log file in
        :param log_level: The log level of messages to print
        :param want_console_log: True if we should print to the console

        :rtype:logging.Logger
        """
        logger = logging.getLogger('razer')
        logger.setLevel(log_level)
        formatter = logging.Formatter('%(asctime)s | %(name)-30s | %(levelname)-8s | %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
        # Don't propagate to default logger
        logger.propagate = 0

        if want_console_log:
            console_logger = logging.StreamHandler()
            console_logger.setLevel(log_level)
            console_logger.setFormatter(formatter)
            logger.addHandler(console_logger)

        if log_dir is not None:
            log_file = os.path.join(log_dir, 'razer.log')
            file_logger = logging.handlers.RotatingFileHandler(log_file, maxBytes=16777216, backupCount=10)  # 16MiB
            file_logger.setLevel(log_level)
            file_logger.setFormatter(formatter)
            logger.addHandler(file_logger)

        return logger

    def _check_plugdev_group(self):
        """
        Check if the user is a member of the plugdev group. For the root
        user, this always returns True

        :rtype: bool
        """
        if getpass.getuser() == 'root':
            return True

        try:
            return grp.getgrnam('plugdev').gr_gid in os.getgroups()
        except KeyError:
            pass

        return False

    def _init_udev_monitor(self):
        self._udev_context = Context()
        udev_monitor = Monitor.from_netlink(self._udev_context)
        udev_monitor.filter_by(subsystem='hid')
        self._udev_observer = MonitorObserver(udev_monitor, callback=self._udev_input_event, name='device-monitor')

    def _init_screensaver_monitor(self):
        try:
            self._screensaver_monitor = ScreensaverMonitor(self)
            self._screensaver_monitor.monitoring = self._config.getboolean('Startup', 'devices_off_on_screensaver')
        except dbus.exceptions.DBusException as e:
            self.logger.error("Failed to init ScreensaverMonitor: {}".format(e))

    def _init_signals(self):
        """
        Heinous hack to properly handle signals on the mainloop. Necessary
        if we want to use the mainloop run() functionality.
        """
        def signal_action(signum):
            """
            Action to take when a signal is trapped
            """
            self.quit(signum)

        def idle_handler():
            """
            GLib idle handler to propagate signals
            """
            GLib.idle_add(signal_action, priority=GLib.PRIORITY_HIGH)

        def handler(*args):
            """
            Unix signal handler
            """
            signal_action(args[0])

        def install_glib_handler(sig):
            """
            Choose a compatible method and install the handler
            """
            unix_signal_add = None

            if hasattr(GLib, "unix_signal_add"):
                unix_signal_add = GLib.unix_signal_add
            elif hasattr(GLib, "unix_signal_add_full"):
                unix_signal_add = GLib.unix_signal_add_full

            if unix_signal_add:
                unix_signal_add(GLib.PRIORITY_HIGH, sig, handler, sig)
            else:
                print("Can't install GLib signal handler!")

        for sig in signal.SIGINT, signal.SIGTERM, signal.SIGHUP:
            signal.signal(sig, idle_handler)
            GLib.idle_add(install_glib_handler, sig, priority=GLib.PRIORITY_HIGH)

    def read_config(self, config_file):
        """
        Read in the config file and set the defaults

        :param config_file: Config file
        :type config_file: str or None
        """
        # Generate sections as trying to access a value even if a default exists will die if the section does not
        for section in ('General', 'Startup', 'Statistics'):
            self._config[section] = {}

        self._config['DEFAULT'] = {
            'verbose_logging': True,
            'sync_effects_enabled': True,
            'devices_off_on_screensaver': True,
            'key_statistics': False,
        }

        if config_file is not None and os.path.exists(config_file):
            self._config.read(config_file)

    def get_off_on_screensaver(self):
        """
        Returns if turn off on screensaver

        :return: Result
        :rtype: bool
        """
        return self._screensaver_monitor.monitoring

    def enable_turn_off_on_screensaver(self, enable):
        """
        Enable the turning off of devices when the screensaver is active
        """
        self._screensaver_monitor.monitoring = enable

    def supported_devices(self):
        result = {cls.__name__: (cls.USB_VID, cls.USB_PID) for cls in self._device_classes}

        return json.dumps(result)

    def version(self):
        """
        Get the daemon version

        :return: Version string
        :rtype: str
        """
        return __version__

    def suspend_devices(self):
        """
        Suspend all devices
        """
        for device in self._razer_devices:
            device.dbus.suspend_device()

    def resume_devices(self):
        """
        Resume all devices
        """
        for device in self._razer_devices:
            device.dbus.resume_device()

    def get_serial_list(self):
        """
        Get list of devices serials
        """
        serial_list = self._razer_devices.serials()
        self.logger.debug('DBus called get_serial_list')
        return serial_list

    def sync_effects(self, enabled):
        """
        Sync the effects across the devices

        :param enabled: True to sync effects
        :type enabled: bool
        """
        # Todo perhaps move logic to device collection
        for device in self._razer_devices.devices:
            device.dbus.effect_sync = enabled

    def get_sync_effects(self):
        """
        Sync the effects across the devices

        :return: True if any devices sync effects
        :rtype: bool
        """
        result = False

        for device in self._razer_devices.devices:
            result |= device.dbus.effect_sync

        return result

    def _load_devices(self, first_run=False):
        """
        Go through supported devices and load them

        Loops through the available hardware classes, loops through
        each device in the system and adds it if needs be.
        """
        if first_run:
            # Just some pretty output
            max_name_len = max([len(cls.__name__) for cls in self._device_classes]) + 2
            for cls in self._device_classes:
                format_str = 'Loaded device specification: {0:-<' + str(max_name_len) + '} ({1:04x}:{2:04X})'

                self.logger.debug(format_str.format(cls.__name__ + ' ', cls.USB_VID, cls.USB_PID))

        if self._test_dir is not None:
            device_list = os.listdir(self._test_dir)
            test_mode = True
        else:
            device_list = list(self._udev_context.list_devices(subsystem='hid'))
            test_mode = False

        device_number = 0
        for device in device_list:

            for device_class in self._device_classes:
                # Interoperability between generic list of 0000:0000:0000.0000 and pyudev
                if test_mode:
                    sys_name = device
                    sys_path = os.path.join(self._test_dir, device)
                else:
                    sys_name = device.sys_name
                    sys_path = device.sys_path

                if sys_name in self._razer_devices:
                    continue

                if device_class.match(sys_name, sys_path):  # Check it matches sys/ ID format and has device_type file
                    self.logger.info('Found device.%d: %s', device_number, sys_name)

                    # TODO add testdir support
                    # Basically find the other usb interfaces
                    device_match = sys_name.split('.')[0]
                    additional_interfaces = []
                    if not test_mode:
                        for alt_device in device_list:
                            if device_match in alt_device.sys_name and alt_device.sys_name != sys_name:
                                additional_interfaces.append(alt_device.sys_path)

                    # Checking permissions
                    test_file = os.path.join(sys_path, 'device_type')
                    file_group_id = os.stat(test_file).st_gid
                    file_group_name = grp.getgrgid(file_group_id)[0]

                    if os.getgid() != file_group_id and file_group_name != 'plugdev':
                        self.logger.critical("Could not access {0}/device_type, file is not owned by plugdev".format(sys_path))
                        break

                    razer_device = device_class(sys_path, device_number, self._config, testing=self._test_dir is not None, additional_interfaces=sorted(additional_interfaces))

                    # Wireless devices sometimes don't listen
                    count = 0
                    while count < 3:
                        # Loop to get serial, exit early if it gets one
                        device_serial = razer_device.get_serial()
                        if len(device_serial) > 0:
                            break
                        time.sleep(0.1)
                        count += 1
                    else:
                        logging.warning("Could not get serial for device {0}. Skipping".format(sys_name))
                        continue

                    self._razer_devices.add(sys_name, device_serial, razer_device)

                    device_number += 1

    def _add_device(self, device):
        """
        Add device event from udev

        :param device: Udev Device
        :type device: pyudev.device._device.Device
        """
        device_number = len(self._razer_devices)
        for device_class in self._device_classes:
            sys_name = device.sys_name
            sys_path = device.sys_path

            if sys_name in self._razer_devices:
                continue

            if device_class.match(sys_name, sys_path):  # Check it matches sys/ ID format and has device_type file
                self.logger.info('Found valid device.%d: %s', device_number, sys_name)
                razer_device = device_class(sys_path, device_number, self._config, testing=self._test_dir is not None)

                # Its a udev event so currently the device hasn't been chmodded yet
                time.sleep(0.2)

                # Wireless devices sometimes don't listen
                device_serial = razer_device.get_serial()

                if len(device_serial) > 0:
                    # Add Device
                    self._razer_devices.add(sys_name, device_serial, razer_device)
                    self.device_added()
                else:
                    logging.warning("Could not get serial for device {0}. Skipping".format(sys_name))
            else:
                # Basically find the other usb interfaces
                device_match = sys_name.split('.')[0]
                for d in self._razer_devices:
                    if device_match in d.device_id and d.device_id != sys_name:
                        if not sys_path in d.dbus.additional_interfaces:
                            d.dbus.additional_interfaces.append(sys_path)
                            return

    def _remove_device(self, device):
        """
        Remove device event from udev

        :param device: Udev Device
        :type device: pyudev.device._device.Device
        """
        device_id = device.sys_name

        try:
            device = self._razer_devices[device_id]

            device.dbus.close()
            device.dbus.remove_from_connection()
            self.logger.warning("Removing %s", device_id)

            # Delete device
            del self._razer_devices[device.device_id]
            self.device_removed()

        except IndexError:  # Why didn't i set it up as KeyError
            # It will return "extra" events for the additional usb interfaces bound to the driver
            pass

    def _udev_input_event(self, device):
        """
        Function called by the Udev monitor (#observerPattern)

        :param device: Udev device
        :type device: pyudev.device._device.Device
        """
        self.logger.debug('Device event [%s]: %s', device.action, device.device_path)
        if device.action == 'add':
            if self._collecting_udev:
                self._collecting_udev_devices.append(device)
                return
            else:
                self._collecting_udev_devices = [device]
                self._collecting_udev = True
                t = threading.Thread(target=self._collecting_udev_method, args=(device,))
                t.start()
        elif device.action == 'remove':
            self._remove_device(device)

    def _collecting_udev_method(self, device):
        time.sleep(2)  # delay to let udev add all devices that we want
        # Sort the devices
        self._collecting_udev_devices.sort(key=lambda x: x.sys_path, reverse=True)
        for d in self._collecting_udev_devices:
            self._add_device(d)
        self._collecting_udev = False

    def run(self):
        """
        Run the daemon
        """
        self.logger.info('Serving DBus')

        # Start listening for device changes
        self._udev_observer.start()

        # Start the mainloop
        try:
            self._main_loop.run()
        except KeyboardInterrupt:
            self.logger.debug('Shutting down')

    def stop(self):
        """
        Wrapper for quit
        """
        self.quit(None)

    def quit(self, signum):
        """
        Quit by stopping the main loop, observer, and screensaver thread
        """
        # pylint: disable=unused-argument
        if signum is None:
            self.logger.info('Stopping daemon.')
        else:
            self.logger.info('Stopping daemon on signal %d', signum)

        self._main_loop.quit()

        # Stop udev monitor
        self._udev_observer.send_stop()

        for device in self._razer_devices:
            device.dbus.close()
Example #39
0

def test_udev_list_iterate_mock():
    libudev = Mock(name='libudev')
    items = [('spam', 'eggs'), ('foo', 'bar')]
    with pytest.libudev_list(libudev, 'udev_enumerate_get_list_entry', items):
        udev_list = libudev.udev_enumerate_get_list_entry()
        assert list(_util.udev_list_iterate(libudev, udev_list)) == [
            ('spam', 'eggs'), ('foo', 'bar')]


def raise_valueerror():
    raise ValueError('from function')


_CHAR_DEVICES = list(_CONTEXT.list_devices(subsystem="tty"))
@pytest.mark.skipif(len(_CHAR_DEVICES) == 0, reason='no tty devices')
@given(strategies.sampled_from(_CHAR_DEVICES))
@settings(min_satisfying_examples=1, max_examples=5)
def test_get_device_type_character_device(a_device):
    """
    Check that the device type of a character device is actually char.
    """
    assert _util.get_device_type(a_device.device_node) == 'char'

_BLOCK_DEVICES = list(_CONTEXT.list_devices(subsystem="block"))
@pytest.mark.skipif(len(_BLOCK_DEVICES) == 0, reason='no block devices')
@given(strategies.sampled_from(_BLOCK_DEVICES))
@settings(min_satisfying_examples=1, max_examples=5)
def test_get_device_type_block_device(a_device):
    """
Example #40
0
import os

from functools import reduce # pylint: disable=redefined-builtin

from hypothesis import given
from hypothesis import settings
from hypothesis import strategies

import pytest

import pyprocdev

from pyudev import Context

_CONTEXT = Context()
_DEVICES = _CONTEXT.list_devices()

_CONTEXT_STRATEGY = strategies.just(_CONTEXT)

_PROCDEV = pyprocdev.ProcDev()


class TestDrivers(object):
    """
    Test properties of drivers.
    """
    # pylint: disable=too-few-public-methods

    _devices = [d for d in _DEVICES if d.subsystem in ('block', 'char')]
    @pytest.mark.skipif(len(_devices) == 0, reason='no special devices')
    @given(strategies.sampled_from(_devices))
Example #41
0
class RazerDaemon(DBusService):
    """
    Daemon class

    This class sets up the main run loop which serves DBus messages. The logger is initialised
    in this module as well as finding and initialising devices.

    Serves the following functions via DBus
    * getDevices - Returns a list of serial numbers
    * enableTurnOffOnScreensaver - Starts/Continues the run loop on the screensaver thread
    * disableTurnOffOnScreensaver - Pauses the run loop on the screensaver thread
    """

    BUS_PATH = 'org.razer'

    def __init__(self, verbose=False, log_dir=None, console_log=False, run_dir=None, config_file=None, test_dir=None):

        # Check if process exists
        exit_code = subprocess.call(['pgrep', 'razer-service'], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)

        if exit_code == 0:
            print("Daemon already exists. Please stop that one.", file=sys.stderr)
            exit(-1)

        setproctitle.setproctitle('razer-service')

        # Expanding ~ as python doesnt do it by default, also creating dirs if needed
        if log_dir is not None:
            log_dir = os.path.expanduser(log_dir)
            os.makedirs(log_dir, mode=0o750, exist_ok=True)
        if run_dir is not None:
            run_dir = os.path.expanduser(run_dir)
            os.makedirs(run_dir, mode=0o750, exist_ok=True)
        if config_file is not None:
            config_file = os.path.expanduser(config_file)
            os.makedirs(os.path.dirname(config_file), mode=0o750, exist_ok=True)

        self._test_dir = test_dir
        self._data_dir = run_dir
        self._config_file = config_file
        self._config = configparser.ConfigParser()
        self.read_config(config_file)

        # Setup DBus to use gobject main loop
        dbus.mainloop.glib.threads_init()
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
        DBusService.__init__(self, self.BUS_PATH, '/org/razer')

        self._init_signals()
        self._main_loop = GObject.MainLoop()

        # Listen for input events from udev
        self._udev_context = Context()
        udev_monitor = Monitor.from_netlink(self._udev_context)
        udev_monitor.filter_by(subsystem='input')
        self._udev_observer = MonitorObserver(udev_monitor, callback=self._udev_input_event, name='device-monitor')

        # Logging
        logging_level = logging.INFO
        if verbose or self._config.getboolean('General', 'verbose_logging'):
            logging_level = logging.DEBUG

        self.logger = logging.getLogger('razer')
        self.logger.setLevel(logging_level)
        formatter = logging.Formatter('%(asctime)s | %(name)-30s | %(levelname)-8s | %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
        # Dont propagate to default logger
        self.logger.propagate = 0

        if console_log:
            console_logger = logging.StreamHandler()
            console_logger.setLevel(logging_level)
            console_logger.setFormatter(formatter)
            self.logger.addHandler(console_logger)

        if log_dir is not None:
            log_file = os.path.join(log_dir, 'razer.log')
            file_logger = logging.handlers.RotatingFileHandler(log_file, maxBytes=16777216, backupCount=10) # 16MiB
            file_logger.setLevel(logging_level)
            file_logger.setFormatter(formatter)
            self.logger.addHandler(file_logger)

        self.logger.info("Initialising Daemon (v%s). Pid: %d", __version__, os.getpid())

        # Setup screensaver thread
        self._screensaver_thread = ScreensaverThread(self, active=self._config.getboolean('Startup', 'devices_off_on_screensaver'))
        self._screensaver_thread.start()

        self._razer_devices = DeviceCollection()
        self._load_devices(first_run=True)

        # Add DBus methods
        self.logger.info("Adding razer.devices.getDevices method to DBus")
        self.add_dbus_method('razer.devices', 'getDevices', self.get_serial_list, out_signature='as')
        self.logger.info("Adding razer.devices.enableTurnOffOnScreensaver method to DBus")
        self.add_dbus_method('razer.devices', 'enableTurnOffOnScreensaver', self.enable_turn_off_on_screensaver)
        self.logger.info("Adding razer.devices.disableTurnOffOnScreensaver method to DBus")
        self.add_dbus_method('razer.devices', 'disableTurnOffOnScreensaver', self.disable_turn_off_on_screensaver)
        self.logger.info("Adding razer.devices.syncEffects method to DBus")
        self.add_dbus_method('razer.devices', 'syncEffects', self.sync_effects, in_signature='b')
        self.logger.info("Adding razer.daemon.version method to DBus")
        self.add_dbus_method('razer.daemon', 'version', self.version, out_signature='s')
        self.logger.info("Adding razer.daemon.stop method to DBus")
        self.add_dbus_method('razer.daemon', 'stop', self.stop)

        # TODO remove
        self.sync_effects(self._config.getboolean('Startup', 'sync_effects_enabled'))
        # TODO ======

    def _init_signals(self):
        """
        Heinous hack to properly handle signals on the mainloop. Necessary
        if we want to use the mainloop run() functionality.
        """
        def signal_action(signum):
            """
            Action to take when a signal is trapped
            """
            self.quit(signum)

        def idle_handler():
            """
            GLib idle handler to propagate signals
            """
            GLib.idle_add(signal_action, priority=GLib.PRIORITY_HIGH)

        def handler(*args):
            """
            Unix signal handler
            """
            signal_action(args[0])

        def install_glib_handler(sig):
            """
            Choose a compatible method and install the handler
            """
            unix_signal_add = None

            if hasattr(GLib, "unix_signal_add"):
                unix_signal_add = GLib.unix_signal_add
            elif hasattr(GLib, "unix_signal_add_full"):
                unix_signal_add = GLib.unix_signal_add_full

            if unix_signal_add:
                unix_signal_add(GLib.PRIORITY_HIGH, sig, handler, sig)
            else:
                print("Can't install GLib signal handler!")

        for sig in signal.SIGINT, signal.SIGTERM, signal.SIGHUP:
            signal.signal(sig, idle_handler)
            GLib.idle_add(install_glib_handler, sig, priority=GLib.PRIORITY_HIGH)

    def read_config(self, config_file):
        """
        Read in the config file and set the defaults

        :param config_file: Config file
        :type config_file: str or None
        """
        # Generate sections as trying to access a value even if a default exists will die if the section does not
        for section in ('General', 'Startup', 'Statistics'):
            self._config[section] = {}

        self._config['DEFAULT'] = {
            'verbose_logging': True,
            'sync_effects_enabled': True,
            'devices_off_on_screensaver': True,
            'key_statistics': False,
        }

        if config_file is not None and os.path.exists(config_file):
            self._config.read(config_file)

    def enable_turn_off_on_screensaver(self):
        """
        Enable the turning off of devices when the screensaver is active
        """
        self._screensaver_thread.active = True

    def disable_turn_off_on_screensaver(self):
        """
        Disable the turning off of devices when the screensaver is active
        """
        self._screensaver_thread.active = False

    def version(self):
        """
        Get the daemon version

        :return: Version string
        :rtype: str
        """
        return __version__

    def suspend_devices(self):
        """
        Suspend all devices
        """
        for device in self._razer_devices:
            device.dbus.suspend_device()

    def resume_devices(self):
        """
        Resume all devices
        """
        for device in self._razer_devices:
            device.dbus.resume_device()

    def get_serial_list(self):
        """
        Get list of devices serials
        """
        serial_list = self._razer_devices.serials()
        self.logger.debug('DBus called get_serial_list')
        return serial_list

    def sync_effects(self, enabled):
        """
        Sync the effects across the devices

        :param enabled: True to sync effects
        :type enabled: bool
        """
        # Todo perhaps move logic to device collection
        for device in self._razer_devices.devices:
            device.dbus.effect_sync = enabled

    def _load_devices(self, first_run=False):
        """
        Go through supported devices and load them

        Loops through the available hardware classes, loops through
        each device in the system and adds it if needs be.
        """
        classes = razer_daemon.hardware.get_device_classes()

        if first_run:
            # Just some pretty output
            max_name_len = max([len(cls.__name__) for cls in classes]) + 2
            for cls in classes:
                format_str = 'Loaded device specification: {0:-<' + str(max_name_len) + '} ({1:04x}:{2:04X})'

                self.logger.debug(format_str.format(cls.__name__ + ' ', cls.USB_VID, cls.USB_PID))

        for device in self._udev_context.list_devices(subsystem='hid'):
            device_number = 0

            for device_class in classes:
                if device.sys_name in self._razer_devices:
                    continue

                if device_class.match(device.sys_name, device.parent.sys_path):  # Check it matches sys/ ID format and has device_type file
                    self.logger.info('Found device.%d: %s', device_number, device.sys_name)
                    razer_device = device_class(device.sys_path, device_number, self._config, testing=self._test_dir is not None)

                    # Wireless devices sometimes dont listen
                    count = 0
                    while count < 3:
                        # Loop to get serial, exit early if it gets one
                        device_serial = razer_device.get_serial()
                        if len(device_serial) > 0:
                            break
                        count += 1
                    else:
                        logging.warning("Could not get serial for device {0}. Skipping".format(device.sys_name))
                        continue

                    self._razer_devices.add(device.sys_name, device_serial, razer_device)

                    device_number += 1

    def _remove_devices(self):
        """
        Go through the list of current devices and if they no longer exist then remove them
        """
        hid_devices = [dev.sys_name for dev in self._udev_context.list_devices(subsystem='hid')]
        devices_to_remove = [dev for dev in self._razer_devices if dev not in hid_devices]
        for device in devices_to_remove:
            if self._test_dir is not None:
                # Remove from DBus
                device.dbus.remove_from_connection()

            # Remove device
            self.logger.warning("Device %s is missing. Removing from DBus", device.device_id)
            del self._razer_devices[device.device_id]

    def _udev_input_event(self, device):
        self.logger.debug('Device event [%s]: %s', device.action, device.device_path)
        if device.action == 'add':
            self._load_devices()
        elif device.action == 'remove':
            self._remove_devices()

    def run(self):
        """
        Run the daemon
        """
        self.logger.info('Serving DBus')

        # Start listening for device changes
        self._udev_observer.start()

        # Start the mainloop
        try:
            self._main_loop.run()
        except KeyboardInterrupt:
            self.logger.debug('Shutting down')

    def stop(self):
        """
        Wrapper for quit
        """
        self.quit(None)

    def quit(self, signum):
        """
        Quit by stopping the main loop, observer, and screensaver thread
        """
        # pylint: disable=unused-argument
        if signum is None:
            self.logger.info('Stopping daemon.')
        else:
            self.logger.info('Stopping daemon on signal %d', signum)

        self._main_loop.quit()

        # Stop udev monitor
        self._udev_observer.send_stop()

        # Stop screensaver
        self._screensaver_thread.shutdown = True
        self._screensaver_thread.join(timeout=2)
        if self._screensaver_thread.is_alive():
            self.logger.warning('Could not stop the screensaver thread')

        for device in self._razer_devices:
            device.dbus.close()
Example #42
0
_CONTEXT = Context()

def _check_device(device):
    """
    Check that device exists by getting it.
    """
    try:
        Devices.from_path(_CONTEXT, device.sys_path)
        return True
    except DeviceNotFoundError:
        return False

_DEVICE_DATA = udev.DeviceDatabase.db()
_DEVICES = [Devices.from_path(_CONTEXT, d.device_path) for d in _DEVICE_DATA]

_DEVICE_STRATEGY = strategies.sampled_from(_CONTEXT.list_devices())
_DEVICE_STRATEGY = _DEVICE_STRATEGY.filter(_check_device)

_CONTEXT_STRATEGY = strategies.just(_CONTEXT)

_UDEV_VERSION = int(udev.UDevAdm.adm().query_udev_version())

_SUBSYSTEM_STRATEGY = _DEVICE_STRATEGY.map(lambda x: x.subsystem)

# Workaround for issue #181
_SUBSYSTEM_STRATEGY = _SUBSYSTEM_STRATEGY.filter(lambda s: s != 'i2c')

_SYSNAME_STRATEGY = _DEVICE_STRATEGY.map(lambda x: x.sys_name)

_PROPERTY_STRATEGY = _DEVICE_STRATEGY.flatmap(
   lambda d: strategies.sampled_from(d.properties.items())
Example #43
0
class UsbStorageMonitor(object):
    """ USB storage device add monitor

    This monitor is listening to UDEV for USB storage device 'add' events. The callback 
    that is provided to the constructor is called for every USB storage device that is
    added to the system.
    """

    def __init__(self, add_callback, remove_callback = None, change_callback = None, for_gui = False):
        self._logger = logging.getLogger('efalive.UsbStorageMonitor')

        self._external_add_callback = add_callback
        self._external_remove_callback = remove_callback
        self._external_change_callback = change_callback

        self._udev_context = Context()
        self._udev_monitor = Monitor.from_netlink(self._udev_context)
        self._udev_monitor.filter_by('block', device_type='partition')
        self._for_gui = for_gui
        if for_gui:
            self._udev_observer = UdevGuiObserver(self._udev_monitor)
            self._udev_observer.connect('device-event', self._handle_gui_device_event)
        else:
            self._udev_observer = UdevObserver(self._udev_monitor, callback=self._handle_device_event, name='monitor-observer')

    def start(self):
        if self._for_gui:
            self._udev_monitor.start()
        else:
            self._udev_observer.start()

    def stop(self):
        if self._for_gui:
            self._udev_monitor.stop()
        else:
            self._udev_observer.stop()

    def _handle_gui_device_event(self, observer, device):
        self._handle_device_event(device)

    def _handle_device_event(self, device):
        self._debug_device(device)
        if (device.get("ID_BUS") != "usb"):
            return
        self._logger.info("Action %s for device %s" % (device.action, device.device_node))
        if device.action == "add":
            wrapped_device = self._wrap_device(device)
            self._external_add_callback(wrapped_device)
        elif device.action == "remove" and self._external_remove_callback != None:
            wrapped_device = self._wrap_device(device)
            self._external_remove_callback(wrapped_device)
        elif device.action == "change" and self._external_change_callback != None:
            wrapped_device = self._wrap_device(device)
            self._external_change_callback(wrapped_device)
        else:
            self._logger.info("Unhandled action: %s" % device.action)

    def _debug_device(self, device):
        self._logger.debug("Device:")
        self._logger.debug("\tSubsystem: %s" % device.subsystem)
        self._logger.debug("\tType: %s" % device.device_type)
        self._logger.debug("\tName: %s" % device.sys_name)
        self._logger.debug("\tNumber: %s" % device.sys_number)
        self._logger.debug("\tSYS-fs path: %s" % device.sys_path)
        self._logger.debug("\tDriver: %s" % device.driver)
        self._logger.debug("\tAction: %s" % device.action)
        self._logger.debug("\tFile: %s" % device.device_node)
        #self._logger.debug("\tLinks: %s" % device.get_device_file_symlinks())
        #self._logger.debug("\tProperties: %s" % device.get_property_keys())
        #self._logger.debug("\tSYBSYSTEM: %s" % device.get_property("SUBSYSTEM"))
        #self._logger.debug("\tDEVTYPE: %s" % device.get_property("DEVTYPE"))
        ##self._logger.debug("\tID_VENDOR: %s" % device.get("ID_VENDOR"))
        self._logger.debug("\tID_SERIAL: %s" % device.properties.get("ID_SERIAL"))
        self._logger.debug("\tID_MODEL: %s" % device.get("ID_MODEL"))
        self._logger.debug("\tID_TYPE: %s" % device.get("ID_TYPE"))
        self._logger.debug("\tID_BUS: %s" % device.get("ID_BUS"))
        self._logger.debug("\tID_FS_LABEL: %s" % device.get("ID_FS_LABEL"))
        self._logger.debug("\tID_FS_TYPE: %s" % device.get("ID_FS_TYPE"))
        self._logger.debug("\tID_PART_ENTRY_SIZE: %s" % device.get("ID_PART_ENTRY_SIZE"))
        #self._logger.debug("All attributes:")
        #for attrName in device.__iter__():
        #    self._logger.debug(attrName)

    def _wrap_device(self, device):
        """ Convert a PyUdev device to an efaLive device
        """
        if device is None:
            return None
        wrapped_device = UsbStorageDevice(device.device_node)
        if device.get("ID_VENDOR"):
            wrapped_device.vendor = device.get("ID_VENDOR")
        if device.get("ID_MODEL"):
            wrapped_device.model = device.get("ID_MODEL")
        if device.get("ID_PART_ENTRY_SIZE"):
            byte_size = float(device.get("ID_PART_ENTRY_SIZE"))
            size = byte_size / 1024
            unit = "KB"
            if (size > 1024):
                size = size / 1024
                unit = "MB"
            if (size > 1024):
                size = size / 1024
                unit = "GB"
            if (size > 1024):
                size = size / 1024
                unit = "TB"
            wrapped_device.size = "%.1f %s" % (size, unit)
        if device.get("ID_FS_TYPE"):
            wrapped_device.fs_type = device.get("ID_FS_TYPE")
        if device.get("ID_FS_LABEL"):
            wrapped_device.label = device.get("ID_FS_LABEL")
        if device.get("ID_VENDOR_ID") and device.get("ID_MODEL_ID"):
            wrapped_device.bus_id = "%s:%s" % (device.get("ID_VENDOR_ID"), device.get("ID_MODEL_ID"))
        if device.properties.get("ID_SERIAL"):
            wrapped_device.serial = device.properties.get("ID_SERIAL")
        return wrapped_device

    def search_for_usb_block_devices(self):
        for usb_device in self._udev_context.list_devices(subsystem='block', DEVTYPE='partition'):
            if (usb_device.get("ID_BUS") != "usb"):
                continue
            wrapped_device = self._wrap_device(usb_device)
            self._external_add_callback(wrapped_device)
Example #44
0
from pyudev import Context
context = Context()
#for device in context.list_devices(subsystem='input', ID_INPUT_MOUSE=True):
for device in context.list_devices():
    if device.sys_name.startswith('event'):
        print device.parent['NAME']
Example #45
0
#!/usr/bin/python
#
# Copyright (c) 2019 DDN. All rights reserved.
#
# Run this on an agent and it will print out what needs to be in /etc/multipath/bindings
#

import os
from chroma_agent import config
from pyudev import Context

targets = config.get_section("targets")
context = Context()

for k in targets:
    target = os.path.basename(targets[k]["mntpt"])

    if not targets[k]["bdev"].startswith("/dev/mapper/"):
        continue

    mpath = os.path.basename(targets[k]["bdev"])

    device = next(
        x
        for x in context.list_devices().match_property("ID_FS_LABEL", target)
        if int(x["MAJOR"]) > 234)

    print("%s %s" % (mpath, device["DM_UUID"].lstrip("mpath-")))
Example #46
0
class UChromaDeviceManager(metaclass=Singleton):
    """
    Enumerates HID devices which can be managed by uChroma

    This is the main API entry point when developing applications
    with uChroma. Simply instantiate this object and the
    available devices can be fetched from the "devices" dict.

    Uses HIDAPI for low-level hardware interactions. Suitable
    permissions are required on the device nodes or this will
    fail.
    """
    def __init__(self, *callbacks):
        self._logger = Log.get('uchroma.devicemanager')

        self._devices = OrderedDict()
        self._monitor = False
        self._udev_context = Context()
        self._udev_observer = None
        self._callbacks = []

        if callbacks is not None:
            self._callbacks.extend(callbacks)

        self._loop = asyncio.get_event_loop()

        self.device_added = Signal()
        self.device_removed = Signal()

        self.discover()

    async def _fire_callbacks(self, action: str, device: BaseUChromaDevice):
        # delay for udev setup
        await asyncio.sleep(0.2)

        for callback in self._callbacks:
            await callback(action, device)

    def discover(self):
        """
        Perform HID device discovery

        Iterates over all connected HID devices with RAZER_VENDOR_ID
        and checks the product ID against the Hardware descriptor.

        Interface endpoint restrictions are currently hard-coded. In
        the future this should be done by checking the HID report
        descriptor of the endpoint, however this functionality in
        HIDAPI is broken (report_descriptor returns garbage) on
        Linux in the current release.

        Discovery is automatically performed when the object is
        constructed, so this should only need to be called if the
        list of devices changes (monitoring for changes is beyond
        the scope of this API).
        """
        devinfos = sorted(list(hidapi.enumerate(vendor_id=RAZER_VENDOR_ID)),
                          key=lambda x: x.path)

        for devinfo in devinfos:
            parent = self._get_parent(devinfo.product_id)
            if parent is None:
                continue

            if self._key_for_path(parent.sys_path) is not None:
                continue

            hardware = Hardware.get_device(devinfo.product_id)
            if hardware is None:
                continue

            if hardware.type == Hardware.Type.HEADSET:
                if devinfo.interface_number != 3:
                    continue
            elif hardware.type in (Hardware.Type.KEYBOARD,
                                   Hardware.Type.KEYPAD, Hardware.Type.LAPTOP):
                if devinfo.interface_number != 2:
                    continue
            elif hardware.type in (Hardware.Type.MOUSE,
                                   Hardware.Type.MOUSEPAD):
                if devinfo.interface_number != 1:
                    continue
            else:
                if devinfo.interface_number != 0:
                    continue

            device = self._create_device(parent, hardware, devinfo)
            if device is not None:
                self._devices[device.key] = device

                if hardware.type == Hardware.Type.KEYBOARD:
                    device.set_device_mode(0)

                if self._monitor and self._callbacks:
                    ensure_future(self._fire_callbacks('add', device),
                                  loop=self._loop)

    def _next_index(self):
        if not self._devices:
            return 0

        indexes = [device.device_index for device in self._devices.values()]
        indexes.sort()
        for idx, _ in enumerate(indexes):
            if idx + 1 == len(indexes):
                return _ + 1
            if _ + 1 == indexes[idx + 1]:
                continue
            return _ + 1
        raise ValueError('should not be here')

    def _create_device(self, parent, hardware, devinfo):
        input_devs = self._get_input_devices(parent)
        sys_path = parent.sys_path
        index = self._next_index()

        if hardware.type == Hardware.Type.MOUSE:
            if hardware.has_quirk(Quirks.WIRELESS):
                return UChromaWirelessMouse(hardware, devinfo, index, sys_path,
                                            input_devs)
            return UChromaMouse(hardware, devinfo, index, sys_path, input_devs)

        if hardware.type == Hardware.Type.LAPTOP:
            return UChromaLaptop(hardware, devinfo, index, sys_path,
                                 input_devs)

        if hardware.type == Hardware.Type.KEYBOARD:
            input_devs = self._get_input_devices(parent)
            return UChromaKeyboard(hardware, devinfo, index, sys_path,
                                   input_devs)

        if hardware.type == Hardware.Type.KEYPAD:
            input_devs = self._get_input_devices(parent)
            return UChromaKeypad(hardware, devinfo, index, sys_path,
                                 input_devs)

        if hardware.type == Hardware.Type.HEADSET:
            return UChromaHeadset(hardware, devinfo, index, sys_path)

        return UChromaDevice(hardware, devinfo, index, sys_path)

    def _key_for_path(self, path):
        for key, device in self._devices.items():
            if device.sys_path == path:
                return key
        return None

    @property
    def devices(self):
        """
        Dict of available devices, empty if no devices are detected.
        """
        self.discover()

        return self._devices

    @property
    def callbacks(self):
        """
        List of coroutines invoked when device changes are detected
        """
        return self._callbacks

    def _get_parent(self, product_id: int):
        pid = "%04x" % product_id

        devs = self._udev_context.list_devices(tag='uchroma',
                                               subsystem='usb',
                                               ID_MODEL_ID=pid)
        for dev in devs:
            if dev['DEVTYPE'] == 'usb_device':
                return dev

        return None

    def _get_input_devices(self, parent) -> list:
        inputs = []
        if parent is not None:
            for child in parent.children:
                if child.subsystem == 'input' and 'DEVNAME' in child:
                    for link in child.device_links:
                        if link.startswith('/dev/input/by-id/'):
                            inputs.append(link)
                            continue

        return inputs

    def _udev_event(self, device):
        self._logger.debug('Device event [%s]: %s', device.action, device)

        if device.action == 'remove':
            key = self._key_for_path(device.sys_path)
            if key is not None:
                removed = self._devices.pop(key, None)
                if removed is not None:
                    removed.close()
                    if self._callbacks:
                        ensure_future( \
                            self._fire_callbacks('remove', removed), loop=self._loop)

        else:
            if self._key_for_path(device.sys_path) is None:
                self.discover()

    async def close_devices(self):
        """
        Close all open devices and perform cleanup
        """
        for device in self._devices.values():
            await device.shutdown()
        self._devices.clear()

    async def monitor_start(self):
        """
        Start watching for device changes

        Listen for relevant add/remove events from udev and fire callbacks.
        """

        if self._monitor:
            return

        udev_monitor = Monitor.from_netlink(self._udev_context)
        udev_monitor.filter_by_tag('uchroma')
        udev_monitor.filter_by(subsystem='usb', device_type=u'usb_device')

        self._udev_observer = AsyncMonitorObserver(udev_monitor,
                                                   callback=self._udev_event,
                                                   name='uchroma-monitor')
        ensure_future(self._udev_observer.start())
        self._monitor = True

        if self._callbacks:
            for device in self._devices.values():
                ensure_future(self._fire_callbacks('add', device),
                              loop=self._loop)

        self._logger.debug('Udev monitor started')

    async def monitor_stop(self):
        """
        Stop watching for device changes
        """
        if not self._monitor:
            return

        await ensure_future(self._udev_observer.stop())
        self._monitor = False

        self._logger.debug('Udev monitor stopped')
Example #47
0
    def __init__(self,
                 obj,
                 devname,
                 refresh=0,
                 baudrate=115200,
                 bytesize=8,
                 parity='N',
                 stopbits=2,
                 timeout=400,
                 debug=False,
                 window_size=8,
                 rx_window_size=16,
                 transport_fifo_size=100,
                 ack_retransmit_timeout_ms=25,
                 frame_retransmit_timeout_ms=50):
        # Name and type of the connection peer
        self.name = ''
        self.type = ''

        self._devname = devname
        self.object = obj
        self.baudrate = baudrate
        self.bytesize = bytesize
        self.parity = parity
        self.stopbits = stopbits
        self.timeout = timeout

        self.transport_fifo_size = transport_fifo_size
        self.ack_retransmit_timeout_ms = ack_retransmit_timeout_ms
        self.max_window_size = window_size
        self.frame_retransmit_timeout_ms = frame_retransmit_timeout_ms
        self.rx_window_size = rx_window_size

        # State of transport FIFO
        self._transport_fifo = None
        self._last_sent_ack_time_ms = None

        # State for receiving a MIN frame
        self._rx_frame_buf = bytearray()
        self._rx_header_bytes_seen = 0
        self._rx_frame_state = self.SEARCHING_FOR_SOF
        self._rx_frame_checksum = 0
        self._rx_frame_id_control = 0
        self._rx_frame_seq = 0
        self._rx_frame_length = 0
        self._rx_control = 0
        self._stashed_rx_dict = {}

        self._rn = 0  # Sequence number expected to be received next
        self._sn_min = 0  # Sequence number of first frame currently in the sending window
        self._sn_max = 0  # Next sequence number to use for sending a frame
        self.source = {}  # sequence <--> sommand source linking

        self._nack_outstanding = None

        self._transport_fifo_reset()

        if refresh > 0:
            self._refresh = refresh

        self._updateTimer = LoopingCall(self.update)
        self._updateTimer.start(self._refresh)

        context = Context()
        for device in context.list_devices(subsystem='tty'):
            if 'DEVLINKS' in device.keys() and self._devname in device.get(
                    'DEVLINKS'):
                self.Connect()
                self.connectionMade()

        cm = Monitor.from_netlink(context)
        cm.filter_by(subsystem='tty')
        observer = MonitorObserver(cm,
                                   callback=self.ConnectionMCallBack,
                                   name='monitor-observer')
        observer.start()
Example #48
0
class RazerDaemon(DBusService):
    """
    Daemon class

    This class sets up the main run loop which serves DBus messages. The logger is initialised
    in this module as well as finding and initialising devices.

    Serves the following functions via DBus
    * getDevices - Returns a list of serial numbers
    * enableTurnOffOnScreensaver - Starts/Continues the run loop on the screensaver thread
    * disableTurnOffOnScreensaver - Pauses the run loop on the screensaver thread
    """

    BUS_NAME = 'org.razer'

    def __init__(self,
                 verbose=False,
                 log_dir=None,
                 console_log=False,
                 run_dir=None,
                 config_file=None,
                 test_dir=None):

        setproctitle.setproctitle('openrazer-daemon')  # pylint: disable=no-member

        # Expanding ~ as python doesn't do it by default, also creating dirs if needed
        try:
            if log_dir is not None:
                log_dir = os.path.expanduser(log_dir)
                os.makedirs(log_dir, exist_ok=True)
            if run_dir is not None:
                run_dir = os.path.expanduser(run_dir)
                os.makedirs(run_dir, exist_ok=True)
        except NotADirectoryError as e:
            print("Failed to create {}".format(e.filename), file=sys.stderr)
            sys.exit(1)

        if config_file is not None:
            config_file = os.path.expanduser(config_file)
            if not os.path.exists(config_file):
                print("Config file {} does not exist.".format(config_file),
                      file=sys.stderr)
                sys.exit(1)

        self._test_dir = test_dir
        self._run_dir = run_dir
        self._config_file = config_file
        self._config = configparser.ConfigParser()
        self.read_config(config_file)

        # Logging
        log_level = logging.INFO
        if verbose or self._config.getboolean('General', 'verbose_logging'):
            log_level = logging.DEBUG
        self.logger = self._create_logger(log_dir, log_level, console_log)

        # Check for plugdev group
        if not self._check_plugdev_group():
            self.logger.critical("User is not a member of the plugdev group")
            sys.exit(1)

        # Setup DBus to use gobject main loop
        dbus.mainloop.glib.threads_init()
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
        DBusService.__init__(self, self.BUS_NAME, '/org/razer')

        self._init_signals()
        self._main_loop = GLib.MainLoop()

        # Listen for input events from udev
        self._init_udev_monitor()

        # Load Classes
        self._device_classes = openrazer_daemon.hardware.get_device_classes()

        self.logger.info("Initialising Daemon (v%s). Pid: %d", __version__,
                         os.getpid())
        self._init_screensaver_monitor()

        self._razer_devices = DeviceCollection()
        self._load_devices(first_run=True)

        # Add DBus methods
        methods = {
            # interface, method, callback, in-args, out-args
            ('razer.devices', 'getDevices', self.get_serial_list, None, 'as'),
            ('razer.devices', 'supportedDevices', self.supported_devices, None,
             's'),
            ('razer.devices', 'enableTurnOffOnScreensaver',
             self.enable_turn_off_on_screensaver, 'b', None),
            ('razer.devices', 'getOffOnScreensaver',
             self.get_off_on_screensaver, None, 'b'),
            ('razer.devices', 'syncEffects', self.sync_effects, 'b', None),
            ('razer.devices', 'getSyncEffects', self.get_sync_effects, None,
             'b'),
            ('razer.daemon', 'version', self.version, None, 's'),
            ('razer.daemon', 'stop', self.stop, None, None),
        }

        for m in methods:
            self.logger.debug("Adding {}.{} method to DBus".format(m[0], m[1]))
            self.add_dbus_method(m[0],
                                 m[1],
                                 m[2],
                                 in_signature=m[3],
                                 out_signature=m[4])

        self._collecting_udev = False
        self._collecting_udev_devices = []

        # TODO remove
        self.sync_effects(
            self._config.getboolean('Startup', 'sync_effects_enabled'))
        # TODO ======

    @dbus.service.signal('razer.devices')
    def device_removed(self):
        self.logger.debug("Emitted Device Remove Signal")

    @dbus.service.signal('razer.devices')
    def device_added(self):
        self.logger.debug("Emitted Device Added Signal")

    def _create_logger(self, log_dir, log_level, want_console_log):
        """
        Initializes a logger and returns it.

        :param log_dir: If not None, specifies the directory to create the
        log file in
        :param log_level: The log level of messages to print
        :param want_console_log: True if we should print to the console

        :rtype:logging.Logger
        """
        logger = logging.getLogger('razer')
        logger.setLevel(log_level)
        formatter = logging.Formatter(
            '%(asctime)s | %(name)-30s | %(levelname)-8s | %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S')
        # Don't propagate to default logger
        logger.propagate = 0

        if want_console_log:
            console_logger = logging.StreamHandler()
            console_logger.setLevel(log_level)
            console_logger.setFormatter(formatter)
            logger.addHandler(console_logger)

        if log_dir is not None:
            log_file = os.path.join(log_dir, 'razer.log')
            file_logger = logging.handlers.RotatingFileHandler(
                log_file, maxBytes=16777216, backupCount=10)  # 16MiB
            file_logger.setLevel(log_level)
            file_logger.setFormatter(formatter)
            logger.addHandler(file_logger)

        return logger

    def _check_plugdev_group(self):
        """
        Check if the user is a member of the plugdev group. For the root
        user, this always returns True

        :rtype: bool
        """
        if getpass.getuser() == 'root':
            return True

        try:
            return grp.getgrnam('plugdev').gr_gid in os.getgroups()
        except KeyError:
            pass

        return False

    def _init_udev_monitor(self):
        self._udev_context = Context()
        udev_monitor = Monitor.from_netlink(self._udev_context)
        udev_monitor.filter_by(subsystem='hid')
        self._udev_observer = MonitorObserver(udev_monitor,
                                              callback=self._udev_input_event,
                                              name='device-monitor')

    def _init_screensaver_monitor(self):
        try:
            self._screensaver_monitor = ScreensaverMonitor(self)
            self._screensaver_monitor.monitoring = self._config.getboolean(
                'Startup', 'devices_off_on_screensaver')
        except dbus.exceptions.DBusException as e:
            self.logger.error(
                "Failed to init ScreensaverMonitor: {}".format(e))

    def _init_signals(self):
        """
        Heinous hack to properly handle signals on the mainloop. Necessary
        if we want to use the mainloop run() functionality.
        """
        def signal_action(signum):
            """
            Action to take when a signal is trapped
            """
            self.quit(signum)

        def idle_handler():
            """
            GLib idle handler to propagate signals
            """
            GLib.idle_add(signal_action, priority=GLib.PRIORITY_HIGH)

        def handler(*args):
            """
            Unix signal handler
            """
            signal_action(args[0])

        def install_glib_handler(sig):
            """
            Choose a compatible method and install the handler
            """
            unix_signal_add = None

            if hasattr(GLib, "unix_signal_add"):
                unix_signal_add = GLib.unix_signal_add
            elif hasattr(GLib, "unix_signal_add_full"):
                unix_signal_add = GLib.unix_signal_add_full

            if unix_signal_add:
                unix_signal_add(GLib.PRIORITY_HIGH, sig, handler, sig)
            else:
                print("Can't install GLib signal handler!")

        for sig in signal.SIGINT, signal.SIGTERM, signal.SIGHUP:
            signal.signal(sig, idle_handler)
            GLib.idle_add(install_glib_handler,
                          sig,
                          priority=GLib.PRIORITY_HIGH)

    def read_config(self, config_file):
        """
        Read in the config file and set the defaults

        :param config_file: Config file
        :type config_file: str or None
        """
        # Generate sections as trying to access a value even if a default exists will die if the section does not
        for section in ('General', 'Startup', 'Statistics'):
            self._config[section] = {}

        self._config['DEFAULT'] = {
            'verbose_logging': True,
            'sync_effects_enabled': True,
            'devices_off_on_screensaver': True,
            'key_statistics': False,
        }

        if config_file is not None and os.path.exists(config_file):
            self._config.read(config_file)

    def get_off_on_screensaver(self):
        """
        Returns if turn off on screensaver

        :return: Result
        :rtype: bool
        """
        return self._screensaver_monitor.monitoring

    def enable_turn_off_on_screensaver(self, enable):
        """
        Enable the turning off of devices when the screensaver is active
        """
        self._screensaver_monitor.monitoring = enable

    def supported_devices(self):
        result = {
            cls.__name__: (cls.USB_VID, cls.USB_PID)
            for cls in self._device_classes
        }

        return json.dumps(result)

    def version(self):
        """
        Get the daemon version

        :return: Version string
        :rtype: str
        """
        return __version__

    def suspend_devices(self):
        """
        Suspend all devices
        """
        for device in self._razer_devices:
            device.dbus.suspend_device()

    def resume_devices(self):
        """
        Resume all devices
        """
        for device in self._razer_devices:
            device.dbus.resume_device()

    def get_serial_list(self):
        """
        Get list of devices serials
        """
        serial_list = self._razer_devices.serials()
        self.logger.debug('DBus called get_serial_list')
        return serial_list

    def sync_effects(self, enabled):
        """
        Sync the effects across the devices

        :param enabled: True to sync effects
        :type enabled: bool
        """
        # Todo perhaps move logic to device collection
        for device in self._razer_devices.devices:
            device.dbus.effect_sync = enabled

    def get_sync_effects(self):
        """
        Sync the effects across the devices

        :return: True if any devices sync effects
        :rtype: bool
        """
        result = False

        for device in self._razer_devices.devices:
            result |= device.dbus.effect_sync

        return result

    def _load_devices(self, first_run=False):
        """
        Go through supported devices and load them

        Loops through the available hardware classes, loops through
        each device in the system and adds it if needs be.
        """
        if first_run:
            # Just some pretty output
            max_name_len = max(
                [len(cls.__name__) for cls in self._device_classes]) + 2
            for cls in self._device_classes:
                format_str = 'Loaded device specification: {0:-<' + str(
                    max_name_len) + '} ({1:04x}:{2:04X})'

                self.logger.debug(
                    format_str.format(cls.__name__ + ' ', cls.USB_VID,
                                      cls.USB_PID))

        if self._test_dir is not None:
            device_list = os.listdir(self._test_dir)
            test_mode = True
        else:
            device_list = list(
                self._udev_context.list_devices(subsystem='hid'))
            test_mode = False

        device_number = 0
        for device in device_list:

            for device_class in self._device_classes:
                # Interoperability between generic list of 0000:0000:0000.0000 and pyudev
                if test_mode:
                    sys_name = device
                    sys_path = os.path.join(self._test_dir, device)
                else:
                    sys_name = device.sys_name
                    sys_path = device.sys_path

                if sys_name in self._razer_devices:
                    continue

                if device_class.match(
                        sys_name, sys_path
                ):  # Check it matches sys/ ID format and has device_type file
                    self.logger.info('Found device.%d: %s', device_number,
                                     sys_name)

                    # TODO add testdir support
                    # Basically find the other usb interfaces
                    device_match = sys_name.split('.')[0]
                    additional_interfaces = []
                    if not test_mode:
                        for alt_device in device_list:
                            if device_match in alt_device.sys_name and alt_device.sys_name != sys_name:
                                additional_interfaces.append(
                                    alt_device.sys_path)

                    # Checking permissions
                    test_file = os.path.join(sys_path, 'device_type')
                    file_group_id = os.stat(test_file).st_gid
                    file_group_name = grp.getgrgid(file_group_id)[0]

                    if os.getgid(
                    ) != file_group_id and file_group_name != 'plugdev':
                        self.logger.critical(
                            "Could not access {0}/device_type, file is not owned by plugdev"
                            .format(sys_path))
                        break

                    razer_device = device_class(
                        sys_path,
                        device_number,
                        self._config,
                        testing=self._test_dir is not None,
                        additional_interfaces=sorted(additional_interfaces))

                    # Wireless devices sometimes don't listen
                    count = 0
                    while count < 3:
                        # Loop to get serial, exit early if it gets one
                        device_serial = razer_device.get_serial()
                        if len(device_serial) > 0:
                            break
                        time.sleep(0.1)
                        count += 1
                    else:
                        logging.warning(
                            "Could not get serial for device {0}. Skipping".
                            format(sys_name))
                        continue

                    self._razer_devices.add(sys_name, device_serial,
                                            razer_device)

                    device_number += 1

    def _add_device(self, device):
        """
        Add device event from udev

        :param device: Udev Device
        :type device: pyudev.device._device.Device
        """
        device_number = len(self._razer_devices)
        for device_class in self._device_classes:
            sys_name = device.sys_name
            sys_path = device.sys_path

            if sys_name in self._razer_devices:
                continue

            if device_class.match(
                    sys_name, sys_path
            ):  # Check it matches sys/ ID format and has device_type file
                self.logger.info('Found valid device.%d: %s', device_number,
                                 sys_name)
                razer_device = device_class(sys_path,
                                            device_number,
                                            self._config,
                                            testing=self._test_dir is not None)

                # Its a udev event so currently the device hasn't been chmodded yet
                time.sleep(0.2)

                # Wireless devices sometimes don't listen
                device_serial = razer_device.get_serial()

                if len(device_serial) > 0:
                    # Add Device
                    self._razer_devices.add(sys_name, device_serial,
                                            razer_device)
                    self.device_added()
                else:
                    logging.warning(
                        "Could not get serial for device {0}. Skipping".format(
                            sys_name))
            else:
                # Basically find the other usb interfaces
                device_match = sys_name.split('.')[0]
                for d in self._razer_devices:
                    if device_match in d.device_id and d.device_id != sys_name:
                        if not sys_path in d.dbus.additional_interfaces:
                            d.dbus.additional_interfaces.append(sys_path)
                            return

    def _remove_device(self, device):
        """
        Remove device event from udev

        :param device: Udev Device
        :type device: pyudev.device._device.Device
        """
        device_id = device.sys_name

        try:
            device = self._razer_devices[device_id]

            device.dbus.close()
            device.dbus.remove_from_connection()
            self.logger.warning("Removing %s", device_id)

            # Delete device
            del self._razer_devices[device.device_id]
            self.device_removed()

        except IndexError:  # Why didn't i set it up as KeyError
            # It will return "extra" events for the additional usb interfaces bound to the driver
            pass

    def _udev_input_event(self, device):
        """
        Function called by the Udev monitor (#observerPattern)

        :param device: Udev device
        :type device: pyudev.device._device.Device
        """
        self.logger.debug('Device event [%s]: %s', device.action,
                          device.device_path)
        if device.action == 'add':
            if self._collecting_udev:
                self._collecting_udev_devices.append(device)
                return
            else:
                self._collecting_udev_devices = [device]
                self._collecting_udev = True
                t = threading.Thread(target=self._collecting_udev_method,
                                     args=(device, ))
                t.start()
        elif device.action == 'remove':
            self._remove_device(device)

    def _collecting_udev_method(self, device):
        time.sleep(2)  # delay to let udev add all devices that we want
        # Sort the devices
        self._collecting_udev_devices.sort(key=lambda x: x.sys_path,
                                           reverse=True)
        for d in self._collecting_udev_devices:
            self._add_device(d)
        self._collecting_udev = False

    def run(self):
        """
        Run the daemon
        """
        self.logger.info('Serving DBus')

        # Start listening for device changes
        self._udev_observer.start()

        # Start the mainloop
        try:
            self._main_loop.run()
        except KeyboardInterrupt:
            self.logger.debug('Shutting down')

    def stop(self):
        """
        Wrapper for quit
        """
        self.quit(None)

    def quit(self, signum):
        """
        Quit by stopping the main loop, observer, and screensaver thread
        """
        # pylint: disable=unused-argument
        if signum is None:
            self.logger.info('Stopping daemon.')
        else:
            self.logger.info('Stopping daemon on signal %d', signum)

        self._main_loop.quit()

        # Stop udev monitor
        self._udev_observer.send_stop()

        for device in self._razer_devices:
            device.dbus.close()
Example #49
0
from pyudev import Context, Monitor, MonitorObserver


def is_usb(device):
    return device.get('ID_BUS', None) == 'usb'


def log_event(action, dev):
    if 'ID_FS_TYPE' in dev:  # жахни здесь проверку на тип dev
                            # чтобы для Device и Partition выводило разное сообщение
        print('Action:{0} Device/Partition:{1.device_node} Label:{2}'.format(
              action, dev, dev.get('ID_FS_LABEL')))


if __name__ == '__main__':
    udev_context = Context()
    devs = udev_context.list_devices(subsystem='block', DEVTYPE='disk')
    devs = list(filter(is_usb, devs))
    print('All current devices:')
    for d in devs:
        print('device:{0.device_node}'.format(d))
        for c in d.children:
            print('Partition:{0.device_node} Label:{1}'.format(c, c.get("ID_FS_LABEL")))
    monitor = Monitor.from_netlink(udev_context)
    monitor.filter_by('block')
    observer = MonitorObserver(monitor, log_event)
    observer.start()
    while True:
        pass  # a loop for Monitor
Example #50
0
# vendor = Advanced Micro Devices, Inc. [AMD/ATI]
# model = Ellesmere [Radeon RX 470/480/570/570X/580/580X/590]
#
# Reverse order lookup:
# [1002:67df 1682:c580]
# vendor = XFX Pine Group Inc.
# model = Radeon RX 580

from pyudev import Context
from libpci import LibPCI

context = Context()
pci = LibPCI()

for number, device in enumerate(
        context.list_devices(subsystem='pci',
                             ID_PCI_CLASS_FROM_DATABASE='Display controller')):
    vendor_id, device_id = [
        int(i, 16) for i in device.properties['PCI_ID'].split(':')
    ]
    subvendor_id, subdevice_id = [
        int(i, 16) for i in device.properties['PCI_SUBSYS_ID'].split(':')
    ]

    vendor = pci.lookup_vendor_name(vendor_id)
    model = pci.lookup_subsystem_device_name(vendor_id=vendor_id,
                                             device_id=device_id,
                                             subvendor_id=subvendor_id,
                                             subdevice_id=subdevice_id)

    vendor_reverse = pci.lookup_vendor_name(subvendor_id)
    model_reverse = pci.lookup_subsystem_device_name(vendor_id=subvendor_id,
Example #51
0
def get_devices_list():
    udev_context = Context()
    devs = udev_context.list_devices(subsystem='block', DEVTYPE='disk')
    devs = list(filter(is_usb, devs))

    return devs
Example #52
0
 def list_ses_enclosures(self):
     ctx = Context()
     return [
         f'/dev/bsg/{i.sys_name}'
         for i in ctx.list_devices(subsystem='enclosure')
     ]
Example #53
-1
class SCODDaemon:
    def __init__(self):
        self.context = Context()
        self.monitor = None
        
        self.dbus = DBUSThread()
        self.dbus.start()
        self.tell_about_devices()
        print "Done."

    def __del__(self):
        self.dbus.stop()

    def start_listen(self):
        self.monitor = Monitor.from_netlink(self.context)
        for action, device in self.monitor:
            self._new_device(action, device)

    def _new_device(self, act, dev):
        if act != 'add':
            return
    
        time.sleep(0.1)
        if ('MODALIAS' not in dev.keys()):
            return

        d = SCODDevice(dev)
        if ( d.isOurDevice() ):
            self.dbus.tell_about_new_device(d)
    
    def tell_about_devices(self):
        print "DBUS is %s" % self.dbus.isAlive()
        for dev in self.context.list_devices():
            d = SCODDevice(dev)
            if ( d.isOurDevice() ):
                self.dbus.tell_about_new_device(d)
    def stop(self):
        self.dbus.stop()