Index: trunk/BNC/src/RTCM3/RTCM3coDecoder.cpp
===================================================================
--- trunk/BNC/src/RTCM3/RTCM3coDecoder.cpp	(revision 11003)
+++ trunk/BNC/src/RTCM3/RTCM3coDecoder.cpp	(revision 11004)
@@ -181,24 +181,28 @@
     struct SsrCorr::PhaseBias  phaseBiasSav;
     struct SsrCorr::VTEC       vTECSav;
-    memcpy(&clkOrbSav,     &_clkOrb,    sizeof(clkOrbSav)); // save state
+    struct SsrCorr::MetaData   metaDataSav;
+    // save state
+    memcpy(&clkOrbSav,     &_clkOrb,    sizeof(clkOrbSav)); 
     memcpy(&codeBiasSav,   &_codeBias,  sizeof(codeBiasSav));
     memcpy(&phaseBiasSav,  &_phaseBias, sizeof(phaseBiasSav));
     memcpy(&vTECSav,       &_vTEC,      sizeof(vTECSav));
+    memcpy(&metaDataSav,   &_metaData,  sizeof(metaDataSav));
 
     int bytesused = 0;
 
-    GCOB_RETURN irc = _ssrCorr->GetSSR(&_clkOrb, &_codeBias, &_vTEC, &_phaseBias,
+    GCOB_RETURN irc = _ssrCorr->GetSSR(&_clkOrb, &_codeBias, &_vTEC, &_phaseBias, &_metaData,
                                        _buffer.data(), _buffer.size(), &bytesused);
 
     if      (irc <= -30) { // not enough data - restore state and exit loop
-      memcpy(&_clkOrb,    &clkOrbSav,    sizeof(clkOrbSav));
-      memcpy(&_codeBias,  &codeBiasSav,  sizeof(codeBiasSav));
-      memcpy(&_phaseBias, &phaseBiasSav, sizeof(phaseBiasSav));
-      memcpy(&_vTEC,      &vTECSav,      sizeof(vTECSav));
+      memcpy(&_clkOrb,     &clkOrbSav,    sizeof(clkOrbSav));
+      memcpy(&_codeBias,   &codeBiasSav,  sizeof(codeBiasSav));
+      memcpy(&_phaseBias,  &phaseBiasSav, sizeof(phaseBiasSav));
+      memcpy(&_vTEC,       &vTECSav,      sizeof(vTECSav));
+      memcpy(&metaDataSav, &_metaData,    sizeof(metaDataSav));
       break;
     }
 
     else if (irc < 0) {    // error - skip this message (or 1 byte if the
-                            // frame itself couldn't be recognized) and retry
+                           // frame itself couldn't be recognized) and retry
       if (irc != GCOBR_UNKNOWNTYPE) {
         // A recognized-but-unimplemented message (e.g. Tropospheric or
Index: trunk/BNC/src/RTCM3/RTCM3coDecoder.h
===================================================================
--- trunk/BNC/src/RTCM3/RTCM3coDecoder.h	(revision 11003)
+++ trunk/BNC/src/RTCM3/RTCM3coDecoder.h	(revision 11004)
@@ -83,4 +83,5 @@
   SsrCorr::PhaseBias                    _phaseBias;
   SsrCorr::VTEC                         _vTEC;
+  SsrCorr::MetaData                     _metaData;
   int                                   _providerID[3];
   e_type                                _type;
Index: trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit.h
===================================================================
--- trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit.h	(revision 11003)
+++ trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit.h	(revision 11004)
@@ -21,5 +21,5 @@
 enum IGS_NUMBERS {
   RTCM_MESSAGE_NUMBER_IGS = 4076,
-  IGS_SSR_VERSION = 3
+  IGS_SSR_VERSION         = 3
 };
 
@@ -27,15 +27,17 @@
  for these systems to save space */
 enum COR_CONSTANTS {
-  CLOCKORBIT_BUFFERSIZE    = 8192,
-  CLOCKORBIT_NUMGPS        = t_prn::MAXPRN_GPS,
-  CLOCKORBIT_NUMGLONASS    = t_prn::MAXPRN_GLONASS,
-  CLOCKORBIT_NUMGALILEO    = t_prn::MAXPRN_GALILEO,
-  CLOCKORBIT_NUMQZSS       = t_prn::MAXPRN_QZSS,
-  CLOCKORBIT_NUMSBAS       = t_prn::MAXPRN_SBAS,
-  CLOCKORBIT_NUMBDS        = t_prn::MAXPRN_BDS,
-  CLOCKORBIT_NUMBIAS       = 150,
-  CLOCKORBIT_NUMIONOLAYERS =   4,
-  CLOCKORBIT_MAXIONOORDER  =  16,
-  CLOCKORBIT_MAXIONODEGREE =  16
+  COBOFS_MAXNUM          =   10,
+  CLOCKORBIT_BUFFERSIZE  = 8192,
+  CLOCKORBIT_NUMGPS      = t_prn::MAXPRN_GPS,
+  CLOCKORBIT_NUMGLONASS  = t_prn::MAXPRN_GLONASS,
+  CLOCKORBIT_NUMGALILEO  = t_prn::MAXPRN_GALILEO,
+  CLOCKORBIT_NUMQZSS     = t_prn::MAXPRN_QZSS,
+  CLOCKORBIT_NUMSBAS     = t_prn::MAXPRN_SBAS,
+  CLOCKORBIT_NUMBDS      = t_prn::MAXPRN_BDS,
+  CLOCKORBIT_NUMBIAS     =  150,
+  VTEC_NUMIONOLAYERS     =    4,
+  VTEC_MAXIONOORDER      =   16,
+  VTEC_MAXIONODEGREE     =   16,
+  META_MAXNUMENTRIES     =    7
 };
 
@@ -112,4 +114,5 @@
   CorBase COBBASE_NUM;
 
+
   typedef unsigned int CorOffset;
   CorOffset COBOFS_ORBIT;
@@ -349,5 +352,5 @@
 
 #define SSR_MAXURA 5.5 /* > 5466.5mm in meter */
-#define COBOFS_MAXNUM 7
+
 
   /* satellite system data is stored with offset CLOCKORBIT_OFFSET...
@@ -448,7 +451,26 @@
       unsigned int Degree; /* 1-16 */
       unsigned int Order;  /* 1-16 */
-      double Sinus[CLOCKORBIT_MAXIONODEGREE][CLOCKORBIT_MAXIONOORDER];
-      double Cosinus[CLOCKORBIT_MAXIONODEGREE][CLOCKORBIT_MAXIONOORDER];
-    } Layers[CLOCKORBIT_NUMIONOLAYERS];
+      double Sinus[VTEC_MAXIONODEGREE][VTEC_MAXIONOORDER];
+      double Cosinus[VTEC_MAXIONODEGREE][VTEC_MAXIONOORDER];
+    } Layers[VTEC_NUMIONOLAYERS];
+  };
+
+    struct MetaData {
+    unsigned int EpochTime; /* GPS */
+    unsigned int SSRIOD;
+    unsigned int SSRProviderID;
+    unsigned int SSRSolutionID;
+    unsigned int NumEntries; /* 1-7 */
+    struct ModelPart {
+      unsigned int TypeIndicator;
+      unsigned int ApplicationIndicator;
+      unsigned int nonDefaultIndicator;
+      unsigned int nonDefaultIdentifier;
+      unsigned int DataIODIndicator;
+      unsigned int DataIOD;
+      unsigned int additionalParameterIndicator;
+      unsigned int additionalParameterNumBits;
+      unsigned int additionalParameterData;
+    } Entries[META_MAXNUMENTRIES];
   };
 
