001package jmri.jmrix.mrc; 002 003import java.util.Date; 004import java.util.Vector; 005import org.slf4j.Logger; 006import org.slf4j.LoggerFactory; 007 008/** 009 * Converts Stream-based I/O to/from MRC messages. The "MrcInterface" side 010 * sends/receives message objects. 011 * <p> 012 * The connection to a MrcPortController is via a pair of *Streams, which then 013 * carry sequences of characters for transmission. Note that this processing is 014 * handled in an independent thread. 015 * <p> 016 * This handles the state transitions, based on the necessary state in each 017 * message. 018 * 019 * @author Bob Jacobsen Copyright (C) 2001 020 */ 021public abstract class MrcTrafficController implements MrcInterface { 022 023 /** 024 * Create a new MrcTrafficController instance. Simple implementation. 025 */ 026 public MrcTrafficController() { 027 super(); 028 } 029 030 public void setCabNumber(int x) { 031 cabAddress = x; 032 } 033 034 int cabAddress = 0; 035 036 public int getCabNumber() { 037 return cabAddress; 038 } 039 040 // Abstract methods for the MrcInterface 041 @Override 042 abstract public boolean status(); 043 044 @Override 045 abstract public void sendMrcMessage(MrcMessage m); 046 047 // The methods to implement adding and removing listeners 048 protected Vector<MrcTrafficListenerFilter> trafficListeners = new Vector<MrcTrafficListenerFilter>(); 049 050 @Override 051 public synchronized void addTrafficListener(int mask, MrcTrafficListener l) { 052 if (l == null) { 053 throw new java.lang.NullPointerException(); 054 } 055 056 // add only if not already registered 057 MrcTrafficListenerFilter adapter = new MrcTrafficListenerFilter(mask, l); 058 if (!trafficListeners.contains(adapter)) { 059 trafficListeners.addElement(adapter); 060 } 061 } 062 063 @Override 064 public synchronized void removeTrafficListener(int mask, MrcTrafficListener l) { 065 if (l == null) { 066 throw new java.lang.NullPointerException(); 067 } 068 069 MrcTrafficListenerFilter filter = new MrcTrafficListenerFilter(mask, l); 070 if (trafficListeners.contains(filter)) { 071 trafficListeners.remove(trafficListeners.indexOf(filter)).setFilter(mask); 072 } 073 } 074 075 @Override 076 public synchronized void changeTrafficListener(int mask, MrcTrafficListener l) { 077 if (l == null) { 078 throw new java.lang.NullPointerException(); 079 } 080 081 MrcTrafficListenerFilter filter = new MrcTrafficListenerFilter(mask, l); 082 if (trafficListeners.contains(filter)) { 083 trafficListeners.get(trafficListeners.indexOf(filter)).setFilter(mask); 084 } 085 } 086 087 @SuppressWarnings("unchecked") 088 public void notifyRcv(Date timestamp, MrcMessage m) { 089 090 // make a copy of the listener vector to synchronized not needed for transmit 091 Vector<MrcTrafficListenerFilter> v; 092 synchronized (this) { 093 v = (Vector<MrcTrafficListenerFilter>) trafficListeners.clone(); 094 } 095 if (log.isDebugEnabled()) { 096 log.debug("notify of incoming Mrc packet: {}", m.toString());// NOI18N 097 } 098 // forward to all listeners 099 for (MrcTrafficListenerFilter adapter : v) { 100 adapter.fireRcv(timestamp, m); 101 } 102 } 103 104 @SuppressWarnings("unchecked") 105 public void notifyXmit(Date timestamp, MrcMessage m) { 106 107 // make a copy of the listener vector to synchronized not needed for transmit 108 Vector<MrcTrafficListenerFilter> v; 109 synchronized (this) { 110 v = (Vector<MrcTrafficListenerFilter>) trafficListeners.clone(); 111 } 112 if (log.isDebugEnabled()) { 113 log.debug("notify of send Mrc packet: {}", m.toString());// NOI18N 114 } 115 // forward to all listeners 116 for (MrcTrafficListenerFilter adapter : v) { 117 adapter.fireXmit(timestamp, m); 118 } 119 } 120 121 /** 122 * Is there a backlog of information for the outbound link? This includes 123 * both in the program (e.g. the outbound queue) and in the command station 124 * interface (e.g. flow control from the port). 125 * 126 * @return true if busy, false if nothing waiting to send 127 */ 128 abstract public boolean isXmtBusy(); 129 130 /** 131 * Reset statistics (received message count, transmitted message count, 132 * received byte count). 133 */ 134 public void resetStatistics() { 135 receivedMsgCount = 0; 136 transmittedMsgCount = 0; 137 receivedByteCount = 0; 138 } 139 140 /** 141 * Monitor the number of MRC messaages received across the interface. This 142 * includes the messages this client has sent. 143 * 144 * @return count of messages received 145 */ 146 public int getReceivedMsgCount() { 147 return receivedMsgCount; 148 } 149 protected int receivedMsgCount = 0; 150 151 /** 152 * Monitor the number of bytes in MRC messaages received across the 153 * interface. This includes the messages this client has sent. 154 * 155 * @return count of bytes in received messages 156 */ 157 public int getReceivedByteCount() { 158 return receivedByteCount; 159 } 160 protected int receivedByteCount = 0; 161 162 /** 163 * Monitor the number of MRC messages transmitted across the interface. 164 * 165 * @return count of messages sent 166 */ 167 public int getTransmittedMsgCount() { 168 return transmittedMsgCount; 169 } 170 protected int transmittedMsgCount = 0; 171 172 public MrcSystemConnectionMemo getAdapterMemo() { 173 return adaptermemo; 174 } 175 176 public void setAdapterMemo(MrcSystemConnectionMemo memo) { 177 adaptermemo = memo; 178 } 179 180 MrcSystemConnectionMemo adaptermemo; 181 182 public String getUserName() { 183 if (adaptermemo == null) { 184 return "MRC"; // NOI18N 185 } 186 return adaptermemo.getUserName(); 187 } 188 189 public String getSystemPrefix() { 190 if (adaptermemo == null) { 191 return "M"; // NOI18N 192 } 193 return adaptermemo.getSystemPrefix(); 194 } 195 196 private final static Logger log = LoggerFactory.getLogger(MrcTrafficController.class); 197 198}