/*******************************************************************************
*                                                                              *
* Société de Transports de Montréal.                                    	   *
* 2015                                                                       *
*                                                                              *
* Projet Zones Tests                                                           *
*                                                                              *
*                                                                              *
*                                                                              *
*******************************************************************************/
/*
    Description:
    Cette clase contrôle le watchdog interne de Linux.  Elle permet l'ouverture
    ou l'arrêt du watchdog ainsi que son rafraîchissement.

*/

/* ************************************************************************** */
/* Revision:
### 2015????JFM
    Verision d'origine.

### YYYYMMDD Description du besoin ou du bug
    Description du changement.
 */

/* ************************************************************************** */

#include "WatchdogCtrl.h"
#include <sys/io.h>
#include <sys/ioctl.h>
#include <asm/ioctls.h>
#include <QString>
#include <linux/watchdog.h>

CWatchdogCtrl::CWatchdogCtrl(bool UseWatchdog)
{
    fd = -1;
    mUseWatchdog = UseWatchdog;
}

CWatchdogCtrl::~CWatchdogCtrl()
{
    if(fd > -1)
    {
        StopWatchdog();
    }
}

int CWatchdogCtrl::StartWatchdog()
{
    if(mUseWatchdog == false)
    {
        CEngLog::instance()->AddLogString(QString().sprintf("Watchdog CPU désactivé dans la ligne de commande"),1);
        return RET_ERROR;
    }

    if(fd > -1)
        return RET_OK;

    QString PortPath = "/dev/watchdog";
    fd = open(PortPath.toLatin1().data(), O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
    if (fd < 0)
    {
            CEngLog::instance()->AddLogString(QString().sprintf("Erreur d'ouverture du watchdog"));
            return RET_ERROR;
    }
    int interval = -1;
    int BootMode = -1;
    ioctl(fd, WDIOC_GETTIMEOUT, &interval);
    ioctl(fd, WDIOC_GETBOOTSTATUS, &BootMode);


    CEngLog::instance()->AddLogString(QString().sprintf("Ouverture du watchdog réussie: Timeout = %d, BootMode = %d",interval,BootMode));

    return RET_OK;
}

int CWatchdogCtrl::KickWatchdog()
{
    if(mUseWatchdog == false)
    {
        return RET_ERROR;
    }

    if(fd < 0)
        return RET_ERROR;

    if(ioctl(fd, WDIOC_KEEPALIVE, NULL) != 0)
    {
       // CEngLog::instance()->AddLogString(QString().sprintf("Impossible de kicker le watchdog!!!"));
        return RET_ERROR;
    }
    return RET_OK;
}

int CWatchdogCtrl::StopWatchdog()
{
    if(mUseWatchdog == false)
    {
        return RET_ERROR;
    }

    if(fd < 0)
        return RET_ERROR;

    write(fd,"V",1);    //Write character 'V' to notify the watchdog that we want to close it...
    close(fd);
    fd = -1;

    return RET_OK;
}
