Index: /trunk/MagicSoft/Cosy/Changelog
===================================================================
--- /trunk/MagicSoft/Cosy/Changelog	(revision 8863)
+++ /trunk/MagicSoft/Cosy/Changelog	(revision 8864)
@@ -1,3 +1,46 @@
                                                                   -*-*- END -*-*-
+
+ 2008/02/17 Thomas Bretz (La Palma)
+
+   * cosy.cc:            
+     - enable output device file for log-files
+     - set sps default address to "sps"
+
+   * candrv/canopen.[h,cc]:
+     - added member function HasError to return an error status
+       of the network connection
+
+   * candrv/ethernet.[h,cc]:
+     - improved the way a lost connection is reestablished
+     - added HasConnection to return the connection status
+
+   * candrv/interface.h:
+     - added HasConnection to return the connection status
+
+   * candrv/network.cc:
+     - when setting zombies check also the status of the network
+
+   * candrv/nodedrv.h:
+     - made HasError a bit more fool proof
+
+   * devdrv/macs.[cc.h]:
+     - added some more DKC error codes
+     - improved printed error DKC message
+     - do not treat warnings as errors anymore
+
+   * gui/MGCosy.cc:
+     - the RA in TrackPos and CalibPos is in degrees
+
+   * main/MCosy.cc:
+     - replaced some build-in numbers for the shaftenecoder-
+       resolution by it
+     - fixed a weird error: in one case when checking for errors
+       fMac3 was checked without testing for NULL pointer!
+
+   * tcpip/MTcpIpIO.[h,cc]:
+     - imporved the whole communication stuff again, especially
+       the error handling and reestablishing of connections
+
+
 
  2008/02/15 Thomas Bretz (La Palma)
Index: /trunk/MagicSoft/Cosy/candrv/canopen.cc
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/canopen.cc	(revision 8863)
+++ /trunk/MagicSoft/Cosy/candrv/canopen.cc	(revision 8864)
@@ -78,4 +78,9 @@
     if (fInterface)
         fInterface->Stop();
+}
+
+bool CanOpen::HasError() const
+{
+    return fInterface ? !fInterface->HasConnection() : kFALSE;
 }
 
Index: /trunk/MagicSoft/Cosy/candrv/canopen.h
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/canopen.h	(revision 8863)
+++ /trunk/MagicSoft/Cosy/candrv/canopen.h	(revision 8864)
@@ -78,4 +78,6 @@
     virtual void Start();           // Start CanOpen communication
     virtual void Stop();            // Stop  CanOpen communcation
+
+    virtual bool HasError() const;
 
 private:
Index: /trunk/MagicSoft/Cosy/candrv/ethernet.cc
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/ethernet.cc	(revision 8863)
+++ /trunk/MagicSoft/Cosy/candrv/ethernet.cc	(revision 8864)
@@ -74,5 +74,5 @@
 // --------------------------------------------------------------------------
 //
-void Ethernet::ReadSocket(TSocket &rx)
+Bool_t Ethernet::ReadSocket(TSocket &rx)
 {
     Int_t pos = -1;
@@ -87,11 +87,7 @@
     while (!IsThreadCanceled())
     {
-        //TThread::CancelPoint();
-
         unsigned char c;
         const Int_t len = rx.RecvRaw(&c, 1);
 
-        //TThread::CancelPoint();
-
         // No data received (non-blocking mode)
         if (len<0)
@@ -101,11 +97,7 @@
         }
 
-        // Data received with zero length!
+        // Data received with zero length! (Connection lost)
         if (len==0)
-        {
-            gLog << warn << "WARNING - Connection lost (received 0bytes) to " << address << endl;
-            //break; // This break is for TEST PURPOSE FIXME!!!
-            continue;
-        }
+            return kFALSE;
 
         // Data received
@@ -113,5 +105,5 @@
         {
             gLog << err << "Data received from " << address << " is more than one byte!" << endl;
-            break;
+            continue;
         }
 
@@ -121,5 +113,5 @@
             {
                 cout << "Data received from " << address << " too long (> " << MSGLEN << ")" << endl;
-                break;
+                continue;
             }
 
@@ -147,7 +139,88 @@
         // String completed
         HandleMessage(msg);
+
+        return kTRUE;
     }
