Index: /trunk/BNC/RTCM3/RTCM3coDecoder.cpp
===================================================================
--- /trunk/BNC/RTCM3/RTCM3coDecoder.cpp	(revision 933)
+++ /trunk/BNC/RTCM3/RTCM3coDecoder.cpp	(revision 934)
@@ -44,4 +44,5 @@
 #include "RTCM3coDecoder.h"
 #include "bncutils.h"
+#include "bncrinex.h"
 
 using namespace std;
@@ -49,6 +50,32 @@
 // Constructor
 ////////////////////////////////////////////////////////////////////////////
-RTCM3coDecoder::RTCM3coDecoder(const QString& fileName) 
-  : bncZeroDecoder(fileName) {
+RTCM3coDecoder::RTCM3coDecoder(const QString& fileName) {
+
+  // File Output
+  // -----------
+  QSettings settings;
+  QString path = settings.value("corrPath").toString();
+  if (!path.isEmpty()) {
+    expandEnvVar(path);
+    if ( path.length() > 0 && path[path.length()-1] != QDir::separator() ) {
+      path += QDir::separator();
+    }
+    _fileNameSkl = path + fileName;
+  }
+  _out = 0;
+
+  // Socket Server
+  // -------------
+  int port = settings.value("corrPort").toInt();
+  if (port != 0) {
+    _server = new QTcpServer;
+    _server->listen(QHostAddress::Any, port);
+    connect(_server, SIGNAL(newConnection()), this, SLOT(slotNewConnection()));
+    _sockets = new QList<QTcpSocket*>;
+  }
+  else {
+    delete _sockets;
+    delete _server;
+  }
 }
 
@@ -56,4 +83,39 @@
 ////////////////////////////////////////////////////////////////////////////
 RTCM3coDecoder::~RTCM3coDecoder() {
+}
+
+// Reopen Output File
+//////////////////////////////////////////////////////////////////////// 
+void RTCM3coDecoder::reopen() {
+
+  if (!_fileNameSkl.isEmpty()) {
+
+    QSettings settings;
+
+    QDateTime datTim = QDateTime::currentDateTime().toUTC();
+
+    QString hlpStr = bncRinex::nextEpochStr(datTim,
+                                      settings.value("corrIntr").toString());
+
+    QString fileName = _fileNameSkl 
+      + QString("%1").arg(datTim.date().dayOfYear(), 3, 10, QChar('0'))
+      + datTim.toString(".yyC");
+
+    if (_fileName == fileName) {
+      return;
+    }
+    else {
+      _fileName = fileName;
+    }
+
+    delete _out;
+    _out = new ofstream( _fileName.toAscii().data() );
+  }
+}
+
+// New Connection
+////////////////////////////////////////////////////////////////////////////
+void RTCM3coDecoder::slotNewConnection() {
+  _sockets->push_back( _server->nextPendingConnection() );
 }
 
@@ -126,5 +188,5 @@
                _co.Sat[ii].Orbit.DeltaAlongTrack,
                _co.Sat[ii].Orbit.DeltaCrossTrack);
-        *_out << line.toAscii().data();
+        printLine(line);
       }
       for(int ii = CLOCKORBIT_NUMGPS; 
@@ -137,7 +199,6 @@
                _co.Sat[ii].Orbit.DeltaAlongTrack,
                _co.Sat[ii].Orbit.DeltaCrossTrack);
-        *_out << line.toAscii().data();
-      }
-      _out->flush();
+        printLine(line);
+      }
       _buffer = _buffer.substr(bytesused);
       return success;
@@ -151,2 +212,29 @@
   }
 }
