001package jmri.jmrix.bidib.simulator; 002 003import java.io.DataInputStream; 004import java.io.DataOutputStream; 005import java.io.File; 006import java.util.Set; 007import jmri.util.FileUtil; 008 009import jmri.jmrix.bidib.BiDiBSerialPortController; 010import jmri.jmrix.bidib.BiDiBTrafficController; 011import org.slf4j.Logger; 012import org.slf4j.LoggerFactory; 013 014import org.bidib.jbidibc.core.MessageListener; 015import org.bidib.jbidibc.core.NodeListener; 016import org.bidib.jbidibc.core.node.listener.TransferListener; 017import org.bidib.jbidibc.messages.ConnectionListener; 018import org.bidib.jbidibc.simulation.comm.SimulationBidib; 019import org.bidib.jbidibc.simulation.SimulationInterface; 020 021/** 022 * Provide access to a simulated BiDiB system. 023 * 024 * @author Paul Bender, Copyright (C) 2009-2010 025 * @author Eckart Meyer Copyright (C) 2019-2024 026 * 027 */ 028public class BiDiBSimulatorAdapter extends BiDiBSerialPortController { 029 030 protected String simulationFile = "simulation.xml"; //default 031 protected String loadedSimulationFilename = null; 032 protected String absoluteSimulationFile = null; 033 034 035 public BiDiBSimulatorAdapter() { 036 //super(new BiDiBSystemConnectionMemo()); 037// log.debug("ctor BiDiBSimulatorAdapter"); 038 } 039 040 041 public String getSimulationFile() { 042 return simulationFile; 043 } 044 045 public void setSimulationFile(String f) { 046 if (loadedSimulationFilename == null) { 047 loadedSimulationFilename = f; 048 } 049 simulationFile = f; 050 } 051 052 // not sure if this is the recommended way yu check our additional field... but works, I think. 053 @Override 054 public boolean isDirty() { 055 log.debug("isDirty"); 056 if (super.isDirty()) { 057 return true; 058 } 059 return (! simulationFile.equals(loadedSimulationFilename)); 060 } 061 062 //is this ever called? 063 @Override 064 public boolean isRestartRequired() { 065 log.debug("isRestartRequired"); 066 return super.isRestartRequired(); 067 } 068 069 070 071 /** 072 * {@inheritDoc} 073 */ 074 @Override 075 public String getCurrentPortName() { 076 if (absoluteSimulationFile == null) { 077 return getSimulationFile(); 078 } 079 else { 080 return absoluteSimulationFile; 081 } 082 } 083 084 /** 085 * {@inheritDoc} 086 * 087 * Get the "port name" in the format which is used by jbidibc - this is absolute path to the simulation XML file 088 * @return real port name 089 */ 090 @Override 091 public String getRealPortName() { 092 File f = new File(FileUtil.getExternalFilename("profile:" + getSimulationFile())); 093 return f.getAbsolutePath(); 094 } 095 096// @Override 097// public void recover() { 098// log.debug("recover called - ignored."); 099// // nothing 100// } 101// 102// /** 103// * {@inheritDoc} 104// */ 105// @Override 106// public void connect() throws java.io.IOException { 107// log.warn("connect called - ignored."); 108// //openPort(mPort, "JMRI app"); 109// } 110 111 /** 112 * Here we do not really open something. 113 * 114 * @param fileName name of simulation file 115 * @param appName not used 116 * @return error string, null if no error 117 */ 118 @Override 119 public String openPort(String fileName, String appName) { 120 // NOT USED AND NOT CALLED! Would be normally called by ConnectConfigXml 121 // we can't do anything meaningfull here. Even the existance of a file can't 122 // be checked since the seachpath is a secret of the jbidibc library... (the SimulatorBidib) 123 log.debug("simulation openPort: {}", fileName); 124// log.debug("user files path: {}", FileUtil.getUserFilesPath()); 125// log.debug("in profile: {}", FileUtil.getExternalFilename("profile:" + fileName)); 126// log.debug("in settings: {}", FileUtil.getExternalFilename("settings:" + fileName)); 127// Profile p = ProfileManager.getDefault().getActiveProfile(); 128// log.debug("active profile: path: {}, name: {}, uid: {}, id: {}", p.getPath(), p.getName(), p.getUniqueId(), p.getId()); 129// File f = new File(fileName); 130// if (!f.exists()) { 131// f = new File(FileUtil.getExternalFilename("profile:" + fileName)); 132// } 133// if (!f.exists()) { 134// f = new File(FileUtil.getExternalFilename("settings:" + fileName)); 135// } 136// if (!f.exists()) { 137// log.error("File not found: {}", fileName); 138// return "File not found: " + fileName; 139// } 140// absoluteSimulationFile = f.getAbsolutePath(); 141// log.info("Simulation file used: {}", f.getAbsoluteFile()); 142// // open the port in XpressNet mode, check ability to set moderators 143// //setPort(portName); 144// //return "---- TEST ----"; 145 146 147 return null; // normal operation 148 } 149 150 151 /** 152 * Set up all of the other objects to operate with a BiDiBSimulator 153 * connected to this port 154 */ 155 @Override 156 public void configure() { 157 log.debug("configure"); 158 MSG_RAW_LOGGER.debug("RAW> create BiDiB Instance"); 159 160 bidib = SimulationBidib.createInstance(getContext()); 161 BiDiBTrafficController tc = new BiDiBTrafficController(bidib); 162 log.debug("memo: {}, bidib simulator: {}", this.getSystemConnectionMemo(), bidib); 163 this.getSystemConnectionMemo().setBiDiBTrafficController(tc); 164 context = tc.connnectPort(this); //must be done before configuring managers since they may need features from the device 165 opened = false; 166 if (context != null) { 167 opened = true; 168 } 169 else { 170 log.warn("Simulation cannot be opened: {} ({}})", 171 getCurrentPortName(), getCurrentPortName()); 172 } 173 this.getSystemConnectionMemo().configureManagers(); 174 } 175 176 /** 177 * {@inheritDoc} 178 */ 179 @Override 180 public void registerAllListeners(ConnectionListener connectionListener, Set<NodeListener> nodeListeners, 181 Set<MessageListener> messageListeners, Set<TransferListener> transferListeners) { 182 183 SimulationInterface b = (SimulationInterface)bidib; 184 b.setConnectionListener(connectionListener); 185 b.registerListeners(nodeListeners, messageListeners, transferListeners); 186 } 187 188 // base class methods for the BiDiBSerialPortController interface 189 // not used but must be implemented 190 191 /** 192 * {@inheritDoc} 193 */ 194 @Override 195 public DataInputStream getInputStream() { 196// log.trace("getInputStream - pin: {}", pin); 197// if (pin == null) { 198// log.error("getInputStream called before load(), stream not available"); 199// ConnectionStatus.instance().setConnectionState(getUserName(), getCurrentPortName(), ConnectionStatus.CONNECTION_DOWN); 200// } 201// return pin; 202 return null; 203 } 204 205 /** 206 * {@inheritDoc} 207 */ 208 @Override 209 public DataOutputStream getOutputStream() { 210// log.trace("getInputStream - pin: {}", pout); 211// if (pout == null) { 212// log.error("getOutputStream called before load(), stream not available"); 213// ConnectionStatus.instance().setConnectionState(getUserName(), getCurrentPortName(), ConnectionStatus.CONNECTION_DOWN); 214// } 215// return pout; 216 return null; 217 } 218 219 /** 220 * {@inheritDoc} 221 */ 222 @Override 223 public boolean status() { 224 return opened; 225 } 226 227 228 private final static Logger log = LoggerFactory.getLogger(BiDiBSimulatorAdapter.class); 229 private static final Logger MSG_RAW_LOGGER = LoggerFactory.getLogger("RAW"); 230 231}