Index: trunk/BNC/src/bncmain.cpp
===================================================================
--- trunk/BNC/src/bncmain.cpp	(revision 9651)
+++ trunk/BNC/src/bncmain.cpp	(revision 9652)
@@ -267,7 +267,7 @@
       "Upload Corrections Panel keys:\n"
       "   uploadMountpointsOut   {Upload corrections table [character string, semicolon separated list, each element in quotation marks, example:\n"
-      "                          \"igs-ip.net,2101,SSRA03IGS0,1,,pass,IGS14,RTCM-SSR,0,/home/user/BNCOUTPUT${V3PROD}.sp3,/home/user/BNCOUTPUT${V3PROD}.clk,258,1,0;\n"
+      "                          \"igs-ip.net,2101,SSRA03IGS0,1,,pass,IGS14,RTCM-SSR,0,/home/user/BNC0SSRRTS${V3PROD}.sp3,/home/user/BNC0SSRRTS${V3PROD}.clk,/home/user/BNC0SSRRTS${V3PROD}.bia,258,1,0;\n"
       "                          euref-ip.net,2101,EUREF01,1,,pass,ETRF2000,RTCM-SSR,0,,,258,2,0\"]}\n"
-      "   uploadIntr             {Length of SP3 and Clock RINEX file interval [character string: 1 min|2 min|5 min|10 min|15 min|30 min|1 hour|1 day]}\n"
+      "   uploadIntr             {Length of SP3, Clock RINEX and Bias SINEX file interval [character string: 1 min|2 min|5 min|10 min|15 min|30 min|1 hour|1 day]}\n"
       "   uploadSamplRtcmEphCorr {Orbit corrections stream sampling rate [integer number of seconds: 0|5|10|15|20|25|30|35|40|45|50|55|60]}\n"
       "   uploadSamplSp3         {SP3 file sampling rate [integer number of minutes: 0-15]}\n"
@@ -325,5 +325,5 @@
       "//user:pass@igs-ip.net:2101/FFMJ00DEU1 RTCM_3.1 DEU 50.09 8.66 no 2\"\n"
       "(7) bnc --key cmbStreams \"CLK11 BLG 1.0;CLK93 CNES 1.0\"\n"
-      "(8) bnc --key uploadMountpointsOut \"products.igs-ip.net,98756,TEST,letmein,IGS14,2,/Users/weber/BNCOUTPUT${V3PROD}.clk,,33,3,2;"
+      "(8) bnc --key uploadMountpointsOut \"products.igs-ip.net,98756,TEST,letmein,IGS14,2,/Users/weber/BNC0SSRRTS${V3PROD}.clk,,33,3,2;"
       "euref-ip.net,333,TEST2,aaaaa,ETRF2000,2,,,33,5,5\"\n"
       "(9) bnc --key PPP/staTable \"FFMJ00DEU1,100.0,100.0,100.0,100.0,100.0,100.0,0.1,3e-6,7777;"
Index: trunk/BNC/src/bncoutf.cpp
===================================================================
--- trunk/BNC/src/bncoutf.cpp	(revision 9651)
+++ trunk/BNC/src/bncoutf.cpp	(revision 9652)
@@ -72,5 +72,9 @@
   int indHlp = intStr.indexOf("min");
   if (!sampl) {
-    sampl++;
+    if (_sklBaseName.contains("V3PROD")){
+      sampl +=5;
+    } else {
+      sampl++;
+    }
   }
 
@@ -160,4 +164,7 @@
       addition = QString("_CLK");
     }
+    if (_extension.contains("bia") || _extension.contains("BIA")) {
+      addition = QString("_ABS");
+    }
   if (_extension.count(".") == 2) {
     _extension.replace(0,1,"_");
@@ -214,2 +221,6 @@
   return success;
 }
+
+QString bncoutf::agencyFromFileName() {
+  return QString("%1").arg(_sklBaseName.left(3));
+}
Index: trunk/BNC/src/bncoutf.h
===================================================================
--- trunk/BNC/src/bncoutf.h	(revision 9651)
+++ trunk/BNC/src/bncoutf.h	(revision 9652)
@@ -7,4 +7,5 @@
 
 #include "bncutils.h"