-}
-
+
+    return kTRUE;
+}
+
+/*
+void Ethernet::ReadSocket(TSocket &rx)
+{
+    Int_t pos = -1;
+
+    Message msg;
+    msg.cmd = M_BCAN_RX_ind;
+    msg.data[0] = 0;
+    msg.data[1] = 0;
+
+    const TString address = MTcpIpO::GetSocketAddress(rx);
+
+    while (!IsThreadCanceled())
+    {
+        //TThread::CancelPoint();
+
+        unsigned char c;
+        const Int_t len = rx.RecvRaw(&c, 1);
+
+        //TThread::CancelPoint();
+
+        // No data received (non-blocking mode)
+        if (len<0)
+        {
+            usleep(1);
+            continue;
+        }
+
+        // Data received with zero length!
+        if (len==0)
+        {
+            gLog << warn << "WARNING - Connection lost (received 0bytes) to " << address << endl;
+            //break; // This break is for TEST PURPOSE FIXME!!!
+            return;
+        }
+
+        // Data received
+        if (len>1)
+        {
+            gLog << err << "Data received from " << address << " is more than one byte!" << endl;
+            continue;
+        }
+
+        if (pos<0)
+        {
+            if (c>=MSGLEN)
+            {
+                cout << "Data received from " << address << " too long (> " << MSGLEN << ")" << endl;
+                continue;
+            }
+
+            msg.len = c;
+            pos = 2;
+            continue;
+        }
+
+        //            if (pos==2 && c==0x0a)
+        //                continue;
+
+        msg.data[pos++] = c;
+        if (pos-2<msg.len)
+            continue;
+
+#ifdef DEBUG
+        cout << "*** RcvdCanFrame len=" << dec << msg.len << ": ";
+        for (int i=0; i<msg.len; i++)
+            cout << "0x" << setfill('0') << setw(2) << hex << (int)((msg.data+2)[i]) << " ";
+        cout << dec << endl;
+#endif
+
+        pos = -1;
+
+        // String completed
+        HandleMessage(msg);
+    }
+}
+*/
 
 // --------------------------------------------------------------------------
@@ -174,4 +247,7 @@
 //   */
 //
+#ifdef DEBUG
+#include <TStopwatch.h>
+#endif
 void Ethernet::SendCanFrame(WORD_t cobid, BYTE_t m[8], BYTE_t rtr)
 {
@@ -203,5 +279,12 @@
 #endif
 
+#ifdef DEBUG
+    TStopwatch st;
+    st.Start();
+#endif
     MTcpIpO::SendFrame(fTxAddress, fTxPort, (char*)(msg.data+1), msg.len-1);
+#ifdef DEBUG
+    st.Print();
+#endif
     //Send((char*)(msg.data+1), msg.len-1);
 
Index: /trunk/MagicSoft/Cosy/candrv/ethernet.h
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/ethernet.h	(revision 8863)
+++ /trunk/MagicSoft/Cosy/candrv/ethernet.h	(revision 8864)
@@ -17,9 +17,11 @@
 
     // Send interface based on MTcpIpI
-    void ReadSocket(TSocket &rx);
+    Bool_t ReadSocket(TSocket &rx);
 
     // Start/stop communication inherited from Interface
     void Start() { RunThread(); }
     void Stop()  { CancelThread(); }
+
+    Bool_t HasConnection() const { return IsConnectionEstablished(); }
 
 public:
Index: /trunk/MagicSoft/Cosy/candrv/interface.h
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/interface.h	(revision 8863)
+++ /trunk/MagicSoft/Cosy/candrv/interface.h	(revision 8864)
@@ -45,4 +45,6 @@
     virtual void EnableCobId(WORD_t cobid, int flag=TRUE) { }
 
+    virtual bool HasConnection() const { return true; }
+
     // Public interface
     void PrintMsg(const Message &m);
Index: /trunk/MagicSoft/Cosy/candrv/network.cc
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/network.cc	(revision 8863)
+++ /trunk/MagicSoft/Cosy/candrv/network.cc	(revision 8864)
@@ -314,4 +314,7 @@
             continue;
 
+        if (CanOpen::HasError())
+            fNodes[i]->SetZombie();
+
         if (!fNodes[i]->HasError())
             continue;
@@ -325,4 +328,7 @@
         //gLog << "' has error #" << fNodes[i]->GetError() << endl;
     }
