Index: src/checks.py
===================================================================
--- src/checks.py	(revision 13)
+++ src/checks.py	(revision 21)
@@ -438,5 +438,4 @@
             if state.timestamp>=(self._faultStarted + timeout):
                 self.logFault(flight, aircraft, logger, oldState, state)
-                self._faulted = True
                 self._faultStarted = state.timestamp
         else:
Index: src/fsuipc.py
===================================================================
--- src/fsuipc.py	(revision 16)
+++ src/fsuipc.py	(revision 21)
@@ -58,7 +58,31 @@
             return None
 
+    NUM_READATTEMPTS = 3
+
+    @staticmethod
+    def _performRead(data, callback, extra, validator):
+        """Perform a read request.
+
+        If there is a validator, that will be called with the return values,
+        and if the values are wrong, the request is retried at most a certain
+        number of times.
+
+        Return True if the request has succeeded, False if validation has
+        failed during all attempts. An exception may also be thrown if there is
+        some lower-level communication problem."""
+        attemptsLeft = Handler.NUM_READATTEMPTS
+        while attemptsLeft>0:
+            values = pyuipc.read(data)
+            if validator is None or \
+               Handler._callSafe(lambda: validator(values, extra)):
+                Handler._callSafe(lambda: callback(values, extra))
+                return True
+            else:
+                attemptsLeft -= 1
+        return False
+
     class Request(object):
         """A simple, one-shot request."""
-        def __init__(self, forWrite, data, callback, extra):
+        def __init__(self, forWrite, data, callback, extra, validator = None):
             """Construct the request."""
             self._forWrite = forWrite
@@ -66,15 +90,19 @@
             self._callback = callback
             self._extra = extra
+            self._validator = validator
             
         def process(self, time):
-            """Process the request."""            
+            """Process the request.
+
+            Return True if the request has succeeded, False if data validation
+            has failed for a reading request. An exception may also be thrown
+            if there is some lower-level communication problem."""            
             if self._forWrite:
                 pyuipc.write(self._data)
                 Handler._callSafe(lambda: self._callback(True, self._extra))
+                return True
             else:
-                values = pyuipc.read(self._data)
-                Handler._callSafe(lambda: self._callback(values, self._extra))
-
-            return True
+                return Handler._performRead(self._data, self._callback,
+                                            self._extra, self._validator)
 
         def fail(self):
@@ -87,5 +115,5 @@
     class PeriodicRequest(object):
         """A periodic request."""
-        def __init__(self, id,  period, data, callback, extra):
+        def __init__(self, id,  period, data, callback, extra, validator):
             """Construct the periodic request."""
             self._id = id
@@ -96,4 +124,5 @@
             self._callback = callback
             self._extra = extra
+            self._validator = validator
             
         @property
@@ -110,20 +139,26 @@
             """Check if this request should be executed, and if so, do so.
 
-            Return a boolean indicating if the request was executed."""
-            if time < self._nextFire: 
-                return False
-
+            time is the time at which the request is being executed. If this
+            function is called too early, nothing is done, and True is
+            returned.
+
+            Return True if the request has succeeded, False if data validation
+            has failed. An exception may also be thrown if there is some
+            lower-level communication problem."""
+            if time<self._nextFire:
+                return True
+            
             if self._preparedData is None:
                 self._preparedData = pyuipc.prepare_data(self._data)
                 self._data = None
-                
-            values = pyuipc.read(self._preparedData)
-
-            Handler._callSafe(lambda: self._callback(values, self._extra))
-
-            while self._nextFire <= time:
-                self._nextFire += self._period
+
+            isOK = Handler._performRead(self._preparedData, self._callback,
+                                        self._extra, self._validator)
+
+            if isOK:
+                while self._nextFire <= time:
+                    self._nextFire += self._period
             
-            return True
+            return isOK
 
         def fail(self):
@@ -144,4 +179,5 @@
         self._requestCondition = threading.Condition()
         self._connectionRequested = False
+        self._connected = False
 
         self._requests = []
@@ -151,5 +187,5 @@
         self.daemon = True
 
-    def requestRead(self, data, callback, extra = None):
+    def requestRead(self, data, callback, extra = None, validator = None):
         """Request the reading of some data.
 
@@ -165,5 +201,6 @@
         """
         with self._requestCondition:
-            self._requests.append(Handler.Request(False, data, callback, extra))
+            self._requests.append(Handler.Request(False, data, callback, extra,
+                                                  validator))
             self._requestCondition.notify()
 
@@ -192,31 +229,6 @@
             condition.notify()
 
-    def read(self, data):
-        """Read the given data synchronously.
-
-        If a problem occurs, an exception is thrown."""
-        with threading.Condition() as condition:
-            extra = [condition]
-            self._requestRead(data, self._readWriteCallback, extra)
-            while len(extra)<2:
-                condition.wait()
-            if extra[1] is None:
-                raise fs.SimulatorException("reading failed")
-            else:
-                return extra[1]
-
-    def write(self, data):
-        """Write the given data synchronously.
-
-        If a problem occurs, an exception is thrown."""
-        with threading.Condition() as condition:
-            extra = [condition]
-            self._requestWrite(data, self._writeCallback, extra)
-            while len(extra)<2:
-                condition.wait()
-            if extra[1] is None:
-                raise fs.SimulatorException("writing failed")
-
-    def requestPeriodicRead(self, period, data, callback, extra = None):
+    def requestPeriodicRead(self, period, data, callback, extra = None,
+                            validator = None):
         """Request a periodic read of data.
 
