001package jmri.jmrix.dcc4pc;
002
003import java.util.ArrayList;
004
005import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
006import org.slf4j.Logger;
007import org.slf4j.LoggerFactory;
008
009/**
010 * Implement BoardManager for Dcc4Pc systems.
011 *
012 * @author Kevin Dickerson Copyright (C) 2009
013 */
014public class Dcc4PcBoardManager implements Dcc4PcListener {
015
016    public Dcc4PcBoardManager(Dcc4PcTrafficController tc, Dcc4PcSensorManager senManager) {
017        this.tc = tc;
018        this.senManager = senManager;
019        for (int x = MINRC; x < MAXRC; x++){
020            addBoard(x);
021        }
022    }
023    
024    private final static int MINRC = 0;
025    private final static int MAXRC = 4;
026    
027    ArrayList<Integer> boardsToDiscover = new ArrayList<>();
028
029    Dcc4PcTrafficController tc;
030    Dcc4PcSensorManager senManager;
031
032    public void notifyReply(Dcc4PcReply m) {
033        // is this a list of sensors?
034    }
035
036    public void notifyMessage(Dcc4PcMessage m) {
037        // messages are ignored
038    }
039   
040    protected void addBoard(int newBoard){
041        if(!senManager.isBoardCreated(newBoard) && !boardsToDiscover.contains(newBoard)){
042            boardsToDiscover.add(newBoard);
043            Dcc4PcMessage m = Dcc4PcMessage.getInfo(newBoard);
044            m.setTimeout(1000);
045            m.setRetries(2);
046            tc.sendDcc4PcMessage(m, this);  
047        }
048    }
049    
050    @Override
051    @SuppressFBWarnings(value="DLS_DEAD_LOCAL_STORE", justification="See issue #6132")
052    public void reply(Dcc4PcReply r) {
053        if (log.isDebugEnabled()) {
054            log.debug("Reply details sm: {}", r.toHexString());
055        }
056        if(r.getBoard() == -1){
057            return;
058        }
059        if(r.getNumDataElements()==0 && r.getElement(0) == 0x00) {
060            //Simple acknowledgement reply, no further action required
061            return;
062        }
063        int board = r.getBoard();
064        if (r.isError()) {
065            boardsToDiscover.remove((Integer)board);
066        } else {
067            if (r.getMessageType()==Dcc4PcMessage.INFO) {
068                log.debug("Get Info for board {}: {}", board, r.toString());
069                String version;
070                int inputs;
071                int encoding;
072
073                int i = 0;
074                StringBuilder buf = new StringBuilder();
075                while (i < 4) {
076                    buf.append((char) r.getElement(i));
077                    i++;
078                }
079                //skip supported speeds for now
080                String str = buf.toString(); // DLS_DEAD_LOCAL_STORE here: str is unused
081                //We have a reader, now to find out other information about it
082                if (str.equals("RCRD")) {
083                    i = i + 2;
084                    str = str + " ver ";
085                    str = str + r.getElement(i) + ".";
086                    version = r.getElement(i) + "." + r.getElement(i + 1);
087                    i++;
088                    str = str + r.getElement(i) + ", Inputs : ";
089                    i++;
090                    inputs = r.getElement(i);
091                    str = str + r.getElement(i) + ", Encoding : ";
092                    i++;
093                    encoding = r.getElement(i);
094                    if ((r.getElement(i) & 0x01) == 0x01) {
095                        str = str + "Supports Cooked RailCom Encoding";
096                    } else {
097                        str = str + "Supports Raw RailCom Encoding";
098                    }
099
100                    senManager.addActiveBoard(board, version, inputs, encoding);
101
102                    Dcc4PcMessage m = Dcc4PcMessage.getDescription(board);
103                    m.setTimeout(2000);
104                    tc.sendDcc4PcMessage(m, this);
105                    boardsToDiscover.remove((Integer)board);
106                }
107            } else if (r.getMessageType()==Dcc4PcMessage.DESC) {
108                log.debug("Get Description for board {}: {}", board, r.toString());
109
110                senManager.setBoardDescription(board, r.toString());
111                Dcc4PcMessage m = Dcc4PcMessage.getEnabledInputs(board);
112                m.setTimeout(2000);
113                m.setRetries(2);
114                log.debug("Sending {}", m);
115                tc.sendDcc4PcMessage(m, this);
116            } else if (r.getMessageType()==Dcc4PcMessage.CHILDENABLEDINPUTS) {
117                log.debug("Make Sensors for board {}: {}", board, r.toString());
118                senManager.createSensorsForBoard(r);
119            }
120        }
121    }
122
123    @Override
124    public void handleTimeout(Dcc4PcMessage m) {
125        if (log.isDebugEnabled()) {
126            log.debug("timeout received to our last message {}", m.toString());
127        }
128        log.debug("Timeout to message {} for board {}", m.toString(), m.getBoard());
129    }
130
131    @Override
132    public void message(Dcc4PcMessage m) {
133
134    }
135    
136    private final static Logger log = LoggerFactory.getLogger(Dcc4PcBoardManager.class);
137}