Index: trunk/FACT++/src/datalogger.cc
===================================================================
--- trunk/FACT++/src/datalogger.cc	(revision 15059)
+++ trunk/FACT++/src/datalogger.cc	(revision 15060)
@@ -145,4 +145,6 @@
     //shared_ptr<DimStampedInfo> dimInfo;
     unsigned int index;
+    ///counter to know if format has changed during operations
+    unsigned int increment;
 
     ///Dim info constructor
@@ -160,4 +162,5 @@
         //dimInfo = shared_ptr<DimStampedInfo>(info);
         index = 0;
+        increment = 0;
     }
     ///default destructor
@@ -282,4 +285,14 @@
     NumSubAndFitsType fNumSubAndFitsData;
 
+    ///Service for broadcasting subscription status
+    DimDescribedService* fCurrentSubscription;
+    ///Number of seconds since the last update of the subscribed list
+    int fCurrentSubscriptionUpdateRate;
+    ///The last time in seconds of the day when the service was update
+    Time fLastSubscriptionUpdate;
+    ///update the service
+    void updateSubscriptionList();
+    ///set the duration between two updates. a zero or negative value disables the service updates
+    int setSubscriptionListUpdateTimeLapse(const Event& evt);
     /***************************************************
      * DATA LOGGER's CONFIGURATION STUFF
@@ -405,4 +418,48 @@
     return GetCurrentState();
 }
+/**
+ *  UPDATE SUBSCRIPTION LIST. Updates the subscription list service if enough time has passed.
+ *                            Otherwise does nothing
+ */
+void DataLogger::updateSubscriptionList()
+{
+    if (fCurrentSubscriptionUpdateRate <= 0) return;
+    Time timeNow;
+    //if less than the update rate time has passed, just return
+    if (timeNow - fLastSubscriptionUpdate < boost::posix_time::seconds(fCurrentSubscriptionUpdateRate))
+        return;
+    //TODO remove me !
+//    cout << "Updating subscription list with: " << endl;
+
+    fLastSubscriptionUpdate = timeNow;
+
+    //update service !
+    ostringstream output;
+    for (auto serverIt=fServiceSubscriptions.begin();serverIt!=fServiceSubscriptions.end(); serverIt++)
+    {
+        if (serverIt->first == "DATA_LOGGER")
+            continue;
+        for (auto serviceIt=serverIt->second.begin(); serviceIt!=serverIt->second.end(); serviceIt++)
+        {
+            output << serverIt->first << "/" << serviceIt->first << ",";
+            if (serviceIt->second.lastReceivedEvent != Time::None)
+                output << (timeNow - serviceIt->second.lastReceivedEvent).total_seconds();
+            else
+                output << "-1";
+            output << "\n";
+        }
+    }
+//TODO remove me !
+//cout << output.str();
+    fCurrentSubscription->setData(output.str().c_str(), output.str().size()+1);
+    fCurrentSubscription->setQuality(0);
+    fCurrentSubscription->Update();
+}
+int DataLogger::setSubscriptionListUpdateTimeLapse(const Event& evt)
+{
+    fCurrentSubscriptionUpdateRate = evt.GetInt();
+
+    return GetCurrentState();
+}
 vector<Description> DataLogger::GetDescription(const string& server, const string& service)
 {
@@ -540,5 +597,7 @@
                 }
                 list[service].nightlyFile.Close();
-                string fileNameWithoutFits = fileName.substr(0, fileName.size()-4);
+                list[service].increment++;
+                Warn("Format of "+server+"/"+service+" has changed. Closing "+fileName);
+/*                string fileNameWithoutFits = fileName.substr(0, fileName.size()-4);
                 int counter=0;
                 while (counter < 100)
@@ -549,5 +608,4 @@
                     if (!testStream) //fileName available
                     {
-                        Warn("Format of "+server+"/"+service+" has changed. Closing "+fileName+" and renaming it to "+newFileName.str());
                         rename(fileName.c_str(), newFileName.str().c_str());
                         break;
@@ -557,4 +615,5 @@
                 if (counter==100)
                     Error("Could not rename "+fileName+" after 100 trials (because of format change). Aborting");
+*/
                 //reallocate the fits buffer...
                 list[service].fitsBufferAllocated = false;
