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

Jan Luebbe jluebbe at debian.org
Mon Feb 2 18:51:37 UTC 2009


The following commit has been merged in the master branch:
commit 1b616cefa90af944d387d7d016de9d1d6d668fb6
Author: Jan Luebbe <jluebbe at debian.org>
Date:   Wed Dec 17 13:18:19 2008 +0100

    otimed: add simple timesync to NTP and GPS

diff --git a/ChangeLog b/ChangeLog
index b14537b..c505736 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-12-17	Jan Luebbe      <jluebbe at debian.org>
+
+	* [otimed] Add simple timesync to NTP and GPS
+
 2008-12-12	Michael Lauer	<mickey at openmoko.org>
 
 	* [ogsmd] Implemented org.freesmartphone.GSM.Phone.[Start|Stop]AutoRegister()
diff --git a/framework/subsystems/otimed/otimed.py b/framework/subsystems/otimed/otimed.py
index cf70bb5..ef8beee 100644
--- a/framework/subsystems/otimed/otimed.py
+++ b/framework/subsystems/otimed/otimed.py
@@ -1,17 +1,23 @@
 #!/usr/bin/env python
+# -*- coding: UTF-8 -*-
 """
 The Time Deamon - Python Implementation
 
 (C) 2008 Guillaume 'Charlie' Chereau
+(C) 2008 Jan 'Shoragan' Lübbe <jluebbe at lasnet.de>
 (C) 2008 Openmoko, Inc.
 GPLv2 or later
 
 Package: otimed
-Module: otime
+Module: otimed
 """
 
-__version__ = "0.1.0"
+__version__ = "0.2.0"
 
+from datetime import datetime, timedelta
+from math import sqrt
+import socket
+import struct
 import time
 
 # All the dbus modules
@@ -20,50 +26,129 @@ import dbus.service
 import dbus.mainloop.glib
 import gobject
 
-
 import logging
-logger = logging.getLogger('otimed')
+logger = logging.getLogger( 'otimed' )
+
+def getOutput(cmd):
+    from subprocess import Popen, PIPE
+    return Popen(cmd, shell=True, stdout=PIPE).communicate()[0]
+
+def toSeconds( delta ):
+    return delta.days*24*60*60+delta.seconds+delta.microseconds*0.000001
+
+#============================================================================#
+class TimeSource( object ):
+#============================================================================#
+    def __init__( self, bus ):
+        self.offset = None
+        self.bus = bus
+
+#============================================================================#
+class GPSTimeSource( TimeSource ):
+#============================================================================#
+    def __init__( self, bus ):
+        TimeSource.__init__( self, bus )
+        self.invalidTimeout = None
+        self.bus.add_signal_receiver(
+            self._handleTimeChanged,
+            "TimeChanged",
+            "org.freedesktop.Gypsy.Time",
+            None,
+            None
+        )
+
+    def _handleTimeChanged( self, t ):
+        self.offset = datetime.utcfromtimestamp( t ) - datetime.utcnow()
+        if not self.invalidTimeout is None:
+            gobject.source_remove( self.invalidTimeout )
+            self.invalidTimeout = gobject.timeout_add_seconds( 300, self._handleInvaildTimeout )
+        logger.debug( "GPS: offset=%f", toSeconds( self.offset ) )
+
+    def _handleInvaildTimeout( self ):
+        self.offset = None
+        self.invalidTimeout = None
+        logger.debug( "GPS: timeout" )
+        return False
 
