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 resetBusSpeeds(); 020 for (int x = MINRC; x < MAXRC; x++){ 021 addBoard(x); 022 } 023 } 024 025 /** 026 * Start from 8 kbps on both sides: a board that lost power has gone back 027 * to 8 kbps, but the interface may still be at the speed a previous 028 * session set, or the other way round. 029 */ 030 private void resetBusSpeeds() { 031 tc.sendDcc4PcMessage(Dcc4PcMessage.busResetSpeeds(), null); 032 for (int x = MINRC; x < MAXRC; x++){ 033 tc.sendDcc4PcMessage(Dcc4PcMessage.busSetSpeed(x, 0), null); 034 } 035 } 036 037 /** 038 * The interface's port has been reopened after a failure. Reset the bus 039 * speeds as at startup, and look again for boards not found yet. 040 */ 041 void rediscover() { 042 resetBusSpeeds(); 043 boardsToDiscover.clear(); 044 for (int x = MINRC; x < MAXRC; x++){ 045 addBoard(x); 046 } 047 } 048 049 private static final int MINRC = 0; 050 private static final int MAXRC = 4; 051 052 ArrayList<Integer> boardsToDiscover = new ArrayList<>(); 053 054 Dcc4PcTrafficController tc; 055 Dcc4PcSensorManager senManager; 056 057 public void notifyReply(Dcc4PcReply m) { 058 // is this a list of sensors? 059 } 060 061 public void notifyMessage(Dcc4PcMessage m) { 062 // messages are ignored 063 } 064 065 protected void addBoard(int newBoard){ 066 if(!senManager.isBoardCreated(newBoard) && !boardsToDiscover.contains(newBoard)){ 067 boardsToDiscover.add(newBoard); 068 Dcc4PcMessage m = Dcc4PcMessage.getInfo(newBoard); 069 m.setTimeout(1000); 070 m.setRetries(2); 071 tc.sendDcc4PcMessage(m, this); 072 } 073 } 074 075 @Override 076 @SuppressFBWarnings(value="DLS_DEAD_LOCAL_STORE", justification="See issue #6132") 077 public void reply(Dcc4PcReply r) { 078 if (log.isDebugEnabled()) { 079 log.debug("Reply details sm: {}", r.toHexString()); 080 } 081 if(r.getBoard() == -1){ 082 return; 083 } 084 if(r.getNumDataElements()==0 && r.getElement(0) == 0x00) { 085 //Simple acknowledgement reply, no further action required 086 return; 087 } 088 int board = r.getBoard(); 089 if (r.isError()) { 090 boardsToDiscover.remove((Integer)board); 091 } else { 092 if (r.getMessageType()==Dcc4PcMessage.INFO) { 093 log.debug("Get Info for board {}: {}", board, r.toString()); 094 String version; 095 int inputs; 096 int encoding; 097 098 int i = 0; 099 StringBuilder buf = new StringBuilder(); 100 while (i < 4) { 101 buf.append((char) r.getElement(i)); 102 i++; 103 } 104 //skip supported speeds for now 105 String str = buf.toString(); // DLS_DEAD_LOCAL_STORE here: str is unused 106 //We have a reader, now to find out other information about it 107 if (str.equals("RCRD")) { 108 i = i + 2; 109 str = str + " ver "; 110 str = str + r.getElement(i) + "."; 111 version = r.getElement(i) + "." + r.getElement(i + 1); 112 i++; 113 str = str + r.getElement(i) + ", Inputs : "; 114 i++; 115 inputs = r.getElement(i); 116 str = str + r.getElement(i) + ", Encoding : "; 117 i++; 118 encoding = r.getElement(i); 119 if ((r.getElement(i) & 0x01) == 0x01) { 120 str = str + "Supports Cooked RailCom Encoding"; 121 } else { 122 str = str + "Supports Raw RailCom Encoding"; 123 } 124 125 senManager.addActiveBoard(board, version, inputs, encoding); 126 127 Dcc4PcMessage m = Dcc4PcMessage.getDescription(board); 128 m.setTimeout(2000); 129 tc.sendDcc4PcMessage(m, this); 130 boardsToDiscover.remove((Integer)board); 131 } 132 } else if (r.getMessageType()==Dcc4PcMessage.DESC) { 133 log.debug("Get Description for board {}: {}", board, r.toString()); 134 135 senManager.setBoardDescription(board, r.toString()); 136 Dcc4PcMessage m = Dcc4PcMessage.getEnabledInputs(board); 137 m.setTimeout(2000); 138 m.setRetries(2); 139 log.debug("Sending {}", m); 140 tc.sendDcc4PcMessage(m, this); 141 } else if (r.getMessageType()==Dcc4PcMessage.CHILDENABLEDINPUTS) { 142 log.debug("Make Sensors for board {}: {}", board, r.toString()); 143 senManager.createSensorsForBoard(r); 144 } 145 } 146 } 147 148 @Override 149 public void handleTimeout(Dcc4PcMessage m) { 150 if (log.isDebugEnabled()) { 151 log.debug("timeout received to our last message {}", m.toString()); 152 } 153 log.debug("Timeout to message {} for board {}", m.toString(), m.getBoard()); 154 } 155 156 @Override 157 public void message(Dcc4PcMessage m) { 158 159 } 160 161 private static final Logger log = LoggerFactory.getLogger(Dcc4PcBoardManager.class); 162}