Index: trunk/rtcm3torinex/lib/rtcm3torinex.c
===================================================================
--- trunk/rtcm3torinex/lib/rtcm3torinex.c	(revision 5356)
+++ trunk/rtcm3torinex/lib/rtcm3torinex.c	(revision 5358)
@@ -1225,5 +1225,5 @@
         int rrint[RTCM3_MSM_NUMSAT], rdop[RTCM3_MSM_NUMSAT],
         extsat[RTCM3_MSM_NUMSAT];
-        int ll[RTCM3_MSM_NUMCELLS], hc[RTCM3_MSM_NUMCELLS];
+        int ll[RTCM3_MSM_NUMCELLS]/*, hc[RTCM3_MSM_NUMCELLS]*/;
         double cnr[RTCM3_MSM_NUMCELLS];
         double cp[RTCM3_MSM_NUMCELLS], psr[RTCM3_MSM_NUMCELLS],
@@ -1357,5 +1357,5 @@
             for(count = numcells; count--;)
               if(cellmask & (UINT64(1)<<count))
-                GETBITS(hc[count], 1)
+                SKIPBITS(1)/*GETBITS(hc[count], 1)*/
             break;
           case 3:
@@ -1371,5 +1371,5 @@
             for(count = numcells; count--;)
               if(cellmask & (UINT64(1)<<count))
-                GETBITS(hc[count], 1)
+                SKIPBITS(1)/*GETBITS(hc[count], 1)*/
             break;
           case 4:
@@ -1385,5 +1385,5 @@
             for(count = numcells; count--;)
               if(cellmask & (UINT64(1)<<count))
-                GETBITS(hc[count], 1)
+                SKIPBITS(1)/*GETBITS(hc[count], 1)*/
             for(count = numcells; count--;)
               if(cellmask & (UINT64(1)<<count))
@@ -1402,5 +1402,5 @@
             for(count = numcells; count--;)
               if(cellmask & (UINT64(1)<<count))
-                GETBITS(hc[count], 1)
+                SKIPBITS(1)/*GETBITS(hc[count], 1)*/
             for(count = numcells; count--;)
               if(cellmask & (UINT64(1)<<count))
@@ -1422,5 +1422,5 @@
             for(count = numcells; count--;)
               if(cellmask & (UINT64(1)<<count))
-                GETBITS(hc[count], 1)
+                SKIPBITS(1)/*GETBITS(hc[count], 1)*/
             for(count = numcells; count--;)
               if(cellmask & (UINT64(1)<<count))
@@ -1439,5 +1439,5 @@
             for(count = numcells; count--;)
               if(cellmask & (UINT64(1)<<count))
-                GETBITS(hc[count], 1)
+                SKIPBITS(1)/*GETBITS(hc[count], 1)*/
             for(count = numcells; count--;)
               if(cellmask & (UINT64(1)<<count))
@@ -1822,4 +1822,352 @@
 #define NUMSTARTSKIP 3
 #endif
