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     * @param requestIgnoreEcho  If true: Notify listeners on enqueing message, ignore echo from line.
046     *                           Only in effect if preference "LoconetUpdateSlotOnMessageCreation" is set.
047     */
048    @Override
049    public void sendLocoNetMessage(LocoNetMessage m, boolean requestIgnoreEcho) {
050        // update statistics
051        transmittedMsgCount++;
052
053        // forward message
054        destination.sendLocoNetMessage(m, requestIgnoreEcho);
055    }
056
057    /**
058     * Receive a LocoNet message from upstream and forward it to all the local
059     * clients.
060     */
061    @Override
062    public void message(LocoNetMessage m) {
063        notify(m);
064    }
065
066    // methods to connect/disconnect to a source of data in another
067    // LocoNetInterface
068    private LocoNetInterface destination = null;
069
070    /**
071     * Make connection to existing LocoNetInterface object for upstream
072     * communication.
073     *
074     * @param i Interface to be connected
075     */
076    public void connect(LocoNetInterface i) {
077        destination = i;
078        connected = true;
079        i.addLocoNetListener(LocoNetInterface.ALL, this);
080    }
081
082    /**
083     * Break connection to upstream LocoNetInterface object. Once broken,
084     * attempts to send via "message" member will fail.
085     *
086     * @param i previously connected interface
087     */
088    public void disconnectPort(LocoNetInterface i) {
089        if (destination != i) {
090            log.warn("disconnectPort: disconnect called from non-connected LnPortController");
091        }
092        destination = null;
093        connected = false;
094    }
095
096    /**
097     * Implement abstract method to signal if there's a backlog of information
098     * waiting to be sent.
099     *
100     * @return true if busy, false if nothing waiting to send
101     */
102    @Override
103    public boolean isXmtBusy() {
104        return false;
105    }
106
107    private static final Logger log = LoggerFactory.getLogger(LnTrafficRouter.class);
108
109}