+
+// 
+////////////////////////////////////////////////////////////////////////////
+void RTCM3coDecoder::printLine(const QString& line) {
+
+  if (_out) {
+    *_out << line.toAscii().data();
+    _out->flush();
+  }
+
+  if (_sockets) {
+    QMutableListIterator<QTcpSocket*> is(*_sockets);
+    while (is.hasNext()) {
+      QTcpSocket* sock = is.next();
+      if (sock->state() == QAbstractSocket::ConnectedState) {
+        if (sock->write(line.toAscii()) == -1) {
+          delete sock;
+          is.remove();
+        }
+      }
+      else if (sock->state() != QAbstractSocket::ConnectingState) {
+        delete sock;
+        is.remove();
+      }
+    }
+  }
+}
Index: /trunk/BNC/RTCM3/RTCM3coDecoder.h
===================================================================
--- /trunk/BNC/RTCM3/RTCM3coDecoder.h	(revision 933)
+++ /trunk/BNC/RTCM3/RTCM3coDecoder.h	(revision 934)
@@ -26,5 +26,10 @@
 #define RTCM3CODECODER_H
 
-#include "bnczerodecoder.h"
+#include <fstream>
+
+#include <QtCore>
+#include <QtNetwork>
+
+#include "RTCM/GPSDecoder.h"
 
 extern "C" {
@@ -32,14 +37,27 @@
 }
 
-class RTCM3coDecoder : public bncZeroDecoder {
-public:
+class RTCM3coDecoder : public QObject, public GPSDecoder {
+Q_OBJECT
+ public:
   RTCM3coDecoder(const QString& fileName);
   virtual ~RTCM3coDecoder();
   virtual t_irc Decode(char* buffer = 0, int bufLen = 0);
-private:
-  std::string _buffer;
-  ClockOrbit  _co;
-  Bias        _bias;
-} ;
+
+ private slots:
+  void slotNewConnection();
+
+ private:
+  void reopen();
+  void printLine(const QString& line);
+
+  std::ofstream*      _out;
+  QString             _fileNameSkl;
+  QString             _fileName;
+  std::string         _buffer;
+  ClockOrbit          _co;
+  Bias                _bias;
+  QTcpServer*         _server;
+  QList<QTcpSocket*>* _sockets;
+};
 
 #endif