+
+    if (CanOpen::HasError())
+        return true;
 
     return rc;
Index: /trunk/MagicSoft/Cosy/candrv/nodedrv.h
===================================================================
--- /trunk/MagicSoft/Cosy/candrv/nodedrv.h	(revision 8863)
+++ /trunk/MagicSoft/Cosy/candrv/nodedrv.h	(revision 8864)
@@ -60,5 +60,5 @@
 
     int  GetError() const { return fError; }
-    bool HasError() const { return fError; }
+    bool HasError() const { return fError!=0; }
 
     bool IsZombieNode() const { return fIsZombie; }
Index: /trunk/MagicSoft/Cosy/cosy.cc
===================================================================
--- /trunk/MagicSoft/Cosy/cosy.cc	(revision 8863)
+++ /trunk/MagicSoft/Cosy/cosy.cc	(revision 8864)
@@ -90,5 +90,5 @@
     const Bool_t  kDebugMem     = arg.HasOnlyAndRemove("--debug-mem");
     const Bool_t  kDebugThreads = arg.HasOnlyAndRemove("--debug-threads");
-    const TString sps           = arg.GetStringAndRemove("--sps=", "127.0.0.1");
+    const TString sps           = arg.GetStringAndRemove("--sps=", "sps");
     const TString ceco          = arg.GetStringAndRemove("--cc=", "ceco"); // ceco
     const TString pointing      = arg.GetStringAndRemove("--pointing-model=", "bending2.txt"); // ceco
@@ -138,4 +138,5 @@
         gLog << inf << "Open automatic logfile: " << name << endl;
         gLog.SetOutputFile(name);
+        gLog.EnableOutputDevice(MLog::eFile);
     }
 
Index: /trunk/MagicSoft/Cosy/devdrv/macs.cc
===================================================================
--- /trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 8863)
+++ /trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 8864)
@@ -71,4 +71,6 @@
     case 0xa148: return "Drive controlled interpolated relative positioning lagless with encoder 1";
     case 0xa149: return "Drive controlled interpolated relative positioning lagless with encoder 2";
+    case 0xa150: return "Drive controlled positioning with encoder 1";
+    case 0xa151: return "Drive controlled positioning with encoder 2";
     case 0xa208: return "Jog mode positive";
     case 0xa218: return "Jog mode negative";
@@ -86,4 +88,6 @@
     case 0xe251: return "Motor overtemp warning";
     case 0xe252: return "Bleeder overtemp warning";
+    case 0xe257: return "Continous current limit active";
+    case 0xe264: return "Target position out of numerical range";
     case 0xe834: return "Emergency-Stop";
     case 0xe843: return "Positive end-switch activated";
@@ -95,4 +99,5 @@
     case 0xf224: return "Maximum breaking time exceeded";
     case 0xf228: return "Excessive control deviation";
+    case 0xf250: return "Overflow of target position preset memory";
     case 0xf269: return "Error during release of the motor holding brake";
     case 0xf276: return "Absolute encoder out of allowed window";
@@ -120,5 +125,5 @@
     const Int_t type = errinf&0xf000;
 
-    gLog << all << "DKC reports: ";
+    gLog << all << MTime(-1) << ": " << GetNodeName() << " DKC ";
 
     switch (type)
@@ -127,4 +132,6 @@
     case 0xe000: gLog << "WARNING"; break;
     case 0xa000: gLog << "Status"; break;
+    case 0xc000: 
+    case 0xd000: gLog << "Message"; break;
     default:     gLog << "Unknown"; break;
     }
@@ -134,5 +141,5 @@
     gLog << (type==0xf000 || type==0xe000 ? "!" : ".") << endl;
 
-    return type==0xa000;
+    return type!=0xf000;
 }
 
@@ -148,5 +155,5 @@
             return;
         gLog << inf2 << "- " << GetNodeName() << ": Error[0]=" << hex << val << dec << endl;
