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-2023 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 return null; // normal operation 146 } 147 148 149 /** 150 * Set up all of the other objects to operate with a BiDiBSimulator 151 * connected to this port 152 */ 153 @Override 154 public void configure() { 155 log.debug("configure"); 156 MSG_RAW_LOGGER.debug("RAW> create BiDiB Instance"); 157 158 bidib = SimulationBidib.createInstance(getContext()); 159 BiDiBTrafficController tc = new BiDiBTrafficController(bidib); 160 context = tc.connnectPort(this); //must be done before configuring managers since they may need features from the device 161 log.debug("memo: {}, bidib simulator: {}", this.getSystemConnectionMemo(), bidib); 162 this.getSystemConnectionMemo().setBiDiBTrafficController(tc); 163 if (context != null) { 164 opened = true; 165 } 166 else { 167 opened = false; 168 log.warn("Simulation cannot be opened: {} ({}})", 169 getCurrentPortName(), getCurrentPortName()); 170 } 171 this.getSystemConnectionMemo().configureManagers(); 172 } 173 174 /** 175 * {@inheritDoc} 176 */ 177 @Override 178 public void registerAllListeners(ConnectionListener connectionListener, Set<NodeListener> nodeListeners, 179 Set<MessageListener> messageListeners, Set<TransferListener> transferListeners) { 180 181 SimulationInterface b = (SimulationInterface)bidib; 182 b.setConnectionListener(connectionListener); 183 b.registerListeners(nodeListeners, messageListeners, transferListeners); 184 } 185 186 // base class methods for the BiDiBSerialPortController interface 187 // not used but must be implemented 188 189 /** 190 * {@inheritDoc} 191 */ 192 @Override 193 public DataInputStream getInputStream() { 194// log.trace("getInputStream - pin: {}", pin); 195// if (pin == null) { 196// log.error("getInputStream called before load(), stream not available"); 197// ConnectionStatus.instance().setConnectionState(getUserName(), getCurrentPortName(), ConnectionStatus.CONNECTION_DOWN); 198// } 199// return pin; 200 return null; 201 } 202 203 /** 204 * {@inheritDoc} 205 */ 206 @Override 207 public DataOutputStream getOutputStream() { 208// log.trace("getInputStream - pin: {}", pout); 209// if (pout == null) { 210// log.error("getOutputStream called before load(), stream not available"); 211// ConnectionStatus.instance().setConnectionState(getUserName(), getCurrentPortName(), ConnectionStatus.CONNECTION_DOWN); 212// } 213// return pout; 214 return null; 215 } 216 217 /** 218 * {@inheritDoc} 219 */ 220 @Override 221 public boolean status() { 222 return opened; 223 } 224 225 226 private final static Logger log = LoggerFactory.getLogger(BiDiBSimulatorAdapter.class); 227 private static final Logger MSG_RAW_LOGGER = LoggerFactory.getLogger("RAW"); 228 229}