001package jmri.jmris;
002
003import java.io.IOException;
004import jmri.InstanceManager;
005import jmri.Programmer;
006import org.slf4j.Logger;
007import org.slf4j.LoggerFactory;
008
009/**
010 * Abstract interface between the a JMRI Programmer and a network connection
011 * <p>
012 * Connects to default global programmer at construction time.
013 *
014 * @author Paul Bender Copyright (C) 2012
015 */
016abstract public class AbstractProgrammerServer implements jmri.ProgListener {
017
018    private Programmer p = null;
019
020    protected Programmer getProgrammer() {
021        return p;
022    }
023
024    protected int lastCV = -1;
025
026    public AbstractProgrammerServer() {
027        if (InstanceManager.getNullableDefault(jmri.GlobalProgrammerManager.class) != null) {
028            p = InstanceManager.getDefault(jmri.GlobalProgrammerManager.class).getGlobalProgrammer();
029        } else {
030            log.warn("no Service Mode ProgrammerManager configured, network programming disabled");
031        }
032    }
033
034    /*
035     * Protocol Specific Abstract Functions
036     * @param CV CV number (in DCC terms)
037     * @param value vale to read/write to CV
038     * @param status Denotes the completion code from a programming operation
039     */
040    abstract public void sendStatus(int CV, int value, int status) throws IOException;
041
042    abstract public void sendNotAvailableStatus() throws IOException;
043
044    abstract public void parseRequest(String statusString) throws jmri.JmriException, java.io.IOException;
045
046    public void writeCV(jmri.ProgrammingMode mode, int CV, int value) {
047        if (p == null) {
048            try {
049                sendNotAvailableStatus();
050            } catch (java.io.IOException ioe) {
051                // Connection Terminated?
052            }
053            return;
054        }
055        lastCV = CV;
056        try {
057            p.setMode(mode); // need to check if mode is available
058            p.writeCV(String.valueOf(CV), value, this);
059        } catch (jmri.ProgrammerException ex) {
060            //Send failure Status.
061            try {
062                sendNotAvailableStatus();
063            } catch (java.io.IOException ioe) {
064                // Connection Terminated?
065            }
066        }
067    }
068
069    public void readCV(jmri.ProgrammingMode mode, int CV) {
070        if (p == null || !(p.getCanRead())) {
071            try {
072                sendNotAvailableStatus();
073            } catch (java.io.IOException ioe) {
074                // Connection Terminated?
075            }
076            return;
077        }
078        lastCV = CV;
079        try {
080            p.setMode(mode); // need to check if mode is available
081            p.readCV(String.valueOf(CV), this);
082        } catch (jmri.ProgrammerException ex) {
083            //Send failure Status.
084            try {
085                sendNotAvailableStatus();
086            } catch (java.io.IOException ioe) {
087                // Connection Terminated?
088            }
089        }
090    }
091
092    /**
093     * Receive a callback at the end of a programming operation.
094     *
095     * @param value  Value from a read operation, or value written on a write
096     * @param status Denotes the completion code. Note that this is a bitwise
097     *               combination of the various status coded defined in this
098     *               interface.
099     */
100    @Override
101    public void programmingOpReply(int value, int status) {
102        if (log.isDebugEnabled()) {
103            log.debug("programmingOpReply called with value {} and status {}", value, status);
104        }
105        try {
106            sendStatus(lastCV, value, status);
107        } catch (java.io.IOException ioe) {
108            // Connection Terminated?
109            if (log.isDebugEnabled()) {
110                log.debug("Exception while sending reply");
111            }
112        }
113    }
114
115    public void dispose() {
116    }
117
118    private final static Logger log = LoggerFactory.getLogger(AbstractProgrammerServer.class);
119
120}