@@ -458,10 +480,15 @@
   virtual size_t MakePhaseBias(const struct PhaseBias *b, CodeBiasType type, int moremessagesfollow, char *buffer, size_t size) = 0;
   virtual size_t MakeVTEC(const struct VTEC *v, int moremessagesfollow, char *buffer, size_t size) = 0;
-
   /* buffer should point to a RTCM3 block */
-  virtual enum GCOB_RETURN GetSSR(struct ClockOrbit *co, struct CodeBias *b, struct VTEC *v, struct PhaseBias *pb, 
+  virtual enum GCOB_RETURN GetSSR(struct ClockOrbit *co, 
+                                  struct CodeBias *b, struct VTEC *v, 
+                                  struct PhaseBias *pb,
+                                  struct MetaData *md,  
                                   const char *buffer, size_t size, int *bytesused) = 0;
+
+  virtual std::string metaTypeToStr(unsigned int ind) = 0;
   virtual std::string codeTypeToRnxType(char system, CodeType type) = 0;
-  virtual CodeType    rnxTypeToCodeType(char system, std::string type) = 0;
+  virtual CodeType rnxTypeToCodeType(char system, std::string type) = 0;
+
 
 #define MPI         3.141592653589793
Index: trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_igs.cpp
===================================================================
--- trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_igs.cpp	(revision 11003)
+++ trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_igs.cpp	(revision 11004)
@@ -315,5 +315,5 @@
 
 enum GCOB_RETURN SsrCorrIgs::GetSSR(struct ClockOrbit *co, struct CodeBias *b,struct VTEC *v,
-    struct PhaseBias *pb, const char *buffer, size_t size, int *bytesused) {
+    struct PhaseBias *pb, struct MetaData *md, const char *buffer, size_t size, int *bytesused) {
   int mmi = 0, h, rs;
   unsigned int igstype, pos, i, j, s, nums, id;
@@ -920,3 +920,10 @@
   return CODETYPE_RESERVED;
 }
-
+//
+////////////////////////////////////////////////////////////////////////////
+std::string SsrCorrIgs::metaTypeToStr(unsigned int) {
+  // This format does not decode Metadata message content (see md/GetSSR
+  // above); only present to satisfy SsrCorr's interface.
+  return "";
+}
+
Index: trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_igs.h
===================================================================
--- trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_igs.h	(revision 11003)
+++ trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_igs.h	(revision 11004)
@@ -217,5 +217,6 @@
    };
 
