Index: /branches/BNC_2.12/ChangeLog.txt
===================================================================
--- /branches/BNC_2.12/ChangeLog.txt	(revision 8615)
+++ /branches/BNC_2.12/ChangeLog.txt	(revision 8616)
@@ -2,4 +2,5 @@
  BNC VERSION 2.12.7 (??.??.2018)
 --------------------------------------------------------------------------------
+    ADDED   (28.02.2019): lock time in seconds as an optional feed engine output
     ADDED   (27.09.2018): possibility to request a user and password
                           detected sourcetable
Index: /branches/BNC_2.12/src/RTCM3/RTCM3Decoder.cpp
===================================================================
--- /branches/BNC_2.12/src/RTCM3/RTCM3Decoder.cpp	(revision 8615)
+++ /branches/BNC_2.12/src/RTCM3/RTCM3Decoder.cpp	(revision 8616)
@@ -149,4 +149,6 @@
     }
     GETBITS(i, 7);
+    frqObs->_lockTime = lti2sec(type,i);
+    frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0 && frqObs->_phaseValid);
     frqObs->_slipCounter = i;
     if (type == 1002 || type == 1004) {
@@ -193,4 +195,6 @@
       }
       GETBITS(i, 7);
+      frqObs->_lockTime = lti2sec(type,i);
+      frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0 && frqObs->_phaseValid);
       frqObs->_slipCounter = i;
       if (type == 1004) {
@@ -714,4 +718,6 @@
                       + (rrmod[numsat]) * LIGHTSPEED / 1000.0 / cd.wl;
                   frqObs->_phaseValid = true;
+                  frqObs->_lockTime = lti2sec(type,ll[count]);
+                  frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
                   frqObs->_slipCounter = ll[count];
                 }
@@ -728,4 +734,6 @@
                       + rrmod[numsat] * LIGHTSPEED / 1000.0 / cd.wl;
                   frqObs->_phaseValid = true;
+                  frqObs->_lockTime = lti2sec(type,ll[count]);
+                  frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
                   frqObs->_slipCounter = ll[count];
                 }
@@ -743,4 +751,6 @@
                           / cd.wl;
                   frqObs->_phaseValid = true;
+                  frqObs->_lockTime = lti2sec(type,ll[count]);
+                  frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
                   frqObs->_slipCounter = ll[count];
                 }
@@ -761,4 +771,6 @@
                           / cd.wl;
                   frqObs->_phaseValid = true;
+                  frqObs->_lockTime = lti2sec(type,ll[count]);
+                  frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
                   frqObs->_slipCounter = ll[count];
                 }
@@ -784,4 +796,6 @@
                           / cd.wl;
                   frqObs->_phaseValid = true;
+                  frqObs->_lockTime = lti2sec(type,ll[count]);
+                  frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
                   frqObs->_slipCounter = ll[count];
                 }
@@ -802,4 +816,6 @@
                           / cd.wl;
                   frqObs->_phaseValid = true;
+                  frqObs->_lockTime = lti2sec(type,ll[count]);
+                  frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0);
                   frqObs->_slipCounter = ll[count];
                 }
@@ -890,4 +906,6 @@
     }
     GETBITS(i, 7);
+    frqObs->_lockTime = lti2sec(type,i);
+    frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0 && frqObs->_phaseValid);
     frqObs->_slipCounter = i;
     if (type == 1010 || type == 1012) {
@@ -934,4 +952,6 @@
       }
       GETBITS(i, 7);
+      frqObs->_lockTime = lti2sec(type,i);
+      frqObs->_lockTimeValid = (frqObs->_lockTime >= 0.0 && frqObs->_phaseValid);
       frqObs->_slipCounter = i;
       if (type == 1012) {
Index: /branches/BNC_2.12/src/bnccaster.cpp
===================================================================
--- /branches/BNC_2.12/src/bnccaster.cpp	(revision 8615)
+++ /branches/BNC_2.12/src/bnccaster.cpp	(revision 8616)
@@ -95,5 +95,6 @@
     _uSockets = 0;
   }
-
+  
+  _printLockTime = settings.value("printLockTime",false).toBool();
   _samplingRateMult10 = int(settings.value("outSampl").toString().split("sec").first().toDouble() * 10.0);
   _outWait      = settings.value("outWait").toDouble();
