Index: trunk/MagicSoft/Cosy/devdrv/macs.cc
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 1703)
+++ trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 1727)
@@ -33,11 +33,11 @@
     fPosActive(0), fRpmActive(0)
 {
-    fTimeout = new TTimer(this, 100, kFALSE); // 100ms, asynchronous
+//    fTimeout = new TTimer(this, 100); //, kFALSE); // 100ms, asynchronous
 }
 
 Macs::~Macs()
 {
-    fTimerOn = kFALSE;
-    delete fTimeout;
+    //fTimerOn = kFALSE;
+  //  delete fTimeout;
 }
 
@@ -60,16 +60,4 @@
         fVel = val;
         return;
-
-    case 0x4000:
-        switch (subidx)
-        {
-        case 1:
-            cout << GetNodeName() << ": Timeout timer is " << (val?"en":"dis") << "abled." << endl;
-            return;
-        case 2:
-            cout << GetNodeName() << ": Actual timeout time: " << dec << val << "ms" << endl;
-            return;
-        }
-        break;
 
     case 0x6004:
@@ -129,5 +117,5 @@
 }
 
-void Macs::HandleSDOOK(WORD_t idx, BYTE_t subidx)
+void Macs::HandleSDOOK(WORD_t idx, BYTE_t subidx, timeval_t *tv)
 {
     switch (idx)
@@ -137,32 +125,34 @@
         {
         case 0:
-            lout << ddev(MLog::eGui);
+            //lout << ddev(MLog::eGui);
             lout << "- " << GetNodeName() << ": Velocity set." << endl;
-            lout << edev(MLog::eGui);
+            //lout << edev(MLog::eGui);
             return;
         }
         break;
+
     case 0x2003:
         switch (subidx)
         {
         case 0:
-            lout << ddev(MLog::eGui);
+            //lout << ddev(MLog::eGui);
             lout << "- " << GetNodeName() << ": Acceleration set." << endl;
-            lout << edev(MLog::eGui);
+            //lout << edev(MLog::eGui);
             return;
         case 1:
-            lout << ddev(MLog::eGui);
+            //lout << ddev(MLog::eGui);
             lout << "- " << GetNodeName() << ": Decceleration set." << endl;
-            lout << edev(MLog::eGui);
+            //lout << edev(MLog::eGui);
             return;
         }
         break;
+
     case 0x3006:
         switch (subidx)
         {
         case 0:
-            lout << ddev(MLog::eGui);
+            //lout << ddev(MLog::eGui);
             lout << "- " << GetNodeName() << ": RPM mode switched." << endl;
-            lout << edev(MLog::eGui);
+            //lout << edev(MLog::eGui);
             return;
 
@@ -176,24 +166,22 @@
         }
         break;
+
     case 0x4000:
-        if (subidx==0 && fTimerOn)
-        {
-            ResetTimeout();
-            return;
-        }
-        break;
+        HandleNodeguard(tv);
+        return;
+
     case 0x6004:
         switch (subidx)
         {
         case 0:
-            lout << ddev(MLog::eGui);
+            //lout << ddev(MLog::eGui);
             lout << "- " << GetNodeName() << ": Absolute positioning started." << endl;
-            lout << edev(MLog::eGui);
+            //lout << edev(MLog::eGui);
             return;
 
         case 1:
-            lout << ddev(MLog::eGui);
+            //lout << ddev(MLog::eGui);
             lout << "- " << GetNodeName() << ": Relative positioning started." << endl;
-            lout << edev(MLog::eGui);
+            //lout << edev(MLog::eGui);
             return;
         }
@@ -202,5 +190,5 @@
 
     }
-    NodeDrv::HandleSDOOK(idx, subidx);
+    NodeDrv::HandleSDOOK(idx, subidx, tv);
 }
 
@@ -231,8 +219,4 @@
     RequestSDO(0x100b);
     WaitForSdo(0x100b);
-
-    // FIXME! Not statically linked!
-    //    if (fSoftVersion<0x00000035)
-    //        fIsZombie = true;
 }
 
