001package jmri.jmrix.easydcc; 002 003import jmri.jmrix.AbstractMRListener; 004import jmri.jmrix.AbstractMRMessage; 005import jmri.jmrix.AbstractMRReply; 006import jmri.jmrix.AbstractMRTrafficController; 007import org.slf4j.Logger; 008import org.slf4j.LoggerFactory; 009 010/** 011 * Converts Stream-based I/O to/from EasyDcc messages. The "EasyDccInterface" 012 * side sends/receives message objects. 013 * <p> 014 * The connection to a EasyDccPortController is via a pair of *Streams, which 015 * then carry sequences of characters for transmission. Note that this 016 * processing is handled in an independent thread. 017 * <p> 018 * This handles the state transitions, based on the necessary state in each 019 * message. 020 * <p> 021 * Migrated for multiple connections, multi char connection prefix and Simulator. 022 * 023 * @author Bob Jacobsen Copyright (C) 2001 024 */ 025public class EasyDccTrafficController extends AbstractMRTrafficController 026 implements EasyDccInterface { 027 028 /** 029 * Create a new EasyDccTrafficController instance. 030 * 031 * @param adaptermemo the associated SystemConnectionMemo 032 */ 033 public EasyDccTrafficController(EasyDccSystemConnectionMemo adaptermemo) { 034 super(); 035 mMemo = adaptermemo; 036 log.debug("creating a new EasyDccTrafficController object"); 037 } 038 039 // Methods to implement the EasyDccInterface 040 041 @Override 042 public synchronized void addEasyDccListener(EasyDccListener l) { 043 this.addListener(l); 044 } 045 046 @Override 047 public synchronized void removeEasyDccListener(EasyDccListener l) { 048 this.removeListener(l); 049 } 050 051 /** 052 * Forward an EasyDccMessage to all registered EasyDccInterface listeners. 053 */ 054 @Override 055 protected void forwardMessage(AbstractMRListener client, AbstractMRMessage m) { 056 ((EasyDccListener) client).message((EasyDccMessage) m); 057 } 058 059 /** 060 * Forward an EasyDccReply to all registered EasyDccInterface listeners. 061 */ 062 @Override 063 protected void forwardReply(AbstractMRListener client, AbstractMRReply m) { 064 ((EasyDccListener) client).reply((EasyDccReply) m); 065 } 066 067 public void setSensorManager(jmri.SensorManager m) { 068 } 069 070 @Override 071 protected AbstractMRMessage pollMessage() { 072 return null; 073 } 074 075 @Override 076 protected AbstractMRListener pollReplyHandler() { 077 return null; 078 } 079 080 /** 081 * Forward a preformatted message to the actual interface. 082 */ 083 @Override 084 public void sendEasyDccMessage(EasyDccMessage m, EasyDccListener reply) { 085 if (m == null) { 086 log.debug("empty message"); 087 return; 088 } 089 log.debug("EasyDccTrafficController sendMessage() {}", m.toString()); 090 sendMessage(m, reply); 091 } 092 093 @Override 094 protected AbstractMRMessage enterProgMode() { 095 return EasyDccMessage.getProgMode(); 096 } 097 098 @Override 099 protected AbstractMRMessage enterNormalMode() { 100 return EasyDccMessage.getExitProgMode(); 101 } 102 103 /** 104 * Reference to the system connection memo. 105 */ 106 EasyDccSystemConnectionMemo mMemo = null; 107 108 /** 109 * Get access to the system connection memo associated with this traffic 110 * controller. 111 * 112 * @return associated systemConnectionMemo object 113 */ 114 public EasyDccSystemConnectionMemo getSystemConnectionMemo() { 115 return mMemo; 116 } 117 118 /** 119 * Set the system connection memo associated with this traffic controller. 120 * 121 * @param m associated systemConnectionMemo object 122 */ 123 public void setSystemConnectionMemo(EasyDccSystemConnectionMemo m) { 124 mMemo = m; 125 } 126 127 @Override 128 protected AbstractMRReply newReply() { 129 return new EasyDccReply(); 130 } 131 132 @Override 133 protected boolean endOfMessage(AbstractMRReply msg) { 134 // note special case: CV read / register read messages don't actually 135 // end until a P is received! 136 if ((msg.getElement(0) == 'C' && msg.getElement(1) == 'V') || (msg.getElement(0) == 'V')) { 137 // require the P 138 if ((msg.getNumDataElements() > 4) && msg.getElement(msg.getNumDataElements() - 2) != 'P') { 139 return false; 140 } 141 } 142 // detect that the reply buffer ends with "\n" 143 int index = msg.getNumDataElements() - 1; 144 if (msg.getElement(index) != 0x0d) { 145 return false; 146 } else { 147 return true; 148 } 149 } 150 151 /** 152 * Don't send to-normal-mode message if in normal mode 153 */ 154 @Override 155 protected void terminate() { 156 if (mCurrentMode == NORMALMODE) { 157 log.debug("skipping sending normal mode during termination"); 158 return; 159 } else { 160 super.terminate(); 161 } 162 } 163 164 private final static Logger log = LoggerFactory.getLogger(EasyDccTrafficController.class); 165 166}