@@ -172,5 +173,5 @@
            << setw(4)  << obs._time.gpsw()                      << " "
            << setw(14) << setprecision(7) << obs._time.gpssec() << " "
-           << bncRinex::asciiSatLine(obs) << endl;
+           << bncRinex::asciiSatLine(obs,_printLockTime) << endl;
 
       string hlpStr = oStr.str();
@@ -317,5 +318,6 @@
                  << setprecision(7) << obs._time.gpssec() << endl;
           }
-          oStr << obs._staID << ' ' << bncRinex::asciiSatLine(obs) << endl;
+          oStr << obs._staID << ' '
+               << bncRinex::asciiSatLine(obs,_printLockTime) << endl;
           if (!it.hasNext()) {
             oStr << endl;
Index: /branches/BNC_2.12/src/bnccaster.h
===================================================================
--- /branches/BNC_2.12/src/bnccaster.h	(revision 8615)
+++ /branches/BNC_2.12/src/bnccaster.h	(revision 8616)
@@ -75,4 +75,5 @@
    QList<QByteArray>               _staIDs;
    QList<bncGetThread*>            _threads;
+   bool                            _printLockTime;   
    int                             _samplingRateMult10;
    double                          _outWait;
Index: /branches/BNC_2.12/src/bnchelp.html
===================================================================
--- /branches/BNC_2.12/src/bnchelp.html	(revision 8615)
+++ /branches/BNC_2.12/src/bnchelp.html	(revision 8616)
@@ -2612,4 +2612,8 @@
 </p>
 
+<p>A valid 'Lock Time Indicator'
+An optional valid 'Lock Time' is only presented for observations from RTCM Version 3 streams. The parameter provides a measure of the amount of time that has elapsed during which the receiver has maintained continuous lock on that satellite signal. If a cycle slip occurs during the previous measurement cycle, the lock time will be reset to Zero. The 'Lock Time' could be of interest becuase the Lock Time Inficator is different for different RTCM3 measurement types. Hence, the 'Lock Time' in seconds is computed with the respective calculation rule.
+</p>
+
 <p>
 The following table describes the format of BNC's synchronized output of GNSS observations which consists of 'Epoch Records' and 'Observation Records'. Each Epoch Record is followed by one or more Observation Records. The Observation Record is repeated for each satellite having been observed in the current epoch. The length of an Observation Record is given by the number of observation types for this satellite.
@@ -2655,4 +2659,8 @@
 <tr><td>Observation Code</td><td><b>S</b>2W</td><td>1X,A3</td></tr>
 <tr><td>Observed Signal Strength &nbsp; &nbsp;</td><td>34.750</td><td>1X,F8.3</td></tr>
+
+<tr><td><u>Lock Time (optional)</u></td><td></td><td></td></tr>
+<tr><td>Observation Code</td><td><b>T</b>2W</td><td>1X,A3</td></tr>
+<tr><td>Computed Lock Time &nbsp; &nbsp;</td><td>937.000</td><td>1X,F8.3</td></tr>
 
 </table>
Index: /branches/BNC_2.12/src/bncrinex.cpp
===================================================================
--- /branches/BNC_2.12/src/bncrinex.cpp	(revision 8615)
+++ /branches/BNC_2.12/src/bncrinex.cpp	(revision 8616)
@@ -601,5 +601,5 @@
 // One Line in ASCII (Internal) Format
 ////////////////////////////////////////////////////////////////////////////
-string bncRinex::asciiSatLine(const t_satObs& obs) {
+string bncRinex::asciiSatLine(const t_satObs& obs, bool printLockTime) {
 
   ostringstream str;
@@ -631,4 +631,9 @@
           << right << setw(8) << setprecision(3) << frqObs->_snr;
     }
+    if (frqObs->_lockTimeValid && printLockTime) {
+      str << ' '
+          << left  << setw(3) << "T" + frqObs->_rnxType2ch << ' '
+          << right << setw(9) << setprecision(3) << frqObs->_lockTime;
+    }    
   }
 
Index: /branches/BNC_2.12/src/bncrinex.h
===================================================================
--- /branches/BNC_2.12/src/bncrinex.h	(revision 8615)
+++ /branches/BNC_2.12/src/bncrinex.h	(revision 8616)
@@ -49,5 +49,5 @@
                                bool rnxV3,
                                QDateTime* nextEpoch = 0);