@@ -228,5 +240,6 @@
             id = self._nextPeriodicID
             self._nextPeriodicID += 1
-            request = Handler.PeriodicRequest(id, period, data, callback, extra)
+            request = Handler.PeriodicRequest(id, period, data, callback,
+                                              extra, validator)
             self._periodicRequests.append(request)
             self._requestCondition.notify()
@@ -273,5 +286,9 @@
             
     def _connect(self):
-        """Try to connect to the flight simulator via FSUIPC"""
+        """Try to connect to the flight simulator via FSUIPC
+
+        Returns True if the connection has been established, False if it was
+        not due to no longer requested.
+        """
         while self._connectionRequested:
             try:
@@ -283,4 +300,5 @@
                                   self._connectionListener.connected(const.SIM_MSFS9, 
                                                                      description))
+                self._connected = True
                 return True
             except Exception, e:
@@ -294,17 +312,30 @@
         with self._requestCondition:
             while self._connectionRequested:
-                if not self._processRequests(): 
-                    return
-                timeout = None
-                if self._periodicRequests:
-                    self._periodicRequests.sort()
-                    timeout = self._periodicRequests[0].nextFire - time.time()
-                if timeout is None or timeout > 0.0:
-                    self._requestCondition.wait(timeout)
+                self._processRequests()
+                self._waitRequest()
+
+    def _waitRequest(self):
+        """Wait for the time of the next request.
+
+        Returns also, if the connection is no longer requested.
+
+        Should be called with the request condition lock held."""
+        while self._connectionRequested:
+            timeout = None
+            if self._periodicRequests:
+                self._periodicRequests.sort()
+                timeout = self._periodicRequests[0].nextFire - time.time()
+
+            if timeout is not None and timeout <= 0.0:
+                return
+            
+            self._requestCondition.wait(timeout)
                 
     def _disconnect(self):
         """Disconnect from the flight simulator."""
-        pyuipc.close()
-        Handler._callSafe(lambda: self._connectionListener.disconnected())
+        if self._connected:
+            pyuipc.close()
+            Handler._callSafe(lambda: self._connectionListener.disconnected())
+            self._connected = False
 
     def _failRequests(self, request):
@@ -323,19 +354,29 @@
         """Process the given request. 
 
-        If an exception occurs, we try to reconnect.
-        
-        Returns what the request's process() function returned or None if
-        reconnection failed."""        
+        If an exception occurs or invalid data is read too many times, we try
+        to reconnect.
+
+        This function returns only if the request has succeeded, or if a
+        connection is no longer requested.
+
+        This function is called with the request lock held, but is relased
+        whole processing the request and reconnecting."""
         self._requestCondition.release()
 
+        needReconnect = False
         try:
-            return request.process(time)
-        except Exception as e:
-            print "fsuipc.Handler._processRequest: FSUIPC connection failed (" + \
-                str(e) + ") reconnecting."
-            self._disconnect()
-            self._failRequests(request)
-            if not self._connect(): return None
-            else: return True
+            try:
+                if not request.process(time):
+                    print "fsuipc.Handler._processRequest: FSUIPC returned invalid data too many times, reconnecting"
+                    needReconnect = True
+            except Exception as e:
+                print "fsuipc.Handler._processRequest: FSUIPC connection failed (" + \
+                      str(e) + "), reconnecting."
+                needReconnect = True
+
+            if needReconnect:
+                self._disconnect()
+                self._failRequests(request)
+                self._connect()
         finally:
             self._requestCondition.acquire()
@@ -348,7 +389,11 @@
             self._periodicRequests.sort()
             request = self._periodicRequests[0]
-            result = self._processRequest(request, time.time())
-            if result is None: return False
-            elif not result: break
+
+            t = time.time()
+
+            if request.nextFire>t:
+                break
+            
+            self._processRequest(request, t)
 
         while self._connectionRequested and self._requests:
@@ -356,6 +401,5 @@
             del self._requests[0]
 
-            if self._processRequest(request, None) is None:
-                return False
+            self._processRequest(request, None)
 
         return self._connectionRequested
@@ -481,7 +525,9 @@
         """Start the default normal periodic request."""
         assert self._normalRequestID is None
-        self._normalRequestID = self._handler.requestPeriodicRead(1.0,
-                                                                  Simulator.normalData,
-                                                                  self._handleNormal)
+        self._normalRequestID = \
+             self._handler.requestPeriodicRead(1.0,
+                                               Simulator.normalData,
+                                               self._handleNormal,
+                                               validator = self._validateNormal)
 
     def _stopNormal(self):
@@ -491,4 +537,8 @@
         self._normalRequestID = None
         self._monitoring = False
+
+    def _validateNormal(self, data, extra):
+        """Validate the normal data."""
+        return data[0]!=0 and data[1]!=0 and len(data[5])>0 and len(data[6])>0
 
     def _handleNormal(self, data, extra):
@@ -565,5 +615,6 @@
         self._normalRequestID = \
             self._handler.requestPeriodicRead(1.0, data, 
-                                              self._handleNormal)
+                                              self._handleNormal,
+                                              validator = self._validateNormal)
         self._monitoring = True
 
Index: src/logger.py
===================================================================
--- src/logger.py	(revision 17)
+++ src/logger.py	(revision 21)
@@ -73,5 +73,5 @@
             self.message(timestamp, "%s (NO GO)" % (what))
         else:
-            self.message(timestamp, "%s (%f)" % (what, score))
+            self.message(timestamp, "%s (%.1f)" % (what, score))
 
     def noGo(self, faultID, timestamp, what, shortReason):