-   std::string       codeTypeToRnxType(char system, CodeType type);
+   std::string metaTypeToStr(unsigned int ind);
+   std::string codeTypeToRnxType(char system, CodeType type);
    SsrCorr::CodeType rnxTypeToCodeType(char system, std::string type);
 
@@ -229,6 +230,6 @@
        size_t size);
    enum GCOB_RETURN GetSSR(struct ClockOrbit *co, struct CodeBias *b,
-       struct VTEC *v, struct PhaseBias *pb, const char *buffer, size_t size,
-       int *bytesused);
+       struct VTEC *v, struct PhaseBias *pb, struct MetaData *md, 
+       const char *buffer, size_t size, int *bytesused);
 };
 
Index: trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm.cpp
===================================================================
--- trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm.cpp	(revision 11003)
+++ trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm.cpp	(revision 11004)
@@ -496,5 +496,5 @@
 
 enum GCOB_RETURN SsrCorrRtcm::GetSSR(struct ClockOrbit *co, struct CodeBias *b,struct VTEC *v,
-    struct PhaseBias *pb, const char *buffer, size_t size, int *bytesused) {
+    struct PhaseBias *pb, struct MetaData *md, const char *buffer, size_t size, int *bytesused) {
   int mmi = 0, h, rs;
   unsigned int type, pos, i, j, s, nums, id;
@@ -1375,3 +1375,11 @@
   return CODETYPE_RESERVED;
 }
-
+//
+////////////////////////////////////////////////////////////////////////////
+std::string SsrCorrRtcm::metaTypeToStr(unsigned int) {
+  // Metadata messages are not defined in (old) RTCM-SSR, so this format
+  // never decodes model-correction-type codes; only present to satisfy
+  // SsrCorr's interface.
+  return "";
+}
+
Index: trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm.h
===================================================================
--- trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm.h	(revision 11003)
+++ trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm.h	(revision 11004)
@@ -214,11 +214,8 @@
     CODETYPE_BDS_B2a_P          = 13;
     CODETYPE_BDS_B2a_DP         = 14;
-
-
-
-
   }
 
-  std::string       codeTypeToRnxType(char system, CodeType type);
+  std::string metaTypeToStr(unsigned int ind);
+  std::string codeTypeToRnxType(char system, CodeType type);
   SsrCorr::CodeType rnxTypeToCodeType(char system, std::string type);
 
@@ -232,5 +229,6 @@
       size_t size);
   enum GCOB_RETURN GetSSR(struct ClockOrbit *co, struct CodeBias *b,
-      struct VTEC *v, struct PhaseBias *pb, const char *buffer, size_t size,
+      struct VTEC *v, struct PhaseBias *pb, struct MetaData *md, 
+      const char *buffer, size_t size,
       int *bytesused);
  };
