001package jmri.jmrix.loconet;
002
003import org.slf4j.Logger;
004import org.slf4j.LoggerFactory;
005
006/**
007 * Implements a LocoNetInterface by doing a scatter-gather to another, simpler
008 * implementation.
009 * <p>
010 * This is intended for remote operation, where only one copy of each message
011 * should go to/from another node. By putting an LnTrafficRouter implementation
012 * at the remote node, all of the routing of messages to multiple consumers can
013 * be done without traffic over the connection.
014 *
015 * @author Bob Jacobsen Copyright (C) 2002
016 */
017public class LnTrafficRouter extends LnTrafficController implements LocoNetListener {
018
019    /**
020     * Create a default instance connected to a given SystemConnectionMemo.
021     *
022     * @since 4.11.6
023     * @param m the connected LocoNetSystemConnectionMemo
024     */
025    public LnTrafficRouter(LocoNetSystemConnectionMemo m) {
026        // set the memo to point here
027        memo = m;
028        m.setLnTrafficController(this);
029    }
030
031    // Methods to implement the LocoNetInterface for clients.
032    // These use the parent implementations of listeners, addLocoNetListener,
033    // removeLocoNetListener, notify
034    boolean connected = false;
035
036    @Override
037    public boolean status() {
038        return connected;
039    }
040
041    /**
042     * Forward a preformatted LocoNetMessage to the actual interface.
043     *
044     * @param m Message to send; will be updated with CRC
045     */
046    @Override
047    public void sendLocoNetMessage(LocoNetMessage m) {
048        // update statistics
049        transmittedMsgCount++;
050
051        // forward message
052        destination.sendLocoNetMessage(m);
053    }
054
055    /**
056     * Receive a LocoNet message from upstream and forward it to all the local
057     * clients.
058     */
059    @Override
060    public void message(LocoNetMessage m) {
061        notify(m);
062    }
063
064    // methods to connect/disconnect to a source of data in another
065    // LocoNetInterface
066    private LocoNetInterface destination = null;
067
068    /**
069     * Make connection to existing LocoNetInterface object for upstream
070     * communication.
071     *
072     * @param i Interface to be connected
073     */
074    public void connect(LocoNetInterface i) {
075        destination = i;
076        connected = true;
077        i.addLocoNetListener(LocoNetInterface.ALL, this);
078    }
079
080    /**
081     * Break connection to upstream LocoNetInterface object. Once broken,
082     * attempts to send via "message" member will fail.
083     *
084     * @param i previously connected interface
085     */
086    public void disconnectPort(LocoNetInterface i) {
087        if (destination != i) {
088            log.warn("disconnectPort: disconnect called from non-connected LnPortController");
089        }
090        destination = null;
091        connected = false;
092    }
093
094    /**
095     * Implement abstract method to signal if there's a backlog of information
096     * waiting to be sent.
097     *
098     * @return true if busy, false if nothing waiting to send
099     */
100    @Override
101    public boolean isXmtBusy() {
102        return false;
103    }
104
105    private final static Logger log = LoggerFactory.getLogger(LnTrafficRouter.class);
106
107}