@@ -895,4 +954,5 @@
             ("Print information about the internal status of the data logger.");
 
+
      OpenFileToDim fToDim;
      fToDim.code = 0;
@@ -920,4 +980,12 @@
      fNumSubAndFitsIsOn = true;
 
+     string emptyString="";
+     //Subscription list service
+     fCurrentSubscription = new DimDescribedService(GetName() + "/SUBSCRIPTIONS", "C", emptyString.c_str(),
+                                     "List of all the services subscribed by datalogger, except the ones provided by itself."
+                                     "|Liste[string]:list of logged services and the delay in seconds since last update");
+     fCurrentSubscriptionUpdateRate = 60; //by default, 1 minute between each update
+     fLastSubscriptionUpdate = timeNow;
+
      // provide services control commands
      AddEvent("SET_DEBUG_MODE", "B:1", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_Ready)
@@ -945,4 +1013,9 @@
          ("Set the timeout delay for old run numbers."
           "|timeout[min]:Time out in minutes after which files for expired runs are closed.");
+     //Provide access to the duration between two updates of the service list
+     AddEvent("SET_SERVICE_LIST_UPDATE_INTERVAL", "I:1", kSM_Ready, kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun)
+         (bind(&DataLogger::setSubscriptionListUpdateTimeLapse, this, placeholders::_1))
+         ("Set the min interval between two services-list updates."
+          "|duration[sec]:The interval between two updates, in seconds.");
 
      fDestructing = false;
@@ -1000,4 +1073,5 @@
     delete fOpenedRunFiles;
     delete fNumSubAndFits;
+    delete fCurrentSubscription;
 
     if (fNightlyLogFile.is_open())//this file is the only one that has not been closed by GoToReady
@@ -1291,4 +1365,9 @@
     fQuality = evt.GetQoS();
 
+    //update subscription last received time
+    sub.lastReceivedEvent = cTime;
+    //update subscription list service if required
+    updateSubscriptionList();
+
     fMjD = cTime.Mjd() ? cTime.Mjd()-40587 : 0;
 
@@ -1309,6 +1388,6 @@
             ostringstream str;
             str << "Parsing service " << evt.GetName();
-            str << " failed: " << e.what() << " removing the subscription for now.";
-            Error(str);
+            str << " failed: " << e.what() << " removing the subscription to " << sub.server << "/" << sub.service;
+            Warn(str);
             //remove this subscription from the list.
             //because these operators use references to elements, and because they're supposed here to erase these objects on the way, I'm not too sure... so duplicate the names !
@@ -1338,5 +1417,5 @@
         //check if the last received event was before noon and if current one is after noon.
         //if so, close the file so that it gets reopened.
-        sub.lastReceivedEvent = cTime;
+//        sub.lastReceivedEvent = cTime;
         if (!sub.nightlyFile.IsOpen())
             if (GetCurrentState() != kSM_Ready)
@@ -1380,5 +1459,5 @@
         }
 
-        sub.lastReceivedEvent = cTime;
+//        sub.lastReceivedEvent = cTime;
         if (!sub.nightlyFile.IsOpen())
             if (GetCurrentState() != kSM_Ready)
@@ -1386,5 +1465,4 @@
         WriteToFITS(sub, evt.GetData());
     }
-
 }
 
@@ -1704,5 +1782,12 @@
     if (!sub.nightlyFile.IsOpen())
     {
-        const string partialName = CompileFileNameWithPath(fFilePath, serviceName, "fits");
+        string incrementedServiceName = serviceName;
+        if (sub.increment != 0)
+        {
+            ostringstream str;
+            str << "." << sub.increment;
+            incrementedServiceName += str.str();
+        }
+        const string partialName = CompileFileNameWithPath(fFilePath, incrementedServiceName, "fits");
 
         const string fileNameOnly = partialName.substr(partialName.find_last_of('/')+1, partialName.size());