@@ -240,9 +224,20 @@
 void Macs::Init()
 {
+    if (HasError())
+    {
+        lout << "Macs::Init: " << GetNodeName() << " has error --> ZOMBIE!" << endl;
+        SetZombie();
+    }
+
+    StopHostGuarding();
+    StopGuarding();
+
+    usleep(2000.*GetGuardTime());
+
     lout << "- " << GetNodeName() << ": Requesting Mac Software Version." << endl;
     RequestSDO(0x100a);
     WaitForSdo(0x100a);
 
-    if (fIsZombie)
+    if (IsZombieNode())
     {
         lout << GetNodeName() << " - InitDevice failed!" << endl;
@@ -250,5 +245,12 @@
     }
 
-    EnableTimeout(kFALSE);
+    // FIXME! Not statically linked!
+    if (fSoftVersion<0x00000042) // 00.66
+    {
+        lout << GetNodeName() << " - Software Version too old!" << endl;
+        SetZombie();
+        return;
+    }
+
     SetRpmMode(FALSE);
 
@@ -270,4 +272,7 @@
 
     SetNoWait(TRUE);
+
+    StartGuarding(100, 2);
+    StartHostGuarding();
 }
 
@@ -283,5 +288,5 @@
 void Macs::StopDevice()
 {
-    EnableTimeout(kFALSE);
+    //EnableTimeout(kFALSE);
 
     SetNoWait(FALSE);
@@ -348,5 +353,5 @@
 {
     SendSDO(0x2002, vel);     // velocity
-    WaitForSdo(0x2002);
+    WaitForSdo(0x2002, 0);
 }
 
@@ -466,4 +471,6 @@
     {
         lout << "- " << GetNodeName() << ": reports Error occursion." << endl;
+        lout << "Macs::HandlePDO2: " << GetNodeName() << " --> ZOMBIE!" << endl;
+        SetZombie();
         SetError(-1);
         return;
@@ -537,6 +544,6 @@
 
     case 100:
-        lout << "Connection timed out." << endl;
-        EnableTimeout(false);
+        //lout << "Connection timed out." << endl;
+        //EnableTimeout(false);
         return;
 
@@ -562,6 +569,6 @@
     // FIXME: Timeout???
     //
-    while (GetError()<0)
-        usleep(1);
+//  while (GetError()<0)
+//      usleep(1);
 
     //
@@ -569,5 +576,5 @@
     // we can go on working 'as usual' Eg. Initialize a Display Update
     //
-    cout << GetNodeName() << " Handling Error #" << GetError() << endl;
+    cout << GetNodeName() << " Handling Error #" << dec << GetError() << endl;
     switch (GetError())
     {
@@ -576,17 +583,24 @@
     case   9: // zero idx
     case  84: // ON TIME
-        // Stop program?
+        lout << "- " << GetNodeName() << ": Cannot handle error #" << GetError() << endl;
         return;
 
     case 11:  // software endswitch
     case 25:  // hardware endswitch
+        lout << "- " << GetNodeName() << ": Cannot handle error 'Endswitch!'" << endl;
+        return;
+
     case 100: // timeout (movement has been stopped, so we can go on)
         DelError();
         return;
-
+/*
     case 101:
-        lout << "Warning: " << GetNodeName() << " didn't respond in timeout window - try again." << endl;
+        //lout << "Warning: " << GetNodeName() << " didn't respond in timeout window - try again." << endl;
         DelError();
         return;
+        */
+    default:
+        lout << "- " << GetNodeName() << ": Cannot handle error #" << GetError() << endl;
+ 
     }
 }
@@ -633,129 +647,40 @@
 }
 