Index: /trunk/BNC/bncapp.cpp
===================================================================
--- /trunk/BNC/bncapp.cpp	(revision 933)
+++ /trunk/BNC/bncapp.cpp	(revision 934)
@@ -457,6 +457,5 @@
       QTcpSocket* sock = is.next();
       if (sock->state() == QAbstractSocket::ConnectedState) {
-        int fd = sock->socketDescriptor();
-        if (::write(fd, allLines.data(), allLines.size()) != allLines.size()) {
+        if (sock->write(allLines) == -1) {
           delete sock;
           is.remove();
@@ -531,6 +530,5 @@
       QTcpSocket* sock = is.next();
       if (sock->state() == QAbstractSocket::ConnectedState) {
-        int fd = sock->socketDescriptor();
-        if (::write(fd, allLines.data(), allLines.size()) != allLines.size()) {
+        if (sock->write(allLines) == -1) {
           delete sock;
           is.remove();
Index: /trunk/BNC/bncwindow.cpp
===================================================================
--- /trunk/BNC/bncwindow.cpp	(revision 933)
+++ /trunk/BNC/bncwindow.cpp	(revision 934)
@@ -117,6 +117,9 @@
   _outEphPortLineEdit    = new QLineEdit(settings.value("outEphPort").toString());
   _outEphPortLineEdit->setMaximumWidth(9*ww);
+  _corrPortLineEdit    = new QLineEdit(settings.value("corrPort").toString());
+  _corrPortLineEdit->setMaximumWidth(9*ww);
   _rnxPathLineEdit    = new QLineEdit(settings.value("rnxPath").toString());
   _ephPathLineEdit    = new QLineEdit(settings.value("ephPath").toString());
+  _corrPathLineEdit    = new QLineEdit(settings.value("ephPath").toString());
 
   _rnxV3CheckBox = new QCheckBox();
@@ -145,4 +148,12 @@
   if (jj != -1) {
     _ephIntrComboBox->setCurrentIndex(jj);
+  }
+  _corrIntrComboBox    = new QComboBox();
+  _corrIntrComboBox->setMaximumWidth(9*ww);
+  _corrIntrComboBox->setEditable(false);
+  _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
+  int mm = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
+  if (mm != -1) {
+    _corrIntrComboBox->setCurrentIndex(mm);
   }
   _rnxSamplSpinBox    = new QSpinBox();
@@ -282,6 +293,8 @@
   _outPortLineEdit->setWhatsThis(tr("BNC can produce synchronized observations in binary format on your local host through an IP port. Specify a port number here to activate this function."));
   _outEphPortLineEdit->setWhatsThis(tr("BNC can produce ephemeris data in RINEX ASCII format on your local host through an IP port. Specify a port number here to activate this function."));
+  _corrPortLineEdit->setWhatsThis(tr("BNC can produce ephemeris corrections on your local host through an IP port. Specify a port number here to activate this function."));
   _rnxPathLineEdit->setWhatsThis(tr("Here you specify the path to where the RINEX Observation files will be stored. If the specified directory does not exist, BNC will not create RINEX Observation files.")); 
   _ephPathLineEdit->setWhatsThis(tr("Specify the path for saving Broadcast Ephemeris data as RINEX Navigation files. If the specified directory does not exist, BNC will not create RINEX Navigation files."));
+  _corrPathLineEdit->setWhatsThis(tr("Specify the path for saving Broadcast Ephemeris corrections. If the specified directory does not exist, BNC will not create the files."));
   _rnxScrpLineEdit->setWhatsThis(tr("<p>Whenever a RINEX Observation file is saved, you might want to compress, copy or upload it immediately via FTP. BNC allows you to execute a script/batch file to carry out these operations. To do that specify the full path of the script/batch file here. BNC will pass the full RINEX Observation file path to the script as a command line parameter (%1 on Windows systems, $1 onUnix/Linux systems).</p><p>The triggering event for calling the script or batch file is the end of a RINEX Observation file 'Interval'. If that is overridden by a stream outage, the triggering event is the stream reconnection.</p>"));
   _rnxSkelLineEdit->setWhatsThis(tr("<p>Whenever BNC starts generating RINEX Observation files (and then once every day at midnight), it first tries to retrieve information needed for RINEX headers from so-called public RINEX header skeleton files which are derived from sitelogs. However, sometimes public RINEX header skeleton files are not available, its contents is not up to date, or you need to put additional/optional records in the RINEX header.</p><p>For that BNC allows using personal skeleton files that contain the header records you would like to include. You can derive a personal RINEX header skeleton file from the information given in an up to date sitelog. A file in the RINEX 'Directory' with the RINEX 'Skeleton extension' is interpreted by BNC as a personal RINEX header skeleton file for the corresponding stream.</p>"));
@@ -289,4 +302,5 @@
   _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file.</p>"));
   _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file.</p>"));
+  _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of the correction file.</p>"));
   _rnxSamplSpinBox->setWhatsThis(tr("<p>Select the RINEX Observation sampling interval in seconds. A value of zero '0' tells BNC to store all received epochs into RINEX.</p>"));
   _binSamplSpinBox->setWhatsThis(tr("<p>Select the Observation sampling interval in seconds. A value of zero '0' tells BNC to send/store all received epochs.</p>"));
@@ -314,4 +328,5 @@
   QWidget* egroup = new QWidget();
   QWidget* agroup = new QWidget();
+  QWidget* cgroup = new QWidget();
   QWidget* ogroup = new QWidget();
   aogroup->addTab(pgroup,tr("Proxy"));
@@ -320,4 +335,5 @@
   aogroup->addTab(egroup,tr("RINEX Ephemeris"));
   aogroup->addTab(sgroup,tr("Synchronized Observations"));
+  aogroup->addTab(cgroup,tr("Ephemeris Corrections"));
   aogroup->addTab(agroup,tr("Monitor"));
 
@@ -415,4 +431,16 @@
   ogroup->setLayout(oLayout);
  
+  QGridLayout* cLayout = new QGridLayout;
+  cLayout->setColumnMinimumWidth(0,12*ww);
+  cLayout->addWidget(new QLabel("Directory"),                     0, 0);
+  cLayout->addWidget(_corrPathLineEdit,                           0, 1);
+  cLayout->addWidget(new QLabel("Interval"),                      1, 0);
+  cLayout->addWidget(_corrIntrComboBox,                           1, 1);
+  cLayout->addWidget(new QLabel("Port"),                          2, 0);
+  cLayout->addWidget(_corrPortLineEdit,                           2, 1);
+  cLayout->addWidget(new QLabel("Saving ephemeris correction files and correction output through IP port."),3,0,1,2,Qt::AlignLeft);
+  cLayout->addWidget(new QLabel("    "),4,0);
+  cgroup->setLayout(cLayout);
+
   QVBoxLayout* mLayout = new QVBoxLayout;
   mLayout->addWidget(aogroup);
@@ -555,9 +583,12 @@
   settings.setValue("outPort",     _outPortLineEdit->text());
   settings.setValue("outEphPort",  _outEphPortLineEdit->text());
+  settings.setValue("corrPort",    _corrPortLineEdit->text());
   settings.setValue("rnxPath",     _rnxPathLineEdit->text());
   settings.setValue("ephPath",     _ephPathLineEdit->text());
+  settings.setValue("corrPath",    _corrPathLineEdit->text());
   settings.setValue("rnxScript",   _rnxScrpLineEdit->text());
   settings.setValue("rnxIntr",     _rnxIntrComboBox->currentText());
   settings.setValue("ephIntr",     _ephIntrComboBox->currentText());
+  settings.setValue("corrIntr",    _corrIntrComboBox->currentText());
   settings.setValue("rnxSampl",    _rnxSamplSpinBox->value());
   settings.setValue("binSampl",    _binSamplSpinBox->value());
Index: /trunk/BNC/bncwindow.h
===================================================================
--- /trunk/BNC/bncwindow.h	(revision 933)
+++ /trunk/BNC/bncwindow.h	(revision 934)
@@ -90,6 +90,8 @@
     QLineEdit* _outPortLineEdit;
     QLineEdit* _outEphPortLineEdit;
+    QLineEdit* _corrPortLineEdit;
     QLineEdit* _rnxPathLineEdit;
     QLineEdit* _ephPathLineEdit;
+    QLineEdit* _corrPathLineEdit;
     QCheckBox* _rnxV3CheckBox;
     QCheckBox* _ephV3CheckBox;
@@ -99,4 +101,5 @@
     QComboBox* _rnxIntrComboBox;
     QComboBox* _ephIntrComboBox;
+    QComboBox* _corrIntrComboBox;
     QSpinBox*  _rnxSamplSpinBox;
     QSpinBox*  _binSamplSpinBox;
Index: /trunk/BNC/bnczerodecoder.cpp
===================================================================
--- /trunk/BNC/bnczerodecoder.cpp	(revision 933)
+++ /trunk/BNC/bnczerodecoder.cpp	(revision 934)
@@ -48,4 +48,5 @@
 //////////////////////////////////////////////////////////////////////// 
 bncZeroDecoder::bncZeroDecoder(const QString& fileName) {
+
   QSettings settings;
   QString path = settings.value("rnxPath").toString();
Index: /trunk/BNC/bnczerodecoder.h
===================================================================
--- /trunk/BNC/bnczerodecoder.h	(revision 933)
+++ /trunk/BNC/bnczerodecoder.h	(revision 934)
@@ -35,9 +35,8 @@
   ~bncZeroDecoder();
   virtual t_irc Decode(char* buffer, int bufLen);
- protected:
+ private:
   void reopen();
   QString        _fileName;
   std::ofstream* _out;
- private:
   QDate          _fileDate;
 };
