Index: trunk/MagicSoft/Control/SubsystemIO/IONotifier.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/IONotifier.C	(revision 1041)
+++ 	(revision )
@@ -1,100 +1,0 @@
-/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
-================================================================
- 
-  This code is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
- 
-  This code is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
- 
-  You should have received a copy of the GNU General Public License
-  along with Emacs (which is required to make this stuff work); if
-  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-  Cambridge, MA 02139, USA.
-==================================================================
-*/ 
-
-
-//g++ -c IONotifier.C `sigc-config --cflags`
-#include "IONotifier.H"
-//for printf
-#include <stdio.h>
-//for select
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-//for signals
-#include <sigc++/signal_system.h>
-using namespace SigC;
-//for threads
-#include <pthread.h>
-
-IONotifier::IONotifier(int fd_)
-            :fd(fd_),againWritableEmited(false),fdIsValid(true)
-        {
-            pthread_mutex_init(&mutex,NULL);
-            pthread_create(&thread,NULL,&IONotifier::watchFor,this);
-        }
-IONotifier::~IONotifier()
-        {
-            pthread_mutex_lock(&mutex);
-            fdIsValid=false;
-            pthread_mutex_unlock(&mutex);
-            pthread_join(thread,NULL);
-        }
-    
- void * IONotifier::watchFor( void* arg)
-        {
-            IONotifier* self=(IONotifier *) arg;
-            fd_set rfds, wfds;
-            int retval;
-                //first time:
-            self->againWritableEmited=false;
-                //include the actual fd in the sets checked for reading and writing
-
-            while(1){
-                pthread_mutex_lock(&(self->mutex));
-                if(!self->fdIsValid) break;
-                pthread_mutex_unlock(&(self->mutex));
-                if(!self->againWritableEmited){
-//againWritable has not been emited, so we check both if its readable and writable
-                    FD_ZERO(&rfds);FD_ZERO(&wfds);
-                    FD_SET(self->fd, &rfds);FD_SET(self->fd, &wfds);
-                    retval = select(FD_SETSIZE, &rfds, &wfds, NULL, NULL);
-                }else{
-//if againWritable has been emited we don't want to emit if it's writable until something changes. Until then, only check if it's readable
-                    FD_ZERO(&rfds);FD_ZERO(&wfds);
-                    FD_SET(self->fd, &rfds);
-                    retval = select(FD_SETSIZE, &rfds, NULL, NULL, NULL);
-                }
-                
-                if (retval){
-                    
-//                    printf("Data is available now.\n");
-                    if(FD_ISSET(self->fd, &rfds)){
-                            //fd is readable
-                        self->readable.emit();
-//since this new situation:
-                        self->againWritableEmited=false;
-                    }
-                    if(FD_ISSET(self->fd, &wfds)){
-                            //fd is writable
-                        self->againWritable.emit();
-                        self->againWritableEmited=true;
-                    }
-                }else{
-                    perror("Shouldn't arrive here");
-                    
-                }
-                
-            }
-//            pthread_exit
-        }
-
-
-    
-
Index: trunk/MagicSoft/Control/SubsystemIO/IONotifier.H
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/IONotifier.H	(revision 1041)
+++ 	(revision )
@@ -1,33 +1,0 @@
-#ifndef IONOTIFIER
-#define IONOTIFIER
-
-//for signals
-#include <sigc++/signal_system.h>
-using namespace SigC;
-//for threads
-#include <pthread.h>
-
-class IONotifier
-{
-public:
-    
-    Signal0<void> againWritable;
-    Signal0<void> readable;
-    IONotifier(int fd_);
-    ~IONotifier();
-private:
-    int fd;
-    pthread_t thread;
-    bool againWritableEmited;
-    bool fdIsValid;
-    pthread_mutex_t mutex;
-    
-    static void * watchFor( void* arg);
-};
-
-
-    
-
-
-
-#endif
Index: trunk/MagicSoft/Control/SubsystemIO/IONotifier.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/IONotifier.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/IONotifier.cxx	(revision 1053)
@@ -0,0 +1,100 @@
+/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
+================================================================
+ 
+  This code is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+ 
+  This code is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with Emacs (which is required to make this stuff work); if
+  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+  Cambridge, MA 02139, USA.
+==================================================================
+*/ 
+
+
+//g++ -c IONotifier.C `sigc-config --cflags`
+#include "IONotifier.H"
+//for printf
+#include <stdio.h>
+//for select
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+//for signals
+#include <sigc++/signal_system.h>
+using namespace SigC;
+//for threads
+#include <pthread.h>
+
+IONotifier::IONotifier(int fd_)
+            :fd(fd_),againWritableEmited(false),fdIsValid(true)
+        {
+            pthread_mutex_init(&mutex,NULL);
+            pthread_create(&thread,NULL,&IONotifier::watchFor,this);
+        }
+IONotifier::~IONotifier()
+        {
+            pthread_mutex_lock(&mutex);
+            fdIsValid=false;
+            pthread_mutex_unlock(&mutex);
+            pthread_join(thread,NULL);
+        }
+    
+ void * IONotifier::watchFor( void* arg)
+        {
+            IONotifier* self=(IONotifier *) arg;
+            fd_set rfds, wfds;
+            int retval;
+                //first time:
+            self->againWritableEmited=false;
+                //include the actual fd in the sets checked for reading and writing
+
+            while(1){
+                pthread_mutex_lock(&(self->mutex));
+                if(!self->fdIsValid) break;
+                pthread_mutex_unlock(&(self->mutex));
+                if(!self->againWritableEmited){
+//againWritable has not been emited, so we check both if its readable and writable
+                    FD_ZERO(&rfds);FD_ZERO(&wfds);
+                    FD_SET(self->fd, &rfds);FD_SET(self->fd, &wfds);
+                    retval = select(FD_SETSIZE, &rfds, &wfds, NULL, NULL);
+                }else{
+//if againWritable has been emited we don't want to emit if it's writable until something changes. Until then, only check if it's readable
+                    FD_ZERO(&rfds);FD_ZERO(&wfds);
+                    FD_SET(self->fd, &rfds);
+                    retval = select(FD_SETSIZE, &rfds, NULL, NULL, NULL);
+                }
+                
+                if (retval){
+                    
+//                    printf("Data is available now.\n");
+                    if(FD_ISSET(self->fd, &rfds)){
+                            //fd is readable
+                        self->readable.emit();
+//since this new situation:
+                        self->againWritableEmited=false;
+                    }
+                    if(FD_ISSET(self->fd, &wfds)){
+                            //fd is writable
+                        self->againWritable.emit();
+                        self->againWritableEmited=true;
+                    }
+                }else{
+                    perror("Shouldn't arrive here");
+                    
+                }
+                
+            }
+//            pthread_exit
+        }
+
+
+    
+
Index: trunk/MagicSoft/Control/SubsystemIO/IONotifier.hxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/IONotifier.hxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/IONotifier.hxx	(revision 1053)
@@ -0,0 +1,33 @@
+#ifndef IONOTIFIER
+#define IONOTIFIER
+
+//for signals
+#include <sigc++/signal_system.h>
+using namespace SigC;
+//for threads
+#include <pthread.h>
+
+class IONotifier
+{
+public:
+    
+    Signal0<void> againWritable;
+    Signal0<void> readable;
+    IONotifier(int fd_);
+    ~IONotifier();
+private:
+    int fd;
+    pthread_t thread;
+    bool againWritableEmited;
+    bool fdIsValid;
+    pthread_mutex_t mutex;
+    
+    static void * watchFor( void* arg);
+};
+
+
+    
+
+
+
+#endif
Index: trunk/MagicSoft/Control/SubsystemIO/PeriodicAction.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/PeriodicAction.C	(revision 1041)
+++ 	(revision )
@@ -1,120 +1,0 @@
-/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
-================================================================
- 
-  This code is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
- 
-  This code is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
- 
-  You should have received a copy of the GNU General Public License
-  along with Emacs (which is required to make this stuff work); if
-  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-  Cambridge, MA 02139, USA.
-==================================================================
-*/ 
-
-#include "PeriodicAction.H"
-//for signals
-#include <sigc++/signal_system.h>
-using namespace SigC;
-PeriodicAction::PeriodicAction( unsigned int period_)
-            : period(period_),periodic(period_)
-        {
-        }
-    
-            
-PeriodicAction::PeriodicAction ( unsigned int period_, const Slot0<bool> & doWhileData, const Slot0<void> & finallyData ) 
-            : period(period_), periodic(period_) 
-        {
-
-            this->DoWhile(doWhileData);
-            this->FinallyDo(finallyData);
-        }
-    
-void PeriodicAction::DoWhileNot( const Slot0<bool> & s)
-        {
-//              if( doWhileNot || doWhile){
-//                      //doWhile actions were defined before, redefining them
-//                  if(doWhileNot) delete doWhileNot;
-//                  else delete doWhile;
-//                  actionConn.disconnect();
-                
-//              }else{ 
-                actionConn=doWhileNot.connect(s);
-//            }
-            
-            periodConn=periodic.signal.connect(slot(this,&PeriodicAction::DoItOnceAndCheckContinuance_Not));
-        }
-    void PeriodicAction::DoWhile(const Slot0<bool> &s)
-        {
-//              if( doWhileNot || doWhile){
-//                      //doWhile actions were defined before, redefining them
-//                  if(doWhileNot) delete doWhileNot;
-//                  else delete doWhile;
-//                  actionConn.disconnect();
-                
-//              }else{ 
-                actionConn=doWhile.connect(s);
-//            }
-            
-            periodConn=periodic.signal.connect(slot(this,&PeriodicAction::DoItOnceAndCheckContinuance));
-        }
-    void PeriodicAction::FinallyDo( const Slot0<void> & s)
-        {
-            finally.connect(s);
-        }
-    
-    void PeriodicAction::DoItOnceAndCheckContinuance() 
-        {
-            if ( ! doWhile.emit() ){
-                periodic.Stop();
-                finally.emit();
-            }
-        }
-    void PeriodicAction::DoItOnceAndCheckContinuance_Not() 
-        {
-            if ( doWhileNot.emit() ){
-                periodic.Stop();
-                finally.emit();
-            }
-        }
-    
-
-                
-//      public method isRunning { } {
-//          if { "$scheduledId" == "" } {
-//              return 0
-//          } else {
-//              return 1
-//          }
-//      }
-
-    void PeriodicAction::Start () {
-  //        if(! periodic.isRunning ){
-        periodic.Start();
-  //        }
-            //we don't want to launch it twice
-    };
-    
-
-    void PeriodicAction::Stop () {
-//        if(! periodic.isRunning ){
-            periodic.Stop();
-//        }
-      };
-    
-
-//      public method SetPeriod { period_ } {
-//          set period $period_
-//      }
-
-    
-
-
-
-
Index: trunk/MagicSoft/Control/SubsystemIO/PeriodicAction.H
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/PeriodicAction.H	(revision 1041)
+++ 	(revision )
@@ -1,98 +1,0 @@
-#ifndef PERIODICACTION
-#define PERIODICACTION
-/** 
- * Class for periodically calls to a slot: a global function or a method of a
- * given object.
- *
- * Connects the slot to a PeriodicSignal, that wraps a thread, which
- * periodically will call the doWhile[doWhileNot] slot until this returns
- * false[true]. If a FinallyDo action is registered, when the PeriodicAction
- * has finished it will call this finalizing slot
- *
- * To wrap the doWhile, doWhileNot or FinallyDo action properly (type safer
- * than pointer to functions, better object oriented), call the slot factory:
- *
- * slot(global_function)
- * slot(anObject,&Object::Method)
- *
- * EXAMPLE: -----------------------------------------------------------------
- *
- * class Counter: public Object{
- *    Counter(int max, int incr);
- *    bool isIncrementPossible();
- *    void PrintIAmDone();
- * };
- *
- * bool end;void endMe(){end=true;}
- *
- * int main(){
- *   end=false;
- *   Counter byTwo(100,2), byThree(100,3);
- *   
- *   PeriodicAction byTwoEachSec(1000000);
- *   byTwoEachSec.DoWhile(slot(byTwo,&Counter::isIncrementPossible));
- *   byTwoEachSec.FinallyDo(slot(byTwo,&Counter::PrintIAmDone));
- *   byTwoEachSec.Start();
- *   
- *   PeriodicAction byThreeEachTwoSec(2000000);
- *   byThreeEachTwoSec.DoWhile(slot(byThree,&Counter::isIncrementPossible));
- *   byThreeEachTwoSec.FinallyDo(slot(endMe));
- *   byThreeEachTwoSec.Start();
- *   
- *   while(!end){
- *   }
- * }
- * ----------------------------------------------------------------------------
- *
- * Pending: Define behaviour of synchronization of diferent periodicactions
- *
- * Implementation Pending: Check the periodicaction is not running before
- * starting, and it is running before stopping it. (With
- * PeriodicSignal::isRunning) 
- *
- * Implementation Pending: Not thread safe when two periodic actions may
- * access the same variables
- */
-
-
-#include "PeriodicSignal.H"
-//for signals, and Object
-#include <sigc++/signal_system.h>
-using namespace SigC;
-
-class PeriodicAction: public Object {
-
-public:
-        /** Aproximate period (+-500ms) in microsec (so, greater than 500000)
-         *  to repeat doWhile or doWhileNot actions
-         *  @see #doWhile
-         *  @see #doWhileNot
-         */
-    unsigned int period;
-public:
-    PeriodicAction( unsigned int period_);
-                
-    PeriodicAction ( unsigned int period_, const Slot0<bool> & doWhileData,
-                     const Slot0<void> & finallyData );
-    void DoWhileNot( const Slot0<bool> & s);
-    void DoWhile(const Slot0<bool> &s);
-    void FinallyDo( const Slot0<void> & s);
-    void Start();
-    void Stop();
-//  void SetPeriod(unsigned long int period_);
-private:
-    PeriodicSignal periodic;
-    Connection actionConn,periodConn;
-    
-    Signal0<bool> doWhile;
-    Signal0<bool> doWhileNot;
-    
-    Signal0<void> finally;
-    
-    void DoItOnceAndCheckContinuance();
-    void DoItOnceAndCheckContinuance_Not();
-};
-
-
-
-#endif
Index: trunk/MagicSoft/Control/SubsystemIO/PeriodicAction.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/PeriodicAction.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/PeriodicAction.cxx	(revision 1053)
@@ -0,0 +1,120 @@
+/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
+================================================================
+ 
+  This code is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+ 
+  This code is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with Emacs (which is required to make this stuff work); if
+  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+  Cambridge, MA 02139, USA.
+==================================================================
+*/ 
+
+#include "PeriodicAction.H"
+//for signals
+#include <sigc++/signal_system.h>
+using namespace SigC;
+PeriodicAction::PeriodicAction( unsigned int period_)
+            : period(period_),periodic(period_)
+        {
+        }
+    
+            
+PeriodicAction::PeriodicAction ( unsigned int period_, const Slot0<bool> & doWhileData, const Slot0<void> & finallyData ) 
+            : period(period_), periodic(period_) 
+        {
+
+            this->DoWhile(doWhileData);
+            this->FinallyDo(finallyData);
+        }
+    
+void PeriodicAction::DoWhileNot( const Slot0<bool> & s)
+        {
+//              if( doWhileNot || doWhile){
+//                      //doWhile actions were defined before, redefining them
+//                  if(doWhileNot) delete doWhileNot;
+//                  else delete doWhile;
+//                  actionConn.disconnect();
+                
+//              }else{ 
+                actionConn=doWhileNot.connect(s);
+//            }
+            
+            periodConn=periodic.signal.connect(slot(this,&PeriodicAction::DoItOnceAndCheckContinuance_Not));
+        }
+    void PeriodicAction::DoWhile(const Slot0<bool> &s)
+        {
+//              if( doWhileNot || doWhile){
+//                      //doWhile actions were defined before, redefining them
+//                  if(doWhileNot) delete doWhileNot;
+//                  else delete doWhile;
+//                  actionConn.disconnect();
+                
+//              }else{ 
+                actionConn=doWhile.connect(s);
+//            }
+            
+            periodConn=periodic.signal.connect(slot(this,&PeriodicAction::DoItOnceAndCheckContinuance));
+        }
+    void PeriodicAction::FinallyDo( const Slot0<void> & s)
+        {
+            finally.connect(s);
+        }
+    
+    void PeriodicAction::DoItOnceAndCheckContinuance() 
+        {
+            if ( ! doWhile.emit() ){
+                periodic.Stop();
+                finally.emit();
+            }
+        }
+    void PeriodicAction::DoItOnceAndCheckContinuance_Not() 
+        {
+            if ( doWhileNot.emit() ){
+                periodic.Stop();
+                finally.emit();
+            }
+        }
+    
+
+                
+//      public method isRunning { } {
+//          if { "$scheduledId" == "" } {
+//              return 0
+//          } else {
+//              return 1
+//          }
+//      }
+
+    void PeriodicAction::Start () {
+  //        if(! periodic.isRunning ){
+        periodic.Start();
+  //        }
+            //we don't want to launch it twice
+    };
+    
+
+    void PeriodicAction::Stop () {
+//        if(! periodic.isRunning ){
+            periodic.Stop();
+//        }
+      };
+    
+
+//      public method SetPeriod { period_ } {
+//          set period $period_
+//      }
+
+    
+
+
+
+
Index: trunk/MagicSoft/Control/SubsystemIO/PeriodicAction.hxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/PeriodicAction.hxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/PeriodicAction.hxx	(revision 1053)
@@ -0,0 +1,98 @@
+#ifndef PERIODICACTION
+#define PERIODICACTION
+/** 
+ * Class for periodically calls to a slot: a global function or a method of a
+ * given object.
+ *
+ * Connects the slot to a PeriodicSignal, that wraps a thread, which
+ * periodically will call the doWhile[doWhileNot] slot until this returns
+ * false[true]. If a FinallyDo action is registered, when the PeriodicAction
+ * has finished it will call this finalizing slot
+ *
+ * To wrap the doWhile, doWhileNot or FinallyDo action properly (type safer
+ * than pointer to functions, better object oriented), call the slot factory:
+ *
+ * slot(global_function)
+ * slot(anObject,&Object::Method)
+ *
+ * EXAMPLE: -----------------------------------------------------------------
+ *
+ * class Counter: public Object{
+ *    Counter(int max, int incr);
+ *    bool isIncrementPossible();
+ *    void PrintIAmDone();
+ * };
+ *
+ * bool end;void endMe(){end=true;}
+ *
+ * int main(){
+ *   end=false;
+ *   Counter byTwo(100,2), byThree(100,3);
+ *   
+ *   PeriodicAction byTwoEachSec(1000000);
+ *   byTwoEachSec.DoWhile(slot(byTwo,&Counter::isIncrementPossible));
+ *   byTwoEachSec.FinallyDo(slot(byTwo,&Counter::PrintIAmDone));
+ *   byTwoEachSec.Start();
+ *   
+ *   PeriodicAction byThreeEachTwoSec(2000000);
+ *   byThreeEachTwoSec.DoWhile(slot(byThree,&Counter::isIncrementPossible));
+ *   byThreeEachTwoSec.FinallyDo(slot(endMe));
+ *   byThreeEachTwoSec.Start();
+ *   
+ *   while(!end){
+ *   }
+ * }
+ * ----------------------------------------------------------------------------
+ *
+ * Pending: Define behaviour of synchronization of diferent periodicactions
+ *
+ * Implementation Pending: Check the periodicaction is not running before
+ * starting, and it is running before stopping it. (With
+ * PeriodicSignal::isRunning) 
+ *
+ * Implementation Pending: Not thread safe when two periodic actions may
+ * access the same variables
+ */
+
+
+#include "PeriodicSignal.H"
+//for signals, and Object
+#include <sigc++/signal_system.h>
+using namespace SigC;
+
+class PeriodicAction: public Object {
+
+public:
+        /** Aproximate period (+-500ms) in microsec (so, greater than 500000)
+         *  to repeat doWhile or doWhileNot actions
+         *  @see #doWhile
+         *  @see #doWhileNot
+         */
+    unsigned int period;
+public:
+    PeriodicAction( unsigned int period_);
+                
+    PeriodicAction ( unsigned int period_, const Slot0<bool> & doWhileData,
+                     const Slot0<void> & finallyData );
+    void DoWhileNot( const Slot0<bool> & s);
+    void DoWhile(const Slot0<bool> &s);
+    void FinallyDo( const Slot0<void> & s);
+    void Start();
+    void Stop();
+//  void SetPeriod(unsigned long int period_);
+private:
+    PeriodicSignal periodic;
+    Connection actionConn,periodConn;
+    
+    Signal0<bool> doWhile;
+    Signal0<bool> doWhileNot;
+    
+    Signal0<void> finally;
+    
+    void DoItOnceAndCheckContinuance();
+    void DoItOnceAndCheckContinuance_Not();
+};
+
+
+
+#endif
Index: trunk/MagicSoft/Control/SubsystemIO/PeriodicSignal.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/PeriodicSignal.C	(revision 1041)
+++ 	(revision )
@@ -1,64 +1,0 @@
-/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
-================================================================
- 
-  This code is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
- 
-  This code is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
- 
-  You should have received a copy of the GNU General Public License
-  along with Emacs (which is required to make this stuff work); if
-  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-  Cambridge, MA 02139, USA.
-==================================================================
-*/ 
-
-#include "PeriodicSignal.H"
-//for signals
-#include <sigc++/signal_system.h>
-using namespace SigC;
-//for threads
-#include <pthread.h>
-//for sleep,select
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-PeriodicSignal::PeriodicSignal(unsigned int period_)
-            :period(period_)
-        {}
-void PeriodicSignal::Start()
-{
-    stopped=false;
-    pthread_mutex_init(&mutex4stop,NULL);
-    
-    pthread_create(&thread,NULL,&PeriodicSignal::SleepPeriodAndSignal,this);
-    
-};
-void PeriodicSignal::Stop()
-{
-    pthread_mutex_lock(&mutex4stop);
-    stopped=true;
-    pthread_mutex_unlock(&mutex4stop);
-    pthread_join(thread,NULL);
-};
-    
-void * PeriodicSignal::SleepPeriodAndSignal( void* arg)
-{
-    PeriodicSignal* self=(PeriodicSignal *) arg;
-    while(1){
-        pthread_mutex_lock(&(self->mutex4stop));
-        if(self->stopped) break;
-        pthread_mutex_unlock(&(self->mutex4stop));
-        
-        usleep((unsigned long)self->period);
-        
-        self->signal.emit();
-    }
-}
-
Index: trunk/MagicSoft/Control/SubsystemIO/PeriodicSignal.H
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/PeriodicSignal.H	(revision 1041)
+++ 	(revision )
@@ -1,27 +1,0 @@
-#ifndef PERIODICSIGNAL
-#define PERIODICSIGNAL
-//for signals
-#include <sigc++/signal_system.h>
-using namespace SigC;
-//for threads
-#include <pthread.h>
-
-class PeriodicSignal
-{
-private:
-  unsigned int period;//in usec
-public:
-    Signal0<void> signal;
-    
-    PeriodicSignal(unsigned int period_);
-    void Start();
-    void Stop();
-
-private:
-    static void * SleepPeriodAndSignal( void* arg);    
-    pthread_mutex_t  mutex4stop;
-    bool stopped;
-    pthread_t thread;
-
-};
-#endif
Index: trunk/MagicSoft/Control/SubsystemIO/PeriodicSignal.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/PeriodicSignal.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/PeriodicSignal.cxx	(revision 1053)
@@ -0,0 +1,64 @@
+/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
+================================================================
+ 
+  This code is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+ 
+  This code is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with Emacs (which is required to make this stuff work); if
+  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+  Cambridge, MA 02139, USA.
+==================================================================
+*/ 
+
+#include "PeriodicSignal.H"
+//for signals
+#include <sigc++/signal_system.h>
+using namespace SigC;
+//for threads
+#include <pthread.h>
+//for sleep,select
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+PeriodicSignal::PeriodicSignal(unsigned int period_)
+            :period(period_)
+        {}
+void PeriodicSignal::Start()
+{
+    stopped=false;
+    pthread_mutex_init(&mutex4stop,NULL);
+    
+    pthread_create(&thread,NULL,&PeriodicSignal::SleepPeriodAndSignal,this);
+    
+};
+void PeriodicSignal::Stop()
+{
+    pthread_mutex_lock(&mutex4stop);
+    stopped=true;
+    pthread_mutex_unlock(&mutex4stop);
+    pthread_join(thread,NULL);
+};
+    
+void * PeriodicSignal::SleepPeriodAndSignal( void* arg)
+{
+    PeriodicSignal* self=(PeriodicSignal *) arg;
+    while(1){
+        pthread_mutex_lock(&(self->mutex4stop));
+        if(self->stopped) break;
+        pthread_mutex_unlock(&(self->mutex4stop));
+        
+        usleep((unsigned long)self->period);
+        
+        self->signal.emit();
+    }
+}
+
Index: trunk/MagicSoft/Control/SubsystemIO/PeriodicSignal.hxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/PeriodicSignal.hxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/PeriodicSignal.hxx	(revision 1053)
@@ -0,0 +1,27 @@
+#ifndef PERIODICSIGNAL
+#define PERIODICSIGNAL
+//for signals
+#include <sigc++/signal_system.h>
+using namespace SigC;
+//for threads
+#include <pthread.h>
+
+class PeriodicSignal
+{
+private:
+  unsigned int period;//in usec
+public:
+    Signal0<void> signal;
+    
+    PeriodicSignal(unsigned int period_);
+    void Start();
+    void Stop();
+
+private:
+    static void * SleepPeriodAndSignal( void* arg);    
+    pthread_mutex_t  mutex4stop;
+    bool stopped;
+    pthread_t thread;
+
+};
+#endif
Index: trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.C	(revision 1041)
+++ 	(revision )
@@ -1,249 +1,0 @@
-/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
-================================================================
- 
-  This code is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
- 
-  This code is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
- 
-  You should have received a copy of the GNU General Public License
-  along with Emacs (which is required to make this stuff work); if
-  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-  Cambridge, MA 02139, USA.
-==================================================================
-*/ 
-
-//it is a good idea to encapsulate all the configuration file dependence in one a wrapper class SubFormatSubsystem, and derive from it
-//#include "SubFormatSubsystem.C"
-#include "Subsystem.H"
-#include "PeriodicAction.H"
-#include "TCPListener.H"
-#include "TCPSender.H"
-#include "IONotifier.H"
-#include <string>
-//for signals/slots (Callbacks in C++, see http://libsigc.sourceforge.net/)
-#include <sigc++/signal_system.h>
-//libsigc must be installed
-#include <stdio.h>
-using namespace SigC;
-//there's no agreement in maximum lenght message, by now
-
-
-Subsystem::Subsystem (unsigned short int portCommandListener, unsigned long int reportPeriod, char * ccName, unsigned short int portReportListener , unsigned short int maxTimeoutCount_ ) 
-            :
-        TCPListener(portCommandListener), reportSender(ccName,portReportListener), tryReportConn(reportPeriod), locked(false), reportingLoop(reportPeriod), reporting(false),reportAckNotifier(0),maxTimeoutCount(maxTimeoutCount_)
-        {
-//the behaviour is the following: commandListener has been started as a being derived from TCPListener. When connection from cc is opened commands are processed in this->process()
-//when REPOR arrives reportSender(TCPSender) here tries to connect reportListener in CC. When this happens will start a periodic reporting
-
-
-//tryReportConn is the PeriodicAction which will try periodically reportSender.isTrialToConnectSuccesful ...
-            tryReportConn.DoWhileNot(slot(reportSender, &TCPSender::isTrialToConnectSuccesful) );
-//... and when it is succesfull will start reportingLoop periodic action
-            tryReportConn.FinallyDo(slot(this, &Subsystem::StartReporting));
-//tryReportConn is started when REPOR received (See process())
-            
-//reportingLoop is a PeriodicAction which periodically sends the relevant report
-            reportingLoop.DoWhile(slot(this,&Subsystem::SendReport));
-//according the line above, it will be started whe reportSender connection is succesfull
-
-//by now         
-//demo report:
-            strcpy(reportString,"standby:11:44:20:11:01:6:34:12:6.0:6.1:6.05:11:01:36:34:12:10.6:6.0:6.0:00:00:30.0:00:00:4.6:0.1:0.05:0.004:0.0:0.001:0.003:guiding:0.1deg:on:3.1Hz:0.09deg:J2000:Mkn421:messagefromthedrive:");
-            pthread_mutex_init(&mutex4report,NULL);
-            pthread_mutex_init(&mutex4ack,NULL);
-    }
-
-void Subsystem::SetReportString(char * report)
-{
-    SuspendComm();
-    strcpy(this->reportString,report);
-    ResumeComm();
-    
-}
-
-bool Subsystem::SendSpecialReportContaining(char * specialReport)
-{
-    pthread_mutex_lock(&mutex4ack);
-    if(!acknowledgeReceivedForLastReport){
-        timeoutCount++;
-        if(timeoutCount==maxTimeoutCount){
-            pthread_mutex_unlock(&mutex4ack);
-            return false; //SendReport is not succesfull so this will stop Periodic action 
-        }
-    }
-            //before writing the report or sending it make sure no other thread thouches it
-    pthread_mutex_lock(&mutex4report);
-//        SubFormatSubsystem::ElaborateReport
-            //calls overriden method GenerateReport that will do the
-        //append the tag for specialReport in this protocol 
-    sprintf(this->reportString,"SPECIAL:%s",specialReport);
-    
-        //GenerateReport may have filled timestamp. Record it to checkreportacknowledge in future
-
-
-    ExtractTimeStampFromLastReportTo(lastTimeStamp);
-    reportSender.Send(this->reportString);
-    cerr<<"Sending "<<this->reportString<<"\n";
-    pthread_mutex_unlock(&mutex4report);    
-
-    acknowledgeReceivedForLastReport=false;
-    pthread_mutex_unlock(&mutex4ack);
-//????????Order mutexes are lock/unlock????????????
-    return true; //if it goes here reporting was succesfull (Used in PeriodicAction reportingLoop)
-}
-
-    inline void Subsystem::StartReporting()
-        {
-            reportingLoop.Start();
-            reportAckNotifier=new IONotifier(reportSender.IODescriptor());
-//after report is sent via reportSender socket, reportListener in CC is sending an acknowledge. The next signal triggers CheckReportAcknowledge when something is received in reportSender channel (suposedly to be this ack)
-            reportAckNotifier->readable.connect(slot(this,&Subsystem::CheckReportAcknowledge));
-                //the first time
-            timeoutCount=0;
-            acknowledgeReceivedForLastReport=true;
-            
-        }     
-    void Subsystem::ResetConnectionToCC () {
-        if(locked){
-            ULock();
-        }
-        reportingLoop.Stop();
-        reporting=false;
-        delete reportAckNotifier;
-        reportSender.CloseConnection();
-        TCPListener::ClosingChannel(); //but still is waiting for new connections
-    }
-    void Subsystem::process(){
-         if (!locked){
-             if(!reporting){
-//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! pending: compare the whole string, not only the first 5 bytes. strcmp gave problems ??????????????????? 
-                 if ( !strncmp(TCPListener::receivedStream, "REPOR", 5) ) {
-                     cerr<<"received REPOR\n";
-                         //before startreporting, the connection to cc by reportSender has to be stablished
-                     tryReportConn.Start();
-                     reporting=true;
-                     return;
-                 }
-             } else { //already reporting
-                if ( !strncmp(TCPListener::receivedStream,"LOCK!", 5) ) {
-                    Lock();
-                    return;
-                } 
-             }
-             
-         } else { //locked
-//as preliminary tests instead of commands, the new subsystem state is sent
-             if (! strncmp(TCPListener::receivedStream, "ULOCK", 5) ) {
-                 ULock();
-                 return;
-             } 
-             cerr<<"processing ... seting new state: "<< TCPListener::receivedStream <<"\n";
-                 //calls overriden method thet will process the command itself
-             ProcessCmd(TCPListener::receivedStream);
-             
-                 //state=receivedStream;
-             return;
-             
-         }
-
-//if program reaches here is because it hasn't Received REPOR & LOCK in the proper way. Network partner it's not (a properly working) CC. Closing the opened connection and waiting for new one            
-         ResetConnectionToCC();
-    }
-
-bool Subsystem::SendReport () {
-
-    pthread_mutex_lock(&mutex4ack);
-    if(!acknowledgeReceivedForLastReport){
-        timeoutCount++;
-        if(timeoutCount==maxTimeoutCount){
-            pthread_mutex_unlock(&mutex4ack);
-            return false; //SendReport is not succesfull so this will stop Periodic action 
-        }
-    }
-            //before writing the report or sending it make sure no other thread thouches it
-    pthread_mutex_lock(&mutex4report);
-//        SubFormatSubsystem::ElaborateReport
-            //calls overriden method GenerateReport that will do the
-    GenerateReport();
-        //GenerateReport may have filled timestamp. Record it to checkreportacknowledge in future
-
-
-    ExtractTimeStampFromLastReportTo(lastTimeStamp);
-    reportSender.Send(this->reportString);
-    cerr<<"Sending "<<this->reportString<<"\n";
-    pthread_mutex_unlock(&mutex4report);    
-
-    acknowledgeReceivedForLastReport=false;
-    pthread_mutex_unlock(&mutex4ack);
-//????????Order mutexes are lock/unlock????????????
-    return true; //if it goes here reporting was succesfull (Used in PeriodicAction reportingLoop)
-        //acknowledge check is done elsewhere, when it arrives (asynchronously)
-}
-    void Subsystem::CheckReportAcknowledge()
-        {
-            reportSender.Receive();
-
-            pthread_mutex_lock(&mutex4ack);
-//incorporate lastTimeStamp in check           
-            if (reportSender.ReturnNew() == "RECV@" ) {
-                acknowledgeReceivedForLastReport=true;
-                timeoutCount=0;
-            }else{
-                cerr<<"wrong ack!\n";
-            }
-            pthread_mutex_unlock(&mutex4ack);          
-        }
-    
-    void Subsystem::Lock(){
-        cerr<<"Locking to CC mode\n";
-        locked=true;
-    }
-    void Subsystem::ULock(){
-        cerr<<"UNLocking from CC mode\n";
-        locked=false;
-    }  
-    void Subsystem::SuspendComm()
-        {
-            pthread_mutex_lock(&mutex4report);
-        };
-    void Subsystem::ResumeComm()
-        {
-            pthread_mutex_unlock(&mutex4report);
-        };
-void Subsystem::ExtractTimeStampFromLastReportTo(char * lastTimeStamp)
-{
-    string report(this->reportString);
-    string::iterator it=report.begin();
-        //point it to the first appearence of : 
-    it+=report.find(":");
-    
-//cut the first field (between :) which is the status
-    report.erase(report.begin(),it);
-
-//#define TIMESTAMP_LEN 12
-//%02.2d:%02.2d:%02.2d:%03.3d
-    it=report.begin(); //back to the beginning
-    it+=12;
-//cut from the timestamp end to the rest
-    report.erase(it,report.end());
-    strcpy(lastTimeStamp,report.c_str());
-    
-}
-
-
-//TO BE OVERRIDEN:
-
- void Subsystem::ProcessCmd(char *)
-          {};
- void Subsystem::GenerateReport()
-          {}; 
- void Subsystem::HandleConnectionTimeoutIsOver()
-          {};
-
-
Index: trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.H
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.H	(revision 1041)
+++ 	(revision )
@@ -1,258 +1,0 @@
-#ifndef SUBSYSTEM
-#define SUBSYSTEM
-
-#include "PeriodicAction.H"
-#include "TCPListener.H"
-#include "IONotifier.H"
-#include "PeriodicAction.H"
-#include "TCPSender.H"
-#define TIMESTAMP_LEN 12
-//%02.2d:%02.2d:%02.2d:%03.3d
-//in Makefile#define MAXMSG 4096 
-/**
- * Base class for MAGIC Subsystem's communication with CC
- * 
- * It implements commandListener (see MAGIC-TDAS 00-07) as a TCPListener
- * derived class, to be able to custom the behaviour by overriding its
- * methods  
- *
- * Missing properties: Special Report in a GenerateSpecialReport method, also
- * a final implementation of CheckReportAcknowledge (CC sends back
- * "RECV:timestamp", with timestamp the one extracted from subsystem
- * report. So subsystem has to have a member lastReportTimestamp to compare).
- * Timeout in CheckReportAcknowledge?????.
- *
- * @short Base class for MAGIC Subsystem's communication with CC
- * @author Marc Casaldaliga
- * @version 0.9
- * @see TCPListener
- */
-class Subsystem: public TCPListener
-{
-
-public:
-
-        /**
-         * Set the string to be sent in the next report that will be sent to
-         * CC (with timestamp but without protocol specific item,
-         * e.g. trailing \n). The timestamp is the data one, the time when
-         * data was taken (the relevant for analysis), nothing to do with the
-         * the time the report will be sent.
-         *
-         * It takes care internally of suspending and resuming communications
-         * not to send something is being modified etc 
-         *
-         *  @param report CString with pure report (without "\n" ...) 
-         */ 
-    void SetReportString(char * report);
-
-        /**
-         *  Class unique constructor with the parameters which specify
-         *  Subsystem configuration.
-         *
-         *  @param portCommandListener TCP/IP port Subsystem will open to
-         *  listen to cc commands
-         *
-         *  @param reportPeriod Aproximate (+- 500ms) time in microsec,
-         *  between each report is sent to CC
-         *
-         *  @param ccName C string with CC machine name
-         *
-         *  @param portReportListener TCP/IP port opened in CC which Subsystem
-         *  will contact to send reports 
-         *
-         *  @param maxTimeoutCount_. Times subsystem tries to reconnect CC
-         *  (with reportPeriod) periodicity, before it considers CC not
-         *  available. After this count is reached Subsystem has to react some
-         *  way (parking itself,  ...). This is done by
-         *  Subsystem::HandleConnectionTimeoutIsOver 
-         *
-         *  @see #HandleConnectionTimeoutIsOver
-         *
-         */
-    Subsystem (unsigned short int portCommandListener, unsigned long int
-               reportPeriod, char * ccName, unsigned short int
-               portReportListener, unsigned short int maxTimeoutCount_ ); 
-
-        /**
-         * Send (immediately) a special report which a part from
-         * protocol specific items (e.g. trailing \n and special report
-         * identifier) contains the argument specialReport  
-         *
-         * ??? timestamp ????
-         *
-         * It takes care internally of suspending and resuming communications
-         * not to send something is being modified etc 
-         *
-         *  @param specialReport CString with pure special report (without
-         * "\n" ...)
-         * 
-         *  @return Returns whether sending will be succesful (true) or not
-         *  (false)  
-         */ 
-    bool SendSpecialReportContaining(char * specialReport);
-
-protected:
-        /**
-         * Field with the report that will be sent to CC (with timestamp but
-         * without protocol specific item, e.g. trailing \n)
-         *
-         * To be modified only within GenerateReport
-         */
-    char reportString[MAXMSG];
-           
-        /** To be overriden. It has to do all the job of interpreting CC
-         * commands: (not the ones 
-         * regarding starting connection, locking ...) but the ones for the 
-         * subsystem function (This way we separate the protocol dependent
-         * stuff).  
-         *
-         * Compares Subsystem::ccCmd with known commands from cc and executes
-         * the appropiate function 
-         *
-         * This method is automatically called when a command from cc is
-         * received, after checking it is not a communication/locking command 
-         * 
-         * If receiving a nonsense command call to ResetConnectionToCC()
-         * (Network partner it's not -a properly working- CC). In principle
-         * this will close and open again, but let's leave it this way so that
-         * it is not protocol dependent 
-         *
-         * @param ccCmd CString with pure CC command (without "\n" ...) 
-         */
-    virtual void ProcessCmd(char *ccCmd);
-
-        /** GenerateReport (to be overriden) This next method is automatically
-         *   called before sending a report.
-         * 
-         *  According to state and data this should write
-         *  Subsystem::reportString (it 
-         *  should include the timestamp of the data sent, but without any
-         *  trailing \n--this is part of the protocol) 
-         *
-         *  After it, this Subsystem::reportString plus any protocol dependent
-         *  thing is sent. This GenerateReport and send is periodically
-         *  repeated with reportPeriod   
-         *
-         *  Alternatively, one may leave GenerateReport empty and from outside
-         *  call to Subsystem::SetReportString when hardware info is updated
-         *  (probably what one what like to do). 
-         */
-    virtual void GenerateReport();
-
-        /** HandleConnectionTimeoutIsOver. Does what the subsystem is suposed
-         *  to do when it has lost definitely connection to CC. To be
-         *  overriden. 
-         *
-         *  After Subsystem::maxTimeoutCount times of reconnection tries CC is
-         *  considered not available. Subsystem has to react some way (parking
-         *  itself,  ... ) depending on its autonomy. This is done by
-         *  overriding this method with the desired behaviour.
-         *
-         *  After HandleConnectionTimeoutIsOver is done Subsystem will listen
-         *  to CC again and start all communication process.
-         *
-         *  see #maxTimeoutCount
-         */  
-    virtual void HandleConnectionTimeoutIsOver(); 
-
-        /** SuspendComm. Suspend communication threads
-         *
-         *  To prevent Subsystem to access its resources (e.g. send
-         *  reportString) when we are about to access them externally (fill
-         *  reportString with actual data), one can call to this method and
-         *  suspend subsystem activity. 
-         *  To resume it call to Subsystem::ResumeComm. 
-         *  
-         *  Always paired with a ResumeComm.
-         *
-         *  If Subsystem is at that time accessing the resources, SuspendComm
-         *  will wait for them to be released and then will lock them. 
-         *
-         *  @see #ResumeComm
-         *
-         */
-    void SuspendComm();
-
-        /** ResumeComm. Resume communication threads
-         *
-         *  After calling SuspendComm() and having access to Subsystem
-         *  resources (e.g. fill reportString with actual data) allow
-         *  Subsystem to access them again and resume it's activity. we are
-         *  about to access them externally (fill reportString with actual 
-         *  data), one can call to this method and suspend subsystem activity.
-         *  
-         *  @see #SuspendComm
-         *
-         */
-    void ResumeComm();
-
-        /**
-         * Resets communication to CC, to be used when a nonsense command
-         * arrives from CC 
-         * @see #ProcessCmd
-         */
-    void ResetConnectionToCC();
-
-    
-
-private:
-        /**
-         * C string with CC machine name
-         */
-    char* ccName;
-        /**
-         * Aproximate (+- 500ms) time in microsec, between each report is sent
-         * to CC
-         */  
-    unsigned long reportPeriod;
-    
-    unsigned short int portCommandListener;
-    unsigned short int portReportListener;
-
-        //we implement commandListener as a TCPListener derived class, to be   
-        //able to custom the behaviour by overriding it's methods, namely
-        //process     
-
-        /* maxTimeoutCount. Times subsystem tries to reconnect CC (with reportPeriod)
-         *  periodicity, before it considers CC not available.
-         *  
-         *  After this count is reached Subsystem has to react some way
-         *  (parking itself,  ...). This is done by
-         *  Subsystem::HandleConnectionTimeoutIsOver 
-         *
-         *  @see #HandleConnectionTimeoutIsOver
-         *
-         */
-    
-    short int maxTimeoutCount;
-
-
-    bool locked;
-    bool reporting;
-    IONotifier* reportAckNotifier;
-    
-        //we implement reportSender as an instance of class TCPSender
-    TCPSender reportSender;
-        //reporting and trying connections to cc are implemented as
-        //PeriodicActions     
-    PeriodicAction tryReportConn,reportingLoop;
-    pthread_mutex_t mutex4report;
-    inline void StartReporting();
-    virtual void process();
-    bool SendReport();
-    void CheckReportAcknowledge();
-        //to be able to checkreportacknowledge on has to have the timestamp of
-        //the last report sent
-    char lastTimeStamp[TIMESTAMP_LEN];
-    void ExtractTimeStampFromLastReportTo(char *);
-
-    bool acknowledgeReceivedForLastReport;
-    short int timeoutCount;
-    pthread_mutex_t mutex4ack;
-    void Lock();
-    void ULock();
-
-};
-
-#endif
Index: trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.cxx	(revision 1053)
@@ -0,0 +1,249 @@
+/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
+================================================================
+ 
+  This code is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+ 
+  This code is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with Emacs (which is required to make this stuff work); if
+  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+  Cambridge, MA 02139, USA.
+==================================================================
+*/ 
+
+//it is a good idea to encapsulate all the configuration file dependence in one a wrapper class SubFormatSubsystem, and derive from it
+//#include "SubFormatSubsystem.C"
+#include "Subsystem.H"
+#include "PeriodicAction.H"
+#include "TCPListener.H"
+#include "TCPSender.H"
+#include "IONotifier.H"
+#include <string>
+//for signals/slots (Callbacks in C++, see http://libsigc.sourceforge.net/)
+#include <sigc++/signal_system.h>
+//libsigc must be installed
+#include <stdio.h>
+using namespace SigC;
+//there's no agreement in maximum lenght message, by now
+
+
+Subsystem::Subsystem (unsigned short int portCommandListener, unsigned long int reportPeriod, char * ccName, unsigned short int portReportListener , unsigned short int maxTimeoutCount_ ) 
+            :
+        TCPListener(portCommandListener), reportSender(ccName,portReportListener), tryReportConn(reportPeriod), locked(false), reportingLoop(reportPeriod), reporting(false),reportAckNotifier(0),maxTimeoutCount(maxTimeoutCount_)
+        {
+//the behaviour is the following: commandListener has been started as a being derived from TCPListener. When connection from cc is opened commands are processed in this->process()
+//when REPOR arrives reportSender(TCPSender) here tries to connect reportListener in CC. When this happens will start a periodic reporting
+
+
+//tryReportConn is the PeriodicAction which will try periodically reportSender.isTrialToConnectSuccesful ...
+            tryReportConn.DoWhileNot(slot(reportSender, &TCPSender::isTrialToConnectSuccesful) );
+//... and when it is succesfull will start reportingLoop periodic action
+            tryReportConn.FinallyDo(slot(this, &Subsystem::StartReporting));
+//tryReportConn is started when REPOR received (See process())
+            
+//reportingLoop is a PeriodicAction which periodically sends the relevant report
+            reportingLoop.DoWhile(slot(this,&Subsystem::SendReport));
+//according the line above, it will be started whe reportSender connection is succesfull
+
+//by now         
+//demo report:
+            strcpy(reportString,"standby:11:44:20:11:01:6:34:12:6.0:6.1:6.05:11:01:36:34:12:10.6:6.0:6.0:00:00:30.0:00:00:4.6:0.1:0.05:0.004:0.0:0.001:0.003:guiding:0.1deg:on:3.1Hz:0.09deg:J2000:Mkn421:messagefromthedrive:");
+            pthread_mutex_init(&mutex4report,NULL);
+            pthread_mutex_init(&mutex4ack,NULL);
+    }
+
+void Subsystem::SetReportString(char * report)
+{
+    SuspendComm();
+    strcpy(this->reportString,report);
+    ResumeComm();
+    
+}
+
+bool Subsystem::SendSpecialReportContaining(char * specialReport)
+{
+    pthread_mutex_lock(&mutex4ack);
+    if(!acknowledgeReceivedForLastReport){
+        timeoutCount++;
+        if(timeoutCount==maxTimeoutCount){
+            pthread_mutex_unlock(&mutex4ack);
+            return false; //SendReport is not succesfull so this will stop Periodic action 
+        }
+    }
+            //before writing the report or sending it make sure no other thread thouches it
+    pthread_mutex_lock(&mutex4report);
+//        SubFormatSubsystem::ElaborateReport
+            //calls overriden method GenerateReport that will do the
+        //append the tag for specialReport in this protocol 
+    sprintf(this->reportString,"SPECIAL:%s",specialReport);
+    
+        //GenerateReport may have filled timestamp. Record it to checkreportacknowledge in future
+
+
+    ExtractTimeStampFromLastReportTo(lastTimeStamp);
+    reportSender.Send(this->reportString);
+    cerr<<"Sending "<<this->reportString<<"\n";
+    pthread_mutex_unlock(&mutex4report);    
+
+    acknowledgeReceivedForLastReport=false;
+    pthread_mutex_unlock(&mutex4ack);
+//????????Order mutexes are lock/unlock????????????
+    return true; //if it goes here reporting was succesfull (Used in PeriodicAction reportingLoop)
+}
+
+    inline void Subsystem::StartReporting()
+        {
+            reportingLoop.Start();
+            reportAckNotifier=new IONotifier(reportSender.IODescriptor());
+//after report is sent via reportSender socket, reportListener in CC is sending an acknowledge. The next signal triggers CheckReportAcknowledge when something is received in reportSender channel (suposedly to be this ack)
+            reportAckNotifier->readable.connect(slot(this,&Subsystem::CheckReportAcknowledge));
+                //the first time
+            timeoutCount=0;
+            acknowledgeReceivedForLastReport=true;
+            
+        }     
+    void Subsystem::ResetConnectionToCC () {
+        if(locked){
+            ULock();
+        }
+        reportingLoop.Stop();
+        reporting=false;
+        delete reportAckNotifier;
+        reportSender.CloseConnection();
+        TCPListener::ClosingChannel(); //but still is waiting for new connections
+    }
+    void Subsystem::process(){
+         if (!locked){
+             if(!reporting){
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! pending: compare the whole string, not only the first 5 bytes. strcmp gave problems ??????????????????? 
+                 if ( !strncmp(TCPListener::receivedStream, "REPOR", 5) ) {
+                     cerr<<"received REPOR\n";
+                         //before startreporting, the connection to cc by reportSender has to be stablished
+                     tryReportConn.Start();
+                     reporting=true;
+                     return;
+                 }
+             } else { //already reporting
+                if ( !strncmp(TCPListener::receivedStream,"LOCK!", 5) ) {
+                    Lock();
+                    return;
+                } 
+             }
+             
+         } else { //locked
+//as preliminary tests instead of commands, the new subsystem state is sent
+             if (! strncmp(TCPListener::receivedStream, "ULOCK", 5) ) {
+                 ULock();
+                 return;
+             } 
+             cerr<<"processing ... seting new state: "<< TCPListener::receivedStream <<"\n";
+                 //calls overriden method thet will process the command itself
+             ProcessCmd(TCPListener::receivedStream);
+             
+                 //state=receivedStream;
+             return;
+             
+         }
+
+//if program reaches here is because it hasn't Received REPOR & LOCK in the proper way. Network partner it's not (a properly working) CC. Closing the opened connection and waiting for new one            
+         ResetConnectionToCC();
+    }
+
+bool Subsystem::SendReport () {
+
+    pthread_mutex_lock(&mutex4ack);
+    if(!acknowledgeReceivedForLastReport){
+        timeoutCount++;
+        if(timeoutCount==maxTimeoutCount){
+            pthread_mutex_unlock(&mutex4ack);
+            return false; //SendReport is not succesfull so this will stop Periodic action 
+        }
+    }
+            //before writing the report or sending it make sure no other thread thouches it
+    pthread_mutex_lock(&mutex4report);
+//        SubFormatSubsystem::ElaborateReport
+            //calls overriden method GenerateReport that will do the
+    GenerateReport();
+        //GenerateReport may have filled timestamp. Record it to checkreportacknowledge in future
+
+
+    ExtractTimeStampFromLastReportTo(lastTimeStamp);
+    reportSender.Send(this->reportString);
+    cerr<<"Sending "<<this->reportString<<"\n";
+    pthread_mutex_unlock(&mutex4report);    
+
+    acknowledgeReceivedForLastReport=false;
+    pthread_mutex_unlock(&mutex4ack);
+//????????Order mutexes are lock/unlock????????????
+    return true; //if it goes here reporting was succesfull (Used in PeriodicAction reportingLoop)
+        //acknowledge check is done elsewhere, when it arrives (asynchronously)
+}
+    void Subsystem::CheckReportAcknowledge()
+        {
+            reportSender.Receive();
+
+            pthread_mutex_lock(&mutex4ack);
+//incorporate lastTimeStamp in check           
+            if (reportSender.ReturnNew() == "RECV@" ) {
+                acknowledgeReceivedForLastReport=true;
+                timeoutCount=0;
+            }else{
+                cerr<<"wrong ack!\n";
+            }
+            pthread_mutex_unlock(&mutex4ack);          
+        }
+    
+    void Subsystem::Lock(){
+        cerr<<"Locking to CC mode\n";
+        locked=true;
+    }
+    void Subsystem::ULock(){
+        cerr<<"UNLocking from CC mode\n";
+        locked=false;
+    }  
+    void Subsystem::SuspendComm()
+        {
+            pthread_mutex_lock(&mutex4report);
+        };
+    void Subsystem::ResumeComm()
+        {
+            pthread_mutex_unlock(&mutex4report);
+        };
+void Subsystem::ExtractTimeStampFromLastReportTo(char * lastTimeStamp)
+{
+    string report(this->reportString);
+    string::iterator it=report.begin();
+        //point it to the first appearence of : 
+    it+=report.find(":");
+    
+//cut the first field (between :) which is the status
+    report.erase(report.begin(),it);
+
+//#define TIMESTAMP_LEN 12
+//%02.2d:%02.2d:%02.2d:%03.3d
+    it=report.begin(); //back to the beginning
+    it+=12;
+//cut from the timestamp end to the rest
+    report.erase(it,report.end());
+    strcpy(lastTimeStamp,report.c_str());
+    
+}
+
+
+//TO BE OVERRIDEN:
+
+ void Subsystem::ProcessCmd(char *)
+          {};
+ void Subsystem::GenerateReport()
+          {}; 
+ void Subsystem::HandleConnectionTimeoutIsOver()
+          {};
+
+
Index: trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.hxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.hxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/Subsystem.orig.hxx	(revision 1053)
@@ -0,0 +1,258 @@
+#ifndef SUBSYSTEM
+#define SUBSYSTEM
+
+#include "PeriodicAction.H"
+#include "TCPListener.H"
+#include "IONotifier.H"
+#include "PeriodicAction.H"
+#include "TCPSender.H"
+#define TIMESTAMP_LEN 12
+//%02.2d:%02.2d:%02.2d:%03.3d
+//in Makefile#define MAXMSG 4096 
+/**
+ * Base class for MAGIC Subsystem's communication with CC
+ * 
+ * It implements commandListener (see MAGIC-TDAS 00-07) as a TCPListener
+ * derived class, to be able to custom the behaviour by overriding its
+ * methods  
+ *
+ * Missing properties: Special Report in a GenerateSpecialReport method, also
+ * a final implementation of CheckReportAcknowledge (CC sends back
+ * "RECV:timestamp", with timestamp the one extracted from subsystem
+ * report. So subsystem has to have a member lastReportTimestamp to compare).
+ * Timeout in CheckReportAcknowledge?????.
+ *
+ * @short Base class for MAGIC Subsystem's communication with CC
+ * @author Marc Casaldaliga
+ * @version 0.9
+ * @see TCPListener
+ */
+class Subsystem: public TCPListener
+{
+
+public:
+
+        /**
+         * Set the string to be sent in the next report that will be sent to
+         * CC (with timestamp but without protocol specific item,
+         * e.g. trailing \n). The timestamp is the data one, the time when
+         * data was taken (the relevant for analysis), nothing to do with the
+         * the time the report will be sent.
+         *
+         * It takes care internally of suspending and resuming communications
+         * not to send something is being modified etc 
+         *
+         *  @param report CString with pure report (without "\n" ...) 
+         */ 
+    void SetReportString(char * report);
+
+        /**
+         *  Class unique constructor with the parameters which specify
+         *  Subsystem configuration.
+         *
+         *  @param portCommandListener TCP/IP port Subsystem will open to
+         *  listen to cc commands
+         *
+         *  @param reportPeriod Aproximate (+- 500ms) time in microsec,
+         *  between each report is sent to CC
+         *
+         *  @param ccName C string with CC machine name
+         *
+         *  @param portReportListener TCP/IP port opened in CC which Subsystem
+         *  will contact to send reports 
+         *
+         *  @param maxTimeoutCount_. Times subsystem tries to reconnect CC
+         *  (with reportPeriod) periodicity, before it considers CC not
+         *  available. After this count is reached Subsystem has to react some
+         *  way (parking itself,  ...). This is done by
+         *  Subsystem::HandleConnectionTimeoutIsOver 
+         *
+         *  @see #HandleConnectionTimeoutIsOver
+         *
+         */
+    Subsystem (unsigned short int portCommandListener, unsigned long int
+               reportPeriod, char * ccName, unsigned short int
+               portReportListener, unsigned short int maxTimeoutCount_ ); 
+
+        /**
+         * Send (immediately) a special report which a part from
+         * protocol specific items (e.g. trailing \n and special report
+         * identifier) contains the argument specialReport  
+         *
+         * ??? timestamp ????
+         *
+         * It takes care internally of suspending and resuming communications
+         * not to send something is being modified etc 
+         *
+         *  @param specialReport CString with pure special report (without
+         * "\n" ...)
+         * 
+         *  @return Returns whether sending will be succesful (true) or not
+         *  (false)  
+         */ 
+    bool SendSpecialReportContaining(char * specialReport);
+
+protected:
+        /**
+         * Field with the report that will be sent to CC (with timestamp but
+         * without protocol specific item, e.g. trailing \n)
+         *
+         * To be modified only within GenerateReport
+         */
+    char reportString[MAXMSG];
+           
+        /** To be overriden. It has to do all the job of interpreting CC
+         * commands: (not the ones 
+         * regarding starting connection, locking ...) but the ones for the 
+         * subsystem function (This way we separate the protocol dependent
+         * stuff).  
+         *
+         * Compares Subsystem::ccCmd with known commands from cc and executes
+         * the appropiate function 
+         *
+         * This method is automatically called when a command from cc is
+         * received, after checking it is not a communication/locking command 
+         * 
+         * If receiving a nonsense command call to ResetConnectionToCC()
+         * (Network partner it's not -a properly working- CC). In principle
+         * this will close and open again, but let's leave it this way so that
+         * it is not protocol dependent 
+         *
+         * @param ccCmd CString with pure CC command (without "\n" ...) 
+         */
+    virtual void ProcessCmd(char *ccCmd);
+
+        /** GenerateReport (to be overriden) This next method is automatically
+         *   called before sending a report.
+         * 
+         *  According to state and data this should write
+         *  Subsystem::reportString (it 
+         *  should include the timestamp of the data sent, but without any
+         *  trailing \n--this is part of the protocol) 
+         *
+         *  After it, this Subsystem::reportString plus any protocol dependent
+         *  thing is sent. This GenerateReport and send is periodically
+         *  repeated with reportPeriod   
+         *
+         *  Alternatively, one may leave GenerateReport empty and from outside
+         *  call to Subsystem::SetReportString when hardware info is updated
+         *  (probably what one what like to do). 
+         */
+    virtual void GenerateReport();
+
+        /** HandleConnectionTimeoutIsOver. Does what the subsystem is suposed
+         *  to do when it has lost definitely connection to CC. To be
+         *  overriden. 
+         *
+         *  After Subsystem::maxTimeoutCount times of reconnection tries CC is
+         *  considered not available. Subsystem has to react some way (parking
+         *  itself,  ... ) depending on its autonomy. This is done by
+         *  overriding this method with the desired behaviour.
+         *
+         *  After HandleConnectionTimeoutIsOver is done Subsystem will listen
+         *  to CC again and start all communication process.
+         *
+         *  see #maxTimeoutCount
+         */  
+    virtual void HandleConnectionTimeoutIsOver(); 
+
+        /** SuspendComm. Suspend communication threads
+         *
+         *  To prevent Subsystem to access its resources (e.g. send
+         *  reportString) when we are about to access them externally (fill
+         *  reportString with actual data), one can call to this method and
+         *  suspend subsystem activity. 
+         *  To resume it call to Subsystem::ResumeComm. 
+         *  
+         *  Always paired with a ResumeComm.
+         *
+         *  If Subsystem is at that time accessing the resources, SuspendComm
+         *  will wait for them to be released and then will lock them. 
+         *
+         *  @see #ResumeComm
+         *
+         */
+    void SuspendComm();
+
+        /** ResumeComm. Resume communication threads
+         *
+         *  After calling SuspendComm() and having access to Subsystem
+         *  resources (e.g. fill reportString with actual data) allow
+         *  Subsystem to access them again and resume it's activity. we are
+         *  about to access them externally (fill reportString with actual 
+         *  data), one can call to this method and suspend subsystem activity.
+         *  
+         *  @see #SuspendComm
+         *
+         */
+    void ResumeComm();
+
+        /**
+         * Resets communication to CC, to be used when a nonsense command
+         * arrives from CC 
+         * @see #ProcessCmd
+         */
+    void ResetConnectionToCC();
+
+    
+
+private:
+        /**
+         * C string with CC machine name
+         */
+    char* ccName;
+        /**
+         * Aproximate (+- 500ms) time in microsec, between each report is sent
+         * to CC
+         */  
+    unsigned long reportPeriod;
+    
+    unsigned short int portCommandListener;
+    unsigned short int portReportListener;
+
+        //we implement commandListener as a TCPListener derived class, to be   
+        //able to custom the behaviour by overriding it's methods, namely
+        //process     
+
+        /* maxTimeoutCount. Times subsystem tries to reconnect CC (with reportPeriod)
+         *  periodicity, before it considers CC not available.
+         *  
+         *  After this count is reached Subsystem has to react some way
+         *  (parking itself,  ...). This is done by
+         *  Subsystem::HandleConnectionTimeoutIsOver 
+         *
+         *  @see #HandleConnectionTimeoutIsOver
+         *
+         */
+    
+    short int maxTimeoutCount;
+
+
+    bool locked;
+    bool reporting;
+    IONotifier* reportAckNotifier;
+    
+        //we implement reportSender as an instance of class TCPSender
+    TCPSender reportSender;
+        //reporting and trying connections to cc are implemented as
+        //PeriodicActions     
+    PeriodicAction tryReportConn,reportingLoop;
+    pthread_mutex_t mutex4report;
+    inline void StartReporting();
+    virtual void process();
+    bool SendReport();
+    void CheckReportAcknowledge();
+        //to be able to checkreportacknowledge on has to have the timestamp of
+        //the last report sent
+    char lastTimeStamp[TIMESTAMP_LEN];
+    void ExtractTimeStampFromLastReportTo(char *);
+
+    bool acknowledgeReceivedForLastReport;
+    short int timeoutCount;
+    pthread_mutex_t mutex4ack;
+    void Lock();
+    void ULock();
+
+};
+
+#endif
Index: trunk/MagicSoft/Control/SubsystemIO/Subsystem.plain.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/Subsystem.plain.C	(revision 1041)
+++ 	(revision )
@@ -1,361 +1,0 @@
-/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
-================================================================
- 
-  This code is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
- 
-  This code is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
- 
-  You should have received a copy of the GNU General Public License
-  along with Emacs (which is required to make this stuff work); if
-  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-  Cambridge, MA 02139, USA.
-==================================================================
-*/ 
-
-//it is a good idea to encapsulate all the configuration file dependence in one a wrapper class SubFormatSubsystem, and derive from it
-//#include "SubFormatSubsystem.C"
-#include "Subsystem.H"
-#include "PeriodicAction.H"
-#include "TCPListener.H"
-#include "TCPSender.H"
-#include "IONotifier.H"
-#include <string>
-//for signals/slots (Callbacks in C++, see http://libsigc.sourceforge.net/)
-#include <sigc++/signal_system.h>
-//libsigc must be installed
-#include <stdio.h>
-using namespace SigC;
-
-#include <unistd.h> //for usleep
-#include <sys/time.h>
-#include <sys/types.h>
-Subsystem::Subsystem (unsigned short int portCommandListener, unsigned long int reportPeriod, char * ccName, unsigned short int portReportListener , unsigned short int maxTimeoutCount_, char * specialReportOnStartup ) 
-            :
-        TCPListener(portCommandListener), reportSender(ccName,portReportListener),  locked(false),  reporting(false),maxTimeoutCount(maxTimeoutCount_),reportPeriod(reportPeriod)
-        {
-//the behaviour is the following: commandListener has been started as a being derived from TCPListener. When connection from cc is opened commands are processed in this->process()
-//when REPOR arrives reportSender(TCPSender) here tries to connect reportListener in CC. When this happens will start a periodic reporting
-
-            
-//by now         
-//demo report:
-            strcpy(reportString,"standby:11:44:20:11:01:6:34:12:6.0:6.1:6.05:11:01:36:34:12:10.6:6.0:6.0:00:00:30.0:00:00:4.6:0.1:0.05:0.004:0.0:0.001:0.003:guiding:0.1deg:on:3.1Hz:0.09deg:J2000:Mkn421:messagefromthedrive:");
-            pthread_mutex_init(&mutex4report,NULL);
-            pthread_mutex_init(&mutex4reporting,NULL);
-    }
-void * Subsystem::ReportingAndCheckingLoop()
-{
-#ifdef DEBUG
-    printf("Subsystem: ReportingAndChecking Thread created\n");
-    
-#endif
-    timeoutCount=0;
-    acknowledgeReceivedForLastReport=true;
-
-    while(!reportSender.isTrialToConnectSuccesful()){
-#ifdef DEBUG
-        printf("Subsystem: retrying in %d usec\n",reportPeriod);
-#endif
-        usleep(reportPeriod);
-    }
-    fd_set read_fd_set;
-    FD_ZERO (&read_fd_set);
-    FD_SET(reportSender.IODescriptor(), &read_fd_set); 
-    struct timeval tv;
-    tv.tv_sec = 0;
-    tv.tv_usec = (reportPeriod);
-    while(Reporting())
-    {
-            /* Block until input arrives, which is ack. */
-
-        if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, &tv) < 0)
-        {
-            perror("Subsystem: select");
-            exit (EXIT_FAILURE);
-        }
-  
-        if (FD_ISSET(reportSender.IODescriptor(), &read_fd_set))
-        {
-//input arrived, which is the ack
-#ifdef DEBUG
-        printf("Subsystem: ack received\n");
-#endif          
-            CheckReportAcknowledge();
-            FD_SET (reportSender.IODescriptor(), &read_fd_set);
-            continue;
-                //in linux, tv after select represents the time not slept, so we feed it again to select to complete the reportPeriod
-        }else{
-                //input didn't arrrive so it's time to report
-            if(!SendReport()){
-                    //sending was not succesfull
-                
-                    //ResetConnectionToCC();
-                if(locked){
-                    ULock();
-                }
-                reportSender.CloseConnection();
-                
-#ifdef DEBUG
-                printf("Subsystem: ReportingAndChecking Thread exited on ack checking \n");
-#endif
-//TO DO!!!!!!!!!!!!! 
-//                TCPListener::ClosingChannel();
-                
-                break;
-                
-                
-            }
-            
-            FD_SET (reportSender.IODescriptor(), &read_fd_set);
-            tv.tv_sec = 0;
-            tv.tv_usec = reportPeriod;  
-      }
-        
-    }
-//if program reaches here is because it hasn't been able to report correctly 
-#ifdef DEBUG
-    printf("Subsystem: ReportingAndChecking Thread finished\n");
-#endif
-return 0;
-
-}
-    
-void Subsystem::SetReportString(char * report)
-{
-    SuspendComm();
-    strcpy(this->reportString,report);
-    ResumeComm();
-    
-}
-
-bool Subsystem::SendSpecialReportContaining(char * specialReport)
-{
-    if(!acknowledgeReceivedForLastReport){
-        timeoutCount++;
-        if(timeoutCount==maxTimeoutCount){
-#ifdef DEBUG
-            printf("Subsystem: Timeout expired for report acknowledge. ResetConnectionToCC\n");
-#endif            return false; //SendReport is not succesfull so this will stop Periodic action 
-        }
-    }
-            //before writing the report or sending it make sure no other thread thouches it
-    pthread_mutex_lock(&mutex4report);
-//        SubFormatSubsystem::ElaborateReport
-            //calls overriden method GenerateReport that will do the
-        //append the tag for specialReport in this protocol 
-    sprintf(this->reportString,"SPECIAL:%s",specialReport);
-    
-        //GenerateReport may have filled timestamp. Record it to checkreportacknowledge in future
-
-
-    ExtractTimeStampFromLastReportTo(lastTimeStamp);
-    reportSender.Send(this->reportString);
-#ifdef DEBUG
-    printf("Subsystem: Sending %s \n",this->reportString);
-#endif
-    pthread_mutex_unlock(&mutex4report);    
-
-    acknowledgeReceivedForLastReport=false;
-//????????Order mutexes are lock/unlock????????????
-    return true; //if it goes here reporting was succesfull (Used in PeriodicAction reportingLoop)
-}
-
-void Subsystem::ClosingChannel()
-{
-//  #ifdef DEBUG
-//      printf("Subsystem: cancelling ReportingAndChecking\n");
-//  #endif
-
-//      pthread_cancel(reportThread);
-//  #ifdef DEBUG
-//      printf("Subsystem: cancelled ReportingAndChecking\n");
-//  #endif
-    
-    TCPListener::ClosingChannel();
-    if(locked){
-        ULock();
-    }
-#ifdef DEBUG
-    printf("Subsystem: resetting connection\n");
-#endif
-      SetReporting(false);
-#ifdef DEBUG
-      printf("Subsystem: waiting ReportingAndChecking Thread to finish\n");
-#endif
-      pthread_join(reportThread,NULL);
-#ifdef DEBUG
-      printf("Subsystem: ReportingAndChecking finished\n");
-#endif    
-    reportSender.CloseConnection();
-}
-
-
-    void Subsystem::ResetConnectionToCC () {
-        if(locked){
-            ULock();
-        }
-#ifdef DEBUG
-        printf("Subsystem: resetting connection\n");
-#endif
-        SetReporting(false);
-#ifdef DEBUG
-        printf("Subsystem: waiting ReportingAndChecking Thread to finish\n");
-#endif
-        pthread_join(reportThread,NULL);
-#ifdef DEBUG
-        printf("Subsystem: ReportingAndChecking finished\n");
-#endif    
-        reportSender.CloseConnection();
-        TCPListener::ClosingChannel(); //but still is waiting for new connections
-    }
-void Subsystem::process(){
-    if (!locked){
-        if(!Reporting()){
-
-            if ( !strcmp(TCPListener::receivedStream, "REPOR") ) {
-#ifdef DEBUG
-                printf("Subsystem: received REPOR\n");
-#endif
-                    //before startreporting, the connection to cc by reportSender has to be stablished
-                pthread_create(&reportThread,NULL,&Subsystem::pthread_ReportingAndCheckingLoop,this);
-                SetReporting(true);
-                return;
-            }
-        } else { //already reporting
-            if ( !strcmp(TCPListener::receivedStream,"LOCK!") ) {
-                Lock();
-                return;
-            } 
-        }
-             
-    } else { //locked
-//as preliminary tests instead of commands, the new subsystem state is sent
-        if (! strncmp(TCPListener::receivedStream, "ULOCK", 5) ) {
-            ULock();
-            return;
-        } 
-#ifdef DEBUG
-        printf("Subsystem: processing ... seting new state: %s \n", TCPListener::receivedStream);
-#endif  
-            //calls overriden method thet will process the command itself
-        ProcessCmd(TCPListener::receivedStream);
-        
-            //state=receivedStream;
-        return;
-        
-    }
-
-//if program reaches here is because it hasn't Received REPOR & LOCK in the proper way. Network partner it's not (a properly working) CC. Closing the opened connection and waiting for new one            
-    ResetConnectionToCC();
-}
-
-
-bool Subsystem::SendReport () {
-
-    if(!acknowledgeReceivedForLastReport){
-        timeoutCount++;
-        if(timeoutCount==maxTimeoutCount){
-#ifdef DEBUG
-            printf("Subsystem: Timeout expired for report acknowledge. ResetConnectionToCC\n");
-#endif
-            return false; //SendReport is not succesfull so this will stop Periodic action 
-        }
-    }
-            //before writing the report or sending it make sure no other thread thouches it
-    pthread_mutex_lock(&mutex4report);
-//        SubFormatSubsystem::ElaborateReport
-            //calls overriden method GenerateReport that will do the
-    GenerateReport();
-        //GenerateReport may have filled timestamp. Record it to checkreportacknowledge in future
-
-
-    ExtractTimeStampFromLastReportTo(lastTimeStamp);
-    reportSender.Send(this->reportString);
-#ifdef DEBUG
-    printf("Subsystem: Sending %s \n",this->reportString);
-#endif
-    pthread_mutex_unlock(&mutex4report);    
-
-    acknowledgeReceivedForLastReport=false;
-
-    return true; //if it goes here reporting was succesfull (Used in PeriodicAction reportingLoop)
-        //acknowledge check is done elsewhere, when it arrives (asynchronously)
-}
-    void Subsystem::CheckReportAcknowledge()
-        {
-            reportSender.Receive();
-
-//incorporate lastTimeStamp in check           
-            if (reportSender.ReturnNew() == "RECV@" ) {
-                acknowledgeReceivedForLastReport=true;
-                timeoutCount=0;
-            }else{
-                cerr<<"wrong ack!\n";
-            }
-        }
-    
-    void Subsystem::Lock(){
-#ifdef DEBUG
-        printf("Subsystem: Locking to CC mode\n");
-#endif       
-        locked=true;
-    }
-    void Subsystem::ULock(){
-#ifdef DEBUG
-        printf("Subsystem: UNLocking to CC mode\n");
-#endif       
-
-        locked=false;
-    }  
-    void Subsystem::SuspendComm()
-        {
-            pthread_mutex_lock(&mutex4report);
-        };
-    void Subsystem::ResumeComm()
-        {
-            pthread_mutex_unlock(&mutex4report);
-        };
-void Subsystem::ExtractTimeStampFromLastReportTo(char * lastTimeStamp)
-{
-    string report(this->reportString);
-    string::iterator it=report.begin();
-        //point it to the first appearence of : 
-    it+=report.find(":");
-    
-//cut the first field (between :) which is the status
-    report.erase(report.begin(),it);
-
-//#define TIMESTAMP_LEN 12
-//%02.2d:%02.2d:%02.2d:%03.3d
-    it=report.begin(); //back to the beginning
-    it+=12;
-//cut from the timestamp end to the rest
-    report.erase(it,report.end());
-    strcpy(lastTimeStamp,report.c_str());
-    
-}
-void Subsystem::Shutdown()
-{}
-
-void Subsystem::WaitingForShutdown()
-{
-    sleep(6000);
-}
-
-
-//TO BE OVERRIDEN:
-
- void Subsystem::ProcessCmd(char *)
-          {};
- void Subsystem::GenerateReport()
-          {}; 
- void Subsystem::HandleConnectionTimeoutIsOver()
-          {};
-
-
Index: trunk/MagicSoft/Control/SubsystemIO/Subsystem.plain.H
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/Subsystem.plain.H	(revision 1041)
+++ 	(revision )
@@ -1,301 +1,0 @@
-#ifndef SUBSYSTEM
-#define SUBSYSTEM
-
-#include "PeriodicAction.H"
-#include "TCPListener.H"
-#include "PeriodicAction.H"
-#include "TCPSender.H"
-#define TIMESTAMP_LEN 12
-//%02.2d:%02.2d:%02.2d:%03.3d
-//in Makefile#define MAXMSG 4096 
-/**
- * Base class for MAGIC Subsystem's communication with CC
- * 
- * It implements commandListener (see MAGIC-TDAS 00-07) as a TCPListener
- * derived class, to be able to custom the behaviour by overriding its
- * methods  
- *
- * Missing properties: Special Report in a GenerateSpecialReport method, also
- * a final implementation of CheckReportAcknowledge (CC sends back
- * "RECV:timestamp", with timestamp the one extracted from subsystem
- * report. So subsystem has to have a member lastReportTimestamp to compare).
- * Timeout in CheckReportAcknowledge?????.
- *
- * @short Base class for MAGIC Subsystem's communication with CC
- * @author Marc Casaldaliga
- * @version 0.9
- * @see TCPListener
- */
-class Subsystem: public TCPListener
-{
-
-public:
-
-        /**
-         * Set the string to be sent in the next report that will be sent to
-         * CC (with timestamp but without protocol specific item,
-         * e.g. trailing \n). The timestamp is the data one, the time when
-         * data was taken (the relevant for analysis), nothing to do with the
-         * the time the report will be sent.
-         *
-         * It takes care internally of suspending and resuming communications
-         * not to send something is being modified etc 
-         *
-         *  @param report CString with pure report (without "\n" ...) 
-         */ 
-    void SetReportString(char * report);
-
-        /**
-         *  Class unique constructor with the parameters which specify
-         *  Subsystem configuration.
-         *
-         *  @param portCommandListener TCP/IP port Subsystem will open to
-         *  listen to cc commands
-         *
-         *  @param reportPeriod Aproximate (+- 500ms) time in microsec,
-         *  between each report is sent to CC
-         *
-         *  @param ccName C string with CC machine name
-         *
-         *  @param portReportListener TCP/IP port opened in CC which Subsystem
-         *  will contact to send reports 
-         *
-         *  @param maxTimeoutCount_. Times subsystem tries to reconnect CC
-         *  (with reportPeriod) periodicity, before it considers CC not
-         *  available. After this count is reached Subsystem has to react some
-         *  way (parking itself,  ...). This is done by
-         *  Subsystem::HandleConnectionTimeoutIsOver 
-         *
-         *  @param specialReportOnStartup When connection with CC is
-         *  stablished for first time after a Subsystem startup a special
-         *  report to CC with subsystem setup must be sent to ensure any setup
-         *  changes (which may have happened while CC was down) are
-         *  recorded. This C string only contains report content without any
-         *  protocol dependent character 
-         *
-         *  @see #HandleConnectionTimeoutIsOver
-         *
-         */
-    Subsystem (unsigned short int portCommandListener, unsigned long int
-               reportPeriod, char * ccName, unsigned short int
-               portReportListener, unsigned short int maxTimeoutCount_, char *
-               specialReportOnStartup );  
-
-        /**
-         * Send (immediately) a special report which a part from
-         * protocol specific items (e.g. trailing \n and special report
-         * identifier) contains the argument specialReport  
-         *
-         * ??? timestamp ????
-         *
-         * It takes care internally of suspending and resuming communications
-         * not to send something is being modified etc 
-         *
-         *  @param specialReport CString with pure special report (without
-         * "\n" ...)
-         * 
-         *  @return Returns whether sending will be succesful (true) or not
-         *  (false)  
-         */ 
-    bool SendSpecialReportContaining(char * specialReport);
-
-        /**
-         *  Blocks main thread until Subsystem::Shutdown is called
-         */
-    void WaitingForShutdown();
-
-        /**
-         *  Subsystem communications will be shutdown definitely. Call this
-         *  inside ProcessCmd or HandleConnectionTimeoutIsOver when your
-         *  subsystem has to be stopped. If you only want to go standalone but
-         *  still in contact with CC, you have to Ulock it but not this.
-         *
-         *  This call unblocks WaitingForShutdown in main, so your subsystem
-         *  application can finish.
-         */    
-    void Shutdown();
-    
-protected:
-        /**
-         * Field with the report that will be sent to CC (with timestamp but
-         * without protocol specific item, e.g. trailing \n)
-         *
-         * To be modified only within GenerateReport
-         */
-    char reportString[MAXMSG];
-           
-        /** To be overriden. It has to do all the job of interpreting CC
-         * commands: (not the ones 
-         * regarding starting connection, locking ...) but the ones for the 
-         * subsystem function (This way we separate the protocol dependent
-         * stuff).  
-         *
-         * Compares Subsystem::ccCmd with known commands from cc and executes
-         * the appropiate function 
-         *
-         * This method is automatically called when a command from cc is
-         * received, after checking it is not a communication/locking command 
-         * 
-         * If receiving a nonsense command call to ResetConnectionToCC()
-         * (Network partner it's not -a properly working- CC). In principle
-         * this will close and open again, but let's leave it this way so that
-         * it is not protocol dependent 
-         *
-         * @param ccCmd CString with pure CC command (without "\n" ...) 
-         */
-    virtual void ProcessCmd(char *ccCmd);
-
-        /** GenerateReport (to be overriden) This next method is automatically
-         *   called before sending a report.
-         * 
-         *  According to state and data this should write
-         *  Subsystem::reportString (it 
-         *  should include the timestamp of the data sent, but without any
-         *  trailing \n--this is part of the protocol) 
-         *
-         *  After it, this Subsystem::reportString plus any protocol dependent
-         *  thing is sent. This GenerateReport and send is periodically
-         *  repeated with reportPeriod   
-         *
-         *  Alternatively, one may leave GenerateReport empty and from outside
-         *  call to Subsystem::SetReportString when hardware info is updated
-         *  (probably what one what like to do). 
-         */
-    virtual void GenerateReport();
-
-        /** HandleConnectionTimeoutIsOver. Does what the subsystem is suposed
-         *  to do when it has lost definitely connection to CC. To be
-         *  overriden. 
-         *
-         *  After Subsystem::maxTimeoutCount times of reconnection tries CC is
-         *  considered not available. Subsystem has to react some way (parking
-         *  itself,  ... ) depending on its autonomy. This is done by
-         *  overriding this method with the desired behaviour.
-         *
-         *  After HandleConnectionTimeoutIsOver is done Subsystem will listen
-         *  to CC again and start all communication process.
-         *
-         *  see #maxTimeoutCount
-         */  
-    virtual void HandleConnectionTimeoutIsOver(); 
-
-        /** SuspendComm. Suspend communication threads
-         *
-         *  To prevent Subsystem to access its resources (e.g. send
-         *  reportString) when we are about to access them externally (fill
-         *  reportString with actual data), one can call to this method and
-         *  suspend subsystem activity. 
-         *  To resume it call to Subsystem::ResumeComm. 
-         *  
-         *  Always paired with a ResumeComm.
-         *
-         *  If Subsystem is at that time accessing the resources, SuspendComm
-         *  will wait for them to be released and then will lock them. 
-         *
-         *  @see #ResumeComm
-         *
-         */
-    void SuspendComm();
-
-        /** ResumeComm. Resume communication threads
-         *
-         *  After calling SuspendComm() and having access to Subsystem
-         *  resources (e.g. fill reportString with actual data) allow
-         *  Subsystem to access them again and resume it's activity. we are
-         *  about to access them externally (fill reportString with actual 
-         *  data), one can call to this method and suspend subsystem activity.
-         *  
-         *  @see #SuspendComm
-         *
-         */
-    void ResumeComm();
-
-        /**
-         * Resets communication to CC, to be used when a nonsense command
-         * arrives from CC 
-         * @see #ProcessCmd
-         */
-    void ResetConnectionToCC();
-
-    
-
-private:
-        /**
-         * C string with CC machine name
-         */
-    char* ccName;
-        /**
-         * Aproximate (+- 500ms) time in microsec, between each report is sent
-         * to CC
-         */  
-    unsigned long int reportPeriod;
-    
-    unsigned short int portCommandListener;
-    unsigned short int portReportListener;
-
-        //we implement commandListener as a TCPListener derived class, to be   
-        //able to custom the behaviour by overriding it's methods, namely
-        //process     
-
-        /* maxTimeoutCount. Times subsystem tries to reconnect CC (with reportPeriod)
-         *  periodicity, before it considers CC not available.
-         *  
-         *  After this count is reached Subsystem has to react some way
-         *  (parking itself,  ...). This is done by
-         *  Subsystem::HandleConnectionTimeoutIsOver 
-         *
-         *  @see #HandleConnectionTimeoutIsOver
-         *
-         */
-    
-    short int maxTimeoutCount;
-
-
-    bool locked;
-    bool reporting;
-    pthread_mutex_t mutex4reporting;
-    inline bool Reporting(){ 
-        pthread_mutex_lock(&mutex4reporting);
-        bool ret=reporting;
-        pthread_mutex_unlock(&mutex4reporting);
-        return ret;
-    }
-    inline void SetReporting(bool trueValue)
-        {
-            pthread_mutex_lock(&mutex4reporting);
-            reporting=trueValue;
-            pthread_mutex_unlock(&mutex4reporting);
-        }
-    
-        //we implement reportSender as an instance of class TCPSender
-    TCPSender reportSender;
-        //reporting and trying connections to cc are implemented as
-        //PeriodicActions     
-
-    pthread_mutex_t mutex4report;
-    virtual void process();
-    virtual void ClosingChannel();
-    
-    bool SendReport();
-    void CheckReportAcknowledge();
-        //to be able to checkreportacknowledge on has to have the timestamp of
-        //the last report sent
-    char lastTimeStamp[TIMESTAMP_LEN];
-    void ExtractTimeStampFromLastReportTo(char *);
-    pthread_t reportThread;
-    inline static void * pthread_ReportingAndCheckingLoop(void* self)
-        { 
-            return (void *) ( ((Subsystem* )self)->ReportingAndCheckingLoop() );
-        }
-    
-            
-    void * ReportingAndCheckingLoop();
-    
-    bool acknowledgeReceivedForLastReport;
-    short int timeoutCount;
-    void Lock();
-    void ULock();
-
-};
-
-#endif
Index: trunk/MagicSoft/Control/SubsystemIO/Subsystem.plain.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/Subsystem.plain.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/Subsystem.plain.cxx	(revision 1053)
@@ -0,0 +1,361 @@
+/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
+================================================================
+ 
+  This code is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+ 
+  This code is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with Emacs (which is required to make this stuff work); if
+  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+  Cambridge, MA 02139, USA.
+==================================================================
+*/ 
+
+//it is a good idea to encapsulate all the configuration file dependence in one a wrapper class SubFormatSubsystem, and derive from it
+//#include "SubFormatSubsystem.C"
+#include "Subsystem.H"
+#include "PeriodicAction.H"
+#include "TCPListener.H"
+#include "TCPSender.H"
+#include "IONotifier.H"
+#include <string>
+//for signals/slots (Callbacks in C++, see http://libsigc.sourceforge.net/)
+#include <sigc++/signal_system.h>
+//libsigc must be installed
+#include <stdio.h>
+using namespace SigC;
+
+#include <unistd.h> //for usleep
+#include <sys/time.h>
+#include <sys/types.h>
+Subsystem::Subsystem (unsigned short int portCommandListener, unsigned long int reportPeriod, char * ccName, unsigned short int portReportListener , unsigned short int maxTimeoutCount_, char * specialReportOnStartup ) 
+            :
+        TCPListener(portCommandListener), reportSender(ccName,portReportListener),  locked(false),  reporting(false),maxTimeoutCount(maxTimeoutCount_),reportPeriod(reportPeriod)
+        {
+//the behaviour is the following: commandListener has been started as a being derived from TCPListener. When connection from cc is opened commands are processed in this->process()
+//when REPOR arrives reportSender(TCPSender) here tries to connect reportListener in CC. When this happens will start a periodic reporting
+
+            
+//by now         
+//demo report:
+            strcpy(reportString,"standby:11:44:20:11:01:6:34:12:6.0:6.1:6.05:11:01:36:34:12:10.6:6.0:6.0:00:00:30.0:00:00:4.6:0.1:0.05:0.004:0.0:0.001:0.003:guiding:0.1deg:on:3.1Hz:0.09deg:J2000:Mkn421:messagefromthedrive:");
+            pthread_mutex_init(&mutex4report,NULL);
+            pthread_mutex_init(&mutex4reporting,NULL);
+    }
+void * Subsystem::ReportingAndCheckingLoop()
+{
+#ifdef DEBUG
+    printf("Subsystem: ReportingAndChecking Thread created\n");
+    
+#endif
+    timeoutCount=0;
+    acknowledgeReceivedForLastReport=true;
+
+    while(!reportSender.isTrialToConnectSuccesful()){
+#ifdef DEBUG
+        printf("Subsystem: retrying in %d usec\n",reportPeriod);
+#endif
+        usleep(reportPeriod);
+    }
+    fd_set read_fd_set;
+    FD_ZERO (&read_fd_set);
+    FD_SET(reportSender.IODescriptor(), &read_fd_set); 
+    struct timeval tv;
+    tv.tv_sec = 0;
+    tv.tv_usec = (reportPeriod);
+    while(Reporting())
+    {
+            /* Block until input arrives, which is ack. */
+
+        if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, &tv) < 0)
+        {
+            perror("Subsystem: select");
+            exit (EXIT_FAILURE);
+        }
+  
+        if (FD_ISSET(reportSender.IODescriptor(), &read_fd_set))
+        {
+//input arrived, which is the ack
+#ifdef DEBUG
+        printf("Subsystem: ack received\n");
+#endif          
+            CheckReportAcknowledge();
+            FD_SET (reportSender.IODescriptor(), &read_fd_set);
+            continue;
+                //in linux, tv after select represents the time not slept, so we feed it again to select to complete the reportPeriod
+        }else{
+                //input didn't arrrive so it's time to report
+            if(!SendReport()){
+                    //sending was not succesfull
+                
+                    //ResetConnectionToCC();
+                if(locked){
+                    ULock();
+                }
+                reportSender.CloseConnection();
+                
+#ifdef DEBUG
+                printf("Subsystem: ReportingAndChecking Thread exited on ack checking \n");
+#endif
+//TO DO!!!!!!!!!!!!! 
+//                TCPListener::ClosingChannel();
+                
+                break;
+                
+                
+            }
+            
+            FD_SET (reportSender.IODescriptor(), &read_fd_set);
+            tv.tv_sec = 0;
+            tv.tv_usec = reportPeriod;  
+      }
+        
+    }
+//if program reaches here is because it hasn't been able to report correctly 
+#ifdef DEBUG
+    printf("Subsystem: ReportingAndChecking Thread finished\n");
+#endif
+return 0;
+
+}
+    
+void Subsystem::SetReportString(char * report)
+{
+    SuspendComm();
+    strcpy(this->reportString,report);
+    ResumeComm();
+    
+}
+
+bool Subsystem::SendSpecialReportContaining(char * specialReport)
+{
+    if(!acknowledgeReceivedForLastReport){
+        timeoutCount++;
+        if(timeoutCount==maxTimeoutCount){
+#ifdef DEBUG
+            printf("Subsystem: Timeout expired for report acknowledge. ResetConnectionToCC\n");
+#endif            return false; //SendReport is not succesfull so this will stop Periodic action 
+        }
+    }
+            //before writing the report or sending it make sure no other thread thouches it
+    pthread_mutex_lock(&mutex4report);
+//        SubFormatSubsystem::ElaborateReport
+            //calls overriden method GenerateReport that will do the
+        //append the tag for specialReport in this protocol 
+    sprintf(this->reportString,"SPECIAL:%s",specialReport);
+    
+        //GenerateReport may have filled timestamp. Record it to checkreportacknowledge in future
+
+
+    ExtractTimeStampFromLastReportTo(lastTimeStamp);
+    reportSender.Send(this->reportString);
+#ifdef DEBUG
+    printf("Subsystem: Sending %s \n",this->reportString);
+#endif
+    pthread_mutex_unlock(&mutex4report);    
+
+    acknowledgeReceivedForLastReport=false;
+//????????Order mutexes are lock/unlock????????????
+    return true; //if it goes here reporting was succesfull (Used in PeriodicAction reportingLoop)
+}
+
+void Subsystem::ClosingChannel()
+{
+//  #ifdef DEBUG
+//      printf("Subsystem: cancelling ReportingAndChecking\n");
+//  #endif
+
+//      pthread_cancel(reportThread);
+//  #ifdef DEBUG
+//      printf("Subsystem: cancelled ReportingAndChecking\n");
+//  #endif
+    
+    TCPListener::ClosingChannel();
+    if(locked){
+        ULock();
+    }
+#ifdef DEBUG
+    printf("Subsystem: resetting connection\n");
+#endif
+      SetReporting(false);
+#ifdef DEBUG
+      printf("Subsystem: waiting ReportingAndChecking Thread to finish\n");
+#endif
+      pthread_join(reportThread,NULL);
+#ifdef DEBUG
+      printf("Subsystem: ReportingAndChecking finished\n");
+#endif    
+    reportSender.CloseConnection();
+}
+
+
+    void Subsystem::ResetConnectionToCC () {
+        if(locked){
+            ULock();
+        }
+#ifdef DEBUG
+        printf("Subsystem: resetting connection\n");
+#endif
+        SetReporting(false);
+#ifdef DEBUG
+        printf("Subsystem: waiting ReportingAndChecking Thread to finish\n");
+#endif
+        pthread_join(reportThread,NULL);
+#ifdef DEBUG
+        printf("Subsystem: ReportingAndChecking finished\n");
+#endif    
+        reportSender.CloseConnection();
+        TCPListener::ClosingChannel(); //but still is waiting for new connections
+    }
+void Subsystem::process(){
+    if (!locked){
+        if(!Reporting()){
+
+            if ( !strcmp(TCPListener::receivedStream, "REPOR") ) {
+#ifdef DEBUG
+                printf("Subsystem: received REPOR\n");
+#endif
+                    //before startreporting, the connection to cc by reportSender has to be stablished
+                pthread_create(&reportThread,NULL,&Subsystem::pthread_ReportingAndCheckingLoop,this);
+                SetReporting(true);
+                return;
+            }
+        } else { //already reporting
+            if ( !strcmp(TCPListener::receivedStream,"LOCK!") ) {
+                Lock();
+                return;
+            } 
+        }
+             
+    } else { //locked
+//as preliminary tests instead of commands, the new subsystem state is sent
+        if (! strncmp(TCPListener::receivedStream, "ULOCK", 5) ) {
+            ULock();
+            return;
+        } 
+#ifdef DEBUG
+        printf("Subsystem: processing ... seting new state: %s \n", TCPListener::receivedStream);
+#endif  
+            //calls overriden method thet will process the command itself
+        ProcessCmd(TCPListener::receivedStream);
+        
+            //state=receivedStream;
+        return;
+        
+    }
+
+//if program reaches here is because it hasn't Received REPOR & LOCK in the proper way. Network partner it's not (a properly working) CC. Closing the opened connection and waiting for new one            
+    ResetConnectionToCC();
+}
+
+
+bool Subsystem::SendReport () {
+
+    if(!acknowledgeReceivedForLastReport){
+        timeoutCount++;
+        if(timeoutCount==maxTimeoutCount){
+#ifdef DEBUG
+            printf("Subsystem: Timeout expired for report acknowledge. ResetConnectionToCC\n");
+#endif
+            return false; //SendReport is not succesfull so this will stop Periodic action 
+        }
+    }
+            //before writing the report or sending it make sure no other thread thouches it
+    pthread_mutex_lock(&mutex4report);
+//        SubFormatSubsystem::ElaborateReport
+            //calls overriden method GenerateReport that will do the
+    GenerateReport();
+        //GenerateReport may have filled timestamp. Record it to checkreportacknowledge in future
+
+
+    ExtractTimeStampFromLastReportTo(lastTimeStamp);
+    reportSender.Send(this->reportString);
+#ifdef DEBUG
+    printf("Subsystem: Sending %s \n",this->reportString);
+#endif
+    pthread_mutex_unlock(&mutex4report);    
+
+    acknowledgeReceivedForLastReport=false;
+
+    return true; //if it goes here reporting was succesfull (Used in PeriodicAction reportingLoop)
+        //acknowledge check is done elsewhere, when it arrives (asynchronously)
+}
+    void Subsystem::CheckReportAcknowledge()
+        {
+            reportSender.Receive();
+
+//incorporate lastTimeStamp in check           
+            if (reportSender.ReturnNew() == "RECV@" ) {
+                acknowledgeReceivedForLastReport=true;
+                timeoutCount=0;
+            }else{
+                cerr<<"wrong ack!\n";
+            }
+        }
+    
+    void Subsystem::Lock(){
+#ifdef DEBUG
+        printf("Subsystem: Locking to CC mode\n");
+#endif       
+        locked=true;
+    }
+    void Subsystem::ULock(){
+#ifdef DEBUG
+        printf("Subsystem: UNLocking to CC mode\n");
+#endif       
+
+        locked=false;
+    }  
+    void Subsystem::SuspendComm()
+        {
+            pthread_mutex_lock(&mutex4report);
+        };
+    void Subsystem::ResumeComm()
+        {
+            pthread_mutex_unlock(&mutex4report);
+        };
+void Subsystem::ExtractTimeStampFromLastReportTo(char * lastTimeStamp)
+{
+    string report(this->reportString);
+    string::iterator it=report.begin();
+        //point it to the first appearence of : 
+    it+=report.find(":");
+    
+//cut the first field (between :) which is the status
+    report.erase(report.begin(),it);
+
+//#define TIMESTAMP_LEN 12
+//%02.2d:%02.2d:%02.2d:%03.3d
+    it=report.begin(); //back to the beginning
+    it+=12;
+//cut from the timestamp end to the rest
+    report.erase(it,report.end());
+    strcpy(lastTimeStamp,report.c_str());
+    
+}
+void Subsystem::Shutdown()
+{}
+
+void Subsystem::WaitingForShutdown()
+{
+    sleep(6000);
+}
+
+
+//TO BE OVERRIDEN:
+
+ void Subsystem::ProcessCmd(char *)
+          {};
+ void Subsystem::GenerateReport()
+          {}; 
+ void Subsystem::HandleConnectionTimeoutIsOver()
+          {};
+
+
Index: trunk/MagicSoft/Control/SubsystemIO/Subsystem.plain.hxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/Subsystem.plain.hxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/Subsystem.plain.hxx	(revision 1053)
@@ -0,0 +1,301 @@
+#ifndef SUBSYSTEM
+#define SUBSYSTEM
+
+#include "PeriodicAction.H"
+#include "TCPListener.H"
+#include "PeriodicAction.H"
+#include "TCPSender.H"
+#define TIMESTAMP_LEN 12
+//%02.2d:%02.2d:%02.2d:%03.3d
+//in Makefile#define MAXMSG 4096 
+/**
+ * Base class for MAGIC Subsystem's communication with CC
+ * 
+ * It implements commandListener (see MAGIC-TDAS 00-07) as a TCPListener
+ * derived class, to be able to custom the behaviour by overriding its
+ * methods  
+ *
+ * Missing properties: Special Report in a GenerateSpecialReport method, also
+ * a final implementation of CheckReportAcknowledge (CC sends back
+ * "RECV:timestamp", with timestamp the one extracted from subsystem
+ * report. So subsystem has to have a member lastReportTimestamp to compare).
+ * Timeout in CheckReportAcknowledge?????.
+ *
+ * @short Base class for MAGIC Subsystem's communication with CC
+ * @author Marc Casaldaliga
+ * @version 0.9
+ * @see TCPListener
+ */
+class Subsystem: public TCPListener
+{
+
+public:
+
+        /**
+         * Set the string to be sent in the next report that will be sent to
+         * CC (with timestamp but without protocol specific item,
+         * e.g. trailing \n). The timestamp is the data one, the time when
+         * data was taken (the relevant for analysis), nothing to do with the
+         * the time the report will be sent.
+         *
+         * It takes care internally of suspending and resuming communications
+         * not to send something is being modified etc 
+         *
+         *  @param report CString with pure report (without "\n" ...) 
+         */ 
+    void SetReportString(char * report);
+
+        /**
+         *  Class unique constructor with the parameters which specify
+         *  Subsystem configuration.
+         *
+         *  @param portCommandListener TCP/IP port Subsystem will open to
+         *  listen to cc commands
+         *
+         *  @param reportPeriod Aproximate (+- 500ms) time in microsec,
+         *  between each report is sent to CC
+         *
+         *  @param ccName C string with CC machine name
+         *
+         *  @param portReportListener TCP/IP port opened in CC which Subsystem
+         *  will contact to send reports 
+         *
+         *  @param maxTimeoutCount_. Times subsystem tries to reconnect CC
+         *  (with reportPeriod) periodicity, before it considers CC not
+         *  available. After this count is reached Subsystem has to react some
+         *  way (parking itself,  ...). This is done by
+         *  Subsystem::HandleConnectionTimeoutIsOver 
+         *
+         *  @param specialReportOnStartup When connection with CC is
+         *  stablished for first time after a Subsystem startup a special
+         *  report to CC with subsystem setup must be sent to ensure any setup
+         *  changes (which may have happened while CC was down) are
+         *  recorded. This C string only contains report content without any
+         *  protocol dependent character 
+         *
+         *  @see #HandleConnectionTimeoutIsOver
+         *
+         */
+    Subsystem (unsigned short int portCommandListener, unsigned long int
+               reportPeriod, char * ccName, unsigned short int
+               portReportListener, unsigned short int maxTimeoutCount_, char *
+               specialReportOnStartup );  
+
+        /**
+         * Send (immediately) a special report which a part from
+         * protocol specific items (e.g. trailing \n and special report
+         * identifier) contains the argument specialReport  
+         *
+         * ??? timestamp ????
+         *
+         * It takes care internally of suspending and resuming communications
+         * not to send something is being modified etc 
+         *
+         *  @param specialReport CString with pure special report (without
+         * "\n" ...)
+         * 
+         *  @return Returns whether sending will be succesful (true) or not
+         *  (false)  
+         */ 
+    bool SendSpecialReportContaining(char * specialReport);
+
+        /**
+         *  Blocks main thread until Subsystem::Shutdown is called
+         */
+    void WaitingForShutdown();
+
+        /**
+         *  Subsystem communications will be shutdown definitely. Call this
+         *  inside ProcessCmd or HandleConnectionTimeoutIsOver when your
+         *  subsystem has to be stopped. If you only want to go standalone but
+         *  still in contact with CC, you have to Ulock it but not this.
+         *
+         *  This call unblocks WaitingForShutdown in main, so your subsystem
+         *  application can finish.
+         */    
+    void Shutdown();
+    
+protected:
+        /**
+         * Field with the report that will be sent to CC (with timestamp but
+         * without protocol specific item, e.g. trailing \n)
+         *
+         * To be modified only within GenerateReport
+         */
+    char reportString[MAXMSG];
+           
+        /** To be overriden. It has to do all the job of interpreting CC
+         * commands: (not the ones 
+         * regarding starting connection, locking ...) but the ones for the 
+         * subsystem function (This way we separate the protocol dependent
+         * stuff).  
+         *
+         * Compares Subsystem::ccCmd with known commands from cc and executes
+         * the appropiate function 
+         *
+         * This method is automatically called when a command from cc is
+         * received, after checking it is not a communication/locking command 
+         * 
+         * If receiving a nonsense command call to ResetConnectionToCC()
+         * (Network partner it's not -a properly working- CC). In principle
+         * this will close and open again, but let's leave it this way so that
+         * it is not protocol dependent 
+         *
+         * @param ccCmd CString with pure CC command (without "\n" ...) 
+         */
+    virtual void ProcessCmd(char *ccCmd);
+
+        /** GenerateReport (to be overriden) This next method is automatically
+         *   called before sending a report.
+         * 
+         *  According to state and data this should write
+         *  Subsystem::reportString (it 
+         *  should include the timestamp of the data sent, but without any
+         *  trailing \n--this is part of the protocol) 
+         *
+         *  After it, this Subsystem::reportString plus any protocol dependent
+         *  thing is sent. This GenerateReport and send is periodically
+         *  repeated with reportPeriod   
+         *
+         *  Alternatively, one may leave GenerateReport empty and from outside
+         *  call to Subsystem::SetReportString when hardware info is updated
+         *  (probably what one what like to do). 
+         */
+    virtual void GenerateReport();
+
+        /** HandleConnectionTimeoutIsOver. Does what the subsystem is suposed
+         *  to do when it has lost definitely connection to CC. To be
+         *  overriden. 
+         *
+         *  After Subsystem::maxTimeoutCount times of reconnection tries CC is
+         *  considered not available. Subsystem has to react some way (parking
+         *  itself,  ... ) depending on its autonomy. This is done by
+         *  overriding this method with the desired behaviour.
+         *
+         *  After HandleConnectionTimeoutIsOver is done Subsystem will listen
+         *  to CC again and start all communication process.
+         *
+         *  see #maxTimeoutCount
+         */  
+    virtual void HandleConnectionTimeoutIsOver(); 
+
+        /** SuspendComm. Suspend communication threads
+         *
+         *  To prevent Subsystem to access its resources (e.g. send
+         *  reportString) when we are about to access them externally (fill
+         *  reportString with actual data), one can call to this method and
+         *  suspend subsystem activity. 
+         *  To resume it call to Subsystem::ResumeComm. 
+         *  
+         *  Always paired with a ResumeComm.
+         *
+         *  If Subsystem is at that time accessing the resources, SuspendComm
+         *  will wait for them to be released and then will lock them. 
+         *
+         *  @see #ResumeComm
+         *
+         */
+    void SuspendComm();
+
+        /** ResumeComm. Resume communication threads
+         *
+         *  After calling SuspendComm() and having access to Subsystem
+         *  resources (e.g. fill reportString with actual data) allow
+         *  Subsystem to access them again and resume it's activity. we are
+         *  about to access them externally (fill reportString with actual 
+         *  data), one can call to this method and suspend subsystem activity.
+         *  
+         *  @see #SuspendComm
+         *
+         */
+    void ResumeComm();
+
+        /**
+         * Resets communication to CC, to be used when a nonsense command
+         * arrives from CC 
+         * @see #ProcessCmd
+         */
+    void ResetConnectionToCC();
+
+    
+
+private:
+        /**
+         * C string with CC machine name
+         */
+    char* ccName;
+        /**
+         * Aproximate (+- 500ms) time in microsec, between each report is sent
+         * to CC
+         */  
+    unsigned long int reportPeriod;
+    
+    unsigned short int portCommandListener;
+    unsigned short int portReportListener;
+
+        //we implement commandListener as a TCPListener derived class, to be   
+        //able to custom the behaviour by overriding it's methods, namely
+        //process     
+
+        /* maxTimeoutCount. Times subsystem tries to reconnect CC (with reportPeriod)
+         *  periodicity, before it considers CC not available.
+         *  
+         *  After this count is reached Subsystem has to react some way
+         *  (parking itself,  ...). This is done by
+         *  Subsystem::HandleConnectionTimeoutIsOver 
+         *
+         *  @see #HandleConnectionTimeoutIsOver
+         *
+         */
+    
+    short int maxTimeoutCount;
+
+
+    bool locked;
+    bool reporting;
+    pthread_mutex_t mutex4reporting;
+    inline bool Reporting(){ 
+        pthread_mutex_lock(&mutex4reporting);
+        bool ret=reporting;
+        pthread_mutex_unlock(&mutex4reporting);
+        return ret;
+    }
+    inline void SetReporting(bool trueValue)
+        {
+            pthread_mutex_lock(&mutex4reporting);
+            reporting=trueValue;
+            pthread_mutex_unlock(&mutex4reporting);
+        }
+    
+        //we implement reportSender as an instance of class TCPSender
+    TCPSender reportSender;
+        //reporting and trying connections to cc are implemented as
+        //PeriodicActions     
+
+    pthread_mutex_t mutex4report;
+    virtual void process();
+    virtual void ClosingChannel();
+    
+    bool SendReport();
+    void CheckReportAcknowledge();
+        //to be able to checkreportacknowledge on has to have the timestamp of
+        //the last report sent
+    char lastTimeStamp[TIMESTAMP_LEN];
+    void ExtractTimeStampFromLastReportTo(char *);
+    pthread_t reportThread;
+    inline static void * pthread_ReportingAndCheckingLoop(void* self)
+        { 
+            return (void *) ( ((Subsystem* )self)->ReportingAndCheckingLoop() );
+        }
+    
+            
+    void * ReportingAndCheckingLoop();
+    
+    bool acknowledgeReceivedForLastReport;
+    short int timeoutCount;
+    void Lock();
+    void ULock();
+
+};
+
+#endif
Index: trunk/MagicSoft/Control/SubsystemIO/TCPListener.ionotifier.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPListener.ionotifier.C	(revision 1041)
+++ 	(revision )
@@ -1,146 +1,0 @@
-/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
-================================================================
- 
-  This code is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
- 
-  This code is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
- 
-  You should have received a copy of the GNU General Public License
-  along with Emacs (which is required to make this stuff work); if
-  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-  Cambridge, MA 02139, USA.
-==================================================================
-*/ 
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h> 
-#include "socket_functions.h"
-#include "IONotifier.H"
-#include "TCPListener.H"
-#include <string>
-//for signals/slots (Callbacks in C++, see http://libsigc.sourceforge.net/
-#include <sigc++/signal_system.h>
-using namespace SigC;
-//for perror
-#include <stdio.h>
-//for close
-#include <unistd.h>
-
-
-TCPListener::TCPListener (int port_) 
-        :port(port_),newReceived(false),comMode(false),notifierOfIncomingConn(0),channelReadable(0)
-{
-    socketItself=make_socket(port);
-        //specify that socketItself it's willing to listen only at one client at a time
-    
-    if( listen(socketItself,1)<0){
-        perror("in listen");
-    }
-    notifierOfIncomingConn=new IONotifier(socketItself);
-        //when notifierOfIncomingConn becomes readable it's because it is recieving an incoming connection, Accept it with accept method. The next statment connects this readable signal to accept slot
-    notifierOfIncomingConn->readable.connect(slot(*this,&TCPListener::Accept));
-    
-}
-
-TCPListener::~TCPListener() {
-    if(comMode){
-        cerr<<"deleting\n";
-        
-        this->ClosingChannel();
-    }
-    delete notifierOfIncomingConn;
-    close(socketItself);
-}
-    
-void TCPListener::Accept () {
-    size_t size=sizeof(socketAddr);
-    channel=accept(socketItself, (struct sockaddr *) &socketAddr, &size);
-    if(channel<0){
-        perror("in Accept");
-//            exit (EXIT_FAILURE);
-    }else{
-//first of all, don't acccept new connections
-        delete notifierOfIncomingConn;
-        
-        clientAddress=inet_ntoa(socketAddr.sin_addr);
-        clientPort=ntohs(socketAddr.sin_port);
-        fprintf(stderr, "TCPListener: client contacted from %s:%hd\n", clientAddress, clientPort);
-//            fconfigure $channel -buffering line
-// assume channel opens a O_SYNC 
-        channelReadable=new IONotifier(channel);
-        channelReadable->readable.connect(slot(this,&TCPListener::Receive));
-        comMode=true;
-        
-    }
-}
-
-
-//this next method is only internally called when something arrives at channel (be careful, it can be the connection has closed)
-void TCPListener::Receive () { //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
-//      cerr << "Receive\n"
-    int nbytes;
-    nbytes = read (channel, receivedStream, MAXMSG);
-    if (nbytes < 0){
-            /* Read error. */
-        perror("TCPListener: read");
-        exit (EXIT_FAILURE);
-    }else if (nbytes == 0){
-        
-            /* End-of-file. */
-        receivedStream[0]='0';
-        receivedStream[1]='\0';
-        this->ClosingChannel();
-    }else{
-            /* Data read. */
-            //look for '\n' and chomp, in anycase read doesn't supply the \n so add it
-        if(receivedStream[nbytes-1]=='\n'){
-            receivedStream[nbytes-1]='\0';
-#ifdef DEBUG        
-            printf("TCPListener: chomp\n");
-#endif
-        }else{
-            receivedStream[nbytes]='\0';
-        }
-#ifdef DEBUG        
-        printf("TCPListener: got message: `%s'\n", receivedStream);
-#endif
-        this->process();
-        newReceived=true;
-    }
-}
-    
-void TCPListener::ClosingChannel(){
-    cerr<<"TCPListener: closing socket to client from "<<clientAddress<<":"<<clientPort<<"\n";
-    delete channelReadable;
-    close(channel);
-    comMode=false;
-//setup again
-    notifierOfIncomingConn=new IONotifier(socketItself);
-        //when notifierOfIncomingConn becomes readable it's because it is recieving an incoming connection, Accept it with accept method. The next statment connects this readable signal to accept slot
-    notifierOfIncomingConn->readable.connect(slot(*this,&TCPListener::Accept));
-    
-}
-//this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
-void TCPListener::process (){
-//to be overriden
-    cerr<<"TCPListener: message Received ["<<receivedStream<<"] and processed from "<<clientAddress<<":"<<clientPort<<"\n";
-    
-}
-
-string TCPListener::ReturnNew () {
-    if (newReceived) {
-        newReceived=false;
-        return string(receivedStream);
-    }else{
-        return string("0");
-    }
-}
-
-
Index: trunk/MagicSoft/Control/SubsystemIO/TCPListener.ionotifier.H
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPListener.ionotifier.H	(revision 1041)
+++ 	(revision )
@@ -1,47 +1,0 @@
-#ifndef TCPLISTENER
-#define TCPLISTENER
-
-#include "IONotifier.H"
-#include <string>
-#include <sigc++/signal_system.h>
-
-using namespace SigC;
-//in Makefile#define MAXMSG 4096 
-#include <netinet/in.h>
-//this is not properly a TCP server in the broadest sense (multiple clients). It should be called TCPListener(pending: change name consistently!). Only accepts connections from one client and responds driven by this client
-//TCPListener derives from libsigc++(signal/slot) Object to be able to connect signals to its methods
-class TCPListener: public Object {
-private:
-    int port;
-    bool newReceived;
-protected:
-    char receivedStream[MAXMSG];
-private:
-    char * clientAddress;
-    int clientPort;
-        //should be called commIsUp. Class Make up
-    bool comMode;
-public:
-    TCPListener (int port_);
-    ~TCPListener();
-protected:
-        //this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
-    virtual void process ();
-    string ReturnNew ();
-    void ClosingChannel();
-private:
-    void Accept ();    
-    void Receive ();  //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
-
-        
-//server socket(the one which listens to incoming connections) file descriptor    
-    int socketItself;
-//socket opened here to parter the incoming connection. This is the one used to communicate
-    int channel;
-    struct sockaddr_in socketAddr;
-    IONotifier* notifierOfIncomingConn;
-    IONotifier* channelReadable;
-    
-};
-
-#endif
Index: trunk/MagicSoft/Control/SubsystemIO/TCPListener.ionotifier.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPListener.ionotifier.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/TCPListener.ionotifier.cxx	(revision 1053)
@@ -0,0 +1,146 @@
+/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
+================================================================
+ 
+  This code is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+ 
+  This code is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with Emacs (which is required to make this stuff work); if
+  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+  Cambridge, MA 02139, USA.
+==================================================================
+*/ 
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h> 
+#include "socket_functions.h"
+#include "IONotifier.H"
+#include "TCPListener.H"
+#include <string>
+//for signals/slots (Callbacks in C++, see http://libsigc.sourceforge.net/
+#include <sigc++/signal_system.h>
+using namespace SigC;
+//for perror
+#include <stdio.h>
+//for close
+#include <unistd.h>
+
+
+TCPListener::TCPListener (int port_) 
+        :port(port_),newReceived(false),comMode(false),notifierOfIncomingConn(0),channelReadable(0)
+{
+    socketItself=make_socket(port);
+        //specify that socketItself it's willing to listen only at one client at a time
+    
+    if( listen(socketItself,1)<0){
+        perror("in listen");
+    }
+    notifierOfIncomingConn=new IONotifier(socketItself);
+        //when notifierOfIncomingConn becomes readable it's because it is recieving an incoming connection, Accept it with accept method. The next statment connects this readable signal to accept slot
+    notifierOfIncomingConn->readable.connect(slot(*this,&TCPListener::Accept));
+    
+}
+
+TCPListener::~TCPListener() {
+    if(comMode){
+        cerr<<"deleting\n";
+        
+        this->ClosingChannel();
+    }
+    delete notifierOfIncomingConn;
+    close(socketItself);
+}
+    
+void TCPListener::Accept () {
+    size_t size=sizeof(socketAddr);
+    channel=accept(socketItself, (struct sockaddr *) &socketAddr, &size);
+    if(channel<0){
+        perror("in Accept");
+//            exit (EXIT_FAILURE);
+    }else{
+//first of all, don't acccept new connections
+        delete notifierOfIncomingConn;
+        
+        clientAddress=inet_ntoa(socketAddr.sin_addr);
+        clientPort=ntohs(socketAddr.sin_port);
+        fprintf(stderr, "TCPListener: client contacted from %s:%hd\n", clientAddress, clientPort);
+//            fconfigure $channel -buffering line
+// assume channel opens a O_SYNC 
+        channelReadable=new IONotifier(channel);
+        channelReadable->readable.connect(slot(this,&TCPListener::Receive));
+        comMode=true;
+        
+    }
+}
+
+
+//this next method is only internally called when something arrives at channel (be careful, it can be the connection has closed)
+void TCPListener::Receive () { //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
+//      cerr << "Receive\n"
+    int nbytes;
+    nbytes = read (channel, receivedStream, MAXMSG);
+    if (nbytes < 0){
+            /* Read error. */
+        perror("TCPListener: read");
+        exit (EXIT_FAILURE);
+    }else if (nbytes == 0){
+        
+            /* End-of-file. */
+        receivedStream[0]='0';
+        receivedStream[1]='\0';
+        this->ClosingChannel();
+    }else{
+            /* Data read. */
+            //look for '\n' and chomp, in anycase read doesn't supply the \n so add it
+        if(receivedStream[nbytes-1]=='\n'){
+            receivedStream[nbytes-1]='\0';
+#ifdef DEBUG        
+            printf("TCPListener: chomp\n");
+#endif
+        }else{
+            receivedStream[nbytes]='\0';
+        }
+#ifdef DEBUG        
+        printf("TCPListener: got message: `%s'\n", receivedStream);
+#endif
+        this->process();
+        newReceived=true;
+    }
+}
+    
+void TCPListener::ClosingChannel(){
+    cerr<<"TCPListener: closing socket to client from "<<clientAddress<<":"<<clientPort<<"\n";
+    delete channelReadable;
+    close(channel);
+    comMode=false;
+//setup again
+    notifierOfIncomingConn=new IONotifier(socketItself);
+        //when notifierOfIncomingConn becomes readable it's because it is recieving an incoming connection, Accept it with accept method. The next statment connects this readable signal to accept slot
+    notifierOfIncomingConn->readable.connect(slot(*this,&TCPListener::Accept));
+    
+}
+//this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
+void TCPListener::process (){
+//to be overriden
+    cerr<<"TCPListener: message Received ["<<receivedStream<<"] and processed from "<<clientAddress<<":"<<clientPort<<"\n";
+    
+}
+
+string TCPListener::ReturnNew () {
+    if (newReceived) {
+        newReceived=false;
+        return string(receivedStream);
+    }else{
+        return string("0");
+    }
+}
+
+
Index: trunk/MagicSoft/Control/SubsystemIO/TCPListener.ionotifier.hxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPListener.ionotifier.hxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/TCPListener.ionotifier.hxx	(revision 1053)
@@ -0,0 +1,47 @@
+#ifndef TCPLISTENER
+#define TCPLISTENER
+
+#include "IONotifier.H"
+#include <string>
+#include <sigc++/signal_system.h>
+
+using namespace SigC;
+//in Makefile#define MAXMSG 4096 
+#include <netinet/in.h>
+//this is not properly a TCP server in the broadest sense (multiple clients). It should be called TCPListener(pending: change name consistently!). Only accepts connections from one client and responds driven by this client
+//TCPListener derives from libsigc++(signal/slot) Object to be able to connect signals to its methods
+class TCPListener: public Object {
+private:
+    int port;
+    bool newReceived;
+protected:
+    char receivedStream[MAXMSG];
+private:
+    char * clientAddress;
+    int clientPort;
+        //should be called commIsUp. Class Make up
+    bool comMode;
+public:
+    TCPListener (int port_);
+    ~TCPListener();
+protected:
+        //this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
+    virtual void process ();
+    string ReturnNew ();
+    void ClosingChannel();
+private:
+    void Accept ();    
+    void Receive ();  //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
+
+        
+//server socket(the one which listens to incoming connections) file descriptor    
+    int socketItself;
+//socket opened here to parter the incoming connection. This is the one used to communicate
+    int channel;
+    struct sockaddr_in socketAddr;
+    IONotifier* notifierOfIncomingConn;
+    IONotifier* channelReadable;
+    
+};
+
+#endif
Index: trunk/MagicSoft/Control/SubsystemIO/TCPListener.select.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPListener.select.C	(revision 1041)
+++ 	(revision )
@@ -1,224 +1,0 @@
-/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
-================================================================
- 
-  This code is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
- 
-  This code is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
- 
-  You should have received a copy of the GNU General Public License
-  along with Emacs (which is required to make this stuff work); if
-  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-  Cambridge, MA 02139, USA.
-==================================================================
-*/ 
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h> 
-#include "socket_functions.h"
-#include "TCPListener.H"
-#include <string>
-//for signals/slots (Callbacks in C++, see http://libsigc.sourceforge.net/
-#include <sigc++/signal_system.h>
-using namespace SigC;
-//for perror
-#include <stdio.h>
-//for close
-#include <unistd.h>
-
-
-TCPListener::TCPListener (int port_) 
-        :port(port_),newReceived(false),comMode(false)//,destroy(false)
-{
-    socketItself=make_socket(port);
-        //specify that socketItself it's willing to listen only at one client at a time
-    
-    if( listen(socketItself,1)<0){
-        perror("in listen");
-    }
-    pthread_create(&thread,NULL,&TCPListener::Listening,this);
-    pthread_mutex_init(&mutex,NULL);
-}
-void * TCPListener::Listening( void* arg)
-{
-    TCPListener* self=(TCPListener *) arg;
-#ifdef DEBUG
-    printf("TCPListener: Created Listening thread\n");
-    
-#endif
-    fd_set active_fd_set, read_fd_set;
-    int i;
-    size_t size;
-
-
-                /* Initialize the set of active sockets. */
-    FD_ZERO (&active_fd_set);
-    FD_SET (self->socketItself, &active_fd_set);
-
-    while (1)
-    { 
-//        pthread_mutex_lock(&(self->mutex));
-//        if(self->destroy) break;
-//        pthread_mutex_unlock(&(self->mutex));
-
-            /* Block until input arrives on one or more active sockets. */
-        read_fd_set = active_fd_set;
-        if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
-        {
-            perror("TCPListener: select");
-            exit (EXIT_FAILURE);
-        }
-
-            /* Service all the sockets with input pending. */
-        for (i = 0; i < FD_SETSIZE; ++i) {
-            
-            if (FD_ISSET (i, &read_fd_set))
-            {
-                if (i == self->socketItself)
-                {
-                /* Connection request on original socket. */
-#ifdef DEBUG
-                    printf("TCPListener: Accepting connections\n");
-#endif
-                    self->Accept();
-                        //monitor the created channel
-                    FD_SET (self->channel, &active_fd_set);
-                        //but since we don't more than two clients, don't monitor incoming_connections_fd
-                    FD_CLR (self->socketItself, &active_fd_set);
-                }
-                else
-                {
-                    
-                        /* Data arriving on an already-connected socket. */
-#ifdef DEBUG
-                    printf("TCPListener: Received\n");
-#endif
-                   
-        
-                    self->Receive();
-                    if(!self->comMode){ //if connection has been closed to client (after the Receive), until new connection is open don't monitor this
-                        FD_CLR (self->channel, &active_fd_set);
-//monitor incoming_connections_fd back again
-                        FD_SET (self->socketItself, &active_fd_set);
-                    }
-                    
-                }
-            }
-        }
-    
-    }
-#ifdef DEBUG
-    printf("TCPListener: Listening thread finishing\n");
-    
-#endif
-
-}
-
-
-TCPListener::~TCPListener() {
-    if(comMode){
-#ifdef DEBUG
-        printf("TCPListener: deleting\n");
-#endif
-        this->ClosingChannel();
-    }
-//      pthread_mutex_lock(&mutex);
-//      destroy=true;
-//      pthread_mutex_unlock(&mutex); 
-//      pthread_join(thread,NULL);
-    pthread_cancel(thread);
-    
-    close(socketItself);
-
-}
-    
-void TCPListener::Accept () {
-    size_t size=sizeof(socketAddr);
-    channel=accept(socketItself, (struct sockaddr *) &socketAddr, &size);
-    if(channel<0){
-        perror("in Accept");
-//            exit (EXIT_FAILURE);
-    }else{
-        clientAddress=inet_ntoa(socketAddr.sin_addr);
-        clientPort=ntohs(socketAddr.sin_port);
-#ifdef DEBUG
-        fprintf(stderr, "TCPListener: client contacted from %s:%hd\n", clientAddress, clientPort);
-#endif
-//            fconfigure $channel -buffering line
-        comMode=true;
-        
-    }
-}
-
-
-//this next method is only internally called when something arrives at channel (be careful, it can be the connection has closed)
-    
-void TCPListener::Receive () { //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
-#ifdef DEBUG
-    printf("TCPListener: Receive from TCPListener %d\n", this);
-#endif
-    int nbytes;
-    nbytes = read (channel, receivedStream, MAXMSG);
-    if (nbytes < 0){
-            /* Read error. */
-        perror("TCPListener: read");
-        exit (EXIT_FAILURE);
-    }else if (nbytes == 0){
-        
-            /* End-of-file. */
-        receivedStream[0]='0';
-        receivedStream[1]='\0';
-        this->ClosingChannel();
-    }else{
-            /* Data read. */
-            //look for '\n' and chomp, in anycase read doesn't supply the \n so add it
-        if(receivedStream[nbytes-1]=='\n'){
-            receivedStream[nbytes-1]='\0';
-#ifdef DEBUG        
-            printf("TCPListener: chomp\n");
-#endif
-        }else{
-            receivedStream[nbytes]='\0';
-        }
-#ifdef DEBUG        
-        printf("TCPListener: got message: `%s'\n", receivedStream);
-#endif
-        this->process();
-        newReceived=true;
-    }
-}
-
-void TCPListener::ClosingChannel(){
-#ifdef DEBUG
-    printf("TCPListener: closing socket to client from %d:%d\n",clientAddress,clientPort);
-#endif 
-    
-    close(channel);
-    comMode=false;
-
-}
-//this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
-void TCPListener::process (){
-//to be overriden
-#ifdef DEBUG
-    printf("TCPListener: message Received [%s] and processed from client %s:%d \n",receivedStream,clientAddress,clientPort);
-#endif   
-    
-}
-
-string TCPListener::ReturnNew () {
-    if (newReceived) {
-        newReceived=false;
-        return string(receivedStream);
-    }else{
-        return string("0");
-    }
-}
-
-
Index: trunk/MagicSoft/Control/SubsystemIO/TCPListener.select.H
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPListener.select.H	(revision 1041)
+++ 	(revision )
@@ -1,50 +1,0 @@
-#ifndef TCPLISTENER
-#define TCPLISTENER
-
-#include <string>
-#include <sigc++/signal_system.h>
-
-using namespace SigC;
-//in Makefile#define MAXMSG 4096 
-#include <netinet/in.h>
-//this is not properly a TCP server in the broadest sense (multiple clients). It should be called TCPListener(pending: change name consistently!). Only accepts connections from one client and responds driven by this client
-//TCPListener derives from libsigc++(signal/slot) Object to be able to connect signals to its methods
-class TCPListener: public Object {
-private:
-    int port;
-    bool newReceived;
-protected:
-    char receivedStream[MAXMSG];
-private:
-    char * clientAddress;
-    int clientPort;
-        //should be called commIsUp. Class Make up
-    bool comMode;
-    static void * Listening(void * self);
-    
-public:
-    TCPListener (int port_);
-    ~TCPListener();
-protected:
-        //this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
-    virtual void process ();
-    string ReturnNew ();
-    virtual void ClosingChannel();
-private:
-    void Accept ();    
-    void Receive ();  //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
-
-    pthread_t thread;
-    pthread_mutex_t mutex;
-//    bool destroy;
-    
-        
-//server socket(the one which listens to incoming connections) file descriptor    
-    int socketItself;
-//socket opened here to parter the incoming connection. This is the one used to communicate
-    int channel;
-    struct sockaddr_in socketAddr;
-     
-};
-
-#endif
Index: trunk/MagicSoft/Control/SubsystemIO/TCPListener.select.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPListener.select.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/TCPListener.select.cxx	(revision 1053)
@@ -0,0 +1,224 @@
+/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
+================================================================
+ 
+  This code is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+ 
+  This code is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with Emacs (which is required to make this stuff work); if
+  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+  Cambridge, MA 02139, USA.
+==================================================================
+*/ 
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h> 
+#include "socket_functions.h"
+#include "TCPListener.H"
+#include <string>
+//for signals/slots (Callbacks in C++, see http://libsigc.sourceforge.net/
+#include <sigc++/signal_system.h>
+using namespace SigC;
+//for perror
+#include <stdio.h>
+//for close
+#include <unistd.h>
+
+
+TCPListener::TCPListener (int port_) 
+        :port(port_),newReceived(false),comMode(false)//,destroy(false)
+{
+    socketItself=make_socket(port);
+        //specify that socketItself it's willing to listen only at one client at a time
+    
+    if( listen(socketItself,1)<0){
+        perror("in listen");
+    }
+    pthread_create(&thread,NULL,&TCPListener::Listening,this);
+    pthread_mutex_init(&mutex,NULL);
+}
+void * TCPListener::Listening( void* arg)
+{
+    TCPListener* self=(TCPListener *) arg;
+#ifdef DEBUG
+    printf("TCPListener: Created Listening thread\n");
+    
+#endif
+    fd_set active_fd_set, read_fd_set;
+    int i;
+    size_t size;
+
+
+                /* Initialize the set of active sockets. */
+    FD_ZERO (&active_fd_set);
+    FD_SET (self->socketItself, &active_fd_set);
+
+    while (1)
+    { 
+//        pthread_mutex_lock(&(self->mutex));
+//        if(self->destroy) break;
+//        pthread_mutex_unlock(&(self->mutex));
+
+            /* Block until input arrives on one or more active sockets. */
+        read_fd_set = active_fd_set;
+        if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
+        {
+            perror("TCPListener: select");
+            exit (EXIT_FAILURE);
+        }
+
+            /* Service all the sockets with input pending. */
+        for (i = 0; i < FD_SETSIZE; ++i) {
+            
+            if (FD_ISSET (i, &read_fd_set))
+            {
+                if (i == self->socketItself)
+                {
+                /* Connection request on original socket. */
+#ifdef DEBUG
+                    printf("TCPListener: Accepting connections\n");
+#endif
+                    self->Accept();
+                        //monitor the created channel
+                    FD_SET (self->channel, &active_fd_set);
+                        //but since we don't more than two clients, don't monitor incoming_connections_fd
+                    FD_CLR (self->socketItself, &active_fd_set);
+                }
+                else
+                {
+                    
+                        /* Data arriving on an already-connected socket. */
+#ifdef DEBUG
+                    printf("TCPListener: Received\n");
+#endif
+                   
+        
+                    self->Receive();
+                    if(!self->comMode){ //if connection has been closed to client (after the Receive), until new connection is open don't monitor this
+                        FD_CLR (self->channel, &active_fd_set);
+//monitor incoming_connections_fd back again
+                        FD_SET (self->socketItself, &active_fd_set);
+                    }
+                    
+                }
+            }
+        }
+    
+    }
+#ifdef DEBUG
+    printf("TCPListener: Listening thread finishing\n");
+    
+#endif
+
+}
+
+
+TCPListener::~TCPListener() {
+    if(comMode){
+#ifdef DEBUG
+        printf("TCPListener: deleting\n");
+#endif
+        this->ClosingChannel();
+    }
+//      pthread_mutex_lock(&mutex);
+//      destroy=true;
+//      pthread_mutex_unlock(&mutex); 
+//      pthread_join(thread,NULL);
+    pthread_cancel(thread);
+    
+    close(socketItself);
+
+}
+    
+void TCPListener::Accept () {
+    size_t size=sizeof(socketAddr);
+    channel=accept(socketItself, (struct sockaddr *) &socketAddr, &size);
+    if(channel<0){
+        perror("in Accept");
+//            exit (EXIT_FAILURE);
+    }else{
+        clientAddress=inet_ntoa(socketAddr.sin_addr);
+        clientPort=ntohs(socketAddr.sin_port);
+#ifdef DEBUG
+        fprintf(stderr, "TCPListener: client contacted from %s:%hd\n", clientAddress, clientPort);
+#endif
+//            fconfigure $channel -buffering line
+        comMode=true;
+        
+    }
+}
+
+
+//this next method is only internally called when something arrives at channel (be careful, it can be the connection has closed)
+    
+void TCPListener::Receive () { //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
+#ifdef DEBUG
+    printf("TCPListener: Receive from TCPListener %d\n", this);
+#endif
+    int nbytes;
+    nbytes = read (channel, receivedStream, MAXMSG);
+    if (nbytes < 0){
+            /* Read error. */
+        perror("TCPListener: read");
+        exit (EXIT_FAILURE);
+    }else if (nbytes == 0){
+        
+            /* End-of-file. */
+        receivedStream[0]='0';
+        receivedStream[1]='\0';
+        this->ClosingChannel();
+    }else{
+            /* Data read. */
+            //look for '\n' and chomp, in anycase read doesn't supply the \n so add it
+        if(receivedStream[nbytes-1]=='\n'){
+            receivedStream[nbytes-1]='\0';
+#ifdef DEBUG        
+            printf("TCPListener: chomp\n");
+#endif
+        }else{
+            receivedStream[nbytes]='\0';
+        }
+#ifdef DEBUG        
+        printf("TCPListener: got message: `%s'\n", receivedStream);
+#endif
+        this->process();
+        newReceived=true;
+    }
+}
+
+void TCPListener::ClosingChannel(){
+#ifdef DEBUG
+    printf("TCPListener: closing socket to client from %d:%d\n",clientAddress,clientPort);
+#endif 
+    
+    close(channel);
+    comMode=false;
+
+}
+//this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
+void TCPListener::process (){
+//to be overriden
+#ifdef DEBUG
+    printf("TCPListener: message Received [%s] and processed from client %s:%d \n",receivedStream,clientAddress,clientPort);
+#endif   
+    
+}
+
+string TCPListener::ReturnNew () {
+    if (newReceived) {
+        newReceived=false;
+        return string(receivedStream);
+    }else{
+        return string("0");
+    }
+}
+
+
Index: trunk/MagicSoft/Control/SubsystemIO/TCPListener.select.hxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPListener.select.hxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/TCPListener.select.hxx	(revision 1053)
@@ -0,0 +1,50 @@
+#ifndef TCPLISTENER
+#define TCPLISTENER
+
+#include <string>
+#include <sigc++/signal_system.h>
+
+using namespace SigC;
+//in Makefile#define MAXMSG 4096 
+#include <netinet/in.h>
+//this is not properly a TCP server in the broadest sense (multiple clients). It should be called TCPListener(pending: change name consistently!). Only accepts connections from one client and responds driven by this client
+//TCPListener derives from libsigc++(signal/slot) Object to be able to connect signals to its methods
+class TCPListener: public Object {
+private:
+    int port;
+    bool newReceived;
+protected:
+    char receivedStream[MAXMSG];
+private:
+    char * clientAddress;
+    int clientPort;
+        //should be called commIsUp. Class Make up
+    bool comMode;
+    static void * Listening(void * self);
+    
+public:
+    TCPListener (int port_);
+    ~TCPListener();
+protected:
+        //this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
+    virtual void process ();
+    string ReturnNew ();
+    virtual void ClosingChannel();
+private:
+    void Accept ();    
+    void Receive ();  //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
+
+    pthread_t thread;
+    pthread_mutex_t mutex;
+//    bool destroy;
+    
+        
+//server socket(the one which listens to incoming connections) file descriptor    
+    int socketItself;
+//socket opened here to parter the incoming connection. This is the one used to communicate
+    int channel;
+    struct sockaddr_in socketAddr;
+     
+};
+
+#endif
Index: trunk/MagicSoft/Control/SubsystemIO/TCPSender.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPSender.C	(revision 1041)
+++ 	(revision )
@@ -1,181 +1,0 @@
-/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
-================================================================
- 
-  This code is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
- 
-  This code is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
- 
-  You should have received a copy of the GNU General Public License
-  along with Emacs (which is required to make this stuff work); if
-  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-  Cambridge, MA 02139, USA.
-==================================================================
-*/ 
-#include "TCPSender.H"
-#include "PeriodicAction.H"
-#include "socket_functions.h"
-#include <iostream>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h> 
-#include <stdio.h>
-
-TCPSender::TCPSender (char * servName_, unsigned int servPort_ )
-        :retryingTime(3000000),tryingConnect(retryingTime),servPort(servPort_),comMode(false),newReceived(false)//,servName(servName_)
-{
-    strcpy(servName,servName_);
-        //prepare the name
-    init_sockaddr (&server, servName_, servPort);
-        //this->Reset;
-
-    
-}
-TCPSender::~TCPSender(){
-    if(comMode){
-        CloseConnection();
-    }
-}
-    
-void TCPSender::CloseConnection(){
-    if (comMode){
-#ifdef DEBUG
-        cout<<"TCPSender: closing socket to server "<<servName<<":"<<servPort<<"\n";
-#endif
-        close(socketItself);
-        comMode=false;
-    }
-}
-void TCPSender::Reset() {
-    if (comMode){
-        CloseConnection();
-    }
-        //Tryingconnect PeriodicAction object DO this->isTrialToConnectSuccesful periodically WHILE this call is NOT returning true, that is is retrying until connection is succesfull. All the threading is done inside PeriodicAction!
-    tryingConnect.DoWhileNot(slot(this, &TCPSender::isTrialToConnectSuccesful) );
-    
-// //       tryingConnect.FinallyDo(... callback to call when tryingConnect is finished, for example Start reporting periodically (start another PeriodicAction
-//   //     supose we have a virtual method WhenConnectionIsEstablished
-//       tryingConnect.FinallyDo(slot(this,&TCPSender::WhenConnectionIsEstablished));
-    tryingConnect.Start();
-        
-}
-
-int TCPSender::IODescriptor(){ //returns file descriptor (e.g. to use with IONotifier)
-    return socketItself;
-        
-}
-
-bool TCPSender::isTrialToConnectSuccesful(){
-        //create the socketItself. After a failed connect call the socket has to be initialized again (?)
-    socketItself = socket (PF_INET, SOCK_STREAM, 0);
-    if ( (socketItself < 0) || (prepare_socket(socketItself) == -1) ) {
-        perror("TCPSender: socket (client)");
-        exit (EXIT_FAILURE);
-    }
-#ifdef DEBUG
-    printf("TCPSender: trying to connect\n");
-#endif  
-    if (0 > connect (socketItself,
-                     (struct sockaddr *) &server,
-                     sizeof (server))){
-        int myerrno=errno;
-        perror("TCPSender: connect. Retrying");
-        comMode=false;
-        close(socketItself);
-        
-        return false;
-        
-    }else{
-        comMode=true;
-//            fconfigure $socketItself -buffering line
-#ifdef DEBUG
-        printf("TCPSender: TCPSender: successful connection\n");
-#endif
-        return true;
-    }
-}
-
-
-void TCPSender::Send (char *msg ){ //Syncronous send
-    char buffer[MAXMSG];
-    
-    strcpy(buffer,msg);
-    unsigned int len=strlen(buffer);
-    buffer[len]='\n';
-    buffer[len+1]='\0';
-#ifdef DEBUG
-    printf("TCPSender: sending %s \n",buffer);
-#endif
-
-    if(write(socketItself, buffer, strlen(buffer)) != strlen(buffer)){
-        int myerrno=errno;
-    }
-//      char * eol="\n";
-//      if(write(socketItself, eol, strlen(eol)) != strlen(eol)){
-//          int myerrno=errno;
-//      }
-//          //    fsync(readoutSend);
-}
-
-
-void TCPSender::Receive () { //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
-#ifdef DEBUG
-    printf("TCPSender: Receive from TCPSender %d\n", this);
-#endif
-    int nbytes;
-    nbytes = read (socketItself, receivedStream, MAXMSG);
-    if (nbytes < 0){
-            /* Read error. */
-        perror("TCPSender: read");
-//       this->CloseConnection();
-       exit (EXIT_FAILURE);
-    }else if (nbytes == 0){
-        
-            /* End-of-file. */
-        receivedStream[0]='0';
-        receivedStream[1]='\0';
-        this->CloseConnection();
-    }else{
-   /* Data read. */
-            //look for '\n' and chomp, in anycase read doesn't supply the \n so add it
-        if(receivedStream[nbytes-1]=='\n'){
-            receivedStream[nbytes-1]='\0';
-#ifdef DEBUG        
-//            printf("TCPSender: %c%c%c chomp\n", receivedStream[nbytes-3],receivedStream[nbytes-2],receivedStream[nbytes-1]);
-            
-#endif
-        }else{
-            receivedStream[nbytes]='\0';
-        }
-#ifdef DEBUG        
-        printf("TCPSender: got message: `%s'\n", receivedStream);
-#endif
-        this->process();
-        newReceived=true;
-    }
-}
-
-string TCPSender::ReturnNew () {
-    if (newReceived) {
-        newReceived=false;
-        return string(receivedStream);
-    }else{
-        return string("0");
-    }
-}
-
-//this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
-void TCPSender::process (){
-//to be overriden
-#ifdef DEBUG
-    printf("TCPSender: message Received [%s] and processed from server %s:%d \n",receivedStream,servName,servPort);
-#endif
-}
-
-
-
Index: trunk/MagicSoft/Control/SubsystemIO/TCPSender.H
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPSender.H	(revision 1041)
+++ 	(revision )
@@ -1,47 +1,0 @@
-#ifndef TCPSENDER
-#define TCPSENDER
-
-
-#include "PeriodicAction.H"
-#include "socket_functions.h"
-#include <string>
-//in Makefile#define MAXMSG 4096 
-
-class TCPSender : public Object{
-public:
-    char  servName[100];
-    unsigned short int servPort;
-    
-    TCPSender (char * servName_, unsigned int servPort_ );
-    ~TCPSender();
-    
-    void CloseConnection();
-    int IODescriptor();
-    bool isTrialToConnectSuccesful();    
-    void Send (char *msg );
-    void Reset();
-    
-    void Receive ();
-//Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
-    string ReturnNew (); 
-private:
-    struct sockaddr_in server;
-    
-            //file descriptor
-    int socketItself;
-    
-    bool comMode;//better called isCommUp
-    unsigned long int retryingTime;//in usec
-    bool newReceived;
-    char receivedStream[MAXMSG];
-    
-    PeriodicAction tryingConnect;
-  
-//this->CloseConnection method should be capitalized for some consistency. Put the change should be propagated. class Make up!
-    virtual void process ();
-};
-
-
-
-
-#endif
Index: trunk/MagicSoft/Control/SubsystemIO/TCPSender.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPSender.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/TCPSender.cxx	(revision 1053)
@@ -0,0 +1,181 @@
+/*  Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
+================================================================
+ 
+  This code is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+ 
+  This code is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with Emacs (which is required to make this stuff work); if
+  not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+  Cambridge, MA 02139, USA.
+==================================================================
+*/ 
+#include "TCPSender.H"
+#include "PeriodicAction.H"
+#include "socket_functions.h"
+#include <iostream>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h> 
+#include <stdio.h>
+
+TCPSender::TCPSender (char * servName_, unsigned int servPort_ )
+        :retryingTime(3000000),tryingConnect(retryingTime),servPort(servPort_),comMode(false),newReceived(false)//,servName(servName_)
+{
+    strcpy(servName,servName_);
+        //prepare the name
+    init_sockaddr (&server, servName_, servPort);
+        //this->Reset;
+
+    
+}
+TCPSender::~TCPSender(){
+    if(comMode){
+        CloseConnection();
+    }
+}
+    
+void TCPSender::CloseConnection(){
+    if (comMode){
+#ifdef DEBUG
+        cout<<"TCPSender: closing socket to server "<<servName<<":"<<servPort<<"\n";
+#endif
+        close(socketItself);
+        comMode=false;
+    }
+}
+void TCPSender::Reset() {
+    if (comMode){
+        CloseConnection();
+    }
+        //Tryingconnect PeriodicAction object DO this->isTrialToConnectSuccesful periodically WHILE this call is NOT returning true, that is is retrying until connection is succesfull. All the threading is done inside PeriodicAction!
+    tryingConnect.DoWhileNot(slot(this, &TCPSender::isTrialToConnectSuccesful) );
+    
+// //       tryingConnect.FinallyDo(... callback to call when tryingConnect is finished, for example Start reporting periodically (start another PeriodicAction
+//   //     supose we have a virtual method WhenConnectionIsEstablished
+//       tryingConnect.FinallyDo(slot(this,&TCPSender::WhenConnectionIsEstablished));
+    tryingConnect.Start();
+        
+}
+
+int TCPSender::IODescriptor(){ //returns file descriptor (e.g. to use with IONotifier)
+    return socketItself;
+        
+}
+
+bool TCPSender::isTrialToConnectSuccesful(){
+        //create the socketItself. After a failed connect call the socket has to be initialized again (?)
+    socketItself = socket (PF_INET, SOCK_STREAM, 0);
+    if ( (socketItself < 0) || (prepare_socket(socketItself) == -1) ) {
+        perror("TCPSender: socket (client)");
+        exit (EXIT_FAILURE);
+    }
+#ifdef DEBUG
+    printf("TCPSender: trying to connect\n");
+#endif  
+    if (0 > connect (socketItself,
+                     (struct sockaddr *) &server,
+                     sizeof (server))){
+        int myerrno=errno;
+        perror("TCPSender: connect. Retrying");
+        comMode=false;
+        close(socketItself);
+        
+        return false;
+        
+    }else{
+        comMode=true;
+//            fconfigure $socketItself -buffering line
+#ifdef DEBUG
+        printf("TCPSender: TCPSender: successful connection\n");
+#endif
+        return true;
+    }
+}
+
+
+void TCPSender::Send (char *msg ){ //Syncronous send
+    char buffer[MAXMSG];
+    
+    strcpy(buffer,msg);
+    unsigned int len=strlen(buffer);
+    buffer[len]='\n';
+    buffer[len+1]='\0';
+#ifdef DEBUG
+    printf("TCPSender: sending %s \n",buffer);
+#endif
+
+    if(write(socketItself, buffer, strlen(buffer)) != strlen(buffer)){
+        int myerrno=errno;
+    }
+//      char * eol="\n";
+//      if(write(socketItself, eol, strlen(eol)) != strlen(eol)){
+//          int myerrno=errno;
+//      }
+//          //    fsync(readoutSend);
+}
+
+
+void TCPSender::Receive () { //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
+#ifdef DEBUG
+    printf("TCPSender: Receive from TCPSender %d\n", this);
+#endif
+    int nbytes;
+    nbytes = read (socketItself, receivedStream, MAXMSG);
+    if (nbytes < 0){
+            /* Read error. */
+        perror("TCPSender: read");
+//       this->CloseConnection();
+       exit (EXIT_FAILURE);
+    }else if (nbytes == 0){
+        
+            /* End-of-file. */
+        receivedStream[0]='0';
+        receivedStream[1]='\0';
+        this->CloseConnection();
+    }else{
+   /* Data read. */
+            //look for '\n' and chomp, in anycase read doesn't supply the \n so add it
+        if(receivedStream[nbytes-1]=='\n'){
+            receivedStream[nbytes-1]='\0';
+#ifdef DEBUG        
+//            printf("TCPSender: %c%c%c chomp\n", receivedStream[nbytes-3],receivedStream[nbytes-2],receivedStream[nbytes-1]);
+            
+#endif
+        }else{
+            receivedStream[nbytes]='\0';
+        }
+#ifdef DEBUG        
+        printf("TCPSender: got message: `%s'\n", receivedStream);
+#endif
+        this->process();
+        newReceived=true;
+    }
+}
+
+string TCPSender::ReturnNew () {
+    if (newReceived) {
+        newReceived=false;
+        return string(receivedStream);
+    }else{
+        return string("0");
+    }
+}
+
+//this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
+void TCPSender::process (){
+//to be overriden
+#ifdef DEBUG
+    printf("TCPSender: message Received [%s] and processed from server %s:%d \n",receivedStream,servName,servPort);
+#endif
+}
+
+
+
Index: trunk/MagicSoft/Control/SubsystemIO/TCPSender.hxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/TCPSender.hxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/TCPSender.hxx	(revision 1053)
@@ -0,0 +1,47 @@
+#ifndef TCPSENDER
+#define TCPSENDER
+
+
+#include "PeriodicAction.H"
+#include "socket_functions.h"
+#include <string>
+//in Makefile#define MAXMSG 4096 
+
+class TCPSender : public Object{
+public:
+    char  servName[100];
+    unsigned short int servPort;
+    
+    TCPSender (char * servName_, unsigned int servPort_ );
+    ~TCPSender();
+    
+    void CloseConnection();
+    int IODescriptor();
+    bool isTrialToConnectSuccesful();    
+    void Send (char *msg );
+    void Reset();
+    
+    void Receive ();
+//Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
+    string ReturnNew (); 
+private:
+    struct sockaddr_in server;
+    
+            //file descriptor
+    int socketItself;
+    
+    bool comMode;//better called isCommUp
+    unsigned long int retryingTime;//in usec
+    bool newReceived;
+    char receivedStream[MAXMSG];
+    
+    PeriodicAction tryingConnect;
+  
+//this->CloseConnection method should be capitalized for some consistency. Put the change should be propagated. class Make up!
+    virtual void process ();
+};
+
+
+
+
+#endif
Index: trunk/MagicSoft/Control/SubsystemIO/mainForPeriodicAction.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/mainForPeriodicAction.C	(revision 1041)
+++ 	(revision )
@@ -1,59 +1,0 @@
-#include <iostream>
-#include "PeriodicAction.H"
-//the next class derives from sigc++ Object, so its methods are callable as slots
-class Counter:public Object
-{
-public:
-    int max;
-    int count;
-    int incr;
-    
-    Counter(int max_, int incr_)
-            :max(max_),incr(incr_),count(0)
-        {};
-    bool isIncrementPossible()
-        {
-            count+=incr;
-            cout<<"Counter by "<<incr<<" to "<<max<<" is at "<<count<<"\n";
-//be careful on blocking here by putting endl or flushing cout!!!! It spoils the whole thing, because blocks the internal thread
-            if(count<=max) return true;
-            else return false;
-        };
-    void PrintIAmDone()
-        {
-            cout<<"Counter by "<<incr<<" to "<<max<<" is done!\n";
-        };
-    
-};
-bool end;
-
-void endMe()
-{
-    end=true;
-}
-
-int main()
-{
-    end=false;
-    Counter byTwo(100,2), byThree(100,3);
-    
-    PeriodicAction byTwoEachSec(1000000);//in microsec
-//byTwoEachSec will increment byTwo counter until isIncrementPossible returns false (will DoWhile(isIncrementPossible) ). 
-    byTwoEachSec.DoWhile(slot(byTwo,&Counter::isIncrementPossible));
-//DoWhile action has been set to the slot (callback) method isIncrementPossible, member of Counter class,    
-    byTwoEachSec.FinallyDo(slot(byTwo,&Counter::PrintIAmDone));
-//finally, when PeriodicAction finishes, that is, when isIncrementPossible returns false, will call byTwo.PrintIAmDone
-    byTwoEachSec.Start();
-    
-    PeriodicAction byThreeEachTwoSec(2000000);
-    byThreeEachTwoSec.DoWhile(slot(byThree,&Counter::isIncrementPossible));
-    byThreeEachTwoSec.FinallyDo(slot(endMe));
-//in these case FinallyDo is not initialized to a method of an object, but to a global function. How can one provide this flexible interface without signal/slots
-    byThreeEachTwoSec.Start();
-    
-    while(!end){
-    }
-    
-
-    return 0;
-}
Index: trunk/MagicSoft/Control/SubsystemIO/mainForPeriodicAction.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/mainForPeriodicAction.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/mainForPeriodicAction.cxx	(revision 1053)
@@ -0,0 +1,59 @@
+#include <iostream>
+#include "PeriodicAction.H"
+//the next class derives from sigc++ Object, so its methods are callable as slots
+class Counter:public Object
+{
+public:
+    int max;
+    int count;
+    int incr;
+    
+    Counter(int max_, int incr_)
+            :max(max_),incr(incr_),count(0)
+        {};
+    bool isIncrementPossible()
+        {
+            count+=incr;
+            cout<<"Counter by "<<incr<<" to "<<max<<" is at "<<count<<"\n";
+//be careful on blocking here by putting endl or flushing cout!!!! It spoils the whole thing, because blocks the internal thread
+            if(count<=max) return true;
+            else return false;
+        };
+    void PrintIAmDone()
+        {
+            cout<<"Counter by "<<incr<<" to "<<max<<" is done!\n";
+        };
+    
+};
+bool end;
+
+void endMe()
+{
+    end=true;
+}
+
+int main()
+{
+    end=false;
+    Counter byTwo(100,2), byThree(100,3);
+    
+    PeriodicAction byTwoEachSec(1000000);//in microsec
+//byTwoEachSec will increment byTwo counter until isIncrementPossible returns false (will DoWhile(isIncrementPossible) ). 
+    byTwoEachSec.DoWhile(slot(byTwo,&Counter::isIncrementPossible));
+//DoWhile action has been set to the slot (callback) method isIncrementPossible, member of Counter class,    
+    byTwoEachSec.FinallyDo(slot(byTwo,&Counter::PrintIAmDone));
+//finally, when PeriodicAction finishes, that is, when isIncrementPossible returns false, will call byTwo.PrintIAmDone
+    byTwoEachSec.Start();
+    
+    PeriodicAction byThreeEachTwoSec(2000000);
+    byThreeEachTwoSec.DoWhile(slot(byThree,&Counter::isIncrementPossible));
+    byThreeEachTwoSec.FinallyDo(slot(endMe));
+//in these case FinallyDo is not initialized to a method of an object, but to a global function. How can one provide this flexible interface without signal/slots
+    byThreeEachTwoSec.Start();
+    
+    while(!end){
+    }
+    
+
+    return 0;
+}
Index: trunk/MagicSoft/Control/SubsystemIO/mainForPeriodicSignal.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/mainForPeriodicSignal.C	(revision 1041)
+++ 	(revision )
@@ -1,54 +1,0 @@
-#include <iostream>
-#include "PeriodicSignal.H"
-#include <stdio.h>
-//for signals
-#include <sigc++/signal_system.h>
-using namespace SigC;
-class Counter:public Object
-{
-public:
-    int max;
-    int count;
-    int incr;
-    
-    Counter(int max_, int incr_)
-            :max(max_),incr(incr_),count(0)
-        {};
-    void isIncrementPossible()
-        {
-            count+=incr;
-//            cout<<"Counter by "<<incr<<" to "<<max<<" is at "<<count<<"\n";
-            printf("Counter by %d to %d  is at %d\n",incr,max,count);
-        };
-    void PrintIAmDone()
-        {
-            cout<<"Counter by "<<incr<<" to "<<max<<" is done!"<<"\n";
-        };
-    
-};
-bool end;
-
-void endMe()
-{
-    end=true;
-}
-
-int main()
-{
-    end=false;
-    Counter byTwo(100,25), byThree(100,33);
-    
-    PeriodicSignal byTwoEachSec(1000000);
-    byTwoEachSec.signal.connect(slot(byTwo,&Counter::isIncrementPossible));
-    byTwoEachSec.Start();
-    
-    PeriodicSignal byThreeEachTwoSec(2000000);
-    byThreeEachTwoSec.signal.connect(slot(byThree,&Counter::isIncrementPossible));
-    byThreeEachTwoSec.Start();
-    
-    while(!end){
-    }
-    
-
-    return 0;
-}
Index: trunk/MagicSoft/Control/SubsystemIO/mainForPeriodicSignal.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/mainForPeriodicSignal.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/mainForPeriodicSignal.cxx	(revision 1053)
@@ -0,0 +1,54 @@
+#include <iostream>
+#include "PeriodicSignal.H"
+#include <stdio.h>
+//for signals
+#include <sigc++/signal_system.h>
+using namespace SigC;
+class Counter:public Object
+{
+public:
+    int max;
+    int count;
+    int incr;
+    
+    Counter(int max_, int incr_)
+            :max(max_),incr(incr_),count(0)
+        {};
+    void isIncrementPossible()
+        {
+            count+=incr;
+//            cout<<"Counter by "<<incr<<" to "<<max<<" is at "<<count<<"\n";
+            printf("Counter by %d to %d  is at %d\n",incr,max,count);
+        };
+    void PrintIAmDone()
+        {
+            cout<<"Counter by "<<incr<<" to "<<max<<" is done!"<<"\n";
+        };
+    
+};
+bool end;
+
+void endMe()
+{
+    end=true;
+}
+
+int main()
+{
+    end=false;
+    Counter byTwo(100,25), byThree(100,33);
+    
+    PeriodicSignal byTwoEachSec(1000000);
+    byTwoEachSec.signal.connect(slot(byTwo,&Counter::isIncrementPossible));
+    byTwoEachSec.Start();
+    
+    PeriodicSignal byThreeEachTwoSec(2000000);
+    byThreeEachTwoSec.signal.connect(slot(byThree,&Counter::isIncrementPossible));
+    byThreeEachTwoSec.Start();
+    
+    while(!end){
+    }
+    
+
+    return 0;
+}
Index: trunk/MagicSoft/Control/SubsystemIO/mainForSubsystem.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/mainForSubsystem.C	(revision 1041)
+++ 	(revision )
@@ -1,61 +1,0 @@
-//g++ -g mainForSubsystem.C Subsystem.o socket_functions.o -o mainForSubsystem `sigc-config --libs --cflags`
-#include "Subsystem.H"
-//  class MySubsystem: public Subsystem
-//  {
-//  public:
-    
-//      MySubsystem (unsigned short int portCommandListener, unsigned long int
-//                 reportPeriod, char * ccName, unsigned short int
-//                 portReportListener, unsigned short int maxTimeoutCount_, 
-//                 char * specialReportOnStartup)
-//              :Subsystem( portCommandListener, reportPeriod,  ccName, 
-//                          portReportListener,  maxTimeoutCount_, 
-//                          specialReportOnStartup)
-//          {};
-
-//  protected:
-    
-//      virtual void ProcessCmd(char *)
-//          {};
-//      virtual void GenerateReport()
-//          {}; 
-//      virtual void HandleConnectionTimeoutIsOver()
-//          {};
-    
-//  };
-
-            
-#include <unistd.h>
-int main()
-{
-        //This two ports depend on your subsystem
-    unsigned short int portCommandListener=2001;
-    unsigned short int portReportListener=2002;
-    
-    unsigned long int reportPeriod=3000000;//in usec
-    unsigned short int maxTimeoutCount=10;
-        //Unless your subsystem functionallity is integrated in Subsystem
-        //derived class, setup your subsystem hardware here
-        //...
-    
-        //checkout subsystem setup and elaborate the setup/special report:
-    char * specialReportOnStartup="2.34:5:6.89:5.2";
-
-        //now start subsystem communication
-    Subsystem
-        mySubsys(portCommandListener,reportPeriod,"ifae-w41.ifae.es",
-                 portReportListener,maxTimeoutCount,specialReportOnStartup);
-
-
-        //if you haven't overriden ElaborateReport you have to take care to
-        //SetReportString periodically here, along with your subsystem's
-        //hardware control
-
-        //If you have overriden ElaborateReport you just have to
-        //WaitingForShutdown 
-    mySubsys.WaitingForShutdown();
-
-        //setup your subsystem hardware to shutdown ...
-    
-    return 0;
-}
Index: trunk/MagicSoft/Control/SubsystemIO/mainForSubsystem.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/mainForSubsystem.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/mainForSubsystem.cxx	(revision 1053)
@@ -0,0 +1,61 @@
+//g++ -g mainForSubsystem.C Subsystem.o socket_functions.o -o mainForSubsystem `sigc-config --libs --cflags`
+#include "Subsystem.H"
+//  class MySubsystem: public Subsystem
+//  {
+//  public:
+    
+//      MySubsystem (unsigned short int portCommandListener, unsigned long int
+//                 reportPeriod, char * ccName, unsigned short int
+//                 portReportListener, unsigned short int maxTimeoutCount_, 
+//                 char * specialReportOnStartup)
+//              :Subsystem( portCommandListener, reportPeriod,  ccName, 
+//                          portReportListener,  maxTimeoutCount_, 
+//                          specialReportOnStartup)
+//          {};
+
+//  protected:
+    
+//      virtual void ProcessCmd(char *)
+//          {};
+//      virtual void GenerateReport()
+//          {}; 
+//      virtual void HandleConnectionTimeoutIsOver()
+//          {};
+    
+//  };
+
+            
+#include <unistd.h>
+int main()
+{
+        //This two ports depend on your subsystem
+    unsigned short int portCommandListener=2001;
+    unsigned short int portReportListener=2002;
+    
+    unsigned long int reportPeriod=3000000;//in usec
+    unsigned short int maxTimeoutCount=10;
+        //Unless your subsystem functionallity is integrated in Subsystem
+        //derived class, setup your subsystem hardware here
+        //...
+    
+        //checkout subsystem setup and elaborate the setup/special report:
+    char * specialReportOnStartup="2.34:5:6.89:5.2";
+
+        //now start subsystem communication
+    Subsystem
+        mySubsys(portCommandListener,reportPeriod,"ifae-w41.ifae.es",
+                 portReportListener,maxTimeoutCount,specialReportOnStartup);
+
+
+        //if you haven't overriden ElaborateReport you have to take care to
+        //SetReportString periodically here, along with your subsystem's
+        //hardware control
+
+        //If you have overriden ElaborateReport you just have to
+        //WaitingForShutdown 
+    mySubsys.WaitingForShutdown();
+
+        //setup your subsystem hardware to shutdown ...
+    
+    return 0;
+}
Index: trunk/MagicSoft/Control/SubsystemIO/mainForTCPListener.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/mainForTCPListener.C	(revision 1041)
+++ 	(revision )
@@ -1,28 +1,0 @@
-//g++ -g mainForServer.C -o mainForServer `sigc-config --libs --cflags`
-#include "TCPListener.H"
-#include <signal.h>
-//  int end;
-
-//  void endme(int signum)
-//  {
-//      end=1;
-//  }
-
-int main()
-{
-//      signal(SIGINT,endme);
-//      end=0;
-    int count=0;
-    
-    TCPListener myServ(2001);
-//    while(!end){
-    while(true){
-        
-//can do other things ...
-        count++;
-    }
-//  //catch SIGINT(C-c) signal to properly close socket
-//      delete myServ;
-//  //    cout << "closing\n";
-    return 0;
-}
Index: trunk/MagicSoft/Control/SubsystemIO/mainForTCPListener.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/mainForTCPListener.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/mainForTCPListener.cxx	(revision 1053)
@@ -0,0 +1,28 @@
+//g++ -g mainForServer.C -o mainForServer `sigc-config --libs --cflags`
+#include "TCPListener.H"
+#include <signal.h>
+//  int end;
+
+//  void endme(int signum)
+//  {
+//      end=1;
+//  }
+
+int main()
+{
+//      signal(SIGINT,endme);
+//      end=0;
+    int count=0;
+    
+    TCPListener myServ(2001);
+//    while(!end){
+    while(true){
+        
+//can do other things ...
+        count++;
+    }
+//  //catch SIGINT(C-c) signal to properly close socket
+//      delete myServ;
+//  //    cout << "closing\n";
+    return 0;
+}
Index: trunk/MagicSoft/Control/SubsystemIO/mainForTCPSender.C
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/mainForTCPSender.C	(revision 1041)
+++ 	(revision )
@@ -1,17 +1,0 @@
-#include "TCPSender.H"
-//for signals
-#include <sigc++/signal_system.h>
-using namespace SigC;
-#include <unistd.h>  //sleep
-int main()
-{
-    TCPSender myClient("ifae-w41.ifae.es",2001);
-    myClient.Reset();
-    while(true){
-        sleep(1);
-        myClient.Send("Hello");
-        
-    }
-    
-    return 0;
-}
Index: trunk/MagicSoft/Control/SubsystemIO/mainForTCPSender.cxx
===================================================================
--- trunk/MagicSoft/Control/SubsystemIO/mainForTCPSender.cxx	(revision 1053)
+++ trunk/MagicSoft/Control/SubsystemIO/mainForTCPSender.cxx	(revision 1053)
@@ -0,0 +1,17 @@
+#include "TCPSender.H"
+//for signals
+#include <sigc++/signal_system.h>
+using namespace SigC;
+#include <unistd.h>  //sleep
+int main()
+{
+    TCPSender myClient("ifae-w41.ifae.es",2001);
+    myClient.Reset();
+    while(true){
+        sleep(1);
+        myClient.Send("Hello");
+        
+    }
+    
+    return 0;
+}