-void Macs::ReqTimeoutTime()
-{
-    RequestSDO(0x4000, 2);
-    WaitForSdo(0x4000, 2);
-}
-
-void Macs::EnableTimeout(bool enable, LWORDS_t ms)
-{
-    lout << "- " << GetNodeName() << ": " << (enable?"En":"Dis") << "able timeout, " << dec << ms << "ms." << endl;
-    if (!enable)
-    {
-        SendSDO(0x4000, 1, string('o', 'f', 'f'));
-        WaitForSdo(0x4000, 1);
-
-        lout << "- " << GetNodeName() << ": Stopping handshake (PC)." << endl;
-
-        fTimeout->Stop(); //kTRUE);
-
-        fTimerOn = kFALSE;
-    }
-    else
-    {
-        if (ms>0)
-            SetTimeoutTime(ms);
-
-        ResetTimeout();
-
-        fTimerOn = kTRUE;
-        fTimeout->Start(fGuardTime/*/3*2*/, kTRUE); //kFALSE); //TRUE);
-
-        //
-        // Start with kFALSE would be a continous timer, but this
-        // timer seems to stop it's activity at some stage without
-        // any reason
-        //
-        lout << "- " << GetNodeName() << ": starting handshake." << endl;
-        SendSDO(0x4000, 1, string('o', 'n'));
-        WaitForSdo(0x4000, 1);
-    }
-    lout << "- " << GetNodeName() << ": Timeout timer turned "
-        << (enable?"on.":"off.") << endl;
-}
-
-Bool_t Macs::HandleTimer(TTimer *t)
-{
-    /*
-     Fons:
-     -----
-
-     timers never trigger at the same time or when in a TTimer::Notify.
-     Little explanation:
-
-     - there are two types of timers synchronous and a-synchronous.
-     - synchronous timers are only handled via the ROOT eventloop
-       (see TUnixSystem::DispatchOneEvent()). If there are no mouse/keyboard
-       events then the synchronous timer queue is checked. So if the processing
-       of a mouse/keyboard event takes a long time synchronous timers are not
-       called for a while. To prevent this from happening one can call in long
-       procedures gSystem->ProcessEvents(). The system schedules only the
-       next timer in the queue when the current one's Notify() has finished.
-     - a-synchronous timers are triggered via SIGALARM, i.e. the program is
-       interupted and execution jumps to the Notify() function. When the
-       notify is finished the next a-sync timer is scheduled and the system
-       resumes from the place where it was initially interrupted. One of the
-       things to remember when using a-sync timers is don't make any graphics
-       calls in them. X11 is not re-entrant and it might be that the SIGALARM
-       signal interrupted the system while being in X11. A-sync timers are best
-       used to set flags that you can test at a convenient and controlled
-       time.
-       */
-
-    //
-    //  FIXME! Use NMT!
-    //
-    // --- lout << ddev(MLog::eGui);
-    // --- lout << "Send 0x4000: " << GetNodeName() << endl;
-
+void Macs::SendNodeguard()
+{
     SendSDO(0x4000, 0, (LWORD_t)0, false);
-
-    // --- lout << "Done 0x4000: " << GetNodeName() << endl;
-
-    Timer time;
-
-    // --- lout << "dT " << GetNodeName() << ": " <<  dec <<(int)((fTimeoutTime-time.Now())*1000) << endl;
-    // --- lout << edev(MLog::eGui);
-
-    if (time.Now() > fTimeoutTime)
-    {
-        lout << ddev(MLog::eGui);
-        lout << "Warning: " << GetNodeName() << " didn't respond in timeout window." << endl;
-        lout << edev(MLog::eGui);
-        SetError(101);
-    }
-
-    //WaitForSdo(0x4000, 0, kDontWait);
-    //
-    // Would not be necessary if I would Start the timer with
-    // kFALSE. This would be a continous timer, but this
-    // timer seems to stop it's activity at some stage without
-    // any reason
-    //
-    if (fTimerOn)
-        fTimeout->Start(fGuardTime/*/3*2*/, kTRUE);
-
-    return kTRUE;
-}
-
-void Macs::ResetTimeout()
-{
-    Timer time;
-
-    // --- lout << ddev(MLog::eGui);
-    // --- lout << "Reset " << GetNodeName() << ": " << dec << (int)((fTimeoutTime-time.Now())*1000) << endl;
-    // --- lout << edev(MLog::eGui);
-
-    fTimeoutTime = time.Now() + 3.*fGuardTime/1000.;
-}
-
-void Macs::SetTimeoutTime(LWORD_t ms)
-{
-    // FIXME: Is '/2' the best choose?
-    fGuardTime = ms/3;      // how often do we send/request the handshake
-
-    SendSDO(0x4000, 2, ms*2); // How often do we check for the handshake
-    WaitForSdo(0x4000, 2);
-}
-
+}
+
+// --------------------------------------------------------------------------
+//
+// This starts the host guarding. The host guarding is only available
+// if the node guarding is running. The host guarding works with the
+// guardtime and the lifetimefactor from the nodeguarding.
+//
+void Macs::StartHostGuarding()
+{
+    SendSDO(0x100c, 0, (LWORD_t)GetGuardTime());
+    WaitForSdo(0x100c);
+
+    SendSDO(0x100d, 0, (LWORD_t)GetLifeTimeFactor());
+    WaitForSdo(0x100d);
+
+    lout << "- " << GetNodeName() << ": Hostguarding started (" << dec;
+    lout << GetLifeTimeFactor() << "*" << GetGuardTime() << "ms)" << endl;
+}
+
+// --------------------------------------------------------------------------
+//
+// Stop the host guarding.
+//
+void Macs::StopHostGuarding()
+{
+    SendSDO(0x100c, 0, (LWORD_t)0);
+    WaitForSdo(0x100c);
+
+    SendSDO(0x100d, 0, (LWORD_t)0);
+    WaitForSdo(0x100d);
+
+    lout << "- " << GetNodeName() << ": Hostguarding stopped." << endl;
+}
+
