Index: trunk/BNC/RTCM/GPSDecoder.h
===================================================================
--- trunk/BNC/RTCM/GPSDecoder.h	(revision 1216)
+++ trunk/BNC/RTCM/GPSDecoder.h	(revision 1218)
@@ -27,4 +27,6 @@
 
 #include <iostream>
+#include <vector>
+#include <string>
 #include <QPointer>
 #include <QList>
@@ -121,5 +123,5 @@
 class GPSDecoder {
  public:
-  virtual t_irc Decode(char* buffer, int bufLen) = 0;
+  virtual t_irc Decode(char* buffer, int bufLen, std::vector<std::string>& errmsg) = 0;
 
   virtual ~GPSDecoder() {
Index: trunk/BNC/RTCM/RTCM2Decoder.cpp
===================================================================
--- trunk/BNC/RTCM/RTCM2Decoder.cpp	(revision 1216)
+++ trunk/BNC/RTCM/RTCM2Decoder.cpp	(revision 1218)
@@ -42,4 +42,5 @@
 #include <sstream>
 #include <iomanip>
+#include <set>
 
 #include "../bncutils.h"
@@ -64,5 +65,5 @@
 
 RTCM2Decoder::~RTCM2Decoder() {
-  for (t_pairMap::iterator ii = _ephPair.begin(); ii != _ephPair.end(); ii++) {
+  for (t_listMap::iterator ii = _ephList.begin(); ii != _ephList.end(); ii++) {
     delete ii->second;
   }
@@ -104,5 +105,7 @@
 
 //
-t_irc RTCM2Decoder::Decode(char* buffer, int bufLen) {
+t_irc RTCM2Decoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
+
+  errmsg.clear();
 
   _buffer.append(buffer, bufLen);
@@ -165,5 +168,5 @@
       if (_msg2021.valid()) {
         decoded = true;
-      	translateCorr2Obs();
+      	translateCorr2Obs(errmsg);
       }	
     }
@@ -182,35 +185,37 @@
 
 
-void RTCM2Decoder::storeEph(const gpsephemeris& gpseph) {
+bool RTCM2Decoder::storeEph(const gpsephemeris& gpseph, string& storedPRN, vector<int>& IODs) {
   t_ephGPS eph; eph.set(&gpseph);
 
-  storeEph(eph);
-}
-
-
-void RTCM2Decoder::storeEph(const t_ephGPS& gpseph) {
+  return storeEph(eph, storedPRN, IODs);
+}
+
+
+bool RTCM2Decoder::storeEph(const t_ephGPS& gpseph, string& storedPRN, vector<int>& IODs) {
   t_ephGPS* eph = new t_ephGPS(gpseph);
 
   string prn = eph->prn();
 
-  t_pairMap::iterator ip = _ephPair.find(prn);
-  if (ip == _ephPair.end() ) {
-    ip = _ephPair.insert(pair<string, t_ephPair*>(prn, new t_ephPair)).first;
-  }
-  t_ephPair* pair = ip->second;
-
-  if ( !pair->eph || eph->isNewerThan(pair->eph) ) {
-    delete pair->oldEph;
-    pair->oldEph = pair->eph;
-    pair->eph    = eph;
-
-    return;
+  t_listMap::iterator ip = _ephList.find(prn);
+  if (ip == _ephList.end() ) {
+    ip = _ephList.insert(pair<string, t_ephList*>(prn, new t_ephList)).first;
+  }
+  t_ephList* ephList = ip->second;
+
+  bool stored = ephList->store(eph);
+
+  if ( stored ) {
+    storedPRN = eph->prn();
+    ephList->getIODs(IODs);
+    return true;
   }
 
   delete eph;
+
+  return false;
 }
   
   
-void RTCM2Decoder::translateCorr2Obs() {
+void RTCM2Decoder::translateCorr2Obs(vector<string>& errmsg) {
 
   if ( !_msg03.validMsg || !_msg2021.valid() ) {
@@ -248,4 +253,11 @@
     const RTCM2_2021::HiResCorr* corr = icorr->second;
 
+    // beg test
+    if ( corr->PRN >= 200 ) {
+      continue;
+    }
+    // end test
+
+
     ostringstream oPRN; oPRN.fill('0');
 
@@ -255,14 +267,8 @@
     string PRN(oPRN.str());
 
-    t_pairMap::const_iterator ieph = _ephPair.find(PRN);
-    const t_eph* eph0 = 0;
-    const t_eph* eph1 = 0;
-
-    if ( ieph != _ephPair.end() ) {
-      eph0 = ieph->second->eph;
-      eph1 = ieph->second->oldEph;
-    }
-
-    if ( !eph0 && !eph1 ) {
+    t_listMap::const_iterator ieph = _ephList.find(PRN);
+
+    if ( ieph == _ephList.end() ) {
+      errmsg.push_back("missing eph for " + PRN);
       continue;
     }
@@ -277,4 +283,7 @@
     p_obs new_obs = 0;
 
+    // missing IOD
+    vector<string> missingIOD;
+    vector<string>     hasIOD;
     for (unsigned ii = 0; ii < 4; ii++) {
       int          IODcorr = 0;
@@ -312,10 +321,12 @@
       }
 
-      eph = 0;
-      if      ( eph0 && eph0->IOD() == IODcorr ) 
-	eph = eph0;
-      else if ( eph1 && eph1->IOD() == IODcorr ) 
-	eph = eph1;
-      if ( eph && corr ) {
+      eph = ieph->second->getEph(IODcorr);
+
+      if ( eph ) {
+        ostringstream msg;
+        msg << obsT << ':' << setw(3) << eph->IOD();
+        hasIOD.push_back(msg.str());
+
+
 	int    GPSWeek_tot;
 	double GPSWeeks_tot;
@@ -372,9 +383,28 @@
 	}
       }
+      else if ( IODcorr != 0 ) {
+        ostringstream msg;
+        msg << obsT << ':' << setw(3) << IODcorr;
+        missingIOD.push_back(msg.str());
+      }
     } // loop over frequencies
-    
+   
+    // Error report
+    if ( missingIOD.size() ) {
+      ostringstream missingIODstr;
+
+      copy(missingIOD.begin(), missingIOD.end(), ostream_iterator<string>(missingIODstr, "   "));
+
+      errmsg.push_back("missing eph for " + PRN + " , IODs " + missingIODstr.str());
+    }
+
+    // Store new observation
     if ( new_obs ) {
       _obsList.push_back( new_obs );
-    }
-  }
-}
+
+      ///ostringstream hasIODstr;
+      ///copy(hasIOD.begin(), hasIOD.end(), ostream_iterator<string>(hasIODstr, "    "));
+      ///errmsg.push_back("decoded PRN " + PRN + " : " + hasIODstr.str());
+    }
+  }
+}
Index: trunk/BNC/RTCM/RTCM2Decoder.h
===================================================================
--- trunk/BNC/RTCM/RTCM2Decoder.h	(revision 1216)
+++ trunk/BNC/RTCM/RTCM2Decoder.h	(revision 1218)
@@ -27,4 +27,6 @@
 
 #include <map>
+#include <vector>
+#include <list>
 
 #include "GPSDecoder.h"
@@ -39,12 +41,12 @@
     RTCM2Decoder(const std::string& ID);
     virtual ~RTCM2Decoder();
-    virtual t_irc Decode(char* buffer, int bufLen);
+    virtual t_irc Decode(char* buffer, int bufLen, std::vector<std::string>& errmsg);
 
-    void  storeEph(const gpsephemeris& gpseph);
-    void  storeEph(const t_ephGPS&     gpseph);
+    bool  storeEph(const gpsephemeris& gpseph, std::string& storedPRN, std::vector<int>& IODs);
+    bool  storeEph(const t_ephGPS&     gpseph, std::string& storedPRN, std::vector<int>& IODs);
 
     t_irc getStaCrd(double& xx, double& yy, double& zz);
 
-    t_irc getStaCrd(double& xx, double& yy, double& zz,
+    t_irc getStaCrd(double& xx,  double& yy,  double& zz,
                     double& dx1, double& dy1, double& dz1,
                     double& dx2, double& dy2, double& dz2);
@@ -56,21 +58,67 @@
   private:
 
-    class t_ephPair {
+    class t_ephList {
     public:
-      t_ephPair() {
-    	eph    = 0;
-    	oldEph = 0;
+      t_ephList() {}
+      
+      ~t_ephList() {
+        for (std::list<t_eph*>::iterator ii = _eph.begin(); ii != _eph.end(); ii++) {
+          delete  (*ii);
+        }
+      }
+
+      bool store(t_eph* eph) {
+        if ( _eph.size() == 0 ) {
+          _eph.push_back(eph);
+          return true;
+        }
+          
+        std::list<t_eph*>::iterator ii = _eph.begin();
+        while (ii != _eph.end()) {
+          if ( eph->IOD() == (*ii)->IOD() ) {
+            return false;
+          }
+          if ( ! eph->isNewerThan(*ii) ) {
+            break;
+          }
+          ++ii;
+        }
+
+        if ( ii == _eph.begin() && _eph.size() == MAXSIZE) {
+          return false;
+        }
+
+        _eph.insert(ii, eph);
+
+        while ( _eph.size() > MAXSIZE ) {
+          delete _eph.front();
+          _eph.pop_front();
+        }
+
+        return true;
       }
       
-      ~t_ephPair() {
-    	delete eph;
-    	delete oldEph;
+      const t_eph* getEph(int IOD) const {
+        for (std::list<t_eph*>::const_iterator ii = _eph.begin(); ii != _eph.end(); ii++) {
+          if ( (*ii)->IOD() == IOD ) {
+            return (*ii);
+          }
+        }
+        return 0;
       }
-      
-      t_eph* eph;
-      t_eph* oldEph;
+
+      void getIODs(std::vector<int>& IODs) const {
+        IODs.clear();
+        for (std::list<t_eph*>::const_iterator ii = _eph.begin(); ii != _eph.end(); ii++) {
+          IODs.push_back((*ii)->IOD());
+        }
+      }
+
+      static const unsigned MAXSIZE = 3;
+
+      std::list<t_eph*> _eph;
     };
 
-    void translateCorr2Obs();
+    void translateCorr2Obs(std::vector<std::string>& errmsg);
 
     std::string            _ID;
@@ -86,7 +134,7 @@
     rtcm2::RTCM2_22           _msg22;
     rtcm2::RTCM2_2021         _msg2021;
-    std::map<std::string, t_ephPair*> _ephPair;
+    std::map<std::string, t_ephList*> _ephList;
 
-    typedef std::map<std::string, t_ephPair*> t_pairMap;
+    typedef std::map<std::string, t_ephList*> t_listMap;
 };
 
Index: trunk/BNC/RTCM3/RTCM3Decoder.cpp
===================================================================
--- trunk/BNC/RTCM3/RTCM3Decoder.cpp	(revision 1216)
+++ trunk/BNC/RTCM3/RTCM3Decoder.cpp	(revision 1218)
@@ -121,5 +121,7 @@
 // 
 ////////////////////////////////////////////////////////////////////////////
-t_irc RTCM3Decoder::Decode(char* buffer, int bufLen) {
+t_irc RTCM3Decoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
+
+  errmsg.clear();
 
   bool decoded = false;
@@ -128,5 +130,5 @@
   // -----------------------------------------
   if (_mode == unknown || _mode == corrections) {
-    if ( _coDecoder->Decode(buffer, bufLen) == success ) {
+    if ( _coDecoder->Decode(buffer, bufLen, errmsg) == success ) {
       decoded = true;
 
@@ -354,4 +356,16 @@
             decoded = true;
             gpsephemeris* ep = new gpsephemeris(_Parser.ephemerisGPS);
+
+#ifdef DEBUG_RTCM2_2021
+            QString msg = QString("%1: got eph %2 IODC %3 GPSweek %4 TOC %5 TOE %6")
+              .arg(_staID)
+              .arg(ep->satellite, 2)
+              .arg(ep->IODC,      4)
+              .arg(ep->GPSweek,   4)
+              .arg(ep->TOC,       6)
+              .arg(ep->TOE,       6);
+            emit(newMessage(msg.toAscii()));
+#endif
+
             emit newGPSEph(ep);
           }
Index: trunk/BNC/RTCM3/RTCM3Decoder.h
===================================================================
--- trunk/BNC/RTCM3/RTCM3Decoder.h	(revision 1216)
+++ trunk/BNC/RTCM3/RTCM3Decoder.h	(revision 1218)
@@ -40,5 +40,5 @@
   RTCM3Decoder(const QString& fileName);
   virtual ~RTCM3Decoder();
-  virtual t_irc Decode(char* buffer = 0, int bufLen = 0);
+  virtual t_irc Decode(char* buffer, int bufLen, std::vector<std::string>& errmsg);
  signals:
   void newMessage(QByteArray msg);
Index: trunk/BNC/RTCM3/RTCM3coDecoder.cpp
===================================================================
--- trunk/BNC/RTCM3/RTCM3coDecoder.cpp	(revision 1216)
+++ trunk/BNC/RTCM3/RTCM3coDecoder.cpp	(revision 1218)
@@ -109,5 +109,7 @@
 // 
 ////////////////////////////////////////////////////////////////////////////
-t_irc RTCM3coDecoder::Decode(char* buffer, int bufLen) {
+t_irc RTCM3coDecoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
+
+  errmsg.clear();
 
   _buffer.append(buffer, bufLen);
Index: trunk/BNC/RTCM3/RTCM3coDecoder.h
===================================================================
--- trunk/BNC/RTCM3/RTCM3coDecoder.h	(revision 1216)
+++ trunk/BNC/RTCM3/RTCM3coDecoder.h	(revision 1218)
@@ -42,5 +42,5 @@
   RTCM3coDecoder(const QString& staID);
   virtual ~RTCM3coDecoder();
-  virtual t_irc Decode(char* buffer = 0, int bufLen = 0);
+  virtual t_irc Decode(char* buffer, int bufLen, std::vector<std::string>& errmsg);
 
  signals:
Index: trunk/BNC/RTIGS/RTIGSDecoder.cpp
===================================================================
--- trunk/BNC/RTIGS/RTIGSDecoder.cpp	(revision 1216)
+++ trunk/BNC/RTIGS/RTIGSDecoder.cpp	(revision 1218)
@@ -69,5 +69,7 @@
 // 
 ////////////////////////////////////////////////////////////////////////////
-t_irc RTIGSDecoder::Decode(char* buffer, int bufLen) {
+t_irc RTIGSDecoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
+
+  errmsg.clear();
 
   // Append the incomming data to the internal buffer
Index: trunk/BNC/RTIGS/RTIGSDecoder.h
===================================================================
--- trunk/BNC/RTIGS/RTIGSDecoder.h	(revision 1216)
+++ trunk/BNC/RTIGS/RTIGSDecoder.h	(revision 1218)
@@ -51,5 +51,5 @@
   RTIGSDecoder();
   virtual ~RTIGSDecoder();
-  virtual t_irc Decode(char* buffer = 0, int bufLen = 0);
+  virtual t_irc Decode(char* buffer, int bufLen, std::vector<std::string>& errmsg);
 private:
   CGPS_Transform _GPSTrans;
Index: trunk/BNC/bnc.pro
===================================================================
--- trunk/BNC/bnc.pro	(revision 1216)
+++ trunk/BNC/bnc.pro	(revision 1218)
@@ -5,5 +5,6 @@
 ###CONFIG += debug
 
-DEFINES += NO_RTCM3_MAIN
+##DEFINES += NO_RTCM3_MAIN DEBUG_RTCM2_2021
+DEFINES += NO_RTCM3_MAIN 
 
 RESOURCES += bnc.qrc
Index: trunk/BNC/bncapp.cpp
===================================================================
--- trunk/BNC/bncapp.cpp	(revision 1216)
+++ trunk/BNC/bncapp.cpp	(revision 1218)
@@ -149,5 +149,5 @@
 void bncApp::slotMessage(const QByteArray msg) {
 
-  QMutexLocker locker(&_mutex);
+  QMutexLocker locker(&_mutexMessage);
 
   messagePrivate(msg);
@@ -198,4 +198,5 @@
 
   gpsephemeris** ee = &_gpsEph[gpseph->satellite-1];
+
   if ( *ee == 0                         || 
        gpseph->GPSweek > (*ee)->GPSweek ||
Index: trunk/BNC/bncapp.h
===================================================================
--- trunk/BNC/bncapp.h	(revision 1216)
+++ trunk/BNC/bncapp.h	(revision 1218)
@@ -75,4 +75,5 @@
     QString           _bncVersion;
     QMutex            _mutex;
+    QMutex            _mutexMessage;
     QString           _ephPath;
     QString           _ephFileNameGPS;
Index: trunk/BNC/bncgetthread.cpp
===================================================================
--- trunk/BNC/bncgetthread.cpp	(revision 1216)
+++ trunk/BNC/bncgetthread.cpp	(revision 1218)
@@ -41,4 +41,5 @@
 #include <stdlib.h>
 #include <iomanip>
+#include <sstream>
 
 #include <QFile>
@@ -543,5 +544,11 @@
 
         if (_inspSegm<1) {
-          _decoder->Decode(data, nBytes);
+          vector<string> errmsg;
+          _decoder->Decode(data, nBytes, errmsg);
+#ifdef DEBUG_RTCM2_2021
+          for (unsigned ii = 0; ii < errmsg.size(); ii++) {
+            emit newMessage(_staID + ": " + errmsg[ii].c_str());
+          }
+#endif
         }
         else {
@@ -553,5 +560,6 @@
         
             if (decode) { 
-              if ( _decoder->Decode(data, nBytes) == success ) { 
+              vector<string> errmsg;
+              if ( _decoder->Decode(data, nBytes, errmsg) == success ) { 
                 numSucc += 1;
               } 
@@ -559,4 +567,9 @@
                 decode = false;
               }
+#ifdef DEBUG_RTCM2_2021
+              for (unsigned ii = 0; ii < errmsg.size(); ii++) {
+                emit newMessage(_staID + ": " + errmsg[ii].c_str());
+              }
+#endif
             }
         
@@ -737,8 +750,8 @@
 	    bool dump = true;
 
-/*   // RTCMv2 XYZ
-     // ----------
-     RTCM2Decoder* decoder2 = dynamic_cast<RTCM2Decoder*>(_decoder);
-     if ( decoder2 && !_rnx_set_position ) {
+            // RTCMv2 XYZ
+            // ----------
+            RTCM2Decoder* decoder2 = dynamic_cast<RTCM2Decoder*>(_decoder);
+            if ( decoder2 && !_rnx_set_position ) {
 	      double stax, stay, staz;
 	      double dL1[3], dL2[3];
@@ -746,36 +759,24 @@
                                        dL1[0], dL1[1], dL1[2], 
                                        dL2[0], dL2[1], dL2[2]) == success ) {
-                QByteArray msg;
-                QTextStream out(&msg);
-                out.setRealNumberNotation(QTextStream::FixedNotation);
-                out.setRealNumberPrecision(5);
-                ////	_rnx->setApproxPos(stax, stay, staz);
-                out << "STA " << staID()
-                    << ' '    << qSetFieldWidth(15) << stax
-                    << ' '    << qSetFieldWidth(15) << stay
-                    << ' '    << qSetFieldWidth(15) << staz
-                    << " L1 " << qSetFieldWidth(10) << dL1[0]
-                    << ' '    << qSetFieldWidth(10) << dL1[1]
-                    << ' '    << qSetFieldWidth(10) << dL1[2]
-                    << " L2 " << qSetFieldWidth(10) << dL2[0]
-                    << ' '    << qSetFieldWidth(10) << dL2[1]
-                    << ' '    << qSetFieldWidth(10) << dL2[2] << endl;
+
+                ostringstream msg2; msg2.setf(ios::fixed);
+                msg2 << "station coordinates " << staID().data()
+                     << ' ' << setw(14) << setprecision(5) << stax
+                     << ' ' << setw(14) << setprecision(5) << stay
+                     << ' ' << setw(14) << setprecision(5) << staz
+                     << " L1 "
+                     << ' ' << setw(8)  << setprecision(5) << dL1[0]
+                     << ' ' << setw(8)  << setprecision(5) << dL1[1]
+                     << ' ' << setw(8)  << setprecision(5) << dL1[2]
+                     << " L2 "
+                     << ' ' << setw(8)  << setprecision(5) << dL2[0]
+                     << ' ' << setw(8)  << setprecision(5) << dL2[1]
+                     << ' ' << setw(8)  << setprecision(5) << dL2[2] 
+                     << ends;
 	    	_rnx_set_position = true;
-                emit newMessage(msg);
+                emit newMessage(QByteArray(msg2.str().c_str()));
               }
-            }  */
-
-	    ////RTCM2Decoder* decoder2 = dynamic_cast<RTCM2Decoder*>(_decoder);
-	    ////if ( decoder2 && !_rnx_set_position ) {
-	    ////  double stax, stay, staz;
-	    ////  if ( decoder2->getStaCrd(stax, stay, staz) == success ) {
-	    ////	_rnx->setApproxPos(stax, stay, staz);
-	    ////	_rnx_set_position = true;
-	    ////  }
-	    ////  else {
-	    ////	dump = false;
-	    ////  }
-	    ////}
-	      
+            }  
+
 	    if ( dump ) {
 	      long iSec    = long(floor(obs->_o.GPSWeeks+0.5));
@@ -942,6 +943,19 @@
     QMutexLocker locker(&_mutex);
   
-    decoder->storeEph(gpseph);
-  }
-}
-
+    string storedPRN;
+    vector<int> IODs;
+    
+    if ( decoder->storeEph(gpseph, storedPRN, IODs) ) {
+#ifdef DEBUG_RTCM2_2021
+      QString msg = _staID + QString(": stored eph %1 IODs").arg(storedPRN.c_str());
+      
+      for (unsigned ii = 0; ii < IODs.size(); ii++) {
+        msg += QString(" %1").arg(IODs[ii],4);
+      }
+      
+      emit(newMessage(msg.toAscii()));
+#endif
+    }
+  }
+}
+
Index: trunk/BNC/bncwindow.cpp
===================================================================
--- trunk/BNC/bncwindow.cpp	(revision 1216)
+++ trunk/BNC/bncwindow.cpp	(revision 1218)
@@ -67,5 +67,5 @@
 
   connect((bncApp*)qApp, SIGNAL(newMessage(QByteArray)), 
-          this, SLOT(slotWindowMessage(QByteArray)));
+           this, SLOT(slotWindowMessage(QByteArray)));
 
   // Create Actions
@@ -755,5 +755,9 @@
 void bncWindow::slotWindowMessage(const QByteArray msg) {
 
+#ifdef DEBUG_RTCM2_2021  
+  const int maxBufferSize = 1000;
+#else
   const int maxBufferSize = 10000;
+#endif
  
   QString txt = _log->toPlainText() + "\n" + 
Index: trunk/BNC/bnczerodecoder.cpp
===================================================================
--- trunk/BNC/bnczerodecoder.cpp	(revision 1216)
+++ trunk/BNC/bnczerodecoder.cpp	(revision 1218)
@@ -82,5 +82,6 @@
 // Decode Method
 //////////////////////////////////////////////////////////////////////// 
-t_irc bncZeroDecoder::Decode(char* buffer, int bufLen) {
+t_irc bncZeroDecoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
+  errmsg.clear();
   reopen();
   _out->write(buffer, bufLen);
Index: trunk/BNC/bnczerodecoder.h
===================================================================
--- trunk/BNC/bnczerodecoder.h	(revision 1216)
+++ trunk/BNC/bnczerodecoder.h	(revision 1218)
@@ -34,5 +34,5 @@
   bncZeroDecoder(const QString& fileName);
   ~bncZeroDecoder();
-  virtual t_irc Decode(char* buffer, int bufLen);
+  virtual t_irc Decode(char* buffer, int bufLen, std::vector<std::string>& errmsg);
  private:
   void reopen();