+#include <iostream>
 
 class bncoutf {
@@ -13,5 +14,5 @@
   virtual ~bncoutf();
   t_irc write(int GPSweek, double GPSweeks, const QString& str);
-
+  QString agencyFromFileName();
  protected:
   virtual t_irc reopen(int GPSweek, double GPSweeks);
Index: trunk/BNC/src/bncsettings.cpp
===================================================================
--- trunk/BNC/src/bncsettings.cpp	(revision 9651)
+++ trunk/BNC/src/bncsettings.cpp	(revision 9652)
@@ -188,4 +188,5 @@
     setValue_p("uploadSamplSp3",     "1");
     setValue_p("uploadSamplClkRnx", "10");
+    setValue_p("uploadSamplBiaSnx", "60");
     setValue_p("trafo_dx",            "");
     setValue_p("trafo_dy",            "");
Index: trunk/BNC/src/bncwindow.cpp
===================================================================
--- trunk/BNC/src/bncwindow.cpp	(revision 9651)
+++ trunk/BNC/src/bncwindow.cpp	(revision 9652)
@@ -1507,8 +1507,8 @@
   // WhatsThis, Upload Corrections
   // -----------------------------
-  _uploadTable->setWhatsThis(tr("<p>BNC can upload clock and orbit corrections to Broadcast Ephemeris (Broadcast Corrections) in different SSR formats. You may have a situation where clocks and orbits come from an external Real-time Network Engine (1) or a situation where clock and orbit corrections are combined within BNC (2).</p><p>(1) BNC identifies a stream as coming from a Real-time Network Engine if its format is specified as 'RTNET' and hence its decoder string in the 'Streams' canvas is 'RTNET'. It encodes and uploads that stream to the specified Ntrip Broadcaster Host and Port</p><p>(2) BNC understands that it is expected to encode and upload combined Broadcast Ephemeris Corrections if you specify correction streams in the 'Combine Corrections' table.</p><p>To fill the 'Upload Corrections' table, hit the 'Add Row' button, double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Mount' and 'Password' fields to enter the Ntrip Broadcaster IP port (default is 80), the mountpoint and the stream upload password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. An empty 'Host' option field means that you don't want to upload corrections.</p><p>Select a target coordinate reference System (e.g. IGS14) for outgoing clock and orbit corrections.</p><p>Select a target SSR format (e.g. IGS-SSR) for outgoing clock and orbit corrections.</p><p>By default orbit and clock corrections refer to Antenna Phase Center (APC). Tick 'CoM' to refer uploaded corrections to Center of Mass instead of APC.</p><p>Specify a path for saving generated Broadcast Corrections plus Broadcast Ephemeris as SP3 orbit files. If the specified directory does not exist, BNC will not create such files. The following is a path example for a Linux system: /home/user/BNCOUTPUT${V3PROD}.sp3<br>Note that '${V3PROD}' produces the time stamp in the filename, which is related to the RINEX version 3 filename concept.</p><p>Specify a path for saving generated Broadcast Correction clocks plus Broadcast Ephemeris clocks as Clock RINEX files. If the specified directory does not exist, BNC will not create Clock RINEX files. The following is a path example for a Linux system: /home/user/BNCOUTPUT${V3PROD}.clk<br>Note that '${V3PROD}' produces the time stamp in the filename, which is related to the RINEX version 3 filename concept.</p><p>Finally, specify a SSR Provider ID (issued by RTCM), SSR Solution ID, and SSR Issue of Data number.</p><p>In case the 'Combine Corrections' table contains only one Broadcast Correction stream, BNC will add that stream content to the Broadcast Ephemeris to save results in files specified via SP3 and/or Clock RINEX file path. You should then define only the SP3 and Clock RINEX file path and no further option in the 'Upload Corrections' table. <i>[key: uploadMountpointsOut]</i></p>"));
+  _uploadTable->setWhatsThis(tr("<p>BNC can upload clock and orbit corrections to Broadcast Ephemeris (Broadcast Corrections) as well as Code Biases in different SSR formats. You may have a situation where clocks, orbits and code biases come from an external Real-time Network Engine (1) or a situation where clock and orbit corrections are combined within BNC (2).</p><p>(1) BNC identifies a stream as coming from a Real-time Network Engine if its format is specified as 'RTNET' and hence its decoder string in the 'Streams' canvas is 'RTNET'. It encodes and uploads that stream to the specified Ntrip Broadcaster Host and Port</p><p>(2) BNC understands that it is expected to encode and upload combined Broadcast Ephemeris Corrections if you specify correction streams in the 'Combine Corrections' table.</p><p>To fill the 'Upload Corrections' table, hit the 'Add Row' button, double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Mount' and 'Password' fields to enter the Ntrip Broadcaster IP port (default is 80), the mountpoint and the stream upload password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. An empty 'Host' option field means that you don't want to upload corrections.</p><p>Select a target coordinate reference System (e.g. IGS14) for outgoing clock and orbit corrections.</p><p>Select a target SSR format (e.g. IGS-SSR) for outgoing clock and orbit corrections.</p><p>By default orbit and clock corrections refer to Antenna Phase Center (APC). Tick 'CoM' to refer uploaded corrections to Center of Mass instead of APC.</p><p>Specify a path for saving generated Broadcast Corrections plus Broadcast Ephemeris as SP3 orbit files. If the specified directory does not exist, BNC will not create such files. The following is a path example for a Linux system: /home/user/BNC0SSRRTS${V3PROD}.sp3.</p><p>Specify a path for saving generated Broadcast Correction clocks plus Broadcast Ephemeris clocks as Clock RINEX files. If the specified directory does not exist, BNC will not create Clock RINEX files. The following is a path example for a Linux system: /home/user/BNC0SSRRTS${V3PROD}.clk.</p><p>Specify a path for saving generated Code Biases as SINEX Bias files. If the specified directory does not exist, BNC will not create SINEX Bias files. The following is a path example for a Linux system: /home/user/BNC0SSRRTS${V3PROD}.bia.</p><p>Note that '${V3PROD}' produces the time stamp in the filename, which is related to the RINEX version 3 filename concept.</p><p>Finally, specify a SSR Provider ID (issued by RTCM), SSR Solution ID, and SSR Issue of Data number.</p><p>In case the 'Combine Corrections' table contains only one Broadcast Correction stream, BNC will add that stream content to the Broadcast Ephemeris to save results in files specified via SP3 and/or Clock RINEX file path. You should then define only the SP3 and Clock RINEX file path and no further option in the 'Upload Corrections' table. <i>[key: uploadMountpointsOut]</i></p>"));
   addUploadRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Corrections' table.</p>"));
   delUploadRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Corrections' table.</p>"));
-  _uploadIntrComboBox->setWhatsThis(tr("<p>Select the length of the SP3 and Clock RINEX files. <i>[key: uploadIntr]</i></p>"));
+  _uploadIntrComboBox->setWhatsThis(tr("<p>Select the length of the SP3, Clock RINEX and Bias SINEX files. <i>[key: uploadIntr]</i></p>"));
   _uploadSamplRtcmEphCorrSpinBox->setWhatsThis(tr("<p>Select a stream's orbit correction sampling interval in seconds.</p><p>A value of zero '0' tells BNC to upload all available orbit and clock correction samples together in combined messages. <i>[key: uploadSamplRtcmEphCorr]</i></p>"));
   _uploadSamplSp3SpinBox->setWhatsThis(tr("<p>Select a SP3 orbit file sampling interval in minutes.</p><p>A value of zero '0' tells BNC to store all available samples into SP3 orbit files. <i>[key: uploadSamplSp3]</i></p>"));
Index: trunk/BNC/src/src.pri
===================================================================
--- trunk/BNC/src/src.pri	(revision 9651)
+++ trunk/BNC/src/src.pri	(revision 9652)
@@ -58,4 +58,5 @@
           bncmap.h bncantex.h bncephuser.h                            \
           bncoutf.h bncclockrinex.h bncsp3.h bncsinextro.h            \
+          bncbissinex.h                                               \
           bncbytescounter.h bncsslconfig.h reqcdlg.h                  \
           upload/bncrtnetdecoder.h upload/bncuploadcaster.h           \
@@ -96,4 +97,5 @@
           bncmap_svg.cpp bncantex.cpp bncephuser.cpp                  \
           bncoutf.cpp bncclockrinex.cpp bncsp3.cpp bncsinextro.cpp    \
+          bncbiassinex.cpp                                            \
           bncbytescounter.cpp bncsslconfig.cpp reqcdlg.cpp            \
           ephemeris.cpp t_prn.cpp satObs.cpp                          \
Index: trunk/BNC/src/upload/bncrtnetdecoder.cpp
===================================================================
--- trunk/BNC/src/upload/bncrtnetdecoder.cpp	(revision 9651)
+++ trunk/BNC/src/upload/bncrtnetdecoder.cpp	(revision 9652)
@@ -76,5 +76,5 @@
                                                        hlp[3], hlp[4],
                                                        hlp[5], hlp[6], hlp[7], CoM,
-                                                       hlp[9], hlp[10],
+                                                       hlp[9], hlp[10],hlp[11],
                                                        PID, SID, IOD, iRow);
       newCaster->start();
