001package jmri.jmrix.zimo; 002 003import java.util.Vector; 004import org.slf4j.Logger; 005import org.slf4j.LoggerFactory; 006 007/** 008 * Abstract base class for implementations of MX-1 Interface. 009 * <p> 010 * This provides just the basic interface, plus the "" static method for 011 * locating the local implementation. 012 * <p> 013 * Adapted by Sip Bosch for use with zimo Mx-1. 014 * 015 * @author Bob Jacobsen Copyright (C) 2002 016 */ 017public abstract class Mx1TrafficController implements Mx1Interface { 018 019 /** 020 * Create a new TrafficController instance. Simple implementation. 021 */ 022 public Mx1TrafficController() { 023 super(); 024 } 025 026 /** 027 * Must provide a ZimoCommandStation reference at creation time 028 * 029 * @param pCommandStation reference to associated command station object, 030 * preserved for later. 031 * @param prot false if {@link #ASCII}, true if {@link #BINARY} 032 */ 033 Mx1TrafficController(Mx1CommandStation pCommandStation, boolean prot) { 034 mCommandStation = pCommandStation; 035 protocol = prot; 036 } 037 038 public final static boolean ASCII = false; 039 public final static boolean BINARY = true; 040 041 boolean protocol = ASCII; 042 043 public boolean getProtocol() { 044 return protocol; 045 } 046 047 // Abstract methods for the Mx1Interface 048 @Override 049 abstract public boolean status(); 050 051 /** 052 * Forward a pre-formatted Mx1Message to the actual interface. 053 * 054 * @param m Message to send; will be updated with CRC 055 * @param reply the listener to notify of a response 056 */ 057 @Override 058 abstract public void sendMx1Message(Mx1Message m, Mx1Listener reply); 059 060 // The methods to implement adding and removing listeners 061 protected Vector<Mx1Listener> listeners = new Vector<>(); 062 063 @Override 064 public synchronized void addMx1Listener(int mask, Mx1Listener l) { 065 // add only if not already registered 066 if (l == null) { 067 throw new java.lang.NullPointerException(); 068 } 069 if (!listeners.contains(l)) { 070 listeners.addElement(l); 071 } 072 } 073 074 @Override 075 public synchronized void removeMx1Listener(int mask, Mx1Listener l) { 076 if (listeners.contains(l)) { 077 listeners.removeElement(l); 078 } 079 } 080 081 /** 082 * Forward a message to all registered listeners. 083 * 084 * @param m Message to forward. Listeners should not modify it! 085 * @param replyTo Listener for the reply to this message, doesn't get the 086 * echo of it. 087 */ 088 @SuppressWarnings("unchecked") 089 protected void notify(Mx1Message m, Mx1Listener replyTo) { 090 // make a copy of the listener vector to synchronized not needed for transmit 091 Vector<Mx1Listener> v; 092 synchronized (this) { 093 v = (Vector<Mx1Listener>) listeners.clone(); 094 } 095 if (log.isDebugEnabled()) { 096 log.debug("notify of incoming packet: {}", m.toString()); 097 } 098 // forward to all listeners 099 int cnt = v.size(); 100 for (int i = 0; i < cnt; i++) { 101 Mx1Listener client = listeners.elementAt(i); 102 if (client != replyTo) { 103 client.message(m); 104 } 105 } 106 } 107 108 /** 109 * Reference to the command station in communication here 110 */ 111 Mx1CommandStation mCommandStation; 112 113 /** 114 * Get access to communicating command station object 115 * 116 * @return associated Command Station object 117 */ 118 public Mx1CommandStation getCommandStation() { 119 return mCommandStation; 120 } 121 122 public Mx1SystemConnectionMemo getAdapterMemo() { 123 return adaptermemo; 124 } 125 126 public void setAdapterMemo(Mx1SystemConnectionMemo memo) { 127 adaptermemo = memo; 128 } 129 130 Mx1SystemConnectionMemo adaptermemo; 131 132 public String getUserName() { 133 if (adaptermemo == null) { 134 return "Zimo"; // NOI18N 135 } 136 return adaptermemo.getUserName(); 137 } 138 139 public String getSystemPrefix() { 140 if (adaptermemo == null) { 141 return "Z"; // NOI18N 142 } 143 return adaptermemo.getSystemPrefix(); 144 } 145 146 private final static Logger log = LoggerFactory.getLogger(Mx1TrafficController.class); 147 148}