def __init__(self, bus): self.path = "/org/freesmartphone/Time" super(Time, self).__init__(bus, self.path) self.interface = "org.freesmartphone.Time" self.bus = bus timesources = [ x.strip().upper() for x in config.getValue("otimed", "timesources", "GPS,NTP").split(',') ] zonesources = [ x.strip().upper() for x in config.getValue("otimed", "zonesources", "GSM").split(',') ] ntpserver = config.getValue("otimed", "ntpserver", "134.169.172.1").strip() self.timesources = [] if 'GPS' in timesources: self.timesources.append(GPSTimeSource(self.bus)) if 'NTP' in timesources: self.timesources.append(NTPTimeSource(self.bus, ntpserver)) logger.info("loaded timesources %s", self.timesources) self.zonesources = [] if 'GSM' in zonesources: self.zonesources.append(GSMZoneSource(self.bus)) logger.info("loaded zonesources %s", self.zonesources) self.interval = 90 self.updateTimeout = gobject.timeout_add_seconds( self.interval, self._handleUpdateTimeout)
def __init__(self, bus, index, node): self.interface = self.DBUS_INTERFACE self.path = DBUS_PATH_PREFIX + "/Audio" dbus.service.Object.__init__(self, bus, self.path) for player in ( AlsaPlayer, GStreamerPlayer, ): supportedFormats = player.supportedFormats() instance = player(self) for format in supportedFormats: if format not in self.players: self.players[format] = instance scenario_dir = config.getValue(MODULE_NAME, "scenario_dir", "/etc/alsa/scenario") default_scenario = config.getValue(MODULE_NAME, "default_scenario", "default") self.scenario = AlsaScenarios(self, scenario_dir, default_scenario) logger.info( "%s %s initialized. Serving %s at %s" % (self.__class__.__name__, __version__, self.interface, self.path)) logger.debug("^^^ found players for following formats: '%s'" % self.players.keys())
def __init__( self, bus, index, node ): self.interface = self.DBUS_INTERFACE self.path = DBUS_PATH_PREFIX + "/Input" dbus.service.Object.__init__( self, bus, self.path ) asyncworker.AsyncWorker.__init__( self ) logger.info( "%s %s initialized. Serving %s at %s" % ( self.__class__.__name__, __version__, self.interface, self.path ) ) configvalue = config.getValue( MODULE_NAME, "ignoreinput", "" ) ignoreinput = [ int(value) for value in configvalue.split(',') if value != "" ] self.input = {} for i in itertools.count(): if i in ignoreinput: logger.info( "skipping input node %d due to configuration" % ( i ) ) continue try: f = os.open( "/dev/input/event%d" % i, os.O_NONBLOCK ) except OSError, e: logger.debug( "can't open /dev/input/event%d: %s. Assuming it doesn't exist.", i, e ) break else: # Ignore input devices spitting out absolute data (touchscreen, mouse, et. al) if input_device_supports_event_type( f, EV_ABS ): logger.info( "skipping input node %d due to it supporting EV_ABS" % ( i ) ) os.close( f ) continue else: self.input[f] = "event%d" % i
def factory(prefix, controller): #----------------------------------------------------------------------------# objects = [] devname = config.getValue("ogpsd", "device", "DummyDevice") channame = config.getValue("ogpsd", "channel", "GPSChannel") pathname = config.getValue("ogpsd", "path", "") debug = config.getValue("ogpsd", "debug_addr", "") channel = globals()[channame](pathname) if debug: channel.setDebugChannel(UDPChannel(debug)) gpsdev = globals()[devname](controller.bus, channel) objects.append(gpsdev) return objects
class ClientResource(AbstractResource): #----------------------------------------------------------------------------# """ A resource controlled by an external client. The client needs to expose a dbus object implementing org.freesmartphone.Resource. It can register using the RegisterResource of /org/freesmartphone/Usage. If the client is written in python, it can use the framework.Resource class. """ sync_resources_with_lifecycle = config.getValue( "ousaged", "sync_resources_with_lifecycle", "always") def __init__(self, usageControl, name, path, sender): """ Create a new ClientResource Only the resource manager should call this method """ super(ClientResource, self).__init__(usageControl, name) self.path = path self.sender = sender self.iface = None if self.sync_resources_with_lifecycle in ("always", "startup"): self._disable().start() @tasklet.tasklet def _enable(self): """Simply call the client Enable method""" if self.iface is None: self.iface = dbuscache.dbusInterfaceForObjectWithInterface( self.sender, self.path, "org.freesmartphone.Resource") yield tasklet.WaitDBus(self.iface.Enable) @tasklet.tasklet def _disable(self): """Simply call the client Disable method""" if self.iface is None: self.iface = dbuscache.dbusInterfaceForObjectWithInterface( self.sender, self.path, "org.freesmartphone.Resource") yield tasklet.WaitDBus(self.iface.Disable) @tasklet.tasklet def _suspend(self): """Simply call the client Suspend method""" if self.iface is None: self.iface = dbuscache.dbusInterfaceForObjectWithInterface( self.sender, self.path, "org.freesmartphone.Resource") yield tasklet.WaitDBus(self.iface.Suspend) @tasklet.tasklet def _resume(self): """Simply call the client Resume method""" if self.iface is None: self.iface = dbuscache.dbusInterfaceForObjectWithInterface( self.sender, self.path, "org.freesmartphone.Resource") yield tasklet.WaitDBus(self.iface.Resume)
def factory(prefix, controller): #============================================================================# # FIXME I would let the FSOSubsystem object deal with chosing the device type device_map = {'gta02': Gta02Accelerometer, 'mock': MockAccelerometer} device = config.getValue(MODULE_NAME, "accelerometer_type", "mock") device_class = device_map[device] f = FSOSubsystem(device_class(), controller.bus) return [ f, ]
class Input( dbus.service.Object, asyncworker.AsyncWorker ): #----------------------------------------------------------------------------# """A Dbus Object implementing org.freesmartphone.Device.Input""" DBUS_INTERFACE = DBUS_INTERFACE_PREFIX + ".Input" action = { "key": 1, "switch": 5 } def __init__( self, bus, index, node ): self.interface = self.DBUS_INTERFACE self.path = DBUS_PATH_PREFIX + "/Input" dbus.service.Object.__init__( self, bus, self.path ) asyncworker.AsyncWorker.__init__( self ) logger.info( "%s %s initialized. Serving %s at %s" % ( self.__class__.__name__, __version__, self.interface, self.path ) ) configvalue = config.getValue( MODULE_NAME, "ignoreinput", "" ) ignoreinput = [ int(value) for value in configvalue.split(',') if value != "" ] self.input = {} for i in itertools.count(): if i in ignoreinput: logger.info( "skipping input node %d due to configuration" % ( i ) ) continue try: f = os.open( "/dev/input/event%d" % i, os.O_NONBLOCK ) except OSError, e: logger.debug( "can't open /dev/input/event%d: %s. Assuming it doesn't exist.", i, e ) break else: # Ignore input devices spitting out absolute data (touchscreen, mouse, et. al) if input_device_supports_event_type( f, EV_ABS ): logger.info( "skipping input node %d due to it supporting EV_ABS" % ( i ) ) os.close( f ) continue else: self.input[f] = "event%d" % i logger.info( "opened %d input file descriptors", len( self.input ) ) self.watches = {} self.events = {} self.reportheld = {} for option in config.getOptions( MODULE_NAME ): if option.startswith( "report" ): try: name, typ, code, reportheld = config.getValue( MODULE_NAME, option ).split( ',' ) code = int(code) reportheld = bool(int(reportheld)) except ValueError: logger.warning( "wrong syntax for switch definition '%s': ignoring." % option ) else: self.watchForEvent( name, typ, code, reportheld ) if len( self.input ): self.launchStateMachine()
def __init__(self, *args, **kwargs): # kernel specific paths global SYSFS_CALYPSO_POWER_PATH global SYSFS_CALYPSO_RESET_PATH global SYSFS_CALYPSO_FLOW_CONTROL_PATH kernel_release = os.uname()[2] if kernel_release >= "2.6.32": SYSFS_CALYPSO_POWER_PATH = "/sys/bus/platform/devices/gta02-pm-gsm.0/power_on" SYSFS_CALYPSO_RESET_PATH = "/sys/bus/platform/devices/gta02-pm-gsm.0/reset" SYSFS_CALYPSO_FLOW_CONTROL_PATH = "/sys/bus/platform/devices/gta02-pm-gsm.0/flowcontrolled" logger.info("Kernel >=2.6.32, gsm sysfs path updated") AbstractModem.__init__(self, *args, **kwargs) self._channelmap = { "ogsmd.call": 1, "ogsmd.unsolicited": 2, "ogsmd.misc": 3, "ogsmd.gprs": 4 } # VC 1 self._channels["CALL"] = CallChannel(self.pathfactory, "ogsmd.call", modem=self) # VC 2 self._channels["UNSOL"] = UnsolicitedResponseChannel( self.pathfactory, "ogsmd.unsolicited", modem=self) # VC 3 self._channels["MISC"] = MiscChannel(self.pathfactory, "ogsmd.misc", modem=self) # VC 4 # FIXME pre-allocate GPRS channel for pppd? # configure channels self._channels["UNSOL"].setDelegate( UnsolicitedResponseDelegate(self._object, mediator)) # configure behaviour using special commands self._data["cancel-outgoing-call"] = "%CHLD=I" # muxer mode self._muxercommand = config.getValue("ogsmd", "ti_calypso_muxer", "gsm0710muxd") # muxer object self._muxeriface = None
def __init__(self, path, rtscts=False): super(SerialChannel, self).__init__() # set up serial port object and open it self.serial = serial.Serial() self.serial.port = path self.serial.baudrate = config.getValue("ogpsd.serialchannel", "baudrate", 9600) self.serial.rtscts = rtscts self.serial.xonxoff = False self.serial.bytesize = serial.EIGHTBITS self.serial.parity = serial.PARITY_NONE self.serial.stopbits = serial.STOPBITS_ONE self.serial.timeout = None self.datapending = "" self.watchReadyToRead = None self.watchReadyToSend = None
def __init__(self, bus, index, extranodes): self.__class__._instance = self self.interface = self.DBUS_INTERFACE self.path = DBUS_PATH_PREFIX + "/IdleNotifier/%s" % index dbus.service.Object.__init__(self, bus, self.path) logger.info("%s %s initialized. Serving %s at %s", self.__class__.__name__, __version__, self.interface, self.path) self.defaultTimeouts = dict(awake=-1, busy=-1, idle=10, idle_dim=20, idle_prelock=12, lock=2, suspend=20) self.timeouts = self.defaultTimeouts.copy() self.states = "awake busy idle idle_dim idle_prelock lock suspend".split( ) self.validStates = set(self.states) self.allowedStates = set(self.states) self.state = self.states[0] configvalue = config.getValue(MODULE_NAME, "ignoreinput", "") ignoreinput = [ int(value) for value in configvalue.split(',') if value != "" ] self.input = {} for i in itertools.count(): if i in ignoreinput: logger.info("skipping input node %d due to configuration" % i) continue try: f = os.open("/dev/input/event%d" % i, os.O_NONBLOCK) except OSError, e: logger.debug( "can't open /dev/input/event%d: %s. Assuming it doesn't exist." % (i, e)) break else: self.input[f] = "event%d" % i
def __init__(self, *args, **kwargs): AbstractUnsolicitedResponseDelegate.__init__(self, *args, **kwargs) self._callHandler.unsetHook( ) # we have special call handling that doesn't need stock hooks self.fullReadyness = "unknown" self.subsystemReadyness = {"PHB": False, "SMS": False} self.checkForRecamping = (config.getValue("ogsmd", "ti_calypso_deep_sleep", "adaptive") == "adaptive") if self.checkForRecamping: # initialize deep sleep vars self.lastStatus = "busy" self.lastTime = 0 self.firstReregister = 0 self.lastReregister = 0 self.reregisterIntervals = [] self.recampingTimeout = None
def __init__(self, dbus_object, bus, *args, **kwargs): """ Initialize """ assert self.__class__.__name__ != "AbstractModem", "can't instanciate pure virtual class" # FIXME make sure only one modem exists AbstractModem.instance = self self._channels = {} # container for channel instances self._object = dbus_object # dbus object self._bus = bus # dbus bus self._simPinState = "unknown" # SIM PIN state self._simReady = "unknown" # SIM data access state self._data = {} # misc modem-wide data, set/get from channels self._phonebookIndices = {} # min. index, max. index self._phonebookSizes = {} # number length, name length self._data["sim-buffers-sms"] = True self._data["sms-buffered-cb"] = "2,1,2,1,1" self._data["sms-buffered-nocb"] = "2,1,0,0,0" # FIXME: Might be bad as default, since not all modems necessarily support that self._data["sms-direct-cb"] = "2,2,2,1,1" # what about a,3,c,d,e? self._data["sms-direct-nocb"] = "2,2,0,0,0" # dito self._data["pppd-configuration"] = [ \ '115200', 'nodetach', 'crtscts', 'defaultroute', 'debug', 'hide-password', 'holdoff', '3', 'ipcp-accept-local', 'ktune', #'lcp-echo-failure', '10', #'lcp-echo-interval', '20', 'ipcp-max-configure', '4', 'lock', 'noauth', #'demand', 'noipdefault', 'novj', 'novjccomp', #'persist', 'proxyarp', 'replacedefaultroute', 'usepeerdns', ] self._data[ "pppd-does-setup-and-teardown"] = True # default is using connect and disconnect scripts self._charsets = { \ "DEFAULT": "gsm_default", "PHONEBOOK": "gsm_ucs2", "USSD": "gsm_ucs2", } self._data[ "cancel-outgoing-call"] = "H" # default will kill all connections self._data["data-call-handler"] = config.getValue( "ogsmd", "data_call_handler", None)
def dataPort( self ): # FIXME remove duplication and just use pathfactory return config.getValue( "ogsmd", "data", default="/dev/smd7" )
Module: persist """ from __future__ import with_statement __version__ = "1.0.1" MODULE_NAME = "frameworkd.persist" import os, atexit import logging logger = logging.getLogger( MODULE_NAME ) from framework.config import config, rootdir rootdir = os.path.join( rootdir, 'persist' ) format = config.getValue( "frameworkd", "persist_format", "pickle" ) if format == "pickle": import cPickle as pickle elif format == "yaml": from yaml import load, dump try: from yaml import CLoader as Loader from yaml import CDumper as Dumper except ImportError: from yaml import Loader, Dumper class Persist( object ): def __init__( self, rootdir ): self.rootdir = rootdir self.cache = {}
def __init__( self, path, options ): sys.path.append( path ) # to enable 'from <subsystemname> import ...' and 'import <subsystemname>' self.launchTime = time.time() self.options = options daemon.Daemon.__init__( self, "/tmp/frameworkd.pid" ) # dbus & glib mainloop dbus.mainloop.glib.DBusGMainLoop( set_as_default=True ) self.mainloop = gobject.MainLoop() self.bus = dbus.SystemBus() # check if there's already something owning our bus name org.freesmartphone.frameworkd if ( not self.options.values.noframework ) and ( "%s.frameworkd" % DBUS_BUS_NAME_PREFIX in self.bus.list_names() ): logger.error( "dbus bus name org.freesmartphone.frameworkd already claimed. Exiting." ) sys.exit( -1 ) self._subsystems = {} self.busnames = [] # FIXME remove hardcoded controller knowledge from objects self.config = config # gather subsystem plugins scantype scantype = config.getValue( "frameworkd", "scantype", "auto" ) # call me when idle and in mainloop gobject.idle_add( self.idle ) self._configureLoggers() self._handleOverrides() # launch special framework subsystem if ( not self.options.values.noframework ): self._subsystems["frameworkd"] = subsystem.Framework( self.bus, path, scantype, self ) Controller.objects.update( self._subsystems["frameworkd"].objects() ) systemstolaunch = self.options.values.subsystems.split( ',' ) # add internal subsystems subsystems = [ entry for entry in os.listdir( path ) if os.path.isdir( "%s/%s" % ( path, entry ) ) ] # add external subsystems for section in config.sections(): external = config.getValue( section, "external", "" ) if external and ( external not in subsystems ): subsystems.append( section ) # walk and launch subsystems for s in subsystems: disable = config.getBool( s, "disable", False ) external = config.getValue( s, "external", "" ) if disable: logger.info( "skipping subsystem %s as requested via config file." % s ) continue if systemstolaunch != [""]: if s not in systemstolaunch: logger.info( "skipping subsystem %s as requested via command line" % s ) continue if external: logger.info( "launching external subsystem %s" % s ) self._subsystems[s] = subsystem.External( s, external, scantype, self ) else: logger.info( "launching internal subsystem %s" % s ) self._subsystems[s] = subsystem.Subsystem( s, self.bus, path, scantype, self ) Controller.objects.update( self._subsystems[s].objects() ) # do we have any subsystems left? if len( self._subsystems ) <= 1: # no additional subsystems could be loaded if len( self._subsystems ) == 0 or 'frameworkd' in self._subsystems: logger.error( "can't launch without at least one subsystem. Exiting." ) sys.exit( -1 )
def _configureLoggers( self ): # configure all loggers, default being INFO for section in config.sections(): loglevel = loggingmap.get( config.getValue( section, "log_level", debug ) ) logger.debug( "setting logger for %s to %s" % ( section, loglevel ) ) logging.getLogger( section ).setLevel( loglevel )
def factory(prefix, controller): #=========================================================================# sys.path.append(os.path.dirname(os.path.dirname(__file__))) modemtype = config.getValue("ogsmd", "modemtype", "unspecified") device = Device(controller.bus, modemtype) return [device]
def portfactory(self, name): return config.getValue("ogsmd", "serial", default="/dev/ttySAC0")
def _populateCommands( self ): CalypsoModemChannel._populateCommands( self ) c = self._commands["init"] # GSM unsolicited c.append( '+CLIP=1' ) # calling line identification presentation enable c.append( '+COLP=0' ) # connected line identification presentation: disable # DO NOT enable +COLP=1 on the Calypso, it will raise the chance to drop into FSO #211 #c.append( '+COLP=1' ) # connected line identification presentation: enable c.append( '+CCWA=1' ) # call waiting c.append( "+CSSN=1,1" ) # supplementary service notifications: send unsol. code c.append( '+CTZU=1' ) # timezone update c.append( '+CTZR=1' ) # timezone reporting c.append( '+CREG=2' ) # registration information (NOTE not all modems support =2) c.append( "+CAOC=2" ) # advice of charge: send unsol. code # GPRS unsolicited c.append( "+CGEREP=2,1" ) c.append( "+CGREG=2" ) # calypso proprietary unsolicited c.append( "%CPI=3" ) # call progress indication: enable with call number ID, GSM Cause, and ALS c.append( "%CSCN=1,2,1,2" ) # show service change: call control service and supplementary service c.append( "%CSQ=1" ) # signal strength: send unsol. code c.append( "%CPRI=1" ) # gsm cipher indication: send unsol. code c.append( "%CNIV=1" ) c.append( "%CSTAT=1" ) # machine specific (might not be the best place here) c.append( '@ST="-26"' ) # audio side tone: set to minimum deepSleepMode = config.getValue( "ogsmd", "ti_calypso_deep_sleep", "adaptive" ) if deepSleepMode == "never": c.append( "%SLEEP=2" ) # sleep mode: disable all else: c.append( "%SLEEP=4" ) # sleep mode: enable all c.append( createDspCommand() ) c = self._commands["antenna"] c.append( "+CLVL=255" ) # audio output: set to maximum c = self._commands["suspend"] def sms_no_cb( self=self ): if self._modem.data( "sim-buffers-sms" ): return "+CNMI=%s" % self._modem.data( "sms-buffered-nocb" ) else: return "+CNMI=%s" % self._modem.data( "sms-direct-nocb" ) c.append( sms_no_cb ) c.append( "+CTZU=0" ) c.append( "+CTZR=0" ) c.append( "+CREG=0" ) c.append( "+CGREG=0" ) c.append( "+CGEREP=0,0" ) c.append( "%CSQ=0" ) c.append( "%CPRI=0" ) c.append( "%CBHZ=0" ) # home zone cell broadcast: disable c = self._commands["resume"] c.insert( 0, "+CTZU=1" ) c.insert( 0, "+CTZR=1" ) c.insert( 0, "+CREG=2" ) c.insert( 0, "+CGREG=2" ) c.insert( 0, "+CGEREP=2,1" ) c.insert( 0, "%CSQ=1" ) # signal strength: send unsol. code c.insert( 0, "%CPRI=1" ) # gsm cipher indication: send unsol. code c.insert( 0, "%CNIV=1" ) c += self._commands["sim"] # reenable notifications def homezone( self=self ): return "%CBHZ=1" if self._modem.data( "homezone-enabled", False ) else "%CBHZ=0" c.append( homezone )
def createDspCommand(): dspMode = config.getValue( "ogsmd", "ti_calypso_dsp_mode", "aec+nr" ) return "%N" + AEC_NR_MAP.get( dspMode, "aec+nr" )
class Resource(dbus.service.Object, asyncworker.SynchronizedAsyncWorker): #----------------------------------------------------------------------------# """ Base class for all the resources The Resource class is used for anything that need to know about who is using a given resource. The OUsaged subsystem manage all the resources and keep track of how many clients are using them. When a resource is no longer used, its Disable method will be called by ousaged. The resource object can then do whatever is needed. When a resource is disabled and a client need to use it, ousaged will call its Enable method. A resource also needs to be able to prepare for a system suspend, or resume OUsaged will call the Suspend and Resume methods of the resource before a system suspend and after a system wakeup. To define a new resource, a subsystem needs to subclass this class, and call the register method once after initialisation. """ DBUS_INTERFACE = 'org.freesmartphone.Resource' sync_resources_with_lifecycle = config.getValue( "ousaged", "sync_resources_with_lifecycle", "always") commandInProgress = { \ "enable": "enabling", "disable": "disabling", "suspend": "suspending", "resume": "resuming", } commandDone = { \ "enable": "enabled", "disable": "disabled", "suspend": "suspended", "resume": "enabled", } def __init__(self, bus, name): """ Register the object as a new resource in ousaged bus: dbus session bus name: the name of the resource that will be used by the clients """ # HACK HACK HACK: We do _not_ initialize the dbus service object here, # (in order to prevent initializing it twice), but rather rely on someone # else doing this for us. if not isinstance(self, dbus.service.Object): raise RuntimeError( "Resource only allowed as mixin w/ dbus.service.Object") self._resourceBus = bus self._resourceName = name self._resourceStatus = "unknown" self._delayedSignalQueue = Queue.Queue() asyncworker.SynchronizedAsyncWorker.__init__(self) # We need to call the ousaged.Register method, but we can't do it # immediatly for the ousaged object may not be present yet. # We use gobject.idle_add method to make the call only at the next # mainloop iteration def on_idle(self=self): logger.debug("Trying to register resource %s", self._resourceName) try: usaged = self._resourceBus.get_object( "org.freesmartphone.ousaged", "/org/freesmartphone/Usage") usageiface = dbus.Interface(usaged, "org.freesmartphone.Usage") except dbus.exceptions.DBusException: logger.warning( "Can't register resource %s since ousaged is not present. Enabling device", name) gobject.idle_add(self.Enable, lambda: False, lambda dummy: False) else: def on_reply(self=self): logger.debug("%s is now a registered resource", self._resourceName) def on_error(err, self=self): logger.error("%s can't be registered (%s). Enabling", self._resourceName, err) gobject.idle_add(self.Enable, lambda: False, lambda dummy: False) #usageiface = dbuscache.dbusInterfaceForObjectWithInterface( #"org.freesmartphone.ousaged", #"/org/freesmartphone/Usage", #"org.freesmartphone.Usage" ) #usageiface.RegisterResource( self._resourceName, self, reply_handler=on_reply, error_handler=on_error ) usageiface.RegisterResource(self._resourceName, self, reply_handler=on_reply, error_handler=on_error) return False # mainloop: don't call me again gobject.idle_add(on_idle) @exceptionlogger def onProcessElement(self, element): command, ok_callback, err_callback = element logger.debug( "processing command '%s' for resource '%s' (present status=%s)", command, self, self._resourceStatus) stateNow = self._resourceStatus if stateNow == "disabled" and command != "enable": ok_callback() else: def ok(self=self, command=command, dbus_ok=ok_callback): self._updateResourceStatus(self.commandDone[command]) logger.debug( "(ok) done processing command '%s' for resource '%s' (new status=%s); triggering next command", command, self, self._resourceStatus) self.trigger() dbus_ok() def err(error, self=self, command=command, dbus_err=err_callback): logger.debug( "(error) done processing command '%s' for resource '%s' (new status=%s); triggering next command", command, self, self._resourceStatus) self.trigger() dbus_err(error) self._updateResourceStatus(self.commandInProgress[command]) if command == "enable": self._enable(ok, err) elif command == "disable": self._disable(ok, err) elif command == "suspend": self._suspend(ok, err) elif command == "resume": self._resume(ok, err) else: logger.warning("unknown resource command '%s' ignored.", command) self.trigger() def shutdown(self): """ Called by the subsystem during system shutdown. """ if self.sync_resources_with_lifecycle in ( "always", "shutdown" ) and \ self._resourceStatus in ( "enabled" , "enabling", "unknown" ): # no error handling, either it works or not #self._disable( lambda: None, lambda Foo: None ) self.Disable(lambda: None, lambda Foo: None) def _updateResourceStatus(self, nextStatus): logger.info("setting resource status for %s from %s to %s" % (self._resourceName, self._resourceStatus, nextStatus)) self._resourceStatus = nextStatus # send all queued signals, if any if self._resourceStatus == "enabled": logger.debug("resource now enabled. checking signal queue") while not self._delayedSignalQueue.empty(): f, args = self._delayedSignalQueue.get() logger.debug("sending delayed signal %s( %s )", f, args) f(*args) # The DBus methods update the resource status and call the python implementation @dbus.service.method(DBUS_INTERFACE, "", "", async_callbacks=("dbus_ok", "dbus_error")) def Enable(self, dbus_ok, dbus_error): self.enqueue("enable", dbus_ok, dbus_error) @dbus.service.method(DBUS_INTERFACE, "", "", async_callbacks=("dbus_ok", "dbus_error")) def Disable(self, dbus_ok, dbus_error): self.enqueue("disable", dbus_ok, dbus_error) @dbus.service.method(DBUS_INTERFACE, "", "", async_callbacks=("dbus_ok", "dbus_error")) def Suspend(self, dbus_ok, dbus_error): self.enqueue("suspend", dbus_ok, dbus_error) @dbus.service.method(DBUS_INTERFACE, "", "", async_callbacks=("dbus_ok", "dbus_error")) def Resume(self, dbus_ok, dbus_error): self.enqueue("resume", dbus_ok, dbus_error) # Subclass of Service should reimplement these methods def _enable(self, on_ok, on_error): logger.warning("FIXME: Override Resource._enable for resource %s", self._resourceName) on_ok() def _disable(self, on_ok, on_error): logger.warning("FIXME: Override Resource._disable for resource %s", self._resourceName) on_ok() def _suspend(self, on_ok, on_error): logger.warning("FIXME: Override Resource._suspend for resource %s", self._resourceName) on_ok() def _resume(self, on_ok, on_error): logger.warning("FIXME: Override Resource._resume for resource %s", self._resourceName) on_ok()