001package com.pi4j.io.wdt.impl;
002
003/*
004 * #%L
005 * **********************************************************************
006 * ORGANIZATION  :  Pi4J
007 * PROJECT       :  Pi4J :: Java Library (Core)
008 * FILENAME      :  WDTimerImpl.java
009 *
010 * This file is part of the Pi4J project. More information about
011 * this project can be found here:  https://www.pi4j.com/
012 * **********************************************************************
013 * %%
014 * Copyright (C) 2012 - 2019 Pi4J
015 * %%
016 * This program is free software: you can redistribute it and/or modify
017 * it under the terms of the GNU Lesser General Public License as
018 * published by the Free Software Foundation, either version 3 of the
019 * License, or (at your option) any later version.
020 *
021 * This program is distributed in the hope that it will be useful,
022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
024 * GNU General Lesser Public License for more details.
025 *
026 * You should have received a copy of the GNU General Lesser Public
027 * License along with this program.  If not, see
028 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
029 * #L%
030 */
031
032import com.pi4j.io.wdt.WDTimer;
033import com.pi4j.jni.WDT;
034import java.io.IOException;
035
036/**
037 *
038 * @author zerog
039 */
040public final class WDTimerImpl implements WDTimer {
041
042    private static final WDTimerImpl instance = new WDTimerImpl();
043
044    /** File handle for watchdog */
045    private int fd = -1;
046
047    /** File name of watchdog */
048    private String filename;
049
050    /**
051     * Singleton.
052     *
053     * @return instance
054     */
055    public static WDTimer getInstance() {
056        return instance;
057    }
058
059    /**
060     * Open Watchdog.
061     *
062     * @throws IOException
063     */
064    @Override
065    public void open() throws IOException {
066        open("/dev/watchdog");
067    }
068
069
070    /**
071     * Open custom Watchdog
072     *
073     * @param file
074     * @throws IOException
075     */
076    public void open(String file) throws IOException {
077            filename = file;
078            if(fd>0) {
079                throw new IOException("File "+filename+" already open.");
080            }
081            fd = WDT.open(file);
082            if(fd<0) {
083                throw new IOException("Cannot open file handle for " + filename + " got " + fd + " back.");
084            }
085    }
086
087    /**
088     * Set new timeout
089     *
090     * @param timeout
091     * @throws IOException
092     */
093    @Override
094    public void setTimeOut(int timeout) throws IOException {
095        isOpen();
096        int ret = WDT.setTimeOut(fd, timeout);
097        if(ret<0) {
098            throw new IOException("Cannot set timeout for " + filename + " got " + ret + " back.");
099        }
100    }
101
102    /**
103     * Get timeout
104     *
105     * @return
106     * @throws IOException
107     */
108    @Override
109    public int getTimeOut() throws IOException {
110        isOpen();
111        int ret = WDT.getTimeOut(fd);
112        if(ret<0) {
113            throw new IOException("Cannot read timeout for " + filename + " got " + ret + " back.");
114        }
115        return ret;
116    }
117
118    /**
119     * Ping a watchdog.
120     *
121     * @throws IOException
122     */
123    @Override
124    public void heartbeat() throws IOException {
125        isOpen();
126        int ret = WDT.ping(fd);
127        if(ret<0) {
128            throw new IOException("Heartbeat error. File " + filename + " got " + ret + " back.");
129        }
130    }
131
132    /**
133     * Disable watchdog with "Magic Close". Now watchdog not working.
134     * Close watchdog without call disable causes RaspberryPi reboot!
135     * @throws IOException
136     */
137    @Override
138    public void disable() throws IOException {
139        isOpen();
140        int ret = WDT.disable(fd);
141        if(ret<0) {
142            throw new IOException("Cannot disable WatchDog.  File " + filename + " got " + ret + " back.");
143        }
144    }
145
146    /**
147     * Close a watchdog (file). If close without {@link disable} Raspberry reboot after
148     * timeout expired.
149     *
150     * @throws IOException
151     */
152    @Override
153    public void close() throws IOException {
154        isOpen();
155        int ret = WDT.close(fd);
156        if(ret<0) {
157            throw new IOException("Close file " + filename + " got " + ret + " back.");
158        }
159        fd=-1;
160    }
161
162    /**
163     * Test if WDT is open
164     * @throws IOException if not
165     */
166    private void isOpen() throws IOException {
167        if(fd<0) {
168            throw new IOException("Watchdog is not open yet");
169        }
170    }
171}