001package jmri.jmrix.lenz; 002 003import org.slf4j.Logger; 004import org.slf4j.LoggerFactory; 005 006/** 007 * Converts Stream-based I/O to/from XNet messages. The "XNetInterface" side 008 * sends/receives XNetMessage objects. The connection to an XNetPortController is 009 * via a pair of Streams, which then carry sequences of characters for 010 * transmission. 011 * <p> 012 * Messages come to this via the main GUI thread, and are forwarded back to 013 * listeners in that same thread. Reception and transmission are handled in 014 * dedicated threads by RcvHandler and XmtHandler objects. Those are internal 015 * classes defined here. The thread priorities are: 016 * <ul> 017 * <li> RcvHandler - at highest available priority 018 * <li> XmtHandler - down one, which is assumed to be above the GUI 019 * <li> (everything else) 020 * </ul> 021 * 022 * @author Bob Jacobsen Copyright (C) 2001 023 */ 024public class XNetPacketizer extends XNetTrafficController { 025 026 public XNetPacketizer(LenzCommandStation pCommandStation) { 027 super(pCommandStation); 028 // The instance method (from XNetTrafficController) is deprecated 029 } 030 031// The methods to implement the XNetInterface 032 033 /** 034 * Forward a preformatted XNetMessage to the actual interface. 035 * <p> 036 * Checksum is computed and overwritten here, then the message is converted 037 * to a byte array and queue for transmission 038 * 039 * @param m Message to send; will be updated with CRC 040 */ 041 @Override 042 public void sendXNetMessage(XNetMessage m, XNetListener reply) { 043 if (m.length() != 0) { 044 sendMessage(m, reply); 045 java.lang.Thread.yield(); 046 } 047 } 048 049 /** 050 * Add trailer to the outgoing byte stream. This version adds the checksum 051 * to the last byte. 052 * 053 * @param msg The output byte stream 054 * @param offset the first byte not yet used 055 */ 056 @Override 057 protected void addTrailerToOutput(byte[] msg, int offset, jmri.jmrix.AbstractMRMessage m) { 058 if (m.getNumDataElements() == 0) { 059 return; 060 } 061 ((XNetMessage) m).setParity(); 062 msg[offset - 1] = (byte) m.getElement(m.getNumDataElements() - 1); 063 } 064 065 /** 066 * {@inheritDoc} 067 */ 068 @Override 069 public boolean portReadyToSend(jmri.jmrix.AbstractPortController p) { 070 if( !(p instanceof XNetPortController)) { 071 return false; 072 } 073 if (((XNetPortController) p).okToSend()) { 074 ((XNetPortController) p).setOutputBufferEmpty(false); 075 return true; 076 } else { 077 log.debug("XpressNet port not ready to receive"); 078 return false; 079 } 080 } 081 082 private static final Logger log = LoggerFactory.getLogger(XNetPacketizer.class); 083 084}