-   static std::string asciiSatLine(const t_satObs& obs);
+   static std::string asciiSatLine(const t_satObs& obs, bool printLockTime);
 
  private:
Index: /branches/BNC_2.12/src/bncsettings.cpp
===================================================================
--- /branches/BNC_2.12/src/bncsettings.cpp	(revision 8615)
+++ /branches/BNC_2.12/src/bncsettings.cpp	(revision 8616)
@@ -104,5 +104,5 @@
     setValue_p("reqcOutNavFile",      "");
     setValue_p("reqcOutLogFile",      "");
-    setValue_p("reqcSkyPlotSignals",  "C:2&7 E:1&5 G:1&2 J:1&2 R:1&2 S:1&5 I:5&9");
+    setValue_p("reqcSkyPlotSignals",  "C:2&7 E:1&5 G:1&2&5 J:1&2 R:1&2&3 S:1&5 I:5&9");
     setValue_p("reqcPlotDir",         "");
     setValue_p("reqcRnxVersion",      "");
@@ -146,4 +146,5 @@
     setValue_p("outFile",             "");
     setValue_p("outUPort",            "");
+    setValue_p("printLockTime",       "0");
     // Serial Output
     setValue_p("serialMountPoint",    "");
Index: /branches/BNC_2.12/src/bncutils.cpp
===================================================================
--- /branches/BNC_2.12/src/bncutils.cpp	(revision 8615)
+++ /branches/BNC_2.12/src/bncutils.cpp	(revision 8616)
@@ -949,2 +949,70 @@
 }
 
+// Convert RTCM3 lock-time indicator to lock time in seconds
+////////////////////////////////////////////////////////////////////////////
+double lti2sec(int type, int lti) {
+
+  if ( (type>=1001 && type<=1004) ||
+       (type>=1009 && type<=1012)    ) { // RTCM3 msg 100[1...4] and 10[09...12]
+         if (lti<   0) return  -1;
+    else if (lti<  24) return   1*lti;      // [  0   1   23]
+    else if (lti<  48) return   2*lti-24;   // [ 24   2   70]
+    else if (lti<  72) return   4*lti-120;  // [ 72   4  164]
+    else if (lti<  96) return   8*lti-408;  // [168   8  352]
+    else if (lti< 120) return  16*lti-1176; // [360  16  728]
+    else if (lti< 127) return  32*lti-3096; // [744  32  905]
+    else if (lti==127) return  937;
+    else               return  -1;
+  }
+  else if (type%10==2 || type%10==3 ||
+           type%10==4 || type%10==5) {  // RTCM3 MSM-2/-3/-4/-5
+    switch(lti) {
+      case( 0) : return      0;
+      case( 1) : return     32e-3;
+      case( 2) : return     64e-3;
+      case( 3) : return    128e-3;
+      case( 4) : return    256e-3;
+      case( 5) : return    512e-3;
+      case( 6) : return   1024e-3;
+      case( 7) : return   2048e-3;
+      case( 8) : return   4096e-3;
+      case( 9) : return   8192e-3;
+      case(10) : return  16384e-3;
+      case(11) : return  32768e-3;
+      case(12) : return  65536e-3;
+      case(13) : return 131072e-3;
+      case(14) : return 262144e-3;
+      case(15) : return 524288e-3;
+      default  : return     -1;
+    };
+  }
+  else if (type%10==6 || type%10==7) {  // RTCM3 MSM-6 and MSM-7
+         if (lti<   0) return (     -1               );
+    else if (lti<  64) return (      1*lti           )*1e-3;
+    else if (lti<  96) return (      2*lti-64        )*1e-3;
+    else if (lti< 128) return (      4*lti-256       )*1e-3;
+    else if (lti< 160) return (      8*lti-768       )*1e-3;
+    else if (lti< 192) return (     16*lti-2048      )*1e-3;
+    else if (lti< 224) return (     32*lti-5120      )*1e-3;
+    else if (lti< 256) return (     64*lti-12288     )*1e-3;
+    else if (lti< 288) return (    128*lti-28672     )*1e-3;
+    else if (lti< 320) return (    256*lti-65536     )*1e-3;
+    else if (lti< 352) return (    512*lti-147456    )*1e-3;
+    else if (lti< 384) return (   1024*lti-327680    )*1e-3;
+    else if (lti< 416) return (   2048*lti-720896    )*1e-3;
+    else if (lti< 448) return (   4096*lti-1572864   )*1e-3;
+    else if (lti< 480) return (   8192*lti-3407872   )*1e-3;
+    else if (lti< 512) return (  16384*lti-7340032   )*1e-3;
+    else if (lti< 544) return (  32768*lti-15728640  )*1e-3;
+    else if (lti< 576) return (  65536*lti-33554432  )*1e-3;
+    else if (lti< 608) return ( 131072*lti-71303168  )*1e-3;
+    else if (lti< 640) return ( 262144*lti-150994944 )*1e-3;
+    else if (lti< 672) return ( 524288*lti-318767104 )*1e-3;
+    else if (lti< 704) return (1048576*lti-671088640 )*1e-3;
+    else if (lti==704) return (2097152*lti-1409286144)*1e-3;
+    else               return (     -1               );
+  }
+  else {
+    return -1;
+  };
+};
Index: /branches/BNC_2.12/src/bncutils.h
===================================================================
--- /branches/BNC_2.12/src/bncutils.h	(revision 8615)
+++ /branches/BNC_2.12/src/bncutils.h	(revision 8616)
@@ -50,5 +50,5 @@
  * and must be handled separately.
  * @param week GPS week number (must be prefilled, contains fixed value afterwards)
