Index: trunk/BNC/RTCM3/RTCM3Decoder.cpp
===================================================================
--- trunk/BNC/RTCM3/RTCM3Decoder.cpp	(revision 3254)
+++ trunk/BNC/RTCM3/RTCM3Decoder.cpp	(revision 3255)
@@ -446,11 +446,12 @@
   double weekold = 0.0;
   double weeknew = gpseph.GPSweek() + gpseph.GPSweeks() / secPerWeek;
-  if ( _ephList.find(gpseph.prn()) != _ephList.end() ) {
-    weekold = _ephList.find(gpseph.prn())->second.GPSweek() 
-            + _ephList.find(gpseph.prn())->second.GPSweeks() / secPerWeek; 
+  string prn = gpseph.prn().toAscii().data();
+  if ( _ephList.find(prn) != _ephList.end() ) {
+    weekold = _ephList.find(prn)->second.GPSweek() 
+            + _ephList.find(prn)->second.GPSweeks() / secPerWeek; 
   }
 
   if ( weeknew - weekold > 1.0/secPerWeek ) {
-    _ephList[gpseph.prn()] = gpseph;
+    _ephList[prn] = gpseph;
 
     return true;
Index: trunk/BNC/RTCM3/ephemeris.cpp
===================================================================
--- trunk/BNC/RTCM3/ephemeris.cpp	(revision 3254)
+++ trunk/BNC/RTCM3/ephemeris.cpp	(revision 3255)
@@ -14,4 +14,39 @@
 using namespace std;
 
+#define PI          3.1415926535898
+// Returns nearest integer value
+////////////////////////////////////////////////////////////////////////////
+static double NearestInt(double fl, double * remain)
+{
+  bool isneg = fl < 0.0;
+  double intval;
+  if(isneg) fl *= -1.0;
+  intval = (double)((unsigned long)(fl+0.5));
+  if(isneg) {fl *= -1.0; intval *= -1.0;}
+  if(remain)
+    *remain = fl-intval;
+  return intval;
+} /* NearestInt() */
+
+// Returns CRC24
+////////////////////////////////////////////////////////////////////////////
+static unsigned long CRC24(long size, const unsigned char *buf)
+{
+  unsigned long crc = 0;
+  int i;
+
+  while(size--)
+  {
+    crc ^= (*buf++) << (16);
+    for(i = 0; i < 8; i++)
+    {
+      crc <<= 1;
+      if(crc & 0x1000000)
+        crc ^= 0x01864cfb;
+    }
+  }
+  return crc;
+} /* CRC24 */
+
 // 
 ////////////////////////////////////////////////////////////////////////////
@@ -29,8 +64,6 @@
 ////////////////////////////////////////////////////////////////////////////
 void t_ephGPS::set(const gpsephemeris* ee) {
-  ostringstream prn;
-  prn << 'G' << setfill('0') << setw(2) << ee->satellite;
-
-  _prn = prn.str();
+
+  _prn = QString("G%1").arg(ee->satellite, 2, 10, QChar('0'));
 
   // TODO: check if following two lines are correct
@@ -154,4 +187,123 @@
 }
 
+// build up RTCM3 for GPS
+////////////////////////////////////////////////////////////////////////////
+#define GPSTOINT(type, value) static_cast<type>(NearestInt(value,0))
+
+#define GPSADDBITS(a, b) {bitbuffer = (bitbuffer<<(a)) \
+                       |(GPSTOINT(long long,b)&((1ULL<<a)-1)); \
+                       numbits += (a); \
+                       while(numbits >= 8) { \
+                       buffer[size++] = bitbuffer>>(numbits-8);numbits -= 8;}}
+#define GPSADDBITSFLOAT(a,b,c) {long long i = GPSTOINT(long long,(b)/(c)); \
+                             GPSADDBITS(a,i)};
+
+int t_ephGPS::RTCM3(unsigned char *buffer)
+{
+
+  unsigned char *startbuffer = buffer;
+  buffer= buffer+3;
+  int size = 0;
+  int numbits = 0;
+  unsigned long long bitbuffer = 0;
+  if (_ura <= 2.40){
+    _ura = 0;
+  }
+  else if (_ura <= 3.40){
+    _ura = 1;
+  }
+  else if (_ura <= 6.85){
+    _ura = 2;
+  }
+  else if (_ura <= 9.65){
+    _ura = 3;
+  }
+  else if (_ura <= 13.65){
+    _ura = 4;
+  }
+  else if (_ura <= 24.00){
+    _ura = 5;
+  }
+  else if (_ura <= 48.00){
+    _ura = 6;
+  }
+  else if (_ura <= 96.00){
+    _ura = 7;
+  }
+  else if (_ura <= 192.00){
+    _ura = 8;
+  }
+  else if (_ura <= 384.00){
+    _ura = 9;
+  }
+  else if (_ura <= 768.00){
+    _ura = 10;
+  }
+  else if (_ura <= 1536.00){
+    _ura = 11;
+  }
+  else if (_ura <= 1536.00){
+    _ura = 12;
+  }
+  else if (_ura <= 2072.00){
+    _ura = 13;
+  }
+  else if (_ura <= 6144.00){
+    _ura = 14;
+  }
+  else{
+    _ura = 15;
+  }
+
+  GPSADDBITS(12, 1019)
+  GPSADDBITS(6,_prn.right((_prn.length()-1)).toInt())
+  GPSADDBITS(10, _GPSweek)
+  GPSADDBITS(4, _ura)
+  GPSADDBITS(2,_L2Codes)
+  GPSADDBITSFLOAT(14, _IDOT, PI/static_cast<double>(1<<30)
+  /static_cast<double>(1<<13))
+  GPSADDBITS(8, _IODE)
+  GPSADDBITS(16, static_cast<int>(_TOC)>>4)
+  GPSADDBITSFLOAT(8, _clock_driftrate, 1.0/static_cast<double>(1<<30)
+  /static_cast<double>(1<<25))
+  GPSADDBITSFLOAT(16, _clock_drift, 1.0/static_cast<double>(1<<30)
+  /static_cast<double>(1<<13))
+  GPSADDBITSFLOAT(22, _clock_bias, 1.0/static_cast<double>(1<<30)
+  /static_cast<double>(1<<1))
+  GPSADDBITS(10, _IODC)
+  GPSADDBITSFLOAT(16, _Crs, 1.0/static_cast<double>(1<<5))
+  GPSADDBITSFLOAT(16, _Delta_n, PI/static_cast<double>(1<<30)
+  /static_cast<double>(1<<13))
+  GPSADDBITSFLOAT(32, _M0, PI/static_cast<double>(1<<30)/static_cast<double>(1<<1))
+  GPSADDBITSFLOAT(16, _Cuc, 1.0/static_cast<double>(1<<29))
+  GPSADDBITSFLOAT(32, _e, 1.0/static_cast<double>(1<<30)/static_cast<double>(1<<3))
+  GPSADDBITSFLOAT(16, _Cus, 1.0/static_cast<double>(1<<29))
+  GPSADDBITSFLOAT(32, _sqrt_A, 1.0/static_cast<double>(1<<19))
+  GPSADDBITS(16, static_cast<int>(_TOE)>>4)
+  GPSADDBITSFLOAT(16, _Cic, 1.0/static_cast<double>(1<<29))
+  GPSADDBITSFLOAT(32, _OMEGA0, PI/static_cast<double>(1<<30)
+  /static_cast<double>(1<<1))
+  GPSADDBITSFLOAT(16, _Cis, 1.0/static_cast<double>(1<<29))
+  GPSADDBITSFLOAT(32, _i0, PI/static_cast<double>(1<<30)/static_cast<double>(1<<1))
+  GPSADDBITSFLOAT(16, _Crc, 1.0/static_cast<double>(1<<5))
+  GPSADDBITSFLOAT(32, _omega, PI/static_cast<double>(1<<30)
+  /static_cast<double>(1<<1))
+  GPSADDBITSFLOAT(24, _OMEGADOT, PI/static_cast<double>(1<<30)
+  /static_cast<double>(1<<13))
+  GPSADDBITSFLOAT(8, _TGD, 1.0/static_cast<double>(1<<30)/static_cast<double>(1<<1))
+  GPSADDBITS(6, _health) 
+  GPSADDBITS(1, _L2PFlag)
+  GPSADDBITS(1, 0) /* GPS fit interval */
+
+  startbuffer[0]=0xD3;
+  startbuffer[1]=(size >> 8);
+  startbuffer[2]=size;
+  unsigned long  i = CRC24(size+3, startbuffer);
+  buffer[size++] = i >> 16;
+  buffer[size++] = i >> 8;
+  buffer[size++] = i;
+  size += 3;
+  return size;
+}
 
 // Derivative of the state vector using a simple force model (static)
@@ -268,11 +420,14 @@
 void t_ephGlo::set(const glonassephemeris* ee) {
 
-  ostringstream prn;
-  prn << 'R' << setfill('0') << setw(2) << ee->almanac_number;
-  _prn = prn.str();
+  _prn = QString("R%1").arg(ee->almanac_number, 2, 10, QChar('0'));
 
   int ww  = ee->GPSWeek;
   int tow = ee->GPSTOW; 
   updatetime(&ww, &tow, ee->tb*1000, 0);  // Moscow -> GPS
+
+  bncTime hlpTime(ee->GPSWeek, ee->GPSTOW);
+  unsigned year, month, day;
+  hlpTime.civil_date(year, month, day);
+  _gps_utc = gnumleap(year, month, day);
 
   _GPSweek           = ww;
@@ -306,11 +461,96 @@
 }
 
+// build up RTCM3 for GLONASS
+////////////////////////////////////////////////////////////////////////////
+#define GLONASSTOINT(type, value) static_cast<type>(NearestInt(value,0))
+
+#define GLONASSADDBITS(a, b) {bitbuffer = (bitbuffer<<(a)) \
+                       |(GLONASSTOINT(long long,b)&((1ULL<<(a))-1)); \
+                       numbits += (a); \
+                       while(numbits >= 8) { \
+                       buffer[size++] = bitbuffer>>(numbits-8);numbits -= 8;}}
+#define GLONASSADDBITSFLOATM(a,b,c) {int s; long long i; \
+                       if(b < 0.0) \
+                       { \
+                         s = 1; \
+                         i = GLONASSTOINT(long long,(-b)/(c)); \
+                         if(!i) s = 0; \
+                       } \
+                       else \
+                       { \
+                         s = 0; \
+                         i = GLONASSTOINT(long long,(b)/(c)); \
+                       } \
+                       GLONASSADDBITS(1,s) \
+                       GLONASSADDBITS(a-1,i)}
+
+int t_ephGlo::RTCM3(unsigned char *buffer)
+{
+
+  int size = 0;
+  int numbits = 0;
+  long long bitbuffer = 0;
+  unsigned char *startbuffer = buffer;
+  buffer= buffer+3;
+
+  GLONASSADDBITS(12, 1020)
+  GLONASSADDBITS(6, _prn.right((_prn.length()-1)).toInt())
+  GLONASSADDBITS(5, 7+_frequency_number)
+  GLONASSADDBITS(1, 0)
+  GLONASSADDBITS(1, 0)
+  GLONASSADDBITS(2, 0)
+  _tki=_tki+3*60*60;
+  GLONASSADDBITS(5, static_cast<int>(_tki)/(60*60))
+  GLONASSADDBITS(6, (static_cast<int>(_tki)/60)%60)
+  GLONASSADDBITS(1, (static_cast<int>(_tki)/30)%30)
+  GLONASSADDBITS(1, _health) 
+  GLONASSADDBITS(1, 0)
+  unsigned long long timeofday = (static_cast<int>(_tt+3*60*60-_gps_utc)%86400);
+  GLONASSADDBITS(7, timeofday/60/15)
+  GLONASSADDBITSFLOATM(24, _x_velocity*1000, 1000.0/static_cast<double>(1<<20))
+  GLONASSADDBITSFLOATM(27, _x_pos*1000, 1000.0/static_cast<double>(1<<11))
+  GLONASSADDBITSFLOATM(5, _x_acceleration*1000, 1000.0/static_cast<double>(1<<30))
+  GLONASSADDBITSFLOATM(24, _y_velocity*1000, 1000.0/static_cast<double>(1<<20))
+  GLONASSADDBITSFLOATM(27, _y_pos*1000, 1000.0/static_cast<double>(1<<11))
+  GLONASSADDBITSFLOATM(5, _y_acceleration*1000, 1000.0/static_cast<double>(1<<30))
+  GLONASSADDBITSFLOATM(24, _z_velocity*1000, 1000.0/static_cast<double>(1<<20))
+  GLONASSADDBITSFLOATM(27,_z_pos*1000, 1000.0/static_cast<double>(1<<11))
+  GLONASSADDBITSFLOATM(5, _z_acceleration*1000, 1000.0/static_cast<double>(1<<30))
+  GLONASSADDBITS(1, 0)
+  GLONASSADDBITSFLOATM(11, _gamma, 1.0/static_cast<double>(1<<30)
+  /static_cast<double>(1<<10))
+  GLONASSADDBITS(2, 0) /* GLONASS-M P */
+  GLONASSADDBITS(1, 0) /* GLONASS-M ln(3) */
+  GLONASSADDBITSFLOATM(22, _tau, 1.0/static_cast<double>(1<<30))
+  GLONASSADDBITS(5, 0) /* GLONASS-M delta tau */
+  GLONASSADDBITS(5, _E)
+  GLONASSADDBITS(1, 0) /* GLONASS-M P4 */
+  GLONASSADDBITS(4, 0) /* GLONASS-M FT */
+  GLONASSADDBITS(11, 0) /* GLONASS-M NT */
+  GLONASSADDBITS(2, 0) /* GLONASS-M active? */
+  GLONASSADDBITS(1, 0) /* GLONASS additional data */
+  GLONASSADDBITS(11, 0) /* GLONASS NA */
+  GLONASSADDBITS(32, 0) /* GLONASS tau C */
+  GLONASSADDBITS(5, 0) /* GLONASS-M N4 */
+  GLONASSADDBITS(22, 0) /* GLONASS-M tau GPS */
+  GLONASSADDBITS(1, 0) /* GLONASS-M ln(5) */
+  GLONASSADDBITS(7, 0) /* Reserved */
+
+  startbuffer[0]=0xD3;
+  startbuffer[1]=(size >> 8);
+  startbuffer[2]=size;
+  unsigned long i = CRC24(size+3, startbuffer);
+  buffer[size++] = i >> 16;
+  buffer[size++] = i >> 8;
+  buffer[size++] = i;
+  size += 3;
+  return size;
+}
+
 // Set Galileo Satellite Position
 ////////////////////////////////////////////////////////////////////////////
 void t_ephGal::set(const galileoephemeris* ee) {
-  ostringstream prn;
-  prn << 'E' << setfill('0') << setw(2) << ee->satellite;
-
-  _prn = prn.str();
+
+  _prn = QString("E%1").arg(ee->satellite, 2, 10, QChar('0'));
 
   _GPSweek  = ee->Week;
@@ -429,2 +669,8 @@
 }
 