+
+int HandleObsHeader(struct RTCM3ParserData *Parser, char *buffer,
+size_t buffersize, struct HeaderData *hdata)
+{
+  int buffersizeold = buffersize;
+  int i, modified = 0;
+
+  if(Parser->rinex3)
+  {
+    int flags;
+#define CHECKFLAGSNEW(a, b, c) \
+    if(flags & GNSSDF_##b##DATA) \
+    { \
+      int new = hdata ? 1 : 0; \
+      if(!hdata) /* check if already known */ \
+      { \
+        int ic; \
+        for(ic = 0; ic < Parser->info[RTCM3_MSM_##a].numtypes \
+        && Parser->info[RTCM3_MSM_##a].flags[ic] != GNSSDF_##b##DATA; ++ic) \
+          ; \
+        if(ic == Parser->info[RTCM3_MSM_##a].numtypes) \
+          new = 1; \
+      } \
+      if(new) \
+      { \
+        Parser->info[RTCM3_MSM_##a].flags[Parser->info[RTCM3_MSM_##a].numtypes] \
+        = GNSSDF_##b##DATA; \
+        Parser->info[RTCM3_MSM_##a].pos[Parser->info[RTCM3_MSM_##a].numtypes] \
+        = GNSSENTRY_##b##DATA; \
+        if(Parser->info[RTCM3_MSM_##a].type[GNSSENTRY_##b##DATA]) \
+        { \
+          snprintf(Parser->fieldbuffer##a+4*Parser->info[RTCM3_MSM_##a].numtypes, \
+          sizeof(Parser->fieldbuffer##a)-4*Parser->info[RTCM3_MSM_##a].numtypes, \
+          " %-2.2s%c", #c, Parser->info[RTCM3_MSM_##a].type[GNSSENTRY_##b##DATA]); \
+        } \
+        else \
+        { \
+          snprintf(Parser->fieldbuffer##a+4*Parser->info[RTCM3_MSM_##a].numtypes, \
+          sizeof(Parser->fieldbuffer##a)-4*Parser->info[RTCM3_MSM_##a].numtypes, \
+          " %-3s", #c); \
+        } \
+        ++Parser->info[RTCM3_MSM_##a].numtypes; \
+        ++modified; \
+      } \
+    }
+
+#define INITFLAGS(a) \
+    flags = Parser->startflags; \
+    modified = 0; \
+    for(i = 0; i < Parser->Data.numsats; ++i) \
+    { \
+      if(Parser->Data.satellites[i] >= PRN_##a##_START \
+      && Parser->Data.satellites[i] <= PRN_##a##_END) \
+        flags |= Parser->Data.dataflags[i]; \
+    }
+
+    INITFLAGS(SBAS)
+    CHECKFLAGSNEW(SBAS, C1,  C1C)
+    CHECKFLAGSNEW(SBAS, L1C, L1C)
+    CHECKFLAGSNEW(SBAS, D1C, D1C)
+    CHECKFLAGSNEW(SBAS, S1C, S1C)
+    CHECKFLAGSNEW(SBAS, C5,  C5)
+    CHECKFLAGSNEW(SBAS, L5,  L5)
+    CHECKFLAGSNEW(SBAS, D5,  D5)
+    CHECKFLAGSNEW(SBAS, S5,  S5)
+
+    if(modified)
+    {
+      if(hdata)
+        hdata->data.named.typesofobsS = buffer;
+      i = 1+snprintf(buffer, buffersize,
+      "S  %3d%-52.52s  SYS / # / OBS TYPES",
+      Parser->info[RTCM3_MSM_SBAS].numtypes, Parser->fieldbufferSBAS);
+      buffer += i; buffersize -= i;
+    }
+
+    INITFLAGS(GPS)
+    CHECKFLAGSNEW(GPS, C1,  C1C)
+    CHECKFLAGSNEW(GPS, L1C, L1C)
+    CHECKFLAGSNEW(GPS, D1C, D1C)
+    CHECKFLAGSNEW(GPS, S1C, S1C)
+    CHECKFLAGSNEW(GPS, P1,  C1W)
+    CHECKFLAGSNEW(GPS, L1P, L1W)
+    CHECKFLAGSNEW(GPS, D1P, D1W)
+    CHECKFLAGSNEW(GPS, S1P, S1W)
+    CHECKFLAGSNEW(GPS, C5,  C5)
+    CHECKFLAGSNEW(GPS, L5,  L5)
+    CHECKFLAGSNEW(GPS, D5,  D5)
+    CHECKFLAGSNEW(GPS, S5,  S5)
+    CHECKFLAGSNEW(GPS, P2,  C2W)
+    CHECKFLAGSNEW(GPS, L2P, L2W)
+    CHECKFLAGSNEW(GPS, D2P, D2W)
+    CHECKFLAGSNEW(GPS, S2P, S2W)
+    CHECKFLAGSNEW(GPS, C2,  C2)
+    CHECKFLAGSNEW(GPS, L2C, L2)
+    CHECKFLAGSNEW(GPS, D2C, D2)
+    CHECKFLAGSNEW(GPS, S2C, S2)
+    CHECKFLAGSNEW(GPS, C1N, C1)
+    CHECKFLAGSNEW(GPS, L1N, L1)
+    CHECKFLAGSNEW(GPS, D1N, D1)
+    CHECKFLAGSNEW(GPS, S1N, S1)
+
+    if(modified)
+    {
+      if(hdata)
+        hdata->data.named.typesofobsG = buffer;
+      i = 1+snprintf(buffer, buffersize,
+      "G  %3d%-52.52s  SYS / # / OBS TYPES",
+      Parser->info[RTCM3_MSM_GPS].numtypes, Parser->fieldbufferGPS);
+      if(Parser->info[RTCM3_MSM_GPS].numtypes>13)
+      {
+        i += snprintf(buffer+i-1, buffersize,
+        "\n      %-52.52s  SYS / # / OBS TYPES", Parser->fieldbufferGPS+13*4);
+      }
+      buffer += i; buffersize -= i;
+    }
+
+    INITFLAGS(GLONASS)
+    CHECKFLAGSNEW(GLONASS, C1,  C1C)
+    CHECKFLAGSNEW(GLONASS, L1C, L1C)
+    CHECKFLAGSNEW(GLONASS, D1C, D1C)
+    CHECKFLAGSNEW(GLONASS, S1C, S1C)
+    CHECKFLAGSNEW(GLONASS, P1,  C1P)
+    CHECKFLAGSNEW(GLONASS, L1P, L1P)
+    CHECKFLAGSNEW(GLONASS, D1P, D1P)
+    CHECKFLAGSNEW(GLONASS, S1P, S1P)
+    CHECKFLAGSNEW(GLONASS, P2,  C2P)
+    CHECKFLAGSNEW(GLONASS, L2P, L2P)
+    CHECKFLAGSNEW(GLONASS, D2P, D2P)
+    CHECKFLAGSNEW(GLONASS, S2P, S2P)
+    CHECKFLAGSNEW(GLONASS, C2,  C2C)
+    CHECKFLAGSNEW(GLONASS, L2C, L2C)
+    CHECKFLAGSNEW(GLONASS, D2C, D2C)
+    CHECKFLAGSNEW(GLONASS, S2C, S2C)
+
+    if(modified)
+    {
+      if(hdata)
+        hdata->data.named.typesofobsR = buffer;
+      i = 1+snprintf(buffer, buffersize,
+      "R  %3d%-52.52s  SYS / # / OBS TYPES",
+      Parser->info[RTCM3_MSM_GLONASS].numtypes, Parser->fieldbufferGLONASS);
+      if(Parser->info[RTCM3_MSM_GLONASS].numtypes>13)
+      {
+        i += snprintf(buffer+i-1, buffersize,
+        "\n      %-52.52s  SYS / # / OBS TYPES", Parser->fieldbufferGLONASS+13*4);
+      }
+      buffer += i; buffersize -= i;
+    }
+
+    INITFLAGS(GALGIO)
+    CHECKFLAGSNEW(GALILEO, C1,   C1)
+    CHECKFLAGSNEW(GALILEO, L1C,  L1)
+    CHECKFLAGSNEW(GALILEO, D1C,  D1)
+    CHECKFLAGSNEW(GALILEO, S1C,  S1)
+    CHECKFLAGSNEW(GALILEO, C6,   C6)
+    CHECKFLAGSNEW(GALILEO, L6,   L6)
+    CHECKFLAGSNEW(GALILEO, D6,   D6)
+    CHECKFLAGSNEW(GALILEO, S6,   S6)
+    CHECKFLAGSNEW(GALILEO, C5,   C5)
+    CHECKFLAGSNEW(GALILEO, L5,   L5)
+    CHECKFLAGSNEW(GALILEO, D5,   D5)
+    CHECKFLAGSNEW(GALILEO, S5,   S5)
+    CHECKFLAGSNEW(GALILEO, C5B,  C7)
+    CHECKFLAGSNEW(GALILEO, L5B,  L7)
+    CHECKFLAGSNEW(GALILEO, D5B,  D7)
+    CHECKFLAGSNEW(GALILEO, S5B,  S7)
+    CHECKFLAGSNEW(GALILEO, C5AB, C8)
+    CHECKFLAGSNEW(GALILEO, L5AB, L8)
+    CHECKFLAGSNEW(GALILEO, D5AB, D8)
+    CHECKFLAGSNEW(GALILEO, S5AB, S8)
+
+    if(modified)
+    {
+      if(hdata)
+        hdata->data.named.typesofobsE = buffer;
+      i = 1+snprintf(buffer, buffersize,
+      "E  %3d%-52.52s  SYS / # / OBS TYPES",
+      Parser->info[RTCM3_MSM_GALILEO].numtypes, Parser->fieldbufferGALILEO);
+      if(Parser->info[RTCM3_MSM_GALILEO].numtypes>13)
+      {
+        i += snprintf(buffer+i-1, buffersize,
+        "\n      %-52.52s  SYS / # / OBS TYPES", Parser->fieldbufferGALILEO+13*4);
+      }
+      buffer += i; buffersize -= i;
+    }
+
+    INITFLAGS(COMPASS)
+    CHECKFLAGSNEW(COMPASS, CB1,  C2I)
+    CHECKFLAGSNEW(COMPASS, LB1,  L2I)
+    CHECKFLAGSNEW(COMPASS, DB1,  D2I)
+    CHECKFLAGSNEW(COMPASS, SB1,  S2I)
+    CHECKFLAGSNEW(COMPASS, CB2,  C7I)
+    CHECKFLAGSNEW(COMPASS, LB2,  L7I)
+    CHECKFLAGSNEW(COMPASS, DB2,  D7I)
+    CHECKFLAGSNEW(COMPASS, SB2,  S7I)
+    CHECKFLAGSNEW(COMPASS, CB3,  C6I)
+    CHECKFLAGSNEW(COMPASS, LB3,  L6I)
+    CHECKFLAGSNEW(COMPASS, DB3,  D6I)
+    CHECKFLAGSNEW(COMPASS, SB3,  S6I)
+
+    if(modified)
+    {
+      if(hdata)
+        hdata->data.named.typesofobsC = buffer;
+      i = 1+snprintf(buffer, buffersize,
+      "C  %3d%-52.52s  SYS / # / OBS TYPES",
+      Parser->info[RTCM3_MSM_COMPASS].numtypes, Parser->fieldbufferCOMPASS);
+      if(Parser->info[RTCM3_MSM_COMPASS].numtypes>13)
+      {
+        i += snprintf(buffer+i-1, buffersize,
+        "\n      %-52.52s  SYS / # / OBS TYPES", Parser->fieldbufferCOMPASS+13*4);
+      }
+      buffer += i; buffersize -= i;
+    }
+
+    INITFLAGS(QZSS)
+
+    CHECKFLAGSNEW(QZSS, C1,  C1C)
+    CHECKFLAGSNEW(QZSS, L1C, L1C)
+    CHECKFLAGSNEW(QZSS, D1C, D1C)
+    CHECKFLAGSNEW(QZSS, S1C, S1C)
+
+    CHECKFLAGSNEW(QZSS, CSAIF, C1Z)
+    CHECKFLAGSNEW(QZSS, LSAIF, L1Z)
+    CHECKFLAGSNEW(QZSS, DSAIF, D1Z)
+    CHECKFLAGSNEW(QZSS, SSAIF, S1Z)
+
+    CHECKFLAGSNEW(QZSS, C1N, C1)
+    CHECKFLAGSNEW(QZSS, L1N, L1)
+    CHECKFLAGSNEW(QZSS, D1N, D1)
+    CHECKFLAGSNEW(QZSS, S1N, S1)
+
+    CHECKFLAGSNEW(QZSS, C6, C6)
+    CHECKFLAGSNEW(QZSS, L6, L6)
+    CHECKFLAGSNEW(QZSS, D6, D6)
+    CHECKFLAGSNEW(QZSS, S6, S6)
+
+    CHECKFLAGSNEW(QZSS, C2,  C2)
+    CHECKFLAGSNEW(QZSS, L2C, L2)
+    CHECKFLAGSNEW(QZSS, D2C, D2)
+    CHECKFLAGSNEW(QZSS, S2C, S2)
+
+    CHECKFLAGSNEW(QZSS, C5,  C5)
+    CHECKFLAGSNEW(QZSS, L5,  L5)
+    CHECKFLAGSNEW(QZSS, D5,  D5)
+    CHECKFLAGSNEW(QZSS, S5,  S5)
+
+    if(modified)
+    {
+      if(hdata)
+        hdata->data.named.typesofobsJ = buffer;
+      i = 1+snprintf(buffer, buffersize,
+      "J  %3d%-52.52s  SYS / # / OBS TYPES",
+      Parser->info[RTCM3_MSM_QZSS].numtypes, Parser->fieldbufferQZSS);
+      if(Parser->info[RTCM3_MSM_QZSS].numtypes>13)
+      {
+        i += snprintf(buffer+i-1, buffersize,
+        "\n      %-52.52s  SYS / # / OBS TYPES", Parser->fieldbufferQZSS+13*4);
+      }
+      buffer += i; buffersize -= i;
+    }
+  }
+  else
+  {
+#define CHECKFLAGS(a, b) \
+    if(flags & GNSSDF_##a##DATA) \
+    { \
+      if(Parser->datafields[RINEXENTRY_##b##DATA]) \
+      { \
+        Parser->info[RTCM3_MSM_GPS].flags[Parser->datafields[\
+        RINEXENTRY_##b##DATA]-1] = GNSSDF_##a##DATA; \
+        Parser->info[RTCM3_MSM_GPS].pos[Parser->datafields[\
+        RINEXENTRY_##b##DATA]-1] = GNSSENTRY_##a##DATA; \
+      } \
+      else \
+      { \
+        Parser->flags[Parser->info[RTCM3_MSM_GPS].numtypes] = GNSSDF_##a##DATA; \
+        Parser->pos[Parser->info[RTCM3_MSM_GPS].numtypes] = GNSSENTRY_##a##DATA; \
+        Parser->datafields[RINEXENTRY_##b##DATA] = \
+        ++Parser->info[RTCM3_MSM_GPS].numtypes; \
+        snprintf(Parser->fieldbuffer+6*Parser->numdatafields, \
+        sizeof(Parser->fieldbuffer)-6*Parser->numdatafields, "    "#b); \
+        ++Parser->numdatafields; \
+        ++modified; \
+      } \
+    }
+
+    int flags = Parser->startflags;
+    for(i = 0; i < Parser->Data.numsats; ++i)
+      flags |= Parser->Data.dataflags[i];
+
+    CHECKFLAGS(C1,C1)
+    CHECKFLAGS(C2,C2)
+    CHECKFLAGS(P1,P1)
+    CHECKFLAGS(P2,P2)
+    CHECKFLAGS(L1C,L1)
+    CHECKFLAGS(L1P,L1)
+    CHECKFLAGS(L2C,L2)
+    CHECKFLAGS(L2P,L2)
+    CHECKFLAGS(D1C,D1)
+    CHECKFLAGS(D1P,D1)
+    CHECKFLAGS(D2C,D2)
+    CHECKFLAGS(D2P,D2)
+    CHECKFLAGS(S1C,S1)
+    CHECKFLAGS(S1P,S1)
+    CHECKFLAGS(S2C,S2)
+    CHECKFLAGS(S2P,S2)
+    CHECKFLAGS(C5,C5)
+    CHECKFLAGS(L5,L5)
+    CHECKFLAGS(D5,D5)
+    CHECKFLAGS(S5,S5)
+    CHECKFLAGS(C5AB,C8)
+    CHECKFLAGS(L5AB,L8)
+    CHECKFLAGS(D5AB,D8)
+    CHECKFLAGS(S5AB,S8)
+    CHECKFLAGS(C5B,C7)
+    CHECKFLAGS(L5B,L7)
+    CHECKFLAGS(D5B,D7)
+    CHECKFLAGS(S5B,S7)
+    CHECKFLAGS(C6,C6)
+    CHECKFLAGS(L6,L6)
+    CHECKFLAGS(D6,D6)
+    CHECKFLAGS(S6,S6)
+    /* Skip C1N and SAIF for RINEX2! */
+
+    if(hdata)
+      hdata->data.named.typesofobs = buffer;
+    if(modified)
+    {
+      i = 1+snprintf(buffer, buffersize,
+      "%6d%-54.54s# / TYPES OF OBSERV", Parser->info[RTCM3_MSM_GPS].numtypes,
+      Parser->fieldbuffer);
+      if(Parser->info[RTCM3_MSM_GPS].numtypes>9)
+      {
+        i += snprintf(buffer+i-1, buffersize,
+        "\n      %-54.54s# / TYPES OF OBSERV", Parser->fieldbuffer+9*6);
+      }
+      if(Parser->info[RTCM3_MSM_GPS].numtypes>18)
+      {
+        i += snprintf(buffer+i-1, buffersize,
+        "\n      %-54.54s# / TYPES OF OBSERV", Parser->fieldbuffer+18*6);
+      }
+      buffer += i; buffersize -= i;
+    }
+  }
+  return buffersizeold - buffersize;
+}
 
 void HandleHeader(struct RTCM3ParserData *Parser)
@@ -1983,286 +2331,6 @@
   hdata.numheaders = 18;
 
-  if(Parser->rinex3)
-  {
-#define CHECKFLAGSNEW(a, b, c) \
-    if(flags & GNSSDF_##b##DATA) \
-    { \
-      Parser->info[RTCM3_MSM_##a].flags[Parser->info[RTCM3_MSM_##a].numtypes] \
-      = GNSSDF_##b##DATA; \
-      Parser->info[RTCM3_MSM_##a].pos[Parser->info[RTCM3_MSM_##a].numtypes] \
-      = GNSSENTRY_##b##DATA; \
-      ++Parser->info[RTCM3_MSM_##a].numtypes; \
-      if(Parser->info[RTCM3_MSM_##a].type[GNSSENTRY_##b##DATA]) \
-        snprintf(tbuffer+tbufferpos, sizeof(tbuffer)-tbufferpos, " %-2.2s%c", #c,\
-        Parser->info[RTCM3_MSM_##a].type[GNSSENTRY_##b##DATA]); \
-      else \
-        snprintf(tbuffer+tbufferpos, sizeof(tbuffer)-tbufferpos, " %-3s", #c); \
-      tbufferpos += 4; \
-    }
-
-    int flags = Parser->startflags;
-    char tbuffer[6*RINEXENTRY_NUMBER+1];
-    int tbufferpos = 0;
-    for(i = 0; i < Parser->Data.numsats; ++i)
-      flags |= Parser->Data.dataflags[i];
-
-    CHECKFLAGSNEW(SBAS, C1,  C1C)
-    CHECKFLAGSNEW(SBAS, L1C, L1C)
-    CHECKFLAGSNEW(SBAS, D1C, D1C)
-    CHECKFLAGSNEW(SBAS, S1C, S1C)
-    CHECKFLAGSNEW(SBAS, C5,  C5)
-    CHECKFLAGSNEW(SBAS, L5,  L5)
-    CHECKFLAGSNEW(SBAS, D5,  D5)
-    CHECKFLAGSNEW(SBAS, S5,  S5)
-
-    hdata.data.named.typesofobsS = buffer;
-    i = 1+snprintf(buffer, buffersize,
-    "S  %3d%-52.52s  SYS / # / OBS TYPES", Parser->info[RTCM3_MSM_SBAS].numtypes, tbuffer);
-    buffer += i; buffersize -= i;
-
-    tbufferpos = 0;
-
-    CHECKFLAGSNEW(GPS, C1,  C1C)
-    CHECKFLAGSNEW(GPS, L1C, L1C)
-    CHECKFLAGSNEW(GPS, D1C, D1C)
-    CHECKFLAGSNEW(GPS, S1C, S1C)
-    CHECKFLAGSNEW(GPS, P1,  C1W)
-    CHECKFLAGSNEW(GPS, L1P, L1W)
-    CHECKFLAGSNEW(GPS, D1P, D1W)
-    CHECKFLAGSNEW(GPS, S1P, S1W)
-    CHECKFLAGSNEW(GPS, C5,  C5)
-    CHECKFLAGSNEW(GPS, L5,  L5)
-    CHECKFLAGSNEW(GPS, D5,  D5)
-    CHECKFLAGSNEW(GPS, S5,  S5)
-    CHECKFLAGSNEW(GPS, P2,  C2W)
-    CHECKFLAGSNEW(GPS, L2P, L2W)
-    CHECKFLAGSNEW(GPS, D2P, D2W)
-    CHECKFLAGSNEW(GPS, S2P, S2W)
-    CHECKFLAGSNEW(GPS, C2,  C2)
-    CHECKFLAGSNEW(GPS, L2C, L2)
-    CHECKFLAGSNEW(GPS, D2C, D2)
-    CHECKFLAGSNEW(GPS, S2C, S2)
-    CHECKFLAGSNEW(GPS, C1N, C1)
-    CHECKFLAGSNEW(GPS, L1N, L1)
-    CHECKFLAGSNEW(GPS, D1N, D1)
-    CHECKFLAGSNEW(GPS, S1N, S1)
-
-    hdata.data.named.typesofobsG = buffer;
-    i = 1+snprintf(buffer, buffersize,
-    "G  %3d%-52.52s  SYS / # / OBS TYPES", Parser->info[RTCM3_MSM_GPS].numtypes, tbuffer);
-    if(Parser->info[RTCM3_MSM_GPS].numtypes>13)
-    {
-      i += snprintf(buffer+i-1, buffersize,
-      "\n      %-52.52s  SYS / # / OBS TYPES", tbuffer+13*4);
-    }
-    buffer += i; buffersize -= i;
-
-    tbufferpos = 0;
-
-    CHECKFLAGSNEW(GLONASS, C1,  C1C)
-    CHECKFLAGSNEW(GLONASS, L1C, L1C)
-    CHECKFLAGSNEW(GLONASS, D1C, D1C)
-    CHECKFLAGSNEW(GLONASS, S1C, S1C)
-    CHECKFLAGSNEW(GLONASS, P1,  C1P)
-    CHECKFLAGSNEW(GLONASS, L1P, L1P)
-    CHECKFLAGSNEW(GLONASS, D1P, D1P)
-    CHECKFLAGSNEW(GLONASS, S1P, S1P)
-    CHECKFLAGSNEW(GLONASS, P2,  C2P)
-    CHECKFLAGSNEW(GLONASS, L2P, L2P)
-    CHECKFLAGSNEW(GLONASS, D2P, D2P)
-    CHECKFLAGSNEW(GLONASS, S2P, S2P)
-    CHECKFLAGSNEW(GLONASS, C2,  C2C)
-    CHECKFLAGSNEW(GLONASS, L2C, L2C)
-    CHECKFLAGSNEW(GLONASS, D2C, D2C)
-    CHECKFLAGSNEW(GLONASS, S2C, S2C)
-
-    hdata.data.named.typesofobsR = buffer;
-    i = 1+snprintf(buffer, buffersize,
-    "R  %3d%-52.52s  SYS / # / OBS TYPES", Parser->info[RTCM3_MSM_GLONASS].numtypes, tbuffer);
-    if(Parser->info[RTCM3_MSM_GLONASS].numtypes>13)
-    {
-      i += snprintf(buffer+i-1, buffersize,
-      "\n      %-52.52s  SYS / # / OBS TYPES", tbuffer+13*4);
-    }
-    buffer += i; buffersize -= i;
-
-    tbufferpos = 0;
-
-    CHECKFLAGSNEW(GALILEO, C1,   C1)
-    CHECKFLAGSNEW(GALILEO, L1C,  L1)
-    CHECKFLAGSNEW(GALILEO, D1C,  D1)
-    CHECKFLAGSNEW(GALILEO, S1C,  S1)
-    CHECKFLAGSNEW(GALILEO, C6,   C6)
-    CHECKFLAGSNEW(GALILEO, L6,   L6)
-    CHECKFLAGSNEW(GALILEO, D6,   D6)
-    CHECKFLAGSNEW(GALILEO, S6,   S6)
-    CHECKFLAGSNEW(GALILEO, C5,   C5)
-    CHECKFLAGSNEW(GALILEO, L5,   L5)
-    CHECKFLAGSNEW(GALILEO, D5,   D5)
-    CHECKFLAGSNEW(GALILEO, S5,   S5)
-    CHECKFLAGSNEW(GALILEO, C5B,  C7)
-    CHECKFLAGSNEW(GALILEO, L5B,  L7)
-    CHECKFLAGSNEW(GALILEO, D5B,  D7)
-    CHECKFLAGSNEW(GALILEO, S5B,  S7)
-    CHECKFLAGSNEW(GALILEO, C5AB, C8)
-    CHECKFLAGSNEW(GALILEO, L5AB, L8)
-    CHECKFLAGSNEW(GALILEO, D5AB, D8)
-    CHECKFLAGSNEW(GALILEO, S5AB, S8)
-
-    hdata.data.named.typesofobsE = buffer;
-    i = 1+snprintf(buffer, buffersize,
-    "E  %3d%-52.52s  SYS / # / OBS TYPES", Parser->info[RTCM3_MSM_GALILEO].numtypes, tbuffer);
-    if(Parser->info[RTCM3_MSM_GALILEO].numtypes>13)
-    {
-      i += snprintf(buffer+i-1, buffersize,
-      "\n      %-52.52s  SYS / # / OBS TYPES", tbuffer+13*4);
-    }
-    buffer += i; buffersize -= i;
-
-    tbufferpos = 0;
-
-    CHECKFLAGSNEW(COMPASS, CB1,  C2I)
-    CHECKFLAGSNEW(COMPASS, LB1,  L2I)
-    CHECKFLAGSNEW(COMPASS, DB1,  D2I)
-    CHECKFLAGSNEW(COMPASS, SB1,  S2I)
-    CHECKFLAGSNEW(COMPASS, CB2,  C7I)
-    CHECKFLAGSNEW(COMPASS, LB2,  L7I)
-    CHECKFLAGSNEW(COMPASS, DB2,  D7I)
-    CHECKFLAGSNEW(COMPASS, SB2,  S7I)
-    CHECKFLAGSNEW(COMPASS, CB3,  C6I)
-    CHECKFLAGSNEW(COMPASS, LB3,  L6I)
-    CHECKFLAGSNEW(COMPASS, DB3,  D6I)
-    CHECKFLAGSNEW(COMPASS, SB3,  S6I)
-
-    hdata.data.named.typesofobsC = buffer;
-    i = 1+snprintf(buffer, buffersize,
-    "C  %3d%-52.52s  SYS / # / OBS TYPES", Parser->info[RTCM3_MSM_COMPASS].numtypes, tbuffer);
-    if(Parser->info[RTCM3_MSM_COMPASS].numtypes>13)
-    {
-      i += snprintf(buffer+i-1, buffersize,
-      "\n      %-52.52s  SYS / # / OBS TYPES", tbuffer+13*4);
-    }
-    buffer += i; buffersize -= i;
-
-    tbufferpos = 0;
-
-    CHECKFLAGSNEW(QZSS, C1,  C1C)
-    CHECKFLAGSNEW(QZSS, L1C, L1C)
-    CHECKFLAGSNEW(QZSS, D1C, D1C)
-    CHECKFLAGSNEW(QZSS, S1C, S1C)
-
-    CHECKFLAGSNEW(QZSS, CSAIF, C1Z)
-    CHECKFLAGSNEW(QZSS, LSAIF, L1Z)
-    CHECKFLAGSNEW(QZSS, DSAIF, D1Z)
-    CHECKFLAGSNEW(QZSS, SSAIF, S1Z)
-
-    CHECKFLAGSNEW(QZSS, C1N, C1)
-    CHECKFLAGSNEW(QZSS, L1N, L1)
-    CHECKFLAGSNEW(QZSS, D1N, D1)
-    CHECKFLAGSNEW(QZSS, S1N, S1)
-
-    CHECKFLAGSNEW(QZSS, C6, C6)
-    CHECKFLAGSNEW(QZSS, L6, L6)
-    CHECKFLAGSNEW(QZSS, D6, D6)
-    CHECKFLAGSNEW(QZSS, S6, S6)
-
-    CHECKFLAGSNEW(QZSS, C2,  C2)
-    CHECKFLAGSNEW(QZSS, L2C, L2)
-    CHECKFLAGSNEW(QZSS, D2C, D2)
-    CHECKFLAGSNEW(QZSS, S2C, S2)
-
-    CHECKFLAGSNEW(QZSS, C5,  C5)
-    CHECKFLAGSNEW(QZSS, L5,  L5)
-    CHECKFLAGSNEW(QZSS, D5,  D5)
-    CHECKFLAGSNEW(QZSS, S5,  S5)
-
-    hdata.data.named.typesofobsJ = buffer;
-    i = 1+snprintf(buffer, buffersize,
-    "J  %3d%-52.52s  SYS / # / OBS TYPES", Parser->info[RTCM3_MSM_QZSS].numtypes, tbuffer);
-    if(Parser->info[RTCM3_MSM_QZSS].numtypes>13)
-    {
-      i += snprintf(buffer+i-1, buffersize,
-      "\n      %-52.52s  SYS / # / OBS TYPES", tbuffer+13*4);
-    }
-    buffer += i; buffersize -= i;
-  }
-  else
-  {
-#define CHECKFLAGS(a, b) \
-    if(flags & GNSSDF_##a##DATA) \
-    { \
-      if(data[RINEXENTRY_##b##DATA]) \
-      { \
-        Parser->info[RTCM3_MSM_GPS].flags[data[RINEXENTRY_##b##DATA]-1] = GNSSDF_##a##DATA; \
-        Parser->info[RTCM3_MSM_GPS].pos[data[RINEXENTRY_##b##DATA]-1] = GNSSENTRY_##a##DATA; \
-      } \
-      else \
-      { \
-        Parser->flags[Parser->info[RTCM3_MSM_GPS].numtypes] = GNSSDF_##a##DATA; \
-        Parser->pos[Parser->info[RTCM3_MSM_GPS].numtypes] = GNSSENTRY_##a##DATA; \
-        data[RINEXENTRY_##b##DATA] = ++Parser->info[RTCM3_MSM_GPS].numtypes; \
-        snprintf(tbuffer+tbufferpos, sizeof(tbuffer)-tbufferpos, "    "#b); \
-        tbufferpos += 6; \
-      } \
-    }
-
-    int flags = Parser->startflags;
-    int data[RINEXENTRY_NUMBER];
-    char tbuffer[6*RINEXENTRY_NUMBER+1];
-    int tbufferpos = 0;
-    for(i = 0; i < RINEXENTRY_NUMBER; ++i)
-      data[i] = 0;
-    for(i = 0; i < Parser->Data.numsats; ++i)
-      flags |= Parser->Data.dataflags[i];
-
-    CHECKFLAGS(C1,C1)
-    CHECKFLAGS(C2,C2)
-    CHECKFLAGS(P1,P1)
-    CHECKFLAGS(P2,P2)
-    CHECKFLAGS(L1C,L1)
-    CHECKFLAGS(L1P,L1)
-    CHECKFLAGS(L2C,L2)
-    CHECKFLAGS(L2P,L2)
-    CHECKFLAGS(D1C,D1)
-    CHECKFLAGS(D1P,D1)
-    CHECKFLAGS(D2C,D2)
-    CHECKFLAGS(D2P,D2)
-    CHECKFLAGS(S1C,S1)
-    CHECKFLAGS(S1P,S1)
-    CHECKFLAGS(S2C,S2)
-    CHECKFLAGS(S2P,S2)
-    CHECKFLAGS(C5,C5)
-    CHECKFLAGS(L5,L5)
-    CHECKFLAGS(D5,D5)
-    CHECKFLAGS(S5,S5)
-    CHECKFLAGS(C5AB,C8)
-    CHECKFLAGS(L5AB,L8)
-    CHECKFLAGS(D5AB,D8)
-    CHECKFLAGS(S5AB,S8)
-    CHECKFLAGS(C5B,C7)
-    CHECKFLAGS(L5B,L7)
-    CHECKFLAGS(D5B,D7)
-    CHECKFLAGS(S5B,S7)
-    CHECKFLAGS(C6,C6)
-    CHECKFLAGS(L6,L6)
-    CHECKFLAGS(D6,D6)
-    CHECKFLAGS(S6,S6)
-    /* Skip C1N and SAIF for RINEX2! */
-
-    hdata.data.named.typesofobs = buffer;
-    i = 1+snprintf(buffer, buffersize,
-    "%6d%-54.54s# / TYPES OF OBSERV", Parser->info[RTCM3_MSM_GPS].numtypes, tbuffer);
-    if(Parser->info[RTCM3_MSM_GPS].numtypes>9)
-    {
-      i += snprintf(buffer+i-1, buffersize,
-      "\n      %-54.54s# / TYPES OF OBSERV", tbuffer+9*6);
-    }
-    if(Parser->info[RTCM3_MSM_GPS].numtypes>18)
-    {
-      i += snprintf(buffer+i-1, buffersize,
-      "\n      %-54.54s# / TYPES OF OBSERV", tbuffer+18*6);
-    }
-    buffer += i; buffersize -= i;
-  }
+  i = HandleObsHeader(Parser, buffer, buffersize, &hdata);
+  buffer += i; buffersize -= i;
 
   {
@@ -2543,12 +2611,14 @@
       else if (r == 1 || r == 2)
       {
-        int i, j, o;
+        int i, j, o, nh=0;
+        char newheader[512];
         struct converttimeinfo cti;
 
-        if(Parser->init < NUMSTARTSKIP) /* skip first epochs to detect correct data types */
+        /* skip first epochs to detect correct data types */
+        if(Parser->init < (Parser->changeobs ? 1 : NUMSTARTSKIP))
         {
           ++Parser->init;
 
-          if(Parser->init == NUMSTARTSKIP)
+          if(Parser->init == (Parser->changeobs ? 1 : NUMSTARTSKIP))
             HandleHeader(Parser);
           else
@@ -2568,9 +2638,20 @@
         converttime(&cti, Parser->Data.week,
         (int)floor(Parser->Data.timeofweek/1000.0));
+        newheader[0] = 0;
+        if(Parser->changeobs)
+        {
+          nh = HandleObsHeader(Parser, newheader, sizeof(newheader), 0);
+        }
         if(Parser->rinex3)
         {
-          RTCM3Text("> %04d %02d %02d %02d %02d%11.7f  0%3d\n",
+          RTCM3Text("> %04d %02d %02d %02d %02d%11.7f  %d%3d\n",
           cti.year, cti.month, cti.day, cti.hour, cti.minute, cti.second
-          + fmod(Parser->Data.timeofweek/1000.0,1.0), Parser->Data.numsats);
+          + fmod(Parser->Data.timeofweek/1000.0,1.0), nh ? 4 : 0,
+          Parser->Data.numsats);
+          if(nh)
+          {
+            RTCM3Text("%s\n                             "
+            "                               END OF HEADER\n", newheader);
+          }
           for(i = 0; i < Parser->Data.numsats; ++i)
           {
@@ -2882,7 +2963,8 @@
         else
         {
-          RTCM3Text(" %02d %2d %2d %2d %2d %10.7f  0%3d",
+          RTCM3Text(" %02d %2d %2d %2d %2d %10.7f  %d%3d",
           cti.year%100, cti.month, cti.day, cti.hour, cti.minute, cti.second
-          + fmod(Parser->Data.timeofweek/1000.0,1.0), Parser->Data.numsats);
+          + fmod(Parser->Data.timeofweek/1000.0,1.0),  nh ? 4 : 0,
+          Parser->Data.numsats);
           for(i = 0; i < 12 && i < Parser->Data.numsats; ++i)
           {
@@ -2957,4 +3039,9 @@
             o += 12;
           }
+          if(nh)
+          {
+            RTCM3Text("%s\n                             "
+            "                               END OF HEADER\n", newheader);
+          }
           for(i = 0; i < Parser->Data.numsats; ++i)
           {
@@ -3092,4 +3179,5 @@
   int         timeout;
   int         rinex3;
+  int         changeobs;
   const char *user;
   const char *password;
@@ -3119,4 +3207,5 @@
 { "glonassephemeris", required_argument, 0, 'G'},
 { "rinex3",           no_argument,       0, '3'},
+{ "changeobs",        no_argument,       0, 'O'},
 { "proxyport",        required_argument, 0, 'R'},
 { "proxyhost",        required_argument, 0, 'S'},
@@ -3126,5 +3215,5 @@
 {0,0,0,0}};
 #endif
-#define ARGOPT "-d:s:p:r:t:f:u:E:G:M:S:R:n:h3"
+#define ARGOPT "-d:s:p:r:t:f:u:E:G:M:S:R:n:h3O"
 
 enum MODE { HTTP = 1, RTSP = 2, NTRIP1 = 3, AUTO = 4, END };
@@ -3259,4 +3348,5 @@
   args->rinex3 = 0;
   args->nmea = 0;
+  args->changeobs = 0;
   args->proxyhost = 0;
   args->proxyport = "2101";
@@ -3285,4 +3375,5 @@
     case 'n': args->nmea = optarg; break;
     case 'R': args->proxyport = optarg; break;
+    case 'O': args->changeobs = 1; break;
     case 'h': help=1; break;
     case 'M':
@@ -3357,4 +3448,5 @@
     " -R " LONG_OPT("--proxyport        ") "proxy port, optional (default 2101)\n"
     " -n " LONG_OPT("--nmea             ") "NMEA string for sending to server\n"
+    " -O " LONG_OPT("--changeobs        ") "Add observation type change header lines\n"
     " -M " LONG_OPT("--mode             ") "mode for data request\n"
     "     Valid modes are:\n"
@@ -3457,4 +3549,5 @@
     Parser.gpsephemeris = args.gpsephemeris;
     Parser.rinex3 = args.rinex3;
+    Parser.changeobs = args.changeobs;
 
     if(args.proxyhost)
Index: trunk/rtcm3torinex/lib/rtcm3torinex.h
===================================================================
--- trunk/rtcm3torinex/lib/rtcm3torinex.h	(revision 5356)
+++ trunk/rtcm3torinex/lib/rtcm3torinex.h	(revision 5358)
@@ -36,12 +36,15 @@
 #define PRN_GALILEO_START         71
 #define PRN_GALILEO_END           100
+#define PRN_GIOVE_START           101
+#define PRN_GIOVE_END             102
 #define PRN_SBAS_START            120
-#define PRN_SBAS_END              138
-#define PRN_GIOVE_START           139
-#define PRN_GIOVE_END             140
-#define PRN_COMPASS_START         141
-#define PRN_COMPASS_END           170
+#define PRN_SBAS_END              141
+#define PRN_COMPASS_START         161
+#define PRN_COMPASS_END           190
 #define PRN_QZSS_START            193
 #define PRN_QZSS_END              202
+
+#define PRN_GALGIO_START          PRN_GALILEO_START
+#define PRN_GALGIO_END            PRN_GIOVE_END
 
 #define PRN_GLONASS_NUM           (PRN_GLONASS_END-PRN_GLONASS_START+1)
@@ -470,8 +473,18 @@
   /* For RINEX2 only field GPS is used */
   struct DataInfo info[RTCM3_MSM_NUMSYS];
+  int          datafields[RINEXENTRY_NUMBER]; /* for RTCM2 header */
+  char         fieldbuffer[6*RINEXENTRY_NUMBER+1];
+  char         fieldbufferSBAS[4*RINEXENTRY_NUMBER+1];
+  char         fieldbufferGPS[4*RINEXENTRY_NUMBER+1];
+  char         fieldbufferGLONASS[4*RINEXENTRY_NUMBER+1];
+  char         fieldbufferGALILEO[4*RINEXENTRY_NUMBER+1];
+  char         fieldbufferCOMPASS[4*RINEXENTRY_NUMBER+1];
+  char         fieldbufferQZSS[4*RINEXENTRY_NUMBER+1];
+  int          numdatafields; /* for RTCM2 */
   int          validwarning;
   int          init;
   int          startflags;
   int          rinex3;
+  int          changeobs;
   const char * headerfile;
   const char * glonassephemeris;
Index: trunk/rtcm3torinex/rtcm3torinex.txt
===================================================================
--- trunk/rtcm3torinex/rtcm3torinex.txt	(revision 5356)
+++ trunk/rtcm3torinex/rtcm3torinex.txt	(revision 5358)
@@ -25,8 +25,16 @@
 1019  GPS Ephemeris
 1020  GLONASS Ephemeris
+1045-1046 Galileo Ephemeris
+1071-1077 GPS-MSM data
+1081-1087 GLONASS-MSM data
+1091-1097 Galileo-MSM data
+1101-1107 SBAS-MSM data
+1111-1117 QZSS-MSM data
+1121-1127 BeiDou-MSM data
 4088-4095 Proprietary messages (under development)
 
 Note that this version of rtcm3torinex only handles RTCM3 message types 1001,
-1002, 1003, 1004, 1009, 1010, 1011, 1012, 1019 and 1020.
+1002, 1003, 1004, 1009, 1010, 1011, 1012, 1013, 1019, 1020, 1045, 1046,
+1071-1077, 1081-1087, 1091-1097, 1101-1107, 1111-1117 and 1121-1127.
 
 The generated RINEX is somewhat limited due to the streaming character of the
@@ -39,4 +47,6 @@
    the observables, which exist in the first epoch are output. If there
    are new observables later on, these are ignored.
+   The Option --changeobs removes that limitation, but not many tools can use
+   the resulting files which include header change records.
  - Only known message types are interpreted. Send me new RTCM3 data files and
    data support can be improved. See contact address at the end of this document.
@@ -61,4 +71,5 @@
  -R --proxyport        proxy port, optional (default 2101)
  -n --nmea             NMEA string for sending to server
+ -O --changeobs        Add observation type change header lines
  -M --mode             mode for data request
      Valid modes are:
