001package jmri.jmrix.can.adapters.loopback;
002
003import jmri.jmrix.AbstractMRListener;
004import jmri.jmrix.AbstractMRMessage;
005import jmri.jmrix.AbstractMRReply;
006import jmri.jmrix.can.CanListener;
007import jmri.jmrix.can.CanMessage;
008import jmri.jmrix.can.CanReply;
009import org.slf4j.Logger;
010import org.slf4j.LoggerFactory;
011
012/**
013 * Traffic controller for loopback CAN simulation.
014 *
015 * @author Bob Jacobsen Copyright (C) 2008
016 */
017public class LoopbackTrafficController extends jmri.jmrix.can.TrafficController {
018
019    public LoopbackTrafficController() {
020        super();
021    }
022
023    protected jmri.jmrix.can.CanSystemConnectionMemo adaptermemo;
024
025    /**
026     * Forward a CanMessage to all registered CanInterface listeners.
027     */
028    @Override
029    protected void forwardMessage(AbstractMRListener client, AbstractMRMessage m) {
030        ((CanListener) client).message((CanMessage) m);
031    }
032
033    /**
034     * Forward a CanReply to all registered CanInterface listeners.
035     */
036    @Override
037    protected void forwardReply(AbstractMRListener client, AbstractMRReply r) {
038        ((CanListener) client).reply((CanReply) r);
039    }
040
041    public boolean isBootMode() {
042        return false;
043    }
044
045    /**
046     * Forward a preformatted message to the actual interface.
047     */
048    @Override
049    public void sendCanMessage(CanMessage m, CanListener reply) {
050        log.debug("TrafficController sendCanMessage() {}", m.toString());
051        notifyMessage(m, reply);
052    }
053
054    /**
055     * Forward a preformatted reply to the actual interface.
056     */
057    @Override
058    public void sendCanReply(CanReply r, CanListener reply) {
059        log.debug("TrafficController sendCanReply() {}", r.toString());
060        notifyReply(r, reply);
061    }
062
063    /**
064     * Add trailer to the outgoing byte stream.
065     *
066     * @param msg    The output byte stream
067     * @param offset the first byte not yet used
068     */
069    @Override
070    protected void addTrailerToOutput(byte[] msg, int offset, AbstractMRMessage m) {
071        return;
072    }
073
074    /**
075     * Determine how many bytes the entire message will take, including
076     * space for header and trailer
077     *
078     * @param m The message to be sent
079     * @return Number of bytes
080     */
081    @Override
082    protected int lengthOfByteStream(AbstractMRMessage m) {
083        return m.getNumDataElements();
084    }
085
086    // New message for hardware protocol
087    @Override
088    protected AbstractMRMessage newMessage() {
089        log.debug("New CanMessage created");
090        CanMessage msg = new CanMessage(getCanid());
091        return msg;
092    }
093
094    /**
095     * Make a CanReply from a system-specific reply
096     */
097    @Override
098    public CanReply decodeFromHardware(AbstractMRReply m) {
099        log.error("decodeFromHardware unexpected");
100        return null;
101
102        /*         if (log.isDebugEnabled()) log.debug("Decoding from hardware: '"+m+"'\n"); */
103        /*      CanReply gc = (CanReply)m; */
104        /*         CanReply ret = new CanReply(); */
105        /*  */
106        /*      // Get the ID */
107        /*         ret.setId(gc.getID()); */
108        /*          */
109        /*         // Get the data */
110        /*         for (int i = 0; i < gc.getNumBytes(); i++) { */
111        /*             ret.setElement(i, gc.getByte(i)); */
112        /*         } */
113        /*         ret.setNumDataElements(gc.getNumBytes()); */
114        /*         if (log.isDebugEnabled()) log.debug("Decoded as "+ret); */
115        /*          */
116        /*         return ret; */
117    }
118
119    /**
120     * Encode a CanMessage for the hardware
121     */
122    @Override
123    public AbstractMRMessage encodeForHardware(CanMessage m) {
124        log.error("encodeForHardware unexpected");
125        return null;
126    }
127
128    // New reply from hardware
129    @Override
130    protected AbstractMRReply newReply() {
131        log.debug("New CanReply created");
132        CanReply reply = new CanReply();
133        return reply;
134    }
135
136    /*
137     * Dummy; loopback doesn't parse serial messages
138     */
139    @Override
140    protected boolean endOfMessage(AbstractMRReply r) {
141        log.error("endNormalReply unexpected");
142        return true;
143    }
144
145    /*
146     * Dummy; loopback doesn't parse serial messages
147     */
148    boolean endNormalReply(AbstractMRReply r) {
149        log.error("endNormalReply unexpected");
150        return true;
151    }
152
153    private final static Logger log = LoggerFactory.getLogger(LoopbackTrafficController.class);
154
155}