Index: /trunk/BNC/src/GPSS/gpssDecoder.cpp
===================================================================
--- /trunk/BNC/src/GPSS/gpssDecoder.cpp	(revision 4283)
+++ /trunk/BNC/src/GPSS/gpssDecoder.cpp	(revision 4283)
@@ -0,0 +1,146 @@
+
+/* -------------------------------------------------------------------------
+ * BKG NTRIP Client
+ * -------------------------------------------------------------------------
+ *
+ * Class:      gpssDecoder
+ *
+ * Purpose:    Decode Data in GPSS Format
+ *
+ * Author:     L. Mervart
+ *
+ * Created:    20-Dec-2008
+ *
+ * Changes:    
+ *
+ * -----------------------------------------------------------------------*/
+
+#include "gpssDecoder.h"
+#include "bncapp.h"
+
+using namespace std;
+
+struct t_epochHeader {
+  double t_epoch;
+  int    n_svs;
+};
+
+// Cyclic Redundancy Check
+////////////////////////////////////////////////////////////////////////////
+unsigned short cal_crc(unsigned char *buf, int num) {
+  unsigned short polynomial = 0x8408;
+  unsigned short crc = 0;
+  int i;
+  while ( num-- ) {
+    crc = ( crc & 0xFF00 ) | ( *buf++^( crc & 0x00FF ) );
+    for( i=0; i<8; i++ ){
+      if( crc & 0x0001 ){
+        crc >>= 1;
+        crc ^= polynomial;
+      }
+      else{
+        crc >>= 1;
+      }
+    }
+  }
+  return (crc);
+}
+
+// Constructor
+////////////////////////////////////////////////////////////////////////////
+gpssDecoder::gpssDecoder() : GPSDecoder() {
+  connect(this, SIGNAL(newGPSEph(gpsephemeris*)), 
+          (bncApp*) qApp, SLOT(slotNewGPSEph(gpsephemeris*)));
+}
+
+// Destructor
+////////////////////////////////////////////////////////////////////////////
+gpssDecoder::~gpssDecoder() {
+}
+
+// 
+////////////////////////////////////////////////////////////////////////////
+t_irc gpssDecoder::Decode(char* data, int dataLen, vector<string>& errmsg) {
+
+  errmsg.clear();
+
+  _buffer += QByteArray(data, dataLen);
+
+  bool obsFound = false;
+  bool ephFound = false;
+  int iBeg;
+  while ( (iBeg = _buffer.indexOf(0x02)) != -1) {
+    _buffer = _buffer.mid(iBeg);
+
+    int recordSize;
+    int crc;
+   
+    // Observations
+    // ------------
+    if      (_buffer.length() > 0 && char(_buffer[1]) == 0x00) {
+
+      int reqLength = 2 + sizeof(recordSize) + sizeof(t_epochHeader);
+
+      if (_buffer.length() >= reqLength) {
+        t_epochHeader epochHdr;
+        memcpy(&epochHdr, _buffer.data() + 2 + sizeof(recordSize), 
+               sizeof(epochHdr));
+        
+        reqLength += epochHdr.n_svs * sizeof(t_obs) + sizeof(crc) + 1;
+
+        if (_buffer.length() >= reqLength) {
+
+          int checkLen = 2 + sizeof(recordSize) + sizeof(t_epochHeader) + 
+                         epochHdr.n_svs * sizeof(t_obs);
+          memcpy(&crc, _buffer.data() + checkLen, sizeof(crc));
+          int crcCal = cal_crc((unsigned char*) _buffer.data(), checkLen);
+
+          if (crc == crcCal) {
+            for (int is = 0; is < epochHdr.n_svs; is++) {
+              obsFound = true;
+              t_obs obs;
+              memcpy(&obs, _buffer.data() + 2 + sizeof(recordSize) + 
+                     sizeof(epochHdr) + is * sizeof(t_obs), sizeof(t_obs));
+              _obsList.push_back(obs);
+            }
+          }
+        }
+      }
+      _buffer = _buffer.mid(reqLength);
+    }
+
+    // Ephemeris
+    // ---------
+    else if (_buffer.length() > 0 && char(_buffer[1]) == 0x01) {
+      int reqLength = 2 + sizeof(recordSize) + sizeof(gpsephemeris) +
+                      sizeof(crc) + 1;
+
+      if (_buffer.length() >= reqLength) {
+
+        int checkLen = 2 + sizeof(recordSize) + sizeof(gpsephemeris);
+        memcpy(&crc, _buffer.data() + checkLen, sizeof(crc));
+        int crcCal = cal_crc((unsigned char*) _buffer.data(), checkLen);
+
+        if (crc == crcCal) {
+          ephFound = true;
+          gpsephemeris* gpsEph = new gpsephemeris;
+          memcpy(gpsEph, _buffer.data() + 2 + sizeof(recordSize), 
+                 sizeof(gpsephemeris));
+          emit newGPSEph(gpsEph);
+        }
+      }
+      _buffer = _buffer.mid(reqLength);
+    }
+
+    else {
+      _buffer == _buffer.mid(1);
+    }
+  }
+
+  if (obsFound || ephFound) {
+    return success;
+  }
+  else {
+    return failure;
+  }
+}
Index: /trunk/BNC/src/GPSS/gpssDecoder.h
===================================================================
--- /trunk/BNC/src/GPSS/gpssDecoder.h	(revision 4283)
+++ /trunk/BNC/src/GPSS/gpssDecoder.h	(revision 4283)
@@ -0,0 +1,27 @@
+
+#ifndef GPSSDECODER_H
+#define GPSSDECODER_H
+
+#include <QtCore>
+
+#include "RTCM/GPSDecoder.h"
+#include "rtcm3torinex.h"
+
+class gpssDecoder : public QObject, public GPSDecoder {
+Q_OBJECT
+
+ public:
+  gpssDecoder();
+  virtual ~gpssDecoder();
+  virtual t_irc Decode(char* data, int dataLen, std::vector<std::string>& errmsg);
+
+ signals:
+  void newMessage(QByteArray msg, bool showOnScreen);
+  void newGPSEph(gpsephemeris* gpseph);
+
+ private:
+  QByteArray _buffer;
+} ;
+
+#endif
+
Index: /trunk/BNC/src/GPSS/hassDecoder.cpp
===================================================================
--- /trunk/BNC/src/GPSS/hassDecoder.cpp	(revision 4283)
+++ /trunk/BNC/src/GPSS/hassDecoder.cpp	(revision 4283)
@@ -0,0 +1,167 @@
+
+/* -------------------------------------------------------------------------
+ * BKG NTRIP Client
+ * -------------------------------------------------------------------------
+ *
+ * Class:      hassDecoder
+ *
+ * Purpose:    Decode Data (PPP Corrections) in HASS Format
+ *
+ * Author:     L. Mervart
+ *
+ * Created:    19-Nov-2011
+ *
+ * Changes:    
+ *
+ * -----------------------------------------------------------------------*/
+
+#include <iostream>
+
+#include "hassDecoder.h"
+#include "bncapp.h"
+#include "bnctime.h"
+#include "bncutils.h"
+#include "bncsettings.h"
+#include "RTCM3/RTCM3coDecoder.h"
+
+using namespace std;
+
+// Constructor
+////////////////////////////////////////////////////////////////////////////
+hassDecoder::hassDecoder(const QString& staID) {
+  _staID = staID;
+
+  // File Output
+  // -----------
+  bncSettings 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 + staID;
+  }
+  _out      = 0;
+  _GPSweeks = -1.0;
+
+  connect(this, SIGNAL(newCorrLine(QString, QString, long)), 
+          (bncApp*) qApp, SLOT(slotNewCorrLine(QString, QString, long)));
+}
+
+// Destructor
+////////////////////////////////////////////////////////////////////////////
+hassDecoder::~hassDecoder() {
+  delete _out;
+}
+
+// 
+////////////////////////////////////////////////////////////////////////////
+t_irc hassDecoder::Decode(char* data, int dataLen, vector<string>& errmsg) {
+  QMutexLocker locker(&_mutex);
+
+  errmsg.clear();
+
+  _buffer += QByteArray(data, dataLen);
+
+  bool corrFound = false;
+  int indexEOL = -1;
+  while ( (indexEOL = _buffer.indexOf('\n')) != -1) {
+    QByteArray line = _buffer.left(indexEOL-1);
+    _buffer = _buffer.mid(indexEOL+1);
+
+    if (QString(line).split(QRegExp("\\s+"), QString::SkipEmptyParts).count() != 11) {
+      continue;
+    }
+    else {
+      corrFound = true;
+    }
+
+    QTextStream in(line, QIODevice::ReadOnly | QIODevice::Text);
+    int     mjd, IOD;
+    double  daySec;
+    ColumnVector dx(3);
+    ColumnVector dxRate(3);
+    double clkFull;
+
+    QString prn;
+    
+    in >> mjd >> daySec >> prn >> IOD >> dx[0] >> dx[1] >> dx[2] >> clkFull
+       >> dxRate[0] >> dxRate[1] >> dxRate[2];
+
+    // Correction Time
+    // ---------------
+    bncTime tt; 
+    tt.setmjd(daySec, mjd);
+
+    _GPSweeks = tt.gpssec();
+    long coTime = tt.gpsw() * 7*24*3600 + long(floor(_GPSweeks+0.5));
+
+    // Transform Correction
+    // --------------------
+    dx     = -dx;
+    dxRate = -dxRate;
+
+    t_eph* eph = 0;
+    if (_eph.contains(prn)) {
+      if      (_eph.value(prn)->last && _eph.value(prn)->last->IOD() == IOD) {
+        eph = _eph.value(prn)->last;
+      }
+      else if (_eph.value(prn)->prev && _eph.value(prn)->prev->IOD() == IOD) {
+        eph = _eph.value(prn)->prev;
+      }
+    }
+    if (!eph) {
+      continue;
+    }
+
+    ColumnVector xc(4);
+    ColumnVector vv(3);
+    eph->position(tt.gpsw(), tt.gpssec(), xc.data(), vv.data());
+
+    ColumnVector rao(3);
+    XYZ_to_RSW(xc.Rows(1,3), vv, dx,     rao);
+
+    ColumnVector dotRao(3);
+    XYZ_to_RSW(xc.Rows(1,3), vv, dxRate, dotRao);
+
+    double dClk = clkFull - xc[3] * t_CST::c;
+
+    // Print Correction Line
+    // ---------------------
+    QString corrLine;
+
+    int updateInterval = 0;
+    int messageType    = 0;
+    if      (prn[0] == 'G') {
+      messageType = COTYPE_GPSCOMBINED;
+    }
+    else if (prn[0] == 'R') {
+      messageType = COTYPE_GLONASSCOMBINED;
+    }
+
+    corrLine.sprintf("%d %d %d %.1f %s"
+                     "   %3d"
+                     "   %8.3f %8.3f %8.3f %8.3f"
+                     "   %10.5f %10.5f %10.5f %10.5f"
+                     "   %10.5f",
+                     messageType, updateInterval, tt.gpsw(), _GPSweeks,
+                     prn.toAscii().data(), IOD, 
+                     dClk, rao[0], rao[1], rao[2],
+                     0.0, dotRao[0], dotRao[1], dotRao[2], 0.0);
+
+    RTCM3coDecoder::reopen(_fileNameSkl, _fileName, _out);    
+    if (_out) {
+      *_out << corrLine.toAscii().data() << endl;
+      _out->flush();
+    }
+    emit newCorrLine(corrLine, _staID, coTime);
+  }
+
+  if (corrFound) {
+    return success;
+  }
+  else {
+    return failure;
+  }
+}
Index: /trunk/BNC/src/GPSS/hassDecoder.h
===================================================================
--- /trunk/BNC/src/GPSS/hassDecoder.h	(revision 4283)
+++ /trunk/BNC/src/GPSS/hassDecoder.h	(revision 4283)
@@ -0,0 +1,30 @@
+
+#ifndef HASSDECODER_H
+#define HASSDECODER_H
+
+#include <QtCore>
+
+#include "bncephuser.h"
+#include "RTCM/GPSDecoder.h"
+
+class hassDecoder : public bncEphUser, public GPSDecoder {
+Q_OBJECT
+ public:
+  hassDecoder(const QString& staID);
+  virtual ~hassDecoder();
+  virtual t_irc Decode(char* data, int dataLen, std::vector<std::string>& errmsg);
+
+ signals:
+  void newCorrLine(QString line, QString staID, long coTime);
+
+ private:
+  std::ofstream* _out;
+  QString        _staID;
+  QString        _fileNameSkl;
+  QString        _fileName;
+  QByteArray     _buffer;
+  double         _GPSweeks;
+} ;
+
+#endif
+
Index: /trunk/BNC/src/serial/posix_qextserialport.cpp
===================================================================
--- /trunk/BNC/src/serial/posix_qextserialport.cpp	(revision 4283)
+++ /trunk/BNC/src/serial/posix_qextserialport.cpp	(revision 4283)
@@ -0,0 +1,1121 @@
+
+/*!
+\class Posix_QextSerialPort
+\version 1.0.0
+\author Stefan Sander
+
+A cross-platform serial port class.
+This class encapsulates the POSIX portion of QextSerialPort.  The user will be notified of errors
+and possible portability conflicts at run-time by default - this behavior can be turned off by
+defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off portability
+warnings) in the project.  Note that _TTY_NOWARN_ will also turn off portability warnings.
+*/
+
+#ifdef sparc
+#include <sys/filio.h>
+#endif
+
+#include <stdio.h>
+#include "posix_qextserialport.h"
+
+/*!
+\fn Posix_QextSerialPort::Posix_QextSerialPort()
+Default constructor.  Note that the name of the device used by a QextSerialPort constructed with
+this constructor will be determined by #defined constants, or lack thereof - the default behavior
+is the same as _TTY_LINUX_.  Possible naming conventions and their associated constants are:
+
+\verbatim
+
+Constant         Used By         Naming Convention
+----------       -------------   ------------------------
+_TTY_WIN_        Windows         COM1, COM2
+_TTY_IRIX_       SGI/IRIX        /dev/ttyf1, /dev/ttyf2
+_TTY_HPUX_       HP-UX           /dev/tty1p0, /dev/tty2p0
+_TTY_SUN_        SunOS/Solaris   /dev/ttya, /dev/ttyb
+_TTY_DIGITAL_    Digital UNIX    /dev/tty01, /dev/tty02
+_TTY_FREEBSD_    FreeBSD         /dev/ttyd0, /dev/ttyd1
+_TTY_LINUX_      Linux           /dev/ttyS0, /dev/ttyS1
+<none>           Linux           /dev/ttyS0, /dev/ttyS1
+\endverbatim
+
+This constructor assigns the device name to the name of the first port on the specified system.
+See the other constructors if you need to open a different port.
+*/
+Posix_QextSerialPort::Posix_QextSerialPort()
+: QextSerialBase()
+{
+    Posix_File=new QFile();
+}
+
+/*!
+\fn Posix_QextSerialPort::Posix_QextSerialPort(const Posix_QextSerialPort&)
+Copy constructor.
+*/
+Posix_QextSerialPort::Posix_QextSerialPort(const Posix_QextSerialPort& s)
+ : QextSerialBase(s.port)
+{
+	setOpenMode(s.openMode());
+    port = s.port;
+    Settings.BaudRate=s.Settings.BaudRate;
+    Settings.DataBits=s.Settings.DataBits;
+    Settings.Parity=s.Settings.Parity;
+    Settings.StopBits=s.Settings.StopBits;
+    Settings.FlowControl=s.Settings.FlowControl;
+    lastErr=s.lastErr;
+
+    Posix_File=new QFile();
+    Posix_File=s.Posix_File;
+    memcpy(&Posix_Timeout, &s.Posix_Timeout, sizeof(struct timeval));
+    memcpy(&Posix_Copy_Timeout, &s.Posix_Copy_Timeout, sizeof(struct timeval));
+    memcpy(&Posix_CommConfig, &s.Posix_CommConfig, sizeof(struct termios));
+}
+
+/*!
+\fn Posix_QextSerialPort::Posix_QextSerialPort(const QString & name)
+Constructs a serial port attached to the port specified by name.
+name is the name of the device, which is windowsystem-specific,
+e.g."COM1" or "/dev/ttyS0".
+*/
+Posix_QextSerialPort::Posix_QextSerialPort(const QString & name)
+ : QextSerialBase(name)
+{
+    Posix_File=new QFile();
+}
+
+/*!
+\fn Posix_QextSerialPort::Posix_QextSerialPort(const PortSettings& settings)
+Constructs a port with default name and specified settings.
+*/
+Posix_QextSerialPort::Posix_QextSerialPort(const PortSettings& settings)
+ : QextSerialBase()
+{
+    setBaudRate(settings.BaudRate);
+    setDataBits(settings.DataBits);
+    setParity(settings.Parity);
+    setStopBits(settings.StopBits);
+    setFlowControl(settings.FlowControl);
+
+    Posix_File=new QFile();
+    setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec);
+}
+
+/*!
+\fn Posix_QextSerialPort::Posix_QextSerialPort(const QString & name, const PortSettings& settings)
+Constructs a port with specified name and settings.
+*/
+Posix_QextSerialPort::Posix_QextSerialPort(const QString & name, const PortSettings& settings)
+ : QextSerialBase(name)
+{
+    setBaudRate(settings.BaudRate);
+    setDataBits(settings.DataBits);
+    setParity(settings.Parity);
+    setStopBits(settings.StopBits);
+    setFlowControl(settings.FlowControl);
+
+    Posix_File=new QFile();
+    setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec);
+}
+
+/*!
+\fn Posix_QextSerialPort& Posix_QextSerialPort::operator=(const Posix_QextSerialPort& s)
+Override the = operator.
+*/
+Posix_QextSerialPort& Posix_QextSerialPort::operator=(const Posix_QextSerialPort& s)
+{
+   	setOpenMode(s.openMode());
+    port = s.port;
+    Settings.BaudRate=s.Settings.BaudRate;
+    Settings.DataBits=s.Settings.DataBits;
+    Settings.Parity=s.Settings.Parity;
+    Settings.StopBits=s.Settings.StopBits;
+    Settings.FlowControl=s.Settings.FlowControl;
+    lastErr=s.lastErr;
+
+    Posix_File=s.Posix_File;
+    memcpy(&Posix_Timeout, &(s.Posix_Timeout), sizeof(struct timeval));
+    memcpy(&Posix_Copy_Timeout, &(s.Posix_Copy_Timeout), sizeof(struct timeval));
+    memcpy(&Posix_CommConfig, &(s.Posix_CommConfig), sizeof(struct termios));
+    return *this;
+}
+
+/*!
+\fn Posix_QextSerialPort::~Posix_QextSerialPort()
+Standard destructor.
+*/
+Posix_QextSerialPort::~Posix_QextSerialPort()
+{
+    if (isOpen()) {
+        close();
+    }
+    Posix_File->close();
+    delete Posix_File;
+}
+
+/*!
+\fn void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate)
+Sets the baud rate of the serial port.  Note that not all rates are applicable on
+all platforms.  The following table shows translations of the various baud rate
+constants on Windows(including NT/2000) and POSIX platforms.  Speeds marked with an *
+are speeds that are usable on both Windows and POSIX.
+
+\note
+BAUD76800 may not be supported on all POSIX systems.  SGI/IRIX systems do not support
+BAUD1800.
+
+\verbatim
+
+  RATE          Windows Speed   POSIX Speed
+  -----------   -------------   -----------
+   BAUD50                 110          50
+   BAUD75                 110          75
+  *BAUD110                110         110
+   BAUD134                110         134.5
+   BAUD150                110         150
+   BAUD200                110         200
+  *BAUD300                300         300
+  *BAUD600                600         600
+  *BAUD1200              1200        1200
+   BAUD1800              1200        1800
+  *BAUD2400              2400        2400
+  *BAUD4800              4800        4800
+  *BAUD9600              9600        9600
+   BAUD14400            14400        9600
+  *BAUD19200            19200       19200
+  *BAUD38400            38400       38400
+   BAUD56000            56000       38400
+  *BAUD57600            57600       57600
+   BAUD76800            57600       76800
+  *BAUD115200          115200      115200
+   BAUD128000          128000      115200
+   BAUD256000          256000      115200
+\endverbatim
+*/
+void Posix_QextSerialPort::setBaudRate(BaudRateType baudRate)
+{
+    LOCK_MUTEX();
+    if (Settings.BaudRate!=baudRate) {
+        switch (baudRate) {
+            case BAUD14400:
+                Settings.BaudRate=BAUD9600;
+                break;
+
+            case BAUD56000:
+                Settings.BaudRate=BAUD38400;
+                break;
+
+            case BAUD76800:
+
+#ifndef B76800
+                Settings.BaudRate=BAUD57600;
+#else
+                Settings.BaudRate=baudRate;
+#endif
+                break;
+
+            case BAUD128000:
+            case BAUD256000:
+                Settings.BaudRate=BAUD115200;
+                break;
+
+            default:
+                Settings.BaudRate=baudRate;
+                break;
+        }
+    }
+    if (isOpen()) {
+        switch (baudRate) {
+
+            /*50 baud*/
+            case BAUD50:
+                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 50 baud operation.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B50;
+#else
+                cfsetispeed(&Posix_CommConfig, B50);
+                cfsetospeed(&Posix_CommConfig, B50);
+#endif
+                break;
+
+            /*75 baud*/
+            case BAUD75:
+                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 75 baud operation.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B75;
+#else
+                cfsetispeed(&Posix_CommConfig, B75);
+                cfsetospeed(&Posix_CommConfig, B75);
+#endif
+                break;
+
+            /*110 baud*/
+            case BAUD110:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B110;
+#else
+                cfsetispeed(&Posix_CommConfig, B110);
+                cfsetospeed(&Posix_CommConfig, B110);
+#endif
+                break;
+
+            /*134.5 baud*/
+            case BAUD134:
+                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 134.5 baud operation.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B134;
+#else
+                cfsetispeed(&Posix_CommConfig, B134);
+                cfsetospeed(&Posix_CommConfig, B134);
+#endif
+                break;
+
+            /*150 baud*/
+            case BAUD150:
+                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 150 baud operation.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B150;
+#else
+                cfsetispeed(&Posix_CommConfig, B150);
+                cfsetospeed(&Posix_CommConfig, B150);
+#endif
+                break;
+
+            /*200 baud*/
+            case BAUD200:
+                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows does not support 200 baud operation.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B200;
+#else
+                cfsetispeed(&Posix_CommConfig, B200);
+                cfsetospeed(&Posix_CommConfig, B200);
+#endif
+                break;
+
+            /*300 baud*/
+            case BAUD300:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B300;
+#else
+                cfsetispeed(&Posix_CommConfig, B300);
+                cfsetospeed(&Posix_CommConfig, B300);
+#endif
+                break;
+
+            /*600 baud*/
+            case BAUD600:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B600;
+#else
+                cfsetispeed(&Posix_CommConfig, B600);
+                cfsetospeed(&Posix_CommConfig, B600);
+#endif
+                break;
+
+            /*1200 baud*/
+            case BAUD1200:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B1200;
+#else
+                cfsetispeed(&Posix_CommConfig, B1200);
+                cfsetospeed(&Posix_CommConfig, B1200);
+#endif
+                break;
+
+            /*1800 baud*/
+            case BAUD1800:
+                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and IRIX do not support 1800 baud operation.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B1800;
+#else
+                cfsetispeed(&Posix_CommConfig, B1800);
+                cfsetospeed(&Posix_CommConfig, B1800);
+#endif
+                break;
+
+            /*2400 baud*/
+            case BAUD2400:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B2400;
+#else
+                cfsetispeed(&Posix_CommConfig, B2400);
+                cfsetospeed(&Posix_CommConfig, B2400);
+#endif
+                break;
+
+            /*4800 baud*/
+            case BAUD4800:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B4800;
+#else
+                cfsetispeed(&Posix_CommConfig, B4800);
+                cfsetospeed(&Posix_CommConfig, B4800);
+#endif
+                break;
+
+            /*9600 baud*/
+            case BAUD9600:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B9600;
+#else
+                cfsetispeed(&Posix_CommConfig, B9600);
+                cfsetospeed(&Posix_CommConfig, B9600);
+#endif
+                break;
+
+            /*14400 baud*/
+            case BAUD14400:
+                TTY_WARNING("Posix_QextSerialPort: POSIX does not support 14400 baud operation.  Switching to 9600 baud.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B9600;
+#else
+                cfsetispeed(&Posix_CommConfig, B9600);
+                cfsetospeed(&Posix_CommConfig, B9600);
+#endif
+                break;
+
+            /*19200 baud*/
+            case BAUD19200:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B19200;
+#else
+                cfsetispeed(&Posix_CommConfig, B19200);
+                cfsetospeed(&Posix_CommConfig, B19200);
+#endif
+                break;
+
+            /*38400 baud*/
+            case BAUD38400:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B38400;
+#else
+                cfsetispeed(&Posix_CommConfig, B38400);
+                cfsetospeed(&Posix_CommConfig, B38400);
+#endif
+                break;
+
+            /*56000 baud*/
+            case BAUD56000:
+                TTY_WARNING("Posix_QextSerialPort: POSIX does not support 56000 baud operation.  Switching to 38400 baud.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B38400;
+#else
+                cfsetispeed(&Posix_CommConfig, B38400);
+                cfsetospeed(&Posix_CommConfig, B38400);
+#endif
+                break;
+
+            /*57600 baud*/
+            case BAUD57600:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B57600;
+#else
+                cfsetispeed(&Posix_CommConfig, B57600);
+                cfsetospeed(&Posix_CommConfig, B57600);
+#endif
+                break;
+
+            /*76800 baud*/
+            case BAUD76800:
+                TTY_PORTABILITY_WARNING("Posix_QextSerialPort Portability Warning: Windows and some POSIX systems do not support 76800 baud operation.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+
+#ifdef B76800
+                Posix_CommConfig.c_cflag|=B76800;
+#else
+                TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support.  Switching to 57600 baud.");
+                Posix_CommConfig.c_cflag|=B57600;
+#endif //B76800
+#else  //CBAUD
+#ifdef B76800
+                cfsetispeed(&Posix_CommConfig, B76800);
+                cfsetospeed(&Posix_CommConfig, B76800);
+#else
+                TTY_WARNING("Posix_QextSerialPort: Posix_QextSerialPort was compiled without 76800 baud support.  Switching to 57600 baud.");
+                cfsetispeed(&Posix_CommConfig, B57600);
+                cfsetospeed(&Posix_CommConfig, B57600);
+#endif //B76800
+#endif //CBAUD
+                break;
+
+            /*115200 baud*/
+            case BAUD115200:
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B115200;
+#else
+                cfsetispeed(&Posix_CommConfig, B115200);
+                cfsetospeed(&Posix_CommConfig, B115200);
+#endif
+                break;
+
+            /*128000 baud*/
+            case BAUD128000:
+                TTY_WARNING("Posix_QextSerialPort: POSIX does not support 128000 baud operation.  Switching to 115200 baud.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B115200;
+#else
+                cfsetispeed(&Posix_CommConfig, B115200);
+                cfsetospeed(&Posix_CommConfig, B115200);
+#endif
+                break;
+
+            /*256000 baud*/
+            case BAUD256000:
+                TTY_WARNING("Posix_QextSerialPort: POSIX does not support 256000 baud operation.  Switching to 115200 baud.");
+#ifdef CBAUD
+                Posix_CommConfig.c_cflag&=(~CBAUD);
+                Posix_CommConfig.c_cflag|=B115200;
+#else
+                cfsetispeed(&Posix_CommConfig, B115200);
+                cfsetospeed(&Posix_CommConfig, B115200);
+#endif
+                break;
+        }
+        tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Posix_QextSerialPort::setDataBits(DataBitsType dataBits)
+Sets the number of data bits used by the serial port.  Possible values of dataBits are:
+\verbatim
+    DATA_5      5 data bits
+    DATA_6      6 data bits
+    DATA_7      7 data bits
+    DATA_8      8 data bits
+\endverbatim
+
+\note
+This function is subject to the following restrictions:
+\par
+    5 data bits cannot be used with 2 stop bits.
+\par
+    8 data bits cannot be used with space parity on POSIX systems.
+
+*/
+void Posix_QextSerialPort::setDataBits(DataBitsType dataBits)
+{
+    LOCK_MUTEX();
+    if (Settings.DataBits!=dataBits) {
+        if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) ||
+            (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5) ||
+            (Settings.Parity==PAR_SPACE && dataBits==DATA_8)) {
+        }
+        else {
+            Settings.DataBits=dataBits;
+        }
+    }
+    if (isOpen()) {
+        switch(dataBits) {
+
+            /*5 data bits*/
+            case DATA_5:
+                if (Settings.StopBits==STOP_2) {
+                    TTY_WARNING("Posix_QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
+                }
+                else {
+                    Settings.DataBits=dataBits;
+                    Posix_CommConfig.c_cflag&=(~CSIZE);
+                    Posix_CommConfig.c_cflag|=CS5;
+                    tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                }
+                break;
+
+            /*6 data bits*/
+            case DATA_6:
+                if (Settings.StopBits==STOP_1_5) {
+                    TTY_WARNING("Posix_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
+                }
+                else {
+                    Settings.DataBits=dataBits;
+                    Posix_CommConfig.c_cflag&=(~CSIZE);
+                    Posix_CommConfig.c_cflag|=CS6;
+                    tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                }
+                break;
+
+            /*7 data bits*/
+            case DATA_7:
+                if (Settings.StopBits==STOP_1_5) {
+                    TTY_WARNING("Posix_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
+                }
+                else {
+                    Settings.DataBits=dataBits;
+                    Posix_CommConfig.c_cflag&=(~CSIZE);
+                    Posix_CommConfig.c_cflag|=CS7;
+                    tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                }
+                break;
+
+            /*8 data bits*/
+            case DATA_8:
+                if (Settings.StopBits==STOP_1_5) {
+                    TTY_WARNING("Posix_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
+                }
+                else {
+                    Settings.DataBits=dataBits;
+                    Posix_CommConfig.c_cflag&=(~CSIZE);
+                    Posix_CommConfig.c_cflag|=CS8;
+                    tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                }
+                break;
+        }
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Posix_QextSerialPort::setParity(ParityType parity)
+Sets the parity associated with the serial port.  The possible values of parity are:
+\verbatim
+    PAR_SPACE       Space Parity
+    PAR_MARK        Mark Parity
+    PAR_NONE        No Parity
+    PAR_EVEN        Even Parity
+    PAR_ODD         Odd Parity
+\endverbatim
+
+\note
+This function is subject to the following limitations:
+\par
+POSIX systems do not support mark parity.
+\par
+POSIX systems support space parity only if tricked into doing so, and only with
+   fewer than 8 data bits.  Use space parity very carefully with POSIX systems.
+
+*/
+void Posix_QextSerialPort::setParity(ParityType parity)
+{
+    LOCK_MUTEX();
+    if (Settings.Parity!=parity) {
+        if (parity==PAR_MARK || (parity==PAR_SPACE && Settings.DataBits==DATA_8)) {
+        }
+        else {
+            Settings.Parity=parity;
+        }
+    }
+    if (isOpen()) {
+        switch (parity) {
+
+            /*space parity*/
+            case PAR_SPACE:
+                if (Settings.DataBits==DATA_8) {
+                    TTY_PORTABILITY_WARNING("Posix_QextSerialPort:  Space parity is only supported in POSIX with 7 or fewer data bits");
+                }
+                else {
+
+                    /*space parity not directly supported - add an extra data bit to simulate it*/
+                    Posix_CommConfig.c_cflag&=~(PARENB|CSIZE);
+                    switch(Settings.DataBits) {
+                        case DATA_5:
+                            Settings.DataBits=DATA_6;
+                            Posix_CommConfig.c_cflag|=CS6;
+                            break;
+
+                        case DATA_6:
+                            Settings.DataBits=DATA_7;
+                            Posix_CommConfig.c_cflag|=CS7;
+                            break;
+
+                        case DATA_7:
+                            Settings.DataBits=DATA_8;
+                            Posix_CommConfig.c_cflag|=CS8;
+                            break;
+
+                        case DATA_8:
+                            break;
+                    }
+                    tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                }
+                break;
+
+            /*mark parity - WINDOWS ONLY*/
+            case PAR_MARK:
+                TTY_WARNING("Posix_QextSerialPort: Mark parity is not supported by POSIX.");
+                break;
+
+            /*no parity*/
+            case PAR_NONE:
+                Posix_CommConfig.c_cflag&=(~PARENB);
+                tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                break;
+
+            /*even parity*/
+            case PAR_EVEN:
+                Posix_CommConfig.c_cflag&=(~PARODD);
+                Posix_CommConfig.c_cflag|=PARENB;
+                tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                break;
+
+            /*odd parity*/
+            case PAR_ODD:
+                Posix_CommConfig.c_cflag|=(PARENB|PARODD);
+                tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                break;
+        }
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Posix_QextSerialPort::setStopBits(StopBitsType stopBits)
+Sets the number of stop bits used by the serial port.  Possible values of stopBits are:
+\verbatim
+    STOP_1      1 stop bit
+    STOP_1_5    1.5 stop bits
+    STOP_2      2 stop bits
+\endverbatim
+\note
+This function is subject to the following restrictions:
+\par
+    2 stop bits cannot be used with 5 data bits.
+\par
+    POSIX does not support 1.5 stop bits.
+
+*/
+void Posix_QextSerialPort::setStopBits(StopBitsType stopBits)
+{
+    LOCK_MUTEX();
+    if (Settings.StopBits!=stopBits) {
+        if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) || stopBits==STOP_1_5) {}
+        else {
+            Settings.StopBits=stopBits;
+        }
+    }
+    if (isOpen()) {
+        switch (stopBits) {
+
+            /*one stop bit*/
+            case STOP_1:
+                Settings.StopBits=stopBits;
+                Posix_CommConfig.c_cflag&=(~CSTOPB);
+                tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                break;
+
+            /*1.5 stop bits*/
+            case STOP_1_5:
+                TTY_WARNING("Posix_QextSerialPort: 1.5 stop bit operation is not supported by POSIX.");
+                break;
+
+            /*two stop bits*/
+            case STOP_2:
+                if (Settings.DataBits==DATA_5) {
+                    TTY_WARNING("Posix_QextSerialPort: 2 stop bits cannot be used with 5 data bits");
+                }
+                else {
+                    Settings.StopBits=stopBits;
+                    Posix_CommConfig.c_cflag|=CSTOPB;
+                    tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                }
+                break;
+        }
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Posix_QextSerialPort::setFlowControl(FlowType flow)
+Sets the flow control used by the port.  Possible values of flow are:
+\verbatim
+    FLOW_OFF            No flow control
+    FLOW_HARDWARE       Hardware (RTS/CTS) flow control
+    FLOW_XONXOFF        Software (XON/XOFF) flow control
+\endverbatim
+\note
+FLOW_HARDWARE may not be supported on all versions of UNIX.  In cases where it is
+unsupported, FLOW_HARDWARE is the same as FLOW_OFF.
+
+*/
+void Posix_QextSerialPort::setFlowControl(FlowType flow)
+{
+    LOCK_MUTEX();
+    if (Settings.FlowControl!=flow) {
+        Settings.FlowControl=flow;
+    }
+    if (isOpen()) {
+        switch(flow) {
+
+            /*no flow control*/
+            case FLOW_OFF:
+                Posix_CommConfig.c_cflag&=(~CRTSCTS);
+                Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY));
+                tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                break;
+
+            /*software (XON/XOFF) flow control*/
+            case FLOW_XONXOFF:
+                Posix_CommConfig.c_cflag&=(~CRTSCTS);
+                Posix_CommConfig.c_iflag|=(IXON|IXOFF|IXANY);
+                tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                break;
+
+            case FLOW_HARDWARE:
+                Posix_CommConfig.c_cflag|=CRTSCTS;
+                Posix_CommConfig.c_iflag&=(~(IXON|IXOFF|IXANY));
+                tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+                break;
+        }
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Posix_QextSerialPort::setTimeout(ulong sec, ulong millisec);
+Sets the read and write timeouts for the port to sec seconds and millisec milliseconds.
+Note that this is a per-character timeout, i.e. the port will wait this long for each
+individual character, not for the whole read operation.  This timeout also applies to the
+bytesWaiting() function.
+
+\note
+POSIX does not support millisecond-level control for I/O timeout values.  Any
+timeout set using this function will be set to the next lowest tenth of a second for
+the purposes of detecting read or write timeouts.  For example a timeout of 550 milliseconds
+will be seen by the class as a timeout of 500 milliseconds for the purposes of reading and
+writing the port.  However millisecond-level control is allowed by the select() system call,
+so for example a 550-millisecond timeout will be seen as 550 milliseconds on POSIX systems for
+the purpose of detecting available bytes in the read buffer.
+
+*/
+void Posix_QextSerialPort::setTimeout(ulong sec, ulong millisec)
+{
+    LOCK_MUTEX();
+    Settings.Timeout_Sec=sec;
+    Settings.Timeout_Millisec=millisec;
+    Posix_Copy_Timeout.tv_sec=sec;
+    Posix_Copy_Timeout.tv_usec=millisec;
+    if (isOpen()) {
+        tcgetattr(Posix_File->handle(), &Posix_CommConfig);
+        Posix_CommConfig.c_cc[VTIME]=sec*10+millisec/100;
+        tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn bool Posix_QextSerialPort::open(OpenMode mode)
+Opens the serial port associated to this class.
+This function has no effect if the port associated with the class is already open.
+The port is also configured to the current settings, as stored in the Settings structure.
+*/
+bool Posix_QextSerialPort::open(OpenMode mode)
+{
+    LOCK_MUTEX();
+    if (mode == QIODevice::NotOpen)
+    	return isOpen();
+    if (!isOpen()) {
+        /*open the port*/
+        Posix_File->setFileName(port);
+        ////        qDebug("Trying to open File");
+        if (Posix_File->open(QIODevice::ReadWrite|QIODevice::Unbuffered)) {
+          ///            qDebug("Opened File succesfully");
+            /*set open mode*/
+            QIODevice::open(mode);
+
+            /*configure port settings*/
+            tcgetattr(Posix_File->handle(), &Posix_CommConfig);
+
+            /*set up other port settings*/
+            Posix_CommConfig.c_cflag|=CREAD|CLOCAL;
+            Posix_CommConfig.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG));
+            Posix_CommConfig.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY));
+            Posix_CommConfig.c_oflag&=(~OPOST);
+            Posix_CommConfig.c_cc[VMIN]=0;
+            Posix_CommConfig.c_cc[VINTR] = _POSIX_VDISABLE;
+            Posix_CommConfig.c_cc[VQUIT] = _POSIX_VDISABLE;
+            Posix_CommConfig.c_cc[VSTART] = _POSIX_VDISABLE;
+            Posix_CommConfig.c_cc[VSTOP] = _POSIX_VDISABLE;
+            Posix_CommConfig.c_cc[VSUSP] = _POSIX_VDISABLE;
+            setBaudRate(Settings.BaudRate);
+            setDataBits(Settings.DataBits);
+            setParity(Settings.Parity);
+            setStopBits(Settings.StopBits);
+            setFlowControl(Settings.FlowControl);
+            setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec);
+            tcsetattr(Posix_File->handle(), TCSAFLUSH, &Posix_CommConfig);
+        } else {
+            qDebug("Could not open File! Error code : %d", Posix_File->error());
+        }
+    }
+    UNLOCK_MUTEX();
+    return isOpen();
+}
+
+/*!
+\fn void Posix_QextSerialPort::close()
+Closes a serial port.  This function has no effect if the serial port associated with the class
+is not currently open.
+*/
+void Posix_QextSerialPort::close()
+{
+    LOCK_MUTEX();
+    Posix_File->close();
+    QIODevice::close();
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Posix_QextSerialPort::flush()
+Flushes all pending I/O to the serial port.  This function has no effect if the serial port
+associated with the class is not currently open.
+*/
+void Posix_QextSerialPort::flush()
+{
+    LOCK_MUTEX();
+    if (isOpen()) {
+        Posix_File->flush();
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn qint64 Posix_QextSerialPort::size() const
+This function will return the number of bytes waiting in the receive queue of the serial port.
+It is included primarily to provide a complete QIODevice interface, and will not record errors
+in the lastErr member (because it is const).  This function is also not thread-safe - in
+multithreading situations, use Posix_QextSerialPort::bytesWaiting() instead.
+*/
+qint64 Posix_QextSerialPort::size() const
+{
+    int numBytes;
+    if (ioctl(Posix_File->handle(), FIONREAD, &numBytes)<0) {
+        numBytes=0;
+    }
+    return (qint64)numBytes;
+}
+
+/*!
+\fn qint64 Posix_QextSerialPort::bytesAvailable()
+Returns the number of bytes waiting in the port's receive queue.  This function will return 0 if
+the port is not currently open, or -1 on error.  Error information can be retrieved by calling
+Posix_QextSerialPort::getLastError().
+*/
+qint64 Posix_QextSerialPort::bytesAvailable()
+{
+    LOCK_MUTEX();
+    if (isOpen()) {
+        int bytesQueued;
+        fd_set fileSet;
+        FD_ZERO(&fileSet);
+        FD_SET(Posix_File->handle(), &fileSet);
+
+        /*on Linux systems the Posix_Timeout structure will be altered by the select() call.
+          Make sure we use the right timeout values*/
+        //memcpy(&Posix_Timeout, &Posix_Copy_Timeout, sizeof(struct timeval));
+        Posix_Timeout = Posix_Copy_Timeout;
+        int n=select(Posix_File->handle()+1, &fileSet, NULL, &fileSet, &Posix_Timeout);
+        if (!n) {
+            lastErr=E_PORT_TIMEOUT;
+            UNLOCK_MUTEX();
+            return -1;
+        }
+        if (n==-1 || ioctl(Posix_File->handle(), FIONREAD, &bytesQueued)==-1) {
+            translateError(errno);
+            UNLOCK_MUTEX();
+            return -1;
+        }
+        lastErr=E_NO_ERROR;
+        UNLOCK_MUTEX();
+        return bytesQueued + QIODevice::bytesAvailable();
+    }
+    UNLOCK_MUTEX();
+    return 0;
+}
+
+/*!
+\fn void Posix_QextSerialPort::ungetChar(char)
+This function is included to implement the full QIODevice interface, and currently has no
+purpose within this class.  This function is meaningless on an unbuffered device and currently
+only prints a warning message to that effect.
+*/
+void Posix_QextSerialPort::ungetChar(char)
+{
+    /*meaningless on unbuffered sequential device - return error and print a warning*/
+    TTY_WARNING("Posix_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless");
+}
+
+/*!
+\fn void Posix_QextSerialPort::translateError(ulong error)
+Translates a system-specific error code to a QextSerialPort error code.  Used internally.
+*/
+void Posix_QextSerialPort::translateError(ulong error)
+{
+    switch (error) {
+        case EBADF:
+        case ENOTTY:
+            lastErr=E_INVALID_FD;
+            break;
+
+        case EINTR:
+            lastErr=E_CAUGHT_NON_BLOCKED_SIGNAL;
+            break;
+
+        case ENOMEM:
+            lastErr=E_NO_MEMORY;
+            break;
+    }
+}
+
+/*!
+\fn void Posix_QextSerialPort::setDtr(bool set)
+Sets DTR line to the requested state (high by default).  This function will have no effect if
+the port associated with the class is not currently open.
+*/
+void Posix_QextSerialPort::setDtr(bool set)
+{
+    LOCK_MUTEX();
+    if (isOpen()) {
+        int status;
+        ioctl(Posix_File->handle(), TIOCMGET, &status);
+        if (set) {
+            status|=TIOCM_DTR;
+        }
+        else {
+            status&=~TIOCM_DTR;
+        }
+        ioctl(Posix_File->handle(), TIOCMSET, &status);
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Posix_QextSerialPort::setRts(bool set)
+Sets RTS line to the requested state (high by default).  This function will have no effect if
+the port associated with the class is not currently open.
+*/
+void Posix_QextSerialPort::setRts(bool set)
+{
+    LOCK_MUTEX();
+    if (isOpen()) {
+        int status;
+        ioctl(Posix_File->handle(), TIOCMGET, &status);
+        if (set) {
+            status|=TIOCM_RTS;
+        }
+        else {
+            status&=~TIOCM_RTS;
+        }
+        ioctl(Posix_File->handle(), TIOCMSET, &status);
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn unsigned long Posix_QextSerialPort::lineStatus()
+returns the line status as stored by the port function.  This function will retrieve the states
+of the following lines: DCD, CTS, DSR, and RI.  On POSIX systems, the following additional lines
+can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD.  The value returned is an unsigned
+long with specific bits indicating which lines are high.  The following constants should be used
+to examine the states of individual lines:
+
+\verbatim
+Mask        Line
+------      ----
+LS_CTS      CTS
+LS_DSR      DSR
+LS_DCD      DCD
+LS_RI       RI
+LS_RTS      RTS (POSIX only)
+LS_DTR      DTR (POSIX only)
+LS_ST       Secondary TXD (POSIX only)
+LS_SR       Secondary RXD (POSIX only)
+\endverbatim
+
+This function will return 0 if the port associated with the class is not currently open.
+*/
+unsigned long Posix_QextSerialPort::lineStatus()
+{
+    unsigned long Status=0, Temp=0;
+    LOCK_MUTEX();
+    if (isOpen()) {
+        ioctl(Posix_File->handle(), TIOCMGET, &Temp);
+        if (Temp&TIOCM_CTS) {
+            Status|=LS_CTS;
+        }
+        if (Temp&TIOCM_DSR) {
+            Status|=LS_DSR;
+        }
+        if (Temp&TIOCM_RI) {
+            Status|=LS_RI;
+        }
+        if (Temp&TIOCM_CD) {
+            Status|=LS_DCD;
+        }
+        if (Temp&TIOCM_DTR) {
+            Status|=LS_DTR;
+        }
+        if (Temp&TIOCM_RTS) {
+            Status|=LS_RTS;
+        }
+        if (Temp&TIOCM_ST) {
+            Status|=LS_ST;
+        }
+        if (Temp&TIOCM_SR) {
+            Status|=LS_SR;
+        }
+    }
+    UNLOCK_MUTEX();
+    return Status;
+}
+
+/*!
+\fn qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize)
+Reads a block of data from the serial port.  This function will read at most maxSize bytes from
+the serial port and place them in the buffer pointed to by data.  Return value is the number of
+bytes actually read, or -1 on error.
+
+\warning before calling this function ensure that serial port associated with this class
+is currently open (use isOpen() function to check if port is open).
+*/
+qint64 Posix_QextSerialPort::readData(char * data, qint64 maxSize)
+{
+    LOCK_MUTEX();
+    int retVal=0;
+    retVal=Posix_File->read(data, maxSize);
+    if (retVal==-1)
+        lastErr=E_READ_FAILED;
+    UNLOCK_MUTEX();
+
+    return retVal;
+}
+
+/*!
+\fn qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize)
+Writes a block of data to the serial port.  This function will write maxSize bytes
+from the buffer pointed to by data to the serial port.  Return value is the number
+of bytes actually written, or -1 on error.
+
+\warning before calling this function ensure that serial port associated with this class
+is currently open (use isOpen() function to check if port is open).
+*/
+qint64 Posix_QextSerialPort::writeData(const char * data, qint64 maxSize)
+{
+    LOCK_MUTEX();
+    int retVal=0;
+    retVal=Posix_File->write(data, maxSize);
+    if (retVal==-1)
+       lastErr=E_WRITE_FAILED;
+    UNLOCK_MUTEX();
+
+    flush();
+    return retVal;
+}
Index: /trunk/BNC/src/serial/posix_qextserialport.h
===================================================================
--- /trunk/BNC/src/serial/posix_qextserialport.h	(revision 4283)
+++ /trunk/BNC/src/serial/posix_qextserialport.h	(revision 4283)
@@ -0,0 +1,56 @@
+
+#ifndef _POSIX_QEXTSERIALPORT_H_
+#define _POSIX_QEXTSERIALPORT_H_
+
+#include <stdio.h>
+#include <termios.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include "qextserialbase.h"
+
+class Posix_QextSerialPort:public QextSerialBase {
+public:
+    Posix_QextSerialPort();
+    Posix_QextSerialPort(const Posix_QextSerialPort& s);
+    Posix_QextSerialPort(const QString & name);
+    Posix_QextSerialPort(const PortSettings& settings);
+    Posix_QextSerialPort(const QString & name, const PortSettings& settings);
+    Posix_QextSerialPort& operator=(const Posix_QextSerialPort& s);
+    virtual ~Posix_QextSerialPort();
+
+    virtual void setBaudRate(BaudRateType);
+    virtual void setDataBits(DataBitsType);
+    virtual void setParity(ParityType);
+    virtual void setStopBits(StopBitsType);
+    virtual void setFlowControl(FlowType);
+    virtual void setTimeout(ulong, ulong);
+
+    virtual bool open(OpenMode mode=0);
+    virtual void close();
+    virtual void flush();
+
+    virtual qint64 size() const;
+    virtual qint64 bytesAvailable();
+
+    virtual void ungetChar(char c);
+
+    virtual void translateError(ulong error);
+
+    virtual void setDtr(bool set=true);
+    virtual void setRts(bool set=true);
+    virtual ulong lineStatus();
+
+protected:
+    QFile* Posix_File;
+    struct termios Posix_CommConfig;
+    struct timeval Posix_Timeout;
+    struct timeval Posix_Copy_Timeout;
+
+    virtual qint64 readData(char * data, qint64 maxSize);
+    virtual qint64 writeData(const char * data, qint64 maxSize);
+};
+
+#endif
Index: /trunk/BNC/src/serial/qextserialbase.cpp
===================================================================
--- /trunk/BNC/src/serial/qextserialbase.cpp	(revision 4283)
+++ /trunk/BNC/src/serial/qextserialbase.cpp	(revision 4283)
@@ -0,0 +1,250 @@
+
+#include "qextserialbase.h"
+
+/*!
+\class QextSerialBase
+\version 1.0.0
+\author Stefan Sander
+
+A common base class for Win_QextSerialBase, Posix_QextSerialBase and QextSerialPort.
+*/
+#ifdef QT_THREAD_SUPPORT
+QMutex* QextSerialBase::mutex=NULL;
+unsigned long QextSerialBase::refCount=0;
+#endif
+
+/*!
+\fn QextSerialBase::QextSerialBase()
+Default constructor.
+*/
+QextSerialBase::QextSerialBase()
+ : QIODevice()
+{
+
+#ifdef _TTY_WIN_
+    setPortName("COM1");
+
+#elif defined(_TTY_IRIX_)
+    setPortName("/dev/ttyf1");
+
+#elif defined(_TTY_HPUX_)
+    setPortName("/dev/tty1p0");
+
+#elif defined(_TTY_SUN_)
+    setPortName("/dev/ttya");
+
+#elif defined(_TTY_DIGITAL_)
+    setPortName("/dev/tty01");
+
+#elif defined(_TTY_FREEBSD_)
+    setPortName("/dev/ttyd1");
+
+#else
+    setPortName("/dev/ttyS0");
+#endif
+
+    construct();
+}
+
+/*!
+\fn QextSerialBase::QextSerialBase(const QString & name)
+Construct a port and assign it to the device specified by the name parameter.
+*/
+QextSerialBase::QextSerialBase(const QString & name)
+ : QIODevice()
+{
+    setPortName(name);
+    construct();
+}
+
+/*!
+\fn QextSerialBase::~QextSerialBase()
+Standard destructor.
+*/
+QextSerialBase::~QextSerialBase()
+{
+
+#ifdef QT_THREAD_SUPPORT
+    refCount--;
+    if (mutex && refCount==0) {
+        delete mutex;
+        mutex=NULL;
+    }
+#endif
+
+}
+
+/*!
+\fn void QextSerialBase::construct()
+Common constructor function for setting up default port settings.
+(115200 Baud, 8N1, Hardware flow control where supported, otherwise no flow control, and 500 ms timeout).
+*/
+void QextSerialBase::construct()
+{
+    Settings.BaudRate=BAUD115200;
+    Settings.DataBits=DATA_8;
+    Settings.Parity=PAR_NONE;
+    Settings.StopBits=STOP_1;
+    Settings.FlowControl=FLOW_HARDWARE;
+    Settings.Timeout_Sec=0;
+    Settings.Timeout_Millisec=500;
+
+#ifdef QT_THREAD_SUPPORT
+    if (!mutex) {
+        mutex=new QMutex( QMutex::Recursive );
+    }
+    refCount++;
+#endif
+
+	setOpenMode(QIODevice::NotOpen);
+}
+
+/*!
+\fn void QextSerialBase::setPortName(const QString & name)
+Sets the name of the device associated with the object, e.g. "COM1", or "/dev/ttyS0".
+*/
+void QextSerialBase::setPortName(const QString & name)
+{
+    port = name;
+}
+
+/*!
+\fn QString QextSerialBase::portName() const
+Returns the name set by setPortName().
+*/
+QString QextSerialBase::portName() const
+{
+    return port;
+}
+
+/*!
+\fn BaudRateType QextSerialBase::baudRate(void) const
+Returns the baud rate of the serial port.  For a list of possible return values see
+the definition of the enum BaudRateType.
+*/
+BaudRateType QextSerialBase::baudRate(void) const
+{
+    return Settings.BaudRate;
+}
+
+/*!
+\fn DataBitsType QextSerialBase::dataBits() const
+Returns the number of data bits used by the port.  For a list of possible values returned by
+this function, see the definition of the enum DataBitsType.
+*/
+DataBitsType QextSerialBase::dataBits() const
+{
+    return Settings.DataBits;
+}
+
+/*!
+\fn ParityType QextSerialBase::parity() const
+Returns the type of parity used by the port.  For a list of possible values returned by
+this function, see the definition of the enum ParityType.
+*/
+ParityType QextSerialBase::parity() const
+{
+    return Settings.Parity;
+}
+
+/*!
+\fn StopBitsType QextSerialBase::stopBits() const
+Returns the number of stop bits used by the port.  For a list of possible return values, see
+the definition of the enum StopBitsType.
+*/
+StopBitsType QextSerialBase::stopBits() const
+{
+    return Settings.StopBits;
+}
+
+/*!
+\fn FlowType QextSerialBase::flowControl() const
+Returns the type of flow control used by the port.  For a list of possible values returned
+by this function, see the definition of the enum FlowType.
+*/
+FlowType QextSerialBase::flowControl() const
+{
+    return Settings.FlowControl;
+}
+
+/*!
+\fn bool QextSerialBase::isSequential() const
+Returns true if device is sequential, otherwise returns false. Serial port is sequential device
+so this function always returns true. Check QIODevice::isSequential() documentation for more 
+information.
+*/
+bool QextSerialBase::isSequential() const
+{
+	return true;
+}
+
+/*!
+\fn bool QextSerialBase::atEnd() const
+This function will return true if the input buffer is empty (or on error), and false otherwise.
+Call QextSerialBase::lastError() for error information.
+*/
+bool QextSerialBase::atEnd() const
+{
+    if (size()) {
+        return true;
+    }
+    return false;
+}
+
+/*!
+\fn qint64 QextSerialBase::readLine(char * data, qint64 maxSize)
+This function will read a line of buffered input from the port, stopping when either maxSize bytes
+have been read, the port has no more data available, or a newline is encountered.
+The value returned is the length of the string that was read.
+*/
+qint64 QextSerialBase::readLine(char * data, qint64 maxSize)
+{
+    qint64 numBytes = bytesAvailable();
+    char* pData = data;
+
+	if (maxSize < 2)	//maxSize must be larger than 1
+		return -1;
+
+    /*read a byte at a time for MIN(bytesAvail, maxSize - 1) iterations, or until a newline*/
+    while (pData<(data+numBytes) && --maxSize) {
+        readData(pData, 1);
+        if (*pData++ == '\n') {
+            break;
+        }
+    }
+    *pData='\0';
+
+    /*return size of data read*/
+    return (pData-data);
+}
+
+/*!
+\fn ulong QextSerialBase::lastError() const
+Returns the code for the last error encountered by the port, or E_NO_ERROR if the last port
+operation was successful.  Possible error codes are:
+
+\verbatim
+Error                           Explanation
+---------------------------     -------------------------------------------------------------
+E_NO_ERROR                      No Error has occured
+E_INVALID_FD                    Invalid file descriptor (port was not opened correctly)
+E_NO_MEMORY                     Unable to allocate memory tables (POSIX)
+E_CAUGHT_NON_BLOCKED_SIGNAL     Caught a non-blocked signal (POSIX)
+E_PORT_TIMEOUT                  Operation timed out (POSIX)
+E_INVALID_DEVICE                The file opened by the port is not a character device (POSIX)
+E_BREAK_CONDITION               The port detected a break condition
+E_FRAMING_ERROR                 The port detected a framing error
+                                (usually caused by incorrect baud rate settings)
+E_IO_ERROR                      There was an I/O error while communicating with the port
+E_BUFFER_OVERRUN                Character buffer overrun
+E_RECEIVE_OVERFLOW              Receive buffer overflow
+E_RECEIVE_PARITY_ERROR          The port detected a parity error in the received data
+E_TRANSMIT_OVERFLOW             Transmit buffer overflow
+E_READ_FAILED                   General read operation failure
+E_WRITE_FAILED                  General write operation failure
+\endverbatim
+*/
+ulong QextSerialBase::lastError() const
+{
+    return lastErr;
+}
Index: /trunk/BNC/src/serial/qextserialbase.h
===================================================================
--- /trunk/BNC/src/serial/qextserialbase.h	(revision 4283)
+++ /trunk/BNC/src/serial/qextserialbase.h	(revision 4283)
@@ -0,0 +1,196 @@
+
+#ifndef _QEXTSERIALBASE_H_
+#define _QEXTSERIALBASE_H_
+
+#include <QIODevice>
+#include <QFile>
+
+#ifdef QT_THREAD_SUPPORT
+#include <QThread>
+#include <QMutex>
+#endif
+
+/*if all warning messages are turned off, flag portability warnings to be turned off as well*/
+#ifdef _TTY_NOWARN_
+#define _TTY_NOWARN_PORT_
+#endif
+
+/*macros for thread support*/
+#ifdef QT_THREAD_SUPPORT
+#define LOCK_MUTEX() mutex->lock()
+#define UNLOCK_MUTEX() mutex->unlock()
+#else
+#define LOCK_MUTEX()
+#define UNLOCK_MUTEX()
+#endif
+
+/*macros for warning messages*/
+#ifdef _TTY_NOWARN_PORT_
+#define TTY_PORTABILITY_WARNING(s)
+#else
+#define TTY_PORTABILITY_WARNING(s) qWarning(s)
+#endif
+#ifdef _TTY_NOWARN_
+#define TTY_WARNING(s)
+#else
+#define TTY_WARNING(s) qWarning(s)
+#endif
+
+
+/*line status constants*/
+#define LS_CTS  0x01
+#define LS_DSR  0x02
+#define LS_DCD  0x04
+#define LS_RI   0x08
+#define LS_RTS  0x10
+#define LS_DTR  0x20
+#define LS_ST   0x40
+#define LS_SR   0x80
+
+/*error constants*/
+#define E_NO_ERROR                   0
+#define E_INVALID_FD                 1
+#define E_NO_MEMORY                  2
+#define E_CAUGHT_NON_BLOCKED_SIGNAL  3
+#define E_PORT_TIMEOUT               4
+#define E_INVALID_DEVICE             5
+#define E_BREAK_CONDITION            6
+#define E_FRAMING_ERROR              7
+#define E_IO_ERROR                   8
+#define E_BUFFER_OVERRUN             9
+#define E_RECEIVE_OVERFLOW          10
+#define E_RECEIVE_PARITY_ERROR      11
+#define E_TRANSMIT_OVERFLOW         12
+#define E_READ_FAILED               13
+#define E_WRITE_FAILED              14
+
+/*enums for port settings*/
+enum NamingConvention {
+    WIN_NAMES,
+    IRIX_NAMES,
+    HPUX_NAMES,
+    SUN_NAMES,
+    DIGITAL_NAMES,
+    FREEBSD_NAMES,
+    LINUX_NAMES
+};
+
+enum BaudRateType {
+    BAUD50,                //POSIX ONLY
+    BAUD75,                //POSIX ONLY
+    BAUD110,
+    BAUD134,               //POSIX ONLY
+    BAUD150,               //POSIX ONLY
+    BAUD200,               //POSIX ONLY
+    BAUD300,
+    BAUD600,
+    BAUD1200,
+    BAUD1800,              //POSIX ONLY
+    BAUD2400,
+    BAUD4800,
+    BAUD9600,
+    BAUD14400,             //WINDOWS ONLY
+    BAUD19200,
+    BAUD38400,
+    BAUD56000,             //WINDOWS ONLY
+    BAUD57600,
+    BAUD76800,             //POSIX ONLY
+    BAUD115200,
+    BAUD128000,            //WINDOWS ONLY
+    BAUD256000             //WINDOWS ONLY
+};
+
+enum DataBitsType {
+    DATA_5,
+    DATA_6,
+    DATA_7,
+    DATA_8
+};
+
+enum ParityType {
+    PAR_NONE,
+    PAR_ODD,
+    PAR_EVEN,
+    PAR_MARK,               //WINDOWS ONLY
+    PAR_SPACE
+};
+
+enum StopBitsType {
+    STOP_1,
+    STOP_1_5,               //WINDOWS ONLY
+    STOP_2
+};
+
+enum FlowType {
+    FLOW_OFF,
+    FLOW_HARDWARE,
+    FLOW_XONXOFF
+};
+
+/*structure to contain port settings*/
+struct PortSettings {
+    BaudRateType BaudRate;
+    DataBitsType DataBits;
+    ParityType Parity;
+    StopBitsType StopBits;
+    FlowType FlowControl;
+    ulong Timeout_Sec;
+    ulong Timeout_Millisec;
+};
+
+class QextSerialBase : public QIODevice {
+public:
+    QextSerialBase();
+    QextSerialBase(const QString & name);
+    virtual ~QextSerialBase();
+    virtual void construct();
+    virtual void setPortName(const QString & name);
+    virtual QString portName() const;
+
+    virtual void setBaudRate(BaudRateType)=0;
+    virtual BaudRateType baudRate() const;
+    virtual void setDataBits(DataBitsType)=0;
+    virtual DataBitsType dataBits() const;
+    virtual void setParity(ParityType)=0;
+    virtual ParityType parity() const;
+    virtual void setStopBits(StopBitsType)=0;
+    virtual StopBitsType stopBits() const;
+    virtual void setFlowControl(FlowType)=0;
+    virtual FlowType flowControl() const;
+    virtual void setTimeout(ulong, ulong)=0;
+
+    virtual bool open(OpenMode mode=0)=0;
+    virtual bool isSequential() const;
+    virtual void close()=0;
+    virtual void flush()=0;
+
+    virtual qint64 size() const=0;
+    virtual qint64 bytesAvailable()=0;
+    virtual bool atEnd() const;
+
+    virtual void ungetChar(char c)=0;
+    virtual qint64 readLine(char * data, qint64 maxSize);
+
+    virtual ulong lastError() const;
+    virtual void translateError(ulong error)=0;
+
+    virtual void setDtr(bool set=true)=0;
+    virtual void setRts(bool set=true)=0;
+    virtual ulong lineStatus()=0;
+
+protected:
+    QString port;
+    PortSettings Settings;
+    ulong lastErr;
+
+#ifdef QT_THREAD_SUPPORT
+    static QMutex* mutex;
+    static ulong refCount;
+#endif
+
+    virtual qint64 readData(char * data, qint64 maxSize)=0;
+    virtual qint64 writeData(const char * data, qint64 maxSize)=0;
+
+};
+
+#endif
Index: /trunk/BNC/src/serial/qextserialport.cpp
===================================================================
--- /trunk/BNC/src/serial/qextserialport.cpp	(revision 4283)
+++ /trunk/BNC/src/serial/qextserialport.cpp	(revision 4283)
@@ -0,0 +1,98 @@
+
+/*!
+\class QextSerialPort
+\version 1.0.0
+\author Stefan Sander
+
+A cross-platform serial port class.
+This class encapsulates a serial port on both POSIX and Windows systems.  The user will be
+notified of errors and possible portability conflicts at run-time by default - this behavior can
+be turned off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn
+off portability warnings) in the project.
+
+\note
+On Windows NT/2000/XP this class uses Win32 serial port functions by default.  The user may
+select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can
+make no guarantees as to the quality of POSIX support under NT/2000 however.
+
+*/
+
+#include <stdio.h>
+#include "qextserialport.h"
+
+/*!
+\fn QextSerialPort::QextSerialPort()
+Default constructor.  Note that the naming convention used by a QextSerialPort constructed with
+this constructor will be determined by #defined constants, or lack thereof - the default behavior
+is the same as _TTY_LINUX_.  Possible naming conventions and their associated constants are:
+
+\verbatim
+
+Constant         Used By         Naming Convention
+----------       -------------   ------------------------
+_TTY_WIN_        Windows         COM1, COM2
+_TTY_IRIX_       SGI/IRIX        /dev/ttyf1, /dev/ttyf2
+_TTY_HPUX_       HP-UX           /dev/tty1p0, /dev/tty2p0
+_TTY_SUN_        SunOS/Solaris   /dev/ttya, /dev/ttyb
+_TTY_DIGITAL_    Digital UNIX    /dev/tty01, /dev/tty02
+_TTY_FREEBSD_    FreeBSD         /dev/ttyd0, /dev/ttyd1
+_TTY_LINUX_      Linux           /dev/ttyS0, /dev/ttyS1
+<none>           Linux           /dev/ttyS0, /dev/ttyS1
+\endverbatim
+
+The object will be associated with the first port in the system, e.g. COM1 on Windows systems.
+See the other constructors if you need to use a port other than the first.
+*/
+QextSerialPort::QextSerialPort()
+ : QextBaseType()
+{}
+
+/*!
+\fn QextSerialPort::QextSerialPort(const QString & name)
+Constructs a serial port attached to the port specified by name.
+name is the name of the device, which is windowsystem-specific,
+e.g."COM1" or "/dev/ttyS0".
+*/
+QextSerialPort::QextSerialPort(const QString & name)
+ : QextBaseType(name)
+{}
+
+/*!
+\fn QextSerialPort::QextSerialPort(PortSettings const& settings)
+Constructs a port with default name and settings specified by the settings parameter.
+*/
+QextSerialPort::QextSerialPort(PortSettings const& settings)
+ : QextBaseType(settings)
+{}
+
+/*!
+\fn QextSerialPort::QextSerialPort(const QString & name, PortSettings const& settings)
+Constructs a port with the name and settings specified.
+*/
+QextSerialPort::QextSerialPort(const QString & name, PortSettings const& settings)
+ : QextBaseType(name, settings)
+{}
+
+/*!
+\fn QextSerialPort::QextSerialPort(const QextSerialPort& s)
+Copy constructor.
+*/
+QextSerialPort::QextSerialPort(const QextSerialPort& s)
+ : QextBaseType(s)
+{}
+
+/*!
+\fn QextSerialPort& QextSerialPort::operator=(const QextSerialPort& s)
+Overrides the = operator.
+*/
+QextSerialPort& QextSerialPort::operator=(const QextSerialPort& s)
+{
+    return (QextSerialPort&)QextBaseType::operator=(s);
+}
+
+/*!
+\fn QextSerialPort::~QextSerialPort()
+Standard destructor.
+*/
+QextSerialPort::~QextSerialPort()
+{}
Index: /trunk/BNC/src/serial/qextserialport.h
===================================================================
--- /trunk/BNC/src/serial/qextserialport.h	(revision 4283)
+++ /trunk/BNC/src/serial/qextserialport.h	(revision 4283)
@@ -0,0 +1,27 @@
+
+#ifndef _QEXTSERIALPORT_H_
+#define _QEXTSERIALPORT_H_
+
+/*POSIX CODE*/
+#ifdef _TTY_POSIX_
+#include "posix_qextserialport.h"
+#define QextBaseType Posix_QextSerialPort
+
+/*MS WINDOWS CODE*/
+#else
+#include "win_qextserialport.h"
+#define QextBaseType Win_QextSerialPort
+#endif
+
+class QextSerialPort: public QextBaseType {
+public:
+    QextSerialPort();
+    QextSerialPort(const QString & name);
+    QextSerialPort(PortSettings const& s);
+    QextSerialPort(const QString & name, PortSettings const& s);
+    QextSerialPort(const QextSerialPort& s);
+    QextSerialPort& operator=(const QextSerialPort&);
+    virtual ~QextSerialPort();
+};
+
+#endif
Index: /trunk/BNC/src/serial/win_qextserialport.cpp
===================================================================
--- /trunk/BNC/src/serial/win_qextserialport.cpp	(revision 4283)
+++ /trunk/BNC/src/serial/win_qextserialport.cpp	(revision 4283)
@@ -0,0 +1,877 @@
+/*!
+\class Win_QextSerialPort
+\version 1.0.0
+\author Stefan Sander
+
+A cross-platform serial port class.
+This class encapsulates the Windows portion of QextSerialPort.  The user will be notified of
+errors and possible portability conflicts at run-time by default - this behavior can be turned
+off by defining _TTY_NOWARN_ (to turn off all warnings) or _TTY_NOWARN_PORT_ (to turn off
+portability warnings) in the project.  Note that defining _TTY_NOWARN_ also defines
+_TTY_NOWARN_PORT_.
+
+\note
+On Windows NT/2000/XP this class uses Win32 serial port functions by default.  The user may
+select POSIX behavior under NT, 2000, or XP ONLY by defining _TTY_POSIX_ in the project. I can
+make no guarantees as to the quality of POSIX support under NT/2000 however.
+
+*/
+
+#include <stdio.h>
+#include "win_qextserialport.h"
+
+/*!
+\fn Win_QextSerialPort::Win_QextSerialPort()
+Default constructor.  Note that the name of the device used by a Win_QextSerialPort constructed
+with this constructor will be determined by #defined constants, or lack thereof - the default
+behavior is the same as _TTY_LINUX_.  Possible naming conventions and their associated constants
+are:
+
+\verbatim
+
+Constant         Used By         Naming Convention
+----------       -------------   ------------------------
+_TTY_WIN_        Windows         COM1, COM2
+_TTY_IRIX_       SGI/IRIX        /dev/ttyf1, /dev/ttyf2
+_TTY_HPUX_       HP-UX           /dev/tty1p0, /dev/tty2p0
+_TTY_SUN_        SunOS/Solaris   /dev/ttya, /dev/ttyb
+_TTY_DIGITAL_    Digital UNIX    /dev/tty01, /dev/tty02
+_TTY_FREEBSD_    FreeBSD         /dev/ttyd0, /dev/ttyd1
+_TTY_LINUX_      Linux           /dev/ttyS0, /dev/ttyS1
+<none>           Linux           /dev/ttyS0, /dev/ttyS1
+\endverbatim
+
+This constructor associates the object with the first port on the system, e.g. COM1 for Windows
+platforms.  See the other constructor if you need a port other than the first.
+*/
+Win_QextSerialPort::Win_QextSerialPort():QextSerialBase() {
+    Win_Handle=INVALID_HANDLE_VALUE;
+}
+
+/*!Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort&)
+Copy constructor.
+*/
+Win_QextSerialPort::Win_QextSerialPort(const Win_QextSerialPort& s):QextSerialBase(s.port) {
+    Win_Handle=INVALID_HANDLE_VALUE;
+    setOpenMode(s.openMode());
+    lastErr=s.lastErr;
+    port = s.port;
+    Settings.FlowControl=s.Settings.FlowControl;
+    Settings.Parity=s.Settings.Parity;
+    Settings.DataBits=s.Settings.DataBits;
+    Settings.StopBits=s.Settings.StopBits;
+    Settings.BaudRate=s.Settings.BaudRate;
+    Win_Handle=s.Win_Handle;
+    memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG));
+    memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS));
+}
+
+/*!
+\fn Win_QextSerialPort::Win_QextSerialPort(const QString & name)
+Constructs a serial port attached to the port specified by devName.
+devName is the name of the device, which is windowsystem-specific,
+e.g."COM2" or "/dev/ttyS0".
+*/
+Win_QextSerialPort::Win_QextSerialPort(const QString & name):QextSerialBase(name) {
+    Win_Handle=INVALID_HANDLE_VALUE;
+}
+
+/*!
+\fn Win_QextSerialPort::Win_QextSerialPort(const PortSettings& settings)
+Constructs a port with default name and specified settings.
+*/
+Win_QextSerialPort::Win_QextSerialPort(const PortSettings& settings) {
+    Win_Handle=INVALID_HANDLE_VALUE;
+    setBaudRate(settings.BaudRate);
+    setDataBits(settings.DataBits);
+    setStopBits(settings.StopBits);
+    setParity(settings.Parity);
+    setFlowControl(settings.FlowControl);
+    setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec);
+}
+
+/*!
+\fn Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings)
+Constructs a port with specified name and settings.
+*/
+Win_QextSerialPort::Win_QextSerialPort(const QString & name, const PortSettings& settings) {
+    Win_Handle=INVALID_HANDLE_VALUE;
+    setPortName(name);
+    setBaudRate(settings.BaudRate);
+    setDataBits(settings.DataBits);
+    setStopBits(settings.StopBits);
+    setParity(settings.Parity);
+    setFlowControl(settings.FlowControl);
+    setTimeout(settings.Timeout_Sec, settings.Timeout_Millisec);
+}
+
+/*!
+\fn Win_QextSerialPort::~Win_QextSerialPort()
+Standard destructor.
+*/
+Win_QextSerialPort::~Win_QextSerialPort() {
+    if (isOpen()) {
+        close();
+    }
+}
+
+/*!
+\fn Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s)
+overrides the = operator
+*/
+Win_QextSerialPort& Win_QextSerialPort::operator=(const Win_QextSerialPort& s) {
+    setOpenMode(s.openMode());
+    lastErr=s.lastErr;
+    port = s.port;
+    Settings.FlowControl=s.Settings.FlowControl;
+    Settings.Parity=s.Settings.Parity;
+    Settings.DataBits=s.Settings.DataBits;
+    Settings.StopBits=s.Settings.StopBits;
+    Settings.BaudRate=s.Settings.BaudRate;
+    Win_Handle=s.Win_Handle;
+    memcpy(&Win_CommConfig, &s.Win_CommConfig, sizeof(COMMCONFIG));
+    memcpy(&Win_CommTimeouts, &s.Win_CommTimeouts, sizeof(COMMTIMEOUTS));
+    return *this;
+}
+
+/*!
+\fn bool Win_QextSerialPort::open(OpenMode mode)
+Opens a serial port.  Note that this function does not specify which device to open.  If you need
+to open a device by name, see Win_QextSerialPort::open(const char*).  This function has no effect
+if the port associated with the class is already open.  The port is also configured to the current
+settings, as stored in the Settings structure.
+*/
+bool Win_QextSerialPort::open(OpenMode mode) {
+    unsigned long confSize = sizeof(COMMCONFIG);
+    Win_CommConfig.dwSize = confSize;
+
+    LOCK_MUTEX();
+    if (mode == QIODevice::NotOpen)
+        return isOpen();
+    if (!isOpen()) {
+        /*open the port*/
+        Win_Handle=CreateFileA(port.toAscii(), GENERIC_READ|GENERIC_WRITE,
+                              FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+        if (Win_Handle!=INVALID_HANDLE_VALUE) {
+            /*set open mode*/
+            QIODevice::open(mode);
+
+            /*configure port settings*/
+            GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);
+            GetCommState(Win_Handle, &(Win_CommConfig.dcb));
+
+            /*set up parameters*/
+            Win_CommConfig.dcb.fBinary=TRUE;
+            Win_CommConfig.dcb.fInX=FALSE;
+            Win_CommConfig.dcb.fOutX=FALSE;
+            Win_CommConfig.dcb.fAbortOnError=FALSE;
+            Win_CommConfig.dcb.fNull=FALSE;
+            setBaudRate(Settings.BaudRate);
+            setDataBits(Settings.DataBits);
+            setStopBits(Settings.StopBits);
+            setParity(Settings.Parity);
+            setFlowControl(Settings.FlowControl);
+            setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec);
+            SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+        }
+    }
+    UNLOCK_MUTEX();
+    return isOpen();
+}
+
+/*!
+\fn void Win_QextSerialPort::close()
+Closes a serial port.  This function has no effect if the serial port associated with the class
+is not currently open.
+*/
+void Win_QextSerialPort::close() {
+    LOCK_MUTEX();
+    CloseHandle(Win_Handle);
+    QIODevice::close();
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Win_QextSerialPort::flush()
+Flushes all pending I/O to the serial port.  This function has no effect if the serial port
+associated with the class is not currently open.
+*/
+void Win_QextSerialPort::flush() {
+    LOCK_MUTEX();
+    if (isOpen()) {
+        FlushFileBuffers(Win_Handle);
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn qint64 Win_QextSerialPort::size() const
+This function will return the number of bytes waiting in the receive queue of the serial port.
+It is included primarily to provide a complete QIODevice interface, and will not record errors
+in the lastErr member (because it is const).  This function is also not thread-safe - in
+multithreading situations, use Win_QextSerialPort::bytesAvailable() instead.
+*/
+qint64 Win_QextSerialPort::size() const {
+    int availBytes;
+    COMSTAT Win_ComStat;
+    DWORD Win_ErrorMask=0;
+    ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat);
+    availBytes = Win_ComStat.cbInQue;
+    return (qint64)availBytes;
+}
+
+/*!
+\fn qint64 Win_QextSerialPort::bytesAvailable()
+Returns the number of bytes waiting in the port's receive queue.  This function will return 0 if
+the port is not currently open, or -1 on error.  Error information can be retrieved by calling
+Win_QextSerialPort::getLastError().
+*/
+qint64 Win_QextSerialPort::bytesAvailable() {
+    LOCK_MUTEX();
+    if (isOpen()) {
+        DWORD Errors;
+        COMSTAT Status;
+        bool success=ClearCommError(Win_Handle, &Errors, &Status);
+        translateError(Errors);
+        if (success) {
+            lastErr=E_NO_ERROR;
+            UNLOCK_MUTEX();
+            return Status.cbInQue + QIODevice::bytesAvailable();
+        }
+        UNLOCK_MUTEX();
+        return (unsigned int)-1;
+    }
+    UNLOCK_MUTEX();
+    return 0;
+}
+
+/*!
+\fn void Win_QextSerialPort::translateError(ulong error)
+Translates a system-specific error code to a QextSerialPort error code.  Used internally.
+*/
+void Win_QextSerialPort::translateError(ulong error) {
+    if (error&CE_BREAK) {
+        lastErr=E_BREAK_CONDITION;
+    }
+    else if (error&CE_FRAME) {
+        lastErr=E_FRAMING_ERROR;
+    }
+    else if (error&CE_IOE) {
+        lastErr=E_IO_ERROR;
+    }
+    else if (error&CE_MODE) {
+        lastErr=E_INVALID_FD;
+    }
+    else if (error&CE_OVERRUN) {
+        lastErr=E_BUFFER_OVERRUN;
+    }
+    else if (error&CE_RXPARITY) {
+        lastErr=E_RECEIVE_PARITY_ERROR;
+    }
+    else if (error&CE_RXOVER) {
+        lastErr=E_RECEIVE_OVERFLOW;
+    }
+    else if (error&CE_TXFULL) {
+        lastErr=E_TRANSMIT_OVERFLOW;
+    }
+}
+
+/*!
+\fn qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
+Reads a block of data from the serial port.  This function will read at most maxlen bytes from
+the serial port and place them in the buffer pointed to by data.  Return value is the number of
+bytes actually read, or -1 on error.
+
+\warning before calling this function ensure that serial port associated with this class
+is currently open (use isOpen() function to check if port is open).
+*/
+qint64 Win_QextSerialPort::readData(char *data, qint64 maxSize)
+{
+    LOCK_MUTEX();
+    int retVal=0;
+    COMSTAT Win_ComStat;
+    DWORD Win_BytesRead=0;
+    DWORD Win_ErrorMask=0;
+    ClearCommError(Win_Handle, &Win_ErrorMask, &Win_ComStat);
+    if (Win_ComStat.cbInQue &&
+        (!ReadFile(Win_Handle, (void*)data, (DWORD)maxSize, &Win_BytesRead, NULL)
+        || Win_BytesRead==0)) {
+        lastErr=E_READ_FAILED;
+        retVal=-1;
+    }
+    else {
+        retVal=((int)Win_BytesRead);
+    }
+    UNLOCK_MUTEX();
+
+    return retVal;
+}
+
+/*!
+\fn qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
+Writes a block of data to the serial port.  This function will write len bytes
+from the buffer pointed to by data to the serial port.  Return value is the number
+of bytes actually written, or -1 on error.
+
+\warning before calling this function ensure that serial port associated with this class
+is currently open (use isOpen() function to check if port is open).
+*/
+qint64 Win_QextSerialPort::writeData(const char *data, qint64 maxSize)
+{
+    LOCK_MUTEX();
+    int retVal=0;
+    DWORD Win_BytesWritten;
+    if (!WriteFile(Win_Handle, (void*)data, (DWORD)maxSize, &Win_BytesWritten, NULL)) {
+        lastErr=E_WRITE_FAILED;
+        retVal=-1;
+    }
+    else {
+        retVal=((int)Win_BytesWritten);
+    }
+    UNLOCK_MUTEX();
+
+    flush();
+    return retVal;
+}
+
+/*!
+\fn void Win_QextSerialPort::ungetChar(char c)
+This function is included to implement the full QIODevice interface, and currently has no
+purpose within this class.  This function is meaningless on an unbuffered device and currently
+only prints a warning message to that effect.
+*/
+void Win_QextSerialPort::ungetChar(char c) {
+
+    /*meaningless on unbuffered sequential device - return error and print a warning*/
+    TTY_WARNING("Win_QextSerialPort: ungetChar() called on an unbuffered sequential device - operation is meaningless");
+}
+
+/*!
+\fn void Win_QextSerialPort::setFlowControl(FlowType flow)
+Sets the flow control used by the port.  Possible values of flow are:
+\verbatim
+    FLOW_OFF            No flow control
+    FLOW_HARDWARE       Hardware (RTS/CTS) flow control
+    FLOW_XONXOFF        Software (XON/XOFF) flow control
+\endverbatim
+*/
+void Win_QextSerialPort::setFlowControl(FlowType flow) {
+    LOCK_MUTEX();
+    if (Settings.FlowControl!=flow) {
+        Settings.FlowControl=flow;
+    }
+    if (isOpen()) {
+        switch(flow) {
+
+            /*no flow control*/
+            case FLOW_OFF:
+                Win_CommConfig.dcb.fOutxCtsFlow=FALSE;
+                Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
+                Win_CommConfig.dcb.fInX=FALSE;
+                Win_CommConfig.dcb.fOutX=FALSE;
+                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+                break;
+
+            /*software (XON/XOFF) flow control*/
+            case FLOW_XONXOFF:
+                Win_CommConfig.dcb.fOutxCtsFlow=FALSE;
+                Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_DISABLE;
+                Win_CommConfig.dcb.fInX=TRUE;
+                Win_CommConfig.dcb.fOutX=TRUE;
+                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+                break;
+
+            case FLOW_HARDWARE:
+                Win_CommConfig.dcb.fOutxCtsFlow=TRUE;
+                Win_CommConfig.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE;
+                Win_CommConfig.dcb.fInX=FALSE;
+                Win_CommConfig.dcb.fOutX=FALSE;
+                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+                break;
+        }
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Win_QextSerialPort::setParity(ParityType parity)
+Sets the parity associated with the serial port.  The possible values of parity are:
+\verbatim
+    PAR_SPACE       Space Parity
+    PAR_MARK        Mark Parity
+    PAR_NONE        No Parity
+    PAR_EVEN        Even Parity
+    PAR_ODD         Odd Parity
+\endverbatim
+*/
+void Win_QextSerialPort::setParity(ParityType parity) {
+    LOCK_MUTEX();
+    if (Settings.Parity!=parity) {
+        Settings.Parity=parity;
+    }
+    if (isOpen()) {
+        Win_CommConfig.dcb.Parity=(unsigned char)parity;
+        switch (parity) {
+
+            /*space parity*/
+            case PAR_SPACE:
+                if (Settings.DataBits==DATA_8) {
+                    TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: Space parity with 8 data bits is not supported by POSIX systems.");
+                }
+                Win_CommConfig.dcb.fParity=TRUE;
+                break;
+
+            /*mark parity - WINDOWS ONLY*/
+            case PAR_MARK:
+                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning:  Mark parity is not supported by POSIX systems");
+                Win_CommConfig.dcb.fParity=TRUE;
+                break;
+
+            /*no parity*/
+            case PAR_NONE:
+                Win_CommConfig.dcb.fParity=FALSE;
+                break;
+
+            /*even parity*/
+            case PAR_EVEN:
+                Win_CommConfig.dcb.fParity=TRUE;
+                break;
+
+            /*odd parity*/
+            case PAR_ODD:
+                Win_CommConfig.dcb.fParity=TRUE;
+                break;
+        }
+        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Win_QextSerialPort::setDataBits(DataBitsType dataBits)
+Sets the number of data bits used by the serial port.  Possible values of dataBits are:
+\verbatim
+    DATA_5      5 data bits
+    DATA_6      6 data bits
+    DATA_7      7 data bits
+    DATA_8      8 data bits
+\endverbatim
+
+\note
+This function is subject to the following restrictions:
+\par
+    5 data bits cannot be used with 2 stop bits.
+\par
+    1.5 stop bits can only be used with 5 data bits.
+\par
+    8 data bits cannot be used with space parity on POSIX systems.
+
+*/
+void Win_QextSerialPort::setDataBits(DataBitsType dataBits) {
+    LOCK_MUTEX();
+    if (Settings.DataBits!=dataBits) {
+        if ((Settings.StopBits==STOP_2 && dataBits==DATA_5) ||
+            (Settings.StopBits==STOP_1_5 && dataBits!=DATA_5)) {
+        }
+        else {
+            Settings.DataBits=dataBits;
+        }
+    }
+    if (isOpen()) {
+        switch(dataBits) {
+
+            /*5 data bits*/
+            case DATA_5:
+                if (Settings.StopBits==STOP_2) {
+                    TTY_WARNING("Win_QextSerialPort: 5 Data bits cannot be used with 2 stop bits.");
+                }
+                else {
+                    Win_CommConfig.dcb.ByteSize=5;
+                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+                }
+                break;
+
+            /*6 data bits*/
+            case DATA_6:
+                if (Settings.StopBits==STOP_1_5) {
+                    TTY_WARNING("Win_QextSerialPort: 6 Data bits cannot be used with 1.5 stop bits.");
+                }
+                else {
+                    Win_CommConfig.dcb.ByteSize=6;
+                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+                }
+                break;
+
+            /*7 data bits*/
+            case DATA_7:
+                if (Settings.StopBits==STOP_1_5) {
+                    TTY_WARNING("Win_QextSerialPort: 7 Data bits cannot be used with 1.5 stop bits.");
+                }
+                else {
+                    Win_CommConfig.dcb.ByteSize=7;
+                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+                }
+                break;
+
+            /*8 data bits*/
+            case DATA_8:
+                if (Settings.StopBits==STOP_1_5) {
+                    TTY_WARNING("Win_QextSerialPort: 8 Data bits cannot be used with 1.5 stop bits.");
+                }
+                else {
+                    Win_CommConfig.dcb.ByteSize=8;
+                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+                }
+                break;
+        }
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Win_QextSerialPort::setStopBits(StopBitsType stopBits)
+Sets the number of stop bits used by the serial port.  Possible values of stopBits are:
+\verbatim
+    STOP_1      1 stop bit
+    STOP_1_5    1.5 stop bits
+    STOP_2      2 stop bits
+\endverbatim
+
+\note
+This function is subject to the following restrictions:
+\par
+    2 stop bits cannot be used with 5 data bits.
+\par
+    1.5 stop bits cannot be used with 6 or more data bits.
+\par
+    POSIX does not support 1.5 stop bits.
+*/
+void Win_QextSerialPort::setStopBits(StopBitsType stopBits) {
+    LOCK_MUTEX();
+    if (Settings.StopBits!=stopBits) {
+        if ((Settings.DataBits==DATA_5 && stopBits==STOP_2) ||
+            (stopBits==STOP_1_5 && Settings.DataBits!=DATA_5)) {
+        }
+        else {
+            Settings.StopBits=stopBits;
+        }
+    }
+    if (isOpen()) {
+        switch (stopBits) {
+
+            /*one stop bit*/
+            case STOP_1:
+                Win_CommConfig.dcb.StopBits=ONESTOPBIT;
+                SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+                break;
+
+            /*1.5 stop bits*/
+            case STOP_1_5:
+                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: 1.5 stop bit operation is not supported by POSIX.");
+                if (Settings.DataBits!=DATA_5) {
+                    TTY_WARNING("Win_QextSerialPort: 1.5 stop bits can only be used with 5 data bits");
+                }
+                else {
+                    Win_CommConfig.dcb.StopBits=ONE5STOPBITS;
+                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+                }
+                break;
+
+            /*two stop bits*/
+            case STOP_2:
+                if (Settings.DataBits==DATA_5) {
+                    TTY_WARNING("Win_QextSerialPort: 2 stop bits cannot be used with 5 data bits");
+                }
+                else {
+                    Win_CommConfig.dcb.StopBits=TWOSTOPBITS;
+                    SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+                }
+                break;
+        }
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Win_QextSerialPort::setBaudRate(BaudRateType baudRate)
+Sets the baud rate of the serial port.  Note that not all rates are applicable on
+all platforms.  The following table shows translations of the various baud rate
+constants on Windows(including NT/2000) and POSIX platforms.  Speeds marked with an *
+are speeds that are usable on both Windows and POSIX.
+\verbatim
+
+  RATE          Windows Speed   POSIX Speed
+  -----------   -------------   -----------
+   BAUD50                 110          50
+   BAUD75                 110          75
+  *BAUD110                110         110
+   BAUD134                110         134.5
+   BAUD150                110         150
+   BAUD200                110         200
+  *BAUD300                300         300
+  *BAUD600                600         600
+  *BAUD1200              1200        1200
+   BAUD1800              1200        1800
+  *BAUD2400              2400        2400
+  *BAUD4800              4800        4800
+  *BAUD9600              9600        9600
+   BAUD14400            14400        9600
+  *BAUD19200            19200       19200
+  *BAUD38400            38400       38400
+   BAUD56000            56000       38400
+  *BAUD57600            57600       57600
+   BAUD76800            57600       76800
+  *BAUD115200          115200      115200
+   BAUD128000          128000      115200
+   BAUD256000          256000      115200
+\endverbatim
+*/
+void Win_QextSerialPort::setBaudRate(BaudRateType baudRate) {
+    LOCK_MUTEX();
+    if (Settings.BaudRate!=baudRate) {
+        switch (baudRate) {
+            case BAUD50:
+            case BAUD75:
+            case BAUD134:
+            case BAUD150:
+            case BAUD200:
+                Settings.BaudRate=BAUD110;
+                break;
+
+            case BAUD1800:
+                Settings.BaudRate=BAUD1200;
+                break;
+
+            case BAUD76800:
+                Settings.BaudRate=BAUD57600;
+                break;
+
+            default:
+                Settings.BaudRate=baudRate;
+                break;
+        }
+    }
+    if (isOpen()) {
+        switch (baudRate) {
+
+            /*50 baud*/
+            case BAUD50:
+                TTY_WARNING("Win_QextSerialPort: Windows does not support 50 baud operation.  Switching to 110 baud.");
+                Win_CommConfig.dcb.BaudRate=CBR_110;
+                break;
+
+            /*75 baud*/
+            case BAUD75:
+                TTY_WARNING("Win_QextSerialPort: Windows does not support 75 baud operation.  Switching to 110 baud.");
+                Win_CommConfig.dcb.BaudRate=CBR_110;
+                break;
+
+            /*110 baud*/
+            case BAUD110:
+                Win_CommConfig.dcb.BaudRate=CBR_110;
+                break;
+
+            /*134.5 baud*/
+            case BAUD134:
+                TTY_WARNING("Win_QextSerialPort: Windows does not support 134.5 baud operation.  Switching to 110 baud.");
+                Win_CommConfig.dcb.BaudRate=CBR_110;
+                break;
+
+            /*150 baud*/
+            case BAUD150:
+                TTY_WARNING("Win_QextSerialPort: Windows does not support 150 baud operation.  Switching to 110 baud.");
+                Win_CommConfig.dcb.BaudRate=CBR_110;
+                break;
+
+            /*200 baud*/
+            case BAUD200:
+                TTY_WARNING("Win_QextSerialPort: Windows does not support 200 baud operation.  Switching to 110 baud.");
+                Win_CommConfig.dcb.BaudRate=CBR_110;
+                break;
+
+            /*300 baud*/
+            case BAUD300:
+                Win_CommConfig.dcb.BaudRate=CBR_300;
+                break;
+
+            /*600 baud*/
+            case BAUD600:
+                Win_CommConfig.dcb.BaudRate=CBR_600;
+                break;
+
+            /*1200 baud*/
+            case BAUD1200:
+                Win_CommConfig.dcb.BaudRate=CBR_1200;
+                break;
+
+            /*1800 baud*/
+            case BAUD1800:
+                TTY_WARNING("Win_QextSerialPort: Windows does not support 1800 baud operation.  Switching to 1200 baud.");
+                Win_CommConfig.dcb.BaudRate=CBR_1200;
+                break;
+
+            /*2400 baud*/
+            case BAUD2400:
+                Win_CommConfig.dcb.BaudRate=CBR_2400;
+                break;
+
+            /*4800 baud*/
+            case BAUD4800:
+                Win_CommConfig.dcb.BaudRate=CBR_4800;
+                break;
+
+            /*9600 baud*/
+            case BAUD9600:
+                Win_CommConfig.dcb.BaudRate=CBR_9600;
+                break;
+
+            /*14400 baud*/
+            case BAUD14400:
+                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 14400 baud operation.");
+                Win_CommConfig.dcb.BaudRate=CBR_14400;
+                break;
+
+            /*19200 baud*/
+            case BAUD19200:
+                Win_CommConfig.dcb.BaudRate=CBR_19200;
+                break;
+
+            /*38400 baud*/
+            case BAUD38400:
+                Win_CommConfig.dcb.BaudRate=CBR_38400;
+                break;
+
+            /*56000 baud*/
+            case BAUD56000:
+                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 56000 baud operation.");
+                Win_CommConfig.dcb.BaudRate=CBR_56000;
+                break;
+
+            /*57600 baud*/
+            case BAUD57600:
+                Win_CommConfig.dcb.BaudRate=CBR_57600;
+                break;
+
+            /*76800 baud*/
+            case BAUD76800:
+                TTY_WARNING("Win_QextSerialPort: Windows does not support 76800 baud operation.  Switching to 57600 baud.");
+                Win_CommConfig.dcb.BaudRate=CBR_57600;
+                break;
+
+            /*115200 baud*/
+            case BAUD115200:
+                Win_CommConfig.dcb.BaudRate=CBR_115200;
+                break;
+
+            /*128000 baud*/
+            case BAUD128000:
+                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 128000 baud operation.");
+                Win_CommConfig.dcb.BaudRate=CBR_128000;
+                break;
+
+            /*256000 baud*/
+            case BAUD256000:
+                TTY_PORTABILITY_WARNING("Win_QextSerialPort Portability Warning: POSIX does not support 256000 baud operation.");
+                Win_CommConfig.dcb.BaudRate=CBR_256000;
+                break;
+        }
+        SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Win_QextSerialPort::setDtr(bool set)
+Sets DTR line to the requested state (high by default).  This function will have no effect if
+the port associated with the class is not currently open.
+*/
+void Win_QextSerialPort::setDtr(bool set) {
+    LOCK_MUTEX();
+    if (isOpen()) {
+        if (set) {
+            EscapeCommFunction(Win_Handle, SETDTR);
+        }
+        else {
+            EscapeCommFunction(Win_Handle, CLRDTR);
+        }
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn void Win_QextSerialPort::setRts(bool set)
+Sets RTS line to the requested state (high by default).  This function will have no effect if
+the port associated with the class is not currently open.
+*/
+void Win_QextSerialPort::setRts(bool set) {
+    LOCK_MUTEX();
+    if (isOpen()) {
+        if (set) {
+            EscapeCommFunction(Win_Handle, SETRTS);
+        }
+        else {
+            EscapeCommFunction(Win_Handle, CLRRTS);
+        }
+    }
+    UNLOCK_MUTEX();
+}
+
+/*!
+\fn ulong Win_QextSerialPort::lineStatus(void)
+returns the line status as stored by the port function.  This function will retrieve the states
+of the following lines: DCD, CTS, DSR, and RI.  On POSIX systems, the following additional lines
+can be monitored: DTR, RTS, Secondary TXD, and Secondary RXD.  The value returned is an unsigned
+long with specific bits indicating which lines are high.  The following constants should be used
+to examine the states of individual lines:
+
+\verbatim
+Mask        Line
+------      ----
+LS_CTS      CTS
+LS_DSR      DSR
+LS_DCD      DCD
+LS_RI       RI
+\endverbatim
+
+This function will return 0 if the port associated with the class is not currently open.
+*/
+ulong Win_QextSerialPort::lineStatus(void) {
+    unsigned long Status=0, Temp=0;
+    LOCK_MUTEX();
+    if (isOpen()) {
+        GetCommModemStatus(Win_Handle, &Temp);
+        if (Temp&MS_CTS_ON) {
+            Status|=LS_CTS;
+        }
+        if (Temp&MS_DSR_ON) {
+            Status|=LS_DSR;
+        }
+        if (Temp&MS_RING_ON) {
+            Status|=LS_RI;
+        }
+        if (Temp&MS_RLSD_ON) {
+            Status|=LS_DCD;
+        }
+    }
+    UNLOCK_MUTEX();
+    return Status;
+}
+
+/*!
+\fn void Win_QextSerialPort::setTimeout(ulong sec, ulong millisec);
+Sets the read and write timeouts for the port to sec seconds and millisec milliseconds.
+*/
+void Win_QextSerialPort::setTimeout(ulong sec, ulong millisec) {
+    LOCK_MUTEX();
+    Settings.Timeout_Sec=sec;
+    Settings.Timeout_Millisec=millisec;
+    if(isOpen()) {
+        Win_CommTimeouts.ReadIntervalTimeout = sec*1000+millisec;
+        Win_CommTimeouts.ReadTotalTimeoutMultiplier = sec*1000+millisec;
+        Win_CommTimeouts.ReadTotalTimeoutConstant = 0;
+        Win_CommTimeouts.WriteTotalTimeoutMultiplier = sec*1000+millisec;
+        Win_CommTimeouts.WriteTotalTimeoutConstant = 0;
+        SetCommTimeouts(Win_Handle, &Win_CommTimeouts);
+    }
+    UNLOCK_MUTEX();
+}
Index: /trunk/BNC/src/serial/win_qextserialport.h
===================================================================
--- /trunk/BNC/src/serial/win_qextserialport.h	(revision 4283)
+++ /trunk/BNC/src/serial/win_qextserialport.h	(revision 4283)
@@ -0,0 +1,48 @@
+#ifndef _WIN_QEXTSERIALPORT_H_
+#define _WIN_QEXTSERIALPORT_H_
+
+#include "qextserialbase.h"
+
+/*if all warning messages are turned off, flag portability warnings to be turned off as well*/
+#ifdef _TTY_NOWARN_
+#define _TTY_NOWARN_PORT_
+#endif
+
+#include <windows.h>
+
+class Win_QextSerialPort:public QextSerialBase {
+public:
+    Win_QextSerialPort();
+    Win_QextSerialPort(Win_QextSerialPort const& s);
+    Win_QextSerialPort(const QString & name);
+    Win_QextSerialPort(const PortSettings& settings);
+    Win_QextSerialPort(const QString & name, const PortSettings& settings);
+    Win_QextSerialPort& operator=(const Win_QextSerialPort& s);
+    virtual ~Win_QextSerialPort();
+    virtual bool open(OpenMode mode=0);
+    virtual void close();
+    virtual void flush();
+    virtual qint64 size() const;
+    virtual void ungetChar(char c);
+    virtual void setFlowControl(FlowType);
+    virtual void setParity(ParityType);
+    virtual void setDataBits(DataBitsType);
+    virtual void setStopBits(StopBitsType);
+    virtual void setBaudRate(BaudRateType);
+    virtual void setDtr(bool set=true);
+    virtual void setRts(bool set=true);
+    virtual ulong lineStatus(void);
+    virtual qint64 bytesAvailable();
+    virtual void translateError(ulong);
+    virtual void setTimeout(ulong, ulong);
+
+protected:
+    HANDLE Win_Handle;
+    COMMCONFIG Win_CommConfig;
+    COMMTIMEOUTS Win_CommTimeouts;
+
+    virtual qint64 readData(char *data, qint64 maxSize);
+    virtual qint64 writeData(const char *data, qint64 maxSize);
+};
+
+#endif
Index: /trunk/BNC/src/test_tcpip_client.pl
===================================================================
--- /trunk/BNC/src/test_tcpip_client.pl	(revision 4283)
+++ /trunk/BNC/src/test_tcpip_client.pl	(revision 4283)
@@ -0,0 +1,33 @@
+#!/usr/bin/perl -w
+
+use strict;
+use IO::Socket;
+
+# List of Parameters
+# ------------------
+my($port) = @ARGV;
+
+if (!defined($port)) {
+  die "Usage: test_tcpip_client.pl portNumber\n";
+}
+
+# Local Variables
+# ---------------
+my($serverHostName) = "localhost";
+my $server;
+
+my $retries = 10;
+while ($retries--) {
+  $server = IO::Socket::INET->new( Proto    => "tcp",
+                                   PeerAddr => $serverHostName,
+                                   PeerPort => $port);
+  last if ($server);
+}
+die "Cannot connect to $serverHostName on $port: $!" unless ($server);
+
+my $buffer;
+while (defined ($buffer = <$server>)) {
+  print $buffer;
+}
+
+
Index: /trunk/BNC/src/upload/bnccustomtrafo.cpp
===================================================================
--- /trunk/BNC/src/upload/bnccustomtrafo.cpp	(revision 4283)
+++ /trunk/BNC/src/upload/bnccustomtrafo.cpp	(revision 4283)
@@ -0,0 +1,199 @@
+/* -------------------------------------------------------------------------
+ * BKG NTRIP Server
+ * -------------------------------------------------------------------------
+ *
+ * Class:      bnccustomtrafo
+ *
+ * Purpose:    This class sets Helmert Transformation Parameters
+ *
+ * Author:     G. Weber
+ *
+ * Created:    22-Mar-2009
+ *
+ * Changes:
+ *
+ * -----------------------------------------------------------------------*/
+
+#include "bnccustomtrafo.h"
+#include "bncsettings.h"
+
+using namespace std;
+
+// Constructor
+////////////////////////////////////////////////////////////////////////////
+bncCustomTrafo::bncCustomTrafo(QWidget* parent) : QDialog(parent) {
+
+  setMinimumSize(400,150);
+  QVBoxLayout* mainLayout = new QVBoxLayout(this);
+  QGridLayout* editLayout = new QGridLayout;
+
+  setWindowTitle(tr("Custom Transformation Parameters"));
+
+ bncSettings settings;
+
+ _dxLineEdit = new QLineEdit(settings.value("trafo_dx").toString());
+ _dyLineEdit = new QLineEdit(settings.value("trafo_dy").toString());
+ _dzLineEdit = new QLineEdit(settings.value("trafo_dz").toString());
+ _dxrLineEdit = new QLineEdit(settings.value("trafo_dxr").toString());
+ _dyrLineEdit = new QLineEdit(settings.value("trafo_dyr").toString());
+ _dzrLineEdit = new QLineEdit(settings.value("trafo_dzr").toString());
+ _oxLineEdit = new QLineEdit(settings.value("trafo_ox").toString());
+ _oyLineEdit = new QLineEdit(settings.value("trafo_oy").toString());
+ _ozLineEdit = new QLineEdit(settings.value("trafo_oz").toString());
+ _oxrLineEdit = new QLineEdit(settings.value("trafo_oxr").toString());
+ _oyrLineEdit = new QLineEdit(settings.value("trafo_oyr").toString());
+ _ozrLineEdit = new QLineEdit(settings.value("trafo_ozr").toString());
+ _scLineEdit = new QLineEdit(settings.value("trafo_sc").toString());
+ _scrLineEdit = new QLineEdit(settings.value("trafo_scr").toString());
+ _t0LineEdit = new QLineEdit(settings.value("trafo_t0").toString());
+
+  // WhatsThis
+  // ---------
+  _dxLineEdit->setWhatsThis(tr("<p>Set translation in X at epoch t0.</p>"));
+  _dyLineEdit->setWhatsThis(tr("<p>Set translation in Y at epoch t0.</p>"));
+  _dzLineEdit->setWhatsThis(tr("<p>Set translation in Z at epoch t0.</p>"));
+  _dxrLineEdit->setWhatsThis(tr("<p>Set translation rate in X.</p>"));
+  _dyrLineEdit->setWhatsThis(tr("<p>Set translation rate in Y.</p>"));
+  _dzrLineEdit->setWhatsThis(tr("<p>Set translation rate in Z.</p>"));
+  _oxLineEdit->setWhatsThis(tr("<p>Set rotation in X at epoch t0.</p>"));
+  _oyLineEdit->setWhatsThis(tr("<p>Set rotation in Y at epoch t0.</p>"));
+  _ozLineEdit->setWhatsThis(tr("<p>Set rotation in Z at epoch t0.</p>"));
+  _oxrLineEdit->setWhatsThis(tr("<p>Set rotation rate in X.</p>"));
+  _oyrLineEdit->setWhatsThis(tr("<p>Set rotation rate in Y.</p>"));
+  _ozrLineEdit->setWhatsThis(tr("<p>Set rotation rate in Z.</p>"));
+  _scLineEdit->setWhatsThis(tr("<p>Set scale at epoch t0.</p>"));
+  _scrLineEdit->setWhatsThis(tr("<p>Set scale rate.</p>"));
+  _t0LineEdit->setWhatsThis(tr("<p>Set reference epoch e.g. 2000.0</p>"));
+
+  int ww = QFontMetrics(font()).width('w');
+  _dxLineEdit->setMaximumWidth(9*ww);
+  _dyLineEdit->setMaximumWidth(9*ww);
+  _dzLineEdit->setMaximumWidth(9*ww);
+  _dxrLineEdit->setMaximumWidth(9*ww);
+  _dyrLineEdit->setMaximumWidth(9*ww);
+  _dzrLineEdit->setMaximumWidth(9*ww);
+  _oxLineEdit->setMaximumWidth(9*ww);
+  _oyLineEdit->setMaximumWidth(9*ww);
+  _ozLineEdit->setMaximumWidth(9*ww);
+  _oxrLineEdit->setMaximumWidth(9*ww);
+  _oyrLineEdit->setMaximumWidth(9*ww);
+  _ozrLineEdit->setMaximumWidth(9*ww);
+  _scLineEdit->setMaximumWidth(9*ww);
+  _scrLineEdit->setMaximumWidth(9*ww);
+  _t0LineEdit->setMaximumWidth(9*ww);
+
+  editLayout->addWidget(new QLabel(tr("dX(t0) [m]")),     0, 0, Qt::AlignRight);
+  editLayout->addWidget(_dxLineEdit,                      0, 1);
+  editLayout->addWidget(new QLabel(tr("dY(t0) [m]")),     0, 2, Qt::AlignRight);
+  editLayout->addWidget(_dyLineEdit,                      0, 3);
+  editLayout->addWidget(new QLabel(tr("dZ(t0) [m]")),     0, 4, Qt::AlignRight);
+  editLayout->addWidget(_dzLineEdit,                      0, 5);
+  editLayout->addWidget(new QLabel(tr("dXr [m/y]")),      1, 0, Qt::AlignRight);
+  editLayout->addWidget(_dxrLineEdit,                     1, 1);
+  editLayout->addWidget(new QLabel(tr("dYr [m/y]")),      1, 2, Qt::AlignRight);
+  editLayout->addWidget(_dyrLineEdit,                     1, 3);
+  editLayout->addWidget(new QLabel(tr("dZr [m/y]")),      1, 4, Qt::AlignRight);
+  editLayout->addWidget(_dzrLineEdit,                     1, 5);
+  editLayout->addWidget(new QLabel(tr("   oX(t0) [as]")), 2, 0, Qt::AlignRight);
+  editLayout->addWidget(_oxLineEdit,                      2, 1);
+  editLayout->addWidget(new QLabel(tr("   oY(t0) [as]")), 2, 2, Qt::AlignRight);
+  editLayout->addWidget(_oyLineEdit,                      2, 3);
+  editLayout->addWidget(new QLabel(tr("   oZ(t0) [as]")), 2, 4, Qt::AlignRight);
+  editLayout->addWidget(_ozLineEdit,                      2, 5);
+  editLayout->addWidget(new QLabel(tr("oXr [as/y]")),     3, 0, Qt::AlignRight);
+  editLayout->addWidget(_oxrLineEdit,                     3, 1);
+  editLayout->addWidget(new QLabel(tr("oYr [as/y]")),     3, 2, Qt::AlignRight);
+  editLayout->addWidget(_oyrLineEdit,                     3, 3);
+  editLayout->addWidget(new QLabel(tr("oZr [as/y]")),     3, 4, Qt::AlignRight);
+  editLayout->addWidget(_ozrLineEdit,                     3, 5);
+  editLayout->addWidget(new QLabel(tr("S(t0) [10^-9]")),  4, 0, Qt::AlignRight);
+  editLayout->addWidget(_scLineEdit,                      4, 1);
+  editLayout->addWidget(new QLabel(tr("Sr [10^-9/y]")),   4, 2, Qt::AlignRight);
+  editLayout->addWidget(_scrLineEdit,                     4, 3);
+  editLayout->addWidget(new QLabel(tr("t0 [y]")),         4, 4, Qt::AlignRight);
+  editLayout->addWidget(_t0LineEdit,                      4, 5);
+  editLayout->addWidget(new QLabel("Specify up to 14 Helmert Transformation Parameters for transformation from IGS08"), 5, 0, 1, 6, Qt::AlignCenter);
+  editLayout->addWidget(new QLabel("into target reference system."), 6, 0, 1, 6, Qt::AlignCenter);
+
+  mainLayout->addLayout(editLayout);
+
+  _buttonWhatsThis = new QPushButton(tr("Help=Shift+F1"), this);
+  connect(_buttonWhatsThis, SIGNAL(clicked()), this, SLOT(slotWhatsThis()));
+ 
+  _buttonCancel = new QPushButton(tr("Cancel"), this);
+  connect(_buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
+
+  _buttonOK = new QPushButton(tr("OK"), this);
+  connect(_buttonOK, SIGNAL(clicked()), this, SLOT(accept()));
+
+  _buttonOK->setDefault(true);
+
+  QHBoxLayout* buttonLayout = new QHBoxLayout;
+
+  buttonLayout->addWidget(_buttonWhatsThis);
+  buttonLayout->addStretch(1);
+  buttonLayout->addWidget(_buttonCancel);
+  buttonLayout->addWidget(_buttonOK);
+
+  mainLayout->addLayout(buttonLayout);
+}
+
+// Destructor
+////////////////////////////////////////////////////////////////////////////
+bncCustomTrafo::~bncCustomTrafo() {
+  delete _buttonCancel;
+  delete _buttonOK;
+  delete _buttonWhatsThis;
+}
+
+// Accept slot
+////////////////////////////////////////////////////////////////////////////
+void bncCustomTrafo::accept() {
+
+  if ( !_dxLineEdit->text().isEmpty()  &&
+       !_dyLineEdit->text().isEmpty()  &&
+       !_dzLineEdit->text().isEmpty()  &&
+       !_dxrLineEdit->text().isEmpty() &&
+       !_dyrLineEdit->text().isEmpty() &&
+       !_dzrLineEdit->text().isEmpty() &&
+       !_oxLineEdit->text().isEmpty()  &&
+       !_oyLineEdit->text().isEmpty()  &&
+       !_ozLineEdit->text().isEmpty()  &&
+       !_oxrLineEdit->text().isEmpty() &&
+       !_oyrLineEdit->text().isEmpty() &&
+       !_ozrLineEdit->text().isEmpty() &&
+       !_scLineEdit->text().isEmpty()  &&
+       !_scrLineEdit->text().isEmpty() &&
+       !_t0LineEdit->text().isEmpty() ) {
+
+    bncSettings settings;
+    settings.setValue("trafo_dx",   _dxLineEdit->text());
+    settings.setValue("trafo_dy",   _dyLineEdit->text());
+    settings.setValue("trafo_dz",   _dzLineEdit->text());
+    settings.setValue("trafo_dxr",  _dxrLineEdit->text());
+    settings.setValue("trafo_dyr",  _dyrLineEdit->text());
+    settings.setValue("trafo_dzr",  _dzrLineEdit->text());
+    settings.setValue("trafo_ox",   _oxLineEdit->text());
+    settings.setValue("trafo_oy",   _oyLineEdit->text());
+    settings.setValue("trafo_oz",   _ozLineEdit->text());
+    settings.setValue("trafo_oxr",  _oxrLineEdit->text());
+    settings.setValue("trafo_oyr",  _oyrLineEdit->text());
+    settings.setValue("trafo_ozr",  _ozrLineEdit->text());
+    settings.setValue("trafo_sc",   _scLineEdit->text());
+    settings.setValue("trafo_scr",  _scrLineEdit->text());
+    settings.setValue("trafo_t0",   _t0LineEdit->text());
+
+  } else {
+   QMessageBox::warning(this, tr("Warning"),
+                               tr("Incomplete settings"),
+                               QMessageBox::Ok);
+  }
+
+  QDialog::accept();
+}
+
+// Whats This Help
+void bncCustomTrafo::slotWhatsThis() {
+QWhatsThis::enterWhatsThisMode();
+}
+
Index: /trunk/BNC/src/upload/bnccustomtrafo.h
===================================================================
--- /trunk/BNC/src/upload/bnccustomtrafo.h	(revision 4283)
+++ /trunk/BNC/src/upload/bnccustomtrafo.h	(revision 4283)
@@ -0,0 +1,42 @@
+#ifndef BNCCUSTOMTRAFO_H
+#define BNCCUSTOMTRAFO_H
+
+#include <QtCore>
+#include <QtGui>
+#include <QWhatsThis>
+
+class bncCustomTrafo : public QDialog {
+  Q_OBJECT
+
+  public:
+    bncCustomTrafo(QWidget* parent);
+    ~bncCustomTrafo();
+
+  private slots:
+    virtual void accept();
+    void slotWhatsThis();
+
+  private:
+    QLineEdit*   _dxLineEdit;
+    QLineEdit*   _dyLineEdit;
+    QLineEdit*   _dzLineEdit;
+    QLineEdit*   _dxrLineEdit;
+    QLineEdit*   _dyrLineEdit;
+    QLineEdit*   _dzrLineEdit;
+    QLineEdit*   _oxLineEdit;
+    QLineEdit*   _oyLineEdit;
+    QLineEdit*   _ozLineEdit;
+    QLineEdit*   _oxrLineEdit;
+    QLineEdit*   _oyrLineEdit;
+    QLineEdit*   _ozrLineEdit;
+    QLineEdit*   _scLineEdit;
+    QLineEdit*   _scrLineEdit;
+    QLineEdit*   _t0LineEdit;
+
+    QPushButton* _buttonGet;
+    QPushButton* _buttonCancel;
+    QPushButton* _buttonOK;
+    QPushButton* _buttonWhatsThis;
+};
+
+#endif
Index: /trunk/BNC/src/upload/bncephuploadcaster.cpp
===================================================================
--- /trunk/BNC/src/upload/bncephuploadcaster.cpp	(revision 4283)
+++ /trunk/BNC/src/upload/bncephuploadcaster.cpp	(revision 4283)
@@ -0,0 +1,77 @@
+/* -------------------------------------------------------------------------
+ * BKG NTRIP Server
+ * -------------------------------------------------------------------------
+ *
+ * Class:      bncEphUploadCaster
+ *
+ * Purpose:    Connection to NTRIP Caster for Ephemeris
+ *
+ * Author:     L. Mervart
+ *
+ * Created:    03-Apr-2011
+ *
+ * Changes:    
+ *
+ * -----------------------------------------------------------------------*/
+
+#include <iostream>
+#include <math.h>
+#include "bncephuploadcaster.h" 
+#include "bncsettings.h"
+
+using namespace std;
+
+// Constructor
+////////////////////////////////////////////////////////////////////////////
+bncEphUploadCaster::bncEphUploadCaster() {
+  bncSettings settings;
+
+  QString mountpoint = settings.value("uploadEphMountpoint").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();
+    int     sampl    = settings.value("uploadEphSampl").toInt();
+
+    _ephUploadCaster = new bncUploadCaster(mountpoint, outHost, outPort, 
+                                           password, -1, sampl);
+
+    connect(_ephUploadCaster, SIGNAL(newBytes(QByteArray,double)), 
+          this, SIGNAL(newBytes(QByteArray,double)));
+
+    _ephUploadCaster->start();
+  }
+}
+
+// Destructor
+////////////////////////////////////////////////////////////////////////////
+bncEphUploadCaster::~bncEphUploadCaster() {
+  if (_ephUploadCaster) {
+    _ephUploadCaster->deleteSafely();
+  }
+}
+
+// List of Stored Ephemeris changed (virtual)
+////////////////////////////////////////////////////////////////////////////
+void bncEphUploadCaster::ephBufferChanged() {
+  if (_ephUploadCaster) {
+    QByteArray outBuffer;
+    QMapIterator<QString, t_ephPair*> it(_eph);
+    while (it.hasNext()) {
+      it.next();
+
+      t_eph* eph = it.value()->last;
+      unsigned char Array[80];
+      int size = eph->RTCM3(Array);
+      if (size > 0) {
+        outBuffer += QByteArray((char*) Array, size);
+      }
+    }
+    if (outBuffer.size() > 0) {
+      _ephUploadCaster->setOutBuffer(outBuffer);
+    }
+  }
+}
Index: /trunk/BNC/src/upload/bncephuploadcaster.h
===================================================================
--- /trunk/BNC/src/upload/bncephuploadcaster.h	(revision 4283)
+++ /trunk/BNC/src/upload/bncephuploadcaster.h	(revision 4283)
@@ -0,0 +1,21 @@
+#ifndef BNCEPHUPLOADCASTER_H
+#define BNCEPHUPLOADCASTER_H
+
+#include <newmat.h>
+#include "bncuploadcaster.h"
+#include "bncephuser.h"
+
+class bncEphUploadCaster : public bncEphUser {
+ Q_OBJECT
+ public:
+  bncEphUploadCaster();
+  virtual ~bncEphUploadCaster();
+ signals:
+  void newBytes(QByteArray staID, double nbyte);
+ protected:
+  virtual void ephBufferChanged();
+ private:
+  bncUploadCaster* _ephUploadCaster;
+};
+
+#endif
Index: /trunk/BNC/src/upload/bncrtnetdecoder.cpp
===================================================================
--- /trunk/BNC/src/upload/bncrtnetdecoder.cpp	(revision 4283)
+++ /trunk/BNC/src/upload/bncrtnetdecoder.cpp	(revision 4283)
@@ -0,0 +1,102 @@
+// Part of BNC, a utility for retrieving decoding and
+// converting GNSS data streams from NTRIP broadcasters.
+//
+// Copyright (C) 2007
+// German Federal Agency for Cartography and Geodesy (BKG)
+// http://www.bkg.bund.de
+// Czech Technical University Prague, Department of Geodesy
+// http://www.fsv.cvut.cz
+//
+// Email: euref-ip@bkg.bund.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation, version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/* -------------------------------------------------------------------------
+ * BKG NTRIP Client
+ * -------------------------------------------------------------------------
+ *
+ * Class:      bncRtnetDecoder
+ *
+ * Purpose:    Implementation of RTNet (SP3-like) output decoder
+ *
+ * Author:     L. Mervart
+ *
+ * Created:    28-Mar-2011
+ *
+ * Changes:    
+ *
+ * -----------------------------------------------------------------------*/
+
+#include <iostream>
+#include "bncrtnetdecoder.h"
+#include "bncsettings.h"
+
+using namespace std;
+
+// Constructor
+//////////////////////////////////////////////////////////////////////// 
+bncRtnetDecoder::bncRtnetDecoder() {
+  bncSettings settings;
+
+  // List of upload casters
+  // ----------------------
+  int iRow = -1;
+  QListIterator<QString> it(settings.value("uploadMountpointsOut").toStringList());
+  while (it.hasNext()) {
+    QStringList hlp = it.next().split(",");
+    if (hlp.size() > 6) {
+      ++iRow;
+      int  outPort = hlp[1].toInt();
+      bool CoM     = (hlp[5].toInt() == Qt::Checked);
+      int PID = 0;
+      if (hlp.size() > 8) {
+        PID = hlp[8].toInt();
+      }
+      int SID = 0;
+      if (hlp.size() > 9) {
+        SID = hlp[9].toInt();
+      }
+      int IOD = 0;
+      if (hlp.size() > 10) {
+        IOD = hlp[10].toInt();
+      }
+      bncRtnetUploadCaster* newCaster = new bncRtnetUploadCaster(
+                                                       hlp[2], hlp[0], outPort, 
+                                                       hlp[3], hlp[4], CoM,
+                                                       hlp[6], hlp[7], 
+                                                       PID, SID, IOD, iRow);
+      newCaster->start();
+      _casters.push_back(newCaster);
+    }
+  }
+}
+
+// Destructor
+//////////////////////////////////////////////////////////////////////// 
+bncRtnetDecoder::~bncRtnetDecoder() {
+  for (int ic = 0; ic < _casters.size(); ic++) {
+    _casters[ic]->deleteSafely();
+  }
+}
+
+// Decode Method
+//////////////////////////////////////////////////////////////////////// 
+t_irc bncRtnetDecoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
+  errmsg.clear();
+  for (int ic = 0; ic < _casters.size(); ic++) {
+    _casters[ic]->decodeRtnetStream(buffer, bufLen);
+  }
+  return success;
+}
+
Index: /trunk/BNC/src/upload/bncrtnetdecoder.h
===================================================================
--- /trunk/BNC/src/upload/bncrtnetdecoder.h	(revision 4283)
+++ /trunk/BNC/src/upload/bncrtnetdecoder.h	(revision 4283)
@@ -0,0 +1,43 @@
+// Part of BNC, a utility for retrieving decoding and
+// converting GNSS data streams from NTRIP broadcasters.
+//
+// Copyright (C) 2007
+// German Federal Agency for Cartography and Geodesy (BKG)
+// http://www.bkg.bund.de
+// Czech Technical University Prague, Department of Geodesy
+// http://www.fsv.cvut.cz
+//
+// Email: euref-ip@bkg.bund.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation, version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef BNCRTNETDECODER_H
+#define BNCRTNETDECODER_H
+
+#include <fstream>
+#include <QtCore>
+#include "bncrtnetuploadcaster.h"
+#include "RTCM/GPSDecoder.h"
+
+class bncRtnetDecoder: public GPSDecoder {
+ public:
+  bncRtnetDecoder();
+  ~bncRtnetDecoder();
+  virtual t_irc Decode(char* buffer, int bufLen, 
+                       std::vector<std::string>& errmsg);
+ private:
+  QVector<bncRtnetUploadCaster*> _casters;
+};
+
+#endif  // include blocker
Index: /trunk/BNC/src/upload/bncrtnetuploadcaster.cpp
===================================================================
--- /trunk/BNC/src/upload/bncrtnetuploadcaster.cpp	(revision 4283)
+++ /trunk/BNC/src/upload/bncrtnetuploadcaster.cpp	(revision 4283)
@@ -0,0 +1,566 @@
+/* -------------------------------------------------------------------------
+ * BKG NTRIP Server
+ * -------------------------------------------------------------------------
+ *
+ * Class:      bncRtnetUploadCaster
+ *
+ * Purpose:    Connection to NTRIP Caster
+ *
+ * Author:     L. Mervart
+ *
+ * Created:    29-Mar-2011
+ *
+ * Changes:    
+ *
+ * -----------------------------------------------------------------------*/
+
+#include <math.h>
+#include "bncrtnetuploadcaster.h" 
+#include "bncsettings.h"
+#include "bncephuser.h"
+#include "bncclockrinex.h"
+#include "bncsp3.h"
+
+using namespace std;
+
+// Constructor
+////////////////////////////////////////////////////////////////////////////
+bncRtnetUploadCaster::bncRtnetUploadCaster(const QString& mountpoint,
+                                 const QString& outHost, int outPort,
+                                 const QString& password, 
+                                 const QString& crdTrafo, bool  CoM, 
+                                 const QString& sp3FileName,
+                                 const QString& rnxFileName,
+                                 int PID, int SID, int IOD, int iRow) :
+  bncUploadCaster(mountpoint, outHost, outPort, password, iRow, 0) {
+
+  _crdTrafo   = crdTrafo;
+  _CoM        = CoM;
+  _PID        = PID;
+  _SID        = SID;
+  _IOD        = IOD;
+
+  // Member that receives the ephemeris
+  // ----------------------------------
+  _ephUser = new bncEphUser();
+
+  bncSettings settings;
+  QString     intr  = settings.value("uploadIntr").toString();
+
+  _samplRtcmEphCorr  = settings.value("uploadSamplRtcmEphCorr").toDouble();
+  double samplClkRnx = settings.value("uploadSamplClkRnx").toDouble();
+  double samplSp3    = settings.value("uploadSamplSp3").toDouble() * 60.0;
+
+  if (_samplRtcmEphCorr == 0.0) {
+    _usedEph = 0;
+  }
+  else {
+    _usedEph = new QMap<QString, t_eph*>;
+  }
+
+  // RINEX writer
+  // ------------
+  if (!rnxFileName.isEmpty()) {
+    _rnx = new bncClockRinex(rnxFileName, intr, samplClkRnx);
+  }
+  else {
+    _rnx = 0;
+  }
+
+  // SP3 writer
+  // ----------
+  if (!sp3FileName.isEmpty()) {
+    _sp3 = new bncSP3(sp3FileName, intr, samplSp3);
+  }
+  else {
+    _sp3 = 0;
+  }
+
+  // Set Transformation Parameters
+  // -----------------------------
+  if      (_crdTrafo == "ETRF2000") {
+    _dx  =    0.0521;
+    _dy  =    0.0493;
+    _dz  =   -0.0585;
+    _dxr =    0.0001;
+    _dyr =    0.0001;
+    _dzr =   -0.0018;
+    _ox  =  0.000891;
+    _oy  =  0.005390;
+    _oz  = -0.008712;
+    _oxr =  0.000081;
+    _oyr =  0.000490;
+    _ozr = -0.000792;
+    _sc  =      1.34;
+    _scr =      0.08;
+    _t0  =    2000.0;
+  }
+  else if (_crdTrafo == "NAD83") {
+    _dx  =    0.9963;
+    _dy  =   -1.9024;
+    _dz  =   -0.5210;
+    _dxr =    0.0005;
+    _dyr =   -0.0006;
+    _dzr =   -0.0013;
+    _ox  = -0.025915;
+    _oy  = -0.009426;
+    _oz  = -0.011599;
+    _oxr = -0.000067;
+    _oyr =  0.000757;
+    _ozr =  0.000051;
+    _sc  =      0.78;
+    _scr =     -0.10;
+    _t0  =    1997.0;
+  }
+  else if (_crdTrafo == "GDA94") {
+    _dx  =   -0.07973;
+    _dy  =   -0.00686;
+    _dz  =    0.03803;
+    _dxr =    0.00225;
+    _dyr =   -0.00062;
+    _dzr =   -0.00056;
+    _ox  =  0.0000351;
+    _oy  = -0.0021211;
+    _oz  = -0.0021411;
+    _oxr = -0.0014707;
+    _oyr = -0.0011443;
+    _ozr = -0.0011701;
+    _sc  =      6.636;
+    _scr =      0.294;
+    _t0  =     1994.0;
+  }
+  else if (_crdTrafo == "SIRGAS2000") {
+    _dx  =   -0.0051;
+    _dy  =   -0.0065;
+    _dz  =   -0.0099;
+    _dxr =    0.0000;
+    _dyr =    0.0000;
+    _dzr =    0.0000;
+    _ox  =  0.000150;
+    _oy  =  0.000020;
+    _oz  =  0.000021;
+    _oxr =  0.000000;
+    _oyr =  0.000000;
+    _ozr =  0.000000;
+    _sc  =     0.000;
+    _scr =     0.000;
+    _t0  =    0000.0;
+  }
+  else if (_crdTrafo == "SIRGAS95") {
+    _dx  =    0.0077;
+    _dy  =    0.0058;
+    _dz  =   -0.0138;
+    _dxr =    0.0000;
+    _dyr =    0.0000;
+    _dzr =    0.0000;
+    _ox  =  0.000000;
+    _oy  =  0.000000;
+    _oz  = -0.000030;
+    _oxr =  0.000000;
+    _oyr =  0.000000;
+    _ozr =  0.000000;
+    _sc  =     1.570;
+    _scr =     0.000;
+    _t0  =    0000.0;
+  }
+  else if (_crdTrafo == "Custom") {
+    _dx  = settings.value("trafo_dx").toDouble();
+    _dy  = settings.value("trafo_dy").toDouble();
+    _dz  = settings.value("trafo_dz").toDouble();
+    _dxr = settings.value("trafo_dxr").toDouble();
+    _dyr = settings.value("trafo_dyr").toDouble();
+    _dzr = settings.value("trafo_dzr").toDouble();
+    _ox  = settings.value("trafo_ox").toDouble();
+    _oy  = settings.value("trafo_oy").toDouble();
+    _oz  = settings.value("trafo_oz").toDouble();
+    _oxr = settings.value("trafo_oxr").toDouble();
+    _oyr = settings.value("trafo_oyr").toDouble();
+    _ozr = settings.value("trafo_ozr").toDouble();
+    _sc  = settings.value("trafo_sc").toDouble();
+    _scr = settings.value("trafo_scr").toDouble();
+    _t0  = settings.value("trafo_t0").toDouble();
+  }
+}
+
+// Destructor
+////////////////////////////////////////////////////////////////////////////
+bncRtnetUploadCaster::~bncRtnetUploadCaster() {
+  if (isRunning()) {
+    wait();
+  }
+  delete _rnx;
+  delete _sp3;
+  delete _ephUser;
+  delete _usedEph;
+}
+
+// 
+////////////////////////////////////////////////////////////////////////////
+void bncRtnetUploadCaster::decodeRtnetStream(char* buffer, int bufLen) {
+                                        
+  QMutexLocker locker(&_mutex);
+
+  // Append to internal buffer
+  // -------------------------
+  _rtnetStreamBuffer.append(QByteArray(buffer, bufLen));
+
+  // Select buffer part that contains last epoch
+  // -------------------------------------------
+  QStringList lines;
+  int iEpoBeg = _rtnetStreamBuffer.lastIndexOf('*');   // begin of last epoch
+  if (iEpoBeg == -1) {
+    _rtnetStreamBuffer.clear();
+    return;
+  }
+  _rtnetStreamBuffer = _rtnetStreamBuffer.mid(iEpoBeg);
+
+  int iEpoEnd = _rtnetStreamBuffer.lastIndexOf("EOE"); // end   of last epoch
+  if (iEpoEnd == -1) {
+    return;
+  }
+  else {
+    lines = _rtnetStreamBuffer.left(iEpoEnd).split('\n', QString::SkipEmptyParts);
+    _rtnetStreamBuffer = _rtnetStreamBuffer.mid(iEpoEnd+3);
+  }
+
+  if (lines.size() < 2) {
+    return;
+  }
+
+  // Keep the last unfinished line in buffer
+  // ---------------------------------------
+  int iLastEOL = _rtnetStreamBuffer.lastIndexOf('\n');
+  if (iLastEOL != -1) {
+    _rtnetStreamBuffer = _rtnetStreamBuffer.mid(iLastEOL+1);
+  }
+
+  // Read first line (with epoch time)
+  // ---------------------------------
+  QTextStream in(lines[0].toAscii());
+  QString hlp;
+  int     year, month, day, hour, min;
+  double  sec;
+  in >> hlp >> year >> month >> day >> hour >> min >> sec;
+  bncTime epoTime; epoTime.set( year, month, day, hour, min, sec);
+
+  struct ClockOrbit co;
+  memset(&co, 0, sizeof(co));
+  co.GPSEpochTime      = static_cast<int>(epoTime.gpssec());
+  co.GLONASSEpochTime  = static_cast<int>(fmod(epoTime.gpssec(), 86400.0))
+                       + 3 * 3600 - gnumleap(year, month, day);
+  co.ClockDataSupplied = 1;
+  co.OrbitDataSupplied = 1;
+  co.SatRefDatum       = DATUM_ITRF;
+  co.SSRIOD            = _IOD;
+  co.SSRProviderID     = _PID; // 256 .. BKG,  257 ... EUREF
+  co.SSRSolutionID     = _SID;
+  
+  struct Bias bias;
+  memset(&bias, 0, sizeof(bias));
+  bias.GPSEpochTime     = co.GPSEpochTime;
+  bias.GLONASSEpochTime = co.GLONASSEpochTime;
+  
+  for (int ii = 1; ii < lines.size(); ii++) {
+ 
+    QString      prn;
+    ColumnVector xx(14); xx = 0.0;
+  
+    QTextStream in(lines[ii].toAscii());
+
+    in >> prn;
+    if (prn[0] == 'P') {
+      prn.remove(0,1);
+    }
+
+    t_eph* eph = 0;
+    const bncEphUser::t_ephPair* ephPair = _ephUser->ephPair(prn);
+    if (ephPair) {
+
+      eph = ephPair->last;
+
+      // Use previous ephemeris if the last one is too recent
+      // ----------------------------------------------------
+      const int MINAGE = 60; // seconds
+      if (ephPair->prev && eph->receptDateTime().isValid() &&
+          eph->receptDateTime().secsTo(currentDateAndTimeGPS()) < MINAGE) {
+        eph = ephPair->prev;
+      }
+
+      // Make sure the clock messages refer to same IOD as orbit messages
+      // ----------------------------------------------------------------
+      if (_usedEph) {
+        if (fmod(epoTime.gpssec(), _samplRtcmEphCorr) == 0.0) {
+          (*_usedEph)[prn] = eph;
+        }
+        else {
+          eph = 0;
+          if (_usedEph->contains(prn)) {
+            t_eph* usedEph = _usedEph->value(prn);
+            if      (usedEph == ephPair->last) {
+              eph = ephPair->last;
+            }
+            else if (usedEph == ephPair->prev) {
+              eph = ephPair->prev;
+            }
+          }
+        }
+      }
+    }
+
+    if (eph) {
+
+      in >> xx(1) >> xx(2) >> xx(3) >> xx(4) >> xx(5) 
+         >> xx(6) >> xx(7) >> xx(8) >> xx(9) >> xx(10)
+         >> xx(11) >> xx(12) >> xx(13) >> xx(14);
+      xx(1) *= 1e3;          // x-crd
+      xx(2) *= 1e3;          // y-crd
+      xx(3) *= 1e3;          // z-crd
+      xx(4) *= 1e-6;         // clk
+      xx(5) *= 1e-6;         // rel. corr.
+                             // xx(6), xx(7), xx(8) ... PhaseCent - CoM
+                             // xx(9)  ... P1-C1 DCB in meters
+                             // xx(10) ... P1-P2 DCB in meters
+                             // xx(11) ... dT
+      xx(12) *= 1e3;         // x-crd at time + dT
+      xx(13) *= 1e3;         // y-crd at time + dT
+      xx(14) *= 1e3;         // z-crd at time + dT
+  
+      struct ClockOrbit::SatData* sd = 0;
+      if      (prn[0] == 'G') {
+        sd = co.Sat + co.NumberOfGPSSat;
+        ++co.NumberOfGPSSat;
+      }
+      else if (prn[0] == 'R') {
+        sd = co.Sat + CLOCKORBIT_NUMGPS + co.NumberOfGLONASSSat;
+        ++co.NumberOfGLONASSSat;
+      }
+      if (sd) {
+        QString outLine;
+        processSatellite(eph, epoTime.gpsw(), epoTime.gpssec(), prn, 
+                         xx, sd, outLine);
+      }
+  
+      struct Bias::BiasSat* biasSat = 0;
+      if      (prn[0] == 'G') {
+        biasSat = bias.Sat + bias.NumberOfGPSSat;
+        ++bias.NumberOfGPSSat;
+      }
+      else if (prn[0] == 'R') {
+        biasSat = bias.Sat + CLOCKORBIT_NUMGPS + bias.NumberOfGLONASSSat;
+        ++bias.NumberOfGLONASSSat;
+      }
+  
+      // Coefficient of Ionosphere-Free LC
+      // ---------------------------------
+      const static double a_L1_GPS =  2.54572778;
+      const static double a_L2_GPS = -1.54572778;
+      const static double a_L1_Glo =  2.53125000;
+      const static double a_L2_Glo = -1.53125000;
+  
+      if (biasSat) {
+        biasSat->ID = prn.mid(1).toInt();
+        biasSat->NumberOfCodeBiases = 3;
+        if      (prn[0] == 'G') {
+          biasSat->Biases[0].Type = CODETYPEGPS_L1_Z;
+          biasSat->Biases[0].Bias = - a_L2_GPS * xx(10);
+          biasSat->Biases[1].Type = CODETYPEGPS_L1_CA;
+          biasSat->Biases[1].Bias = - a_L2_GPS * xx(10) + xx(9);
+          biasSat->Biases[2].Type = CODETYPEGPS_L2_Z;
+          biasSat->Biases[2].Bias = a_L1_GPS * xx(10);
+        }
+        else if (prn[0] == 'R') {
+          biasSat->Biases[0].Type = CODETYPEGLONASS_L1_P;
+          biasSat->Biases[0].Bias = - a_L2_Glo * xx(10);
+          biasSat->Biases[1].Type = CODETYPEGLONASS_L1_CA;
+          biasSat->Biases[1].Bias = - a_L2_Glo * xx(10) + xx(9);
+          biasSat->Biases[2].Type = CODETYPEGLONASS_L2_P;
+          biasSat->Biases[2].Bias = a_L1_Glo * xx(10);
+        }
+      }
+    }
+  }
+
+  QByteArray hlpBufferCo;  
+
+  // Orbit and Clock Corrections together
+  // ------------------------------------
+  if (_samplRtcmEphCorr == 0.0) {
+    if (co.NumberOfGPSSat > 0 || co.NumberOfGLONASSSat > 0) {
+      char obuffer[CLOCKORBIT_BUFFERSIZE];
+      int len = MakeClockOrbit(&co, COTYPE_AUTO, 0, obuffer, sizeof(obuffer));
+      if (len > 0) {
+        hlpBufferCo = QByteArray(obuffer, len);
+      }
+    }
+  }
+
+  // Orbit and Clock Corrections separately
+  // --------------------------------------
+  else {
+    if (co.NumberOfGPSSat > 0) {
+      char obuffer[CLOCKORBIT_BUFFERSIZE];
+      if (fmod(epoTime.gpssec(), _samplRtcmEphCorr) == 0.0) {
+        int len1 = MakeClockOrbit(&co, COTYPE_GPSORBIT, 1, obuffer, sizeof(obuffer));
+        if (len1 > 0) {
+          hlpBufferCo += QByteArray(obuffer, len1);
+        }
+      }
+      int mmsg = (co.NumberOfGLONASSSat > 0) ? 1 : 0;
+      int len2 = MakeClockOrbit(&co, COTYPE_GPSCLOCK, mmsg, obuffer, sizeof(obuffer));
+      if (len2 > 0) {
+        hlpBufferCo += QByteArray(obuffer, len2);
+      }
+    }
+    if (co.NumberOfGLONASSSat > 0) {
+      char obuffer[CLOCKORBIT_BUFFERSIZE];
+      if (fmod(epoTime.gpssec(), _samplRtcmEphCorr) == 0.0) {
+        int len1 = MakeClockOrbit(&co, COTYPE_GLONASSORBIT, 1, obuffer, sizeof(obuffer));
+        if (len1 > 0) {
+          hlpBufferCo += QByteArray(obuffer, len1);
+        }
+      }
+      int len2 = MakeClockOrbit(&co, COTYPE_GLONASSCLOCK, 0, obuffer, sizeof(obuffer));
+      if (len2 > 0) {
+        hlpBufferCo += QByteArray(obuffer, len2);
+      }
+    }
+  }
+  
+  // Biases
+  // ------
+  QByteArray hlpBufferBias;  
+  if (bias.NumberOfGPSSat > 0 || bias.NumberOfGLONASSSat > 0) {
+    char obuffer[CLOCKORBIT_BUFFERSIZE];
+    int len = MakeBias(&bias, BTYPE_AUTO, 0, obuffer, sizeof(obuffer));
+    if (len > 0) {
+      hlpBufferBias = QByteArray(obuffer, len);
+    }
+  }
+
+  if (hlpBufferCo.size() > 0) {
+    _outBuffer = hlpBufferCo + hlpBufferBias;
+  }
+}
+
+// 
+////////////////////////////////////////////////////////////////////////////
+void bncRtnetUploadCaster::processSatellite(t_eph* eph, int GPSweek, 
+                                       double GPSweeks, const QString& prn, 
+                                       const ColumnVector& xx, 
+                                       struct ClockOrbit::SatData* sd,
+                                       QString& outLine) {
+
+  const double secPerWeek = 7.0 * 86400.0;
+
+  ColumnVector rsw(3);
+  ColumnVector rsw2(3);
+  double dClk;
+
+  for (int ii = 1; ii <= 2; ++ii) {
+
+    int    GPSweek12  = GPSweek;
+    double GPSweeks12 = GPSweeks;
+    if (ii == 2) {
+      GPSweeks12 += xx(11);
+      if (GPSweeks12 > secPerWeek) {
+        GPSweek12  += 1;
+        GPSweeks12 -= secPerWeek;
+      }
+    }
+
+    ColumnVector xB(4);
+    ColumnVector vv(3);
+
+    eph->position(GPSweek12, GPSweeks12, xB.data(), vv.data());
+    
+    ColumnVector xyz;
+    if (ii == 1) {
+      xyz = xx.Rows(1,3);
+    }
+    else {
+      xyz = xx.Rows(12,14);
+    }
+    
+    // Correction Center of Mass -> Antenna Phase Center
+    // -------------------------------------------------
+    if (! _CoM) {
+      xyz(1) += xx(6);
+      xyz(2) += xx(7);
+      xyz(3) += xx(8);
+    }
+    
+    if (_crdTrafo != "IGS08") {
+      crdTrafo(GPSweek12, xyz);
+    }
+    
+    ColumnVector dx = xB.Rows(1,3) - xyz ;
+    
+    if (ii == 1) {
+      XYZ_to_RSW(xB.Rows(1,3), vv, dx, rsw);
+      dClk = (xx(4) + xx(5) - xB(4)) * 299792458.0;
+    }
+    else {
+      XYZ_to_RSW(xB.Rows(1,3), vv, dx, rsw2);
+    }
+  }
+
+  if (sd) {
+    sd->ID                    = prn.mid(1).toInt();
+    sd->IOD                   = eph->IOD();
+    sd->Clock.DeltaA0         = dClk;
+    sd->Orbit.DeltaRadial     = rsw(1);
+    sd->Orbit.DeltaAlongTrack = rsw(2);
+    sd->Orbit.DeltaCrossTrack = rsw(3);
+    sd->Orbit.DotDeltaRadial     = (rsw2(1) - rsw(1)) / xx(11);
+    sd->Orbit.DotDeltaAlongTrack = (rsw2(2) - rsw(2)) / xx(11);
+    sd->Orbit.DotDeltaCrossTrack = (rsw2(3) - rsw(3)) / xx(11);
+  }
+
+  outLine.sprintf("%d %.1f %s  %3d  %10.3f  %8.3f %8.3f %8.3f\n", 
+                  GPSweek, GPSweeks, eph->prn().toAscii().data(),
+                  eph->IOD(), dClk, rsw(1), rsw(2), rsw(3));
+
+  if (_rnx) {
+    _rnx->write(GPSweek, GPSweeks, prn, xx);
+  }
+  if (_sp3) {
+    _sp3->write(GPSweek, GPSweeks, prn, xx);
+  }
+}
+
+// Transform Coordinates
+////////////////////////////////////////////////////////////////////////////
+void bncRtnetUploadCaster::crdTrafo(int GPSWeek, ColumnVector& xyz) {
+
+  // Current epoch minus 2000.0 in years
+  // ------------------------------------
+  double dt = (GPSWeek - (1042.0+6.0/7.0)) / 365.2422 * 7.0 + 2000.0 - _t0;
+
+  ColumnVector dx(3);
+
+  dx(1) = _dx + dt * _dxr;
+  dx(2) = _dy + dt * _dyr;
+  dx(3) = _dz + dt * _dzr;
+
+  static const double arcSec = 180.0 * 3600.0 / M_PI;
+
+  double ox = (_ox + dt * _oxr) / arcSec;
+  double oy = (_oy + dt * _oyr) / arcSec;
+  double oz = (_oz + dt * _ozr) / arcSec;
+
+  double sc = 1.0 + _sc * 1e-9 + dt * _scr * 1e-9;
+
+  Matrix rMat(3,3);
+  rMat(1,1) = 1.0;
+  rMat(1,2) = -oz;
+  rMat(1,3) =  oy;
+  rMat(2,1) =  oz;
+  rMat(2,2) = 1.0;
+  rMat(2,3) = -ox;
+  rMat(3,1) = -oy;
+  rMat(3,2) =  ox;
+  rMat(3,3) = 1.0;
+
+  xyz = sc * rMat * xyz + dx;
+}
+
Index: /trunk/BNC/src/upload/bncrtnetuploadcaster.h
===================================================================
--- /trunk/BNC/src/upload/bncrtnetuploadcaster.h	(revision 4283)
+++ /trunk/BNC/src/upload/bncrtnetuploadcaster.h	(revision 4283)
@@ -0,0 +1,66 @@
+#ifndef BNCRTNETUPLOADCASTER_H
+#define BNCRTNETUPLOADCASTER_H
+
+#include <newmat.h>
+#include "bncuploadcaster.h"
+#include "bnctime.h"
+#include "ephemeris.h"
+extern "C" {
+#include "clock_orbit_rtcm.h"
+}
+
+class bncEphUser;
+class bncoutf;
+class bncClockRinex;
+class bncSP3;
+
+class bncRtnetUploadCaster : public bncUploadCaster {
+ Q_OBJECT
+ public:
+  bncRtnetUploadCaster(const QString& mountpoint,
+                  const QString& outHost, int outPort,
+                  const QString& password, 
+                  const QString& crdTrafo, bool  CoM, 
+                  const QString& sp3FileName,
+                  const QString& rnxFileName,
+                  int PID, int SID, int IOD, int iRow);
+  void decodeRtnetStream(char* buffer, int bufLen);
+ protected:
+  virtual ~bncRtnetUploadCaster();
+ private:
+  void processSatellite(t_eph* eph, int GPSweek, 
+                        double GPSweeks, const QString& prn, 
+                        const ColumnVector& xx, 
+                        struct ClockOrbit::SatData* sd,
+                        QString& outLine);
+  void crdTrafo(int GPSWeek, ColumnVector& xyz);
+
+  bncEphUser*    _ephUser;
+  QString        _rtnetStreamBuffer;
+  QString        _crdTrafo;
+  bool           _CoM;
+  int            _PID;
+  int            _SID;
+  int            _IOD;
+  double         _samplRtcmEphCorr;
+  double         _dx;
+  double         _dy;
+  double         _dz;
+  double         _dxr;
+  double         _dyr;
+  double         _dzr;
+  double         _ox;
+  double         _oy;
+  double         _oz;
+  double         _oxr;
+  double         _oyr;
+  double         _ozr;
+  double         _sc;
+  double         _scr;
+  double         _t0;
+  bncClockRinex* _rnx;
+  bncSP3*        _sp3;
+  QMap<QString, t_eph*>* _usedEph;
+};
+
+#endif
Index: /trunk/BNC/src/upload/bncuploadcaster.cpp
===================================================================
--- /trunk/BNC/src/upload/bncuploadcaster.cpp	(revision 4283)
+++ /trunk/BNC/src/upload/bncuploadcaster.cpp	(revision 4283)
@@ -0,0 +1,153 @@
+/* -------------------------------------------------------------------------
+ * BKG NTRIP Server
+ * -------------------------------------------------------------------------
+ *
+ * Class:      bncUploadCaster
+ *
+ * Purpose:    Connection to NTRIP Caster
+ *
+ * Author:     L. Mervart
+ *
+ * Created:    29-Mar-2011
+ *
+ * Changes:    
+ *
+ * -----------------------------------------------------------------------*/
+
+#include <math.h>
+#include "bncuploadcaster.h" 
+#include "bncversion.h"
+#include "bncapp.h"
+#include "bnctableitem.h"
+
+using namespace std;
+
+// Constructor
+////////////////////////////////////////////////////////////////////////////
+bncUploadCaster::bncUploadCaster(const QString& mountpoint,
+                                 const QString& outHost, int outPort,
+                                 const QString& password, int iRow, 
+                                 int rate) {
+  _mountpoint    = mountpoint;
+  _outHost       = outHost;
+  _outPort       = outPort;
+  _password      = password;
+  _outSocket     = 0;
+  _sOpenTrial    = 0;
+  _iRow          = iRow;
+  _rate          = rate;
+  if      (_rate < 5) {
+    _rate = 5;
+  }
+  else if (_rate > 60) {
+    _rate = 60;
+  }
+  _isToBeDeleted = false;
+
+  bncApp* app = (bncApp*) qApp;
+  connect(this, SIGNAL(newMessage(QByteArray,bool)), 
+          app, SLOT(slotMessage(const QByteArray,bool)));
+
+  if (app->_uploadTableItems.find(_iRow) != app->_uploadTableItems.end()){
+    connect(this, SIGNAL(newBytes(QByteArray,double)), 
+            app->_uploadTableItems.value(iRow), 
+            SLOT(slotNewBytes(const QByteArray,double)));
+  }
+}
+
+// Safe Desctructor
+////////////////////////////////////////////////////////////////////////////
+void bncUploadCaster::deleteSafely() {
+  _isToBeDeleted = true;
+  if (!isRunning()) {
+    delete this;
+  }
+}
+
+// Destructor
+////////////////////////////////////////////////////////////////////////////
+bncUploadCaster::~bncUploadCaster() {
+  if (isRunning()) {
+    wait();
+  }
+}
+
+// Endless Loop
+////////////////////////////////////////////////////////////////////////////
+void bncUploadCaster::run() {
+  while (true) {
+    if (_isToBeDeleted) {
+      QThread::quit();
+      deleteLater();
+      return;
+    }
+    open();
+    if (_outSocket && _outSocket->state() == QAbstractSocket::ConnectedState) {
+      QMutexLocker locker(&_mutex);
+      _outSocket->write(_outBuffer);
+      _outSocket->flush();
+      emit newBytes(_mountpoint.toAscii(), _outBuffer.size());
+    }
+    sleep(_rate);
+  }
+}
+
+// Start the Communication with NTRIP Caster
+////////////////////////////////////////////////////////////////////////////
+void bncUploadCaster::open() {
+
+  if (_mountpoint.isEmpty()) {
+    return;
+  }
+
+  if (_outSocket != 0 && 
+      _outSocket->state() == QAbstractSocket::ConnectedState) {
+    return;
+  }
+
+  delete _outSocket; _outSocket = 0;
+
+  double minDt = pow(2.0,_sOpenTrial);
+  if (++_sOpenTrial > 4) {
+    _sOpenTrial = 4;
+  }
+  if (_outSocketOpenTime.isValid() &&
+      _outSocketOpenTime.secsTo(QDateTime::currentDateTime()) < minDt) {
+    return;
+  }
+  else {
+    _outSocketOpenTime = QDateTime::currentDateTime();
+  }
+
+  _outSocket = new QTcpSocket();
+  _outSocket->connectToHost(_outHost, _outPort);
+
+  const int timeOut = 5000;  // 5 seconds
+  if (!_outSocket->waitForConnected(timeOut)) {
+    delete _outSocket;
+    _outSocket = 0;
+    emit(newMessage("Broadcaster: Connect timeout", true));
+    return;
+  }
+
+  QByteArray msg = "SOURCE " + _password.toAscii() + " /" + 
+                   _mountpoint.toAscii() + "\r\n" +
+                   "Source-Agent: NTRIP BNC/" BNCVERSION "\r\n\r\n";
+
+  _outSocket->write(msg);
+  _outSocket->waitForBytesWritten();
+
+  _outSocket->waitForReadyRead();
+  QByteArray ans = _outSocket->readLine();
+
+  if (ans.indexOf("OK") == -1) {
+    delete _outSocket;
+    _outSocket = 0;
+    emit(newMessage("Broadcaster: Connection broken", true));
+  }
+  else {
+    emit(newMessage("Broadcaster: Connection opened", true));
+    _sOpenTrial = 0;
+  }
+}
+
Index: /trunk/BNC/src/upload/bncuploadcaster.h
===================================================================
--- /trunk/BNC/src/upload/bncuploadcaster.h	(revision 4283)
+++ /trunk/BNC/src/upload/bncuploadcaster.h	(revision 4283)
@@ -0,0 +1,42 @@
+#ifndef BNCUPLOADCASTER_H
+#define BNCUPLOADCASTER_H
+
+#include <QtNetwork>
+
+class bncUploadCaster : public QThread {
+ Q_OBJECT
+ public:
+  bncUploadCaster(const QString& mountpoint,
+                  const QString& outHost, int outPort,
+                  const QString& password, int iRow, int rate);
+  virtual void deleteSafely();
+  void setOutBuffer(const QByteArray& outBuffer) {
+    QMutexLocker locker(&_mutex);
+    _outBuffer = outBuffer;
+  }
+
+ protected:
+  virtual    ~bncUploadCaster();
+  QMutex     _mutex;  
+  QByteArray _outBuffer;
+
+ signals:
+  void newMessage(const QByteArray msg, bool showOnScreen);
+  void newBytes(QByteArray staID, double nbyte);
+
+ private:
+  void         open();
+  virtual void run();
+  bool        _isToBeDeleted;
+  QString     _mountpoint;
+  QString     _outHost;
+  int         _outPort;
+  QString     _password;
+  QTcpSocket* _outSocket;
+  int         _sOpenTrial;
+  QDateTime   _outSocketOpenTime;
+  int         _iRow;
+  int         _rate;
+};
+
+#endif
Index: unk/BNC/test_tcpip_client.pl
===================================================================
--- /trunk/BNC/test_tcpip_client.pl	(revision 4282)
+++ 	(revision )
@@ -1,33 +1,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-use IO::Socket;
-
-# List of Parameters
-# ------------------
-my($port) = @ARGV;
-
-if (!defined($port)) {
-  die "Usage: test_tcpip_client.pl portNumber\n";
-}
-
-# Local Variables
-# ---------------
-my($serverHostName) = "localhost";
-my $server;
-
-my $retries = 10;
-while ($retries--) {
-  $server = IO::Socket::INET->new( Proto    => "tcp",
-                                   PeerAddr => $serverHostName,
-                                   PeerPort => $port);
-  last if ($server);
-}
-die "Cannot connect to $serverHostName on $port: $!" unless ($server);
-
-my $buffer;
-while (defined ($buffer = <$server>)) {
-  print $buffer;
-}
-
-