-        SetError(EvalStatus(val) ? 0 : val);
+        CheckErrorDKC(val);
         return;
 
@@ -680,4 +687,12 @@
 }
 
+void Macs::CheckErrorDKC(LWORD_t val)
+{
+    Bool_t rc = EvalStatus(val);
+    SetError(rc ? 0 : val);
+    if (!rc)
+        SetZombie();
+}
+
 void Macs::HandlePDO2(const BYTE_t *data, const timeval_t &tv)
 {
@@ -688,6 +703,5 @@
     if (errnum==0xff && (errinf&0xf000)<=0xe000)
     {
-        EvalStatus(errnum, errinf);
-        SetError(0);
+        CheckErrorDKC(errnum, errinf);
         return;
     }
@@ -915,5 +929,5 @@
     case 0xff:
         gLog << err << "DKC error! Go and check what is going on!" << endl;
-        DelError();
+        //DelError();
         return;
 /*
Index: /trunk/MagicSoft/Cosy/devdrv/macs.h
===================================================================
--- /trunk/MagicSoft/Cosy/devdrv/macs.h	(revision 8863)
+++ /trunk/MagicSoft/Cosy/devdrv/macs.h	(revision 8864)
@@ -44,4 +44,10 @@
         return EvalStatus(errnum|(errinf<<16));
     }
+    void CheckErrorDKC(LWORD_t val);
+    void CheckErrorDKC(UInt_t errnum, UInt_t errinf)
+    {
+        CheckErrorDKC(errnum|(errinf<<16));
+    }
+
 
     void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, const timeval_t &tv);
Index: /trunk/MagicSoft/Cosy/gui/MGCosy.cc
===================================================================
--- /trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 8863)
+++ /trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 8864)
@@ -1149,6 +1149,6 @@
     RaDec dest1(xy1.X()*15., xy1.Y()); // xy.X()  [h]->[ø]
 
-    cout << "TrackPos: " << dest0.Ra() << "h " << dest0.Dec() << "\xb0" << endl;
-    cout << "CalibPos: " << dest1.Ra() << "h " << dest1.Dec() << "\xb0" << endl;
+    cout << "TrackPos: " << dest0.Ra() << "\xb0 " << dest0.Dec() << "\xb0" << endl;
+    cout << "CalibPos: " << dest1.Ra() << "\xb0 " << dest1.Dec() << "\xb0" << endl;
 
     RaDec dest[2] = { dest0, dest1 };
Index: /trunk/MagicSoft/Cosy/main/MCosy.cc
===================================================================
--- /trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 8863)
+++ /trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 8864)
@@ -143,6 +143,9 @@
     // Get the values          (FIXME!)
     //
-    int p1 =  (fZd1->GetPos()/*+8192*/)%fZd1->GetPhysRes();
-    int p2 = -(fZd2->GetPos()/*+8192*/)%fZd2->GetPhysRes();
+    //int p1 =  (fZd1->GetPos()+fZd1->GetPhysRes()/2)%fZd1->GetPhysRes();
+    //int p2 = -(fZd2->GetPos()+fZd2->GetPhysRes()/2)%fZd2->GetPhysRes();
+
+    int p1 =  fZd1->GetPos();//+fZd1->GetPhysRes()/2)%fZd1->GetPhysRes();
+    int p2 = -fZd2->GetPos();//+fZd2->GetPhysRes()/2)%fZd2->GetPhysRes();
 
     if (fZd1->IsZombieNode())
@@ -562,5 +565,6 @@
         fMac1->HandleError();
         fMac2->HandleError();
-        fMac3->HandleError();
+        if (fMac3)
+            fMac3->HandleError();
         if (HasError() || HasZombie())
             return false;
@@ -948,6 +952,6 @@
     gLog << " * Max:  " << zmax << "deg  " << amax << "deg" << endl;
 