Index: trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm_new.cpp
===================================================================
--- trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm_new.cpp	(revision 11003)
+++ trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm_new.cpp	(revision 11004)
@@ -459,6 +459,6 @@
 }
 
-enum GCOB_RETURN SsrCorrRtcmNew::GetSSR(struct ClockOrbit *co, struct CodeBias *b,struct VTEC *v,
-    struct PhaseBias *pb, const char *buffer, size_t size, int *bytesused) {
+enum GCOB_RETURN SsrCorrRtcmNew::GetSSR(struct ClockOrbit *co, struct CodeBias *b, struct VTEC *v,
+    struct PhaseBias *pb, struct MetaData *md, const char *buffer, size_t size, int *bytesused) {
   int mmi = 0, h, rs;
   unsigned int type, pos, i, j, s, nums, id;
@@ -501,48 +501,48 @@
     *bytesused = sizeofrtcmblock + 6;
     
-  if (type == VTEC_BASE) {
-    unsigned int l, o, d;
-    if (!v)
+  if (type == METADATATYPE_BASE) {
+    unsigned int i;
+    if (!md)
       return GCOBR_NOVTECPARAMETER;
-    memset(v, 0, sizeof(*v));
-    D_GPS_EPOCH_TIME(v->EpochTime)
-    D_SSR_UPDATE_INTERVAL(v->UpdateInterval)
-    D_MULTIPLE_MESSAGE_INDICATOR(mmi)
-    D_SSR_IOD(v->SSRIOD)
-    D_SSR_PROVIDER_ID(v->SSRProviderID)
-    D_SSR_SOLUTION_ID(v->SSRSolutionID)
-    D_VTEC_QUALITY_INDICATOR(v->Quality)
-    D_NO_IONO_LAYERS(v->NumLayers)
-#ifdef BNC_DEBUG_SSR
-          fprintf(stderr, "epochTime %d ui %d mmi %d ssrIod %d providerId %d solId %d vtecQ %8.3f numLay %d \n",
-        		  v->EpochTime, v->UpdateInterval, mmi,
-				  v->SSRIOD, v->SSRProviderID, v->SSRSolutionID, v->Quality, v->NumLayers);
-#endif
-    for (l = 0; l < v->NumLayers; ++l) {
-      D_IONO_HEIGHT(v->Layers[l].Height)
-      D_IONO_DEGREE(v->Layers[l].Degree)
-      D_IONO_ORDER(v->Layers[l].Order)
-#ifdef BNC_DEBUG_SSR
-          fprintf(stderr, "h  %8.3f deg %d ord %d \n",
-        		  v->Layers[l].Height, v->Layers[l].Degree, v->Layers[l].Order);
-#endif
-      for (o = 0; o <= v->Layers[l].Order; ++o) {
-        for (d = o; d <= v->Layers[l].Degree; ++d) {
-          D_IONO_COEFF_C(v->Layers[l].Cosinus[d][o])
-#ifdef BNC_DEBUG_SSR
-          fprintf(stderr, "C[%02d][%02d]  %8.3f \n",
-        		  d, o, v->Layers[l].Cosinus[d][o]);
-#endif
-        }
-      }
-      for (o = 1; o <= v->Layers[l].Order; ++o) {
-        for (d = o; d <= v->Layers[l].Degree; ++d) {
-          D_IONO_COEFF_S(v->Layers[l].Sinus[d][o])
-#ifdef BNC_DEBUG_SSR
-          fprintf(stderr, "S[%02d][%02d]  %8.3f \n",
-        		  d, o, v->Layers[l].Sinus[d][o]);
-#endif
-        }
-      }
+    memset(md, 0, sizeof(*md));
+    D_SSR_IOD(md->SSRIOD)
+    D_SSR_PROVIDER_ID(md->SSRProviderID)
+    D_SSR_SOLUTION_ID(md->SSRSolutionID)
+    D_NUMBER_OF_SSR_MODEL_CORRECTION_ENTRIES(md->NumEntries)
+#ifdef BNC_DEBUG_SSR
+          fprintf(stderr, "ssrIod %d providerId %d solId %d numEntries %d \n",
+        		      md->SSRIOD, md->SSRProviderID, md->SSRSolutionID, md->NumEntries);
+#endif 
+    for (i = 0; i < md->NumEntries; ++i) {
+      unsigned int numbits;
+      D_MODEL_CORRECTION_TYPE_INDICATOR(md->Entries[i].TypeIndicator)
+      D_MODEL_CORRECTION_APPLICATION_INDICATOR(md->Entries[i].ApplicationIndicator)
+
+      D_NON_DEFAULT_MODEL_CORRECTION_INDICATOR(md->Entries[i].nonDefaultIndicator)
+      if (md->Entries[i].ApplicationIndicator) {
+        D_NON_DEFAULT_MODEL_CORRECTION_IDENTIFIER(md->Entries[i].nonDefaultIdentifier)
+      }
+      D_MODEL_CORRECTION_DATA_IOD_INDICATOR(md->Entries[i].DataIODIndicator)
+      if (md->Entries[i].DataIODIndicator) {
+        D_MODEL_CORRECTION_DATA_IOD(md->Entries[i].DataIOD)
+      }
+      if (md->Entries[i].nonDefaultIndicator) {
+        D_ADDITIONAL_MODEL_PARAMETER_INDICATOR(md->Entries[i].additionalParameterIndicator)
+      }
+      if (md->Entries[i].additionalParameterIndicator) {
+        D_NUMBER_OF_ADDITIONAL_MODEL_PARAMETER_BITS(numbits)
+        md->Entries[i].additionalParameterNumBits = numbits;
+      }
+      if (md->Entries[i].nonDefaultIndicator && 
+          md->Entries[i].additionalParameterIndicator) {
+        D_ADDITIONAL_MODEL_PARAMETER_DATA(md->Entries[i].additionalParameterData, numbits)
+      }
+      
+#ifdef BNC_DEBUG_SSR
+      fprintf(stderr, "entry %d type (%s) apply: %s \n",
+        		  i, md->Entries[i].TypeIndicator, metaTypeToStr(md->Entries[i].TypeIndicator),
+              md->Entries[i].ApplicationIndicator ? "yes" : "no");
+#endif
+
     }
 #ifdef BNC_DEBUG_SSR
@@ -1050,6 +1050,7 @@
           }
     }
+    //else if (kind == COBOFS_)
     else {
-      /* COBOFS_PBEXT / COBOFS_SATANT / COBOFS_REGIONO: message numbers are
+      /* COBOFS_SATANT / COBOFS_REGIONO: message numbers are
          recognized (see setCorType()) but decoding is not implemented yet */
       return GCOBR_UNKNOWNTYPE;
@@ -1234,3 +1235,15 @@
   return CODETYPE_RESERVED;
 }
-
+//
+////////////////////////////////////////////////////////////////////////////
+std::string SsrCorrRtcmNew::metaTypeToStr(unsigned int ind) {
+      if (ind == 1) return "satellite antenna PCV: ";
+      if (ind == 2) return "satellite antenna GDV: ";
+      if (ind == 3) return "solid earth tides: ";
+      if (ind == 4) return "ocean loading: ";
+      if (ind == 5) return "pole tides: ";
+      if (ind == 6) return "relativity: ";
+      if (ind == 7) return "GNSS BE reference: ";      
+
+  return "reserved!";      
+}
Index: trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm_new.h
===================================================================
--- trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm_new.h	(revision 11003)
+++ trunk/BNC/src/RTCM3/clock_and_orbit/clock_orbit_rtcm_new.h	(revision 11004)
@@ -269,6 +269,7 @@
     }
   }
-
-  std::string       codeTypeToRnxType(char system, CodeType type);
+  
+  std::string metaTypeToStr(unsigned int ind);
+  std::string codeTypeToRnxType(char system, CodeType type);
   SsrCorr::CodeType rnxTypeToCodeType(char system, std::string type);
 
@@ -277,5 +278,7 @@
   size_t MakePhaseBias(const struct PhaseBias *b, PhaseBiasType type, int moremessagesfollow, char *buffer, size_t size);
   size_t MakeVTEC(const struct VTEC *v, int moremessagesfollow, char *buffer, size_t size);
-  enum GCOB_RETURN GetSSR(struct ClockOrbit *co, struct CodeBias *b, struct VTEC *v, struct PhaseBias *pb, const char *buffer, size_t size, int *bytesused);
+  enum GCOB_RETURN GetSSR(struct ClockOrbit *co, struct CodeBias *b, struct VTEC *v, 
+                          struct PhaseBias *pb, struct MetaData *md, 
+                          const char *buffer, size_t size, int *bytesused);
  };
 
