001package jmri.jmrix.lenz;
002
003/**
004 * XNet specific class to send heartbeat messages to
005 * the XNet.  Heartbeat messages are only required if
006 * no other messages are sent for a specific period
007 * of time, so any outgoing message should restart
008 * the timer.
009 *
010 * @author Paul Bender Copyright (C) 2019 
011 */
012public class XNetHeartBeat implements XNetListener {
013
014    private javax.swing.Timer keepAliveTimer; // Timer used to periodically
015    // send a message to both
016    // ports to keep the ports
017    // open
018    private static final int keepAliveTimeoutValue = 30000; // Interval
019    // to send a message
020    // Must be < 60s.
021    private final XNetTrafficController tc;
022    private final XNetSystemConnectionMemo memo;
023
024    public XNetHeartBeat(XNetSystemConnectionMemo memo) {
025        this.memo = memo;
026        tc = memo.getXNetTrafficController();
027        tc.addXNetListener(~0,this);
028        keepAliveTimer();
029    }
030
031    /*
032     * Set up the keepAliveTimer, and start it.
033     */
034    private void keepAliveTimer() {
035        if (keepAliveTimer == null) {
036            keepAliveTimer = new javax.swing.Timer(keepAliveTimeoutValue, e -> {
037                // If the timer times out, and we are not currently
038                // programming, send a request for status
039                XNetProgrammer p = null;
040                if(memo.provides(jmri.GlobalProgrammerManager.class)){
041                    p = (XNetProgrammer) (memo.getProgrammerManager().getGlobalProgrammer());
042                }
043                if (p == null || !(p.programmerBusy())) {
044                   tc.sendXNetMessage(
045                    XNetMessage.getCSStatusRequestMessage(),
046                    null);
047                }
048            });
049        }
050        keepAliveTimer.stop();
051        keepAliveTimer.setInitialDelay(keepAliveTimeoutValue);
052        keepAliveTimer.setRepeats(true);
053        keepAliveTimer.start();
054    }
055
056    public void dispose(){
057       keepAliveTimer.stop();
058       keepAliveTimer = null;
059    }
060
061    // XNetListener methods.
062
063    /**
064     * {@inheritDoc}
065     */
066    @Override
067    public void message(XNetReply msg){
068        // this class doesn't care about incoming messages.
069    }
070
071    /**
072     * {@inheritDoc}
073     */
074    @Override
075    public void message(XNetMessage msg){
076       // if we see any outgoing message, restart the timer
077       keepAliveTimer.restart();
078    }
079
080    /**
081     * {@inheritDoc}
082     */
083    @Override
084    public void notifyTimeout(XNetMessage msg){
085        // this class doesn't care about timeouts.
086    }
087
088}