- * @param secOfWeek seconds in GPS week (must be prefilled, contains fixed value afterwards) 
+ * @param secOfWeek seconds in GPS week (must be prefilled, contains fixed value afterwards)
  * @param mSecOfWeek milli seconds in GLONASS time
  * @param fixnumleap when <code>true</code> then result is UTC time, otherwise it is GPS
@@ -86,8 +86,8 @@
 void         jacobiEll_XYZ(const double* Ell, Matrix& jacobi);
 
-void         covariXYZ_NEU(const SymmetricMatrix& Qxyz, const double* Ell, 
+void         covariXYZ_NEU(const SymmetricMatrix& Qxyz, const double* Ell,
                            SymmetricMatrix& Qneu);
 
-void         covariNEU_XYZ(const SymmetricMatrix& Qneu, const double* Ell, 
+void         covariNEU_XYZ(const SymmetricMatrix& Qneu, const double* Ell,
                            SymmetricMatrix& Qxyz);
 
@@ -98,10 +98,10 @@
 double       nint(double val);
 
-ColumnVector rungeKutta4(double xi, const ColumnVector& yi, double dx, double* acc, 
+ColumnVector rungeKutta4(double xi, const ColumnVector& yi, double dx, double* acc,
                          ColumnVector (*der)(double x, const ColumnVector& y, double* acc));
 
 void         GPSweekFromDateAndTime(const QDateTime& dateTime, int& GPSWeek, double& GPSWeeks);
 
-void         GPSweekFromYMDhms(int year, int month, int day, int hour, int min, double sec, 
+void         GPSweekFromYMDhms(int year, int month, int day, int hour, int min, double sec,
                                int& GPSWeek, double& GPSWeeks);
 
@@ -114,5 +114,5 @@
 int          readDbl(const QString& str, int pos, int len, double& value);
 
-void         topos(double xRec, double yRec, double zRec, double xSat, double ySat, double zSat, 
+void         topos(double xRec, double yRec, double zRec, double xSat, double ySat, double zSat,
                    double& rho, double& eleSat, double& azSat);
 
@@ -121,5 +121,5 @@
 QString      fortranFormat(double value, int width, int prec);
 
-void         kalman(const Matrix& AA, const ColumnVector& ll, const DiagonalMatrix& PP, 
+void         kalman(const Matrix& AA, const ColumnVector& ll, const DiagonalMatrix& PP,
                     SymmetricMatrix& QQ, ColumnVector& xx);
 
@@ -141,4 +141,10 @@
 
 int          factorial(int n);
+
+/** Convert RTCM3 lock-time indicator to lock time in seconds
+* depending on input message format. Returns -1 if format is
+* unknown or indicator is invalid
+*/
+double       lti2sec(int type, int lti);
 
 
Index: /branches/BNC_2.12/src/bncwindow.cpp
===================================================================
--- /branches/BNC_2.12/src/bncwindow.cpp	(revision 8615)
+++ /branches/BNC_2.12/src/bncwindow.cpp	(revision 8616)
@@ -286,4 +286,6 @@
   _outFileLineEdit    = new QLineEdit(settings.value("outFile").toString());
   _outUPortLineEdit   = new QLineEdit(settings.value("outUPort").toString());
+  _printLockTimeCheckBox = new QCheckBox();
+  _printLockTimeCheckBox->setCheckState(Qt::CheckState(settings.value("printLockTime").toInt()));  
 
   connect(_outPortLineEdit, SIGNAL(textChanged(const QString &)),
@@ -291,4 +293,7 @@
 
   connect(_outFileLineEdit, SIGNAL(textChanged(const QString &)),
+          this, SLOT(slotBncTextChanged()));
+
+  connect(_printLockTimeCheckBox, SIGNAL(stateChanged(int)),
           this, SLOT(slotBncTextChanged()));
 
@@ -758,6 +763,8 @@
   sLayout->addWidget(new QLabel("Port (unsynchronized)"),           4, 0);
   sLayout->addWidget(_outUPortLineEdit,                             4, 1);
-  sLayout->addWidget(new QLabel(""),                                5, 1);
-  sLayout->setRowStretch(6, 999);
+  sLayout->addWidget(new QLabel("Print lock time"),                 5, 0);
+  sLayout->addWidget(_printLockTimeCheckBox,                        5, 1);
+  sLayout->addWidget(new QLabel(""),                                6, 1);
+  sLayout->setRowStretch(7, 999);
 
   sgroup->setLayout(sLayout);
@@ -1283,4 +1290,5 @@
   _outFileLineEdit->setWhatsThis(tr("<p>Specify the full path to a file where synchronized observations are saved in plain ASCII format.</p><p>Beware that the size of this file can rapidly increase depending on the number of incoming streams.</p>"));
   _outUPortLineEdit->setWhatsThis(tr("<p>BNC can produce unsynchronized observations in a plain ASCII format on your local host via IP port.</p><p>Specify a port number to activate this function.</p>"));
+  _printLockTimeCheckBox->setWhatsThis(tr("<p>Print the lock time in seconds in the feed engine output.</p>"));
 
   // WhatsThis, Serial Output
@@ -1458,4 +1466,5 @@
   delete _outFileLineEdit;
   delete _outUPortLineEdit;
+  delete _printLockTimeCheckBox;
   delete _serialMountPointLineEdit;
   delete _serialPortNameLineEdit;
@@ -1875,4 +1884,5 @@
   settings.setValue("outFile",     _outFileLineEdit->text());
   settings.setValue("outUPort",    _outUPortLineEdit->text());
+  settings.setValue("printLockTime",_printLockTimeCheckBox->checkState());  
 // Serial Output
   settings.setValue("serialMountPoint",_serialMountPointLineEdit->text());
Index: /branches/BNC_2.12/src/bncwindow.h
===================================================================
--- /branches/BNC_2.12/src/bncwindow.h	(revision 8615)
+++ /branches/BNC_2.12/src/bncwindow.h	(revision 8616)
@@ -132,4 +132,5 @@
     QLineEdit* _outPortLineEdit;
     QLineEdit* _outUPortLineEdit;
+    QCheckBox* _printLockTimeCheckBox;    
     QLineEdit* _ephOutPortLineEdit;
     QLineEdit* _corrPortLineEdit;
Index: /branches/BNC_2.12/src/satObs.h
===================================================================
--- /branches/BNC_2.12/src/satObs.h	(revision 8615)
+++ /branches/BNC_2.12/src/satObs.h	(revision 8616)
@@ -23,4 +23,6 @@
     _snr             = 0.0;
     _snrValid        = false;
+    _lockTime        = 0.0;
+    _lockTimeValid   = false;
     _slip            = false;
     _slipCounter     = 0;
@@ -36,4 +38,6 @@
   double            _snr;
   bool              _snrValid;
+  double            _lockTime;
+  bool              _lockTimeValid;  
   bool              _slip;
   int               _slipCounter;