Index: trunk/BNC/src/upload/bncrtnetuploadcaster.cpp
===================================================================
--- trunk/BNC/src/upload/bncrtnetuploadcaster.cpp	(revision 9651)
+++ trunk/BNC/src/upload/bncrtnetuploadcaster.cpp	(revision 9652)
@@ -20,4 +20,5 @@
 #include "bncephuser.h"
 #include "bncclockrinex.h"
+#include "bncbiassinex.h"
 #include "bncsp3.h"
 #include "gnss.h"
@@ -33,5 +34,5 @@
     const QString& userName, const QString& password,
     const QString& crdTrafo, const QString& ssrFormat, bool CoM, const QString& sp3FileName,
-    const QString& rnxFileName, int PID, int SID, int IOD, int iRow) :
+    const QString& rnxFileName, const QString& bsxFileName, int PID, int SID, int IOD, int iRow) :
     bncUploadCaster(mountpoint, outHost, outPort, ntripVersion, userName, password, iRow, 0) {
 
@@ -53,4 +54,8 @@
   if (!rnxFileName.isEmpty()) {
     _casterID += " " + rnxFileName;
+  }
+
+  if (!bsxFileName.isEmpty()) {
+    _casterID += " " + bsxFileName;
   }
 
@@ -87,5 +92,6 @@
   }
   int samplClkRnx = settings.value("uploadSamplClkRnx").toInt();