-    fMin = fBending.AddOffsets(fMin/TMath::RadToDeg());
-    fMax = fBending.AddOffsets(fMax/TMath::RadToDeg());
+    fMin = fBending.AddOffsets(fMin*TMath::DegToRad());
+    fMax = fBending.AddOffsets(fMax*TMath::DegToRad());
 
     gLog << " * Min': " << fMin.Zd()*TMath::RadToDeg() << "deg  " << fMin.Az()*TMath::RadToDeg() << "deg" << endl;
@@ -1628,5 +1632,5 @@
     gLog << inf << "Open Repfile: " << name << endl;
     fOutRep = new MLog(name, kTRUE);
-    *fOutRep << "[Drive Report File]" << endl;
+    *fOutRep << all << "[Drive Report File]" << endl;
     *fOutRep << "Version <cvs>" << endl;
     *fOutRep << "Date " << MTime(-1) << endl;
Index: /trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.cc
===================================================================
--- /trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.cc	(revision 8863)
+++ /trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.cc	(revision 8864)
@@ -2,4 +2,6 @@
 
 #include <unistd.h>    // usleep
+
+#include <errno.h>
 
 #include <TSocket.h>
@@ -153,14 +155,8 @@
 }
 
-void MTcpIpIO::ReadSocket(TSocket &rx)
-{
-    // Clear buffer!
-    char c;
-//    while (fRxSocket->RecvRaw(&c, 1)>0 && !HasStopFlag())
-    while (rx.RecvRaw(&c, 1)>0 && !IsThreadCanceled())
-        usleep(1);
-
+Bool_t MTcpIpIO::ReadSocket(TSocket &rx)
+{
     TString str;
-    //        while (!HasStopFlag())
+
     while (!IsThreadCanceled())
     {
@@ -175,12 +171,7 @@
         }
 
-        // Data received with zero length!
+        // Data received with zero length! (Connection lost)
         if (len==0)
-        {
-            // THIS MEANS CONNECTIION LOST!!!!
-            cout << "============> len==0 (CONNECTION LOST?)" << endl;
-            break; // This break is for TEST PURPOSE FIXME!!!
-            continue;
-        }
+            return kFALSE; // This break is for TEST PURPOSE FIXME!!!
 
         // Data received
@@ -202,7 +193,126 @@
         str = "";
     }
-}
-
-//void *MTcpIpIO::Thread()
+
+    return kTRUE;
+}
+
+Bool_t MTcpIpI::WaitForData(TSocket &sock)
+{
+    // No connection established?
+    if (!sock.IsValid())
+    {
+        gLog << warn << "TSocket invalid on port " << fPortRx << "." << endl;
+        return kFALSE;
+    }
+
+    fConnectionEstablished = kTRUE;
+
+    // Get connection on port fPortRx and redirected
+    while (!IsThreadCanceled())
+    {
+        // Check for pending data (every ms)
+        switch (sock.Select(TSocket::kRead, 1))
+        {
+        case kTRUE:  // Data pending... go on reading
+            if (!ReadSocket(sock))
+            {
+                gLog << warn << "WARNING - Connection lost to " << MTcpIpO::GetSocketAddress(sock) << endl;
+                return kFALSE;
+            }
+
+            // *FALLTHROUGH*
+        case kFALSE: // Time out, no data yet, go on waiting
+
+            // Go on waiting for new data
+            continue;
+
+        default:  // Error occurance
+            gLog << err << "TSocket::Select returned an error: " << strerror(errno) << endl;
+            return kFALSE;
+        }
+    }
+    return kTRUE; //???
+}
+
+void MTcpIpI::WaitForConnection(TServerSocket &server)
+{
+    gLog << all << " Wait for connection" << endl;
+
+    while (!IsThreadCanceled())
+    {
+        gLog << all << "Listening for new connection on port " << fPortRx << "..." << endl;
+
+        // Check for a connection request (reminder: we are in non-blocking mode)
+        TSocket *socket = 0;
+
+        while (!IsThreadCanceled())
+        {
+            socket = server.Accept();
+
+            // Accept returned an error
+            if (socket==0)
+            {
+                gLog << err << "Error: TServerSock::Accept on port " << fPortRx << ": " << strerror(errno) << endl;
+                // Since we don't know the type of the error we better shut down the socket
+                return;
+            }
+
+            // No connection request pending
+            if ((Long_t)socket<0)
+            {
+                MThread::Sleep(1000); // Wait a ms
+                continue;
+            }
+
+            // Connection established
+            break;
+        }
+
+        if ((Long_t)socket<=0)
+            return;
+
+        if (!WaitForData(*socket))
+            fConnectionEstablished = kFALSE;
+
+        delete socket;
+    }
+}
+
+Int_t MTcpIpI::Thread()
+{
+    gLog << inf << "- Starting server listening on port " << fPortRx << "..." << endl;
+
+    while (!IsThreadCanceled())
+    {
+        TServerSocket *server=new TServerSocket(fPortRx, kTRUE);
+        server->SetOption(kNoBlock, 1);
+
+        while (!IsThreadCanceled() && server->IsValid())
+            WaitForConnection(*server);
+
+        if (!server->IsValid())
+        {
+            gLog << err << "ServerSocket on port " << fPortRx << " invalid: ";
+            switch (server->GetErrorCode())
+            {
+            case  0: gLog << "No error." << endl; break;
+            case -1: gLog << "low level socket() call failed." << endl; break;
+            case -2: gLog << "low level bind() call failed." << endl; break;
+            case -3: gLog << "low level listen() call failed." << endl; break;
+            default: gLog << "Unknown." << endl; break;
+            }
+        }
+
+        delete server;
+
+        MThread::Sleep(5000000);
+    }
+
+    gLog << inf << "- Listening server stopped on port " << fPortRx << "." << endl;
+
+    return 0;
+}
+
+/*
 Int_t MTcpIpI::Thread()
 {
@@ -276,8 +386,44 @@
         gLog << all << "Connection established on port " << fPortRx << "." << endl;
 
-        fRxSocket->SetOption(kNoBlock, 1);
+
+        //fRxSocket->SetOption(kNoBlock, 1);
+
+        // Waqit for data
+        while (!IsThreadCanceled())
+        {
+            switch (fRxSocket->Select(kRead, 1))
+            {
+            case kTRUE:  // Data waiting to be read
+                break;
+            case kFALSE: // time out
+                usleep(10);
+                continue;
+            }
+
+            // ERROR
+            cout << "Error: TRxSocket::Select on port " << fPortRx << "." << endl;
+
+            delete fServSock;
+            delete fRxSocket;
+            fServSock = NULL;
+            fRxSocket = NULL;
+            break;
+        }¨
+
+        if (!fServSock)
+            continue;
+
+        if (IsThreadCanceled())
+        {
+            delete fServSock;
+            delete fRxSocket;
+            fServSock = NULL;
+            fRxSocket = NULL;
+            continue;
+        }
 
         // ------ IDENTICAL UP TO HERE ------
 
+        // Read and evaluate data
         ReadSocket(*fRxSocket);
 
@@ -292,3 +438,3 @@
     return 0;
 //    return NULL;
-}
+}*/
Index: /trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.h
===================================================================
--- /trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.h	(revision 8863)
+++ /trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.h	(revision 8864)
@@ -18,13 +18,19 @@
 {
 private:
-    Int_t fPortRx;
+    Int_t  fPortRx;
+    Bool_t fConnectionEstablished;
+
+    Bool_t WaitForData(TSocket &sock);
+    void   WaitForConnection(TServerSocket &server);
 
     Int_t Thread();
 
-    virtual void ReadSocket(TSocket &rx) = 0;
+    virtual Bool_t ReadSocket(TSocket &rx) = 0;
 
 public:
-    MTcpIpI(Int_t rx) : MThread(Form("MTcpIpI::%d", rx)), fPortRx(rx) { /*RunThread();*/ }
+    MTcpIpI(Int_t rx) : MThread(Form("MTcpIpI::%d", rx)), fPortRx(rx), fConnectionEstablished(kFALSE) { /*RunThread();*/ }
     ~MTcpIpI() { CancelThread(); }
+
+    Bool_t IsConnectionEstablished() const { return fConnectionEstablished; }
 };
 
@@ -52,5 +58,5 @@
 {
 private:
-    void ReadSocket(TSocket &rx);
+    Bool_t ReadSocket(TSocket &rx);
 
 public:
