Index: /branches/BNC_2.12/src/RTCM3/RTCM3Decoder.cpp
===================================================================
--- /branches/BNC_2.12/src/RTCM3/RTCM3Decoder.cpp	(revision 9204)
+++ /branches/BNC_2.12/src/RTCM3/RTCM3Decoder.cpp	(revision 9205)
@@ -936,6 +936,5 @@
     if ((i & ((1 << 20) - 1)) != 0x80000) {
       frqObs->_code = l1range * 0.02;
-      frqObs->_phase = (l1range * 0.02 + i * 0.0005)
-          / GLO_WAVELENGTH_L1(freq - 7);
+      frqObs->_phase = (l1range * 0.02 + i * 0.0005) / GLO_WAVELENGTH_L1(freq - 7);
       frqObs->_codeValid = frqObs->_phaseValid = true;
     }
@@ -1047,5 +1046,10 @@
     GETFLOATSIGN(eph._Cus, 16, 1.0 / (double )(1 << 29))
     GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
-    if (eph._sqrt_A < 1000.0) {return false;}
+    if (eph._sqrt_A < 1000.0) {
+      emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
+           .arg(_staID).arg(1020,4).arg(eph._prn.toString().c_str())
+           .arg(eph._sqrt_A,10,'F',3).toAscii(), true));
+      return false;
+    }
     GETBITS(i, 16)
     i <<= 4;
@@ -1102,5 +1106,10 @@
     GETBITS(eph._almanac_health, 1) /* almanac healthy */
     GETBITS(eph._almanac_health_availablility_indicator, 1) /* almanac health ok */
-    if (eph._almanac_health_availablility_indicator == 0.0) {return false;}
+    if (eph._almanac_health_availablility_indicator == 0.0) {
+      emit(newMessage(QString("%1: Block %2 (%3): ALM = %4: missing data!")
+           .arg(_staID).arg(1019,4).arg(eph._prn.toString().c_str())
+           .arg(eph._almanac_health_availablility_indicator).toAscii(), true));
+      return false;
+    }
     GETBITS(eph._P1, 2) /*  P1 */
     GETBITS(i, 5)
@@ -1138,8 +1147,17 @@
     GETBITS(eph._M_FT, 4) /* GLONASS-M Ft */
     GETBITS(eph._M_NT, 11) /* GLONASS-M Nt */
-    if (eph._M_NT == 0.0) {return false;}
+    if (eph._M_NT == 0.0) {
+      emit(newMessage(QString("%1: Block %2 (%3): NT = %4: missing data!")
+           .arg(_staID).arg(1019,4).arg(eph._prn.toString().c_str()).arg(eph._M_NT,4).toAscii(), true));
+      return false;
+    }
     GETBITS(eph._M_M, 2) /* GLONASS-M M */
     GETBITS(eph._additional_data_availability, 1) /* GLONASS-M The Availability of Additional Data */
-    if (eph._additional_data_availability == 0.0) {return false;}
+    if (eph._additional_data_availability == 0.0) {
+      emit(newMessage(QString("%1: Block %2 (%3): ADD = %4: missing data!")
+           .arg(_staID).arg(1019,4).arg(eph._prn.toString().c_str())
+           .arg(eph._additional_data_availability).toAscii(), true));
+      return false;
+    }
     GETBITS(eph._NA, 11) /* GLONASS-M Na */
     GETFLOATSIGNM(eph._tauC, 32, 1.0/(double)(1<<30)/(double)(1<<1)) /* GLONASS tau c */
@@ -1156,8 +1174,17 @@
     eph._xv(2) = eph._y_pos * 1.e3;
     eph._xv(3) = eph._z_pos * 1.e3;
+    if (eph._xv.Rows(1,3).NormFrobenius() < 1.0) {
+      emit(newMessage(QString("%1: Block %2 (%3): zero position!")
+           .arg(_staID).arg(1019,4).arg(eph._prn.toString().c_str()).toAscii(), true));
+      return false;
+    }
     eph._xv(4) = eph._x_velocity * 1.e3;
     eph._xv(5) = eph._y_velocity * 1.e3;
     eph._xv(6) = eph._z_velocity * 1.e3;
-
+    if (eph._xv.Rows(4,6).NormFrobenius() < 1.0) {
+      emit(newMessage(QString("%1: Block %2 (%3): zero velocity!")
+           .arg(_staID).arg(1019,4).arg(eph._prn.toString().c_str()).toAscii(), true));
+      return false;
+    }
     GLOFreq[sv - 1] = 100 + eph._frequency_number ; /* store frequency for other users (MSM) */
     _gloFrq = QString("%1 %2").arg(eph._prn.toString().c_str()).arg(eph._frequency_number, 2, 'f', 0);
@@ -1204,5 +1231,10 @@
     GETFLOATSIGN(eph._Cus, 16, 1.0 / (double )(1 << 29))
     GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
-    if (eph._sqrt_A < 1000.0) {return false;}
+    if (eph._sqrt_A < 1000.0) {
+      emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
+           .arg(_staID).arg(1044,4).arg(eph._prn.toString().c_str())
+           .arg(eph._sqrt_A,10,'F',3).toAscii(), true));
+      return false;
+    }
     GETBITS(i, 16)
     i <<= 4;
@@ -1313,5 +1345,10 @@
     GETFLOAT(eph._e,            32, 1.0 / (double )(1 << 30) / (double )(1 << 3))
     GETFLOAT(eph._sqrt_A,       32, 1.0 / (double )(1 << 19))
-    if (eph._sqrt_A < 1000.0) {return false;}
+    if (eph._sqrt_A < 1000.0) {
+      emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
+           .arg(_staID).arg(1041,4).arg(eph._prn.toString().c_str())
+           .arg(eph._sqrt_A,10,'F',3).toAscii(), true));
+      return false;
+    }
     GETFLOATSIGN(eph._OMEGA0,   32, R2R_PI/(double)(1<<30)/(double)(1<< 1))
     GETFLOATSIGN(eph._omega,    32, R2R_PI/(double)(1<<30)/(double)(1<< 1))
@@ -1355,4 +1392,11 @@
     GETFLOATSIGN(eph._y_pos, 30, 0.08)
     GETFLOATSIGN(eph._z_pos, 25, 0.4)
+    ColumnVector pos(3);
+    pos(1) = eph._x_pos; pos(2) = eph._y_pos; pos(3) = eph._z_pos;
+    if (pos.NormFrobenius() < 1.0) {
+      emit(newMessage(QString("%1: Block %2 (%3): zero position!")
+           .arg(_staID).arg(1043,4).arg(eph._prn.toString().c_str()).toAscii(), true));
+      return false;
+    }
     GETFLOATSIGN(eph._x_velocity, 17, 0.000625)
     GETFLOATSIGN(eph._y_velocity, 17, 0.000625)
@@ -1411,5 +1455,4 @@
     GETFLOATSIGN(eph._Cus, 16, 1.0 / (double )(1 << 29))
     GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
-    if (eph._sqrt_A < 1000.0) {return false;}
     GETBITSFACTOR(eph._TOEsec, 14, 60)
     /* FIXME: overwrite value, copied from old code */
@@ -1434,8 +1477,14 @@
       GETBITS(eph._e1DataInValid, 1)
       if (eph._E5bHS != eph._E1_bHS) {
+        emit(newMessage(QString("%1: Block %2 (%3) SHS E5b %4 E1B %5: inconsistent health!")
+             .arg(_staID).arg(1046,4).arg(eph._prn.toString().c_str())
+             .arg(eph._E5bHS).arg(eph._E1_bHS).toAscii(), true));
         return false;
       }
       if ((eph._BGD_1_5A == 0.0 && fabs(eph._BGD_1_5B) > 1e-9) ||
           (eph._BGD_1_5B == 0.0 && fabs(eph._BGD_1_5A) > 1e-9)) {
+        emit(newMessage(QString("%1: Block %2 (%3) BGD_15a = %4 BGD_15b = %5: inconsistent BGD!")
+             .arg(_staID).arg(1046,4).arg(eph._prn.toString().c_str())
+             .arg(eph._BGD_1_5A,10,'E',3).arg(eph._BGD_1_5B,10,'E',3).toAscii(), true));
         return false;
       }
@@ -1453,4 +1502,11 @@
     }
     eph._TOT = 0.9999e9;
+
+    if (eph._sqrt_A < 1000.0) {
+      emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
+           .arg(_staID).arg(eph._inav? 1046 : 1045,4).arg(eph._prn.toString().c_str())
+           .arg(eph._sqrt_A,10,'F',3).toLatin1(), true));
+      return false;
+    }
 
     emit newGalileoEph(eph);
@@ -1499,6 +1555,11 @@
     GETFLOATSIGN(eph._Cus, 18, 1.0 / (double )(1 << 30) / (double )(1 << 1))
     GETFLOAT(eph._sqrt_A, 32, 1.0 / (double )(1 << 19))
-	if (eph._sqrt_A < 1000.0) {return false;}
-	GETBITS(i, 17)
+    if (eph._sqrt_A < 1000.0) {
+      emit(newMessage(QString("%1: Block %2 (%3) SQRT_A %4 m!")
+           .arg(_staID).arg(1042,4).arg(eph._prn.toString().c_str())
+           .arg(eph._sqrt_A,10,'F',3).toAscii(), true));
+      return false;
+    }
+	  GETBITS(i, 17)
     i <<= 3;
     eph._TOEsec = i;
@@ -1692,7 +1753,8 @@
           case 1045:
           case 1046:
-            // reject 1045/1046 from JAXA RTKLIB encoded stations
             if (_staID.contains("AIRA") || _staID.contains("STK2") ||
                 _staID.contains("CCJ2") || _staID.contains("SYOG")) {
+              emit(newMessage(QString("%1: Block temporary %2 from JAXA RTKLIB encoded stations!")
+                   .arg(_staID).arg(id).toAscii(), true));
               break;
             }
@@ -1725,9 +1787,8 @@
 uint32_t RTCM3Decoder::CRC24(long size, const unsigned char *buf) {
   uint32_t crc = 0;
-  int i;
-
-  while (size--) {
+  int ii;
+ while (size--) {
     crc ^= (*buf++) << (16);
-    for (i = 0; i < 8; i++) {
+    for (ii = 0; ii < 8; ii++) {
       crc <<= 1;
       if (crc & 0x1000000)
Index: /branches/BNC_2.12/src/bncephuser.cpp
===================================================================
--- /branches/BNC_2.12/src/bncephuser.cpp	(revision 9204)
+++ /branches/BNC_2.12/src/bncephuser.cpp	(revision 9205)
@@ -206,12 +206,8 @@
   }
   double rr = xc.Rows(1,3).norm_Frobenius();
-  double rv = vv.norm_Frobenius();
+
   const double MINDIST = 2.e7;
   const double MAXDIST = 6.e7;
   if (rr < MINDIST || rr > MAXDIST || std::isnan(rr)) {
-    eph->setCheckState(t_eph::bad);
-    return;
-  }
-  if (eph->type() == t_eph::GLONASS && rv < 1.0) {
     eph->setCheckState(t_eph::bad);
     return;
@@ -224,38 +220,38 @@
     QDateTime now = currentDateAndTimeGPS();
     bncTime currentTime(now.toString(Qt::ISODate).toStdString());
-    double dt = fabs(currentTime - toc);
+    double dt = currentTime - toc;
 
     // update interval: 2h, data sets are valid for 4 hours
-    if      (eph->type() == t_eph::GPS     && dt > 4*3600) {
+    if      (eph->type() == t_eph::GPS     && (dt > 4*3600.0 || dt < -2*3600.0)) {
       eph->setCheckState(t_eph::outdated);
       return;
     }
     // update interval: 3h, data sets are valid for 4 hours
-    else if (eph->type() == t_eph::Galileo && dt > 4*3600) {
+    else if (eph->type() == t_eph::Galileo && (dt > 4*3600.0 || dt <       0.0)) {
       eph->setCheckState(t_eph::outdated);
       return;
     }
     // updated every 30 minutes
-    else if (eph->type() == t_eph::GLONASS && dt > 2*3600) {
+    else if (eph->type() == t_eph::GLONASS && (dt > 1*3600.0 || dt <   -1800.0)) {
       eph->setCheckState(t_eph::outdated);
       return;
     }
     // orbit parameters are valid for 7200 seconds (minimum)
-    else if (eph->type() == t_eph::QZSS    && dt > 3*3600) {
+    else if (eph->type() == t_eph::QZSS    && (dt > 2*3600.0 || dt < -1*3600.0)) {
       eph->setCheckState(t_eph::outdated);
       return;
     }
     // maximum update interval: 300 sec
-    else if (eph->type() == t_eph::SBAS    && dt > 1*3600) {
+    else if (eph->type() == t_eph::SBAS    && (dt >     600 || dt <       -300)) {
       eph->setCheckState(t_eph::outdated);
       return;
     }
     // updates 1h (GEO) up to 6 hours non-GEO
-    else if (eph->type() == t_eph::BDS     && dt > 6*3600) {
+    else if (eph->type() == t_eph::BDS     && (dt > 6*3600  || dt <        0.0)) {
       eph->setCheckState(t_eph::outdated);
       return;
     }
     // update interval: up to 24 hours
-    else if (eph->type() == t_eph::IRNSS   && dt > 24*3600) {
+    else if (eph->type() == t_eph::IRNSS   && fabs(dt > 24*3600)) {
       eph->setCheckState(t_eph::outdated);
       return;
@@ -281,28 +277,35 @@
 
     // some lines to allow update of ephemeris data sets after outage
-    if      (eph->type() == t_eph::GPS     && dt >  4*3600) {
-      ephL->setCheckState(t_eph::outdated);
-      return;
-    }
-    else if (eph->type() == t_eph::Galileo && dt >  4*3600) {
-      ephL->setCheckState(t_eph::outdated);
-      return;
-    }
-    else if (eph->type() == t_eph::GLONASS && dt >  2*3600) {
-      ephL->setCheckState(t_eph::outdated);
-      return;
-    }
-    else if (eph->type() == t_eph::QZSS    && dt >  3*3600) {
-      ephL->setCheckState(t_eph::outdated);
-      return;
-    }
-    else if  (eph->type() == t_eph::SBAS   && dt >    3600) {
-      ephL->setCheckState(t_eph::outdated);
-      return;
-    }
+    // update interval: 2h,
+    if      (eph->type() == t_eph::GPS     && dt >  2*3600) {
+      ephL->setCheckState(t_eph::outdated);
+      return;
+    }
+    // update interval: 3h,
+    else if (eph->type() == t_eph::Galileo && dt >  3*3600) {
+      ephL->setCheckState(t_eph::outdated);
+      return;
+    }
+    // updated every 30 minutes
+    else if (eph->type() == t_eph::GLONASS && dt >    1800) {
+      ephL->setCheckState(t_eph::outdated);
+      return;
+    }
+    // updated every ?
+    else if (eph->type() == t_eph::QZSS    && dt >  2*3600) {
+      ephL->setCheckState(t_eph::outdated);
+      return;
+    }
+    // maximum update interval: 300 sec
+    else if  (eph->type() == t_eph::SBAS   && dt >     300) {
+      ephL->setCheckState(t_eph::outdated);
+      return;
+    }
+    // updates 1h (GEO) up to 6 hours non-GEO
     else if  (eph->type() == t_eph::BDS    && dt >  6*3600) {
       ephL->setCheckState(t_eph::outdated);
       return;
     }
+    // update interval: up to 24 hours
     else if  (eph->type() == t_eph::IRNSS  && dt > 24*3600) {
       ephL->setCheckState(t_eph::outdated);