+// build up RTCM3 for Galileo
+////////////////////////////////////////////////////////////////////////////
+int t_ephGal::RTCM3(unsigned char *buffer) {
+
+  return 0;
+}
Index: trunk/BNC/RTCM3/ephemeris.h
===================================================================
--- trunk/BNC/RTCM3/ephemeris.h	(revision 3254)
+++ trunk/BNC/RTCM3/ephemeris.h	(revision 3255)
@@ -14,6 +14,6 @@
   virtual ~t_eph() {};
 
-  bool        isNewerThan(const t_eph* eph) const;
-  std::string prn() const {return _prn;}
+  bool     isNewerThan(const t_eph* eph) const;
+  QString  prn() const {return _prn;}
   void    setReceptDateTime(const QDateTime& dateTime) {
     _receptDateTime = dateTime;
@@ -41,10 +41,12 @@
 
   virtual int  IOD() const = 0;
+  
+  virtual int  RTCM3(unsigned char *) = 0;
 
  protected:  
-  std::string _prn;
-  int         _GPSweek;
-  double      _GPSweeks;
-  QDateTime   _receptDateTime;
+  QString   _prn;
+  int       _GPSweek;
+  double    _GPSweeks;
+  QDateTime _receptDateTime;
 };
 
@@ -63,4 +65,6 @@
 
   virtual int  IOD() const { return static_cast<int>(_IODC); }
+
+  virtual int  RTCM3(unsigned char *);
 
  private:
@@ -92,4 +96,8 @@
 
   double  _TGD;              //  [s]    
+  double _health;            //  SV health
+  double _ura;               //  SV accuracy
+  double _L2PFlag;           //  L2 P data flag
+  double _L2Codes;           //  Codes on L2 channel 
 };
 
@@ -106,4 +114,6 @@
   virtual int  IOD() const;
 
+  virtual int  RTCM3(unsigned char *);
+
   void set(const glonassephemeris* ee);
 
@@ -115,4 +125,5 @@
   mutable ColumnVector _xv;  // status vector (position, velocity) at time _tt
 
+  double  _gps_utc;
   double  _E;                // [days]   
   double  _tau;              // [s]      
@@ -146,4 +157,6 @@
   virtual int  IOD() const { return static_cast<int>(_IODnav); }
 
+  virtual int  RTCM3(unsigned char *);
+
  private:
   double  _IODnav;             
@@ -169,4 +182,5 @@
   double  _IDOT;             //  [rad/s]
   double  _BGD_1_5A;         //  group delay [s] 
+  double  _BGD_1_5B;         //  group delay [s] 
   int     _SISA;             //  Signal In Space Accuracy
   int     _E5aHS;            //  E5a Health Status
Index: trunk/BNC/upload/bncephuploadcaster.cpp
===================================================================
--- trunk/BNC/upload/bncephuploadcaster.cpp	(revision 3254)
+++ trunk/BNC/upload/bncephuploadcaster.cpp	(revision 3255)
@@ -27,15 +27,20 @@
 
   QString mountpoint = settings.value("uploadEphMountpoint").toString();
-  QString outHost    = settings.value("uploadEphHost").toString();
-  int     outPort    = settings.value("uploadEphPort").toInt();
-  QString password   = settings.value("uploadEphPassword").toString();
+  if (mountpoint.isEmpty()) {
+    _ephUploadCaster = 0;
+  }
+  else {
+    QString outHost    = settings.value("uploadEphHost").toString();
+    int     outPort    = settings.value("uploadEphPort").toInt();
+    QString password   = settings.value("uploadEphPassword").toString();
 
-  _ephUploadCaster = new bncUploadCaster(mountpoint, outHost, outPort, 
+    _ephUploadCaster = new bncUploadCaster(mountpoint, outHost, outPort, 
                                          password, -1);
 
-  connect(_ephUploadCaster, SIGNAL(newBytes(QByteArray,double)), 
+    connect(_ephUploadCaster, SIGNAL(newBytes(QByteArray,double)), 
           this, SIGNAL(newBytes(QByteArray,double)));
 
-  _ephUploadCaster->start();
+    _ephUploadCaster->start();
+  }
 }
 
@@ -43,5 +48,7 @@
 ////////////////////////////////////////////////////////////////////////////
 bncEphUploadCaster::~bncEphUploadCaster() {
-  _ephUploadCaster->deleteSafely();
+  if (_ephUploadCaster) {
+    _ephUploadCaster->deleteSafely();
+  }
 }
 
@@ -49,4 +56,7 @@
 ////////////////////////////////////////////////////////////////////////////
 void bncEphUploadCaster::ephBufferChanged() {
-
+  if (_ephUploadCaster) {
+    QByteArray dummy = "from bncEphUploadCaster";
+    _ephUploadCaster->setOutBuffer(dummy);
+  }
 }
Index: trunk/BNC/upload/bncrtnetuploadcaster.cpp
===================================================================
--- trunk/BNC/upload/bncrtnetuploadcaster.cpp	(revision 3254)
+++ trunk/BNC/upload/bncrtnetuploadcaster.cpp	(revision 3255)
@@ -444,5 +444,5 @@
 
   outLine.sprintf("%d %.1f %s  %3d  %10.3f  %8.3f %8.3f %8.3f\n", 
-                  GPSweek, GPSweeks, eph->prn().c_str(),
+                  GPSweek, GPSweeks, eph->prn().toAscii().data(),
                   eph->IOD(), dClk, rsw(1), rsw(2), rsw(3));
 
