| 
      1
     | 
    
      /**
 
     | 
  
  
    | 
      2
     | 
    
       * \file qwatchdog.cpp
 
     | 
  
  
    | 
      3
     | 
    
       *
 
     | 
  
  
    | 
      4
     | 
    
       * \brief Keep tickling the watchdog so we don't reboot
 
     | 
  
  
    | 
      5
     | 
    
       *
 
     | 
  
  
    | 
      6
     | 
    
       *     o  0
 
     | 
  
  
    | 
      7
     | 
    
       *     | /       Copyright (c) 2005-2012
 
     | 
  
  
    | 
      8
     | 
    
       *    (CL)---o   Critical Link, LLC
 
     | 
  
  
    | 
      9
     | 
    
       *      \
 
     | 
  
  
    | 
      10
     | 
    
       *       O
 
     | 
  
  
    | 
      11
     | 
    
       */
 
     | 
  
  
    | 
      12
     | 
    
      #include <stdio.h>
 
     | 
  
  
    | 
      13
     | 
    
      #include <stdlib.h>
 
     | 
  
  
    | 
      14
     | 
    
      #include <string.h>
 
     | 
  
  
    | 
      15
     | 
    
      #include <unistd.h>
 
     | 
  
  
    | 
      16
     | 
    
      #include <fcntl.h>
 
     | 
  
  
    | 
      17
     | 
    
      #include <sys/ioctl.h>
 
     | 
  
  
    | 
      18
     | 
    
      #include <errno.h>
 
     | 
  
  
    | 
      19
     | 
    
      
 
     | 
  
  
    | 
      20
     | 
    
      #if defined (WIN32)
 
     | 
  
  
    | 
      21
     | 
    
      #elif defined (__GNUC__)
 
     | 
  
  
    | 
      22
     | 
    
      #include <linux/types.h>
 
     | 
  
  
    | 
      23
     | 
    
      #include <linux/watchdog.h>
 
     | 
  
  
    | 
      24
     | 
    
      #elif defined (_TMS320C6X)
 
     | 
  
  
    | 
      25
     | 
    
      #endif
 
     | 
  
  
    | 
      26
     | 
    
      
 
     | 
  
  
    | 
      27
     | 
    
      #include "qwatchdog.h"
 
     | 
  
  
    | 
      28
     | 
    
      
 
     | 
  
  
    | 
      29
     | 
    
      #if defined(__GNUC__) // linux
 
     | 
  
  
    | 
      30
     | 
    
      
 
     | 
  
  
    | 
      31
     | 
    
      /**
 
     | 
  
  
    | 
      32
     | 
    
       * @brief Constructor
 
     | 
  
  
    | 
      33
     | 
    
       * @param anBarkMs Bark Rate (How often to Ping the System Watchdog)
 
     | 
  
  
    | 
      34
     | 
    
       * @param apParent QT Parent Object
 
     | 
  
  
    | 
      35
     | 
    
       */
 
     | 
  
  
    | 
      36
     | 
    
      tcQWatchDog::tcQWatchDog(int anBarkMs, QObject* apParent)
 
     | 
  
  
    | 
      37
     | 
    
          : QObject(apParent)
 
     | 
  
  
    | 
      38
     | 
    
          , mnBarkMs(anBarkMs)
 
     | 
  
  
    | 
      39
     | 
    
          , mnFd(-1)
 
     | 
  
  
    | 
      40
     | 
    
          , mnTimerId(-1)
 
     | 
  
  
    | 
      41
     | 
    
      {
     | 
  
  
    | 
      42
     | 
    
          mnBarkMs = mnBarkMs ?: 10000; // do not allow 0 interval
 
     | 
  
  
    | 
      43
     | 
    
      
 
     | 
  
  
    | 
      44
     | 
    
          if(!getenv("DISABLE_WATCHDOG"))
     | 
  
  
    | 
      45
     | 
    
          {
     | 
  
  
    | 
      46
     | 
    
              struct watchdog_info ident;
 
     | 
  
  
    | 
      47
     | 
    
      
 
     | 
  
  
    | 
      48
     | 
    
              mnFd = ::open("/dev/watchdog", O_WRONLY);
     | 
  
  
    | 
      49
     | 
    
              if(0 < mnFd) // should actually end up >> 0
 
     | 
  
  
    | 
      50
     | 
    
              {
     | 
  
  
    | 
      51
     | 
    
                  int interval = mnBarkMs*2/1000;
 
     | 
  
  
    | 
      52
     | 
    
                  int status = 0;
 
     | 
  
  
    | 
      53
     | 
    
                  memset(&ident, '\0', sizeof(ident));
 
     | 
  
  
    | 
      54
     | 
    
                  status = ioctl(mnFd, WDIOC_GETSUPPORT, &ident);
 
     | 
  
  
    | 
      55
     | 
    
                  if(0 != status)
 
     | 
  
  
    | 
      56
     | 
    
                  {
     | 
  
  
    | 
      57
     | 
    
                      qWarning("Unable to get watchdog info!:%s\n",strerror(errno));
     | 
  
  
    | 
      58
     | 
    
                  }
 
     | 
  
  
    | 
      59
     | 
    
                  else
 
     | 
  
  
    | 
      60
     | 
    
                  {
     | 
  
  
    | 
      61
     | 
    
                      qDebug("Watchdog:%s - v%08x - opts = 0x%08x\n",
     | 
  
  
    | 
      62
     | 
    
                             ident.identity, ident.firmware_version, ident.options);
 
     | 
  
  
    | 
      63
     | 
    
                  }
 
     | 
  
  
    | 
      64
     | 
    
                  status = ioctl(mnFd, WDIOC_SETTIMEOUT, &interval);
 
     | 
  
  
    | 
      65
     | 
    
                  if(0 != status)
 
     | 
  
  
    | 
      66
     | 
    
                  {
     | 
  
  
    | 
      67
     | 
    
                      qWarning("Unable to set watchdog timeout!:%s\n",strerror(errno));
     | 
  
  
    | 
      68
     | 
    
                  }
 
     | 
  
  
    | 
      69
     | 
    
                  interval = -1;
 
     | 
  
  
    | 
      70
     | 
    
                  status = ioctl(mnFd, WDIOC_GETTIMEOUT, &interval);
 
     | 
  
  
    | 
      71
     | 
    
                  if((0 == status) && (interval*1000) < (mnBarkMs*2))
 
     | 
  
  
    | 
      72
     | 
    
                      mnBarkMs = interval * 500; // set WD timeout to 1/2 interval
 
     | 
  
  
    | 
      73
     | 
    
      
 
     | 
  
  
    | 
      74
     | 
    
                  qDebug("Watchdog timeout set to %dms [%dms requested]\n", mnBarkMs, anBarkMs);
     | 
  
  
    | 
      75
     | 
    
      
 
     | 
  
  
    | 
      76
     | 
    
                  if(0 == status)
 
     | 
  
  
    | 
      77
     | 
    
                      mnTimerId = startTimer(mnBarkMs);
 
     | 
  
  
    | 
      78
     | 
    
              }
 
     | 
  
  
    | 
      79
     | 
    
              else
 
     | 
  
  
    | 
      80
     | 
    
              {
     | 
  
  
    | 
      81
     | 
    
                  qWarning("Unable to open /dev/watchdog!:%s\n",strerror(errno));
     | 
  
  
    | 
      82
     | 
    
              }
 
     | 
  
  
    | 
      83
     | 
    
          }
 
     | 
  
  
    | 
      84
     | 
    
          else
 
     | 
  
  
    | 
      85
     | 
    
          {
     | 
  
  
    | 
      86
     | 
    
              qWarning("Watchdod disabled.. DISABLE_WATCHDOG env var set\n");
     | 
  
  
    | 
      87
     | 
    
          }
 
     | 
  
  
    | 
      88
     | 
    
      }
 
     | 
  
  
    | 
      89
     | 
    
      
 
     | 
  
  
    | 
      90
     | 
    
      /**
 
     | 
  
  
    | 
      91
     | 
    
       * @brief Destructor
 
     | 
  
  
    | 
      92
     | 
    
       */
 
     | 
  
  
    | 
      93
     | 
    
      tcQWatchDog::~tcQWatchDog()
 
     | 
  
  
    | 
      94
     | 
    
      {
     | 
  
  
    | 
      95
     | 
    
          if(-1 != mnTimerId)
 
     | 
  
  
    | 
      96
     | 
    
              killTimer(mnTimerId);
 
     | 
  
  
    | 
      97
     | 
    
          if(-1 != mnFd)
 
     | 
  
  
    | 
      98
     | 
    
              ::close(mnFd);
 
     | 
  
  
    | 
      99
     | 
    
      }
 
     | 
  
  
    | 
      100
     | 
    
      
 
     | 
  
  
    | 
      101
     | 
    
      /**
 
     | 
  
  
    | 
      102
     | 
    
       * @brief Sends Ping to System Watchdog
 
     | 
  
  
    | 
      103
     | 
    
       */
 
     | 
  
  
    | 
      104
     | 
    
      void tcQWatchDog::timerEvent(QTimerEvent *)
 
     | 
  
  
    | 
      105
     | 
    
      {
     | 
  
  
    | 
      106
     | 
    
          //bark
 
     | 
  
  
    | 
      107
     | 
    
          int dummy = 1;
 
     | 
  
  
    | 
      108
     | 
    
      
 
     | 
  
  
    | 
      109
     | 
    
          ioctl(mnFd, WDIOC_KEEPALIVE, &dummy);
 
     | 
  
  
    | 
      110
     | 
    
      
 
     | 
  
  
    | 
      111
     | 
    
      }
 
     | 
  
  
    | 
      112
     | 
    
      #else
 
     | 
  
  
    | 
      113
     | 
    
      
 
     | 
  
  
    | 
      114
     | 
    
      // no watchdog on windows
 
     | 
  
  
    | 
      115
     | 
    
      /**
 
     | 
  
  
    | 
      116
     | 
    
       * \brief Constructor
 
     | 
  
  
    | 
      117
     | 
    
       *
 
     | 
  
  
    | 
      118
     | 
    
       * \param anBarkMs Bark Rate (How often to Ping the System Watchdog)
 
     | 
  
  
    | 
      119
     | 
    
       * \param apParent Pointer to parent QT Object
 
     | 
  
  
    | 
      120
     | 
    
       */
 
     | 
  
  
    | 
      121
     | 
    
      tcQWatchDog::tcQWatchDog(int anBarkMs, QObject* apParent)
 
     | 
  
  
    | 
      122
     | 
    
          : QObject(apParent)
 
     | 
  
  
    | 
      123
     | 
    
          , mnBarkMs(anBarkMs)
 
     | 
  
  
    | 
      124
     | 
    
          , mnFd(-1)
 
     | 
  
  
    | 
      125
     | 
    
      {
     | 
  
  
    | 
      126
     | 
    
          qWarning("No watchdog support on this platform\n");
     | 
  
  
    | 
      127
     | 
    
      }
 
     | 
  
  
    | 
      128
     | 
    
      
 
     | 
  
  
    | 
      129
     | 
    
      /**
 
     | 
  
  
    | 
      130
     | 
    
       * \brief Destructor
 
     | 
  
  
    | 
      131
     | 
    
       */
 
     | 
  
  
    | 
      132
     | 
    
      tcQWatchDog::~tcQWatchDog()
 
     | 
  
  
    | 
      133
     | 
    
      {
     | 
  
  
    | 
      134
     | 
    
      }
 
     | 
  
  
    | 
      135
     | 
    
      
 
     | 
  
  
    | 
      136
     | 
    
      /**
 
     | 
  
  
    | 
      137
     | 
    
       * \brief Timer Event does nothing for Windows
 
     | 
  
  
    | 
      138
     | 
    
       */
 
     | 
  
  
    | 
      139
     | 
    
      void tcQWatchDog::timerEvent(QTimerEvent *)
 
     | 
  
  
    | 
      140
     | 
    
      {
     | 
  
  
    | 
      141
     | 
    
      }
 
     | 
  
  
    | 
      142
     | 
    
      #endif // __GNUC__
 
     | 
  
  
    | 
      143
     | 
    
      
 
     | 
  
  
    | 
      144
     | 
    
      #ifdef WATCHDOG_UT
 
     | 
  
  
    | 
      145
     | 
    
      #include <iostream>
 
     | 
  
  
    | 
      146
     | 
    
      #include <QStringList>
 
     | 
  
  
    | 
      147
     | 
    
      #include <QtCore/QDebug>
 
     | 
  
  
    | 
      148
     | 
    
      #include <QtCore/QCoreApplication>
 
     | 
  
  
    | 
      149
     | 
    
      
 
     | 
  
  
    | 
      150
     | 
    
      class CMyApp : public QCoreApplication
 
     | 
  
  
    | 
      151
     | 
    
      {
     | 
  
  
    | 
      152
     | 
    
      public:
 
     | 
  
  
    | 
      153
     | 
    
          CMyApp(int ms, int argc, char** argv);
 
     | 
  
  
    | 
      154
     | 
    
      protected:
 
     | 
  
  
    | 
      155
     | 
    
          void timerEvent(QTimerEvent*);
 
     | 
  
  
    | 
      156
     | 
    
      };
 
     | 
  
  
    | 
      157
     | 
    
      
 
     | 
  
  
    | 
      158
     | 
    
      CMyApp::CMyApp(int ms , int argc, char** argv)
 
     | 
  
  
    | 
      159
     | 
    
          : QCoreApplication (argc, argv)
 
     | 
  
  
    | 
      160
     | 
    
      {
     | 
  
  
    | 
      161
     | 
    
          printf("My App here... printing a \'.\' every %d sec\n",ms/10000);
     | 
  
  
    | 
      162
     | 
    
          startTimer(ms);
 
     | 
  
  
    | 
      163
     | 
    
      }
 
     | 
  
  
    | 
      164
     | 
    
      void CMyApp::timerEvent(QTimerEvent*)
 
     | 
  
  
    | 
      165
     | 
    
      {
     | 
  
  
    | 
      166
     | 
    
          printf(".");
     | 
  
  
    | 
      167
     | 
    
          fflush(stdout);
 
     | 
  
  
    | 
      168
     | 
    
      }
 
     | 
  
  
    | 
      169
     | 
    
      
 
     | 
  
  
    | 
      170
     | 
    
      int main(int argc, char** argv)
 
     | 
  
  
    | 
      171
     | 
    
      {
     | 
  
  
    | 
      172
     | 
    
          CMyApp a(10000, argc, argv);
 
     | 
  
  
    | 
      173
     | 
    
      
 
     | 
  
  
    | 
      174
     | 
    
          qDebug() << "Building watchdog...";
 
     | 
  
  
    | 
      175
     | 
    
          tcQWatchDog woof;
 
     | 
  
  
    | 
      176
     | 
    
          qDebug() << "Entering main loop... reboot comin!";
 
     | 
  
  
    | 
      177
     | 
    
          return a.exec();
 
     | 
  
  
    | 
      178
     | 
    
      
 
     | 
  
  
    | 
      179
     | 
    
      }
 
     | 
  
  
    | 
      180
     | 
    
      #endif // WATCHDOG_UT
 
     |