|
new file 100644
|
|
|
import dbus, dbus.service, dbus.exceptions
|
|
|
from event.sync import EventDispatcher
|
|
|
|
|
|
|
|
|
OP_DPM_EMU = 'dpm-emulation'
|
|
|
OP_TR_EMU = 'tr-emulation'
|
|
|
OP_BS_EMU = 'bad-sector-emulation'
|
|
|
OP_DEV_ID = 'device-id'
|
|
|
|
|
|
|
|
|
class CDEmuDaemonProxy(EventDispatcher):
|
|
|
_name = 'net.sf.cdemu.CDEmuDaemon'
|
|
|
_object_path = '/Daemon'
|
|
|
|
|
|
def __init__(self, use_system=False):
|
|
|
"""
|
|
|
Low-level abstraction for communitating with cdemu daemon
|
|
|
:param autostart_daemon: Attempt to start daemon if it is not running
|
|
|
:param use_system: Not recommended. Consider this option deprecated. Left as a compatibility option
|
|
|
"""
|
|
|
super().__init__(
|
|
|
'daemon_started',
|
|
|
'daemon_stopped',
|
|
|
'device_status_changed',
|
|
|
'device_option_changed',
|
|
|
'device_mapping_ready',
|
|
|
'device_added',
|
|
|
'device_removed'
|
|
|
)
|
|
|
|
|
|
self._is_running = False
|
|
|
self.use_system = use_system
|
|
|
|
|
|
if self.use_system:
|
|
|
self.bus = dbus.SystemBus()
|
|
|
else:
|
|
|
self.bus = dbus.SessionBus()
|
|
|
|
|
|
self.bus.add_signal_receiver(self.from_daemon, dbus_interface='net.sf.cdemu.CDEmuDaemon',
|
|
|
member_keyword='signal', message_keyword='params')
|
|
|
self.bus.add_signal_receiver(self.from_dbus, dbus_interface='org.freedesktop.DBus',
|
|
|
member_keyword='signal', message_keyword='params')
|
|
|
|
|
|
self.obj = None
|
|
|
self.interface = None
|
|
|
|
|
|
self.connect()
|
|
|
|
|
|
@property
|
|
|
def is_running(self):
|
|
|
return self._is_running
|
|
|
|
|
|
def connect(self, retry=True):
|
|
|
self.obj = self.bus.get_object(self._name, self._object_path)
|
|
|
self.interface = dbus.Interface(self.obj, dbus_interface='net.sf.cdemu.CDEmuDaemon')
|
|
|
|
|
|
self.ping_daemon(retry)
|
|
|
|
|
|
def ping_daemon(self, retry=True):
|
|
|
try:
|
|
|
self.obj.Ping(dbus_interface='org.freedesktop.DBus.Peer')
|
|
|
self._is_running = True
|
|
|
self.dispatch('daemon_started')
|
|
|
except dbus.exceptions.DBusException as e:
|
|
|
if e.get_dbus_name() == 'org.freedesktop.DBus.Error.ServiceUnknown' and retry:
|
|
|
self.connect(False)
|
|
|
|
|
|
def from_dbus(self, *args, signal, params):
|
|
|
print('from_dbus', '|'.join([str(a) for a in args]), signal, params)
|
|
|
if signal == 'NameOwnerChanged':
|
|
|
if args[0] == self._name:
|
|
|
if args[2]:
|
|
|
self._is_running = True
|
|
|
self.dispatch('daemon_started')
|
|
|
else:
|
|
|
self._is_running = False
|
|
|
self.dispatch('daemon_stopped')
|
|
|
|
|
|
def from_daemon(self, *args, signal, params):
|
|
|
print('from_daemon', '|'.join([str(a) for a in args]), signal, params)
|
|
|
if signal == "DeviceStatusChanged":
|
|
|
self.dispatch('device_status_changed', *args)
|
|
|
elif signal == "DeviceOptionChanged":
|
|
|
self.dispatch('device_option_changed', *args)
|
|
|
elif signal == "DeviceMappingReady":
|
|
|
self.dispatch('device_mapping_ready', *args)
|
|
|
elif signal == "DeviceAdded":
|
|
|
self.dispatch('device_added', *args)
|
|
|
elif signal == "DeviceRemoved":
|
|
|
self.dispatch('device_removed', *args)
|
|
|
|
|
|
def get_daemon_version(self):
|
|
|
return self.interface.GetDaemonVersion()
|
|
|
|
|
|
def get_library_version(self):
|
|
|
return self.interface.GetLibraryVersion()
|
|
|
|
|
|
def get_daemon_interface_version2(self):
|
|
|
return self.interface.GetDaemonInterfaceVersion2()
|
|
|
|
|
|
def enum_daemon_debug_masks(self):
|
|
|
return self.interface.EnumDaemonDebugMasks()
|
|
|
|
|
|
def enum_library_debug_masks(self):
|
|
|
return self.interface.EnumLibraryDebugMasks()
|
|
|
|
|
|
def enum_supported_parsers(self):
|
|
|
return self.interface.EnumSupportedParsers()
|
|
|
|
|
|
def enum_supported_writers(self):
|
|
|
return self.interface.EnumSupportedWriters()
|
|
|
|
|
|
def enum_supported_filter_streams(self):
|
|
|
return self.interface.EnumSupportedFilterStreams()
|
|
|
|
|
|
def enum_writer_parameters(self, writer_id):
|
|
|
return self.interface.EnumWriterParameters('(s)', writer_id)
|
|
|
|
|
|
def get_number_of_devices(self):
|
|
|
return self.interface.GetNumberOfDevices()
|
|
|
|
|
|
def device_get_mapping(self, device_number):
|
|
|
return self.interface.DeviceGetMapping(device_number)
|
|
|
|
|
|
def device_get_status(self, device_number):
|
|
|
return self.interface.DeviceGetStatus(device_number)
|
|
|
|
|
|
def device_load(self, device_number, filenames, parameters={}):
|
|
|
return self.interface.DeviceLoad(device_number, filenames, parameters)
|
|
|
|
|
|
def device_create_blank(self, device_number, filename, parameters):
|
|
|
return self.interface.DeviceCreateBlank(device_number, filename, parameters)
|
|
|
|
|
|
def device_unload(self, device_number):
|
|
|
return self.interface.DeviceUnload(device_number)
|
|
|
|
|
|
def device_get_option(self, device_number, option_name):
|
|
|
return self.interface.DeviceGetOption(device_number, option_name)
|
|
|
|
|
|
def device_set_option(self, device_number, option_name, option_value):
|
|
|
return self.interface.DeviceSetOption(device_number, option_name, option_value)
|
|
|
|
|
|
def add_device(self):
|
|
|
return self.interface.AddDevice()
|
|
|
|
|
|
def remove_device(self):
|
|
|
return self.interface.RemoveDevice()
|