[pkg-fso-commits] [SCM] FSO frameworkd Debian packaging branch, master, updated. milestone4-368-g700ab82

Michael 'Mickey' Lauer mickey at vanille-media.de
Mon Feb 2 18:51:42 UTC 2009


The following commit has been merged in the master branch:
commit 54deb9ed8776593a7c4005081bf45ba2a1070e95
Author: Michael 'Mickey' Lauer <mickey at vanille-media.de>
Date:   Fri Dec 19 20:04:48 2008 +0100

    add preliminary netlink message dispatcher

diff --git a/framework/services.py b/framework/services.py
new file mode 100644
index 0000000..40b90d2
--- /dev/null
+++ b/framework/services.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python
+"""
+freesmartphone.org Framework Daemon
+
+(C) 2008 Michael 'Mickey' Lauer <mlauer at vanille-media.de>
+(C) 2008 Openmoko, Inc.
+GPLv2 or later
+
+Package: framework
+Module: services
+"""
+
+__version__ = "0.1.0"
+
+import gobject
+
+import os, time, sys, socket, fcntl
+try:
+    socket.NETLINK_KOBJECT_UEVENT
+except AttributeError:
+    socket.NETLINK_KOBJECT_UEVENT = 15 # not present in earlier versions
+
+import logging
+logger = logging.getLogger( "frameworkd.services" )
+
+#----------------------------------------------------------------------------#
+class KObjectDispatcher( object ):
+#----------------------------------------------------------------------------#
+    """
+    An object dispatching kobject messages
+    """
+    @classmethod
+    def addMatch( klass, action, path, callback ):
+        if klass._instance is None:
+            klass._instance = KObjectDispatcher()
+        klass._instance._addMatch( action, path, callback )
+
+    @classmethod
+    def removeMatch( klass, action, path, callback ):
+        if klass._instance is None:
+            raise KeyError( "Unknown match" )
+        else:
+            klass._instance._removeMatch( action, path, callback )
+            if not len( klass._matches ):
+                self._instance = None
+
+    _instance = None
+    _matches = {}
+
+    def __init__( self ):
+        self._socketU = None
+        self._socketR = None
+        self._watchU = None
+        self._watchR = None
+
+        # register with kobject system
+        self._socketU = socket.socket( socket.AF_NETLINK, socket.SOCK_DGRAM, socket.NETLINK_KOBJECT_UEVENT )
+        self._socketR = socket.socket( socket.AF_NETLINK, socket.SOCK_DGRAM, socket.NETLINK_ROUTE )
+        # this only works as root
+        if ( os.getgid() ):
+            logger.error( "Can't bind to netlink as non-root" )
+            return
+
+        try:
+            self._socketU.bind( ( os.getpid(), 1 ) )
+        except socket.error, e:
+            logger.error( "Could not bind to netlink, uevent notifications will not work." )
+        else:
+            logger.info( "Successfully bound to netlink uevent." )
+            self._watchU = gobject.io_add_watch( self._socketU.fileno(), gobject.IO_IN, self._onActivityU )
+
+        try:
+            self._socketR.bind( ( os.getpid(), 1 ) )
+        except socket.error, e:
+            logger.error( "Could not bind to netlink, kobject notifications will not work." )
+        else:
+            logger.info( "Successfully bound to netlink route." )
+            self._watchR = gobject.io_add_watch( self._socketR.fileno(), gobject.IO_IN, self._onActivityR )
+
+
+    def __del__( self ):
+        """
+        Deregister
+        """
+        for w in ( self._watchU, self._watchR ):
+            if w is not None:
+                gobject.remove_source( w )
+                w = None
+        for s in ( self._socketU, self._socketR ):
+            if s is not None:
+                s.shutdown( SHUT_RD )
+                s = None
+        logger.info( "Unlinked from all netlink objects. No further notifications." )
+
+    def _addMatch( self, action, path, callback ):
+        #print "action='%s', path='%s'" % ( action, path )
+        if action == '*':
+            self._addMatch( "add", path, callback )
+            self._addMatch( "remove", path, callback )
+        elif action in "add remove".split():
+            path = path.replace( '*', '' )
+            if path == '' or path.startswith( '/' ):
+                match = "%s@%s" % ( action, path )
+                #print "adding match", match
+                self._matches.setdefault( match, [] ).append( callback )
+                #print "all matches are", self._matches
+            else:
+                raise ValueError( "Path needs to start with / or be '*'" )
+        else:
+            raise ValueError( "Action needs to be 'add' or 'remove'" )
+
+    def _removeMatch( self, action, path, callback ):
+        if action == '*':
+            self._removeMatch( "add", path, callback )
+            self._removeMatch( "remove", path, callback )
+        elif action in "add remove".split():
+            path = path.replace( '*', '' )
+            if path == '' or path.startswith( '/' ):
+                match = "%s@%s" % ( action, path )
+                #print "removing match", match
+                try:
+                    matches = self._matches[match]
+                except KeyError:
+                    pass
+                else:
+                    matches.remove( callback )
+                #print "all matches are", self._matches
+            else:
+                raise ValueError( "Path needs to start with / or be '*'" )
+        else:
+            raise ValueError( "Action needs to be 'add' or 'remove'" )
+
+    def _onActivityU( self, source, condition ):
+        """
+        Run through callbacks and call, if applicable
+        """
+        data = os.read( source, 512 )
+        print "MSG='%s'" % repr(data)
+        logger.debug( "Received kobject notification: %s" % repr(data) )
+        parts = data.split( '\0' )
+        action, path = parts[0].split( '@' )
+        properties = {}
+        if len( parts ) > 1:
+            properties = dict( [ x.split('=') for x in parts if '=' in x ] )
+        #print "action='%s', path='%s', properties='%s'" % ( action, path, properties
+        for match, rules in self._matches.iteritems():
+            #print "checking %s startswith %s" % ( parts[0], match )
+            if parts[0].startswith( match ):
+                for rule in rules:
+                    rule( action, path, **properties )
+        return True
+
+    def _onActivityR( self, source, condition ):
+        """
+        Run through callbacks and call, if applicable
+        """
+        data = os.read( source, 512 )
+        print "MSG='%s'" % repr(data)
+        logger.debug( "Received route notification: %s" % repr(data) )
+
+        msgtype = data[24] # 03 iface down, 02 iface up
+        iface = data[36:36+8].strip()
+        #parts = data.split( '\0' )
+        #action, path = parts[0].split( '@' )
+        #properties = {}
+        #if len( parts ) > 1:
+            #properties = dict( [ x.split('=') for x in parts if '=' in x ] )
+        ##print "action='%s', path='%s', properties='%s'" % ( action, path, properties
+        #for match, rules in self._matches.iteritems():
+            ##print "checking %s startswith %s" % ( parts[0], match )
+            #if parts[0].startswith( match ):
+                #for rule in rules:
+                    #rule( action, path, **properties )
+        return True
+
+#----------------------------------------------------------------------------#
+if __name__ == "__main__":
+#----------------------------------------------------------------------------#
+    def class_callback( *args, **kwargs ):
+        print "class callback", args, kwargs
+
+    def devices_callback( *args, **kwargs ):
+        print "devices callback", args, kwargs
+
+    def all_callback( *args, **kwargs ):
+        print "* callback", args, kwargs
+
+    KObjectDispatcher.addMatch( "add", "/class/", class_callback )
+    KObjectDispatcher.addMatch( "add", "/devices/", devices_callback )
+    KObjectDispatcher.addMatch( "*", "*", all_callback )
+
+    mainloop = gobject.MainLoop()
+    mainloop.run()
diff --git a/framework/subsystems/ogsmd/modems/abstract/pdp.py b/framework/subsystems/ogsmd/modems/abstract/pdp.py
index d18b3e3..cccd07e 100644
--- a/framework/subsystems/ogsmd/modems/abstract/pdp.py
+++ b/framework/subsystems/ogsmd/modems/abstract/pdp.py
@@ -13,11 +13,13 @@ Module: pdp
 
 """
 
-__version__ = "0.1.3"
+__version__ = "0.2.0"
 
 from .mediator import AbstractMediator
 from .overlay import OverlayFile
 
+from framework.services import KObjectDispatcher
+
 import gobject
 import os, subprocess, signal, copy
 
@@ -48,6 +50,11 @@ class Pdp( AbstractMediator ):
         self.ppp = None
         self.overlays = []
 
+        #KObjectDispatcher.addMatch( "*", "/devices/virtual/net", self._onInterfaceChange )
+
+    def _onInterfaceChange( action, path, **kwargs ):
+        logger.debug( "detected interface change", action, path )
+
     #
     # public
     #

-- 
FSO frameworkd Debian packaging



More information about the pkg-fso-commits mailing list