+#============================================================================#
+class NTPTimeSource( TimeSource ):
+#============================================================================#
+    def __init__( self, bus, server = "134.169.172.1", interval = 70 ):
+        TimeSource.__init__( self, bus )
+        self.server = server
+        self.interval = interval
+        self.updateTimeout = gobject.timeout_add_seconds( self.interval, self._handleUpdateTimeout )
+
+    def _handleUpdateTimeout( self ):
+        logger.debug( "NTP: requesting timestamp" )
+        self.offset = None
+        # FIXME do everything async
+        epoch = 2208988800L
+        client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
+        data = '\x1b' + 47 * '\0'
+        client.sendto( data, ( self.server, 123 ))
+        data, address = client.recvfrom( 1024 )
+        if data:
+            s, f = struct.unpack( '!12I', data )[10:12]
+            s -= epoch
+            t = s + f/(2.0**32)
+            self.offset = datetime.utcfromtimestamp( t ) - datetime.utcnow()
+            logger.debug( "NTP: offset=%f", toSeconds( self.offset ) )
+        else:
+            self.offset = None
+            logger.warning( "NTP: no timestamp received" )
+        # reenable timeout
+        return True
 
 #============================================================================#
-class Time(dbus.service.Object):
+class Time( dbus.service.Object ):
 #============================================================================#
-    def __init__(self, bus):
+    def __init__( self, bus ):
         self.path = "/org/freesmartphone/Time"
-        super(Time, self).__init__(bus, self.path)
+        super( Time, self ).__init__( bus, self.path )
         self.interface = "org.freesmartphone.Time"
         self.bus = bus
-        
-        self.last_emitted = None
-        gobject.timeout_add_seconds(1, self.time_changed)
-
-    @dbus.service.method("org.freesmartphone.Time", in_signature='i', out_signature='iiiiiiiii')
-    def GetLocalTime(self, seconds = None):
-        """seconds -> (year, mon, day, hour, min, sec, wday, yday, isdst)
-           
-           Convert seconds since Epoch to a time tuple expressing local time.   
-           When `seconds` is not passed in, convert the current time instead.
-        """ 
-        logger.debug("GetLocalTime")
-        return time.localtime(seconds)
-        
-    @dbus.service.signal('org.freesmartphone.Time', signature='iiiiiiiii')
-    def Minute(self, year, mon, day, hour, min, sec, wday, yday, isdst):
-        """signal used to notify a minute change in the local time"""
-        logger.debug("Minute %d:%d", hour, min)
-        
-    def time_changed(self):
-        local_time = time.localtime()
-        if local_time[:5] != self.last_emitted:
-            self.last_emitted = local_time[:5]
-            self.Minute(*local_time)
-        return True
 
+        self.sources = []
+        self.sources.append( GPSTimeSource( self.bus ) )
+        self.sources.append( NTPTimeSource( self.bus ) )
+
+        self.interval = 80
+        self.updateTimeout = gobject.timeout_add_seconds( self.interval, self._handleUpdateTimeout )
+
+    def _handleUpdateTimeout( self ):
+        logger.debug( "checking time sources" )
+        offsets = []
+        for source in self.sources:
+            if not source.offset is None:
+                offsets.append( toSeconds( source.offset ) )
+
+        if not offsets:
+            logger.debug( "no working time source" )
+            return True
+
+        n = len( offsets )
+        mean = sum( offsets ) / n
+        sd = sqrt( sum( (x-mean)**2 for x in offsets ) / n )
+        logger.info( "offsets: n=%i mean=%f sd=%f", n, mean, sd )
+
+        if sd < 15.0 < mean:
+            logger.info( "adjusting clock by %f seconds" % mean )
+            d = timedelta( seconds=mean )
+            for source in self.sources:
+                if not source.offset is None:
+                    source.offset = source.offset - d
+            t = datetime.utcnow() + d
+            getOutput( "date -u -s %s" % t.strftime( "%m%d%H%M%Y.%S" ) )
+            getOutput( "hwclock --systohc" )
+
+        # reenable timeout
+        return True
 
 #============================================================================#
-def factory(prefix, controller):
+def factory( prefix, controller ):
 #============================================================================#
     """This is the magic function that will be called by the framework module manager"""
-    time_service = Time(controller.bus)
+    time_service = Time( controller.bus )
     return [time_service]
 

-- 
FSO frameworkd Debian packaging



More information about the pkg-fso-commits mailing list