Index: trunk/BNC/src/satObs.cpp
===================================================================
--- trunk/BNC/src/satObs.cpp	(revision 11041)
+++ trunk/BNC/src/satObs.cpp	(revision 11047)
@@ -2,4 +2,5 @@
 #include <iomanip>
 #include <sstream>
+#include <cstdlib>
 #include <newmatio.h>
 
@@ -132,11 +133,22 @@
 
   e_ssrFormat ssrFormat = ssrUnknown;
+
+  // TEMPORARY BACKWARD COMPATIBILITY - remove later on:
+  // .ssr files written before the SSR format line (a single integer) was
+  // added after the "> ORBIT" epoch line don't have it - their first line
+  // is already the first satellite. Such a line is kept (firstLine) and
+  // processed as the first correction below, with ssrFormat unknown.
+  // To revert: read the format line unconditionally again, i.e. drop the
+  // "only one integer on the line" test and the firstLine handling in the
+  // loop below.
+  string firstLine;
+  getline(inStream, firstLine);
   {
-    string line;
-    getline(inStream, line);
-    istringstream in(line.c_str());
-    int ssrFormatInt = 0;
-    if (in >> ssrFormatInt) {
+    istringstream in(firstLine.c_str());
+    int    ssrFormatInt = 0;
+    string rest;
+    if ((in >> ssrFormatInt) && !(in >> rest)) { // format line
       ssrFormat = static_cast<e_ssrFormat>(ssrFormatInt);
+      firstLine.clear();
     }
   }
@@ -150,5 +162,10 @@
 
     string line;
-    getline(inStream, line);
+    if (ii == 0 && !firstLine.empty()) { // TEMPORARY BACKWARD COMPATIBILITY, see above
+      line = firstLine;
+    }
+    else {
+      getline(inStream, line);
+    }
     istringstream in(line.c_str());
 
@@ -245,5 +262,6 @@
       *out << "> CODE_BIAS " << epoTime.datestr(' ') << ' ' << epoTime.timestr(1, ' ') << " "
         << satCodeBias._updateInt << " "
-        << biasList.size() << ' ' << satCodeBias._staID << endl;
+        << biasList.size() << ' ' << satCodeBias._staID << ' '
+        << satCodeBias._ssrIOD << ' ' << satCodeBias._ssrProviderID << endl;
     }
     *out << satCodeBias._prn.toString() << "   " << setw(2) << satCodeBias._bias.size();
@@ -268,4 +286,6 @@
     return;
   }
+  int ssrIOD, ssrProviderID;
+  t_corrSSR::readSsrIOD(epoLine, ssrIOD, ssrProviderID);
   for (int ii = 0; ii < numSat; ii++) {
     t_satCodeBias satCodeBias;
@@ -273,4 +293,6 @@
     satCodeBias._updateInt = updateInt;
     satCodeBias._staID = staID;
+    satCodeBias._ssrIOD = ssrIOD;
+    satCodeBias._ssrProviderID = ssrProviderID;
 
     string line;
@@ -313,5 +335,6 @@
       *out << "> PHASE_BIAS " << epoTime.datestr(' ') << ' ' << epoTime.timestr(1, ' ') << " "
         << satPhaseBias._updateInt << " "
-        << biasList.size() << ' ' << satPhaseBias._staID << endl;
+        << biasList.size() << ' ' << satPhaseBias._staID << ' '
+        << satPhaseBias._ssrIOD << ' ' << satPhaseBias._ssrProviderID << endl;
 
       if (satPhaseBias._ssrFormat == e_ssrFormat::ssrRtcmNew) {
@@ -373,4 +396,6 @@
     return;
   }
+  int ssrIOD, ssrProviderID;
+  t_corrSSR::readSsrIOD(epoLine, ssrIOD, ssrProviderID);
   for (int ii = 0; ii <= numSat; ii++) {
     t_satPhaseBias satPhaseBias;
@@ -378,4 +403,6 @@
     satPhaseBias._updateInt = updateInt;
     satPhaseBias._staID = staID;
+    satPhaseBias._ssrIOD = ssrIOD;
+    satPhaseBias._ssrProviderID = ssrProviderID;
 
     string line;
@@ -392,11 +419,11 @@
     switch (ssrFormat) {
     case e_ssrFormat::ssrRtcmNew:
-      satPhaseBias._dispBiasConsistInd = metadata1;
-      satPhaseBias._MelbWuebConsistInd = metadata2;
+      satPhaseBias._satYawInfoInd = metadata1;
+      satPhaseBias._extPBPhaseInd = metadata2;
       break;
     case e_ssrFormat::ssrRtcmOld:
     case e_ssrFormat::ssrUnknown:
-      satPhaseBias._satYawInfoInd = metadata1;
-      satPhaseBias._extPBPhaseInd = metadata2;
+      satPhaseBias._dispBiasConsistInd = metadata1;
+      satPhaseBias._MelbWuebConsistInd = metadata2;
       break;
     }
@@ -575,7 +602,7 @@
       in >> frqAntenna._frqType >> frqAntenna._nadirCorrectionIndicator >> frqAntenna._nadirCorrection;
       for (unsigned kk = 0; kk < numAngles; kk++) {
-        double val;
-        in >> val;
-        frqAntenna._nadirAngleCorrection.push_back(val);
+        string valStr; // may be "nan" (invalid value), which operator>> can't parse
+        in >> valStr;
+        frqAntenna._nadirAngleCorrection.push_back(strtod(valStr.c_str(), 0));
       }
       satAntenna._freq.push_back(frqAntenna);
@@ -684,4 +711,19 @@
 
   return unknown;
+}
+
+// Optional SSR IOD and Provider ID trailing the staID in CODE_BIAS and
+// PHASE_BIAS epoch lines (older files don't have them: -1 = unknown)
+////////////////////////////////////////////////////////////////////////////
+void t_corrSSR::readSsrIOD(const string& line, int& ssrIOD, int& ssrProviderID) {
+  istringstream inLine(line.c_str());
+  string hlp;
+  for (int ii = 0; ii < 11; ii++) { // '>', type, 6 x date/time, updateInt, numEntries, staID
+    inLine >> hlp;
+  }
+  if (!(inLine >> ssrIOD >> ssrProviderID)) {
+    ssrIOD        = -1;
+    ssrProviderID = -1;
+  }
 }
 
