001package jmri.jmrix.loconet; 002 003import java.io.IOException; 004 005import jmri.InstanceManager; 006import jmri.ShutDownManager; 007import jmri.ShutDownTask; 008import jmri.implementation.AbstractShutDownTask; 009 010import org.slf4j.Logger; 011import org.slf4j.LoggerFactory; 012 013/** 014 * Base for classes representing a LocoNet communications port. 015 * 016 * @author Kevin Dickerson Copyright (C) 2011 017 * @author Bob Jacobsen Copyright (C) 2023 018 */ 019public abstract class LnNetworkPortController extends jmri.jmrix.AbstractNetworkPortController { 020 021 /** 022 * Base class. Implementations will provide InputStream and OutputStream 023 * objects to LnTrafficController classes, who in turn will deal in messages. 024 * 025 * @param connectionMemo associated memo for this connection 026 */ 027 protected LnNetworkPortController(LocoNetSystemConnectionMemo connectionMemo) { 028 super(connectionMemo); 029 setManufacturer(LnConnectionTypeList.DIGITRAX); 030 } 031 032 protected LnCommandStationType commandStationType = null; 033 034 protected boolean mTurnoutNoRetry = false; 035 protected boolean mTurnoutExtraSpace = false; 036 protected boolean mInterrogateAtStart = true; 037 038 protected boolean mTranspondingAvailable = false; 039 040 protected boolean mLoconetProtocolAutoDetect = false; 041 042 protected LnCommandStationType[] commandStationTypes = { 043 LnCommandStationType.COMMAND_STATION_DCS100, 044 LnCommandStationType.COMMAND_STATION_DCS240, 045 LnCommandStationType.COMMAND_STATION_DCS210, 046 LnCommandStationType.COMMAND_STATION_DCS200, 047 LnCommandStationType.COMMAND_STATION_DCS050, 048 LnCommandStationType.COMMAND_STATION_DCS051, 049 LnCommandStationType.COMMAND_STATION_DCS052, 050 LnCommandStationType.COMMAND_STATION_DB150, 051 LnCommandStationType.COMMAND_STATION_IBX_TYPE_1, 052 LnCommandStationType.COMMAND_STATION_IBX_TYPE_2, 053 LnCommandStationType.COMMAND_STATION_LBPS, 054 LnCommandStationType.COMMAND_STATION_MM, 055 LnCommandStationType.COMMAND_STATION_DCS210PLUS, 056 LnCommandStationType.COMMAND_STATION_DCS240PLUS}; 057 058 protected String[] commandStationNames; 059 060 { 061 commandStationNames = new String[commandStationTypes.length]; 062 int i = 0; 063 for (LnCommandStationType type : commandStationTypes) { 064 commandStationNames[i++] = type.getName(); 065 } 066 } 067 068 /** 069 * While opening, also register a ShutDown item that 070 * makes sure the socket is cleanly closed. 071 */ 072 @Override 073 public void connect() throws IOException { 074 super.connect(); 075 076 ShutDownTask shutDownTask = new AbstractShutDownTask("Writing Blocks") { 077 @Override 078 public void run() { 079 log.info("Closing LocoNet network connection"); 080 try { 081 socketConn.close(); 082 } catch (IOException ex) { 083 log.error("Exception closing LocoNet network connection", ex); 084 } 085 } 086 }; 087 InstanceManager.getDefault(ShutDownManager.class).register(shutDownTask); 088 } 089 090 // There are also "PR3 standalone programmer" and "Stand-alone LocoNet" 091 // in pr3/PR3Adapter 092 /** 093 * Set config info from a name, which needs to be one of the valid ones. 094 * 095 * @param name the name of the command station 096 */ 097 public void setCommandStationType(String name) { 098 try { 099 setCommandStationType(LnCommandStationType.getByName(name)); 100 } catch (IllegalArgumentException e) { 101 // not a valid command station type, force 102 log.error("Invalid command station name: \"{}\", defaulting to {}", name, commandStationTypes[0]); 103 setCommandStationType(commandStationTypes[0]); 104 } 105 } 106 107 /** 108 * Set configcommand station type. 109 * 110 * @param value command station type enum 111 */ 112 public void setCommandStationType(LnCommandStationType value) { 113 if (value == null) { 114 return; // can happen while switching protocols 115 } 116 log.debug("setCommandStationType: {}", value); 117 commandStationType = value; 118 } 119 120 @Override 121 public LocoNetSystemConnectionMemo getSystemConnectionMemo() { 122 return (LocoNetSystemConnectionMemo) super.getSystemConnectionMemo(); 123 } 124 125 public void setTurnoutHandling(String value) { 126 if (value.equals("One Only") || value.equals(Bundle.getMessage("HandleOneOnly")) 127 || value.equals("Both") || value.equals(Bundle.getMessage("HandleBoth"))) { 128 mTurnoutNoRetry = true; 129 } 130 log.debug("turnout no retry: {}", mTurnoutNoRetry); // NOI18N 131 if (value.equals("Spread") || value.equals(Bundle.getMessage("HandleSpread")) 132 || value.equals("Both") || value.equals(Bundle.getMessage("HandleBoth"))) { 133 mTurnoutExtraSpace = true; 134 } 135 log.debug("turnout extra space: {}", mTurnoutExtraSpace); // NOI18N 136 } 137 138 /** 139 * Set whether transponding is available. 140 * 141 * @param value either yes or no 142 */ 143 public void setTranspondingAvailable(String value) { 144 // default (most common state) is off, so just check for Yes 145 mTranspondingAvailable = (value.equals("Yes") || value.equals(Bundle.getMessage("ButtonYes"))); 146 log.debug("transponding available: {}", mTranspondingAvailable); // NOI18N 147 } 148 149 /** 150 * Set whether to use XP slots if available or not. 151 * 152 * @param value either Bundle.getMessage("LoconetProtocolAutoDetect") or no 153 */ 154 public void setLoconetProtocolAutoDetect(String value) { 155 // default (most common state) is off, so just check for Yes 156 mLoconetProtocolAutoDetect = (value.equals("Yes") || value.equals(Bundle.getMessage("LoconetProtocolAutoDetect"))); 157 log.debug("Loconet XPSlots: {}", mLoconetProtocolAutoDetect); // NOI18N 158 } 159 /** 160 * Set whether to interrogate at startup 161 * 162 * @param value either yes or no 163 */ 164 public void setInterrogateOnStart(String value) { 165 // default (most common state) is on, so just check for No 166 mInterrogateAtStart = !(value.equals("No") || value.equals(Bundle.getMessage("ButtonNo"))); 167 log.debug("Interrogate at StartUp: {}", mInterrogateAtStart); // NOI18N 168 } 169 170 /** 171 * Set the third port option. Only to be used after construction, but before 172 * the openPort call. 173 */ 174 @Override 175 public void configureOption3(String value) { 176 super.configureOption3(value); 177 log.debug("configureOption3: {}", value); 178 setTurnoutHandling(value); 179 } 180 181 private final static Logger log = LoggerFactory.getLogger(LnNetworkPortController.class); 182 183}