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 * {@inheritDoc} 028 */ 029 @Override 030 protected void forwardMessage(AbstractMRListener client, AbstractMRMessage m) { 031 ((CanListener) client).message((CanMessage) m); 032 } 033 034 /** 035 * Forward a CanReply to all registered CanInterface listeners. 036 * {@inheritDoc} 037 */ 038 @Override 039 protected void forwardReply(AbstractMRListener client, AbstractMRReply r) { 040 ((CanListener) client).reply((CanReply) r); 041 } 042 043 public boolean isBootMode() { 044 return false; 045 } 046 047 /** 048 * Forward a preformatted message to the actual interface. 049 * {@inheritDoc} 050 */ 051 @Override 052 public void sendCanMessage(CanMessage m, CanListener reply) { 053 log.debug("TrafficController sendCanMessage() {}", m.toString()); 054 notifyMessage(m, reply); 055 } 056 057 /** 058 * Forward a preformatted reply to the actual interface. 059 * {@inheritDoc} 060 */ 061 @Override 062 public void sendCanReply(CanReply r, CanListener reply) { 063 log.debug("TrafficController sendCanReply() {}", r.toString()); 064 notifyReply(r, reply); 065 } 066 067 /** 068 * Add trailer to the outgoing byte stream. 069 * 070 * @param msg The output byte stream 071 * @param offset the first byte not yet used 072 */ 073 @Override 074 protected void addTrailerToOutput(byte[] msg, int offset, AbstractMRMessage m) { 075 } 076 077 /** 078 * Determine how many bytes the entire message will take, including 079 * space for header and trailer 080 * 081 * @param m The message to be sent 082 * @return Number of bytes 083 */ 084 @Override 085 protected int lengthOfByteStream(AbstractMRMessage m) { 086 return m.getNumDataElements(); 087 } 088 089 // New message for hardware protocol 090 @Override 091 protected AbstractMRMessage newMessage() { 092 log.debug("New CanMessage created"); 093 return new CanMessage(getCanid()); 094 } 095 096 /** 097 * Make a CanReply from a system-specific reply. 098 * loop back returns null. 099 * {@inheritDoc} 100 */ 101 @Override 102 public CanReply decodeFromHardware(AbstractMRReply m) { 103 log.error("decodeFromHardware unexpected"); 104 return null; 105 } 106 107 /** 108 * Encode a CanMessage for the hardware. 109 * loop back returns null. 110 * {@inheritDoc} 111 */ 112 @Override 113 public AbstractMRMessage encodeForHardware(CanMessage m) { 114 log.error("encodeForHardware unexpected"); 115 return null; 116 } 117 118 // New reply from hardware 119 @Override 120 protected AbstractMRReply newReply() { 121 log.debug("New CanReply created"); 122 return new CanReply(); 123 } 124 125 /** 126 * Dummy; loopback doesn't parse serial messages. 127 * {@inheritDoc} 128 */ 129 @Override 130 protected boolean endOfMessage(AbstractMRReply r) { 131 log.error("endOfMessage unexpected"); 132 return true; 133 } 134 135 private final static Logger log = LoggerFactory.getLogger(LoopbackTrafficController.class); 136 137}