-  int samplSp3 = settings.value("uploadSamplSp3").toInt() * 60;
+  int samplSp3    = settings.value("uploadSamplSp3").toInt() * 60;
+  int samplBiaSnx = settings.value("uploadSamplBiaSnx").toInt();
 
   if (_samplRtcmEphCorr == 0.0) {
@@ -113,4 +119,14 @@
     _sp3 = 0;
   }
+
+  // SINEX writer
+  // ------------
+  if (!bsxFileName.isEmpty()) {
+    _bsx = new bncBiasSinex(bsxFileName, intr, samplBiaSnx);
+  }
+  else {
+    _bsx = 0;
+  }
+
 
   // Set Transformation Parameters
@@ -674,4 +690,8 @@
             biasSat->Biases[ii].Type = type;
             biasSat->Biases[ii].Bias = it.value();
+            if (_bsx) {
+              QString obsCode = 'C' + it.key();
+              _bsx->write(epoTime.gpsw(), epoTime.gpssec(), prnStr, obsCode, it.value());
+            }
           }
         }
@@ -737,4 +757,8 @@
             phasebiasSat->Biases[ii].SignalsWideLaneIntegerIndicator = pbSig.wlIndicator;
             phasebiasSat->Biases[ii].SignalDiscontinuityCounter = pbSig.discontinuityCounter;
+            if (_bsx) {
+              QString obsCode = 'L' + pbSig.type;
+              _bsx->write(epoTime.gpsw(), epoTime.gpssec(), prnStr, obsCode, pbSig.bias);
+            }
           }
         }
Index: trunk/BNC/src/upload/bncrtnetuploadcaster.h
===================================================================
--- trunk/BNC/src/upload/bncrtnetuploadcaster.h	(revision 9651)
+++ trunk/BNC/src/upload/bncrtnetuploadcaster.h	(revision 9652)
@@ -14,4 +14,5 @@
 class bncClockRinex;
 class bncSP3;
+class bncBiasSinex;
 
 class bncRtnetUploadCaster : public bncUploadCaster {
@@ -26,4 +27,5 @@
                   const QString& sp3FileName,
                   const QString& rnxFileName,
+                  const QString& bsxFileName,
                   int PID, int SID, int IOD, int iRow);
   void decodeRtnetStream(char* buffer, int bufLen);
@@ -78,4 +80,5 @@
   bncClockRinex* _rnx;
   bncSP3*        _sp3;
+  bncBiasSinex*  _bsx;
   QMap<QString, const t_eph*>* _usedEph;
 };
